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)"
......@@ -1171,18 +1171,21 @@ ProcessorArch # 1
AlignSpace
Proc_Cache_CleanInvalidateAll # 4
Proc_Cache_CleanAll # 4
Proc_Cache_InvalidateAll # 4
Proc_TLB_InvalidateAll # 4
Proc_TLB_InvalidateEntry # 4
Proc_WriteBuffer_Drain # 4
Proc_IMB_Full # 4
Proc_IMB_Range # 4
Proc_MMU_Changing # 4
Proc_MMU_ChangingEntry # 4
Proc_MMU_ChangingUncached # 4
Proc_MMU_ChangingUncachedEntry # 4
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
Proc_IMB_Full # 4
Proc_IMB_Range # 4
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
;maximum logical space size cleaned by range strategy
;
AMB_ARMA_CleanRange_thresh * 256*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)
]
GBLL ValidateAMBHandles ; whether to check handles given to AppMAMBan
;whether to check handles given to AMBControl - not very useful when in kernel
;
GBLL ValidateAMBHandles
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
^ 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
^ 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
;ptr to node handle array (1 word per entry)
AMBNodeHandles # 4
;ptr to physical page bin array
AMBPhysBin # 4
AMBPhysBinEntries # 4
;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)
AMBmaxwork * :INDEX:@
;
;task node format
;
^ 0
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
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)
[ 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)
;
]
;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).
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
......@@ -102,13 +104,12 @@ gs_done
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 R4,R2 ;so we can check for moved block
MOV R0,#ModHandReason_ExtendBlock
BL XROS_Module
MOVVS R2,R4 ;in case block ptr not preserved on error
BEQ grwshrn_free ;shrunk to nothing
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
BL AMB_BlockResize
MOVVS R2,R4 ;in case block ptr not preserved on error
BVS grwshrn_done
;fix-up links if block has moved
CMP R4,R2
......@@ -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,28 +13,36 @@
; 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
;;; BVS err_cantclaim - this should not happen
;don't store ws pointer till end of initialise - service routines must
;know when initialise is not yet complete
;
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
;;; BVS err_cantclaim
STR R2,AMBNodeHandles
;put all handles on free list (entry 0 is used as hdr of free list)
......@@ -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
......@@ -57,7 +65,7 @@ AMBControl_Init
STR R3,AMBPhysBinEntries
MOV R3,R3,LSL #2 ;1 word per entry
BL ClaimSysHeapNode
;;; BVS err_cantclaim
;;; BVS err_cantclaim
STR R2,AMBPhysBin
;init PhysBin
......@@ -77,22 +85,21 @@ 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
STR R12,[R0] ;now initialisation is complete
Pull "R0-R4,R12,PC"
......@@ -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
......@@ -54,16 +146,16 @@ AMB_movepagesin_L2PT ROUT
CMP r8,#8
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
STMIA r9!,{r0-r7} ;write 8 L2PT entries
LDMIA r10!,{r0-r7} ;next 8 page numbers
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
BGE %BT10
......@@ -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
; ----------------------------------------------------------------------------------
;
;here, r4 = old logical addr. of 1st page, r8 = no. of pages
; AMB_SetMemMapEntries_SparseMapOut:
;
;StrongARM lets us clean data cache (DC) after remapping, because it writes back by
;physical address.
;
MOV r0,r4 ;r0 := start address for clean/flush
ADD r1,r0,r8,LSL #Log2PageSize ;r1 := end address for clean/flush (exclusive)
; 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
;
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