Commit 9cd4cbe4 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Add support for shareable pages and additional access privileges

Detail:
  This set of changes:
  * Refactors page table entry encoding/decoding so that it's (mostly) performed via functions in the MMU files (s.ARM600, s.VMSAv6) rather than on an ad-hoc basis as was the case previously
  * Page table entry encoding/decoding performed during ROM init is also handled via the MMU functions, which resolves some cases where the wrong cache policy was in use on ARMv6+
  * Adds basic support for shareable pages - on non-uniprocessor systems all pages will be marked as shareable (however, we are currently lacking ARMops which broadcast cache maintenance operations to other cores, so safe sharing of cacheable regions isn't possible yet)
  * Adds support for the VMSA XN flag and the "privileged ROM" access permission. These are exposed via RISC OS access privileges 4 and above, taking advantage of the fact that 4 bits have always been reserved for AP values but only 4 values were defined
  * Adds OS_Memory 17 and 18 to convert RWX-style access flags to and from RISC OS access privelege numbers; this allows us to make arbitrary changes to the mappings of AP values 4+ between different OS/hardware versions, and allows software to more easily cope with cases where the most precise AP isn't available (e.g. no XN on <=ARMv5)
  * Extends OS_Memory 24 (CheckMemoryAccess) to return executability information
  * Adds exported OSMem header containing definitions for OS_Memory and OS_DynamicArea
  File changes:
  - Makefile - export C and assembler versions of hdr/OSMem
  - Resources/UK/Messages - Add more text for OS_Memory errors
  - hdr/KernelWS - Correct comment regarding DCacheCleanAddress. Allocate workspace for MMU_PPLTrans and MMU_PPLAccess.
  - hdr/OSMem - New file containing exported OS_Memory and OS_DynamicArea constants, and public page flags
  - hdr/Options - Reduce scope of ARM6support to only cover builds which require ARMv3 support
  - s/AMBControl/Workspace - Clarify AMBNode_PPL usage
  - s/AMBControl/growp, mapslot, mapsome, memmap - Use AreaFlags_ instead of AP_
  - s/AMBControl/main, memmap - Use GetPTE instead of generating page table entry manually
  - s/ARM600 - Remove old coments relating to lack of stack. Update BangCam to use GetPTE. Update PPL tables, removing PPLTransL1 (L1 entries are now derived from L2 table on demand) and adding a separate table for ARM6. Implement the ARM600 versions of the Get*PTE ('get page table entry') and Decode*Entry functions
  - s/ARMops - Add Init_PCBTrans function to allow relevant MMU_PPLTrans/MMU_PCBTrans pointers to be set up during the pre-MMU stage of ROM init. Update ARM_Analyse to set up the pointers that are used post MMU init.
  - s/ChangeDyn - Move a bunch of flags to hdr/OSMem. Rename the AP_ dynamic area flags to AreaFlags_ to avoid name clashes and confusion with the page table AP_ values exported by Hdr:MEMM.ARM600/Hdr:MEMM.VMSAv6. Also generate the relevant flags for OS_Memory 24 so that it can refer to the fixed areas by their name instead of hardcoding the permissions.
  - s/GetAll - GET Hdr:OSMem
  - s/HAL - Change initial page table setup to use DA/page flags and GetPTE instead of building page table entries manually. Simplify AllocateL2PT by removing the requirement for the user to supply the access perimssions that will be used for the area; instead for ARM6 we just assume that cacheable memory is the norm and set L1_U for any L1 entry we create here.
  - s/Kernel - Add GetPTE macro (for easier integration of Get*PTE functions) and GenPPLAccess macro (for easy generation of OS_Memory 24 flags)
  - s/MemInfo - Fixup OS_Memory 0 to not fail on seeing non-executable pages. Implement OS_Memory 17 & 18. Tidy up some error generation. Make OS_Memory 13 use GetPTE. Extend OS_Memory 24 to return (non-) executability information, to use the named CMA_ constants generated by s/ChangeDyn, and to use the Decode*Entry functions when it's necessary to decode page table entries.
  - s/NewReset - Use AreaFlags_ instead of AP_
  - s/VMSAv6 - Remove old comments relating to lack of stack. Update BangCam to use GetPTE. Update PPL tables, removing PPLTransL1 (L1 entries are now derived from L2 table on demand) and adding a separate table for shareable pages. Implement the VMSAv6 versions of the Get*PTE and Decode*Entry functions.
Admin:
  Tested on Raspberry Pi 1, Raspberry Pi 3, Iyonix, RPCEmu (ARM6 & ARM7), comparing before and after CAM and page table dumps to check for any unexpected differences


Version 5.55. Tagged as 'Kernel-5_55'
parent 72a424b7
......@@ -37,6 +37,7 @@ EXPORTS = ${EXP_HDR}.EnvNumbers \
${EXP_HDR}.HALEntries \
${EXP_HDR}.ModHand \
${EXP_HDR}.OSEntries \
${EXP_HDR}.OSMem \
${EXP_HDR}.OSMisc \
${EXP_HDR}.OSRSI6 \
${EXP_HDR}.PL310 \
......@@ -50,6 +51,7 @@ EXPORTS = ${EXP_HDR}.EnvNumbers \
${C_EXP_HDR}.HALEntries \
${C_EXP_HDR}.ModHand \
${C_EXP_HDR}.OSEntries \
${C_EXP_HDR}.OSMem \
${C_EXP_HDR}.OSMisc \
${C_EXP_HDR}.OSRSI6 \
${C_EXP_HDR}.RISCOS \
......@@ -118,6 +120,9 @@ ${EXP_HDR}.ModHand: hdr.ModHand
${EXP_HDR}.OSEntries: hdr.OSEntries
${CP} hdr.OSEntries $@ ${CPFLAGS}
${EXP_HDR}.OSMem: hdr.OSMem
${CP} hdr.OSMem $@ ${CPFLAGS}
${EXP_HDR}.OSMisc: hdr.OSMisc
${CP} hdr.OSMisc $@ ${CPFLAGS}
......@@ -159,6 +164,10 @@ ${C_EXP_HDR}.ModHand: hdr.ModHand
${C_EXP_HDR}.OSEntries: Global.h.OSEntries h.OSEntries
${FAPPEND} $@ h.OSEntries Global.h.OSEntries
${C_EXP_HDR}.OSMem: hdr.OSMem
${MKDIR} ${C_EXP_HDR}
${HDR2H} hdr.OSMem $@
${C_EXP_HDR}.OSMisc: hdr.OSMisc
${MKDIR} ${C_EXP_HDR}
${HDR2H} hdr.OSMisc $@
......
......@@ -167,6 +167,9 @@ BadKeyHandler:Bad key handler
BadGDriver:Bad graphics driver number
TooManyGDrivers:Too many graphics drivers
BadErrPtr:SWI &%0 returned a bad error pointer
NoMemChunkAvailable:No chunk available
NoRoomForIO:No room for IO space
AccessPrivilegeNotFound:Access privilege not found
600:ARM 600 Processor
610:ARM 610 Processor
......
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.54"
Module_Version SETA 554
Module_MajorVersion SETS "5.55"
Module_Version SETA 555
Module_MinorVersion SETS ""
Module_Date SETS "24 Jul 2016"
Module_ApplicationDate SETS "24-Jul-16"
Module_Date SETS "02 Aug 2016"
Module_ApplicationDate SETS "02-Aug-16"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.54"
Module_HelpVersion SETS "5.54 (24 Jul 2016)"
Module_FullVersion SETS "5.55"
Module_HelpVersion SETS "5.55 (02 Aug 2016)"
END
/* (5.54)
/* (5.55)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 5.54
#define Module_MajorVersion_CMHG 5.55
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 24 Jul 2016
#define Module_Date_CMHG 02 Aug 2016
#define Module_MajorVersion "5.54"
#define Module_Version 554
#define Module_MajorVersion "5.55"
#define Module_Version 555
#define Module_MinorVersion ""
#define Module_Date "24 Jul 2016"
#define Module_Date "02 Aug 2016"
#define Module_ApplicationDate "24-Jul-16"
#define Module_ApplicationDate "02-Aug-16"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.54"
#define Module_HelpVersion "5.54 (24 Jul 2016)"
#define Module_LibraryVersionInfo "5:54"
#define Module_FullVersion "5.55"
#define Module_HelpVersion "5.55 (02 Aug 2016)"
#define Module_LibraryVersionInfo "5:55"
......@@ -277,7 +277,7 @@ SVCStackAddress * &FA200000
ABTStackAddress * &FA300000
UNDStackAddress * &FA400000
PhysicalAccess * &FA500000
DCacheCleanAddress * &FA600000 ; eg. for StrongARM, 256k of space, up to FAF40000
DCacheCleanAddress * &FA600000 ; eg. for StrongARM, 256k of space, up to FA640000
KbuffsBaseAddress * &FA640000 ; kernel buffers for long command lines, size KbuffsMaxSize
HALWorkspaceNCNB * &FA6E8000 ; 32K of uncacheable HAL workspace (if requested)
L2PT * &FA800000
......@@ -1166,7 +1166,9 @@ ProcessorFlags # 4 ; Processor flags (IMB, Arch4 etc)
AlignSpace
MMU_PPLTrans # 4
MMU_PCBTrans # 4
MMU_PPLAccess # 4
Proc_Cache_CleanInvalidateAll # 4
Proc_Cache_CleanInvalidateRange # 4
......
; Copyright 2016 Castle Technology Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; Definitions for OS_DynamicArea, OS_Memory and other related SWIs
; OS_DynamicArea reason codes
DAReason_Create * 0
DAReason_Remove * 1
DAReason_GetInfo * 2
DAReason_Enumerate * 3
DAReason_Renumber * 4
DAReason_ReturnFree * 5
DAReason_GetChangeInfo * 6 ; Internal use only (intended for TaskManager)
DAReason_EnumerateInfo * 7 ; Internal use only (intended for TaskManager)
DAReason_SetClamps * 8
DAReason_SparseClaim * 9
DAReason_SparseRelease * 10
; Reasons 11-19 allocated to ROL
DAReason_LocateAddress * 20
DAReason_PMP_PhysOp * 21
DAReason_PMP_LogOp * 22
DAReason_PMP_Resize * 23
DAReason_PMP_GetInfo * 24
DAReason_PMP_GetPages * 25
DAReason_Limit * 26 ;end of defined DA reasons
; Dynamic area / page flags
DynAreaFlags_APBits * 15 :SHL: 0
DynAreaFlags_NotBufferable * 1 :SHL: 4
DynAreaFlags_NotCacheable * 1 :SHL: 5
DynAreaFlags_DoublyMapped * 1 :SHL: 6
DynAreaFlags_NotUserDraggable * 1 :SHL: 7
DynAreaFlags_NeedsSpecificPages * 1 :SHL: 8 ; whether area will ever require particular physical pages
DynAreaFlags_Shrinkable * 1 :SHL: 9 ; whether area may be shrunk when need more space in free pool
DynAreaFlags_SparseMap * 1 :SHL: 10 ; whether area may have non-contiguous mapping of pages (Holey dynamic areas Batman!)
DynAreaFlags_PiersBinding * 1 :SHL: 11 ; whether area is bound to client application, and so may be swapped out with it (not implemented yet)
DynAreaFlags_CPBits * 7 :SHL: 12 ; cache policy variant for NotBufferable and NotCacheable bits
DynAreaFlags_NeedsDMA * 1 :SHL: 15 ; only allocate from DMAable memory
; Bits 16-19 are used by RISCOS Ltd. We can reuse them for internal flags, but
; should probably avoid allocating any public flags.
DynAreaFlags_PMP * 1 :SHL: 20 ; DA is backed by PMP/page is member of PMP
; Cache policies
;
CP_NCNB_Default * 0 ; no policy variants
CP_NCB_Default * 0 ; OS decides buffer policy (currently always MergingIdempotent)
CP_NCB_NonMerging * 1 ; Non-merging write buffer. If not available, unbuffered.
CP_NCB_Merging * 2 ; Merging write buffer. If not available, non-merging.
CP_NCB_MergingIdempotent * 3 ; Merging write buffer with idempotent memory (i.e. VMSA "Normal" non-cacheable type). If not available, merging write buffer.
CP_CNB_Default * 0 ; OS decides cache policy (writethrough). NCNB if not available
CP_CNB_Writethrough * 1 ; Writethrough cacheable, non-buffered. If not available, NCNB.
CP_CNB_Writeback * 2 ; Writeback cacheable, non-buffered. If not available,CNB_Writethrough.
CP_CB_Default * 0 ; OS decides cache policy (WB if available, W alloc if HAL requests)
CP_CB_Writethrough * 1 ; Writethrough cacheable, read allocate. If not available, NCB_Merging
CP_CB_WritebackReadAlloc * 2 ; Writeback cacheable, read allocate. If not available, writethrough.
CP_CB_WritebackWriteAlloc * 3 ; Writeback cacheable, write allocate. If not available, WB/R.
CP_CB_AlternativeDCache * 4 ; Use XScale/SA11x0 mini-data cache. If not available, CB_Default.
;
; Public page flags (note - may overlap DA flags)
;
; APBits, NotBufferable, NotCacheable, DoublyMapped, CPBits and PMP are the
; DA flags which are also (public) page flags.
;
; 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)
; Dynamic area handler reason codes
DAHandler_PreGrow * 0
DAHandler_PostGrow * 1
DAHandler_PreShrink * 2
DAHandler_PostShrink * 3
DAHandler_TestShrink * 4 ; Shrinkable DAs: Find abount can shrink by
DAHandler_Abort * 5 ; ROL abortable DAs
DAHandler_ResizePMP * 6 ; PMP DAs: Called on OS_ChangeDynamicArea
; OS_Memory reason codes
OSMemReason_Convert * 0 ; Convert PA <-> LA <-> PN, alter cacheability
OSMemReason_PhysSize * 6 ; Return physical memory arrangement table info
OSMemReason_ReadPhys * 7 ; Read physical memory arrangement table
OSMemReason_Amounts * 8 ; Return amounts of various memory types
OSMemReason_IOSpace * 9 ; Return controller presence/base address
OSMemReason_RecommendPage * 12 ; Recommend contiguous pages for DA grow handler
OSMemReason_MapIOPermanent * 13 ; Map in IO area
OSMemReason_AccessPhysAddr * 14 ; Temporarily map in phys addr
OSMemReason_ReleasePhysAddr * 15 ; Release the temp mapping
OSMemReason_MemoryAreaInfo * 16 ; Return size & location of various non-DA areas
OSMemReason_MemoryAccessPrivileges * 17 ; Decode AP numbers into permission flags
OSMemReason_FindAccessPrivilege * 18 ; Find best AP number from given permission flags
OSMemReason_CheckMemoryAccess * 24 ; Return attributes/permissions for a logical address range
; OS_Memory 17/18 permission flags
MemPermission_UserX * 1<<0 ; Executable in user mode
MemPermission_UserW * 1<<1 ; Writable in user mode
MemPermission_UserR * 1<<2 ; Readable in user mode
MemPermission_PrivX * 1<<3 ; Executable in privileged modes
MemPermission_PrivW * 1<<4 ; Writable in privileged modes
MemPermission_PrivR * 1<<5 ; Readable in privileged modes
; OS_Memory 24 (CheckMemoryAccess) flags
CMA_Completely_UserR * 1<<0 ; completely readable in user mode
CMA_Completely_UserW * 1<<1 ; completely writable in user mode
CMA_Completely_PrivR * 1<<2 ; completely readable in privileged modes
CMA_Completely_PrivW * 1<<3 ; completely writable in privileged modes
CMA_Partially_UserR * 1<<4 ; partially readable in user mode
CMA_Partially_UserW * 1<<5 ; partially writable in user mode
CMA_Partially_PrivR * 1<<6 ; partially readable in privileged modes
CMA_Partially_PrivW * 1<<7 ; partially writable in privileged modes
CMA_Completely_Phys * 1<<8 ; completely physically mapped (i.e. IO memory)
CMA_Completely_Abort * 1<<9 ; completely abortable (i.e. custom data abort handler)
CMA_Completely_UserXN * 1<<10 ; completely non-executable in user mode
CMA_Completely_PrivXN * 1<<11 ; completely non-executable in privileged modes
CMA_Partially_Phys * 1<<12 ; partially physically mapped
CMA_Partially_Abort * 1<<13 ; partially abortable
CMA_Partially_UserXN * 1<<14 ; partially non-executable in user mode
CMA_Partially_PrivXN * 1<<15 ; partially non-executable in privileged modes
END
......@@ -84,7 +84,7 @@ SASTMhatbroken SETL SupportARMv4 :LAND: NoARMv5
CacheCleanerHack SETL {TRUE}
InterruptDelay SETL SupportARMv4 :LAND: NoARMv5
ARM6support SETL (MEMM_Type = "ARM600") ; Needs updating for VMSAv6 compatability
ARM6support SETL (MEMM_Type = "ARM600") :LAND: NoARMv4
XScaleMiniCache SETL {FALSE}
XScaleJTAGDebug SETL {TRUE}
......
......@@ -27,7 +27,7 @@ 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_PPL # 4 ;Page flags, as limited by DynAreaFlags_AccessMask
AMBNode_pages # 0 ;list of page numbers from here on (1 word per page)
AMBNode_HdrEnd # 0
;
......
......@@ -77,7 +77,7 @@ growpages ROUT
TST R5,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend
;
MOVEQ R5,#-1 ;map the pages to Nowhere initially
MOVEQ R6,#AP_Duff
MOVEQ R6,#AreaFlags_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
......
......@@ -100,20 +100,10 @@ AMBControl_Init
STR R1,AMBFlags
; Calculate default page flags
LDR r2,=ZeroPage
[ MEMM_Type = "VMSAv6"
ADRL r1,PPLTrans
|
LDR r1, [r2, #ProcessorFlags]
TST r1, #CPUFlag_ExtendedPages
ADREQL r1, PPLTrans
ADRNEL r1, PPLTransX
]
LDR r3,[r1] ; Page type + access flags
LDR r2,[r2,#MMU_PCBTrans]
LDRB r2,[r2] ; Cacheability + other attribs
ORR r3,r3,r2
STR r3,AMBPageFlags
MOV R0, #0
MOV R1, #0
GetPTE R0, 4K, R0, R1
STR R0,AMBPageFlags
|
MOV R1,#AMBFlag_LazyMapIn_disable
STR R1,AMBFlags
......
......@@ -81,7 +81,7 @@ ms_domap
LDREQ R6,=DuffEntry
MOVNE R6,#ApplicationStart
STR R6,[R1,#AMBNode_startaddr]
MOVEQ R6,#AP_Duff
MOVEQ R6,#AreaFlags_Duff
MOVNE R6,#0
STR R6,[R1,#AMBNode_PPL]
......
......@@ -61,7 +61,7 @@ mapsome
ADD R4,R4,R7,LSL #2
MOV R5,R1
CMP R5,#-1
MOVEQ R6,#AP_Duff
MOVEQ R6,#AreaFlags_Duff
MOVNE R6,#0
;entry: R3 = no. of pages, R4 -> list of page entries,
; R5 := start logical address, R6 = PPL
......
......@@ -530,38 +530,16 @@ AMB_SetMemMapEntries ROUT
BEQ AMB_smme_exit
CMP r5,#-1
MOVEQ r9,#AP_Duff ;PPL for mapped out pages
MOVEQ r9,#AreaFlags_Duff ;PPL for mapped out pages
MOVNE r9,r6 ;PPL for mapped in pages
01
;get L2PT protection etc. bits, appropriate to PPL in R9, into R11
ADRL r1,PPLTrans
AND lr,r9,#3
LDR r7,=ZeroPage
LDR r11,[r1,lr,LSL #2]
[ MEMM_Type = "VMSAv6"
; VMSAv6 is tricky, use XCBTable/PCBTrans
ASSERT DynAreaFlags_CPBits = 7*XCB_P :SHL: 10
ASSERT DynAreaFlags_NotCacheable = XCB_NC :SHL: 4
ASSERT DynAreaFlags_NotBufferable = XCB_NB :SHL: 4
LDR r2,[r7,#MMU_PCBTrans]
TST r9,#PageFlags_TempUncacheableBits
AND r1,r9,#DynAreaFlags_NotCacheable + DynAreaFlags_NotBufferable
AND r0,r9,#DynAreaFlags_CPBits
ORRNE r1,r1,#XCB_TU<<4 ; if temp uncache, set TU bit
ORR r1,r1,r0,LSR #10-4
LDRB r1,[r2,r1,LSR #4] ; convert to X, C and B bits for this CPU
ORR r11,r11,r1
|
TST r9,#DynAreaFlags_NotCacheable
TSTEQ r9,#PageFlags_TempUncacheableBits
ORREQ r11,r11,#L2_C ;if cacheable (area bit CLEAR + temp count zero), then OR in C bit
TST r9,#DynAreaFlags_NotBufferable
ORREQ r11,r11,#L2_B ;if bufferable (area bit CLEAR), then OR in B bit
]
MOV r0, #0
GetPTE r11, 4K, r0, r9
LDR r7,=ZeroPage
MOV r10,r4 ;ptr to next page number
LDR r2,[r10] ;page number of 1st page
LDR r7,[r7,#CamEntriesPointer] ;r7 -> CAM
ADD r1,r7,r2,LSL #CAM_EntrySizeLog2 ;r1 -> CAM entry for 1st page
......@@ -624,7 +602,7 @@ AMB_smme_exit
;
; AMB_SetMemMapEntries_MyPPL:
;
; As above, but uses provided PPL when mapping out instead of forcing to AP_Duff
; As above, but uses provided PPL when mapping out instead of forcing to AreaFlags_Duff
;
; entry:
; R3 = no. of pages
......@@ -746,7 +724,7 @@ AMB_SetMemMapEntries_SparseMapOut ROUT
FRAMLDR r5
FRAMLDR r10,,r4 ;ptr to page list
LDR r2,=ZeroPage
MOV r9,#AP_Duff ;permissions for DuffEntry
MOV r9,#AreaFlags_Duff ;permissions for DuffEntry
LDR r7,[r2,#CamEntriesPointer] ;r7 -> CAM
MOV r4,#ApplicationStart ;log. address of first page
LDR r1,=DuffEntry ;means Nowhere, in CAM
......@@ -775,7 +753,7 @@ AMB_SetMemMapEntries_SparseMapOut ROUT
ADD r0,r7,r0,LSL #CAM_EntrySizeLog2 ;r0 -> CAM entry for page
ASSERT CAM_LogAddr=0
ASSERT CAM_PageFlags=4
STMIA r0,{r1,r9} ;CAM entry for page set to DuffEntry,AP_Duff
STMIA r0,{r1,r9} ;CAM entry for page set to DuffEntry,AreaFlags_Duff
LDR lr,=L2PT ;lr -> L2PT
MOV r2, #0
STR r2,[lr,r4,LSR #(Log2PageSize-2)] ;L2PT entry for page set to 0 (means translation fault)
......
......@@ -57,7 +57,6 @@ TempUncache_L2PTMask * L2_X+L2_C+L2_B
; out: r0, r1, r4, r6 corrupted
; r2, r3, r5, r7-r12 preserved
;
; NB Use of stack is allowed in this routine
BangCamUpdate ROUT
TST r11, #DynAreaFlags_DoublyMapped ; if moving page to doubly mapped area
......@@ -129,11 +128,7 @@ BangCamUpdate ROUT
; out: r0, r1, r4, r6 corrupted
; r2, r3, r5, r7-r12 preserved
;
; NB Can't use stack - there might not be one!
;
; NB Also - the physical page number MUST be in range.
; This routine must work in 32-bit mode
; NB The physical page number MUST be in range.
BangCam ROUT
TST r11, #DynAreaFlags_DoublyMapped ; if area doubly mapped
......@@ -150,30 +145,9 @@ BangCam ROUT
ADD r0, r0, r6, LSL #12 ; move on address by the number of pages left
BangCamAltEntry
LDR r4, =DuffEntry ; check for requests to map a page to nowhere
LDR r6, =ZeroPage
TEQ r4, r3 ; don't actually map anything to nowhere
LDR r1, [r6, #ProcessorFlags]
MOVEQ pc, lr
TST r1, #CPUFlag_ExtendedPages
AND r4, r11, #3 ; first use PPL bits
ADREQ r1, PPLTrans
ADRNE r1, PPLTransX ; always use extended pages if supported
LDR r1, [r1, r4, LSL #2] ; get PPL bits and SmallPage indicator
ASSERT DynAreaFlags_CPBits = 7*XCB_P :SHL: 10
ASSERT DynAreaFlags_NotCacheable = XCB_NC :SHL: 4
ASSERT DynAreaFlags_NotBufferable = XCB_NB :SHL: 4
ORR r0, r0, r1
LDR r6, [r6, #MMU_PCBTrans]
AND r4, r11, #DynAreaFlags_CPBits
AND r1, r11, #DynAreaFlags_NotCacheable + DynAreaFlags_NotBufferable
TST r11, #PageFlags_TempUncacheableBits
ORRNE r1, r1, #DynAreaFlags_NotCacheable ; if temp uncache, set NC bit, ignore P
ORREQ r1, r1, r4, LSR #10-4 ; else use NC, NB and P bits
LDRB r1, [r6, r1, LSR #4] ; convert to X, C and B bits for this CPU
ORR r0, r0, r1
GetPTE r0, 4K, r0, r11
LDR r1, =L2PT ; point to level 2 page tables
......@@ -245,12 +219,21 @@ BangL2PT_sledgehammer
Pull "pc"
[ ARM6support
PPLTransARM6
& (AP_Full * L2_APMult) + L2_SmallPage ; R any W any
& (AP_Read * L2_APMult) + L2_SmallPage ; R any W sup
& (AP_None * L2_APMult) + L2_SmallPage ; R sup W sup
& (AP_Read * L2_APMult) + L2_SmallPage ; R any W sup
PPLTransL1
& (AP_Full * L1_APMult) + L1_Section ; R any W any
& (AP_Read * L1_APMult) + L1_Section ; R any W sup
& (AP_None * L1_APMult) + L1_Section ; R sup W sup
& (AP_ROM * L1_APMult) + L1_Section ; R any W none
PPLAccessARM6 ; EL1EL0
; RWXRWX
GenPPLAccess 2_111111
GenPPLAccess 2_111101
GenPPLAccess 2_111000
GenPPLAccess 2_111101
DCD -1
]
PPLTrans
& (AP_Full * L2_APMult) + L2_SmallPage ; R any W any
......@@ -264,11 +247,13 @@ PPLTransX
& (AP_None * L2X_APMult) + L2_ExtPage ; R sup W sup
& (AP_ROM * L2X_APMult) + L2_ExtPage ; R any W none
PageSizes
& 4*1024 ; 0 is 4K
& 8*1024 ; 4 is 8K
& 16*1024 ; 8 is 16
& 32*1024 ; C is 32
PPLAccess ; EL1EL0
; RWXRWX
GenPPLAccess 2_111111
GenPPLAccess 2_111101
GenPPLAccess 2_111000
GenPPLAccess 2_101101
DCD -1
PageShifts
= 12, 13, 0, 14 ; 1 2 3 4
......@@ -357,4 +342,203 @@ MMUC_modcon_readonly
MOV r2, lr
Pull "r3,r4,r5,pc"
; If extended pages are supported:
; PPLTrans should contain L2X_AP + L2_ExtPage
; PCBTrans should contain L2_C+L2_B+L2_TEX (for an extended page)
; If extended pages aren't supported:
; PPLTrans should contain L2_AP + L2_SmallPage
; PCBTrans should contain L2_C+L2_B
; In:
; r0 = phys addr (aligned)
; r1 = page flags:
; DynAreaFlags_APBits
; DynAreaFlags_NotBufferable
; DynAreaFlags_NotCacheable
; DynAreaFlags_CPBits
; PageFlags_TempUncacheableBits
; r2 -> PPLTrans
; r3 -> PCBTrans
; Out:
; r0 = PTE for 4K page ("small page" or "extended page" depending on PPLTrans)
Get4KPTE ROUT
Entry "r4"
AND lr, r1, #DynAreaFlags_APBits
LDR lr, [r2, lr, LSL #2]
; Insert AP bits, page type/size
ORR r0, r0, lr
; Insert CB+TEX bits
ASSERT DynAreaFlags_CPBits = 7*XCB_P :SHL: 10
ASSERT DynAreaFlags_NotCacheable = XCB_NC :SHL: 4
ASSERT DynAreaFlags_NotBufferable = XCB_NB :SHL: 4
TST r1, #PageFlags_TempUncacheableBits
AND r4, r1, #DynAreaFlags_NotCacheable + DynAreaFlags_NotBufferable
AND lr, r1, #DynAreaFlags_CPBits
ORRNE r4, r4, #DynAreaFlags_NotCacheable ; if temp uncache, set NC bit, ignore P
ORREQ r4, r4, lr, LSR #10-4 ; else use NC, NB and P bits
LDRB r4, [r3, r4, LSR #4] ; convert to X, C and B bits for this CPU
ORR r0, r0, r4
EXIT
; In:
; As per Get4KPTE
; Out:
; r0 = PTE for 64K page ("large page")
Get64KPTE ROUT
Entry "r4"
AND lr, r1, #DynAreaFlags_APBits
LDR lr, [r2, lr, LSL #2]
; Force to large page
ORR r0, r0, #L2_LargePage
; Insert AP bits
AND lr, lr, #L2X_AP ; If extended pages are supported, we need to expand L2X_AP to L2_AP
MOV r4, #L2_APMult/L2X_APMult
MLA r0, r4, lr, r0
50
; Insert CB+TEX bits
; Shared with Get1MPTE
ASSERT DynAreaFlags_CPBits = 7*XCB_P :SHL: 10
ASSERT DynAreaFlags_NotCacheable = XCB_NC :SHL: 4
ASSERT DynAreaFlags_NotBufferable = XCB_NB :SHL: 4
TST r1, #PageFlags_TempUncacheableBits
AND r4, r1, #DynAreaFlags_NotCacheable + DynAreaFlags_NotBufferable
AND lr, r1, #DynAreaFlags_CPBits
ORRNE r4, r4, #DynAreaFlags_NotCacheable ; if temp uncache, set NC bit, ignore P
ORREQ r4, r4, lr, LSR #10-4 ; else use NC, NB and P bits
LDRB r4, [r3, r4, LSR #4] ; convert to X, C and B bits for this CPU
; Move TEX field up
ORR r4, r4, r4, LSL #L2L_TEXShift-L2_TEXShift
BIC r4, r4, #L2_TEX :OR: ((L2_C+L2_B) :SHL: (L2L_TEXShift-L2_TEXShift))
ORR r0, r0, r4
EXIT
; In:
; As per Get4KPTE
; Out:
; r0 = PTE for 1M page ("section")
Get1MPTE
ALTENTRY
AND lr, r1, #DynAreaFlags_APBits
[ ARM6support
; Set U bit if cacheable and not ROM access
; (Because ROM access isn't supported, it'll get mapped to AP_Read.
; Writes to ROM will presumably be ignored by the bus, but if we have
; U set it will update the cache, effectively giving people the power
; to temporarily overwrite ROM)
CMP lr, #2
TSTLS r1, #DynAreaFlags_NotCacheable
ORREQ r0, r0, #L1_U
]
LDR lr, [r2, lr, LSL #2]
; Force to section map
ORR r0, r0, #L1_Section
; Insert AP bits
ASSERT L1_AP = L2X_AP :SHL: 6
AND lr, lr, #L2X_AP
ORR r0, r0, lr, LSL #6
; Insert CB+TEX bits
ASSERT L1_C = L2_C
ASSERT L1_B = L2_B
ASSERT L1_TEXShift = L2L_TEXShift
B %BT50
; In:
; r0 = L2PT entry
; Out:
; r0 = phys addr
; r1 = page flags
; or -1 if fault
; r2 = page size (bytes)
DecodeL2Entry ROUT
ANDS r2, r0, #3
MOVEQ r1, #-1
MOVEQ pc, lr
Entry "r3-r5"
; Get AP bits in low bits
ASSERT L2X_APMult = 1:SHL:4
MOV r1, r0, LSR #4
; Remap TEX+CB so that they're in the same position as an extended page entry