Commit 1f84ad9f authored by Jeffrey Lee's avatar Jeffrey Lee Committed by ROOL

Allow reservation of memory pages

This change adds a new OS_Memory reason code, 23, for reserving memory
without actually assigning it to a dynamic area. Other dynamic areas can
still use the memory, but only the code that reserved it will be allowed
to claim exclusive use over it (i.e. PageFlags_Unavailable).

This is useful for systems such as the PCI heap, where physically
contiguous memory is required, but the memory isn't needed all of the
time. By reserving the pages, it allows other regular DAs to make use of
the memory when the PCI heap is small. But when the PCI heap needs to
grow, it guarantees that (if there's enough free memory in the system)
the previously reserved pages can be allocated to the PCI heap.

Notes:

* Reservations are handled on an honour system; there's no checking that
the program that reserved the memory is the one attempting to map it in.

* For regular NeedsSpecificPages DAs, reserved pages can only be used if
the special "RESV" R0 return value is used.

* For PMP DAs, reserved pages can only be made Unavailable if the entry
in the page block also specifies the Reserved page flag. The actual
state of the Reserved flag can't be modified via PMP DA ops, the flag is
only used to indicate the caller's permission/intent to make the page
Unavailable.

* If a PMP DA tries to make a Reserved page Unavailable without
specifying the Reserved flag, the kernel will try to swap it out for a
replacement page taken from the free pool (preserving the contents and
generating Service_PagesUnsafe / Service_PagesSafe, as if another DA
had claimed the page)

Version 6.28. Tagged as 'Kernel-6_28'
parent a52c5049
......@@ -9,12 +9,12 @@
GBLS Module_ApplicationDate
GBLS Module_HelpVersion
GBLS Module_ComponentName
Module_MajorVersion SETS "6.27"
Module_Version SETA 627
Module_MajorVersion SETS "6.28"
Module_Version SETA 628
Module_MinorVersion SETS ""
Module_Date SETS "19 Nov 2019"
Module_ApplicationDate SETS "19-Nov-19"
Module_ComponentName SETS "Kernel"
Module_FullVersion SETS "6.27"
Module_HelpVersion SETS "6.27 (19 Nov 2019)"
Module_FullVersion SETS "6.28"
Module_HelpVersion SETS "6.28 (19 Nov 2019)"
END
/* (6.27)
/* (6.28)
*
* This file is automatically maintained by srccommit, do not edit manually.
*
*/
#define Module_MajorVersion_CMHG 6.27
#define Module_MajorVersion_CMHG 6.28
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 19 Nov 2019
#define Module_MajorVersion "6.27"
#define Module_Version 627
#define Module_MajorVersion "6.28"
#define Module_Version 628
#define Module_MinorVersion ""
#define Module_Date "19 Nov 2019"
......@@ -16,6 +16,6 @@
#define Module_ComponentName "Kernel"
#define Module_FullVersion "6.27"
#define Module_HelpVersion "6.27 (19 Nov 2019)"
#define Module_LibraryVersionInfo "6:27"
#define Module_FullVersion "6.28"
#define Module_HelpVersion "6.28 (19 Nov 2019)"
#define Module_LibraryVersionInfo "6:28"
......@@ -83,7 +83,8 @@ CP_CB_AlternativeDCache * 4 ; Use XScale/SA11x0 mini-data ca
;
; N.B. not all public flags are writable.
;
PageFlags_Unavailable * 1 :SHL: 15 ; physical page has been claimed by someone for exclusive use (can't be requested by PreGrow handler or PMP PhysOp page list)
PageFlags_Reserved * 1 :SHL: 7 ; physical page has been reserved for future use. It can still be allocated to arbitrary DAs, but only the program that reserved it can claim it for exclusive use (PageFlags_Unavailable)
PageFlags_Unavailable * 1 :SHL: 15 ; physical page has been claimed by someone for exclusive use (can't be requested by PreGrow handler or PMP PhysOp page list)
; Dynamic area handler reason codes
......@@ -96,6 +97,8 @@ DAHandler_TestShrink * 4 ; Shrinkable DAs: Find abount can shrink
DAHandler_Abort * 5 ; ROL abortable DAs
DAHandler_ResizePMP * 6 ; PMP DAs: Called on OS_ChangeDynamicArea
DAHandler_RESV * &56534552 ; "RESV" magic value for use by PreGrow handlers
; OS_Memory reason codes
OSMemReason_Convert * 0 ; Convert PA <-> LA <-> PN, alter cacheability
......@@ -114,6 +117,7 @@ OSMemReason_DMAPrep * 19 ; Convert PA <-> LA, perform cache maint
OSMemReason_Compatibility * 20 ; Get/set compatibility settings
OSMemReason_MapIO64Permanent * 21 ; Map in IO area from 64-bit space
OSMemReason_AccessPhysAddr64 * 22 ; Temporarily map in 64-bit phys addr
OSMemReason_ReservePages * 23 ; Reserve (or un-reserve) pages
OSMemReason_CheckMemoryAccess * 24 ; Return attributes/permissions for a logical address range
; OS_Memory 17/18 permission flags
......
......@@ -512,6 +512,9 @@ AMB_LazyFixUp ROUT
LDR r5,[r5,#CamEntriesPointer]
ADD r5,r5,r3,LSL #CAM_EntrySizeLog2 ;r5 -> CAM entry affected
MOVS r0,r0,LSL #Log2PageSize ;address is now ordinary again, and must be non-zero
LDR r12,[r5,#CAM_PageFlags]
AND r12,r12,#StickyPageFlags
ORR r1,r1,r12
ASSERT CAM_LogAddr=0
ASSERT CAM_PageFlags=4
STMIA r5,{r0,r1} ;update CAM entry
......@@ -674,11 +677,19 @@ AMB_movepagesin_L2PT ROUT
;exit: $reg = addr of CAM entry
;
MACRO
UpdateCAM $reg
UpdateCAM $reg,$temp
ADD $reg,r11,$reg,LSL #CAM_EntrySizeLog2 ;r0 -> CAM entry for 1st page
LDR $temp,[$reg,#CAM_PageFlags]
AND $temp,$temp,#StickyPageFlags
ORR $temp,$temp,lr
[ $temp > r9
ASSERT CAM_LogAddr=0
ASSERT CAM_PageFlags=4
STMIA $reg,{r9,lr} ;store logical addr,PPL
STMIA $reg,{r9,$temp} ;store logical addr,PPL
|
STR r9,[$reg,#CAM_LogAddr]
STR $temp,[$reg,#CAM_PageFlags]
]
MEND
; ----------------------------------------------------------------------------------
......@@ -694,10 +705,10 @@ AMB_movepagesin_L2PT ROUT
; r10 -> page list
;
AMB_movepagesin_CAM ROUT
Entry "r0-r11"
Entry "r0-r12"
MOV lr,r9
BIC lr,r9,#StickyPageFlags
MOV r9,r3
LDR r11,=ZeroPage
LDR r11,[r11,#CamEntriesPointer] ;r11 -> CAM
......@@ -706,21 +717,21 @@ AMB_movepagesin_CAM ROUT
BLT %FT20
10
LDMIA r10!,{r0-r7} ;next 8 page numbers
UpdateCAM r0
UpdateCAM r0,r12
ADD r9,r9,#PageSize ;next logical addr
UpdateCAM r1
UpdateCAM r1,r12
ADD r9,r9,#PageSize
UpdateCAM r2
UpdateCAM r2,r12
ADD r9,r9,#PageSize
UpdateCAM r3
UpdateCAM r3,r12
ADD r9,r9,#PageSize
UpdateCAM r4
UpdateCAM r4,r12
ADD r9,r9,#PageSize
UpdateCAM r5
UpdateCAM r5,r12
ADD r9,r9,#PageSize
UpdateCAM r6
UpdateCAM r6,r12
ADD r9,r9,#PageSize
UpdateCAM r7
UpdateCAM r7,r12
ADD r9,r9,#PageSize
SUB r8,r8,#8
CMP r8,#8
......@@ -730,7 +741,7 @@ AMB_movepagesin_CAM ROUT
EXIT EQ
30
LDR r0,[r10],#4
UpdateCAM r0
UpdateCAM r0,r12
ADD r9,r9,#PageSize
SUBS r8,r8,#1
BNE %BT30
......@@ -748,9 +759,9 @@ AMB_movepagesin_CAM ROUT
; r10 -> page list
;
AMB_movepagesout_CAM ROUT
Entry "r0-r11"
Entry "r0-r12"
MOV lr,r9
BIC lr,r9,#StickyPageFlags
LDR r9,=DuffEntry
LDR r11,=ZeroPage
LDR r11,[r11,#CamEntriesPointer] ;r11 -> CAM
......@@ -759,14 +770,14 @@ AMB_movepagesout_CAM ROUT
BLT %FT20
10
LDMIA r10!,{r0-r7} ;next 8 page numbers
UpdateCAM r0
UpdateCAM r1
UpdateCAM r2
UpdateCAM r3
UpdateCAM r4
UpdateCAM r5
UpdateCAM r6
UpdateCAM r7
UpdateCAM r0,r12
UpdateCAM r1,r12
UpdateCAM r2,r12
UpdateCAM r3,r12
UpdateCAM r4,r12
UpdateCAM r5,r12
UpdateCAM r6,r12
UpdateCAM r7,r12
SUB r8,r8,#8
CMP r8,#8
BGE %BT10
......@@ -775,7 +786,7 @@ AMB_movepagesout_CAM ROUT
EXIT EQ
30
LDR r0,[r10],#4
UpdateCAM r0
UpdateCAM r0,r12
SUBS r8,r8,#1
BNE %BT30
EXIT
......
......@@ -71,9 +71,13 @@ BangCamUpdate ROUT
ASSERT CAM_LogAddr=0
ASSERT CAM_PageFlags=4
LDMIA r1, {r0, r6} ; r0 = current logaddress, r6 = current PPL
Push "r0, r6" ; save old logical address, PPL
BIC r4, r11, #PageFlags_Unsafe
BIC r4, r4, #StickyPageFlags
AND r6, r6, #StickyPageFlags
ORR r4, r4, r6
STMIA r1, {r3, r4} ; store new address, PPL
Push "r0, r6" ; save old logical address, PPL
LDR r1, =ZeroPage+PhysRamTable ; go through phys RAM table
MOV r6, r2 ; make copy of r2 (since that must be preserved)
10
......
This diff is collapsed.
......@@ -73,7 +73,7 @@ MemReturn
B ChangeCompatibility ; 20
B MapIO64permanent ; 21
B AccessPhysAddr64 ; 22
B %BT20 ; 23 reserved for us
B ReservePages ; 23
B CheckMemoryAccess ; 24
; 25+ reserved for ROL
40
......@@ -622,6 +622,7 @@ MemoryReadPhys ROUT
BCC %FT30
LDR lr, [r7, r5, LSL #CAM_EntrySizeLog2] ; Page is there so get PPL and determine if it's available or not.
TST lr, #PageFlags_Unavailable
TSTEQ lr, #PageFlags_Reserved
ORREQ r3, r3, #DRAM_Pattern :SHL: 28
ORRNE r3, r3, #(DRAM_Pattern :OR: NotAvailable) :SHL: 28
ADD r5, r5, #1 ; Increment page count.
......@@ -872,10 +873,11 @@ RP_nextchunk
;find first available page
RP_nextpage
CMP r9,r1
BLO RP_nextchunk
BLO RP_nextchunk ;not enough pages left in chunk
LDR r6,[r5,r7,LSL #CAM_EntrySizeLog2] ;page flags from CAM
;must not be marked Unavailable or Required
TST r6,#PageFlags_Unavailable :OR: PageFlags_Required
TSTEQ r6,#PageFlags_Reserved
BEQ RP_checkotherpages
RP_nextpagecontinue
CMP r9,r4
......@@ -890,6 +892,7 @@ RP_checkotherpages
RP_checkotherpagesloop
LDR r6,[r5,r10,LSL #CAM_EntrySizeLog2] ;page flags from CAM
TST r6,#PageFlags_Unavailable :OR: PageFlags_Required
TSTEQ r6,#PageFlags_Reserved
BNE RP_nextpagecontinue
SUB r10,r10,#1
CMP r10,r7
......@@ -1849,6 +1852,93 @@ ChangeCompatibility ROUT
30
]
;----------------------------------------------------------------------------------------
;
; In: r0 = flags
; bit meaning
; 0-7 23 (reason code)
; 8 0 = reserve, 1 = release reservation
; 9-31 reserved (set to 0)
; r1 = base page number
; r2 = page count
;
; Attempts to reserve (or remove the reservation) on a range of pages.
; Dynamic areas can still use the memory, but only the code that reserved
; it will be allowed to claim exclusive use over it (i.e. perform an
; action that will cause PageFlags_Unavailable to be set)
;
; This is useful for systems such as the PCI heap, where physically
; contiguous memory is required, but the memory isn't needed all of the
; time. By reserving the pages, it allows other regular DAs to make use
; of the memory when the PCI heap is small. But when the PCI heap needs
; to grow, it guarantees that (if there's enough free memory in the
; system) the previously reserved pages can be allocated to the PCI heap.
;
; Notes:
;
; * Reservations are handled on an honour system; there's no checking
; that the program that reserved the memory is the one attempting to
; mark it Unavailable.
; * For regular NeedsSpecificPages DAs, reserved pages can only be used
; if the special "RESV" R0 return value is used (DAHandler_RESV)
; * For PMP DAs, reserved pages can only be made Unavailable if the entry
; in the page block also specifies the Reserved page flag. The actual
; state of the Reserved flag can't be modified via PMP DA ops; the flag
; is only used to indicate the caller's permission/intent to make an
; already Reserved page Unavailable.
; * If a PMP DA tries to make a Reserved page Unavailable without
; specifying the Reserved flag, the kernel will try to swap it out for
; a replacement page taken from the free pool (preserving the contents
; and generating Service_PagesUnsafe / Service_PagesSafe, as if another
; DA had claimed the page)
;
ReservePages ROUT
Entry "r1-r5"
LDR r3, =ZeroPage+CamEntriesPointer
LDR r4, [r3, #MaxCamEntry-CamEntriesPointer]
LDR r3, [r3]
SUBS r4, r4, r1
SUBHSS r4, r4, r2
BLO %FT90
ADD r3, r3, #CAM_PageFlags
ADD r3, r3, r1, LSL #CAM_EntrySizeLog2
MOV r5, r3
TST r0, #1:SHL:8
BEQ %FT20
10
SUBS r2, r2, #1
EXIT LO
LDR r4, [r5]
BIC r4, r4, #PageFlags_Reserved
STR r4, [r5], #CAM_EntrySize
B %BT10
20
SUBS r2, r2, #1
EXIT LO
LDR r4, [r5]
TST r4, #PageFlags_Unavailable ; If already claimed
TSTEQ r4, #PageFlags_Reserved ; Or already reserved
BNE %FT30 ; Then complain
ORR r4, r4, #PageFlags_Reserved
STR r4, [r5], #CAM_EntrySize
B %BT20
30
CMP r3, r5
LDRNE r4, [r3]
BICNE r4, r4, #PageFlags_Reserved ; Remove reservations we just added
STRNE r4, [r3], #CAM_EntrySize
BNE %BT30
ADRL r0, ErrorBlock_CantGetPhysMem
SETV
EXIT
90
ADRL r0, ErrorBlock_BadParameters
SETV
EXIT
;----------------------------------------------------------------------------------------
;
; In: r0 = flags
......
......@@ -78,9 +78,13 @@ BangCamUpdate ROUT
ASSERT CAM_LogAddr=0
ASSERT CAM_PageFlags=4
LDMIA r1, {r0, r6} ; r0 = current logaddress, r6 = current PPL
Push "r0, r6" ; save old logical address, PPL
BIC r4, r11, #PageFlags_Unsafe
BIC r4, r4, #StickyPageFlags
AND r6, r6, #StickyPageFlags
ORR r4, r4, r6
STMIA r1, {r3, r4} ; store new address, PPL
Push "r0, r6" ; save old logical address, PPL
LDR r1, =ZeroPage+PhysRamTable ; go through phys RAM table
MOV r6, r2 ; make copy of r2 (since that must be preserved)
10
......
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