ARM600 15 KB
Newer Older
Neil Turton's avatar
Neil Turton committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
; Copyright 1996 Acorn Computers 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.
;
; > ARM600

        GBLL    DebugAborts
DebugAborts SETL {FALSE}

Jeffrey Lee's avatar
Jeffrey Lee committed
20 21 22 23 24 25 26 27 28 29 30 31 32
        ; Convert given page flags to the equivalent temp uncacheable L2PT flags
        ; n.b. temp not used here but included for VMSAv6 compatibility
        MACRO
        GetTempUncache $out, $pageflags, $pcbtrans, $temp
        ASSERT  DynAreaFlags_CPBits = 7*XCB_P :SHL: 10
        ASSERT  DynAreaFlags_NotCacheable = XCB_NC :SHL: 4
        ASSERT  DynAreaFlags_NotBufferable = XCB_NB :SHL: 4
        AND     $out, $pageflags, #DynAreaFlags_NotCacheable + DynAreaFlags_NotBufferable
        ORR     $out, $out, #DynAreaFlags_NotCacheable      ; treat as temp uncache
        LDRB    $out, [$pcbtrans, $out, LSR #4]             ; convert to X, C and B bits for this CPU
        MEND

TempUncache_L2PTMask * L2_X+L2_C+L2_B
Neil Turton's avatar
Neil Turton committed
33 34 35

; MMU interface file - ARM600 version

36 37
        KEEP

Neil Turton's avatar
Neil Turton committed
38 39 40 41
; **************** CAM manipulation utility routines ***********************************

; **************************************************************************************
;
42
;       BangCamUpdate - Update CAM, MMU for page move, coping with page currently mapped in
Neil Turton's avatar
Neil Turton committed
43
;
44 45
; mjs Oct 2000
; reworked to use generic ARM ops (vectored to appropriate routines during boot)
Neil Turton's avatar
Neil Turton committed
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
;
; First look in the CamEntries table to find the logical address L this physical page is
; currently allocated to. Then check in the Level 2 page tables to see if page L is currently
; at page R2. If it is, then map page L to be inaccessible, otherwise leave page L alone.
; Then map logical page R3 to physical page R2.
;
; in:   r2 = physical page number
;       r3 = logical address (2nd copy if doubly mapped area)
;       r9 = offset from 1st to 2nd copy of doubly mapped area (either source or dest, but not both)
;       r11 = PPL + CB bits
;
; 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
        SUBNE   r3, r3, r9                      ; then CAM soft copy holds ptr to 1st copy

Jeffrey Lee's avatar
Jeffrey Lee committed
66
        LDR     r1, =ZeroPage
Neil Turton's avatar
Neil Turton committed
67
        LDR     r1, [r1, #CamEntriesPointer]
68 69 70
        ADD     r1, r1, r2, LSL #CAM_EntrySizeLog2 ; point at cam entry (logaddr, PPL)
        ASSERT  CAM_LogAddr=0
        ASSERT  CAM_PageFlags=4
Neil Turton's avatar
Neil Turton committed
71
        LDMIA   r1, {r0, r6}                    ; r0 = current logaddress, r6 = current PPL
72 73
        BIC     r4, r11, #PageFlags_Unsafe
        STMIA   r1, {r3, r4}                    ; store new address, PPL
Neil Turton's avatar
Neil Turton committed
74
        Push    "r0, r6"                        ; save old logical address, PPL
Jeffrey Lee's avatar
Jeffrey Lee committed
75
        LDR     r1, =ZeroPage+PhysRamTable      ; go through phys RAM table
Neil Turton's avatar
Neil Turton committed
76 77 78 79 80 81 82 83
        MOV     r6, r2                          ; make copy of r2 (since that must be preserved)
10
        LDMIA   r1!, {r0, r4}                   ; load next address, size
        SUBS    r6, r6, r4, LSR #12             ; subtract off that many pages
        BCS     %BT10                           ; if more than that, go onto next bank

        ADD     r6, r6, r4, LSR #12             ; put back the ones which were too many
        ADD     r0, r0, r6, LSL #12             ; move on address by the number of pages left
Robert Sprowson's avatar
Robert Sprowson committed
84
        LDR     r6, [sp]                        ; reload old logical address
Neil Turton's avatar
Neil Turton committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102

; now we have r6 = old logical address, r2 = physical page number, r0 = physical address

        TEQ     r6, r3                          ; TMD 19-Jan-94: if old logaddr = new logaddr, then
        BEQ     %FT20                           ; don't remove page from where it is, to avoid window
                                                ; where page is nowhere.
        LDR     r1, =L2PT
        ADD     r6, r1, r6, LSR #10             ; r6 -> L2PT entry for old log.addr
        MOV     r4, r6, LSR #12                 ; r4 = word offset into L2 for address r6
        LDR     r4, [r1, r4, LSL #2]            ; r4 = L2PT entry for L2PT entry for old log.addr
        TST     r4, #3                          ; if page not there
        BEQ     %FT20                           ; then no point in trying to remove it

        LDR     r4, [r6]                        ; r4 = L2PT entry for old log.addr
        MOV     r4, r4, LSR #12                 ; r4 = physical address for old log.addr
        TEQ     r4, r0, LSR #12                 ; if equal to physical address of page being moved
        BNE     %FT20                           ; if not there, then just put in new page

103
        AND     r4, r11, #PageFlags_Unsafe
Neil Turton's avatar
Neil Turton committed
104 105 106
        Push    "r0, r3, r11, r14"              ; save phys.addr, new log.addr, new PPL, lr
        ADD     r3, sp, #4*4
        LDMIA   r3, {r3, r11}                   ; reload old logical address, old PPL
107 108 109
        LDR     r0, =DuffEntry                  ; Nothing to do if wasn't mapped in
        ORR     r11, r11, r4
        TEQ     r3, r0
Neil Turton's avatar
Neil Turton committed
110
        MOV     r0, #0                          ; cause translation fault
111
        BLNE    BangL2PT                        ; map page out
Neil Turton's avatar
Neil Turton committed
112 113 114 115 116 117 118
        Pull    "r0, r3, r11, r14"
20
        ADD     sp, sp, #8                      ; junk old logical address, PPL
        B       BangCamAltEntry                 ; and branch into BangCam code

; **************************************************************************************
;
119
;       BangCam - Update CAM, MMU for page move, assuming page currently mapped out
Neil Turton's avatar
Neil Turton committed
120 121
;
; This routine maps a physical page to a given logical address
122
; It is assumed that the physical page is currently not mapped anywhere else
Neil Turton's avatar
Neil Turton committed
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
;
; in:   r2 = physical page number
;       r3 = logical address (2nd copy if doubly mapped)
;       r9 = offset from 1st to 2nd copy of doubly mapped area (either source or dest, but not both)
;       r11 = PPL
;
; 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

BangCam ROUT
        TST     r11, #DynAreaFlags_DoublyMapped ; if area doubly mapped
        SUBNE   r3, r3, r9              ; then move ptr to 1st copy

Jeffrey Lee's avatar
Jeffrey Lee committed
142
        LDR     r1, =ZeroPage+PhysRamTable ; go through phys RAM table
Neil Turton's avatar
Neil Turton committed
143 144 145 146 147 148 149 150 151
        MOV     r6, r2                  ; make copy of r2 (since that must be preserved)
10
        LDMIA   r1!, {r0, r4}           ; load next address, size
        SUBS    r6, r6, r4, LSR #12     ; subtract off that many pages
        BCS     %BT10                   ; if more than that, go onto next bank

        ADD     r6, r6, r4, LSR #12     ; put back the ones which were too many
        ADD     r0, r0, r6, LSL #12     ; move on address by the number of pages left
BangCamAltEntry
152
        LDR     r4, =DuffEntry          ; check for requests to map a page to nowhere
153
        LDR     r6, =ZeroPage
154
        TEQ     r4, r3                  ; don't actually map anything to nowhere
155
        LDR     r1, [r6, #ProcessorFlags]
156
        MOVEQ   pc, lr
157
        TST     r1, #CPUFlag_ExtendedPages
Neil Turton's avatar
Neil Turton committed
158
        AND     r4, r11, #3             ; first use PPL bits
159 160
        ADREQ   r1, PPLTrans
        ADRNE   r1, PPLTransX           ; always use extended pages if supported
Neil Turton's avatar
Neil Turton committed
161
        LDR     r1, [r1, r4, LSL #2]    ; get PPL bits and SmallPage indicator
162

163 164 165
        ASSERT  DynAreaFlags_CPBits = 7*XCB_P :SHL: 10
        ASSERT  DynAreaFlags_NotCacheable = XCB_NC :SHL: 4
        ASSERT  DynAreaFlags_NotBufferable = XCB_NB :SHL: 4
Kevin Bracey's avatar
Kevin Bracey committed
166 167 168 169 170 171 172 173

        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
174
        ORREQ   r1, r1, r4, LSR #10-4                   ; else use NC, NB and P bits
Kevin Bracey's avatar
Kevin Bracey committed
175 176
        LDRB    r1, [r6, r1, LSR #4]                    ; convert to X, C and B bits for this CPU
        ORR     r0, r0, r1
Neil Turton's avatar
Neil Turton committed
177 178 179

        LDR     r1, =L2PT               ; point to level 2 page tables

180 181
        ;fall through to BangL2PT

Neil Turton's avatar
Neil Turton committed
182 183 184 185 186 187 188
;internal entry point for updating L2PT entry
;
; entry: r0 = new L2PT value, r1 -> L2PT, r3 = logical address (4k aligned), r11 = PPL
;
; exit: r0,r1,r4,r6 corrupted
;
BangL2PT                                        ; internal entry point used only by BangCamUpdate
189 190 191
        Push    "lr"
        MOV     r6, r0

192 193 194
        TST     r11, #PageFlags_Unsafe
        BNE     %FT30

Neil Turton's avatar
Neil Turton committed
195 196 197
        TST     r11, #DynAreaFlags_DoublyMapped
        BNE     BangL2PT_sledgehammer           ;if doubly mapped, don't try to be clever

Jeffrey Lee's avatar
Jeffrey Lee committed
198 199 200 201 202 203 204 205
        ;In order to safely map out a cacheable page and remove it from the
        ;cache, we need to perform the following process:
        ;* Make the page uncacheable
        ;* Flush TLB
        ;* Clean+invalidate cache
        ;* Write new mapping (r6)
        ;* Flush TLB
        ;For uncacheable pages we can just do the last two steps
206 207
        ;
        TEQ     r6, #0                          ;EQ if mapping out
Kevin Bracey's avatar
Kevin Bracey committed
208
        TSTEQ   r11, #DynAreaFlags_NotCacheable ;EQ if also cacheable (overcautious for temp uncache+illegal PCB combos)
Jeffrey Lee's avatar
Jeffrey Lee committed
209
        LDR     r4, =ZeroPage
Jeffrey Lee's avatar
Jeffrey Lee committed
210 211 212 213 214 215 216 217 218 219 220 221 222
        BNE     %FT20
        LDR     lr, [r4, #MMU_PCBTrans]
        GetTempUncache r0, r11, lr
        LDR     lr, [r1, r3, LSR #10]           ;get current L2PT entry
        BIC     lr, lr, #TempUncache_L2PTMask   ;remove current attributes
        ORR     lr, lr, r0
        STR     lr, [r1, r3, LSR #10]           ;Make uncacheable
        MOV     r0, r3
        ARMop   MMU_ChangingUncachedEntry,,, r4 ; TLB flush
        MOV     r0, r3
        ADD     r1, r3, #4096
        ARMop   Cache_CleanInvalidateRange,,, r4 ; Cache flush
        LDR     r1, =L2PT
Neil Turton's avatar
Neil Turton committed
223

224
20      STR     r6, [r1, r3, LSR #10]           ;update L2PT entry
Jeffrey Lee's avatar
Jeffrey Lee committed
225 226 227
        Pull    "lr"
        MOV     r0, r3
        ARMop   MMU_ChangingUncachedEntry,,tailcall,r4
Neil Turton's avatar
Neil Turton committed
228 229

BangL2PT_sledgehammer
230 231 232 233 234

        ;sledgehammer is super cautious and does cache/TLB coherency on a global basis
        ;should only be used for awkward cases
        ;
        TEQ     r6, #0                          ;EQ if mapping out
Kevin Bracey's avatar
Kevin Bracey committed
235
        TSTEQ   r11, #DynAreaFlags_NotCacheable ;EQ if also cacheable (overcautious for temp uncache+illegal PCB combos)
236
        ADR     lr, %FT30
Jeffrey Lee's avatar
Jeffrey Lee committed
237
        LDR     r4, =ZeroPage
238 239 240 241
        ARMop   MMU_Changing, EQ, tailcall, r4
        ARMop   MMU_ChangingUncached, NE, tailcall, r4

30      STR     r6, [r1, r3, LSR #10]!          ; update level 2 page table (and update pointer so we can use bank-to-bank offset
Neil Turton's avatar
Neil Turton committed
242
        TST     r11, #DynAreaFlags_DoublyMapped ; if area doubly mapped
243 244
        STRNE   r6, [r1, r9, LSR #10]           ; then store entry for 2nd copy as well
        ADDNE   r3, r3, r9                      ; and point logical address back at 2nd copy
Neil Turton's avatar
Neil Turton committed
245

246
        Pull    "pc"
Neil Turton's avatar
Neil Turton committed
247

Neil Turton's avatar
Neil Turton committed
248

249 250 251 252 253 254
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

Neil Turton's avatar
Neil Turton committed
255 256 257 258
PPLTrans
        &       (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
259
        &       (AP_ROM  * L2_APMult) + L2_SmallPage      ; R any W none
Neil Turton's avatar
Neil Turton committed
260

Kevin Bracey's avatar
Kevin Bracey committed
261 262 263 264 265 266
PPLTransX
        &       (AP_Full * L2X_APMult) + L2_ExtPage       ; R any W any
        &       (AP_Read * L2X_APMult) + L2_ExtPage       ; R any W sup
        &       (AP_None * L2X_APMult) + L2_ExtPage       ; R sup W sup
        &       (AP_ROM  * L2X_APMult) + L2_ExtPage       ; R any W none

Neil Turton's avatar
Neil Turton committed
267 268 269 270 271 272 273 274 275 276
PageSizes
        &       4*1024                  ; 0 is 4K
        &       8*1024                  ; 4 is 8K
        &       16*1024                 ; 8 is 16
        &       32*1024                 ; C is 32

PageShifts
        =       12, 13, 0, 14           ; 1 2 3 4
        =       0,  0,  0, 15           ; 5 6 7 8

Jeffrey Lee's avatar
Jeffrey Lee committed
277
        LTORG
Neil Turton's avatar
Neil Turton committed
278 279 280

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
Jeffrey Lee's avatar
Jeffrey Lee committed
281
; "ARM600"-specific OS_MMUControl code
Neil Turton's avatar
Neil Turton committed
282
;
Jeffrey Lee's avatar
Jeffrey Lee committed
283

Neil Turton's avatar
Neil Turton committed
284
; in:   r0 = 0 (reason code 0, for modify control register)
Neil Turton's avatar
Neil Turton committed
285 286 287 288 289 290 291
;       r1 = EOR mask
;       r2 = AND mask
;
;       new control = ((old control AND r2) EOR r1)
;
; out:  r1 = old value
;       r2 = new value
Neil Turton's avatar
Neil Turton committed
292 293 294 295 296
MMUControl_ModifyControl ROUT
        Push    "r3,r4,r5"
        CMP     r1,#0
        CMPEQ   r2,#&FFFFFFFF
        BEQ     MMUC_modcon_readonly
Jeffrey Lee's avatar
Jeffrey Lee committed
297
        LDR     r3,=ZeroPage
298 299 300 301
        LDRB    r5,[r3, #ProcessorArch]
        PHPSEI  r4                      ; disable IRQs while we modify soft copy (and possibly switch caches off/on)

        CMP     r5,#ARMv4
302
        LDRLO   lr, [r3, #MMUControlSoftCopy]
303
        ARM_read_control lr,HS
304 305
;        MOVHS   lr,lr,LSL #19
;        MOVHS   lr,lr,LSR #19           ; if ARMv4 or later, we can read control reg. - trust this more than soft copy
Neil Turton's avatar
Neil Turton committed
306 307 308
        AND     r2, r2, lr
        EOR     r2, r2, r1
        MOV     r1, lr
309 310 311
        LDR     r5, [r3, #ProcessorFlags]
        TST     r5, #CPUFlag_SplitCache
        BEQ     %FT05
312 313 314 315 316
 [ {FALSE}
        TST     r2,#MMUC_C              ; if split caches, then I bit mirrors C bit
        ORRNE   r2,r2,#MMUC_I
        BICEQ   r2,r2,#MMUC_I
 ]
Neil Turton's avatar
Neil Turton committed
317
05
Neil Turton's avatar
Neil Turton committed
318 319
        STR     r2, [r3, #MMUControlSoftCopy]
        BIC     lr, r2, r1              ; lr = bits going from 0->1
Neil Turton's avatar
Neil Turton committed
320
        TST     lr, #MMUC_C             ; if cache turning on then flush cache before we do it
321
        TSTEQ   lr, #MMUC_I
Neil Turton's avatar
Neil Turton committed
322
        BEQ     %FT10
323

324
        Push    "r0"
Jeffrey Lee's avatar
Jeffrey Lee committed
325
        ARMop   Cache_InvalidateAll,,,r3
326
        Pull    "r0"
Neil Turton's avatar
Neil Turton committed
327
10
328
        BIC     lr, r1, r2              ; lr = bits going from 1->0
329 330
        TST     lr, #MMUC_C             ; if cache turning off then clean data cache first
        BEQ     %FT15
331
        Push    "r0"
Jeffrey Lee's avatar
Jeffrey Lee committed
332
        ARMop   Cache_CleanAll,,,r3
333
        Pull    "r0"
Neil Turton's avatar
Neil Turton committed
334 335 336 337
15
        ARM_write_control r2
        BIC     lr, r1, r2              ; lr = bits going from 1->0
        TST     lr, #MMUC_C             ; if cache turning off then flush cache afterwards
338
        TSTNE   lr, #MMUC_I
Neil Turton's avatar
Neil Turton committed
339
        BEQ     %FT20
340
        Push    "r0"
Jeffrey Lee's avatar
Jeffrey Lee committed
341
        ARMop   Cache_InvalidateAll,,,r3
342
        Pull    "r0"
Neil Turton's avatar
Neil Turton committed
343
20
Kevin Bracey's avatar
Kevin Bracey committed
344
        PLP     r4                      ; restore IRQ state
Neil Turton's avatar
Neil Turton committed
345 346 347
        Pull    "r3,r4,r5,pc"

MMUC_modcon_readonly
Jeffrey Lee's avatar
Jeffrey Lee committed
348
        LDR     r3, =ZeroPage
349 350
        LDRB    r5, [r3, #ProcessorArch]
        CMP     r5, #ARMv4
351
        LDRLO   lr, [r3, #MMUControlSoftCopy]
352
        ARM_read_control lr,HS
353 354
;        MOVHS   lr,lr,LSL #19
;        MOVHS   lr,lr,LSR #19           ; if ARMv4 or later, we can read control reg. - trust this more than soft copy
355
        STRHS   lr, [r3, #MMUControlSoftCopy]
Neil Turton's avatar
Neil Turton committed
356 357 358 359
        MOV     r1, lr
        MOV     r2, lr
        Pull    "r3,r4,r5,pc"

Neil Turton's avatar
Neil Turton committed
360
        END