MemInfo 89.9 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 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
; 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.
;
; > MemInfo

        LTORG

;----------------------------------------------------------------------------------------
; MemorySWI
;
;       In:     r0 = reason code and flags
;                       bits 0-7  = reason code
;                       bits 3-31 = reason specific flags
;       Out:    specific to reason codes
;
;       Perform miscellaneous operations for memory management.
;
MemorySWI       ROUT
        Push    lr                              ; Save real return address.
        AND     lr, r0, #&FF                    ; Get reason code.
        CMP     lr, #(%40-%30):SHR:2            ; If valid reason code then
        ADDCC   lr, lr, #(%30-%10):SHR:2        ;   determine where to jump to in branch table,
        ADDCC   lr, pc, lr, LSL #2
        Push    lr, CC                          ;   save address so we can
10
        ADRCC   lr, MemReturn                   ;   set up default return address for handler routines
        Pull    pc, CC                          ;   and jump into branch table.
20
        ADRL    r0, ErrorBlock_HeapBadReason    ; Otherwise, unknown reason code.
        SETV
        ; Drop through to...

MemReturn
 [ International
        BLVS    TranslateError
 ]
        Pull    lr                              ; Get back real return address.
        BVS     SLVK_SetV
        ExitSWIHandler

30
53
        B       MemoryConvertFIQCheck           ; 0
Neil Turton's avatar
Neil Turton committed
54 55 56 57 58
        B       %BT20                           ; Reason codes 1-5 are reserved.
        B       %BT20
        B       %BT20
        B       %BT20
        B       %BT20
59 60 61 62
        B       MemoryPhysSize                  ; 6
        B       MemoryReadPhys                  ; 7
        B       MemoryAmounts                   ; 8
        B       MemoryIOSpace                   ; 9
63
        B       %BT20                           ; Reason code 10 reserved (for free pool locking)
64
        B       %BT20                           ; Reason code 11 reserved (for PCImapping).
65 66 67 68
        B       RecommendPage                   ; 12
        B       MapIOpermanent                  ; 13
        B       AccessPhysAddr                  ; 14
        B       ReleasePhysAddr                 ; 15
69
        B       MemoryAreaInfo                  ; 16
70 71
        B       MemoryAccessPrivileges          ; 17
        B       FindAccessPrivilege             ; 18
72
        B       DMAPrep                         ; 19
73
        B       ChangeCompatibility             ; 20
74
        B       MapIO64permanent                ; 21
75
        B       AccessPhysAddr64                ; 22
76
        B       ReservePages                    ; 23
77 78
        B       CheckMemoryAccess               ; 24
                                                ; 25+ reserved for ROL
Neil Turton's avatar
Neil Turton committed
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
40


;----------------------------------------------------------------------------------------
; MemoryConvert
;
;       In:     r0 = flags
;                       bit     meaning
;                       0-7     0 (reason code)
;                       8       page number provided when set
;                       9       logical address provided when set
;                       10      physical address provided when set
;                       11      fill in page number when set
;                       12      fill in logical address when set
;                       13      fill in physical address when set
;                       14-15   0,1=don't change cacheability
;                               2=disable caching on these pages
;                               3=enable caching on these pages
;                       16-31   reserved (set to 0)
;               r1 -> page block
;               r2 = number of 3 word entries in page block
;
;       Out:    r1 -> updated page block
;
;       Converts between representations of memory addresses. Can also set the
;       cacheability of the specified pages.
;

; Declare symbols used for decoding flags (given and wanted are used
; so that C can be cleared by rotates of the form a,b). We have to munge
; the flags a bit to make the rotates even.
;
ppn             *       1:SHL:0         ; Bits for address formats.
logical         *       1:SHL:1
physical        *       1:SHL:2
all             *       ppn :OR: logical :OR: physical
given           *       24              ; Rotate for given fields.
wanted          *       20              ; Rotate for wanted fields.
ppn_bits        *       ((ppn :SHL: 4) :OR: ppn)
logical_bits    *       ((logical :SHL: 4) :OR: logical)
physical_bits   *       ((physical :SHL: 4) :OR: physical)
cacheable_bit   *       1:SHL:15
alter_cacheable *       1:SHL:16

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
; Small wrapper to make sure FIQs are disabled if we're making pages uncacheable
; (Modern ARMs ignore unexpected cache hits, so big coherency issues if we make
; a page uncacheable which is being used by FIQ).
MemoryConvertFIQCheck ROUT
        AND     r11, r0, #3:SHL:14
        TEQ     r11, #2:SHL:14
        BNE     MemoryConvertNoFIQCheck
        Entry   "r0-r1"
        MOV     r1, #Service_ClaimFIQ
        SWI     XOS_ServiceCall
        LDMIA   sp, {r0-r1}
        BL      MemoryConvertNoFIQCheck
        FRAMSTR r0
        MRS     r11, CPSR
        MOV     r1, #Service_ReleaseFIQ
        SWI     XOS_ServiceCall
139
        MSR     CPSR_f, r11
140 141 142
        EXIT

MemoryConvertNoFIQCheck   ROUT
143
        Entry   "r0-r11"                ; Need lots of registers!!
Neil Turton's avatar
Neil Turton committed
144

Kevin Bracey's avatar
Kevin Bracey committed
145 146 147 148 149
;        MRS     lr, CPSR
;        Push    "lr"
;        ORR     lr, lr, #I32_bit+F32_bit
;        MSR     CPSR_c, lr

Neil Turton's avatar
Neil Turton committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163
        BIC     lr, r0, #all,given      ; Need to munge r0 to get rotates to work (must be even).
        AND     r0, r0, #all,given
        ORR     r0, r0, lr, LSL #1      ; Move bits 11-30 to 12-31.

        TST     r0, #all,given          ; Check for invalid argument (no fields provided)
        TEQNE   r2, #0                  ;   (no entries in table).
        ADREQL  r0, ErrorBlock_BadParameters
        BEQ     %FT95

        EOR     lr, r0, r0, LSL #given-wanted   ; If flag bits 8-10 and 12-14 contain common bits then
        AND     lr, lr, #all,wanted             ;   clear bits in 12-14 (ie. don't fill in fields already given).
        EOR     lr, lr, #all,wanted
        BIC     r0, r0, lr

Jeffrey Lee's avatar
Jeffrey Lee committed
164
        LDR     r6, =ZeroPage
