Commit da847c79 authored by Mike Stephens's avatar Mike Stephens
Browse files

reintroduce Ursula AMBControl, recoded with generic ARMop style, not debugged yet

Version 5.35, 4.79.2.12. Tagged as 'Kernel-5_35-4_79_2_12'
parent 15faf754
......@@ -9,12 +9,16 @@
GBLS Module_ApplicationDate2
GBLS Module_ApplicationDate4
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.11"
Module_Date SETS "20 Oct 2000"
Module_ApplicationDate2 SETS "20-Oct-00"
Module_ApplicationDate4 SETS "20-Oct-2000"
Module_FullVersion SETS "5.35 (4.79.2.11)"
Module_HelpVersion SETS "5.35 (20 Oct 2000) 4.79.2.11"
Module_MinorVersion SETS "4.79.2.12"
Module_Date SETS "10 Nov 2000"
Module_ApplicationDate2 SETS "10-Nov-00"
Module_ApplicationDate4 SETS "10-Nov-2000"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.35 (4.79.2.12)"
Module_HelpVersion SETS "5.35 (10 Nov 2000) 4.79.2.12"
END
......@@ -4,16 +4,19 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.11
#define Module_Date_CMHG 20 Oct 2000
#define Module_MinorVersion_CMHG 4.79.2.12
#define Module_Date_CMHG 10 Nov 2000
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.11"
#define Module_Date "20 Oct 2000"
#define Module_MinorVersion "4.79.2.12"
#define Module_Date "10 Nov 2000"
#define Module_ApplicationDate2 "20-Oct-00"
#define Module_ApplicationDate4 "20-Oct-2000"
#define Module_ApplicationDate2 "10-Nov-00"
#define Module_ApplicationDate4 "10-Nov-2000"
#define Module_FullVersion "5.35 (4.79.2.11)"
#define Module_HelpVersion "5.35 (20 Oct 2000) (4.79.2.11)"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "RiscOS/Sources/Kernel"
#define Module_FullVersion "5.35 (4.79.2.12)"
#define Module_HelpVersion "5.35 (10 Nov 2000) (4.79.2.12)"
......@@ -1174,6 +1174,7 @@ ProcessorArch # 1
Proc_Cache_CleanInvalidateAll # 4
Proc_Cache_CleanAll # 4
Proc_Cache_InvalidateAll # 4
Proc_Cache_RangeThreshold # 4
Proc_TLB_InvalidateAll # 4
Proc_TLB_InvalidateEntry # 4
Proc_WriteBuffer_Drain # 4
......@@ -1183,6 +1184,8 @@ Proc_MMU_Changing # 4
Proc_MMU_ChangingEntry # 4
Proc_MMU_ChangingUncached # 4
Proc_MMU_ChangingUncachedEntry # 4
Proc_MMU_ChangingEntries # 4
Proc_MMU_ChangingUncachedEntries # 4
]
......
......@@ -236,6 +236,7 @@ ARM6support SETL {TRUE}
;despatch and wider SWI hashing)
;
;any ARM
;
GBLL ChocolateSysHeap ;whether to save cost of SysHeap block claim/release for common cases (eg. callback blocks)
;also reduces SysHeap stress by using fewer blocks in total
GBLL ChocolateOSMod ;whether to reduce SysHeap stress in module handling
......@@ -244,11 +245,16 @@ ARM6support SETL {TRUE}
GBLL ChocolateService ;whether to implement fast module service call distribution (uses table introduced
;into module format by Ursula API
;possibly enabled at run time for some ARMs only
;
GBLL ChocolateAMB ;whether to compile support for Lazy task swapping
ChocolateSysHeap SETL {TRUE}
ChocolateOSMod SETL {TRUE}
ChocolateSysVars SETL {TRUE}
ChocolateOscli SETL {TRUE}
ChocolateService SETL {TRUE}
ChocolateAMB SETL {TRUE}
[ ChocolateSysHeap
GBLA MaxChocolateCBBlocks ;max quick CallBack blocks available at any one time (else ordinary heap nodes used)
GBLA MaxChocolateSVBlocks ;max quick Software Vector blocks available at any one time (else ordinary heap nodes used)
......
......@@ -13,6 +13,13 @@
; limitations under the License.
;
; Implements OS_AMBControl (takes care of application memory management for Wimp)
;
; Nov 1995 mjs development version originated as Module
; Jul 1996 mjs fully implemented in kernel for RISC OS 3.70
; Mar 1997 mjs performance enhancements for Ursula OS
; Oct 2000 mjs Ursula code resurrected for 32-bit HALised kernel, hoorah!
GET s.AMBControl.Options
GET s.AMBControl.Workspace
GET s.AMBControl.main
......
......@@ -14,57 +14,47 @@
;
; > s.Memory
; lifted from Wimp source (v3.67)
; Small veneer between AMBControl's memory block requirements and OS_Heap,
; using system heap. This is changed since Ursula - old code called OS_Module
; and claimed blocks from RMA, which is an anachronism since code is in
; the kernel.
; this OS_Module equivalent looks at ptr-4 which the Heap Manager uses
; to store the real size of the block. In this way the memory use is
; more efficient (especially when extending a block) and RMA should
; fragment less often.
XROS_Module Entry
TEQ R0,#6
TEQNE R0,#7
TEQNE R0,#13
SWINE XOS_Module
EXIT NE
TEQ R0,#6
BEQ ros_claim
TEQ R0,#7
BEQ ros_free
; extend
Push "R3-R5"
LDR R4,[R2,#-8]
LDR R5,[R2,#-4]!
ADD R5,R5,R3 ; R5 is proposed new size
SUB R4,R4,#4
CMP R4,R5
CMPGE R3,#0
BLT %FT02
STR R5,[R2],#4 ; enough space so just store
Pull "R3-R5"
; can never error
CLRV
EXIT
02
SUB R3,R5,R4
SWI XOS_Module
STRVC R5,[R2],#4
Pull "R3-R5"
EXIT
; quantise sizes to reduce heap stress
;
AMBblockQ * 64
ros_free
SUB R2,R2,#4
SWI XOS_Module
EXIT
;in: r3=size
;out: r2 -> block, r0 corrupted
;
AMB_BlockClaim ROUT
Push "r1,r3,lr"
ADD r3,r3,#AMBblockQ - 1
BIC r3,r3,#AMBblockQ - 1
BL ClaimSysHeapNode
Pull "r1,r3,pc"
;in: r2 -> block
;out: r0 corrupted
;
AMB_BlockFree ROUT
Push "r1,lr"
BL FreeSysHeapNode
Pull "r1,pc"
ros_claim
ADD R3,R3,#4
SWI XOS_Module
STRVC R3,[R2],#4 ; so modptr-4 = amount asked for + 4
SUB R3,R3,#4 ; needs to be preserved
EXIT
;in: r2 -> block, r3 = new size
;out: r2 -> new block, r0 corrupted
;
AMB_BlockResize ROUT
Push "r1,r3,lr"
ADD r3,r3,#AMBblockQ - 1
BIC r3,r3,#AMBblockQ - 1
LDR r1,[r2,#-4] ;pick up OS_Heap's size word (naughty!)
SUB r1,r1,#8 ;heap size will be 8 more than quantised size
SUBS r3,r3,r1 ;required size change
MOVNE r0, #HeapReason_ExtendBlock
BLNE DoSysHeapOpWithExtension
Pull "r1,r3,pc"
END
......@@ -13,10 +13,12 @@
; limitations under the License.
;
; > s.Options
AMBMagicNodeID * &4E424D41 ;"AMBN"
AMBInitialMaxNodes * 256
AMBGrowMaxNodes * 64
AMBGrowMaxNodes * 64 ;not used now AMBControl is in kernel
;Bin pages by physical address, for quick mapping from page number to
......@@ -30,15 +32,49 @@ AMBPhysBinMask * &7F
ApplicationStart * (32*1024)
AbsMaxAppSize * (28*1024*1024) ;28 Mb application space limit for RISC OS
AbsMaxAppPages * (AbsMaxAppSize:SHR:Log2PageSize) ;and same limit expressed in Pages
[ ChocolateAMB
AMBMIRegWords * (AbsMaxAppPages+31) :SHR: 5 ;no. of words for AMBMappedInRegister
;convenient to set this at fixed max size
;(only 896 bytes for 28Mb AppSpace)
]
;maximum logical space size cleaned by range strategy
;whether to check handles given to AMBControl - not very useful when in kernel
;
AMB_ARMA_CleanRange_thresh * 256*1024
GBLL ValidateAMBHandles
ValidateAMBHandles SETL {FALSE}
GBLL ValidateAMBHandles ; whether to check handles given to AppMAMBan
ValidateAMBHandles SETL {FALSE}
;performance enhancements originally introduced for Ursula OS
;
; ChocolateAMB - if {FALSE}, disables all AMBControl crazy chocolate flavour enhancements
;
; AMB_LazyMapIn - if {TRUE}, individual pages of a swapped-in task are only mapped in when
; necessary (happens via abort mechanism). This typically makes the swapping
; cost much lower and much less sensitive to large slot size. The worst case
; swapping cost is still good (abort mechanism cost is very small).
; Probably only worth supporting this on ARMs with simple instruction restart
; after abort (originally StrongARM revT or later for Ursula)
;
; AMB_LimpidFreePool - if {TRUE}, the cache(s) can be assumed to be clear with respect to the FreePool
; when AMBControl fetches pages from it. This allows AMBControl to avoid any
; cache clean/flush for moving pages out of the FreePool. This assumption is
; valid if either: FreePool pages are uncacheable; or FreePool pages are
; never used in situ; or FreePool pages are flushed after use in situ.
;
; AMB_ChocTrace - if {TRUE}, keep trace info for some enhanced code calls and data (probably development only)
GBLL AMB_LazyMapIn
GBLL AMB_LimpidFreePool
GBLL AMB_ChocTrace
AMB_LazyMapIn SETL {TRUE} :LAND: ChocolateAMB
AMB_LimpidFreePool SETL {TRUE} :LAND: ChocolateAMB ;allowed because FreePool is currently marked uncacheable
;current implementation assumes uncacheability as criterion
AMB_ChocTrace SETL {FALSE} :LAND: ChocolateAMB ;development only
END
......@@ -14,36 +14,76 @@
;
; > s.Workspace
; task node format
;
;task node format
;
^ 0
AMBNode_id # 4 ; magic identifier
AMBNode_handle # 4 ; handle for external reference
AMBNode_prev # 4 ; -> previous node
AMBNode_next # 4 ; -> next node
AMBNode_pagetable # 0 ; data comprising page table from here on
AMBNode_Npages # 4 ; no. of pages in page list
AMBNode_startaddr # 4 ; logical address of first page (-1 means nowhere)
AMBNode_PPL # 4 ; PPL ('page protection level') for pages
AMBNode_pages # 0 ; list of pages from here on (1 word per page no.)
; main workspace
AMBNode_HdrStart # 0
AMBNode_id # 4 ;magic identifier
AMBNode_handle # 4 ;handle for external reference
AMBNode_prev # 4 ;ptr to previous node
AMBNode_next # 4 ;ptr to next node
AMBNode_pagetable # 0 ;data comprising page table from here on
AMBNode_Npages # 4 ;no. of pages in page list
AMBNode_startaddr # 4 ;logical address of first page (-1 means nowhere)
AMBNode_PPL # 4 ;PPL ('page protection level') for pages
AMBNode_pages # 0 ;list of page numbers from here on (1 word per page)
AMBNode_HdrEnd # 0
;
AMBNode_HdrSize * AMBNode_HdrEnd - AMBNode_HdrStart
;
;main workspace
;
^ 0,R12
AMBNhandles # 4 ; total handles available
AMBNtasks # 4 ; No. of tasks currently allocated
AMBMappedInNode # 4 ; node ptr of mapped-in task, or 0 for none
AMBNhandles # 4 ;total handles available
AMBNtasks # 4 ;no. of tasks currently allocated
AMBMappedInNode # 4 ;node ptr of mapped-in task, or 0 for none
AMBNodeHandles # 4 ;ptr to node handle array (1 word per entry)
AMBPhysBin # 4 ;ptr to physical page bin array
AMBPhysBinEntries # 4 ;no. of entries in physical page bin array
AMBAnchorNode # AMBNode_HdrSize ;dummy node - see note (1) below
;
[ ChocolateAMB
AMBFlags # 4 ;bits defined as below
AMBNContextSwitches # 4 ;monotonic count of total no. of task map-in's (eg. for performance tracing)
[ AMB_ChocTrace
AMBNmakeunsparse # 4 ;count of no. of calls to AMB_MakeUnsparse
AMBNmemmoveshrink # 4 ;count of no. of Service_MemoryMoved shrink fixups
AMBNmemmovegrow # 4 ;count of no. of Service_MemoryMoved grow fixups
]
AMBMappedInNpages # 4 ;no. of pages of MappedInNode really mapped in
AMBMappedInRegister # AMBMIRegWords*4 ;1 bit per page - see note (2) below
]
;
AMBmaxwork * :INDEX:@ ;size of main workspace (assumed to be multiple of 4 bytes)
;ptr to node handle array (1 word per entry)
AMBNodeHandles # 4
;ptr to physical page bin array
AMBPhysBin # 4
AMBPhysBinEntries # 4
[ ChocolateAMB
;
;definition of bits in AMBFlags
;
AMBFlag_LazyMapIn_disable * &80000000 ;bit 31 LazyMapIn permanent disable (eg. not running on StrongARM)
AMBFlag_LazyMapIn_suspend * &40000000 ;bit 30 LazyMapIn suspend (controlled via AMB SWI)
;bits 29..0 reserved (0)
;
]
;dummy node (0 page entries) forms anchor of circular node list
;this averts the need for any special case for add or remove node
AMBAnchorNode # (AMBNode_pages - AMBNode_id)
;Notes:
;
; (1) AMBAnchorNode is a dummy node with 0 page entries that forms the anchor of a
; circular node list. This averts the need for any special case for adding or
; removing nodes.
;
; (2) AMBMappedInRegister is a 'bitmap' of the current page mapping status of the
; MappedInNode. This supports AMB_LazyMapIn. Bit n corresponds to the n'th page
; of the MappedInNode; if it is set, then that page is currently mapped in. The
; bits are packed 'little endian', so bit 0 is the LSB of word 0, bit 31 is
; the MSB of word 0, bit 32 is the LSB of word 1 and so on. The bits are only
; significant when AMBMappedInNpages is > 0 (and then all AMBNode_Npages bits
; for the MappedInNode are significant).
AMBmaxwork * :INDEX:@
END
......@@ -27,6 +27,8 @@
allocate
Push "R0,R3,R4,LR"
; Debug AMB,"allocate ",r0,r1
MOV R3,#AbsMaxAppSize
SUB R3,R3,#ApplicationStart
MOV R3,R3,LSR #Log2PageSize ;R3 = absolute max app pages
......@@ -40,44 +42,16 @@ allocate
CMP R4,#0 ;any handles available?
BNE %FT01
[ {TRUE} ; give up
; give up
Pull "R0,R3,R4,LR"
ADR R0,err_nomorehandles
B SLVK_SetV
]
[ {FALSE} ; oh no we don't, we're not a module now
;try to extend handles array
MOV R2,R0
MOV R0,#ModHandReason_ExtendBlock
MOV R3,#(GrowMaxNodes:SHL:2)
SWI XOS_Module
BVS alloc_done
MOV R0,R2
STR R0,AMBNodeHandles ;in case block has moved
LDR R3,AMBNhandles
STR R3,[R0] ;first free handle now
ADD LR,R3,#GrowMaxNodes
STR LR,AMBNhandles
ADD R4,R0,R3,LSL #2
ADD R3,R3,#1
;put new handles on free list
00
STR R3,[R4],#4
ADD R3,R3,#1
CMP R3,LR
BNE %BT00
MOV R3,#0
STR R3,[R4] ;0 = end of list
LDR R4,[R0] ;now we have a useable handle
]
01
;get memory for node - from RMA
MOV R3,#(AMBNode_pages - AMBNode_id) ;size excluding page list
ADD R3,R3,R1,LSL #2 ;plus one word per page
MOV R0,#ModHandReason_Claim
BL XROS_Module
BL AMB_BlockClaim
BVS alloc_done
;remember handle in node
......@@ -128,16 +102,17 @@ alloc_ok
STR R2,AMBMappedInNode ;allocated node is also mapped in
LDR R2,[R2,#AMBNode_handle] ;change address to handle
CLRV
alloc_done
; Debug AMB,"<alloc ",r1,r2
STRVS R0,[SP]
Pull "R0,R3,R4,LR"
B SLVK_TestV
;free page table space and return 0 handle
alloc_zeropages
MOV R0,#ModHandReason_Free
BL XROS_Module
BL AMB_BlockFree
MOV R1,#0
MOV R2,#0
B alloc_done
......
......@@ -27,6 +27,8 @@
deallocate
Push "R0-R3,LR"
; Debug AMB,"deallocate ",r0,r2
[ ValidateAMBHandles
;validate handle
LDR R0,AMBNhandles
......@@ -76,8 +78,8 @@ deallocate
STREQ R0,AMBMappedInNode
;free node (at R2)
MOV R0,#ModHandReason_Free
BL XROS_Module
BL AMB_BlockFree
dealloc_done
STRVS R0,[SP]
Pull "R0-R3,LR"
......
......@@ -62,10 +62,21 @@ growpages ROUT
; R5 := start logical address
BL AMB_FindMemMapEntries ;find page nos.
[ AMB_LazyMapIn
LDR R5,AMBFlags
TST R5,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend
;
MOVEQ R5,#-1 ;map the pages to Nowhere initially
MOVEQ R6,#AP_Duff
LDRNE R5,[R0,#AMBNode_startaddr]
ADDNE R5,R5,R7,LSL #Log2PageSize ;R5 := first new page new address
LDRNE R6,[R0,#AMBNode_PPL] ;R6 := dest PPL flags
|
LDR R5,[R0,#AMBNode_startaddr]
ADD R5,R5,R7,LSL #Log2PageSize ;R5 := first new page new address
LDR R6,[R0,#AMBNode_PPL] ;R6 := dest PPL flags
]
;
;entry: R3 = no. of pages, R4 -> list of page entries,
; R5 = start logical address, R6 = PPL
BL AMB_SetMemMapEntries ;remap
......@@ -81,7 +92,8 @@ growpages ROUT
STR R5,[R6,#MemLimit] ;update MemLimit
02
STRVS R0,[SP]
;;; STRVS R0,[SP]
CLRV
Pull "R0-R7,PC"
[ ShrinkableDAs
......
......@@ -31,6 +31,8 @@ growshrink
Push "R0,R2,R4,R5,LR"
; Debug AMB,"growshrink ",r0,r1,r2
MOV R5,#AbsMaxAppSize
SUB R5,R5,#ApplicationStart
MOV R5,R5,LSR #Log2PageSize ;R5 = absolute max app pages
......@@ -103,11 +105,10 @@ grwshr_node
Push "R0,R3,R4,LR"
CMP R1,#0
BEQ grwshrn_free ;shrunk to nothing
SUB R4,R1,R5
MOV R3,R4,ASL #2
MOV R3,#(AMBNode_pages - AMBNode_id) ;new size excluding page list
ADD R3,R3,R1,LSL #2 ;new size
MOV R4,R2 ;so we can check for moved block
MOV R0,#ModHandReason_ExtendBlock
BL XROS_Module
BL AMB_BlockResize
MOVVS R2,R4 ;in case block ptr not preserved on error
BVS grwshrn_done
;fix-up links if block has moved
......@@ -152,8 +153,7 @@ grwshrn_free
MOVEQ R0,#0
STREQ R0,AMBMappedInNode
MOV R0,#ModHandReason_Free
BL XROS_Module
BL AMB_BlockFree
MOVVC R2,#0
B grwshrn_done
......
......@@ -13,15 +13,14 @@
; limitations under the License.
;
; AMBControl - takes care of application memory management (for Wimp)
;Nov 95 - Started by mjs
; > s.main
;;; Initialisation
;
AMBControl_Init
Push "R0-R4,R12,LR"
;claim main workspace
LDR R3,=AMBmaxwork
BL ClaimSysHeapNode
;;; BVS err_cantclaim - this should not happen
......@@ -31,7 +30,16 @@ AMBControl_Init
;
MOV R12,R2
;block for handle array
;zero-init workspace
MOV R1,#0
LDR R3,=AMBmaxwork
ADD R3,R3,R2
00
STR R1,[R2],#4
CMP R2,R3
BLO %BT00
;claim block for handle array
MOV R3,#(AMBInitialMaxNodes:SHL:2)
BL ClaimSysHeapNode
;;; BVS err_cantclaim
......@@ -49,7 +57,7 @@ AMBControl_Init
MOV R0,#0 ; = end of list
STR R0,[R2]
;block for PhysBin array
;claim block for PhysBin array
LDR R3,=MaxCamEntry
LDR R3,[R3]
ADD R3,R3,#1 ;no. of RAM pages extant
......@@ -77,20 +85,19 @@ AMBControl_Init
SUBS R4,R4,#1
BNE %BT03
; init anchor node stuff etc.
MOV R0,#0
STR R0,AMBNtasks
STR R0,AMBMappedInNode
;init any other workspace that shouldn't init as 0
ADR R1,AMBAnchorNode
MOV R3,R1
STR R0,[R1],#4 ; node id = 0 for ank node (not a real node!)
STR R0,[R1],#4 ; handle = 0
STR R3,[R1],#4 ; prev (starts -> ank node)
STR R3,[R1],#4 ; next (starts -> ank node)
STR R0,[R1],#4 ; Npages
STR R0,[R1],#4 ; startaddr
STR R0,[R1],#4 ; PPL
STR R1,[R1,#AMBNode_prev] ;anchor prev initially -> anchor (empty list)
STR R1,[R1,#AMBNode_next] ;anchor next initially -> anchor (empty list)
[ AMB_LazyMapIn
; currently always disable, need to sort out when abort fix up is supported
; and for which ARMs
;
! 0, "AMBControl currently always disables LazyMapIn (needs abort handler hooks)"
;
MOV R1,#AMBFlag_LazyMapIn_disable
STR R1,AMBFlags
]
MOV R0,#AMBControl_ws
STR R12,[R0] ;now initialisation is complete
......@@ -119,7 +126,11 @@ reasons0
B growshrink ;2
B mapslot ;3
B readinfo ;4
[ AMB_LazyMapIn
B laziness ;5
|
B reserved ;5
]
B reserved ;6
B reserved ;7
B mjs_info ;8 - system reason code, dumps info to buffer
......@@ -128,6 +139,58 @@ reasons1
B SLVK_SetV
[ AMB_LazyMapIn
;
;entry: R0=5 (reason),R1=1 for lazy on, 0 for lazy off, -1 to read lazy only
;exit: R1=new lazy value, after any restrictions of platform applied
;
;action: if reading only, if lazy disabled, or if new state = current, do nothing
; if state is changing, map out any current node, change state, map in any current node
;
laziness ROUT
Push "R2-R3,LR"
CMP R1,#-1
BEQ %FT20
LDR R2,AMBFlags ;R2 := current flags
TST R2,#AMBFlag_LazyMapIn_disable ;disable is permanent
BNE %FT20
CMP R1,#0
MOV R1,R2
ORREQ R1,R1,#AMBFlag_LazyMapIn_suspend
BICNE R1,R1,#AMBFlag_LazyMapIn_suspend ;R1 := new flags
EOR R3,R1,R2
TST R3,#AMBFlag_LazyMapIn_suspend ;is suspend status changing?
BEQ %FT20
LDR R3,AMBMappedInNode
CMP R3,#0
BEQ %FT10
Push "R0-R3"
MOV R0,#3
MOV R1,#-1
LDR R2,[R3,#AMBNode_handle]
SWI XOS_AMBControl ;map out current node
Pull "R0-R3"
10
STR R1,AMBFlags
CMP R3,#0
BEQ %FT20
Push "R0-R3"
MOV R0,#3
MOV R1,#0
LDR R2,[R3,#AMBNode_handle]
SWI XOS_AMBControl ;map in current node
Pull "R0-R3"
20
LDR R1,AMBFlags
TST R1,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend
MOVEQ R1,#1
MOVNE R1,#0
Pull "R2-R3,LR"
B SLVK
;
] ;AMB_LazyMapIn
;entry: R0=8 (reason),R1 -> buffer (say 4k for up to 255 tasks)
;exit: buffer filled:
; 0 Ntasks
......@@ -171,11 +234,6 @@ reserved
;;; errors (sod internationalisation)
;;;err_cantclaim
;;; DCD 0
;;; DCB "AMBControl failed to claim workspace",0
;;; ALIGN
err_badreason
DCD 0
DCB "bad AMBControl reason code",0
......
......@@ -23,8 +23,14 @@
; R2 = handle
; R3,R4 used if bit 8 set - see mapsome
;
; Note that if bit 8 is clear, the use is restricted to mapping in or out of
; whole slots only. Hence if bit 8 is clear, behaviour is undefined unless
; R1 is one of: 0, &8000 or -1.
;
mapslot
; Debug AMB,"mapslot",r0,r1,r2,r3,r4
TST R0,#&100 ;if bit 8 set, then mapsome
BNE mapsome
......@@ -71,16 +77,48 @@ mapslot
BEQ ms_done ;else do map only if not already mapped in, and asked to map in
ms_domap
CMP R5,#-1
CMP R5,#-1 ;EQ if it is a map out
LDREQ R6,=DuffEntry
MOVNE R6,#ApplicationStart
STR R6,[R1,#AMBNode_startaddr]
MOVEQ R6,#AP_Duff
MOVNE R6,#0
STR R6,[R1,#AMBNode_PPL]
[ AMB_LazyMapIn
LDRNE R2,AMBNContextSwitches
ADDNE R2,R2,#1
STRNE R2,AMBNContextSwitches
LDR R2,AMBFlags
TST R2,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend
BNE ms_cantbelazy
;
; - if map out, do sparse map out of whole page list then zero AMBMappedInNpages
; - if map in, just zero AMBMappedInNpages (last map out will have cleared AMBMappedInRegister)
;
MOV R2,R5
CMP R2,#-1
LDREQ R3,AMBMappedInNpages
ADREQ R5,AMBMappedInRegister
LDREQ R6,[R1,#AMBNode_Npages]
;entry: R3 = no. pages mapped in, R4 -> list of page entries,
; R5 -> bitmap of pages mapped in, R6=total no. of pages in page list
BLEQ AMB_SetMemMapEntries_SparseMapOut
MOV R3,#0
STR R3,AMBMappedInNpages
MOV R5,R2
B ms_mapdone
ms_cantbelazy
;entry: R3 = no. of pages, R4 -> list of page entries,
; R5 := start logical address, R6 = PPL
BL AMB_SetMemMapEntries
ms_mapdone
|
;entry: R3 = no. of pages, R4 -> list of page entries,
; R5 := start logical address, R6 = PPL
BL AMB_SetMemMapEntries
]
;update AppSpace kernel stuff
LDR R2,[R1,#AMBNode_Npages]
LDR R3,=AppSpaceDANode
......@@ -96,7 +134,8 @@ ms_domap
STR R3,AMBMappedInNode
ms_done
STRVS R0,[SP]
;;; STRVS R0,[SP]
CLRV
Pull "R0-R6,LR"
B SLVK_TestV
......
......@@ -15,25 +15,117 @@
; > s.memmap
; low level memory mapping
; **************************************************************************************
;
;convert page number in $reg to L2PT entry (physical address+protection bits),
; ----------------------------------------------------------------------------------
;
;convert page number in $pnum to L2PT entry (physical address+protection bits),
;using PhysBin table for speed
;
;entry: lr -> PhysBin table, r11 = protection bits
;exit: r12 corrupted
;entry: $ptable -> PhysBin table, $pbits = protection bits
;exit: $temp corrupted
;
MACRO
PageNumToL2PT $reg
BIC r12,$reg,#(3:SHL:(AMBPhysBinShift-2)) ;word alignment for PhysBin lookup
LDR r12,[lr,r12,LSR #(AMBPhysBinShift-2)] ;start physical address of bin
AND $reg,$reg,#AMBPhysBinMask ;no. pages into bin
ADD $reg,r12,$reg,LSL #Log2PageSize ;physical address of page
ORR $reg,$reg,r11 ;munge in protection bits
PageNumToL2PT $pnum,$ptable,$pbits,$temp
BIC $temp,$pnum,#(3:SHL:(AMBPhysBinShift-2)) ;word alignment for PhysBin lookup
LDR $temp,[$ptable,$temp,LSR #(AMBPhysBinShift-2)] ;start physical address of bin
AND $pnum,$pnum,#AMBPhysBinMask ;no. pages into bin
ADD $pnum,$temp,$pnum,LSL #Log2PageSize ;physical address of page
ORR $pnum,$pnum,$pbits ;munge in protection bits
MEND
[ AMB_LazyMapIn
; ----------------------------------------------------------------------------------
;
;AMB_LazyFixUp
;
; *Only* for ARMs where the abort handler can restart instructions
;
; Routine to be used in abort handlers (in abort32 mode), that checks to see if abort
; is expected, and fixes things up if so, ready to restart instruction.
;
; Fix up consists of mapping in affected page, and updating AMBMappedInRegister. This
; may seem like a lot of work, but remember that the L2PT and CAM updates for each page are
; needed anyway in non-lazy scheme, so there is really only a housekeeping overhead.
;
; There is no cache clean/flush consideration here, since the map is a map in from Nowhere.
; TLB flush consideration is left to main abort handler code - in fact there may not
; be a TLB flush consideration at all, if ARM TLB can be assumed not to cache an
; entry which is a translation fault, as seems rational.
;
; entry: r0 = aborting address (data address for data abort, instruction address
; for prefetch abort), r1-r7 trashable, no stack
; exit: r0 = non-zero if abort was expected and fixed up, zero if not
;
AMB_LazyFixUp ROUT
; not hooked in yet!
! 0, "AMB_LazyFixUp needs hooking into abort handlers"
MOV r7,r12
MOV r12,#AMBControl_ws
LDR r12,[r12]
CMP r12,#0
BEQ %FT20
SUBS r0,r0,#ApplicationStart
BMI %FT20
MOV r0,r0,LSR #Log2PageSize ;address now in terms of pages from ApplicationStart
LDR r1,AMBMappedInNode
CMP r1,#0
BEQ %FT20
LDR r2,[r1,#AMBNode_Npages]
CMP r2,r0
BLS %FT20
;
;need not check MappedInRegister first, since if abort has happened in range of current
;AppSpace, then the page can be assumed to be mapped out
;
ADD r1,r1,#AMBNode_pages
ADD r1,r1,r0,LSL #2 ;r1 -> page involved, in node page list
LDR r2,AMBPhysBin
! 0, "AMB_LazyFixup a symbol for L2PT protection bits would be handy"
MOV r3,#&FF0
ORR r3,r3,#&E ;&FFE = L2PT protection bits for ordinary page
LDR r4,[r1]
MOV r6,r4
PageNumToL2PT r4,r2,r3,r5
;
;here, r6 = page number of page involved, r4 = new L2PT entry value to map in page
;
LDR r2,AMBMappedInNpages ;for convenience, update bitmap etc. here...
ADD r2,r2,#1
STR r2,AMBMappedInNpages
ADR r2,AMBMappedInRegister
ADD r2,r2,r0,LSR #5-2 ;r2 -> bitmap word affected
BIC r2,r2,#3
AND r3,r0,#31
MOV r5,#1
MOV r5,r5,LSL r3 ;mask for bit affected in bitmap word
LDR r3,[r2]
ORR r3,r3,r5
STR r3,[r2]
ADD r0,r0,#ApplicationStart:SHR:Log2PageSize ;address now in terms of pages from 0
MOV r5,#L2PT
STR r4,[r5,r0,LSL #2] ;update L2PT
MOV r5,#0
LDR r5,[r5,#CamEntriesPointer]
ADD r5,r5,r6,LSL #3 ;r5 -> CAM entry affected
MOV r0,r0,LSL #Log2PageSize ;address is now ordinary again, and must be non-zero
MOV r1,#0 ;0 = AP for ordinary page
STMIA r5,{r0,r1} ;update CAM entry
MOV r12,r7
MOV pc,lr ;r0 is non-zero
20
MOV r0,#0
MOV r12,r7
MOV pc,lr
] ;AMB_LazyMapIn
; ----------------------------------------------------------------------------------
;
;AMB_movepagesin_L2PT
;
;updates L2PT for new logical page positions, does not update CAM
......@@ -55,14 +147,14 @@ AMB_movepagesin_L2PT ROUT
BLT %FT20
10
LDMIA r10!,{r0-r7} ;next 8 page numbers
PageNumToL2PT r0
PageNumToL2PT r1
PageNumToL2PT r2
PageNumToL2PT r3
PageNumToL2PT r4
PageNumToL2PT r5
PageNumToL2PT r6
PageNumToL2PT r7
PageNumToL2PT r0,lr,r11,r12
PageNumToL2PT r1,lr,r11,r12
PageNumToL2PT r2,lr,r11,r12
PageNumToL2PT r3,lr,r11,r12
PageNumToL2PT r4,lr,r11,r12
PageNumToL2PT r5,lr,r11,r12
PageNumToL2PT r6,lr,r11,r12
PageNumToL2PT r7,lr,r11,r12
STMIA r9!,{r0-r7} ;write 8 L2PT entries
SUB r8,r8,#8
CMP r8,#8
......@@ -72,17 +164,15 @@ AMB_movepagesin_L2PT ROUT
BEQ %FT35
30
LDR r0,[r10],#4
PageNumToL2PT r0
PageNumToL2PT r0,lr,r11,r12
STR r0,[r9],#4
SUBS r8,r8,#1
BNE %BT30
35
ARM_read_ID r0
AND r0,r0,#&F000
CMP r0,#&A000
ARMA_drain_WB EQ ;because L2PT area for AppSpace will be bufferable
Pull "r0-r10,r12,pc"
; ----------------------------------------------------------------------------------
;
;update CAM entry for page number in $reg
;
;entry: r11 -> CAM, r9 = logical addr of page, lr = PPL of page
......@@ -94,6 +184,8 @@ AMB_movepagesin_L2PT ROUT
STMIA $reg,{r9,lr} ;store logical addr,PPL
MEND
; ----------------------------------------------------------------------------------
;
;AMB_movepagesin_CAM
;
;updates CAM, does not update L2PT
......@@ -147,7 +239,8 @@ AMB_movepagesin_CAM ROUT
BNE %BT30
Pull "r0-r11,pc"
; ----------------------------------------------------------------------------------
;
;AMB_movepagesout_CAM
;
;updates CAM, does not update L2PT
......@@ -190,7 +283,8 @@ AMB_movepagesout_CAM ROUT
BNE %BT30
Pull "r0-r11,pc"
; ----------------------------------------------------------------------------------
;
;AMB_movepagesout_L2PT
;
;updates L2PT for old logical page positions, does not update CAM
......@@ -229,40 +323,10 @@ AMB_movepagesout_L2PT ROUT
SUBS r8,r8,#1
BNE %BT30
35
ARM_read_ID r0
AND r0,r0,#&F000
CMP r0,#&A000
ARMA_drain_WB EQ ;because L2PT area for AppSpace will be bufferable
Pull "r0-r8,pc"
[ ARM810support
;Previously supported ARMs all tolerate cache (clean and) flush _after_
;remapping - ARMs 6,7 because there is no clean, StrongARM because the cache
;writebacks use physical address.
;ARM810 does not support clean of writeback cache after remapping, since
;writebacks use virtual address. Rather than completely restructure code,
;this routine is called before remapping where necessary, and cleans/flushes
;if it finds we are running on ARM 810.
;
;corrupts r3
;
AMB_cachecleanflush_ifARM810
ARM_read_ID r3
AND r3,r3,#&F000
CMP r3,#&8000
MOVNE pc,lr ;not ARM8
[ ARM810cleanflushbroken
Push "lr"
ARM8_cleanflush_IDC r3,lr
Pull "pc"
|
ARM8_cleanflush_IDC r3
MOV pc,lr
]
] ;ARM810support
;**************************************************************************
; ----------------------------------------------------------------------------------
;
; AMB_SetMemMapEntries:
;
; entry:
......@@ -271,9 +335,8 @@ AMB_cachecleanflush_ifARM810
; R5 = start logical address of mapping (-1 means 'out of the way')
; R6 = PPL ('page protection level') for mapping
;
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AMB_SetMemMapEntries ROUT
Push "r0-r4,r7-r11,lr"
MOVS r8,r3
......@@ -298,8 +361,13 @@ AMB_SetMemMapEntries ROUT
LDR r2,[r10] ;page number of 1st page
MOV r7,#0
LDR r7,[r7,#CamEntriesPointer] ;r7 -> CAM
ADD r1,r7,r2,LSL #3
ADD r1,r7,r2,LSL #3 ;r1 -> CAM entry for 1st page
[ AMB_LimpidFreePool
LDR r4,[r1] ;fetch old logical addr. of 1st page from CAM
LDR r3,[r1,#4] ;fetch old PPL of 1st page from CAM
|
LDR r4,[r1] ;fetch old logical addr. of 1st page from CAM
]
CMP r5,#-1
BEQ AMB_smme_mapout
......@@ -309,135 +377,199 @@ AMB_SetMemMapEntries ROUT
BEQ AMB_smme_mapin
;map from somewhere to somewhere (should be App Space <-> Free Pool)
;could be an optimise here if source is FreePool and we know that FreePool
;has not been used - ie. no need to clean/flush cache(s) - not done yet (requires
;sorting of Wimp_ClaimFreeMemory)
[ ARM810support
BL AMB_cachecleanflush_ifARM810
;
[ AMB_LimpidFreePool
;can avoid cache clean/flush for moving pages out from FreePool, since FreePool pages are uncacheable
;
TST r3, #DynAreaFlags_NotCacheable ;test PPL of 1st page for not cacheable bit set
BEQ AMB_smme_mapnotlimpid ;if clear, must do full map somewhere with cache clean/flush
;
;this should be map FreePool -> App Space then
;
MOV r0,r4 ;address of 1st page
MOV r1,r8 ;number of pages
MOV r3,#0
ARMop MMU_ChangingUncachedEntries,,,r3 ;no cache worries, hoorah
MOV r3,r5
BL AMB_movepagesout_L2PT ;unmap 'em from where they are
BL AMB_movepagesin_L2PT ;map 'em to where they now be
BL AMB_movepagesin_CAM ;keep the bloomin' soft CAM up to date
Pull "r0-r4,r7-r11, pc"
AMB_smme_mapnotlimpid
]
;
MOV r0,r4 ;address of 1st page
MOV r1,r8 ;number of pages
MOV r3,#0
ARMop MMU_ChangingEntries,,,r3 ;
MOV r3,r5
BL AMB_movepagesout_L2PT
BL AMB_movepagesin_L2PT
BL AMB_movepagesin_CAM
B AMB_smme_cachecleanflush ;needed because of the map out from source
Pull "r0-r4,r7-r11, pc"
;all pages sourced from same old logical page 'nowhere'
;all pages sourced from same old logical page Nowhere, ie. pages currently mapped out, no cache worries
;
AMB_smme_mapin
MOV r0,r4 ;address of 1st page
MOV r1,r8 ;number of pages
MOV r3,#0
ARMop MMU_ChangingUncachedEntries,,,r3 ;TLB coherency, possibly not needed (TLBs shouldn't cache 0 entries)
MOV r3,r5
BL AMB_movepagesin_L2PT
BL AMB_movepagesin_CAM
;don't need to flush cache at end of mapin (already coherent, since
;nothing mapped in before), but do need to flush TLB (eg. TLB will cache
;access denial for app space after mapout)
B AMB_smme_TLBflush
Pull "r0-r4,r7-r11, pc"
;all pages destined for same new logical page 'nowhere'
;all pages destined for same new logical page Nowhere, ie. mapping them out
;
AMB_smme_mapout
[ ARM810support
BL AMB_cachecleanflush_ifARM810
]
MOV r0,r4 ;address of 1st page
MOV r1,r8 ;number of pages
MOV r3,#0
ARMop MMU_ChangingEntries,,,r3 ;
LDR r3,=DuffEntry
BL AMB_movepagesout_L2PT
BL AMB_movepagesout_CAM
;(clean and) flush cache(s) appropriately, then flush TLB(s)
AMB_smme_cachecleanflush
ARM_read_ID r0
AND r0,r0,#&F000
[ ARM810support
CMP r0,#&8000 ;cache clean/flush done before remapping if ARM810
ARM8_flush_TLB EQ
Pull "r0-r4,r7-r11, pc",EQ
]
CMP r0,#&A000
BEQ AMB_smme_cachecleanflush_strongarm
MOV r11, #0
ARMop MMU_Changing,,,r11
AMB_smme_exit
Pull "r0-r4,r7-r11, pc"
AMB_smme_cachecleanflush_strongarm
;we have a StrongARM then
[ AMB_LazyMapIn
; ----------------------------------------------------------------------------------
;
; AMB_SetMemMapEntries_SparseMapOut:
;
;here, r4 = old logical addr. of 1st page, r8 = no. of pages
;
;StrongARM lets us clean data cache (DC) after remapping, because it writes back by
;physical address.
; entry:
; R3 = no. of pages currently mapped in (0=none)
; R4 -> list of page entries (1 word per entry, giving page no.)
; R5 -> bitmap of pages mapped in (1 bit per page in whole page list)
; R6 = total no. of pages in slot
;
MOV r0,r4 ;r0 := start address for clean/flush
ADD r1,r0,r8,LSL #Log2PageSize ;r1 := end address for clean/flush (exclusive)
AMB_SetMemMapEntries_SparseMapOut ROUT
;Cleaning a sufficiently small space by range will be quicker, because of the fixed
;memory reading cost for a full DC clean. A sufficiently large space will be better handled
;by full clean, because of the huge number of clean/flush line instructions for the range
;case. We use a threshold to switch between the two schemes. The value of the threshold
;depends on memory speed, core speed etc. but is not particularly critical.
CMP r3,#0
MOVEQ pc,lr
Push "r0-r11,lr"
SUB r2,r1,r0
CMP r2,#AMB_ARMA_CleanRange_thresh
BLO AMB_smme_StrongARM_flushrange
MOV r10,r4 ;ptr to page list
MOV r7,#0
LDR r7,[r7,#CamEntriesPointer] ;r7 -> CAM
LDR lr,=L2PT ;lr -> L2PT
MOV r9,#AP_Duff ;permissions for DuffEntry
LDR r1,=DuffEntry ;means Nowhere, in CAM
MOV r4,#ApplicationStart ;log. address of first page
MOV r2,#0 ;r2 is zero during sparse map out
;if the number of pages mapped in is small enough, we'll do cache/TLB coherency on
;just those pages, else global (performance decision, threshold probably not critical)
ARMop Cache_RangeThreshold,,,r2 ;returns threshold (bytes) in r0
CMP r3,r0,LSR #Log2PageSize
MOVLO r6,#0 ;r6 := 0 if we are to do coherency as we go
BLO %FT10 ;let's do it
Push "lr" ;global coherency
ARMop MMU_Changing,,,r2
Pull "lr"
B %FT10
;skip next 32 pages then continue
06
ADD r10,r10,#32*4
ADD r4,r4,#32*PageSize
;find the sparsely mapped pages, map them out, doing coherency as we go if enabled
10
MOV r8,#1 ;initial bitmap mask for new bitmap word
LDR r11,[r5],#4 ;next word of bitmap
CMP r11,#0 ;if next 32 bits of bitmap clear, skip
BEQ %BT06 ;skip loop must terminate if r3 > 0
12
TST r11,r8 ;page is currently mapped in if bit set
BEQ %FT16
TEQ r6, #0
BNE %FT14 ;check for coherency as we go
Push "lr"
MOV r0,r4 ;address of page
ARMop MMU_ChangingEntry,,,r2
Pull "lr"
14
LDR r0,[r10] ;page no.
ADD r0,r7,r0,LSL #3 ;r0 -> CAM entry for page
STMIA r0,{r1,r9} ;CAM entry for page set to DuffEntry,AP_Duff
STR r2,[lr,r4,LSR #(Log2PageSize-2)] ;L2PT entry for page set to 0 (means translation fault)
SUBS r3,r3,#1
STREQ r2,[r5,#-4] ;make sure we clear last word of bitmap, and...
BEQ %FT20 ;done
16
ADD r10,r10,#4 ;next page no.
ADD r4,r4,#PageSize ;next logical address
MOVS r8,r8,LSL #1 ;if 32 bits processed...
BNE %BT12
STR r2,[r5,#-4] ;zero word of bitmap we've just traversed (r2 is 0)
B %BT10
MOV r2,#ARMA_Cleaner_flipflop
LDR r1,[r2]
EOR r1,r1,#16*1024
STR r1,[r2]
ARMA_clean_DC r1,r2,r3 ;effectively, fully clean/flush wrt non-interrupt stuff
ARMA_drain_WB
ARMA_flush_IC WithoutNOPs ;do *not* flush DC - may be interrupt stuff in it
MOV r0,r0 ;NOPs to ensure 4 instructions after IC flush before return
MOV r0,r0
ARMA_flush_TLBs
Pull "r0-r4,r7-r11, pc"
20
Pull "r0-r11,pc"
AMB_smme_StrongARM_flushrange
[ SAcleanflushbroken ; ARMA_cleanflush_DCentry instruction seems to be ineffective.
01
ARMA_clean_DCentry r0
ARMA_flush_DCentry r0
ADD r0,r0,#32
ARMA_clean_DCentry r0
ARMA_flush_DCentry r0
ADD r0,r0,#32
ARMA_clean_DCentry r0
ARMA_flush_DCentry r0
ADD r0,r0,#32
ARMA_clean_DCentry r0
ARMA_flush_DCentry r0
ADD r0,r0,#32
CMP r0,r1
BLO %BT01 ;loop to clean DC over logical range
|
01
ARMA_cleanflush_DCentry r0
ADD r0,r0,#32
ARMA_cleanflush_DCentry r0
ADD r0,r0,#32
ARMA_cleanflush_DCentry r0
ADD r0,r0,#32
ARMA_cleanflush_DCentry r0
ADD r0,r0,#32
CMP r0,r1
BLO %BT01 ;loop to clean DC over logical range
]
ARMA_drain_WB
ARMA_flush_IC WithoutNOPs
MOV r0,r0 ;NOPs to ensure 4 instructions after IC flush before return
MOV r0,r0
ARMA_flush_TLBs
Pull "r0-r4,r7-r11, pc"
; ----------------------------------------------------------------------------------
;
; AMB_MakeUnsparse
;
; entry: r0 = size of area (at top of current slot) to ensure is not sparsely mapped
;
; action: walk over space involved, to force abort handler fix up to map in any
; pages not already there
;
AMB_MakeUnsparse ROUT
Push "r0-r2,r12,lr"
; Debug AMB,"AMB_MakeUnsparse r0",r0
ADD r0,r0,#PageSize
SUB r0,r0,#1
MOVS r0,r0,LSR #Log2PageSize
BEQ %FT20
MOV r12,#AMBControl_ws
LDR r12,[r12]
CMP r12,#0
BEQ %FT20
LDR r1,AMBMappedInNode
CMP r1,#0
BEQ %FT20
LDR r2,AMBFlags
TST r2,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend
BNE %FT20
[ AMB_ChocTrace
LDR r2,AMBNmakeunsparse
ADD r2,r2,#1
STR r2,AMBNmakeunsparse
]
LDR r2,[r1,#AMBNode_Npages]
; Debug AMB,"AMB_MakeUnsparse pages Npages ",r0,r2
CMP r0,r2
MOVHI r0,r2
SUB lr,r2,r0
MOV lr,lr,LSL #Log2PageSize
ADD lr,lr,#ApplicationStart
; Debug AMB,"AMB_MakeUnsparse MappedInNode addr pages ",r1,lr,r0
10
LDR r2,[lr] ;tends to wash data cache a bit, but this should be called rarely
ADD lr,lr,#PageSize
SUBS r0,r0,#1
BNE %BT10
20
Pull "r0-r2,r12,pc"
AMB_smme_TLBflush
MOV r11,#0
ARMop TLB_InvalidateAll,,,r11
AMB_smme_exit
Pull "r0-r4,r7-r11, pc"
] ;AMB_LazyMapIn
; ************************************************************************
; ----------------------------------------------------------------------------------
;
; AMB_FindMemMapEntries
;
; finds page numbers for pages currently at given logical start address,
......@@ -452,8 +584,6 @@ AMB_smme_exit
; exit:
; buffer at R4 filled in with page numbers
;
; ************************************************************************
AMB_FindMemMapEntries ROUT
Push "r0-r11,lr"
......@@ -497,6 +627,8 @@ AMB_FindMemMapEntries ROUT
BNE %BT30
Pull "r0-r11,pc"
; ----------------------------------------------------------------------------------
;
;AMB_r11topagenum
;entry:
; r0,r1,r2 = lowest addr,highest addr +1,first page no.
......
......@@ -21,22 +21,23 @@
;
; if there is a mapped-in node then recheck which and how many pages it owns
;
; I believe it should only be necessary to
; it is only necessary to:
; 1) reset node's idea of Npages to agree with no. of pages in app space
; 2) find the page numbers for new pages, if Npages has increased
; ie. I believe it is not necessary to recheck page numbers for whole node
; 2) if Npages has increased, find the page numbers for new pages [and update
; the mapped in list, if LazyMapIn]
; ie. page numbers of existing pages are not messed with
;
AMBsrv_memorymoved
AMBsrv_memorymoved ROUT
Push "R3-R6,R12,LR"
MOV R12,#AMBControl_ws
LDR R12,[R12]
CMP R12,#0
Pull "R3-R6,R12,PC",EQ ;AMBControl not initialised yet!
Pull "R3-R6,R12,PC",EQ,^ ;AMBControl not initialised yet!
LDR R4,AMBMappedInNode
CMP R4,#0
Pull "R3-R6,R12,PC",EQ ;done if nothing mapped in
Pull "R3-R6,R12,PC",EQ,^ ;done if nothing mapped in
LDR R3,[R4,#AMBNode_Npages]
......@@ -47,7 +48,12 @@ AMBsrv_memorymoved
CMP R6,R3
STRNE R6,[R4,#AMBNode_Npages] ;update Npages
Pull "R3-R6,R12,PC",LE ;done if Npages same, or shrink
[ AMB_LazyMapIn
Pull "R3-R6,R12,PC",EQ,^ ;done if Npages same
BLT %FT22 ;shrink
|
Pull "R3-R6,R12,PC",LE,^ ;done if Npages same, or shrink
]
MOV R5,#ApplicationStart
ADD R5,R5,R3,LSL #Log2PageSize ;first logical address to find
......@@ -55,7 +61,105 @@ AMBsrv_memorymoved
ADD R4,R4,R3,LSL #2 ;first page number word to use
SUB R3,R6,R3 ;no. of pages to find (grow number)
BL AMB_FindMemMapEntries
Pull "R3-R6,R12,PC"
[ AMB_LazyMapIn
;if Npages has grown, update AMBMappedInNpages and set bits in bitmap for
;new pages, since these will be mapped in.
;
; Debug AMB,"AMBsrv +Npages ",R3
[ AMB_ChocTrace
LDR R5,AMBNmemmovegrow
ADD R5,R5,#1
STR R5,AMBNmemmovegrow
]
LDR R5,AMBFlags
TST R5,#AMBFlag_LazyMapIn_disable :OR AMBFlag_LazyMapIn_suspend
BNE %FT21
LDR R5,AMBMappedInNpages
ADD R5,R5,R3
STR R5,AMBMappedInNpages
LDR R4,AMBMappedInNode
LDR R5,[R4,#AMBNode_Npages]
SUB R5,R5,R3
ADR R6,AMBMappedInRegister
ADD R6,R6,R5,LSR #5-2 ;first word of bitmap affected
BIC R6,R6,#3
AND R5,R5,#31 ;first bit of word
MOV R4,#1
MOV R5,R4,LSL R5 ;bitmap mask
LDR R4,[R6],#4
10
ORR R4,R4,R5
SUBS R3,R3,#1
STREQ R4,[R6,#-4]
BEQ %FT20
MOVS R5,R5,LSL #1
BNE %BT10
STR R4,[R6,#-4]
MOV R4,#-1
12
CMP R3,#32
BLT %FT14
STR R4,[R6],#4
SUBS R3,R3,#32
BEQ %FT20
B %BT12
14
MOV R5,#1
LDR R4,[R6],#4
B %BT10
20
21
Pull "R3-R6,R12,PC",,^
22
SUB R3,R3,R6 ;no. of pages removed from app space (known unsparse before removal)
; Debug AMB,"AMBsrv -Npages ",R3
[ AMB_ChocTrace
LDR R5,AMBNmemmoveshrink
ADD R5,R5,#1
STR R5,AMBNmemmoveshrink
]
LDR R5,AMBFlags
TST R5,#AMBFlag_LazyMapIn_disable :OR AMBFlag_LazyMapIn_suspend
BNE %FT41
LDR R5,AMBMappedInNpages
SUB R5,R5,R3
STR R5,AMBMappedInNpages
LDR R4,AMBMappedInNode
LDR R5,[R4,#AMBNode_Npages]
ADR R6,AMBMappedInRegister
ADD R6,R6,R5,LSR #5-2 ;first word of bitmap affected
BIC R6,R6,#3
AND R5,R5,#31 ;first bit of word
MOV R4,#1
MOV R5,R4,LSL R5 ;bitmap mask
LDR R4,[R6],#4
30
BIC R4,R4,R5
SUBS R3,R3,#1
STREQ R4,[R6,#-4]
BEQ %FT40
MOVS R5,R5,LSL #1
BNE %BT30
STR R4,[R6,#-4]
MOV R4,#0
32
CMP R3,#32
BLT %FT34
STR R4,[R6],#4
SUBS R3,R3,#32
BEQ %FT40
B %BT32
34
MOV R5,#1
LDR R4,[R6],#4
B %BT30
40
41
] ;AMB_LazyMapIn
Pull "R3-R6,R12,PC",,^
;Service_PagesSafe
......@@ -65,17 +169,17 @@ AMBsrv_memorymoved
;
; action: fix-up page numbers in page lists of nodes as necessary
;
AMBsrv_pagessafe
AMBsrv_pagessafe ROUT
Push "R0-R1,R5-R10,R12,LR"
MOV R12,#AMBControl_ws
LDR R12,[R12]
CMP R12,#0
Pull "R0-R1,R5-R10,R12,PC",EQ ;AMBControl not initialised yet!
Pull "R0-R1,R5-R10,R12,PC",EQ,^ ;AMBControl not initialised yet!
LDR R0,AMBNtasks
CMP R0,#0
Pull "R0-R1,R5-R10,R12,PC",EQ ;no nodes to check
Pull "R0-R1,R5-R10,R12,PC",EQ,^ ;no nodes to check
;speed-up - list of pages tends to span a narrow range of page numbers, so
; use min,max limits to skip search
......@@ -136,7 +240,7 @@ AMBsrv_pagessafe
LDR R0,[R0,#AMBNode_next]
CMP R0,R1 ;done if back at anchor node
BNE %BT01
Pull "R0-R1,R5-R10,R12,PC"
Pull "R0-R1,R5-R10,R12,PC",,^
END
......@@ -38,6 +38,27 @@ shrinkpages
MOVEQ R3,#1 ;flag this is the mapped-in node
MOVNE R3,#0 ;flag is not
[ AMB_LazyMapIn
;first make sure the current mapping of mapped in node is simple,
;so that main mapping can cope - easiest thing is to do a sparse map out
;
BNE %FT02
Push "R3,R6"
LDR R3,AMBFlags
TST R3,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend
BNE %FT01
LDR R3,AMBMappedInNpages
ADD R4,R5,#AMBNode_pages
LDR R6,[R5,#AMBNode_Npages]
ADR R5,AMBMappedInRegister
BL AMB_SetMemMapEntries_SparseMapOut
MOV R3,#0
STR R3,AMBMappedInNpages
01
Pull "R3,R6"
02
]
TST R3,#1 ;check flag
MOVEQ R1,#0 ;source is not App space
LDRNE R1,=AppSpaceDANode ;source is App space
......@@ -73,7 +94,8 @@ shrinkpages
STRNE R0,[R5,#MemLimit] ;update MemLimit
02
STRVS R0,[SP]
;;; STRVS R0,[SP]
CLRV
Pull "R0-R7,PC"
......
......@@ -187,6 +187,13 @@ Analyse_ARMv3
STR a2, [v6, #Proc_MMU_ChangingEntry]
STR a3, [v6, #Proc_MMU_ChangingUncached]
STR a4, [v6, #Proc_MMU_ChangingUncachedEntry]
ADR a1, MMU_ChangingEntries_ARMv3
ADR a2, MMU_ChangingUncachedEntries_ARMv3
ADR a3, Cache_RangeThreshold_ARMv3
STR a1, [v6, #Proc_MMU_ChangingEntries]
STR a2, [v6, #Proc_MMU_ChangingUncachedEntries]
STR a3, [v6, #Proc_Cache_RangeThreshold]
B %FT90
Analyse_WriteThroughUnified
......@@ -215,6 +222,13 @@ Analyse_WriteThroughUnified
STR a2, [v6, #Proc_MMU_ChangingEntry]
STR a3, [v6, #Proc_MMU_ChangingUncached]
STR a4, [v6, #Proc_MMU_ChangingUncachedEntry]
ADR a1, MMU_ChangingEntries_Writethrough
ADR a2, MMU_ChangingUncachedEntries
ADR a3, Cache_RangeThreshold_Writethrough
STR a1, [v6, #Proc_MMU_ChangingEntries]
STR a2, [v6, #Proc_MMU_ChangingUncachedEntries]
STR a3, [v6, #Proc_Cache_RangeThreshold]
B %FT90
90
......@@ -371,10 +385,37 @@ MMU_ChangingEntry_ARMv3
MCR p15, 0, a1, c6, c0 ; invalidate TLB entry
MOV pc, lr
MMU_ChangingEntries_ARMv3 ROUT
Push "a2"
MCR p15, 0, a1, c7, c0 ; invalidate cache
10
MCR p15, 0, a1, c6, c0 ; invalidate TLB entry
SUBS a2, a2, #1 ; next page
ADD a1, a1, #PageSize
BNE %BT10
Pull "a2"
MOV pc, lr
MMU_ChangingUncachedEntry_ARMv3
MCR p15, 0, a1, c6, c0 ; invalidate TLB entry
MOV pc, lr
MMU_ChangingUncachedEntries_ARMv3 ROUT
Push "a2"
10
MCR p15, 0, a1, c6, c0 ; invalidate TLB entry
SUBS a2, a2, #1 ; next page
ADD a1, a1, #PageSize
BNE %BT10
Pull "a2"
MOV pc, lr
Cache_RangeThreshold_ARMv3
! 0, "arbitrary Cache_RangeThreshold_ARMv3"
MOV a1, #16*PageSize
MOV pc, lr
Cache_InvalidateUnified
MOV a1, #0
MCR p15, 0, a1, c7, c7
......@@ -422,10 +463,36 @@ MMU_ChangingEntry_Writethrough
Pull "a4"
MOV pc, lr
MMU_ChangingEntries_Writethrough ROUT
Push "a2,a4"
MOV a4, #0
MCR p15, 0, a4, c7, c7 ; invalidate cache
10
MCR p15, 0, a1, c8, c7, 1 ; invalidate TLB entry
SUBS a2, a2, #1 ; next page
ADD a1, a1, #PageSize
BNE %BT10
Pull "a2,a4"
MOV pc, lr
MMU_ChangingUncachedEntry
MCR p15, 0, a1, c8, c7, 1 ; invalidate TLB entry
MOV pc, lr
MMU_ChangingUncachedEntries ROUT
Push "a2"
10
MCR p15, 0, a1, c8, c7, 1 ; invalidate TLB entry
SUBS a2, a2, #1 ; next page
ADD a1, a1, #PageSize
BNE %BT10
Pull "a2"
MOV pc, lr
Cache_RangeThreshold_Writethrough
! 0, "arbitrary Cache_RangeThreshold_Writethrough"
MOV a1, #16*PageSize
MOV pc, lr
; IMPORT Write0_Translated
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment