MemInfo 34 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       MemoryConvert                   ; 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 64
        B       %BT20                           ; Reason code 10 reserved (for MemoryFreePoolLock).
        B       %BT20                           ; Reason code 11 reserved (for PCImapping).
65 66 67 68
        B       RecommendPage                   ; 12
        B       MapIOpermanent                  ; 13
        B       AccessPhysAddr                  ; 14
        B       ReleasePhysAddr                 ; 15
Neil Turton's avatar
Neil Turton committed
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
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
Kevin Bracey's avatar
Kevin Bracey committed
112
flush_tlb       *       1:SHL:30        ; Internal flag
Neil Turton's avatar
Neil Turton committed
113
flush_cache     *       1:SHL:31        ; Internal flag.
Kevin Bracey's avatar
Kevin Bracey committed
114
flush_all       *       flush_tlb :OR: flush_cache
Neil Turton's avatar
Neil Turton committed
115 116

MemoryConvert   ROUT
117
        Entry   "r0-r11"                ; Need lots of registers!!
Neil Turton's avatar
Neil Turton committed
118

Kevin Bracey's avatar
Kevin Bracey committed
119 120 121 122 123
;        MRS     lr, CPSR
;        Push    "lr"
;        ORR     lr, lr, #I32_bit+F32_bit
;        MSR     CPSR_c, lr

