Commit bd294cf9 authored by Ben Avison's avatar Ben Avison Committed by ROOL

Support supersection-mapped memory in OS_Memory 24

To achieve this:
* DecodeL1Entry and DecodeL2Entry return 64-bit physical addresses in
  r0 and r1, with additional return values shuffled up to r2 and r3
* DecodeL1Entry now returns the section size, so callers can distinguish
  section- from supersection-mapped memory
* PhysAddrToPageNo now accepts a 64-bit address (though since the physical
  RAM table is currently still all 32-bit, it will report any top-word-set
  addresses as being not in RAM)

Version 6.22. Tagged as 'Kernel-6_22'
parent 96913c1f
......@@ -9,12 +9,12 @@
GBLS Module_ApplicationDate
GBLS Module_HelpVersion
GBLS Module_ComponentName
Module_MajorVersion SETS "6.21"
Module_Version SETA 621
Module_MajorVersion SETS "6.22"
Module_Version SETA 622
Module_MinorVersion SETS ""
Module_Date SETS "02 Jul 2019"
Module_ApplicationDate SETS "02-Jul-19"
Module_Date SETS "16 Aug 2019"
Module_ApplicationDate SETS "16-Aug-19"
Module_ComponentName SETS "Kernel"
Module_FullVersion SETS "6.21"
Module_HelpVersion SETS "6.21 (02 Jul 2019)"
Module_FullVersion SETS "6.22"
Module_HelpVersion SETS "6.22 (16 Aug 2019)"
END
/* (6.21)
/* (6.22)
*
* This file is automatically maintained by srccommit, do not edit manually.
*
*/
#define Module_MajorVersion_CMHG 6.21
#define Module_MajorVersion_CMHG 6.22
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 02 Jul 2019
#define Module_Date_CMHG 16 Aug 2019
#define Module_MajorVersion "6.21"
#define Module_Version 621
#define Module_MajorVersion "6.22"
#define Module_Version 622
#define Module_MinorVersion ""
#define Module_Date "02 Jul 2019"
#define Module_Date "16 Aug 2019"
#define Module_ApplicationDate "02-Jul-19"
#define Module_ApplicationDate "16-Aug-19"
#define Module_ComponentName "Kernel"
#define Module_FullVersion "6.21"
#define Module_HelpVersion "6.21 (02 Jul 2019)"
#define Module_LibraryVersionInfo "6:21"
#define Module_FullVersion "6.22"
#define Module_HelpVersion "6.22 (16 Aug 2019)"
#define Module_LibraryVersionInfo "6:22"
......@@ -435,48 +435,49 @@ Get1MPTE
; In:
; r0 = L2PT entry
; Out:
; r0 = phys addr
; r1 = page flags
; r0,r1 = phys addr
; r2 = page flags
; or -1 if fault
; r2 = page size (bytes)
; r3 = page size (bytes)
DecodeL2Entry ROUT
ANDS r2, r0, #3
MOVEQ r1, #-1
ANDS r3, r0, #3
MOVEQ r2, #-1
MOVEQ pc, lr
Entry "r3-r5"
Entry "r4-r6"
; Get AP bits in low bits
ASSERT L2X_APMult = 1:SHL:4
MOV r1, r0, LSR #4
MOV r2, r0, LSR #4
; Remap TEX+CB so that they're in the same position as an extended page entry
ASSERT L2_LargePage < L2_SmallPage
ASSERT L2_SmallPage < L2_ExtPage
CMP r2, #L2_SmallPage
CMP r3, #L2_SmallPage
AND r4, r0, #L2_C+L2_B
ANDLT lr, r0, #L2L_TEX
ORRLT r4, r4, lr, LSR #L2L_TEXShift-L2_TEXShift
ANDGT lr, r0, #L2_TEX
ORRGT r4, r4, lr
; Align phys addr to page size and set up R2
; Align phys addr to page size and set up r3
MOV r0, r0, LSR #12
BICLT r0, r0, #15
MOV r0, r0, LSL #12
MOVLT r2, #65536
MOVGE r2, #4096
MOV r1, #0
MOVLT r3, #65536
MOVGE r3, #4096
20
; Common code shared with DecodeL1Entry
; Only four PPL possibilities, so just directly decode it
; ARM access goes 0 => all R/O, 1 => user none, 2 => user R/O, 3 => user R/W
; PPL access goes 0 => user R/W, 1 => user R/O, 2 => user none, 3 => all R/0
; i.e. just invert the bits
AND r1, r1, #3
LDR r3, =ZeroPage
EOR r1, r1, #3
AND r2, r2, #3
LDR r6, =ZeroPage
EOR r2, r2, #3
; Search through PCBTrans for a match on TEX+CB
; Funny order is used so that NCNB is preferred over other variants (since NCNB is common fallback)
LDR r3, [r3, #MMU_PCBTrans]
LDR r6, [r6, #MMU_PCBTrans]
MOV lr, #3
30
LDRB r5, [r3, lr]
LDRB r5, [r6, lr]
CMP r5, r4
BEQ %FT40
TST lr, #2_11
......@@ -492,42 +493,46 @@ DecodeL2Entry ROUT
ASSERT DynAreaFlags_NotBufferable = XCB_NB :SHL: 4
AND r4, lr, #XCB_NC+XCB_NB
AND lr, lr, #7*XCB_P
ORR r1, r1, r4, LSL #4
ORR r1, r1, lr, LSL #10
ORR r2, r2, r4, LSL #4
ORR r2, r2, lr, LSL #10
EXIT
; In:
; r0 = L1PT entry
; Out:
; r0 = phys addr
; r1 = page flags if 1MB page
; r0,r1 = phys addr of section or L2PT entry
; r2 = page flags if 1MB page
; or -1 if fault
; or -2 if page table ptr
; r3 = section size (bytes) if section-mapped
DecodeL1Entry
ALTENTRY
AND r1, r0, #3
AND r2, r0, #3
ASSERT L1_Fault < L1_Page
ASSERT L1_Page < L1_Section
CMP r1, #L1_Page
CMP r2, #L1_Page
BGT %FT50
MOVLT r1, #-1
MOVEQ r1, #-2
MOVLT r2, #-1
MOVEQ r2, #-2
MOVEQ r0, r0, LSR #10
MOVEQ r0, r0, LSL #10
MOVEQ r1, #0
EXIT
50
; Get AP bits in low bits
ASSERT L1_APMult = 1:SHL:10
MOV r1, r0, LSR #10
MOV r2, r0, LSR #10
; Remap TEX+CB so that they're in the same position as an extended page entry
ASSERT L1_C = L2_C
ASSERT L1_B = L2_B
AND r4, r0, #L1_C+L1_B
AND lr, r0, #L1_TEX
ORR r4, r4, lr, LSR #L1_TEXShift-L2_TEXShift
; Align phys addr to page size
; Align phys addr to page size and set up r3
MOV r0, r0, LSR #20
MOV r0, r0, LSL #20
MOV r1, #0
MOV r3, #1048576
; Jump to common code to do AP decode + PCBTrans search
B %BT20
......
......@@ -4370,9 +4370,11 @@ DynArea_AddrLookup_loop
LDR r0, [r5, #InitUsedStart]
ADD r0, r0, #DRAMOffset_FirstFixed - DRAMOffset_L1PT
MOV r1, #0 ; only know 32-bit addresses for now
BL PhysAddrToPageNo
MOV r7, r0 ; r7 = page number of start of static chunk
LDR r0, [r5, #InitUsedEnd]
MOV r1, #0 ; only know 32-bit addresses for now
BL PhysAddrToPageNo
SUB r8, r0, #1 ; r8 = page number of last page in statics
ADD r9, r5, #PhysRamTable
......
......@@ -1436,12 +1436,14 @@ CountPageTablePages ROUT
STR a1, [a2, #L2PTUsed]
EXIT
; int PhysAddrToPageNo(void *addr)
; int PhysAddrToPageNo(uint64_t addr)
;
; Converts a physical address to the page number of the page containing it.
; Returns -1 if address is not in RAM.
PhysAddrToPageNo
TEQ a2, #0
BNE %FT90 ; only handle addresses under 4GB for now
MOV a4, #0
LDR ip, =ZeroPage + PhysRamTable
10 LDMIA ip!, {a2, a3} ; get phys addr, size
......@@ -1489,20 +1491,20 @@ ConstructCAMfromPageTables
LDR v3, =L1PT ; v3 -> L1PT (not used much)
LDR v4, =L2PT ; v4 -> L2PT
30 LDR a1, [v3, v2, LSR #18] ; a1 = first level descriptor
BL DecodeL1Entry ; a1 = phys addr, a2 = page flags/type
CMP a2, #-2 ; Only care about page table pointers
BL DecodeL1Entry ; a1,a2 = phys addr, a3 = page flags/type, a4 = page size (bytes)
CMP a3, #-2 ; Only care about page table pointers
BEQ %FT40
ADDS v2, v2, #&00100000
BCC %BT30
Pull "v1-v8, pc"
40 LDR a1, [v4, v2, LSR #10] ; a1 = second level descriptor
BL DecodeL2Entry ; a1 = phys addr, a2 = flags (-1 if fault), a3 = page size (bytes)
CMP a2, #-1 ; move to next page if fault
BL DecodeL2Entry ; a1,a2 = phys addr, a3 = flags (-1 if fault), a4 = page size (bytes)
CMP a3, #-1 ; move to next page if fault
BEQ %FT80
SUBS a3, a3, #4096 ; large pages get bits 12-15 from the virtual address
ANDNE lr, v2, a3
ORR v6, a2, #PageFlags_Unavailable
SUBS a4, a4, #4096 ; large pages get bits 12-15 from the virtual address
ANDNE lr, v2, a4
ORR v6, a3, #PageFlags_Unavailable
ORRNE a1, a1, lr
BL PhysAddrToPageNo ; -1 if unknown page
ADDS a1, v1, a1, LSL #CAM_EntrySizeLog2 ; a1 -> CAM entry
......
......@@ -2022,13 +2022,13 @@ CheckMemoryAccess ROUT
LDR r7, =L1PT
MOVLO r3, r4 ; Skip all the unallocated regions
31
Push "r0,r1"
Push "r0-r3"
LDR r0, [r7, r3, LSR #20-2]
BL DecodeL1Entry ; TODO bit wasteful. We only care about access privileges, but this call gives us cache info too.
LDR r5, [r10, #MMU_PPLAccess]
AND lr, r1, #DynAreaFlags_APBits
AND lr, r2, #DynAreaFlags_APBits
LDR r5, [r5, lr, LSL #2]
Pull "r0,r1"
Pull "r0-r3"
ADD r4, r3, #1<<20
ORR r5, r5, #CMA_Partially_Phys
BL CMA_AddRange2
......@@ -2244,16 +2244,16 @@ CMA_Done
BICCS r0, r0, r10 ; Not fully mapped, clear completion flags
BCS %FT45
; Get the L2PT entry and decode the flags
Push "r0-r2"
Push "r0-r3"
LDR r0, [r8, r4, LSR #10]
BL DecodeL2Entry ; TODO bit wasteful. We only care about access privileges, but this call gives us cache info too. Also, if we know the L2PT backing exists (it should do) we could skip the logical_to_physical call
; r1 = DA flags
; r2 = DA flags
; Extract and decode AP
LDR r0, =ZeroPage
LDR r5, [r0, #MMU_PPLAccess]
AND lr, r1, #DynAreaFlags_APBits
AND lr, r2, #DynAreaFlags_APBits
LDR r5, [r5, lr, LSL #2]
Pull "r0-r2"
Pull "r0-r3"
ORR r10, r5, r10
ORR r0, r0, r5 ; Set new partial flags
AND r0, r0, r10, ROR #4 ; Discard completion flags which aren't for this range
......
......@@ -539,20 +539,20 @@ Get1MPTE
; In:
; r0 = L2PT entry
; Out:
; r0 = phys addr
; r1 = page flags
; r0,r1 = phys addr
; r2 = page flags
; or -1 if fault
; r2 = page size (bytes)
; r3 = page size (bytes)
DecodeL2Entry ROUT
TST r0, #3
MOVEQ r1, #-1
MOVEQ r2, #-1
MOVEQ pc, lr
Entry "r3-r5"
Entry "r4-r6"
; Find entry in PPL table
LDR r3, =ZeroPage
LDR r2, =L2_AP+L2_XN ; L2_S ignored, pages should either be all shareable or all not shareable
LDR r3, [r3, #MMU_PPLTrans]
AND r4, r2, r0
LDR r6, =ZeroPage
LDR r3, =L2_AP+L2_XN ; L2_S ignored, pages should either be all shareable or all not shareable
LDR r6, [r6, #MMU_PPLTrans]
AND r4, r3, r0
; Get XN
ASSERT L2_XN = 1
ASSERT L2_SmallPage = 2
......@@ -560,12 +560,12 @@ DecodeL2Entry ROUT
TST r0, #L2_SmallPage ; EQ if LargePage
TSTEQ r0, #L2L_XN
BICEQ r4, r4, #L2_XN ; Large page with no XN, so clear the fake XN flag we picked up earlier
MOV r1, #0
MOV r2, #0
10
LDRH r5, [r3, r1]
AND r5, r5, r2
LDRH r5, [r6, r2]
AND r5, r5, r3
CMP r5, r4
ADDNE r1, r1, #2
ADDNE r2, r2, #2
BNE %BT10
; Remap TEX+CB so that they're in the same position as a small page entry
TST r0, #L2_SmallPage ; EQ if LargePage
......@@ -574,21 +574,22 @@ DecodeL2Entry ROUT
AND r4, r0, r4
ANDEQ lr, r0, #L2L_TEX
ORREQ r4, r4, lr, LSR #L2L_TEXShift-L2_TEXShift
; Align phys addr to page size and set up R2
; Align phys addr to page size and set up r3
MOV r0, r0, LSR #12
BICEQ r0, r0, #15
MOV r0, r0, LSL #12
MOVEQ r2, #65536
MOVNE r2, #4096
MOV r1, #0
MOVEQ r3, #65536
MOVNE r3, #4096
20
; Search through PCBTrans for a match on TEX+CB (shared with L1 decoding)
; Funny order is used so that NCNB is preferred over other variants (since NCNB is common fallback)
LDR r3, =ZeroPage
MOV r1, r1, LSR #1
LDR r3, [r3, #MMU_PCBTrans]
LDR r6, =ZeroPage
MOV r2, r2, LSR #1
LDR r6, [r6, #MMU_PCBTrans]
MOV lr, #3*2
30
LDRH r5, [r3, lr]
LDRH r5, [r6, lr]
CMP r5, r4
BEQ %FT40
TST lr, #2_11*2
......@@ -604,52 +605,47 @@ DecodeL2Entry ROUT
ASSERT DynAreaFlags_NotBufferable = XCB_NB :SHL: 4
AND r4, lr, #(XCB_NC+XCB_NB)*2
AND lr, lr, #7*XCB_P*2
ORR r1, r1, r4, LSL #4-1
ORR r1, r1, lr, LSL #10-1
ORR r2, r2, r4, LSL #4-1
ORR r2, r2, lr, LSL #10-1
EXIT
; In:
; r0 = L1PT entry
; Out:
; r0 = phys addr
; r1 = page flags if 1MB page
; r0,r1 = phys addr of section or L2PT entry
; r2 = page flags if 1MB page
; or -1 if fault
; or -2 if page table ptr
; r3 = section size (bytes) if section-mapped
DecodeL1Entry
ALTENTRY
AND r1, r0, #3
AND r2, r0, #3
ASSERT L1_Fault < L1_Page
ASSERT L1_Page < L1_Section
CMP r1, #L1_Page
CMP r2, #L1_Page
BGT %FT50
MOVLT r1, #-1
MOVEQ r1, #-2
MOVLT r2, #-1
MOVEQ r2, #-2
MOVEQ r0, r0, LSR #10
MOVEQ r0, r0, LSL #10
MOVEQ r1, #0
EXIT
50
; If it's a supersection that maps beyond 4GB, pretend it faults for now
TST a1, #L1_SSb32Mask
TSTEQ a1, #L1_SSb36Mask
TSTNE a1, #L1_SS
MOVNE r1, #-1
EXIT NE
; Find entry in PPL table
LDR r3, =ZeroPage
LDR r6, =ZeroPage
LDR lr, =L2_AP
LDR r3, [r3, #MMU_PPLTrans]
LDR r6, [r6, #MMU_PPLTrans]
ASSERT L1_APShift = L2_APShift+6
AND r4, lr, r0, LSR #6
TST r0, #L1_XN
ORRNE r4, r4, #L2_XN
ORR lr, lr, #L2_XN
MOV r1, #0
MOV r2, #0
60
LDRH r5, [r3, r1]
LDRH r5, [r6, r2]
AND r5, r5, lr
CMP r5, r4
ADDNE r1, r1, #2
ADDNE r2, r2, #2
BNE %BT60
; Remap TEX+CB so that they're in the same position as a small page entry
ASSERT L1_C = L2_C
......@@ -657,8 +653,15 @@ DecodeL1Entry
AND r4, r0, #L1_C+L1_B
AND lr, r0, #L1_TEX
ORR r4, r4, lr, LSR #L1_TEXShift-L2_TEXShift
; Align phys addr to page size
; Unpack upper address bits of supersections, align phys addr to page size and set up r3
ANDS r1, r0, #L1_SS
UBFXNE r6, r0, #L1_SSb36Shift, #L1_SSb36Width
UBFXNE r1, r0, #L1_SSb32Shift, #L1_SSb32Width
MOV r0, r0, LSR #20
BICNE r0, r0, #15
MOVEQ r3, #1048576
MOVNE r3, #16777216
ORRNE r1, r1, r6, LSL #36-32
MOV r0, r0, LSL #20
; Now search through PCBTrans for a match
B %BT20
......
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