From 846eee0239926d6b544801e6d76a596c5c849872 Mon Sep 17 00:00:00 2001
From: Jeffrey Lee <me@phlamethrower.co.uk>
Date: Thu, 7 Nov 2019 21:57:36 +0000
Subject: [PATCH] DecodeL1/L2Entry -> LoadAndDecodeL1/L2Entry

Change the DecodeL1/L2Entry routines so that instead of accepting a page
table entry as input, they accept a (suitable-aligned) logical address
and fetch the page table entry themselves. This helps insulate the
calling code from the finer details of the page table format.
---
 s/ARM600  | 14 +++++++++-----
 s/HAL     | 10 ++++------
 s/MemInfo | 39 +++++++++++++++++++--------------------
 s/VMSAv6  | 12 ++++++++----
 4 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/s/ARM600 b/s/ARM600
index 2853c9a..63e46b8 100644
--- a/s/ARM600
+++ b/s/ARM600
@@ -437,13 +437,15 @@ Get1MPTE
         B       %BT50
 
 ; In:
-; r0 = L2PT entry
+; r0 = page-aligned logical addr
 ; Out:
 ; r0,r1 = phys addr
 ; r2 = page flags
 ;      or -1 if fault
 ; r3 = page size (bytes)
-DecodeL2Entry   ROUT
+LoadAndDecodeL2Entry   ROUT
+        LDR     r1, =L2PT
+        LDR     r0, [r1, r0, LSR #10]
         ANDS    r3, r0, #3
         MOVEQ   r2, #-1
         MOVEQ   pc, lr
@@ -468,7 +470,7 @@ DecodeL2Entry   ROUT
         MOVLT   r3, #65536
         MOVGE   r3, #4096
 20
-        ; Common code shared with DecodeL1Entry
+        ; Common code shared with LoadAndDecodeL1Entry
         ; 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
@@ -502,15 +504,17 @@ DecodeL2Entry   ROUT
         EXIT
 
 ; In:
-; r0 = L1PT entry
+; r0 = MB-aligned logical addr
 ; Out:
 ; 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
+LoadAndDecodeL1Entry
         ALTENTRY
+        LDR     r1, =L1PT
+        LDR     r0, [r1, r0, LSR #20-2]
         AND     r2, r0, #3
         ASSERT  L1_Fault < L1_Page
         ASSERT  L1_Page < L1_Section
diff --git a/s/HAL b/s/HAL
index c594a90..e76d873 100644
--- a/s/HAL
+++ b/s/HAL
@@ -1488,18 +1488,16 @@ ConstructCAMfromPageTables
         BHI     %BT10
 
         MOV     v2, #0                          ; v2 = logical address
-        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,a2 = phys addr, a3 = page flags/type, a4 = page size (bytes)
+30      MOV     a1, v2
+        BL      LoadAndDecodeL1Entry            ; 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,a2 = phys addr, a3 = flags (-1 if fault), a4 = page size (bytes)
+40      MOV     a1, v2
+        BL      LoadAndDecodeL2Entry            ; 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    a4, a4, #4096                   ; large pages get bits 12-15 from the virtual address
diff --git a/s/MemInfo b/s/MemInfo
index a2de796..3e77b14 100644
--- a/s/MemInfo
+++ b/s/MemInfo
@@ -2034,12 +2034,11 @@ CheckMemoryAccess ROUT
         LDR     r4, [r10, #IOAllocPtr]
         MOV     r3, r3, LSL #20 ; Get MB-aligned addr of first entry to check
         CMP     r3, r4
-        LDR     r7, =L1PT
         MOVLO   r3, r4 ; Skip all the unallocated regions
 31
         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.
+        MOV     r0, r3
+        BL      LoadAndDecodeL1Entry    ; TODO bit wasteful. We only care about access privileges, but this call gives us cache info too.
         LDR     r5, [r10, #MMU_PPLAccess]
         AND     lr, r2, #DynAreaFlags_APBits
         LDR     r5, [r5, lr, LSL #2]
@@ -2052,21 +2051,22 @@ CheckMemoryAccess ROUT
         BNE     %BT31
 40
         ; Everything else!
-        LDR     r3, =L1PT + (PhysicalAccess:SHR:18)
-        LDR     r3, [r3]
-        TEQ     r3, #0
-        BEQ     %FT50
-        TST     r3, #L1_SS
+        ASSERT  PhysicalAccess >= IO
+        CMP     r1, #HALWorkspace
+        BHS     %FT50
+        Push    "r0-r2"
+        LDR     r0, =PhysicalAccess
+        BL      LoadAndDecodeL1Entry
+        CMP     r2, #-2
+        AND     lr, r2, #DynAreaFlags_APBits
+        Pull    "r0-r2"
+        BHS     %FT50
+        ADD     r4, r3, #PhysicalAccess
+        LDR     r5, [r10, #MMU_PPLAccess]
         LDR     r3, =PhysicalAccess
-        LDREQ   r4, =&100000  ; section mapped
-        LDRNE   r4, =&1000000 ; supersection mapped
-        ; Assume IO memory mapped there
-      [ MEMM_Type = "VMSAv6"
-        LDR     r5, =CMA_Partially_PrivR+CMA_Partially_PrivW+CMA_Partially_Phys
-      |
-        LDR     r5, =CMA_Partially_PrivR+CMA_Partially_PrivW+CMA_Partially_PrivXN+CMA_Partially_Phys
-      ]
-        BL      CMA_AddRange
+        LDR     r5, [r5, lr, LSL #2]
+        ORR     r5, r5, #CMA_Partially_Phys
+        BL      CMA_AddRange2
 50
         ASSERT  HALWorkspace > PhysicalAccess
         LDR     r3, =HALWorkspace
@@ -2259,9 +2259,8 @@ CMA_Done
         BCS     %FT45
         ; Get the L2PT entry and decode the flags
         Push    "r0-r3"
-        LDR     r8, =L2PT
-        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
+        MOV     r0, r4
+        BL      LoadAndDecodeL2Entry    ; 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
         ; r2 = DA flags
         ; Extract and decode AP
         LDR     r0, =ZeroPage
diff --git a/s/VMSAv6 b/s/VMSAv6
index c1d91a6..771547c 100644
--- a/s/VMSAv6
+++ b/s/VMSAv6
@@ -541,13 +541,15 @@ Get1MPTE
         B       %BT50
 
 ; In:
-; r0 = L2PT entry
+; r0 = page-aligned logical addr
 ; Out:
 ; r0,r1 = phys addr
 ; r2 = page flags
 ;      or -1 if fault
 ; r3 = page size (bytes)
-DecodeL2Entry   ROUT
+LoadAndDecodeL2Entry   ROUT
+        LDR     r1, =L2PT
+        LDR     r0, [r1, r0, LSR #10]
         TST     r0, #3
         MOVEQ   r2, #-1
         MOVEQ   pc, lr
@@ -614,15 +616,17 @@ DecodeL2Entry   ROUT
         EXIT
 
 ; In:
-; r0 = L1PT entry
+; r0 = MB-aligned logical addr
 ; Out:
 ; 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
+LoadAndDecodeL1Entry
         ALTENTRY
+        LDR     r1, =L1PT
+        LDR     r0, [r1, r0, LSR #20-2]
         AND     r2, r0, #3
         ASSERT  L1_Fault < L1_Page
         ASSERT  L1_Page < L1_Section
-- 
GitLab