Neil Turton's avatar
Neil Turton committed
165 166 167 168 169 170
        LDR     r7, [r6, #MaxCamEntry]
        LDR     r6, [r6, #CamEntriesPointer]
10
        SUBS    r2, r2, #1
        BCC     %FT70

171 172
        LDMIA   r1!, {r3-r4,r8}         ; Get next three word entry (PN,LA,PA) and move on pointer.
        MOV     r9, #0                  ; Top half of PA is zero
Neil Turton's avatar
Neil Turton committed
173

174
   [ AMB_LazyMapIn
175 176 177
        BL      handle_AMBHonesty       ; may need to make page honest (as if not lazily mapped)
   ]

Neil Turton's avatar
Neil Turton committed
178 179
        TST     r0, #physical,wanted    ; If PA not wanted
        BEQ     %FT20                   ;   then skip.
180 181 182 183 184 185
        TST     r0, #logical,given      ; If LA given (rotate clears C) then
        ADR     lr, %FT15
        BNE     logical_to_physical     ; Get PA from LA
        BL      ppn_to_logical          ; Else get LA from PN (PA wanted (not given) & LA not given => PN given).
        BLCC    ppn_to_physical         ; And get PA from PN (more accurate than getting PA from LA - page may be mapped out)
15
Neil Turton's avatar
Neil Turton committed
186 187 188
        BCS     %FT80
        TST     r0, #logical,wanted
        STRNE   r4, [r1, #-8]           ; Store back LA if wanted.
189
        STR     r8, [r1, #-4]           ; Store back PA.
Neil Turton's avatar
Neil Turton committed
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
20
        TST     r0, #alter_cacheable    ; If altering cacheability
        EORNE   lr, r0, #ppn,given      ;   and PN not given
        TSTNE   lr, #ppn,given
        TSTEQ   r0, #ppn,wanted         ;   OR PN wanted then don't skip
        BEQ     %FT30                   ; else skip.
        TST     r0, #physical_bits,given        ; If PA not given and PA not wanted (rotate clears C) then
        BLEQ    logical_to_physical             ;   get it from LA (PN wanted/not given & PA not given => LA given).
        BLCC    physical_to_ppn         ; Get PN from PA.
        BCS     %FT80
        TST     r0, #ppn,wanted
        STRNE   r3, [r1, #-12]          ; Store back PN if wanted.
30
        TST     r0, #logical,wanted     ; If LA wanted
        EORNE   lr, r0, #physical,wanted
        TSTNE   lr, #physical,wanted    ;   and PA not wanted then don't skip
        BEQ     %FT40                   ; else skip.
        TST     r0, #alter_cacheable    ; If not changing cacheability (already have PN)
        TSTEQ   r0, #ppn_bits,given     ;   and PN not given and PN not wanted (rotate clears C) then
        BLEQ    physical_to_ppn         ;   get it from PA (LA wanted (not given) & PN not given => PA given).
        BLCC    ppn_to_logical          ; Get LA from PN.
        BCS     %FT80
        STR     r4, [r1, #-8]           ; Store back LA.
40
        TST     r0, #alter_cacheable
        BEQ     %BT10

        CMP     r7, r3                  ; Make sure page number is valid (might not have done any conversion).
        BCC     %FT80

220 221 222
        ADD     r3, r6, r3, LSL #CAM_EntrySizeLog2 ; Point to CAM entry for this page.
        ASSERT  CAM_LogAddr=0
        ASSERT  CAM_PageFlags=4
Neil Turton's avatar
Neil Turton committed
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
        LDMIA   r3, {r4,r5}             ; Get logical address and PPL.

        AND     lr, r5, #PageFlags_TempUncacheableBits
        TST     r0, #cacheable_bit
        BNE     %FT50

        TEQ     lr, #PageFlags_TempUncacheableBits      ; Make uncacheable (increment count).
        BEQ     %BT10                                   ; If count has reached max then go no further (should not happen).
        TEQ     lr, #0                                  ; EQ => we have to change L2.
        ADD     r5, r5, #1:SHL:TempUncacheableShift
        B       %FT60
50
        TEQ     lr, #0                                  ; Make cacheable (decrement count).
        BEQ     %BT10                                   ; If count is already 0 then go no further (page already cacheable).
        SUB     r5, r5, #1:SHL:TempUncacheableShift
        TST     r5, #PageFlags_TempUncacheableBits      ; EQ => we have to change L2.
60
240
        STR     r5, [r3, #CAM_PageFlags] ; Write back new PPL.
Neil Turton's avatar
Neil Turton committed
241 242 243
        BNE     %BT10                   ; Do next entry if we don't have to change L2.

        MOV     r4, r4, LSR #12
Jeffrey Lee's avatar
Jeffrey Lee committed
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 270 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
 [ LongDesc
        LDR     r8, =LL3PT
        LDR     r3, =ZeroPage
        ADD     r4, r8, r4, LSL #3      ; Address of L3 entry for logical address.
        ; VMSAv6 is hard, 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
        TST     r0, #cacheable_bit      ; n.b. must match EQ/NE used by ARMop calls
        AND     lr, r5, #DynAreaFlags_NotCacheable + DynAreaFlags_NotBufferable
        AND     r5, r5, #DynAreaFlags_CPBits
        ORR     lr, lr, r5, LSR #10-4
        LDR     r5, [r3, #MMU_PCBTrans]
        ORREQ   lr, lr, #XCB_TU<<4      ; if temp uncache, set TU bit
        LDRB    lr, [r5, lr, LSR #4]    ; get AttrIndx value
        LDRD    r8, [r4]                ; Get L3 entry (safe as we know address is valid).
        BIC     r8, r8, #TempUncache_L3PTMask ; Knock out existing attributes (n.b. assumed to not be large page!)
        ORR     r8, r8, lr              ; Set new attributes
        BNE     %FT63
        ; Making page non-cacheable
        ; There's a potential interrupt hole here - many ARMs ignore cache hits
        ; for pages which are marked as non-cacheable (seen on XScale,
        ; Cortex-A53, Cortex-A15 to name but a few, and documented in many TRMs)
        ; We can't be certain that this page isn't being used by an interrupt
        ; handler, so if we're making it non-cacheable we have to take the safe
        ; route of disabling interrupts around the operation.
        ; Note - currently no consideration is given to FIQ handlers.
        ; Note - we clean the cache as the last step (as opposed to doing it at
        ; the start) to make sure prefetching doesn't pull data back into the
        ; cache.
        MRS     r11, CPSR
        ORR     lr, r11, #I32_bit       ; IRQs off
        ; Yuck, we also need to deal with the case where we're making the
        ; current SVC stack page uncacheable (coherency issue when calling the
        ; ARMops if cache hits to uncacheable pages are ignored). Deal with this
        ; by temporarily dropping into IRQ mode (and thus a different stack) if
        ; we think this is going to happen.
        MOV     r5, r4, LSL #9          ; R5 = original logical address
      [ (LL3PT:SHL:9) <> 0
        SUB     r5, r5, #LL3PT:SHL:9
      ]
        SUB     r10, sp, r5
        CMP     r10, #8192              ; Be extra cautious
        EORLO   lr, lr, #SVC32_mode :EOR: IRQ32_mode
        MSR     CPSR_c, lr              ; Switch mode
        Push    "r0, lr"                ; Preserve OS_Memory flags and (potential) IRQ lr
        STRD    r8, [r4]                ; Write back new L3 entry.
        MOV     r0, r5
        ARMop   MMU_ChangingEntry,,,r3  ; Clean TLB+cache
        Pull    "r0, lr"                ; Restore OS_Memory flags + IRQ lr
        MSR     CPSR_c, r11             ; Back to original mode + IRQ state
        B       %FT65
63
        ; Making page cacheable again
        ; Shouldn't be any cache maintenance worries
        STRD    r8, [r4]                ; Write back new L2 entry.
        MOV     r4, r0
        MOV     r0, r5
        ARMop   MMU_ChangingUncachedEntry,,,r3   ; Clean TLB
        MOV     r0, r4
65
        B       %BT10
 |
307
        LDR     r8, =L2PT
308
        LDR     r3, =ZeroPage
Neil Turton's avatar
Neil Turton committed
309
        ADD     r4, r8, r4, LSL #2      ; Address of L2 entry for logical address.
Jeffrey Lee's avatar
Jeffrey Lee committed
310
   [ MEMM_Type = "VMSAv6"
311 312 313 314 315 316 317 318 319 320
        ; VMSAv6 is hard, 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
        TST     r0, #cacheable_bit      ; n.b. must match EQ/NE used by ARMop calls
        AND     lr, r5, #DynAreaFlags_NotCacheable + DynAreaFlags_NotBufferable
        AND     r5, r5, #DynAreaFlags_CPBits
        ORR     lr, lr, r5, LSR #10-4
        LDR     r5, [r3, #MMU_PCBTrans]
        ORREQ   lr, lr, #XCB_TU<<4      ; if temp uncache, set TU bit
321 322
        MOV     lr, lr, LSR #3
        LDRH    lr, [r5, lr]            ; convert to C, B and TEX bits for this CPU
323
        LDR     r5, [r4]                ; Get L2 entry (safe as we know address is valid).
324
        BIC     r5, r5, #TempUncache_L2PTMask ; Knock out existing attributes (n.b. assumed to not be large page!)
325
        ORR     r5, r5, lr              ; Set new attributes
Jeffrey Lee's avatar
Jeffrey Lee committed
326
   |
Neil Turton's avatar
Neil Turton committed
327 328 329 330
        LDR     r5, [r4]                ; Get L2 entry (safe as we know address is valid).
        TST     r0, #cacheable_bit
        BICEQ   r5, r5, #L2_C           ; Disable/enable cacheability.
        ORRNE   r5, r5, #L2_C
Jeffrey Lee's avatar
Jeffrey Lee committed
331
   ]
Jeffrey Lee's avatar
Jeffrey Lee committed
332 333 334 335 336 337 338 339 340 341 342 343
        BNE     %FT63
        ; Making page non-cacheable
        ; There's a potential interrupt hole here - many ARMs ignore cache hits
        ; for pages which are marked as non-cacheable (seen on XScale,
        ; Cortex-A53, Cortex-A15 to name but a few, and documented in many TRMs)
        ; We can't be certain that this page isn't being used by an interrupt
        ; handler, so if we're making it non-cacheable we have to take the safe
        ; route of disabling interrupts around the operation.
        ; Note - currently no consideration is given to FIQ handlers.
        ; Note - we clean the cache as the last step (as opposed to doing it at
        ; the start) to make sure prefetching doesn't pull data back into the
        ; cache.
344 345 346 347 348 349 350 351 352 353 354 355 356
        MRS     r11, CPSR
        ORR     lr, r11, #I32_bit       ; IRQs off
        ; Yuck, we also need to deal with the case where we're making the
        ; current SVC stack page uncacheable (coherency issue when calling the
        ; ARMops if cache hits to uncacheable pages are ignored). Deal with this
        ; by temporarily dropping into IRQ mode (and thus a different stack) if
        ; we think this is going to happen.
        MOV     r10, r4, LSL #10
        SUB     r10, sp, r10
        CMP     r10, #8192              ; Be extra cautious
        EORLO   lr, lr, #SVC32_mode :EOR: IRQ32_mode
        MSR     CPSR_c, lr              ; Switch mode
        Push    "r0, lr"                ; Preserve OS_Memory flags and (potential) IRQ lr
Jeffrey Lee's avatar
Jeffrey Lee committed
357 358 359
        STR     r5, [r4]                ; Write back new L2 entry.
        ASSERT  (L2PT :SHL: 10) = 0     ; Ensure we can convert r4 back to the page log addr
        MOV     r0, r4, LSL #10
360
        ARMop   MMU_ChangingEntry,,,r3  ; Clean TLB+cache
Jeffrey Lee's avatar
Jeffrey Lee committed
361
        Pull    "r0, lr"                ; Restore OS_Memory flags + IRQ lr
362
        MSR     CPSR_c, r11             ; Back to original mode + IRQ state
Jeffrey Lee's avatar
Jeffrey Lee committed
363 364 365 366 367
        B       %FT65
63
        ; Making page cacheable again
        ; Shouldn't be any cache maintenance worries
        STR     r5, [r4]                ; Write back new L2 entry.
368
        MOV     r5, r0
369
        ASSERT  (L2PT :SHL: 10) = 0     ; Ensure we can convert r4 back to the page log addr
370
        MOV     r0, r4, LSL #10
Jeffrey Lee's avatar
Jeffrey Lee committed
371
        ARMop   MMU_ChangingUncachedEntry,,,r3   ; Clean TLB
372
        MOV     r0, r5
Jeffrey Lee's avatar
Jeffrey Lee committed
373
65
374
        B       %BT10
Jeffrey Lee's avatar
Jeffrey Lee committed
375
 ]
376 377

70
378
        CLRV
Neil Turton's avatar
Neil Turton committed
379 380 381 382 383 384 385 386 387 388 389 390 391
        EXIT

80
        TST     r0, #alter_cacheable    ; If we haven't changed any cacheability stuff then
        BEQ     %FT90                   ;   just return error.

        AND     lr, r0, #all,wanted             ; Get wanted flags.
        LDMIA   sp, {r0,r1,r3}                  ; Get back original flags, pointer and count.
        ORR     r0, r0, lr, LSR #given-wanted   ; Wanted fields are now also given as we have done the conversion.
        BIC     r0, r0, #all:SHL:11             ; Clear wanted flags, we only want to change cacheability.
        EOR     r0, r0, #cacheable_bit          ; If we made them uncacheable then make them cacheable again & v.v.
        SUB     r2, r3, r2
        SUBS    r2, r2, #1              ; Change back the entries we have changed up to (but excluding) the error entry.
392
        BLNE    MemoryConvertNoFIQCheck
Neil Turton's avatar
Neil Turton committed
393 394 395
90
        ADRL    r0, ErrorBlock_BadAddress
95
396
        STR     r0, [sp, #Proc_RegOffset+0]
Neil Turton's avatar
Neil Turton committed
397 398 399
        SETV
        EXIT

400
   [ AMB_LazyMapIn
401
;
402
;  entry: r3,r4,r8,r9 = provided PN,LA,PA triple for entry to make honest (at least one given)
403 404 405
;         r0 bits flag which of PN,LA,PA are given
;  exit:  mapping made honest (as if not lazily mapped) if necessary
handle_AMBHonesty  ROUT
406
        Push    "r0, r3-r4, lr"
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
        TST     r0, #logical,given
        BEQ     %FT10
        MOV     r0, r4
        BL      AMB_MakeHonestLA
        B       %FT90
10
        TST     r0, #ppn,given
        BEQ     %FT20
15
        MOV     r0, r3
        BL      AMB_MakeHonestPN
        B       %FT90
20
        TST     r0, #physical,given
        BEQ     %FT90
422
        Push    "r5, r7, r10-r11"
Jeffrey Lee's avatar
Jeffrey Lee committed
423
        LDR     r14, =ZeroPage
424 425
        LDR     r7, [r14, #MaxCamEntry]
        BL      physical_to_ppn
426
        Pull    "r5, r7, r10-r11"
427 428
        BCC     %BT15
90
429
        Pull    "r0, r3-r4, pc"
430

431
   ] ;AMB_LazyMapIn
432

Neil Turton's avatar
Neil Turton committed
433 434 435 436 437

;----------------------------------------------------------------------------------------
; ppn_to_logical
;
;       In:     r3 = page number
438
;               r8,r9 = physical address if given
Neil Turton's avatar
Neil Turton committed
439 440 441
;               r6 = CamEntriesPointer
;               r7 = MaxCamEntry
;
442
;       Out:    r5 corrupted
Neil Turton's avatar
Neil Turton committed
443 444 445 446 447 448 449
;               CC => r4 = logical address
;               CS => invalid page number
;
;       Convert physical page number to logical address.
;
ppn_to_logical
        CMP     r7, r3                  ; Validate page number.
Kevin Bracey's avatar
Kevin Bracey committed
450
        BCC     meminfo_returncs        ; Invalid so return C set.
Neil Turton's avatar
Neil Turton committed
451

452 453
        ASSERT  CAM_LogAddr=0
        LDR     r4, [r6, r3, LSL #CAM_EntrySizeLog2] ; If valid then lookup logical address.
Neil Turton's avatar
Neil Turton committed
454
        TST     r0, #physical,given     ; If physical address was given then
455 456 457 458 459 460 461
      [ NoARMT2
        LDRNE   r5, =&FFF
        ANDNE   r5, r8, r5              ;   mask off page offset
        ORRNE   r4, r4, r5              ;   and combine with logical address.
      |
        BFINE   r4, r8, #0, #12         ;   apply page offset
      ]
Kevin Bracey's avatar
Kevin Bracey committed
462 463
        CLC
        MOV     pc, lr
Neil Turton's avatar
Neil Turton committed
464

465 466
meminfo_returncs_pullr8
        Pull    "r8"
Kevin Bracey's avatar
Kevin Bracey committed
467 468 469
meminfo_returncs
        SEC
        MOV     pc, lr
Neil Turton's avatar
Neil Turton committed
470 471 472 473

;----------------------------------------------------------------------------------------
; physical_to_ppn
;
474
;       In:     r8,r9 = physical address
Neil Turton's avatar
Neil Turton committed
475 476
;               r7 = MaxCamEntry
;
477
;       Out:    r5,r10-r11 corrupted
Neil Turton's avatar
Neil Turton committed
478 479 480 481 482 483
;               CC => r3 = page number
;               CS => invalid physical address, r3 corrupted
;
;       Convert physical address to physical page number.
;
physical_to_ppn ROUT
484 485
        Push    "r8"
        LDR     r5, =ZeroPage+PhysRamTable
Neil Turton's avatar
Neil Turton committed
486
        MOV     r3, #0                  ; Start at page 0.
487
        MOV     r8, r8, LSR #12
Neil Turton's avatar
Neil Turton committed
488 489
10
        CMP     r7, r3                  ; Stop if we run out of pages
490
        BCC     meminfo_returncs_pullr8
Neil Turton's avatar
Neil Turton committed
491

492 493
        LDMIA   r5!, {r10,r11}          ; Get start address and size of next block.
        SUB     r10, r8, r10, LSR #12   ; Determine if given address is in this block.
494
        CMP     r10, r11, LSR #12
Neil Turton's avatar
Neil Turton committed
495 496 497
        ADDCS   r3, r3, r11, LSR #12    ; Move on to next block.
        BCS     %BT10

498
        Pull    "r8"
Jeffrey Lee's avatar
Jeffrey Lee committed
499

500
        ADD     r3, r3, r10
Kevin Bracey's avatar
Kevin Bracey committed
501 502
        CLC
        MOV     pc, lr
Neil Turton's avatar
Neil Turton committed
503

504 505 506 507 508
;----------------------------------------------------------------------------------------
; ppn_to_physical
;
;       In:     r3 = page number
;
509 510 511
;       Out:    r5 corrupted
;               CC => r8,r9 = physical address
;               CS => invalid page number, r8,r9 corrupted
512 513 514 515 516
;
;       Convert physical page number to physical address.
;
ppn_to_physical ROUT
        Push    "r3,lr"
517
        LDR     r5, =ZeroPage+PhysRamTable
518
10
519
        LDMIA   r5!, {r8,lr}            ; Get start address and size of next block.
520 521 522 523 524 525
        MOVS    lr, lr, LSR #12
        BEQ     %FT20
        CMP     r3, lr
        SUBHS   r3, r3, lr
        BHS     %BT10

526 527
        ADD     r8, r8, r3, LSL #12
        MOV     r9, #0
528 529 530 531 532
        Pull    "r3,pc"
20
        SEC
        Pull    "r3,pc"

Neil Turton's avatar
Neil Turton committed
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562

;----------------------------------------------------------------------------------------
; Symbols used in MemoryPhysSize and MemoryReadPhys
;

; Shifts to determine number of bytes/words to allocate in table.
BitShift        *       10
ByteShift       *       BitShift + 3
WordShift       *       ByteShift + 2

; Bit patterns for different types of memory.
NotPresent      *       &00000000
DRAM_Pattern    *       &11111111
VRAM_Pattern    *       &22222222
ROM_Pattern     *       &33333333
IO_Pattern      *       &44444444
NotAvailable    *       &88888888


;----------------------------------------------------------------------------------------
; MemoryPhysSize
;
;       In:     r0 = 6 (reason code with flag bits 8-31 clear)
;
;       Out:    r1 = table size (in bytes)
;               r2 = page size (in bytes)
;
;       Returns information about the memory arrangement table.
;
MemoryPhysSize
563
        Entry   "r0-r1,r3,sb,ip"
564
        AddressHAL
565 566
        MOV     r0, #PhysInfo_GetTableSize
        ADD     r1, sp, #4
567 568
        CallHAL HAL_PhysInfo
        MOV     r2, #4*1024
569
        CLRV
570
        EXIT
Neil Turton's avatar
Neil Turton committed
571 572 573 574 575 576 577 578 579 580 581 582 583 584


;----------------------------------------------------------------------------------------
; MemoryReadPhys
;
;       In:     r0 = 7 (reason code with flag bits 8-31 clear)
;               r1 -> memory arrangement table to be filled in
;
;       Out:    r1 -> filled in memory arrangement table
;
;       Returns the physical memory arrangement table in the given block.
;
MemoryReadPhys  ROUT

585 586
        Entry   "r0-r12"
        AddressHAL
587 588 589
        MOV     r0, #PhysInfo_WriteTable
        SUB     sp, sp, #8
        MOV     r2, sp
590
        CallHAL HAL_PhysInfo            ; fills in everything except DRAM
591
        ADD     sp, sp, #8              ; We don't use this address range any more
592

593 594
        MOV     r5, #0                  ; Current page number.
        LDR     r6, =ZeroPage+PhysRamTable
595 596 597 598
        LDR     r7, [r6, #CamEntriesPointer-PhysRamTable]
        ADD     r7, r7, #CAM_PageFlags  ; Point to PPL entries.
        LDR     r8, [r6, #MaxCamEntry-PhysRamTable]
10
599
        LDMIA   r6!, {r9,r10}           ; Get physical address and size of next block.
600

601 602 603 604
        TST     r10, #OSAddRAM_IsVRAM   ; If not DRAM then
        ADDNE   r5, r5, r10, LSR #12    ;   adjust current page number
        BNE     %BT10                   ;   and try next block.

605
        MOV     r10, r10, LSR #12
606 607 608 609 610 611 612 613 614 615 616
        LDR     r1, [sp, #4]            ; Get table address back
        MOV     r3, r9, LSR #WordShift
        LDR     r3, [r1, r3, LSL #2]!   ; Get first word of block
        MOV     r4, r9, LSR #BitShift
        AND     r4, r4, #(1<<(WordShift-BitShift))-1 ; Bit offset of first page in the word
        RSB     r4, r4, #32             ; number of bits left to process
        MOV     r3, r3, LSL r4

        ; r1 -> current table location
        ; r3 = next word to store in table
        ; r4 = how much we have to shift r3 before storing it
617 618 619 620 621 622 623
20
        SUBS    r4, r4, #4              ; Reduce shift.
        MOVCS   r3, r3, LSR #4          ; If more space in current word then shift it.
        STRCC   r3, [r1], #4            ; Otherwise, store current word
        MOVCC   r3, #0                  ;   and start a new one.
        MOVCC   r4, #28

624
        LDR     lr, [r7, r5, LSL #CAM_EntrySizeLog2] ; Page is there so get PPL and determine if it's available or not.
625
        TST     lr, #PageFlags_Unavailable
626
        TSTEQ   lr, #PageFlags_Reserved
627 628 629 630
        ORREQ   r3, r3, #DRAM_Pattern :SHL: 28
        ORRNE   r3, r3, #(DRAM_Pattern :OR: NotAvailable) :SHL: 28
        ADD     r5, r5, #1              ; Increment page count.
30
631 632 633 634 635 636 637 638 639 640 641 642 643
        SUBS    r10, r10, #1            ; Decrease size of block.
        BNE     %BT20                   ; Stop if no more block left.

        ; Store the partial last word
        LDR     lr, [r1]
        MOV     r3, r3, LSR r4          ; put bits in correct position
        RSB     r4, r4, #32
        MOV     lr, lr, LSR r4          ; drop the low bits of lr
        ORR     r3, r3, lr, LSL r4      ; combine with r3
        STR     r3, [r1]                ; and store word.

        CMP     r8, r5                  ; Stop if we run out of pages.
        BCS     %BT10
644

645 646 647 648 649 650 651
        ; If softloaded, mark that as unavailable DRAM.
        MOV     r0, #8
        SWI     XOS_ReadSysInfo
        BVS     %FT40
        AND     r1, r1, r2
        ANDS    r1, r1, #1:SHL:4        ; Test OS-runs-from-RAM flag
        BEQ     %FT40
Jeffrey Lee's avatar
Jeffrey Lee committed
652
        LDR     r0, =ZeroPage
653 654
        LDR     r0, [r0, #ROMPhysAddr]
        LDR     r1, [sp, #4]
655 656 657 658 659
        ADD     r0, r1, r0, LSR #ByteShift
        LDR     r1, =DRAM_Pattern :OR: NotAvailable
        MOV     r2, #(OSROM_ImageSize*1024) :SHR: ByteShift
        BL      memset
40
660
        CLRV
Neil Turton's avatar
Neil Turton committed
661 662 663 664 665 666 667 668 669
        EXIT


;----------------------------------------------------------------------------------------
; MemoryAmounts
;
;       In:     r0 = flags
;                       bit     meaning
;                       0-7     8 (reason code)
670
;                       8-11    1=return amount of DRAM (excludes any soft ROM)
Neil Turton's avatar
Neil Turton committed
671 672 673
;                               2=return amount of VRAM
;                               3=return amount of ROM
;                               4=return amount of I/O space
674
;                               5=return amount of soft ROM (ROM loaded into hidden DRAM)
Neil Turton's avatar
Neil Turton committed
675 676 677 678 679 680 681 682
;                       12-31   reserved (set to 0)
;
;       Out:    r1 = number of pages of the specified type of memory
;               r2 = page size (in bytes)
;
;       Return the amount of the specified type of memory.
;
MemoryAmounts   ROUT
683
        Entry   "r3"
Neil Turton's avatar
Neil Turton committed
684

685
        BICS    lr, r0, #&FF            ; Get type of memory required (leave bits 12-31, non-zero => error).
686 687 688 689 690 691 692 693 694
        CMP     lr, #6:SHL:8
        ADDCC   pc, pc, lr, LSR #8-2
        NOP
        B       %FT99                   ; Don't understand 0 (so the spec says).
        B       %FT10                   ; DRAM
        B       %FT20                   ; VRAM
        B       %FT30                   ; ROM
        B       %FT40                   ; I/O
        B       %FT50                   ; Soft ROM
Kevin Bracey's avatar
Kevin Bracey committed
695

696 697
10
        LDR     r1, =ZeroPage
698 699
        LDR     r3, [r1, #VideoSizeFlags]
        TST     r3, #OSAddRAM_IsVRAM
700 701 702 703 704 705 706 707
        MOVNE   r3, r3, LSR #12         ; Extract size from flags when genuine VRAM
        MOVNE   r3, r3, LSL #12
        MOVEQ   r3, #0
        LDR     r1, [r1, #RAMLIMIT]
        SUB     r1, r1, r3              ; DRAM = RAMLIMIT - VRAMSize
        B       %FT97
20
        LDR     r1, =ZeroPage
708 709
        LDR     r1, [r1, #VideoSizeFlags]
        TST     r1, #OSAddRAM_IsVRAM
710 711 712 713 714
        MOVNE   r1, r1, LSR #12
        MOVNE   r1, r1, LSL #12         ; VRAM = VRAMSize
        MOVEQ   r1, #0
        B       %FT97
30
715 716 717 718 719 720 721
        Push    "r0, sb, ip"
        AddressHAL
        MOV     r0, #PhysInfo_HardROM
        SUB     sp, sp, #8
        MOV     r2, sp
        CallHAL HAL_PhysInfo
        LDMIA   sp!, {r0-r1}
722 723
        SUBS    r1, r1, r0
        ADDNE   r1, r1, #1              ; ROM = ROMPhysTop + 1 - ROMPhysBot
724
        Pull    "r0, sb, ip"
725 726 727
        B       %FT97
40
        LDR     r1, =ZeroPage
Jeffrey Lee's avatar
Jeffrey Lee committed
728
        LDR     r3, [r1, #IOAllocTop]
729 730 731 732
        LDR     r1, [r1, #IOAllocLimit]
        SUB     r1, r3, r1              ; IO = IO ceiling - IO floor
        B       %FT97
50
733 734
        Push    "r0"
        MOV     r0, #8
735
        SWI     XOS_ReadSysInfo         ; Are we softloaded?
736 737
        Pull    "r0"
        AND     r1, r1, r2
738 739 740 741
        ANDS    r1, r1, #1:SHL:4        ; Test OS-runs-from-RAM flag
        MOVNE   r1, #OSROM_ImageSize*1024
        B       %FT97
97
742 743
        MOV     r1, r1, LSR #12         ; Return as number of pages.
        MOV     r2, #4*1024             ; Return page size.
744
        CLRV
745
        EXIT
746
99
747 748 749 750
        PullEnv
        ; Fall through...
MemoryBadParameters
        ADRL    r0, ErrorBlock_BadParameters ; n.b. MemReturn handles internationalisation
751
        SETV
752
        MOV     pc, lr
Neil Turton's avatar
Neil Turton committed
753 754 755 756 757 758 759 760 761 762 763


;----------------------------------------------------------------------------------------
; MemoryIOSpace
;
;       In:     r0 = 9 (reason code with flag bits 8-31 clear)
;               r1 = controller ID
;                       bit     meaning
;                       0-7     controller sequence number
;                       8-31    controller type:
;                               0 = EASI card access speed control
Kevin Bracey's avatar
Kevin Bracey committed
764
;                               1 = EASI space(s)
Neil Turton's avatar
Neil Turton committed
765 766
;                               2 = VIDC1
;                               3 = VIDC20
Kevin Bracey's avatar
Kevin Bracey committed
767 768
;                               4 = S space (IOMD,podules,NICs,blah blah)
;                               5 = Extension ROM(s)
769 770 771 772 773 774
;                               6 = Tube ULA
;                               7-31 = Reserved (for us)
;                               32 = Primary ROM
;                               33 = IOMD
;                               34 = FDC37C665/SMC37C665/82C710/SuperIO/whatever
;                               35+ = Reserved (for ROL)
Neil Turton's avatar
Neil Turton committed
775 776 777 778 779
;
;       Out:    r1 = controller base address or 0 if not present
;
;       Return the location of the specified controller.
;
Kevin Bracey's avatar
Kevin Bracey committed
780 781 782 783 784

MemoryIOSpace   ROUT
        Entry   "r0,r2,r3,sb,ip"
        AddressHAL
        CallHAL HAL_ControllerAddress
Kevin Bracey's avatar
Kevin Bracey committed
785 786
        CMP     r0, #-1
        MOVNE   r1, r0
787 788 789
        PullEnv
        MOVNE   pc, lr
        B       MemoryBadParameters
Neil Turton's avatar
Neil Turton committed
790

791
;----------------------------------------------------------------------------------------
792
; MemoryFreePoolLock - removed now that free pool is a PMP
793 794 795 796 797 798 799 800 801 802 803

;----------------------------------------------------------------------------------------
;PCImapping - reserved for Acorn use (PCI manager)
;
; See code on Ursula branch


;----------------------------------------------------------------------------------------
;RecommendPage
;
;       In:     r0 bits 0..7  = 12 (reason code 12)
804 805
;               r0 bit 8 = 1 if region must be DMAable
;               r0 bits 9..31 = 0 (reserved flags)
806 807 808 809 810 811 812 813 814
;               r1 = size of physically contiguous RAM region required (bytes)
;               r2 = log2 of required alignment of base of region (eg. 12 = 4k, 20 = 1M)
;
;       Out:    r3 = page number of first page of recommended region that could be
;                    grown as specific pages by dynamic area handler (only guaranteed
;                    if grow is next page claiming operation)
;        - or error if not possible (eg too big, pages unavailable)
;
RecommendPage ROUT
815
        Push    "r0-r2,r4-r11,lr"
816
        CMP     r2,#30
817 818 819
        BHI     RP_failed         ;refuse to look for alignments above 1G
        ANDS    r11,r0,#1:SHL:8   ;convert flag into something usable in the loop
        MOVNE   r11,#OSAddRAM_NoDMA
820 821 822 823 824 825 826 827 828 829 830
;
        ADD     r1,r1,#&1000
        SUB     r1,r1,#1
        MOV     r1,r1,LSR #12
        MOVS    r1,r1,LSL #12     ;size rounded up to whole no. of pages
;
        CMP     r2,#12
        MOVLO   r2,#12            ;log2 alignment must be at least 12 (4k pages)
        MOV     r0,#1
        MOV     r4,r0,LSL r2      ;required alignment-1
;
Jeffrey Lee's avatar
Jeffrey Lee committed
831
        LDR     r0,=ZeroPage+PhysRamTable
832
        MOV     r3,#0            ;page number, starts at 0
Jeffrey Lee's avatar
Jeffrey Lee committed
833
        LDR     r5,=ZeroPage+CamEntriesPointer
834
        LDR     r5,[r5]
835
        ADD     r5,r5,#CAM_PageFlags ; [r5,<page no.>,LSL #3] addresses flags word in CAM
836 837 838 839 840 841 842
        LDMIA   r0!,{r7,r8}      ;address,size of video chunk (skip this one)
;
RP_nextchunk
        ADD     r3,r3,r8,LSR #12 ;page no. of first page of next chunk
        LDMIA   r0!,{r7,r8}      ;address,size of next physical chunk
        CMP     r8,#0
        BEQ     RP_failed
843 844
        TST     r8,r11           ;ignore non-DMA regions if bit 8 of R0 was set
        BNE     RP_nextchunk
845
;
846
        MOV     r8,r8,LSR #12
847
        ADD     r6,r7,r4
848
        MOV     r8,r8,LSL #12
849 850 851 852 853 854 855 856 857 858 859 860
        SUB     r6,r6,#1         ;round up
        MOV     r6,r6,LSR r2
        MOV     r6,r6,LSL r2
        SUB     r6,r6,r7         ;adjustment to first address of acceptable alignment
        CMP     r6,r8
        BHS     RP_nextchunk     ;negligible chunk
        ADD     r7,r3,r6,LSR #12 ;first page number of acceptable alignment
        SUB     r9,r8,r6         ;remaining size of chunk
;
;find first available page
RP_nextpage
        CMP     r9,r1
861
        BLO     RP_nextchunk      ;not enough pages left in chunk
862
        LDR     r6,[r5,r7,LSL #CAM_EntrySizeLog2] ;page flags from CAM
863 864
        ;must not be marked Unavailable or Required
        TST     r6,#PageFlags_Unavailable :OR: PageFlags_Required
865
        TSTEQ   r6,#PageFlags_Reserved
866 867 868 869 870 871 872 873 874 875 876 877
        BEQ     RP_checkotherpages
RP_nextpagecontinue
        CMP     r9,r4
        BLS     RP_nextchunk
        ADD     r7,r7,r4,LSR #12   ;next page of suitable alignment
        SUB     r9,r9,r4
        B       RP_nextpage
;
RP_checkotherpages
        ADD     r10,r7,r1,LSR #12
        SUB     r10,r10,#1         ;last page required
RP_checkotherpagesloop
878
        LDR     r6,[r5,r10,LSL #CAM_EntrySizeLog2] ;page flags from CAM
879
        TST     r6,#PageFlags_Unavailable :OR: PageFlags_Required
880
        TSTEQ   r6,#PageFlags_Reserved
881 882 883 884 885 886 887 888
        BNE     RP_nextpagecontinue
        SUB     r10,r10,#1
        CMP     r10,r7
        BHI     RP_checkotherpagesloop
;
;success!
;
        MOV     r3,r7
889
        Pull    "r0-r2,r4-r11,pc"
890 891 892

RP_failed
        MOV     r3,#0
893
        ADR     r0,ErrorBlock_NoMemChunkAvailable
894 895
        SETV
        STR     r0,[sp]
896
        Pull    "r0-r2,r4-r11,pc"
897

898
        MakeErrorBlock NoMemChunkAvailable
899

900 901 902 903 904
;----------------------------------------------------------------------------------------
;MapIOpermanent - map IO space (if not already mapped) and return logical address
;
;       In:     r0 bits 0..7  = 13 (reason code 13)
;               r0 bit  8     = 1 to map bufferable space (0 is normal, non-bufferable)
905
;               r0 bit  9     = 1 to map cacheable space (0 is normal, non-cacheable)
906
;               r0 bits 10..12 = cache policy
907
;               r0 bits 13..15 = 0 (reserved flags)
Kevin Bracey's avatar
Kevin Bracey committed
908
;               r0 bit  16    = 1 to doubly map
909 910 911 912
;               r0 bit  17    = 1 if access privileges specified
;               r0 bits 18..23 = 0 (reserved flags)
;               r0 bits 24..27 = access privileges (if bit 17 set)
;               r0 bits 28..31 = 0 (reserved flags)
913 914 915 916 917 918 919
;               r1 = physical address of base of IO space required
;               r2 = size of IO space required (bytes)
;
;       Out:    r3 = logical address of base of IO space
;        - or error if not possible (no room)
;
MapIOpermanent ROUT
920
        Entry   "r0-r2,r12"
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947
        MOV     r3, r2
        MOV     r2, #0
        B       %FT10

;----------------------------------------------------------------------------------------
;MapIO64permanent - map IO space (if not already mapped) from 64-bit physical space
;and return logical address
;
;       In:     r0 bits 0..7  = 21 (reason code 21)
;               r0 bit  8     = 1 to map bufferable space (0 is normal, non-bufferable)
;               r0 bit  9     = 1 to map cacheable space (0 is normal, non-cacheable)
;               r0 bits 10..12 = cache policy
;               r0 bits 13..15 = 0 (reserved flags)
;               r0 bit  16    = 1 to doubly map
;               r0 bit  17    = 1 if access privileges specified
;               r0 bits 18..23 = 0 (reserved flags)
;               r0 bits 24..27 = access privileges (if bit 17 set)
;               r0 bits 28..31 = 0 (reserved flags)
;               r1,r2 = physical address of base of IO space required
;               r3 = size of IO space required (bytes)
;
;       Out:    r3 = logical address of base of IO space
;        - or error if not possible (no room)
;
MapIO64permanent
        ALTENTRY
10      ; Convert the input flags to some DA flags
948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964
        TST     r0, #1:SHL:17
        MOVEQ   r12, #2                 ; Default AP: SVC RW, USR none
        MOVNE   r12, r0, LSR #24        ; Else use given AP
        ANDNE   r12, r12, #DynAreaFlags_APBits
        AND     lr, r0, #&300
        EOR     lr, lr, #&300
        ASSERT  DynAreaFlags_NotBufferable = 1:SHL:4
        ASSERT  DynAreaFlags_NotCacheable = 1:SHL:5
        ORR     r12, r12, lr, LSR #4
        AND     lr, r0, #7:SHL:10
        ASSERT  DynAreaFlags_CPBits = 7:SHL:12
        ORR     r12, r12, lr, LSL #2
        ; Calculate the extra flags needed for RISCOS_MapInIO
        AND     r0, r0, #1:SHL:16
        ASSERT  MapInFlag_DoublyMapped = 1:SHL:20
        MOV     r0, r0, LSL #4
        ; Convert DA flags to page table entry
Jeffrey Lee's avatar
Jeffrey Lee committed
965 966 967 968 969 970 971 972 973 974
 [ LongDesc
        Push    "r0,r1"
        MOV     r0, #0
        GetPTE  r0, 2M, r0, r12
        UBFX    r0, r0, #0, #LL_LowAttr_Start+LL_LowAttr_Size ; Only keep the low attribtues (only high attribute is XN/PXN, which is always forced)
        Pull    "r1"
        ORR     r0, r0, r1              ; Add in the extra flags
        Pull    "r1"
        BL      RISCOS_MapInIO_LowAttr
 |
975
        GetPTE  r0, 1M, r0, r12
Jeffrey Lee's avatar
Jeffrey Lee committed
976
   [ MEMM_Type = "VMSAv6"
977
        ORR     r0, r0, #L1_XN          ; force non-executable to prevent speculative instruction fetches
Jeffrey Lee's avatar
Jeffrey Lee committed
978
   ]
979 980
        ; Map in the region
        BL      RISCOS_MapInIO_PTE
Jeffrey Lee's avatar
Jeffrey Lee committed
981
 ]
982
        MOV     r3, r0
983
        PullEnv
984
        CMP     r3, #0              ;MOV,CMP rather than MOVS to be sure to clear V
985 986 987
        ADREQ   r0, ErrorBlock_NoRoomForIO
        SETV    EQ
        MOV     pc, lr
988

989
        MakeErrorBlock NoRoomForIO
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012

;----------------------------------------------------------------------------------------
;AccessPhysAddr - claim temporary access to given physical address (in fact,
;                 controls access to the 1Mb aligned space containing the address)
;                 The access remains until the next AccessPhysAddr or until a
;                 ReleasePhysAddr (although interrupts or subroutines may temporarily
;                 make their own claims, but restore on Release before returning)
;
;       In:     r0 bits 0..7  = 14 (reason code 14)
;               r0 bit  8     = 1 to map bufferable space, 0 for unbufferable
;               r0 bits 9..31 = 0 (reserved flags)
;               r1 = physical address
;
;       Out:    r2 = logical address corresponding to phys address r1
;               r3 = old state (for ReleasePhysAddr)
;
; Use of multiple accesses: it is fine to make several Access calls, and
; clean up with a single Release at the end. In this case, it is the old state
; (r3) of the *first* Access call that should be passed to Release in order to
; restore the state before any of your accesses. (The r3 values of the other
; access calls can be ignored.)
;
AccessPhysAddr ROUT
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
        Push    "r0-r3,r12,lr"
        MOV     r2, #0
        B       %FT10

;----------------------------------------------------------------------------------------
;AccessPhysAddr64 - claim temporary access to given 64-bit physical address (in fact,
;                 controls access to the 1-16Mb aligned space containing the address)
;                 The access remains until the next AccessPhysAddr or until a
;                 ReleasePhysAddr (although interrupts or subroutines may temporarily
;                 make their own claims, but restore on Release before returning)
;
;       In:     r0 bits 0..7  = 22 (reason code 22)
;               r0 bit  8     = 1 to map bufferable space, 0 for unbufferable
;               r0 bits 9..31 = 0 (reserved flags)
;               r1,r2 = physical address
;
;       Out:    r2 = logical address corresponding to phys address r1
;               r3 = old state (for ReleasePhysAddr)
;
; Use of multiple accesses: it is fine to make several Access calls, and
; clean up with a single Release at the end. In this case, it is the old state
; (r3) of the *first* Access call that should be passed to Release in order to
; restore the state before any of your accesses. (The r3 values of the other
; access calls can be ignored.)
;
AccessPhysAddr64
        Push    "r0-r3,r12,lr"
10      TST     r0, #&100           ;test bufferable bit
1041 1042
        LDR     r0, =OSAP_None+DynAreaFlags_NotCacheable
        ORREQ   r0, r0, #DynAreaFlags_NotBufferable
1043
        SUB     sp, sp, #4          ; word for old state
1044
        MOV     r3, sp              ; pointer to word
1045
        BL      AccessPhysicalAddress
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
        MOVS    r2, r0              ; null pointer means invalid physical address
        LDMIB   sp, {r0,r1}
        BEQ     %FT90
        LDR     r3, [sp], #5*4      ; load old state, and skip stacked r0-r3
        Pull    "r12,pc"

90      ADRL    r0, ErrorBlock_CantGetPhysMem
        SETV
        ADD     sp, sp, #2*4
        Pull    "r1-r3,r12,pc"
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066

;----------------------------------------------------------------------------------------
;ReleasePhysAddr - release temporary access that was claimed by AccessPhysAddr
;
;       In:     r0 bits 0..7  = 15 (reason code 15)
;               r0 bits 8..31 = 0 (reserved flags)
;               r1 = old state to restore
;
ReleasePhysAddr
        Push    "r0-r3,r12,lr"
        MOV     r0, r1
1067
        BL      ReleasePhysicalAddress
1068 1069
        Pull    "r0-r3,r12,pc"

1070 1071
        LTORG

1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
;----------------------------------------------------------------------------------------
;
;        In:    r0 = flags
;                       bit     meaning
;                       0-7     16 (reason code)
;                       8-15    1=cursor/system/sound
;                               2=IRQ stack
;                               3=SVC stack
;                               4=ABT stack
;                               5=UND stack
;                               6=Soft CAM
;                               7=Level 1 page tables
;                               8=Level 2 page tables
;                               9=HAL workspace
;                               10=Kernel buffers
1087
;                               11=HAL uncacheable workspace
1088 1089 1090 1091
;                               12=Kernel 'ZeroPage' workspace
;                               13=Processor vectors
;                               14=DebuggerSpace
;                               15=Scratch space
1092
;                               16=Compatibility page
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122
;                       16-31   reserved (set to 0)
;
;       Out:    r1 = base of area
;               r2 = address space allocated for area (whole number of pages)
;               r3 = actual memory used by area (whole number of pages)
;               all values 0 if not present, or incorporated into another area
;
;       Return size of various low-level memory regions
MemoryAreaInfo ROUT
        Entry   "r0"
        MOV     r1, #0
        MOV     r2, #0
        MOV     r3, #0
        MOV     lr, r0, LSR #8
        AND     lr, lr, #&FF
        CMP     lr, #(MAI_TableEnd - MAI_TableStart)/4
        ADDLO   pc, pc, lr, LSL #2
        B       %FT70
MAI_TableStart
        B       %FT70
        B       MAI_CursSysSound
        B       MAI_IRQStk
        B       MAI_SVCStk
        B       MAI_ABTStk
        B       MAI_UNDStk
        B       MAI_SoftCAM
        B       MAI_L1PT
        B       MAI_L2PT
        B       MAI_HALWs
        B       MAI_Kbuffs
1123
        B       MAI_HALWsNCNB
1124 1125 1126 1127
        B       MAI_ZeroPage
        B       MAI_ProcVecs
        B       MAI_DebuggerSpace
        B       MAI_ScratchSpace
1128
        B       MAI_CompatibilityPage
1129 1130 1131
MAI_TableEnd

70
1132 1133
        PullEnv
        B       MemoryBadParameters
1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167

MAI_CursSysSound
        LDR     r1, =CursorChunkAddress
        MOV     r2, #32*1024
        MOV     r3, r2
        EXIT

MAI_IRQStk
 [ IRQSTK < CursorChunkAddress :LOR: IRQSTK > CursorChunkAddress+32*1024
        LDR     r1, =IRQStackAddress
        MOV     r2, #IRQSTK-IRQStackAddress
        MOV     r3, r2
 ]
        EXIT

MAI_SVCStk
        LDR     r1, =SVCStackAddress
        MOV     r2, #SVCSTK-SVCStackAddress
        MOV     r3, r2
        EXIT

MAI_ABTStk
        LDR     r1, =ABTStackAddress
        MOV     r2, #ABTSTK-ABTStackAddress
        MOV     r3, r2
        EXIT

MAI_UNDStk
        LDR     r1, =UNDSTK :AND: &FFF00000
        LDR     r2, =UNDSTK :AND: &000FFFFF
        MOV     r3, r2
        EXIT

MAI_SoftCAM
Jeffrey Lee's avatar
Jeffrey Lee committed
1168
        LDR     r0, =ZeroPage
1169
        LDR     r1, [r0, #CamEntriesPointer]
Jeffrey Lee's avatar
Jeffrey Lee committed
1170 1171
        LDR     r2, [r0, #SoftCamMapSize]
        MOV     r3, r2
1172 1173 1174
        EXIT

MAI_L1PT
Jeffrey Lee's avatar
Jeffrey Lee committed
1175 1176 1177 1178 1179 1180
      [ LongDesc
        ; Combined L1PT & L2PT
        ASSERT  LL1PT = LL2PT+16*1024
        LDR     r1, =LL2PT
        MOV     r2, #16*1024+4096
      |
1181 1182
        LDR     r1, =L1PT
        MOV     r2, #16*1024
Jeffrey Lee's avatar
Jeffrey Lee committed
1183
      ]
1184 1185 1186 1187
        MOV     r3, r2
        EXIT

MAI_L2PT
Jeffrey Lee's avatar
Jeffrey Lee committed
1188
        L