Neil Turton's avatar
Neil Turton committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
        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

        MOV     r6, #0
        LDR     r7, [r6, #MaxCamEntry]
        LDR     r6, [r6, #CamEntriesPointer]
        LDR     r8, =L2PT

Kevin Bracey's avatar
Kevin Bracey committed
143
        BIC     r0, r0, #flush_all      ; Bit set if any page is really made uncacheable (we must flush the cache).
Neil Turton's avatar
Neil Turton committed
144 145 146 147 148 149
10
        SUBS    r2, r2, #1
        BCC     %FT70

        LDMIA   r1!, {r3-r5}            ; Get next three word entry (PN,LA,PA) and move on pointer.

150 151 152 153
   [ ChocolateAMB
        BL      handle_AMBHonesty       ; may need to make page honest (as if not lazily mapped)
   ]

Neil Turton's avatar
Neil Turton committed
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
        TST     r0, #physical,wanted    ; If PA not wanted
        BEQ     %FT20                   ;   then skip.
        TST     r0, #logical,given      ; If LA not given (rotate clears C) then
        BLEQ    ppn_to_logical          ;   get it from PN (PA wanted (not given) & LA not given => PN given).
        BLCC    logical_to_physical     ; Get PA from LA.
        BCS     %FT80
        TST     r0, #logical,wanted
        STRNE   r4, [r1, #-8]           ; Store back LA if wanted.
        STR     r5, [r1, #-4]           ; Store back PA.
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

        ADD     r3, r6, r3, LSL #3      ; Point to CAM entry for this page.
        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
        STR     r5, [r3, #4]            ; Write back new PPL.
        BNE     %BT10                   ; Do next entry if we don't have to change L2.

        MOV     r4, r4, LSR #12
        ADD     r4, r8, r4, LSL #2      ; Address of L2 entry for logical address.
        LDR     r5, [r4]                ; Get L2 entry (safe as we know address is valid).
Kevin Bracey's avatar
Kevin Bracey committed
217
        ORR     r0, r0, #flush_tlb
Neil Turton's avatar
Neil Turton committed
218 219 220 221 222 223 224 225 226
        TST     r0, #cacheable_bit
        BICEQ   r5, r5, #L2_C           ; Disable/enable cacheability.
        ORREQ   r0, r0, #flush_cache    ; If disable then we must flush cache later.
        ORRNE   r5, r5, #L2_C
        STR     r5, [r4]                ; Write back new L2 entry.

        B       %BT10                   ; Do next entry.

70
Kevin Bracey's avatar
Kevin Bracey committed
227 228 229 230 231 232 233 234 235 236
        ; *** KJB - this assumes that uncacheable pages still allow cache hits (true on all
        ; ARMs so far).
        ; *** Also, fix it up to do it page by page.
        TST     r0, #flush_tlb
        EXIT    EQ                      ; If not flush_tlb, can't have flush_cache
        MOV     r1, r0
        MOV     r0, #0
        ARMop   TLB_InvalidateAll,,,r0
        TST     r1, #flush_cache        ; If any page has been made uncacheable in L2 then flush!
        EXIT    EQ
237 238
        MOV     r0, #0
        ARMop   Cache_CleanInvalidateAll,,,r0
Kevin Bracey's avatar
Kevin Bracey committed
239 240 241
;75
;        Pull    "lr"
;        MSR     CPSR_c, lr
Neil Turton's avatar
Neil Turton committed
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
        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.
        BLNE    MemoryConvert
90
        ADRL    r0, ErrorBlock_BadAddress
95
        STR     r0, [sp]
        SETV
        EXIT

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
   [ ChocolateAMB
;
;  entry: r3,r4,r5 = provided PN,LA,PA triple for entry to make honest (at least one given)
;         r0 bits flag which of PN,LA,PA are given
;  exit:  mapping made honest (as if not lazily mapped) if necessary
handle_AMBHonesty  ROUT
        Push    "r0, r3-r5, lr"
        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
        Push    "r7, r9-r11"
        MOV     r14, #0
        LDR     r7, [r14, #MaxCamEntry]
        BL      physical_to_ppn
        Pull    "r7, r9-r11"
        BCC     %BT15
90
        Pull    "r0, r3-r5, pc"

   ] ;ChocolateAMB

Neil Turton's avatar
Neil Turton committed
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312

;----------------------------------------------------------------------------------------
; ppn_to_logical
;
;       In:     r3 = page number
;               r5 = physical address if given
;               r6 = CamEntriesPointer
;               r7 = MaxCamEntry
;
;       Out:    r9 corrupted
;               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
313 314 315
 [ No26bitCode
        BCC     meminfo_returncs        ; Invalid so return C set.
 |
Neil Turton's avatar
Neil Turton committed
316
        ORRCCS  pc, lr, #C_bit          ; Invalid so return C set.
Kevin Bracey's avatar
Kevin Bracey committed
317
 ]
Neil Turton's avatar
Neil Turton committed
318 319 320 321 322 323

        LDR     r4, [r6, r3, LSL #3]    ; If valid then lookup logical address.
        TST     r0, #physical,given     ; If physical address was given then
        LDRNE   r9, =&FFF
        ANDNE   r9, r5, r9              ;   mask off page offset
        ORRNE   r4, r4, r9              ;   and combine with logical address.
Kevin Bracey's avatar
Kevin Bracey committed
324 325 326 327
 [ No26bitCode
        CLC
        MOV     pc, lr
 |
Neil Turton's avatar
Neil Turton committed
328
        BICS    pc, lr, #C_bit          ; Return C clear.
Kevin Bracey's avatar
Kevin Bracey committed
329
 ]
Neil Turton's avatar
Neil Turton committed
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350


;----------------------------------------------------------------------------------------
; logical_to_physical
;
;       In:     r4 = logical address
;               r8 = L2PT
;
;       Out:    r9 corrupted
;               CC => r5 = physical address
;               CS => invalid logical address, r5 corrupted
;
;       Convert logical address to physical address.
;
logical_to_physical
        MOV     r9, r4, LSR #12         ; r9 = logical page number
        ADD     r9, r8, r9, LSL #2      ; r9 -> L2PT entry for logical address
        MOV     r5, r9, LSR #12         ; r5 = page offset to L2PT entry for logical address
        LDR     r5, [r8, r5, LSL #2]    ; r5 = L2PT entry for L2PT entry for logical address
        EOR     r5, r5, #2_10           ; Check for valid page.
        TST     r5, #3
Kevin Bracey's avatar
Kevin Bracey committed
351 352 353
 [ No26bitCode
        BNE     meminfo_returncs
 |
Neil Turton's avatar
Neil Turton committed
354
        ORRNES  pc, lr, #C_bit
Kevin Bracey's avatar
Kevin Bracey committed
355
 ]
Neil Turton's avatar
Neil Turton committed
356 357 358 359

        LDR     r5, [r9]                ; r5 = L2PT entry for logical address
        EOR     r5, r5, #2_10           ; Check for valid page.
        TST     r5, #3
Kevin Bracey's avatar
Kevin Bracey committed
360 361 362
 [ No26bitCode
        BNE     meminfo_returncs
 |
Neil Turton's avatar
Neil Turton committed
363
        ORRNES  pc, lr, #C_bit
Kevin Bracey's avatar
Kevin Bracey committed
364
 ]
Neil Turton's avatar
Neil Turton committed
365 366 367 368 369

        LDR     r9, =&FFF               ; Valid so
        BIC     r5, r5, r9              ;   mask off bits 0-11,
        AND     r9, r4, r9              ;   get page offset from logical page
        ORR     r5, r5, r9              ;   combine with physical page address.
Kevin Bracey's avatar
Kevin Bracey committed
370 371 372 373
 [ No26bitCode
        CLC
        MOV     pc, lr
 |
Neil Turton's avatar
Neil Turton committed
374
        BICS    pc, lr, #C_bit
Kevin Bracey's avatar
Kevin Bracey committed
375
 ]
Neil Turton's avatar
Neil Turton committed
376

Kevin Bracey's avatar
Kevin Bracey committed
377 378 379
meminfo_returncs
        SEC
        MOV     pc, lr
Neil Turton's avatar
Neil Turton committed
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397

;----------------------------------------------------------------------------------------
; physical_to_ppn
;
;       In:     r5 = physical address
;               r7 = MaxCamEntry
;
;       Out:    r9-r11 corrupted
;               CC => r3 = page number
;               CS => invalid physical address, r3 corrupted
;
;       Convert physical address to physical page number.
;
physical_to_ppn ROUT
        MOV     r9, #PhysRamTable
        MOV     r3, #0                  ; Start at page 0.
10
        CMP     r7, r3                  ; Stop if we run out of pages
Kevin Bracey's avatar
Kevin Bracey committed
398 399 400
 [ No26bitCode
        BCC     meminfo_returncs
 |
Neil Turton's avatar
Neil Turton committed
401
        ORRCCS  pc, lr, #C_bit          ;   (return with C set).
Kevin Bracey's avatar
Kevin Bracey committed
402
 ]
Neil Turton's avatar
Neil Turton committed
403 404 405 406 407 408 409 410

        LDMIA   r9!, {r10,r11}          ; Get start address and size of next block.
        SUB     r10, r5, r10            ; Determine if given address is in this block.
        CMP     r10, r11
        ADDCS   r3, r3, r11, LSR #12    ; Move on to next block.
        BCS     %BT10

        ADD     r3, r3, r10, LSR #12
Kevin Bracey's avatar
Kevin Bracey committed
411 412 413 414
 [ No26bitCode
        CLC
        MOV     pc, lr
 |
Neil Turton's avatar
Neil Turton committed
415
        BICS    pc, lr, #C_bit          ; Return with C clear.
Kevin Bracey's avatar
Kevin Bracey committed
416
 ]
Neil Turton's avatar
Neil Turton committed
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463


;----------------------------------------------------------------------------------------
; 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
        MOV     r1, #PhysSpaceSize :SHR: ByteShift
        MOV     r2, #4*1024
        MOV     pc, lr


;----------------------------------------------------------------------------------------
; 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
464
        Entry   "r1-r10"
Neil Turton's avatar
Neil Turton committed
465

466 467 468
 [ HAL
        ! 0, "Sort out MemoryReadPhys"
 |
469 470
        ; &00000000 to OSROM_ImageSize*1024 is ROM.
        MOV     r2, #(OSROM_ImageSize*1024-&00000000) :SHR: WordShift
Neil Turton's avatar
Neil Turton committed
471 472 473
        LDR     r3, =ROM_Pattern :OR: NotAvailable
        BL      fill_words

474 475
        ; OSROM_ImageSize*1024 to &02000000 is allocated to ROM but is not present.
        MOV     r2, #(&02000000-OSROM_ImageSize*1024) :SHR: WordShift
Neil Turton's avatar
Neil Turton committed
476 477 478
        LDR     r3, =NotPresent :OR: NotAvailable
        BL      fill_words

479
        ; &02000000 to &02400000 is VRAM or not present.
Neil Turton's avatar
Neil Turton committed
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 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
        MOV     r4, #0
        LDR     r4, [r4, #VRAMSize]     ; Get amount of VRAM (in bytes).
        TEQ     r4, #0
        MOVNE   r2, r4, LSR #WordShift  ; If there is some then fill part of table.
        LDRNE   r3, =VRAM_Pattern :OR: NotAvailable
        BLNE    fill_words

        ; End of VRAM to &03000000 is not present.
        RSB     r4, r4, #&03000000-&02000000
        MOV     r2, r4, LSR #WordShift
        LDR     r3, =NotPresent :OR: NotAvailable
        BL      fill_words

        ; &03000000 to &03800000 is I/O.
        MOV     r2, #(&03800000-&03000000) :SHR: WordShift
        LDR     r3, =IO_Pattern :OR: NotAvailable
        BL      fill_words

        ; &03800000 to &08000000 is not present.
        MOV     r2, #(&08000000-&03800000) :SHR: WordShift
        LDR     r3, =NotPresent :OR: NotAvailable
        BL      fill_words

        ; &08000000 to &10000000 is I/O (EASI space).
        MOV     r2, #(&10000000-&08000000) :SHR: WordShift
        LDR     r3, =IO_Pattern :OR: NotAvailable
        BL      fill_words

        ; &10000000 to &20000000 is DRAM or not present.
        MOV     r2, #&10000000          ; Current physical address.
        MOV     r3, #0                  ; Next word to store in table.
        MOV     r4, #32                 ; How much more we have to shift r3 before storing it.
        MOV     r5, #0                  ; Current page number.
        MOV     r6, #PhysRamTable
        LDR     r7, [r3, #CamEntriesPointer]
        ADD     r7, r7, #4              ; Point to PPL entries.
        LDR     r8, [r3, #MaxCamEntry]
10
        LDMIA   r6!, {r9,r10}           ; Get physical address and size of next block.

        CMP     r9, #&10000000          ; If not DRAM then
        ADDCC   r5, r5, r10, LSR #12    ;   adjust current page number
        BCC     %BT10                   ;   and try next block.

        ADD     r10, r10, r9            ; Add amount of unused space between current and start of block.
        SUB     r10, r10, r2            ; size = size + (physaddr - current)
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

        CMP     r2, r9                  ; If not reached start of block then page is not present.
        ORRCC   r3, r3, #(NotPresent :OR: NotAvailable) :SHL: 28
        BCC     %FT30
        LDR     lr, [r7, r5, LSL #3]    ; Page is there so get PPL and determine if it's available or not.
        TST     lr, #PageFlags_Unavailable
        ORREQ   r3, r3, #DRAM_Pattern :SHL: 28
        ORRNE   r3, r3, #(DRAM_Pattern :OR: NotAvailable) :SHL: 28
        ADD     r5, r5, #1              ; Increment page count.
30
        ADD     r2, r2, #&1000          ; Increase current address.
        SUBS    r10, r10, #&1000        ; Decrease size of block.
        BGT     %BT20                   ; Stop if no more block left.

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

        TEQ     r3, #0                          ; If not stored last word then
        MOVNE   r3, r3, LSR r4                  ;   put bits in correct position
        ADDNE   r2, r2, r4, LSL #BitShift       ;   adjust current address
        RSBNE   r4, r4, #32                     ;   rest of word is not present
        LDRNE   lr, =NotPresent :OR: NotAvailable
        ORRNE   r3, r3, lr, LSL r4
        STRNE   r3, [r1], #4                    ;   and store word.

        ; End of last block of DRAM to &20000000 is not present.
        RSBS    r2, r2, #&20000000
        MOVNE   r2, r2, LSR #WordShift
        LDRNE   r3, =NotPresent :OR: NotAvailable
        BLNE    fill_words
562
  ]
Neil Turton's avatar
Neil Turton committed
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579

        EXIT


fill_words
        STR     r3, [r1], #4
        SUBS    r2, r2, #1
        BNE     fill_words
        MOV     pc, lr


;----------------------------------------------------------------------------------------
; MemoryAmounts
;
;       In:     r0 = flags
;                       bit     meaning
;                       0-7     8 (reason code)
580
;                       8-11    1=return amount of DRAM (excludes any soft ROM)
Neil Turton's avatar
Neil Turton committed
581 582 583
;                               2=return amount of VRAM
;                               3=return amount of ROM
;                               4=return amount of I/O space
584
;                               5=return amount of soft ROM (ROM loaded into hidden DRAM)
Neil Turton's avatar
Neil Turton committed
585 586 587 588 589 590 591 592
;                       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
593
        Entry   "r3"
Neil Turton's avatar
Neil Turton committed
594

595 596
 [ HAL
        ! 0, "Sort out MemoryAmounts"
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
        ;
        ;temp bodge for DRAM,VRAM
        ;
        BICS    lr, r0, #&FF            ; Get type of memory required (leave bits 12-31, non-zero => error).
        BEQ     %FT30                   ; Don't understand 0 (so the spec says).
        TEQ     lr, #1:SHL:8
        BNE     %FT10
        MOV     r1, #0
        LDR     r1, [r1, #RAMLIMIT]     ; assume 0 VRAM
        B       %FT20
10
        TEQ     lr, #2:SHL:8
        BNE     %FT40                   ; not implementing anything else in this bodge
        MOV     r1, #0                  ; assume 0 VRAM
20
        MOV     r1, r1, LSR #12         ; Return as number of pages.
        MOV     r2, #4*1024             ; Return page size.
        EXIT
30
        ADRL    r0, ErrorBlock_BadParameters
        SETV
40
        EXIT
620
 |
Neil Turton's avatar
Neil Turton committed
621 622 623
        BICS    lr, r0, #&FF            ; Get type of memory required (leave bits 12-31, non-zero => error).
        BEQ     %FT30                   ; Don't understand 0 (so the spec says).

624 625 626 627 628 629 630 631 632 633 634 635 636
        TEQ     lr, #5:SHL:8            ; Check for soft ROM
        BNE     %FT10
        LDR     r1, =L1PT
        MOV     r2, #ROM
        ADD     r1, r1, r2, LSR #(20-2)   ; L1PT address for ROM
        LDR     r2, [r1]
        MOV     r2, r2, LSR #12
        TEQ     r2, #PhysROM :SHR: 12     ; see if we have hard or soft ROM
        MOVEQ   r1, #0                    ; no soft ROM
        MOVNE   r1, #OSROM_ImageSize*1024 ; this much soft ROM
        B       %FT20

10
Neil Turton's avatar
Neil Turton committed
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
        TEQ     lr, #4:SHL:8            ; Check for IO space.
        LDREQ   r1, =136*1024*1024      ; Just return 136M (includes VIDC and EASI space).
        BEQ     %FT20

        TEQ     lr, #3:SHL:8            ; Check for ROM.
        LDREQ   r1, =OSROM_ImageSize*1024
        BEQ     %FT20

        TEQ     lr, #2:SHL:8            ; Check for VRAM.
        MOVEQ   r1, #0                  ; Return amount of VRAM.
        LDREQ   r1, [r1, #VRAMSize]
        BEQ     %FT20

        TEQ     lr, #1:SHL:8            ; Check for DRAM.
        BNE     %FT30
        MOV     r1, #0
        LDR     lr, [r1, #RAMLIMIT]
        LDR     r1, [r1, #VRAMSize]
        SUB     r1, lr, r1              ; Return amount of RAM - amount of VRAM.

20
        MOV     r1, r1, LSR #12         ; Return as number of pages.
        MOV     r2, #4*1024             ; Return page size.
        EXIT

30
        ADRL    r0, ErrorBlock_BadParameters
        SETV
        EXIT
666
 ]
Neil Turton's avatar
Neil Turton committed
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685


;----------------------------------------------------------------------------------------
; 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
;                               1 = EASI space
;                               2 = VIDC1
;                               3 = VIDC20
;
;       Out:    r1 = controller base address or 0 if not present
;
;       Return the location of the specified controller.
;
Kevin Bracey's avatar
Kevin Bracey committed
686 687 688 689 690 691 692 693 694

 [ HAL
MemoryIOSpace   ROUT
        Entry   "r0,r2,r3,sb,ip"
        AddressHAL
        CallHAL HAL_ControllerAddress
        MOV     r1, r0
        EXIT
 |
Neil Turton's avatar
Neil Turton committed
695
MemoryIOSpace   ROUT
696
        Entry   "r2"
Neil Turton's avatar
Neil Turton committed
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736

        AND     r2, r1, #&FF            ; Get sequence number.
        MOV     r1, r1, LSR #8          ; Get controller type.
        CMP     r1, #4                  ; Make sure it's in range.
        BCS     %FT20

        ADR     lr, controller_types
        LDR     r1, [lr, r1, LSL #2]    ; Get base address or offset to table.
        TEQ     r1, #0                  ; If not present or
        CMPNE   r1, #1024               ;     not offset to table then
        EXIT    GE                      ;   return.

        ADD     lr, lr, r1              ; Point to table indexed by sequence number.
        LDR     r1, [lr], #4            ; Get sequence number limit.
        CMP     r2, r1                  ; Make sure it's in range.
        BCS     %FT20
        LDR     r1, [lr, r2, LSL #2]    ; Get base address.
        EXIT

20
        ADRL    r0, ErrorBlock_BadParameters
        SETV
        EXIT

controller_types
        DCD     IOMD_Base + IOMD_ECTCR  ; Expansion card timing control.
        DCD     easi_space_table - controller_types
        DCD     0
        DCD     VIDC

easi_space_table
        DCD     8                       ; Maximum of 8 expansion cards.
        DCD     PhysSpace + IOMD_EASI_Base0
        DCD     PhysSpace + IOMD_EASI_Base1
        DCD     PhysSpace + IOMD_EASI_Base2
        DCD     PhysSpace + IOMD_EASI_Base3
        DCD     PhysSpace + IOMD_EASI_Base4
        DCD     PhysSpace + IOMD_EASI_Base5
        DCD     PhysSpace + IOMD_EASI_Base6
        DCD     PhysSpace + IOMD_EASI_Base7
Kevin Bracey's avatar
Kevin Bracey committed
737
 ] ; HAL
Neil Turton's avatar
Neil Turton committed
738

739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 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
;----------------------------------------------------------------------------------------
; MemoryFreePoolLock
;
; See code on Ursula branch

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


;----------------------------------------------------------------------------------------
;RecommendPage
;
;       In:     r0 bits 0..7  = 12 (reason code 12)
;               r0 bits 8..31 = 0 (reserved flags)
;               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
        Push    "r0-r2,r4-r10,lr"
        CMP     r2,#30
        BHI     RP_failed            ;refuse to look for alignments above 1G
;
        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
;
        MOV     r0,#PhysRamTable
        MOV     r3,#0            ;page number, starts at 0
        LDR     r5,=CamEntriesPointer
        LDR     r5,[r5]
        ADD     r5,r5,#4         ; [r5,<page no.>,LSL #3] addresses flags word in CAM
        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
;
        ADD     r6,r7,r4
        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
        BLO     RP_nextchunk
        LDR     r6,[r5,r7,LSL #3]  ;page flags from CAM
        ;must not be marked Unavailable or Required
        TST     r6,#PageFlags_Unavailable :OR: PageFlags_Required
        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
        LDR     r6,[r5,r10,LSL #3] ;page flags from CAM
        TST     r6,#PageFlags_Unavailable :OR: PageFlags_Required
        BNE     RP_nextpagecontinue
        SUB     r10,r10,#1
        CMP     r10,r7
        BHI     RP_checkotherpagesloop
;
;success!
;
        MOV     r3,r7
        Pull    "r0-r2,r4-r10,pc"

RP_failed
        MOV     r3,#0
        ADR     r0,RP_error
        SETV
        STR     r0,[sp]
        Pull    "r0-r2,r4-r10,pc"

RP_error
        DCD     0
        DCB     "No chunk available (OS_Memory 12)",0
        ALIGN

844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921
;----------------------------------------------------------------------------------------
;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)
;               r0 bits 9..31 = 0 (reserved flags)
;               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
        Push    "r0-r2,r12,lr"
        TST     r0, #&100           ;test bufferable bit
        MOVNE   r0, #L1_B
        MOVEQ   r0, #0
        BL      RISCOS_MapInIO
        MOV     r3, r0
        CMP     r3, #0              ;MOV,CMP rather than MOVS to be sure to clear V
        Pull    "r0-r2,r12,pc",NE
        ADR     r0, MIp_error
        SETV
        STR     r0, [sp]
        Pull    "r0-r2,r12,pc"

MIp_error
        DCD     0
        DCB     "No room for IO space (OS_Memory 13)",0
        ALIGN

;----------------------------------------------------------------------------------------
;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
        Push    "r0,r1,r12,lr"
        TST     r0, #&100           ;test bufferable bit
        MOVNE   r0, #L1_B
        MOVEQ   r0, #0
        SUB     sp, sp, #4          ; word for old state
        MOV     r2, sp              ; pointer to word
        BL      RISCOS_AccessPhysicalAddress
        MOV     r2, r0
        Pull    r3                  ; old state
        Pull    "r0,r1,r12,pc"

;----------------------------------------------------------------------------------------
;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
        BL      RISCOS_ReleasePhysicalAddress
        Pull    "r0-r3,r12,pc"


Neil Turton's avatar
Neil Turton committed
922
        END