memmap 29 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
; 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.
;
; > s.memmap

; low level memory mapping
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239


; ----------------------------------------------------------------------------------
;
; AMB_SetMemMapEntries_MapIn_Lazy:
;
; entry:
;   R1 =  first page index in PMP/AMBNode
;   R5 =  no. of pages (must be >0)
;   R7 =  logical offset in pages - must be zero for this variant of routine
;   R10 = DANode
;
; Lazy task swapping variant of SetMemMapEntries_MapIn
; Performs a lazy map in if lazy task swapping is enabled
;
AMB_SetMemMapEntries_MapIn_Lazy ROUT
  [ AMB_LazyMapIn
        LDR     r7, AMBFlags
        ANDS    r7, r7, #AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend
        MOVEQ   pc, lr ; Just exit if laziness enabled
        MOV     r7, #0
  ]
        ; Fall through...

; ----------------------------------------------------------------------------------
;
; AMB_SetMemMapEntries_MapIn:
;
; entry:
;   R1 =  first page index in PMP/AMBNode
;   R5 =  no. of pages (must be >0)
;   R7 =  logical offset in pages (zero for standard map in)
;   R10 = DANode
;
; Must not be used if current slot is mapped lazily
;
AMB_SetMemMapEntries_MapIn ROUT
        Entry   "r3,r8,r9,r10"
      [ AMB_Debug
        DebugReg r1, "MapIn phys start "
        DebugReg r5, "count "
        DebugReg r7, "log offset "
        DebugReg r10, "node "
      ]
        ; Update DA logical size prior to R10 being clobbered
        LDR     r3,[r10,#DANode_Size]
        ADD     r3,r3,r5,LSL #Log2PageSize
        STR     r3,[r10,#DANode_Size]

        ; Get correct parameters for the low-level calls
        ADD     r3,r1,r7
        MOV     r3,r3,LSL #Log2PageSize
        ADD     r3,r3,#ApplicationStart

        MOV     r8, r5

        LDR     r9,[r10,#DANode_Flags]
        LDR     lr,=DynAreaFlags_AccessMask
        AND     r9,r9,lr

        LDR     r10,[r10,#DANode_PMP]
        ADD     r10,r10,r1,LSL #2

        ; Map in the pages (assuming area currently unmapped)
        BL      AMB_movepagesin_L2PT
        BL      AMB_movepagesin_CAM
      [ PMPParanoid
        BL      ValidatePMPs
      ]
      [ AMB_Debug
        DebugTX "<MapIn"
      ]
        EXIT


; ----------------------------------------------------------------------------------
;
; AMB_SetMemMapEntries_MapOut:
;
; entry:
;   R1 =  first page index in PMP/AMBNode
;   R5 =  no. of pages (must be >0)
;   R7 =  logical offset in pages (zero for standard map out)
;   R10 = DANode
;
; Must not be used if current slot is mapped lazily
;
AMB_SetMemMapEntries_MapOut ROUT
        Entry   "r3,r4,r8,r9,r10"
      [ AMB_Debug
        DebugReg r1, "MapOut phys start "
        DebugReg r5, "count "
        DebugReg r7, "log offset "
        DebugReg r10, "node "
      ]
        ; Update DA logical size prior to R10 being clobbered
        LDR     r3,[r10,#DANode_Size]
        SUB     r3,r3,r5,LSL #Log2PageSize
        STR     r3,[r10,#DANode_Size]

        ; Get correct parameters for the low-level calls
        LDR     r3,[r10,#DANode_Flags]
        LDR     lr,=DynAreaFlags_AccessMask
        AND     r3,r3,lr

        ADD     r4,r1,r7
        MOV     r4,r4,LSL #Log2PageSize
        ADD     r4,r4,#ApplicationStart

        MOV     r8, r5

        MOV     r9, r3

        LDR     r10,[r10,#DANode_PMP]
        ADD     r10,r10,r1,LSL #2

        ; Map out the pages (assuming area currently fully mapped)
        BL      AMB_movecacheablepagesout_L2PT
        BL      AMB_movepagesout_CAM
      [ PMPParanoid
        BL      ValidatePMPs
      ]
      [ AMB_Debug
        DebugTX "<MapOut"
      ]
        EXIT

  [ AMB_LazyMapIn
; ----------------------------------------------------------------------------------
;
; AMB_SetMemMapEntries_MapOut_Lazy:
;
; entry:
;   R1 =  first page index in PMP/AMBNode
;   R5 =  no. of pages (must be >0)
;   R7 =  logical offset in pages - must be zero for this variant of routine
;   R10 = DANode
;
; Lazy task swapping variant of SetMemMapEntries_MapOut
; Performs a sparse map out if lazy task swapping is enabled
;
AMB_SetMemMapEntries_MapOut_Lazy ROUT
        LDR     r7, AMBFlags
        TST     r7, #AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend
        MOV     r7, #0
        BNE     AMB_SetMemMapEntries_MapOut
        ; Perform a sparse map out via MappedInRegister
        ; Keep track of count of mapped in pages so we can early-exit if we unmap them all
        LDR     r7,[r10,#DANode_Size]
        CMP     r7,#0
        MOVEQ   pc,lr ; Hey, there's already nothing there!
        Entry   "r0-r6,r8-r12"
      [ AMB_Debug
        DebugReg r1, "MapOut_Lazy start "
        DebugReg r5, "count "
        DebugReg r10, "node "
        DebugReg r7, "current log size "
      ]

;to do this safely we need to do it in two passes
;first pass makes pages uncacheable
;second pass unmaps them
;n.b. like most of the AMB code, this assumes nothing will trigger an abort-based lazy map in operation while we're in the middle of this processing!

;
;pass one: make pages uncacheable (preserve bitmap, CAM)
;
        LDR     r2,=ZeroPage

;decide if we want to do TLB coherency as we go
        ARMop   Cache_RangeThreshold,,,r2         ;returns threshold (bytes) in r0
        CMP     r5,r7,LSR #Log2PageSize
        MOVLO   r6,r5
        MOVHS   r6,r7,LSR #Log2PageSize           ;r6 = max number of pages we'll be unmapping
        SUB     r6,r6,r0,LSR #Log2PageSize        ;r6 < 0 if doing coherency as we go

        ADD     r5,r5,r1                          ;r5 = end of region to unmap

        MOV     r3,r7                             ;r3 = logical size

        ; Get MappedInRegister ptr
        AND     r8,r1,#31
        MOV     r9,#1
        ADR     r7,AMBMappedInRegister
        MOV     r9,r9,LSL r8                      ;r9 = current bit in word
        BIC     r8,r1,#31
        LDR     r8,[r7,r8,LSR #5-2]!              ;r8 = current word, r7 = ptr
        Push    "r7-r9"

        LDR     r0,[r10,#DANode_Flags]
        LDR     r11,[r2,#MMU_PCBTrans]
        GetTempUncache r12, r0, r11, lr           ;r12 = temp uncache L2PT flags

        MOV     r4,r1                             ;r4 = current index
        LDR     r11,=L2PT+(ApplicationStart:SHR:(Log2PageSize-2));r11 -> L2PT, offset by appspace start
        CMP     r9,#1
        BNE     %FT32
        B       %FT31
30
        ; Advance to next word
        ADD     r4,r4,#32
        LDR     r8,[r7,#4]!
        CMP     r4,r5
        BHS     %FT39
31
        ; Check register word
        TEQ     r8,#0
        BEQ     %BT30
32
        ; Check register bit
        TST     r8,r9
        BEQ     %FT34
        ; Mapped in page found, make uncacheable
        LDR     r0,[r11,r4,LSL #2]                ;Get current L2PT entry
        CMP     r6,#0
        BIC     r0,r0,#TempUncache_L2PTMask
        ORR     r0,r0,r12
        STR     r0,[r11,r4,LSL #2]                ;Update L2PT
        BGE     %FT33
        ; Do cache/TLB maintenance
        MOV     r1,r4,LSL #Log2PageSize
        ADD     r0,r1,#ApplicationStart
240
        ARMop   MMU_ChangingEntry,,,r2
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
33
        SUBS    r3,r3,#PageSize
        ADDEQ   r5,r4,#1                          ;mapped out all pages in slot; set end to current+1
34
        ; Exit if we've just processed the last page
        ADD     r4,r4,#1
        CMP     r4,r5
        BEQ     %FT40
        ; Advance to next bit of current word
        MOVS    r9,r9,LSL #1
        BCC     %BT32
        ; Finished the word, go back to per-word loop if necessary
        LDR     r8,[r7,#4]!
        MOV     r9,#1
        CMP     r8,#0
        BEQ     %BT30                             ;Next word empty, skip it
        B       %BT32                             ;Not empty, process it

39
        ; Reached end of region
        LDR     r0,[r10,#DANode_Size]
        CMP     r0,r3
        ADDEQ   sp,sp,#12                         ;Junk stacked r7-r9
        BEQ     %FT95                             ;Nothing in region to map out

40
        ; Do global maintenance if required
        CMP     r6,#0
        BLT     %FT41
270
        ARMop   MMU_Changing,,,r2
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
41

;
;pass two: unmap pages (+ clear bitmap + update CAM)
;
        Pull    "r7-r9"
        FRAMLDR r4,,r1
        STR     r3,[r10,#DANode_Size]             ;Write back new logical size

        LDR     r10,[r10,#DANode_PMP]             ;r10 -> page list
        LDR     r3,[r2,#CamEntriesPointer]
        LDR     r12,=DuffEntry

        CMP     r9,#1
        BNE     %FT52
        B       %FT51
50
        ; Advance to next word
        ADD     r4,r4,#32
        LDR     r8,[r7,#4]!
        CMP     r4,r5
        BHS     %FT59
51
        ; Check register word
        TEQ     r8,#0
        BEQ     %BT50
52
        ; Check register bit
        TST     r8,r9
        BEQ     %FT54
        ; Mapped in page found, unmap it
        MOV     lr,#0
        LDR     r0,[r10,r4,LSL #2]                ;Get page number
        STR     lr,[r11,r4,LSL #2]                ;Zero L2PT
        BIC     r8,r8,r9
        ASSERT  CAM_LogAddr=0
        STR     r12,[r3,r0,LSL #CAM_EntrySizeLog2] ;Update CAM
        CMP     r6,#0
        BGE     %FT53
        ; Do TLB maintenance
        MOV     r1,r4,LSL #Log2PageSize
        ADD     r0,r1,#ApplicationStart
        ARMop   MMU_ChangingUncachedEntry,,,r2    ;flush TLB
53
54
        ; Exit if we've just processed the last page
        ADD     r4,r4,#1
        CMP     r4,r5
        BEQ     %FT55
        ; Advance to next bit of current word
        MOVS    r9,r9,LSL #1
        BCC     %BT52
        ; Finished the word, go back to per-word loop if necessary
        STR     r8,[r7]                           ;Writeback new value
        LDR     r8,[r7,#4]!
        MOV     r9,#1
        CMP     r8,#0
        BEQ     %BT50                             ;Next word empty, skip it
        B       %BT52                             ;Not empty, process it

55
        ; Writeback last bitmap word
        STR     r8,[r7]

59
        ; Reached end of region

        ; Do global maintenance if required
        CMP     r6,#0
        BLT     %FT95
        ARMop   MMU_ChangingUncached,,,r2

95
      [ AMB_Debug
        DebugTX "<MapOut"
        FRAMLDR r10
        LDR     r11,[r10,#DANode_Size]
        DebugReg r11, "new log size "
      ]
      [ PMPParanoid
        BL      ValidatePMPs
      ]
        MOV     r7,#0
        EXIT
  |
AMB_SetMemMapEntries_MapOut_Lazy * AMB_SetMemMapEntries_MapOut
  ]

Neil Turton's avatar
Neil Turton committed
359
;
360 361 362
; ----------------------------------------------------------------------------------
;
;convert page number in $pnum to L2PT entry (physical address+protection bits),
363
;using cached PhysRamTable entries for speed
Neil Turton's avatar
Neil Turton committed
364
;
365 366
;entry: $ptable -> PhysRamTable, $pbits = protection bits
;       $cache0, $cache1, $cache2 = PhysRamTable cache
367
;exit:  $temp corrupted
368
;       $cache0, $cache1, $cache2 updated
Neil Turton's avatar
Neil Turton committed
369
;
370

Neil Turton's avatar
Neil Turton committed
371
        MACRO
372 373 374 375 376 377
        PageNumToL2PT $pnum,$ptable,$cache0,$cache1,$cache2,$pbits,$temp
        SUB     $temp,$pnum,$cache0 ; no. pages into block
        CMP     $temp,$cache2
        BLHS    PageNumToL2PTCache_$ptable._$cache0._$cache1._$cache2._$temp
        ADD     $pnum,$cache1,$temp,LSL #Log2PageSize ; physical address of page
        ORR     $pnum,$pbits,$pnum ; munge in protection bits
Neil Turton's avatar
Neil Turton committed
378 379
        MEND

380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
        MACRO
        PageNumToL2PTInit $ptable,$cache0,$cache1,$cache2
        ASSERT  $cache2 > $cache1
        LDR     $ptable,=ZeroPage+PhysRamTable
        MOV     $cache0,#0
        LDMIA   $ptable,{$cache1,$cache2}
        MOV     $cache2,$cache2,LSR #12
        MEND

PageNumToL2PTCache_r4_r5_r6_r7_r12 ROUT
        Entry   "r4"
        ADD     r12,r12,r5 ; Restore page number
        MOV     r5,#0
10
        LDMIA   r4!,{r6,r7} ; Get PhysRamTable entry
        MOV     r7,r7,LSR #12
        CMP     r12,r7
        SUBHS   r12,r12,r7
        ADDHS   r5,r5,r7
        BHS     %BT10
        EXIT    ; r5-r7 = cache entry, r12 = offset into entry

402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424

  [ AMB_LazyMapIn

; ----------------------------------------------------------------------------------
;
;AMB_LazyFixUp
;
; *Only* for ARMs where the abort handler can restart instructions
;
; Routine to be used in abort handlers (in abort32 mode), that checks to see if abort
; is expected, and fixes things up if so, ready to restart instruction.
;
; Fix up consists of mapping in affected page, and updating AMBMappedInRegister. This
; may seem like a lot of work, but remember that the L2PT and CAM updates for each page are
; needed anyway in non-lazy scheme, so there is really only a housekeeping overhead.
;
; There is no cache clean/flush consideration here, since the map is a map in from Nowhere.
; TLB flush consideration is left to main abort handler code - in fact there may not
; be a TLB flush consideration at all, if ARM TLB can be assumed not to cache an
; entry which is a translation fault, as seems rational.
;
; entry: r0 = aborting address (data address for data abort, instruction address
;        for prefetch abort), r1-r7 trashable, no stack
425
;        r2 = 1 for prefetch abort, 0 for data abort
426
;        FSR valid for data aborts, unpredictable for prefetch aborts
427
; exit:  r0 = non-zero (NE status) if abort was expected and fixed up, zero (EQ status) if not
428
;        FAR,FSR,SPSR_abt,lr_abt preserved
429 430 431
;
AMB_LazyFixUp ROUT
        MOV     r7,r12
Jeffrey Lee's avatar
Jeffrey Lee committed
432
        LDR     r12,=ZeroPage+AMBControl_ws
433 434
        LDR     r12,[r12]
        CMP     r12,#0
435
        BEQ     %FT90                                    ;not initialised!
436 437
        LDR     r1,AMBFlags
        TST     r1,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend
438
        BNE     %FT90                                    ;not active
439 440
        LDR     r1,AMBMappedInNode
        CMP     r1,#0
441
        BEQ     %FT90                                    ;no current node
442
        ARM_read_FSR r6                                  ;hang onto FSR in case we have to preserve it
443
        TEQ     r2,#1                                    ;if data abort
444 445 446
        ANDNE   r3,r6,#&F
        TEQNE   r3,#7                                    ; and not a page translation fault
        BNE     %FT20                                    ; then not a lazy abort (and FAR may be invalid anyway)
447
        LDR     r2,[r1,#AMBNode_DANode+DANode_PMPSize]
448
        SUBS    r0,r0,#ApplicationStart
449
        BLO     %FT20                                    ;abort not in current app space
450
        MOV     r0,r0,LSR #Log2PageSize                  ;address now in terms of pages from ApplicationStart
451 452
        CMP     r0,r2
        BHS     %FT20                                    ;abort not in current app space
453 454 455 456 457
      [ AMB_Debug
        Push    "lr"
        DebugReg r0, "Lazy "
        Pull    "lr"
      ]
458
;
459 460 461
; check/update the MappedIn bitmap
;
        ADR     r2,AMBMappedInRegister
462
        MOV     r5,#1
463 464 465 466 467
        ADD     r2,r2,r0,LSR #5-2
        BIC     r2,r2,#3                                 ;r2 -> bitmap word affected
        AND     r3,r0,#31
        MOV     r5,r5,LSL r3                             ;mask for bit affected in bitmap word
        LDR     r3,[r2]
468
        LDR     r4,[r1,#AMBNode_DANode+DANode_Size]      ;count it
469 470 471 472
        TST     r3,r5                                    ;if page already mapped in, not a lazy abort
        BNE     %FT20
        ORR     r3,r3,r5                                 ;ok, mark that we are going to map this page in
        STR     r3,[r2]
473 474 475 476 477 478 479 480
        ADD     r4,r4,#PageSize
        STR     r4,[r1,#AMBNode_DANode+DANode_Size]
        ; Update sparse HWM
        MOV     r3,r0,LSL #Log2PageSize
        LDR     r4,[r1,#AMBNode_DANode+DANode_SparseHWM]
        ADD     r3,r3,#ApplicationStart+PageSize
        CMP     r3,r4
        STRHI   r3,[r1,#AMBNode_DANode+DANode_SparseHWM]
481 482
;
; now map in the the page that went pop
483
;
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
        LDR     r1,[r1,#AMBNode_DANode+DANode_PMP]
        LDR     r2,=ZeroPage+PhysRamTable
        LDR     r3,[r1,r0,LSL #2]                        ;r3 = page involved
        MOV     r6,r3
10
        LDMIA   r2!,{r4,r5}
        MOV     r5,r5,LSR #12
        CMP     r6,r5
        SUBHS   r6,r6,r5
        BHS     %BT10
     [ {FALSE}
        LDR     r1,AMBPageFlags
        ADD     r4,r4,r6,LSL #12
        ORR     r4,r4,r1
        MOV     r1,#0                                    ;0 = AP for ordinary page
     |
        ADD     r4,r4,r6,LSL #12
        MOV     r1,#DynAreaFlags_PMP
        GetPTE  r4,4K,r4,r1
     ]
504
;
505
;here, r0 = page index into appslot, r1 = PPL, r3 = page number of page involved, r4 = new L2PT entry value to map in page
506 507
;
        ADD     r0,r0,#ApplicationStart:SHR:Log2PageSize ;address now in terms of pages from 0
508
        LDR     r5,=L2PT
509
        STR     r4,[r5,r0,LSL #2]                        ;update L2PT
510
;
Jeffrey Lee's avatar
Jeffrey Lee committed
511
        LDR     r5,=ZeroPage
512
        LDR     r5,[r5,#CamEntriesPointer]
513
        ADD     r5,r5,r3,LSL #CAM_EntrySizeLog2          ;r5 -> CAM entry affected
514
        MOVS    r0,r0,LSL #Log2PageSize                  ;address is now ordinary again, and must be non-zero
515 516 517
        LDR     r12,[r5,#CAM_PageFlags]
        AND     r12,r12,#StickyPageFlags
        ORR     r1,r1,r12
518 519
        ASSERT  CAM_LogAddr=0
        ASSERT  CAM_PageFlags=4
520 521
        STMIA   r5,{r0,r1}                               ;update CAM entry
        MOV     r12,r7
522
        MOV     pc,lr                                    ;r0 is non-zero, NE status
523 524 525 526
;
; not our abort, but is possible that client abort handler is in app space, so force all
; app space pages in now (so that client abort handler does not cause lazy abort, scribbling over original abort details)
;
527
20
528 529
        MOV     r1,#ApplicationStart                     ;good old page walk to provoke lazy fixups
        LDR     r2,AMBMappedInNode
530
        LDR     r2,[r2,#AMBNode_DANode+DANode_PMPSize]
531 532 533 534
        CMP     r2,#0
        BEQ     %FT90
        MRS     r0,SPSR                                  ;preserve SPSR_abort for original abort details
        MOV     r4,lr                                    ;preserve lr_abort so we can return properly (!)
535 536
        ARM_read_FAR r5                                  ;preserve FAR in case client abort handler wants to read it
                                                         ;preserve FSR (already in r6) similarly
537 538 539 540 541
30
        LDR     r3,[r1]                                  ;bring that page in by the magic of aborts
        SUBS    r2,r2,#1
        ADD     r1,r1,#PageSize
        BNE     %BT30
542
        MSR     SPSR_cxsf,r0                             ;SPSR for original abort
543
        MOV     lr,r4                                    ;restore return address
544 545
        ARM_write_FAR r5                                 ;restore FAR
        ARM_write_FSR r6                                 ;restore FSR
546
      [ MEMM_Type = "VMSAv6"
547
        myISB   ,r0 ; Not sure if this is necessary or not; do it just in case
548
      ]
549 550
;
90
551
        MOVS    r0,#0
552
        MOV     r12,r7
553
        MOV     pc,lr                                    ;r0 is zero, EQ status
554 555 556

  ] ;AMB_LazyMapIn

557 558 559 560 561 562 563 564 565 566 567
; ----------------------------------------------------------------------------------

  [ AMB_LazyMapIn

;
; If page of given logical address (r0) is in current app space, make sure page is
; 'honest' ie. properly mapped in. This is for things like FindMemMapEntries
; that must return sensible info (and presumably their client needs a consistent
; view of app space mapping, so that laziness is transparent)
;
AMB_MakeHonestLA  ROUT
568
        CMP     r0,#AplWorkMaxSize                       ;quick dismiss if definitely not app address
569 570
        MOVHS   pc,lr
        Push    "r1,r12,lr"
Jeffrey Lee's avatar
Jeffrey Lee committed
571
        LDR     r12,=ZeroPage+AMBControl_ws
572 573 574 575 576 577 578 579 580
        LDR     r12,[r12]
        CMP     r12,#0
        BEQ     %FT90                                    ;we're dormant!
        SUBS    r14,r0,#ApplicationStart
        BMI     %FT90                                    ;below app space
        MOV     r14,r14,LSR #Log2PageSize                ;pages from ApplicationStart
        LDR     r1,AMBMappedInNode
        CMP     r1,#0
        BEQ     %FT90                                    ;no node mapped in
581
        LDR     r1,[r1,#AMBNode_DANode+DANode_PMPSize]
582
        CMP     r1,r14                                   ;HI if log addr is in current app space
583
        LDRHIB  r1, [r0,#0]                              ;make honest if necessary (magic of abort fixups!)
584 585 586 587 588 589 590 591
90
        Pull    "r1,r12,pc"


; similar to AMB_MakeHonestLA, but for page of given page number (r0)
;
AMB_MakeHonestPN  ROUT
        Push    "r1-r3,r12,lr"
592 593
        LDR     r14,=ZeroPage
        LDR     r12,[r14,#AMBControl_ws]
594 595 596 597 598 599
        CMP     r12,#0
        BEQ     %FT90                                    ;we're dormant!
        LDR     r1,[r14,#MaxCamEntry]
        CMP     r0,r1
        BHI     %FT90                                    ;invalid page number
        LDR     r1,[r14,#CamEntriesPointer]
600 601 602 603 604 605
        ADD     r1,r1,r0,LSL #CAM_EntrySizeLog2
        ASSERT  CAM_LogAddr = 0
        ASSERT  CAM_PageFlags = 4
        ASSERT  CAM_PMP = 8
        ASSERT  CAM_PMPIndex = 12
        LDMIA   r1,{r1-r3,r14}
606
        ASSERT  CAM_LogAddr = 0
607 608 609 610
        TST     r2,#DynAreaFlags_PMP                     ;can't be one of ours if not owned by a PMP
        BEQ     %FT90
        LDR     r2,=Nowhere
        TEQ     r1,r2
611 612
        BNE     %FT90                                    ;only a page at Nowhere might be dishonest
        LDR     r1,AMBMappedInNode                       ;let's check the current node
613 614 615 616 617 618
        ADD     r1,r1,#AMBNode_DANode
        CMP     r3,r1
        BNE     %FT90                                    ;doesn't belong to current node, or there is no current node
        ; r14 is the index within the PMP, and the flat logical<->physical indexing scheme used by AMB means it will also be the logical index into application space
        MOV     r2,#ApplicationStart
        LDRB    r2,[r2,r14,LSL #Log2PageSize]            ;make honest if necessary (magic of abort fixups!)
619 620 621 622
90
        Pull    "r1-r3,r12,pc"

  ] ;AMB_LazyMapIn
623 624 625

; ----------------------------------------------------------------------------------
;
Neil Turton's avatar
Neil Turton committed
626 627 628 629 630 631 632
;AMB_movepagesin_L2PT
;
;updates L2PT for new logical page positions, does not update CAM
;
; entry:
;       r3  =  new logical address of 1st page
;       r8  =  number of pages
633
;       r9  =  page flags
Neil Turton's avatar
Neil Turton committed
634 635 636
;       r10 -> page list
;
AMB_movepagesin_L2PT ROUT
637 638 639 640 641 642
        Entry   "r0-r12"

        MOV     r0, #0
        GetPTE  r11, 4K, r0, r9

        PageNumToL2PTInit r4,r5,r6,r7
Neil Turton's avatar
Neil Turton committed
643 644 645 646

        LDR     r9,=L2PT
        ADD     r9,r9,r3,LSR #(Log2PageSize-2) ;r9 -> L2PT for 1st new logical page

647
        CMP     r8,#4
Neil Turton's avatar
Neil Turton committed
648 649
        BLT     %FT20
10
650 651 652 653 654 655 656 657
        LDMIA   r10!,{r0-r3}         ;next 4 page numbers
        PageNumToL2PT r0,r4,r5,r6,r7,r11,r12
        PageNumToL2PT r1,r4,r5,r6,r7,r11,r12
        PageNumToL2PT r2,r4,r5,r6,r7,r11,r12
        PageNumToL2PT r3,r4,r5,r6,r7,r11,r12
        STMIA   r9!,{r0-r3}          ;write 4 L2PT entries
        SUB     r8,r8,#4
        CMP     r8,#4
Neil Turton's avatar
Neil Turton committed
658 659 660 661 662 663
        BGE     %BT10
20
        CMP     r8,#0
        BEQ     %FT35
30
        LDR     r0,[r10],#4
664
        PageNumToL2PT r0,r4,r5,r6,r7,r11,r12
Neil Turton's avatar
Neil Turton committed
665 666 667 668
        STR     r0,[r9],#4
        SUBS    r8,r8,#1
        BNE     %BT30
35
669
        PageTableSync
670
        EXIT
Neil Turton's avatar
Neil Turton committed
671

672 673
; ----------------------------------------------------------------------------------
;
Neil Turton's avatar
Neil Turton committed
674 675 676 677 678 679
;update CAM entry for page number in $reg
;
;entry: r11 -> CAM, r9 = logical addr of page, lr = PPL of page
;exit: $reg = addr of CAM entry
;
        MACRO
680
        UpdateCAM $reg,$temp
681
        ADD     $reg,r11,$reg,LSL #CAM_EntrySizeLog2 ;r0 -> CAM entry for 1st page
682 683 684 685
        LDR     $temp,[$reg,#CAM_PageFlags]
        AND     $temp,$temp,#StickyPageFlags
        ORR     $temp,$temp,lr
      [ $temp > r9
686 687
        ASSERT  CAM_LogAddr=0
        ASSERT  CAM_PageFlags=4
688 689 690 691 692
        STMIA   $reg,{r9,$temp}            ;store logical addr,PPL
      |
        STR     r9,[$reg,#CAM_LogAddr]
        STR     $temp,[$reg,#CAM_PageFlags]
      ]
Neil Turton's avatar
Neil Turton committed
693 694
        MEND

695 696
; ----------------------------------------------------------------------------------
;
Neil Turton's avatar
Neil Turton committed
697 698 699 700 701 702 703 704 705 706 707
;AMB_movepagesin_CAM
;
;updates CAM, does not update L2PT
;
; entry:
;       r3  =  new logical address of 1st page
;       r8  =  number of pages
;       r9  =  PPL for CAM
;       r10 -> page list
;
AMB_movepagesin_CAM ROUT
708
        Entry   "r0-r12"
Neil Turton's avatar
Neil Turton committed
709 710


711
        BIC     lr,r9,#StickyPageFlags
Neil Turton's avatar
Neil Turton committed
712
        MOV     r9,r3
Jeffrey Lee's avatar
Jeffrey Lee committed
713
        LDR     r11,=ZeroPage
Neil Turton's avatar
Neil Turton committed
714 715 716 717 718 719
        LDR     r11,[r11,#CamEntriesPointer]   ;r11 -> CAM

        CMP     r8,#8
        BLT     %FT20
10
        LDMIA   r10!,{r0-r7}                   ;next 8 page numbers
720
        UpdateCAM r0,r12
Neil Turton's avatar
Neil Turton committed
721
        ADD     r9,r9,#PageSize                ;next logical addr
722
        UpdateCAM r1,r12
Neil Turton's avatar
Neil Turton committed
723
        ADD     r9,r9,#PageSize
724
        UpdateCAM r2,r12
Neil Turton's avatar
Neil Turton committed
725
        ADD     r9,r9,#PageSize
726
        UpdateCAM r3,r12
Neil Turton's avatar
Neil Turton committed
727
        ADD     r9,r9,#PageSize
728
        UpdateCAM r4,r12
Neil Turton's avatar
Neil Turton committed
729
        ADD     r9,r9,#PageSize
730
        UpdateCAM r5,r12
Neil Turton's avatar
Neil Turton committed
731
        ADD     r9,r9,#PageSize
732
        UpdateCAM r6,r12
Neil Turton's avatar
Neil Turton committed
733
        ADD     r9,r9,#PageSize
734
        UpdateCAM r7,r12
Neil Turton's avatar
Neil Turton committed
735 736 737 738 739 740
        ADD     r9,r9,#PageSize
        SUB     r8,r8,#8
        CMP     r8,#8
        BGE     %BT10
20
        CMP     r8,#0
741
        EXIT    EQ
Neil Turton's avatar
Neil Turton committed
742 743
30
        LDR     r0,[r10],#4
744
        UpdateCAM r0,r12
Neil Turton's avatar
Neil Turton committed
745 746 747
        ADD     r9,r9,#PageSize
        SUBS    r8,r8,#1
        BNE     %BT30
748
        EXIT
Neil Turton's avatar
Neil Turton committed
749

750 751
; ----------------------------------------------------------------------------------
;
Neil Turton's avatar
Neil Turton committed
752 753 754 755 756 757 758 759 760 761
;AMB_movepagesout_CAM
;
;updates CAM, does not update L2PT
;
; entry:
;       r8  =  number of pages
;       r9  =  PPL for CAM
;       r10 -> page list
;
AMB_movepagesout_CAM ROUT
762
        Entry   "r0-r12"
Neil Turton's avatar
Neil Turton committed
763

764
        BIC     lr,r9,#StickyPageFlags
Neil Turton's avatar
Neil Turton committed
765
        LDR     r9,=DuffEntry
Jeffrey Lee's avatar
Jeffrey Lee committed
766
        LDR     r11,=ZeroPage
Neil Turton's avatar
Neil Turton committed
767 768 769 770 771 772
        LDR     r11,[r11,#CamEntriesPointer]   ;r11 -> CAM

        CMP     r8,#8
        BLT     %FT20
10
        LDMIA   r10!,{r0-r7}                   ;next 8 page numbers
773 774 775 776 777 778 779 780
        UpdateCAM r0,r12
        UpdateCAM r1,r12
        UpdateCAM r2,r12
        UpdateCAM r3,r12
        UpdateCAM r4,r12
        UpdateCAM r5,r12
        UpdateCAM r6,r12
        UpdateCAM r7,r12
Neil Turton's avatar
Neil Turton committed
781 782 783 784 785
        SUB     r8,r8,#8
        CMP     r8,#8
        BGE     %BT10
20
        CMP     r8,#0
786
        EXIT    EQ
Neil Turton's avatar
Neil Turton committed
787 788
30
        LDR     r0,[r10],#4
789
        UpdateCAM r0,r12
Neil Turton's avatar
Neil Turton committed
790 791
        SUBS    r8,r8,#1
        BNE     %BT30
792
        EXIT
Neil Turton's avatar
Neil Turton committed
793

794 795
; ----------------------------------------------------------------------------------
;
Jeffrey Lee's avatar
Jeffrey Lee committed
796
;AMB_movecacheablepagesout_L2PT
Neil Turton's avatar
Neil Turton committed
797 798 799 800
;
;updates L2PT for old logical page positions, does not update CAM
;
; entry:
Jeffrey Lee's avatar
Jeffrey Lee committed
801
;       r3  =  old page flags
Neil Turton's avatar
Neil Turton committed
802 803 804
;       r4  =  old logical address of 1st page
;       r8  =  number of pages
;
Jeffrey Lee's avatar
Jeffrey Lee committed
805 806
AMB_movecacheablepagesout_L2PT
        Entry   "r0-r8"
Neil Turton's avatar
Neil Turton committed
807

Jeffrey Lee's avatar
Jeffrey Lee committed
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847
        ; Calculate L2PT flags needed to make the pages uncacheable
        ; Assume all pages will have identical flags (or at least close enough)
        LDR     lr,=ZeroPage
        LDR     lr,[lr, #MMU_PCBTrans]
        GetTempUncache r0, r3, lr, r1
        LDR     r1, =TempUncache_L2PTMask

        LDR     lr,=L2PT
        ADD     lr,lr,r4,LSR #(Log2PageSize-2)    ;lr -> L2PT 1st entry

        CMP     r8,#4
        BLT     %FT20
10
        LDMIA   lr,{r2-r5}
        BIC     r2,r2,r1
        BIC     r3,r3,r1
        BIC     r4,r4,r1
        BIC     r5,r5,r1
        ORR     r2,r2,r0
        ORR     r3,r3,r0
        ORR     r4,r4,r0
        ORR     r5,r5,r0
        STMIA   lr!,{r2-r5}
        SUB     r8,r8,#4
        CMP     r8,#4
        BGE     %BT10
20
        CMP     r8,#0
        BEQ     %FT35
30
        LDR     r2,[lr]
        BIC     r2,r2,r1
        ORR     r2,r2,r0
        STR     r2,[lr],#4
        SUBS    r8,r8,#1
        BNE     %BT30
35
        FRAMLDR r0,,r4                           ;address of 1st page
        FRAMLDR r1,,r8                           ;number of pages
        LDR     r3,=ZeroPage
848
        ARMop   MMU_ChangingEntries,,,r3
Jeffrey Lee's avatar
Jeffrey Lee committed
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865
        FRAMLDR r4
        FRAMLDR r8
        B       %FT55 ; -> moveuncacheablepagesout_L2PT (avoid pop+push of large stack frame)

; ----------------------------------------------------------------------------------
;
;AMB_moveuncacheablepagesout_L2PT
;
;updates L2PT for old logical page positions, does not update CAM
;
; entry:
;       r4  =  old logical address of 1st page
;       r8  =  number of pages
;
AMB_moveuncacheablepagesout_L2PT
        ALTENTRY
55      ; Enter here from moveuncacheablepagesout
Neil Turton's avatar
Neil Turton committed
866 867 868 869 870 871 872 873 874 875 876 877 878
        LDR     lr,=L2PT
        ADD     lr,lr,r4,LSR #(Log2PageSize-2)    ;lr -> L2PT 1st entry

        MOV     r0,#0                             ;0 means translation fault
        MOV     r1,#0
        MOV     r2,#0
        MOV     r3,#0
        MOV     r4,#0
        MOV     r5,#0
        MOV     r6,#0
        MOV     r7,#0

        CMP     r8,#8
Jeffrey Lee's avatar
Jeffrey Lee committed
879 880
        BLT     %FT70
60
Neil Turton's avatar
Neil Turton committed
881 882 883
        STMIA   lr!,{r0-r7}                       ;blam! (8 entries)
        SUB     r8,r8,#8
        CMP     r8,#8
Jeffrey Lee's avatar
Jeffrey Lee committed
884 885
        BGE     %BT60
70
Neil Turton's avatar
Neil Turton committed
886
        CMP     r8,#0
Jeffrey Lee's avatar
Jeffrey Lee committed
887 888
        BEQ     %FT85
80
Neil Turton's avatar
Neil Turton committed
889 890
        STR     r0,[lr],#4
        SUBS    r8,r8,#1
Jeffrey Lee's avatar
Jeffrey Lee committed
891 892 893 894 895 896 897
        BNE     %BT80
85
        FRAMLDR r0,,r4                           ;address of 1st page
        FRAMLDR r1,,r8                           ;number of pages
        LDR     r3,=ZeroPage
        ARMop   MMU_ChangingUncachedEntries,,,r3 ;no cache worries, hoorah
        EXIT
Neil Turton's avatar
Neil Turton committed
898 899 900 901 902


        LTORG

    END