Commit df4efb68 authored by Jeffrey Lee's avatar Jeffrey Lee Committed by ROOL
Browse files

Support RAM banks with high physical addresses

This changes PhysRamTable to store the address of each RAM bank in terms
of (4KB) pages instead of bytes, effectively allowing it to support a 44
bit physical address space. This means that (when the long descriptor
page table format is used) the OS can now make use of memory located
outside the lower 4GB of the physical address space. However some
public APIs still need extending to allow for all operations to be
supported on high RAM (e.g. OS_Memory logical to physical address
lookups)

OS_Memory 12 (RecommendPage) has been extended to allow R4-R7 to be used
to specify a (64bit) physical address range which the recommended pages
must lie within. For backwards compatibility this defaults to 0-4GB.
parent 402f32c2
...@@ -1035,13 +1035,13 @@ IICBus_Size # 0 ...@@ -1035,13 +1035,13 @@ IICBus_Size # 0
InitWsStart # 0 InitWsStart # 0
InitIRQHandler # 4 ; pointer to IRQ handler (LDR PC'ed from IRQ HW vector) InitIRQHandler # 4 ; pointer to IRQ handler (LDR PC'ed from IRQ HW vector)
InitIRQWs # 16 ; workspace for IRQ handler InitIRQWs # 16 ; workspace for IRQ handler
InitUsedStart # 4 ; start of used pages (L2PT etc) not to be cleared InitUsedStart # 4 ; start of used pages (L2PT etc) not to be cleared (32bit address)
InitUsedEnd # 4 ; end of used pages InitUsedEnd # 4 ; end of used pages (page units)
InitUsedBlock # 4 ; current block in PhysRamTable InitUsedBlock # 4 ; current block in PhysRamTable
InitClearRamWs # 10*4 ; preserve registers during ClearPhysRAM InitClearRamWs # 10*4 ; preserve registers during ClearPhysRAM
InitDMABlock # 8 ; block of DMAable memory extracted from PhysRamTable InitDMABlock # 8 ; block of DMAable memory extracted from PhysRamTable
InitDMAOffset # 4 ; offset+8 into PhysRamTable where memory was taken InitDMAOffset # 4 ; offset+8 into PhysRamTable where memory was taken
InitDMAEnd # 4 ; current DMA alloc pos InitDMAEnd # 4 ; current DMA alloc pos (32bit address)
AlignSpace 32 ; because we clear 32 at a time AlignSpace 32 ; because we clear 32 at a time
InitWsEnd # 0 InitWsEnd # 0
...@@ -1147,8 +1147,11 @@ Oscli_CmdHashLists # 4 ;anchor for hashed command lists structure ...@@ -1147,8 +1147,11 @@ Oscli_CmdHashLists # 4 ;anchor for hashed command lists structure
SkippedTables # 0 SkippedTables # 0
PhysRamTable # 0 ; Pairs of words (physaddr, size+flags) PhysRamTable # 0 ; Pairs of words (physaddr, size+flags)
; indicating RAM present in machine ; indicating RAM present in machine. physaddr
; Unused entries have size of zero ; is in units of pages. size is in bytes, with
; the flags in the low 12 bits. Individual
; entries don't cross 4GB barriers. Unused
; entries have size+flags of zero.
VideoPhysAddr # 4 ; Address of video RAM (in the case of DRAM-only machines, VideoPhysAddr # 4 ; Address of video RAM (in the case of DRAM-only machines,
VideoSizeFlags # 4 ; this is actually a chunk out of DRAM) VideoSizeFlags # 4 ; this is actually a chunk out of DRAM)
DRAMPhysAddrA # 4 ; Next the DRAM DRAMPhysAddrA # 4 ; Next the DRAM
...@@ -1345,7 +1348,7 @@ MaxCamEntry # 4 ; maximum index into the cam map, ie ...@@ -1345,7 +1348,7 @@ MaxCamEntry # 4 ; maximum index into the cam map, ie
; 511 for 16MByte machines, 383 for 12MBytes ; 511 for 16MByte machines, 383 for 12MBytes
; 255 for 8MBytes, otherwise 127 ; 255 for 8MBytes, otherwise 127
RAMLIMIT # 4 RAMLIMIT # 4 ; Number of pages of RAM
ROMPhysAddr # 4 ROMPhysAddr # 4
......
...@@ -88,5 +88,6 @@ OSRSI6_VecPtrTab * 85 ...@@ -88,5 +88,6 @@ OSRSI6_VecPtrTab * 85
OSRSI6_NVECTORS * 86 OSRSI6_NVECTORS * 86
OSRSI6_CAMFormat * 87 ; 0 = 8 bytes per entry, 1 = 16 bytes per entry OSRSI6_CAMFormat * 87 ; 0 = 8 bytes per entry, 1 = 16 bytes per entry
OSRSI6_ABTSTK * 88 OSRSI6_ABTSTK * 88
OSRSI6_PhysRamtableFormat * 89 ; 0 = addresses are in byte units, 1 = addresses are in 4KB units
END END
...@@ -468,7 +468,8 @@ AMB_LazyFixUp ROUT ...@@ -468,7 +468,8 @@ AMB_LazyFixUp ROUT
CMP r6,r5 CMP r6,r5
SUBHS r6,r6,r5 SUBHS r6,r6,r5
BHS %BT10 BHS %BT10
ADD r4,r4,r6,LSL #12 ADD r4,r4,r6
MOV r4,r4,ROR #20 ;High address packed into low bits for LongDesc
MOV r1,#DynAreaFlags_PMP MOV r1,#DynAreaFlags_PMP
GetPTE r4,4K,r4,r1 GetPTE r4,4K,r4,r1
; ;
......
...@@ -86,8 +86,9 @@ BangCamUpdate ROUT ...@@ -86,8 +86,9 @@ BangCamUpdate ROUT
BCS %BT10 ; if more than that, go onto next bank BCS %BT10 ; if more than that, go onto next bank
ADD r6, r6, r4, LSR #12 ; put back the ones which were too many ADD r6, r6, r4, LSR #12 ; put back the ones which were too many
ADD r0, r0, r6, LSL #12 ; move on address by the number of pages left ADD r0, r0, r6 ; move on address by the number of pages left
LDR r6, [sp] ; reload old logical address LDR r6, [sp] ; reload old logical address
MOV r0, r0, LSL #12 ; convert from page units to bytes
; now we have r6 = old logical address, r2 = physical page number, r0 = physical address ; now we have r6 = old logical address, r2 = physical page number, r0 = physical address
......
...@@ -407,10 +407,7 @@ ReadDynamicArea ROUT ...@@ -407,10 +407,7 @@ ReadDynamicArea ROUT
ReadMemMapInfo_Code ReadMemMapInfo_Code
LDR R10, =ZeroPage LDR R10, =ZeroPage
LDR R0, [R10, #Page_Size] LDR R0, [R10, #Page_Size]
LDR R1, [R10, #RAMLIMIT] ; = total memory size LDR R1, [R10, #RAMLIMIT] ; = total number of pages
ADRL R11, PageShifts-1
LDRB R11, [R11, R0, LSR #12]
MOV R1, R1, LSR R11
ExitSWIHandler ExitSWIHandler
; ************************************************************************ ; ************************************************************************
...@@ -867,8 +864,8 @@ DAC_notsparse ...@@ -867,8 +864,8 @@ DAC_notsparse
LDR r10, =ZeroPage LDR r10, =ZeroPage
LDR r11, [r10, #Page_Size] LDR r11, [r10, #Page_Size]
LDR r10, [r10, #RAMLIMIT] ; get total RAM size LDR r10, [r10, #RAMLIMIT] ; get total RAM size
CMP r5, r10 ; if requested maximum size is > total CMP r10, r5, LSR #Log2PageSize ; if requested maximum size is > total
MOVHI r5, r10 ; then set max to total (NB. -1 passed in always yields HI) MOVLS r5, r10, LSL #Log2PageSize ; then set max to total. Note no special handling of R5=-1 is needed (R5=-1 will get treated as 4GB-1. If RAMLIMIT < 4GB then R5 will be clamped correctly, if RAMLIMIT >= 4GB then the request will fail regardless because we only have limited logical address space to work with)
DAC_roundup DAC_roundup
SUB r10, r11, #1 ; also round up to a page multiple SUB r10, r11, #1 ; also round up to a page multiple
...@@ -4591,11 +4588,12 @@ DynArea_AddrLookup_loop ...@@ -4591,11 +4588,12 @@ DynArea_AddrLookup_loop
LDR r0, [r5, #InitUsedStart] LDR r0, [r5, #InitUsedStart]
ADD r0, r0, #DRAMOffset_FirstFixed - DRAMOffset_PageTables ADD r0, r0, #DRAMOffset_FirstFixed - DRAMOffset_PageTables
MOV r1, #0 ; only know 32-bit addresses for now MOV r1, #0 ; start of init block is always 32bit address
BL PhysAddrToPageNo BL PhysAddrToPageNo
MOV r7, r0 ; r7 = page number of start of static chunk MOV r7, r0 ; r7 = page number of start of static chunk
LDR r0, [r5, #InitUsedEnd] LDR r0, [r5, #InitUsedEnd]
MOV r1, #0 ; only know 32-bit addresses for now MOV r1, r0, LSR #20
MOV r0, r0, LSL #12
BL PhysAddrToPageNo BL PhysAddrToPageNo
SUB r8, r0, #1 ; r8 = page number of last page in statics SUB r8, r0, #1 ; r8 = page number of last page in statics
ADD r9, r5, #PhysRamTable ADD r9, r5, #PhysRamTable
...@@ -5678,7 +5676,11 @@ DoTheGrowPagesSpecified ROUT ...@@ -5678,7 +5676,11 @@ DoTheGrowPagesSpecified ROUT
BCS %BT06 BCS %BT06
ADD r3, r3, lr, LSR #12 ; put back what could not be subtracted ADD r3, r3, lr, LSR #12 ; put back what could not be subtracted
ADD r8, r8, r3, LSL #12 ; and add onto base address ADD r8, r8, r3 ; and add onto base address
! 0, "LongDescTODO 4GB"
CMP r8, #1:SHL:20 ; 4GB limit
BHS DoTheGrowPageUnavailable
MOV r8, r8, LSL #12
STR r8, [r1, #8-12] ; store physical address in page block STR r8, [r1, #8-12] ; store physical address in page block
SUBS r2, r2, #1 SUBS r2, r2, #1
...@@ -5807,7 +5809,10 @@ DoTheGrowPagesSpecified ROUT ...@@ -5807,7 +5809,10 @@ DoTheGrowPagesSpecified ROUT
MOV r3, r6 MOV r3, r6
BL ppn_to_physical BL ppn_to_physical
MOV r10, r8 MOV r10, r8
! 0, "LongDescTODO 4GB"
CMP r9, #0
Pull "r3,r5,r8,r9" Pull "r3,r5,r8,r9"
BNE %BT64
; DREG r6, "Using page number " ; DREG r6, "Using page number "
68 68
...@@ -6406,11 +6411,13 @@ CallPreGrow ROUT ...@@ -6406,11 +6411,13 @@ CallPreGrow ROUT
20 20
ADD r2,r2,r12,LSR #12 ; advance page number ADD r2,r2,r12,LSR #12 ; advance page number
21 21
LDR r12,[r0],#8 ; get next chunk details LDMIA r0!,{r3,r12} ; get next chunk details
CMP r12,#0 CMP r12,#0
BEQ %FT90 BEQ %FT90
TST r12,#OSAddRAM_NoDMA TST r12,#OSAddRAM_NoDMA
BNE %BT20 BNE %BT20
CMP r3,#1:SHL:20 ; stick to lower 4GB for compatibility with old code
BHS %BT20
; Check the CAM map to see if any pages here are free ; Check the CAM map to see if any pages here are free
MOV r12,r12,LSR #12 MOV r12,r12,LSR #12
30 30
......
...@@ -476,8 +476,18 @@ RISCOS_Start ...@@ -476,8 +476,18 @@ RISCOS_Start
B %BT31 B %BT31
32 32
; Fill in the Kernel's permanent memory table, sorting by speed and DMA ability ; Fill in the Kernel's permanent memory table, sorting by address, speed and DMA ability.
; Non-DMAable RAM is preferred over DMAable, as the kernel requires very little DMAable RAM, and we don't want to permanently claim DMAable RAM if we're not actually using it for DMA (in case machine only has a tiny amount available) ; * Address: All memory that falls in the low 4GB of the physical map
; comes first. This makes it easier for our initial memory allocation
; (no danger of allocating pages which can't be accessed with the MMU
; off), but may also help with wider software compatibility (all low-
; RAM pages occupy the lowest physical page numbers)
; * Non-DMAable RAM is preferred over DMAable, as the kernel requires
; very little DMAable RAM, and we don't want to permanently claim
; DMAable RAM if we're not actually using it for DMA (in case machine
; only has a tiny amount available)
; * Speed: Fastest RAM is listed first, so that we'll prefer to allocate
; it for these important kernel/system areas
ADD ip, v1, #DRAMOffset_PageZero ADD ip, v1, #DRAMOffset_PageZero
ASSERT DRAMOffset_PageZero > 0 ; If the workspace block is the block containing the OS_AddRAM list, make sure the two don't overlap otherwise we might corrupt it while we copy it ASSERT DRAMOffset_PageZero > 0 ; If the workspace block is the block containing the OS_AddRAM list, make sure the two don't overlap otherwise we might corrupt it while we copy it
...@@ -491,12 +501,11 @@ RISCOS_Start ...@@ -491,12 +501,11 @@ RISCOS_Start
; First put the VRAM information in to free up some regs ; First put the VRAM information in to free up some regs
ADD v7, ip, #VideoPhysAddr ADD v7, ip, #VideoPhysAddr
MOV v4, v4, LSL #12 ; 32bit only for now
! 0, "LongDescTODO VRAM selection doesn't guarantee 32bit address"
STMIA v7!, {v4, v6} STMIA v7!, {v4, v6}
; Now fill in the rest ; Now fill in the rest
ASSERT DRAMPhysAddrA = VideoPhysAddr+8 ASSERT DRAMPhysAddrA = VideoPhysAddr+8
MOV v1, v1, LSR #12
ADDS v2, v2, #4096 ; Store true length ADDS v2, v2, #4096 ; Store true length
ADDCS v2, v2, #1:SHL:31 ; If it overflowed, must have been 4GB block, so clamp at 2GB (loop below will add the second 2GB) ADDCS v2, v2, #1:SHL:31 ; If it overflowed, must have been 4GB block, so clamp at 2GB (loop below will add the second 2GB)
STMIA v7!, {v1, v2} ; workspace block must be first STMIA v7!, {v1, v2} ; workspace block must be first
...@@ -504,29 +513,31 @@ RISCOS_Start ...@@ -504,29 +513,31 @@ RISCOS_Start
TEQ v8, a4 TEQ v8, a4
BEQ %FT39 BEQ %FT39
LDMIA v8!, {v1, v2} LDMIA v8!, {v1, v2}
CMP v1, #1:SHL:20
BHS %BT33 ; skip >4GB addresses for now
MOV v1, v1, LSL #12
ADDS v2, v2, #4096 ; Get true length ADDS v2, v2, #4096 ; Get true length
ADDCS v2, v2, #1:SHL:31 ; If it overflowed, must have been 4GB block, so split into two 2GB blocks ADDCS v2, v2, #1:SHL:31 ; If it overflowed, must have been 4GB block, so split into two 2GB blocks
SUBCS v2, v2, #4096 SUBCS v2, v2, #4096
ADDCS v1, v1, #1:SHL:31 ADDCS v1, v1, #1:SHL:(31-12)
STMCSDB v8!, {v1, v2} STMCSDB v8!, {v1, v2}
ADDCS v2, v2, #4096 ADDCS v2, v2, #4096
SUBCS v1, v1, #1:SHL:31 SUBCS v1, v1, #1:SHL:(31-12)
ADD a1, ip, #DRAMPhysAddrA ADD a1, ip, #DRAMPhysAddrA
LDMIA a1!, {a2, a3} LDMIA a1!, {a2, a3}
TEQ v1, a2 TEQ v1, a2
BEQ %BT33 ; don't duplicate the initial block BEQ %BT33 ; don't duplicate the initial block
; Perform insertion sort ; Perform insertion sort
; a1-a3, v3-v6, ip, lr free ; a1-a3, v3-v6, ip, lr free
AND v3, v2, #&F*OSAddRAM_Speed+OSAddRAM_NoDMA AND v3, v2, #&F*OSAddRAM_Speed
ASSERT OSAddRAM_Speed = 1:SHL:8 CMP v1, #1:SHL:20
ASSERT OSAddRAM_NoDMA < OSAddRAM_Speed ORRLO v3, v3, #1:SHL:31 ; Low RAM takes priority
MOV v3, v3, ROR #8 ; Give NoDMA flag priority over speed when sorting TST v2, #OSAddRAM_NoDMA
ORRNE v3, v3, #1:SHL:30 ; Followed by non-DMA
34 34
AND v4, a3, #&F*OSAddRAM_Speed+OSAddRAM_NoDMA AND v4, a3, #&F*OSAddRAM_Speed
CMP v3, v4, ROR #8 CMP a2, #1:SHL:20
ORRLO v4, v4, #1:SHL:31 ; Low RAM takes priority
TST a3, #OSAddRAM_NoDMA
ORRNE v4, v4, #1:SHL:30 ; Followed by non-DMA
CMP v3, v4 ; Compare priority value
BHI %FT35 BHI %FT35
TEQ a1, v7 TEQ a1, v7
LDMNEIA a1!, {a2, a3} LDMNEIA a1!, {a2, a3}
...@@ -554,7 +565,6 @@ RISCOS_Start ...@@ -554,7 +565,6 @@ RISCOS_Start
ADD a2, a2, v2, LSR #12 ; add on size ADD a2, a2, v2, LSR #12 ; add on size
TEQ v6, v7 TEQ v6, v7
BNE %BT40 BNE %BT40
MOV a2, a2, LSL #12
; Work out how much DMAable RAM the HAL/kernel needs ; Work out how much DMAable RAM the HAL/kernel needs
LDR a1, [sp, #8] LDR a1, [sp, #8]
...@@ -576,7 +586,8 @@ RISCOS_Start ...@@ -576,7 +586,8 @@ RISCOS_Start
; Claim it as normal, but set InitDMAEnd to v1+DRAMOffset_LastFixed so ; Claim it as normal, but set InitDMAEnd to v1+DRAMOffset_LastFixed so
; that the already used bit won't get used for DMA ; that the already used bit won't get used for DMA
; We also need to be careful later on when picking the initial v2 value ; We also need to be careful later on when picking the initial v2 value
ADD lr, v1, #DRAMOffset_LastFixed MOV lr, v1, LSL #12
ADD lr, lr, #DRAMOffset_LastFixed
STR lr, [ip, #InitDMAEnd] STR lr, [ip, #InitDMAEnd]
B %FT43 B %FT43
41 41
...@@ -588,8 +599,11 @@ RISCOS_Start ...@@ -588,8 +599,11 @@ RISCOS_Start
BNE %BT42 BNE %BT42
CMP v2, a1 CMP v2, a1
BLO %BT42 BLO %BT42
CMP v1, #1:SHL:20 ; <4GB only for now
BHS %BT42
; Make a note of this block ; Make a note of this block
STR v1, [ip, #InitDMAEnd] MOV lr, v1, LSL #12
STR lr, [ip, #InitDMAEnd]
43 43
STR v1, [ip, #InitDMABlock] STR v1, [ip, #InitDMABlock]
STR v2, [ip, #InitDMABlock+4] STR v2, [ip, #InitDMABlock+4]
...@@ -597,7 +611,7 @@ RISCOS_Start ...@@ -597,7 +611,7 @@ RISCOS_Start
STR lr, [ip, #InitDMAOffset] STR lr, [ip, #InitDMAOffset]
; Now shrink/remove this memory from PhysRamTable ; Now shrink/remove this memory from PhysRamTable
SUB v2, v2, a1 SUB v2, v2, a1
ADD v1, v1, a1 ADD v1, v1, a1, LSR #12
CMP v2, #4096 ; Block all gone? CMP v2, #4096 ; Block all gone?
STMHSDB a4, {v1, v2} ; no, just shrink it STMHSDB a4, {v1, v2} ; no, just shrink it
BHS %FT55 BHS %FT55
...@@ -609,7 +623,7 @@ RISCOS_Start ...@@ -609,7 +623,7 @@ RISCOS_Start
BNE %BT45 BNE %BT45
SUB v7, v7, #8 SUB v7, v7, #8
; a2 = Total memory size (bytes) ; a2 = Total memory size (pages)
; a3 = PhysRamTable ; a3 = PhysRamTable
; v7 = After last used entry in PhysRamTable ; v7 = After last used entry in PhysRamTable
; ip -> ZeroPage ; ip -> ZeroPage
...@@ -672,29 +686,29 @@ RISCOS_Start ...@@ -672,29 +686,29 @@ RISCOS_Start
ADD v1, a3, #DRAMOffset_PageZero - DRAMOffset_PageTables ADD v1, a3, #DRAMOffset_PageZero - DRAMOffset_PageTables
ADD v2, a3, #DRAMOffset_LastFixed - DRAMOffset_PageTables ADD v2, a3, #DRAMOffset_LastFixed - DRAMOffset_PageTables
STR a2, [v1, #RAMLIMIT] ; remember the RAM size STR a2, [v1, #RAMLIMIT] ; remember the RAM size
MOV lr, a2, LSR #12 SUB lr, a2, #1
SUB lr, lr, #1
STR lr, [v1, #MaxCamEntry] STR lr, [v1, #MaxCamEntry]
MOV lr, a2, LSR #12-CAM_EntrySizeLog2+12 MOV lr, a2, LSR #12-CAM_EntrySizeLog2 ; no. of pages needed for CAM
CMP a2, lr, LSL #12-CAM_EntrySizeLog2+12 CMP a2, lr, LSL #12-CAM_EntrySizeLog2
ADDNE lr, lr, #1 ADDNE lr, lr, #1 ; round up
MOV lr, lr, LSL #12 MOV lr, lr, LSL #12
STR lr, [v1, #SoftCamMapSize] STR lr, [v1, #SoftCamMapSize]
STR a3, [v1, #InitUsedStart] ; store start of L1PT STR a3, [v1, #InitUsedStart] ; store start of L1PT
ADD v1, v1, #DRAMPhysAddrA ADD v1, v1, #DRAMPhysAddrA
MOV v2, v2, LSR #12
MOV v3, a3 MOV v3, a3
; Detect if the DMA claiming adjusted the first block ; Detect if the DMA claiming adjusted the first block
; If so, we'll need to reset v2 to the start of the block at v1 ; If so, we'll need to reset v2 to the start of the block at v1
LDR a1, [v1] LDR a1, [v1]
ADD lr, a1, #DRAMOffset_LastFixed ADD lr, a1, #DRAMOffset_LastFixed:SHR:12
TEQ lr, v2 TEQ lr, v2
MOVNE v2, a1 MOVNE v2, a1
; For the next batch of allocation routines, v1-v3 are treated as globals. ; For the next batch of allocation routines, v1-v3 are treated as globals.
; v1 -> current entry in PhysRamTable ; v1 -> current entry in PhysRamTable
; v2 -> next address to allocate in v1 (may point at end of v1) ; v2 -> next address to allocate in v1 (may point at end of v1), in units of pages
; v3 -> L1PT (or 0 if MMU on - not yet) ; v3 -> L1PT (or 0 if MMU on - not yet)
; Set up some temporary PCBTrans and PPLTrans pointers, and the initial page flags used by the page tables ; Set up some temporary PCBTrans and PPLTrans pointers, and the initial page flags used by the page tables
...@@ -1527,8 +1541,8 @@ ROMDecompAlign * 20 ...@@ -1527,8 +1541,8 @@ ROMDecompAlign * 20
ADD v3, v3, v8 ADD v3, v3, v8
; Work out whether the block was removed or merely shrunk ; Work out whether the block was removed or merely shrunk
LDMDB v3, {v4-v5} LDMDB v3, {v4-v5}
ADD v6, v1, v2 ADD v6, v1, v2, LSR #12
ADD v7, v4, v5 ADD v7, v4, v5, LSR #12
STMDB v3, {v1-v2} STMDB v3, {v1-v2}
TEQ v6, v7 TEQ v6, v7
BEQ %FT40 ; End addresses match, it was shrunk BEQ %FT40 ; End addresses match, it was shrunk
...@@ -1672,19 +1686,19 @@ CountPageTablePages ROUT ...@@ -1672,19 +1686,19 @@ CountPageTablePages ROUT
; Returns -1 if address is not in RAM. ; Returns -1 if address is not in RAM.
PhysAddrToPageNo PhysAddrToPageNo
TEQ a2, #0 ; Convert address to 4K addressing
BNE %FT90 ; only handle addresses under 4GB for now MOV a1, a1, LSR #12
ORR a1, a1, a2, LSL #20
MOV a4, #0 MOV a4, #0
LDR ip, =ZeroPage + PhysRamTable LDR ip, =ZeroPage + PhysRamTable
10 LDMIA ip!, {a2, a3} ; get phys addr, size 10 LDMIA ip!, {a2, a3} ; get phys addr, size
MOVS a3, a3, LSR #12 ; end of list? (size=0) MOVS a3, a3, LSR #12 ; end of list? (size=0)
BEQ %FT90 ; then it ain't RAM BEQ %FT90 ; then it ain't RAM
SUB a2, a1, a2 ; a2 = amount into this bank SUB a2, a1, a2 ; a2 = amount into this bank
CMP a2, a3, LSL #12 ; if more than size CMP a2, a3 ; if more than size
ADDHS a4, a4, a3, LSL #12 ; increase counter by size of bank ADDHS a4, a4, a3 ; increase counter by size of bank
BHS %BT10 ; and move to next BHS %BT10 ; and move to next
ADD a4, a4, a2 ; add offset to counter ADD a1, a4, a2 ; add offset to counter
MOV a1, a4, LSR #12 ; convert counter to a page number
MOV pc, lr MOV pc, lr
90 MOV a1, #-1 90 MOV a1, #-1
...@@ -1754,9 +1768,9 @@ ConstructCAMfromPageTables ...@@ -1754,9 +1768,9 @@ ConstructCAMfromPageTables
; ;
; On entry: ; On entry:
; v1 -> current entry in PhysRamTable ; v1 -> current entry in PhysRamTable
; v2 -> end of last used physical page ; v2 -> end of last used physical page (page units)
; On exit: ; On exit:
; a1 -> next free page ; a1 -> next free page (assumed 32bit address)
; v1, v2 updated ; v1, v2 updated
; ;
; No out of memory check... ; No out of memory check...
...@@ -1764,11 +1778,11 @@ ConstructCAMfromPageTables ...@@ -1764,11 +1778,11 @@ ConstructCAMfromPageTables
Init_ClaimPhysicalPage Init_ClaimPhysicalPage
MOV a1, v2 MOV a1, v2
LDMIA v1, {a2, a3} LDMIA v1, {a2, a3}
MOV a3, a3, LSR #12 ADD a2, a2, a3, LSR #12 ; a2 = end of this bank
ADD a2, a2, a3, LSL #12 ; ip = end of this bank
CMP v2, a2 ; advance v2 to next bank if CMP v2, a2 ; advance v2 to next bank if
LDRHS a1, [v1, #8]! ; this bank is fully used LDRHS a1, [v1, #8]! ; this bank is fully used
ADD v2, a1, #4096 ADD v2, a1, #1
MOV a1, a1, LSL #12 ; Convert to byte address
MOV pc, lr MOV pc, lr
; Allocate and map in some RAM. ; Allocate and map in some RAM.
...@@ -1778,7 +1792,7 @@ Init_ClaimPhysicalPage ...@@ -1778,7 +1792,7 @@ Init_ClaimPhysicalPage
; a2 = access permissions (see Init_MapIn) ; a2 = access permissions (see Init_MapIn)
; a3 = length (4K multiple) ; a3 = length (4K multiple)
; v1 -> current entry in PhysRamTable ; v1 -> current entry in PhysRamTable
; v2 = next physical address ; v2 = next physical address (page units)
; v3 -> L1PT ; v3 -> L1PT
; ;
; On exit: ; On exit:
...@@ -1794,23 +1808,23 @@ Init_MapInRAM ROUT ...@@ -1794,23 +1808,23 @@ Init_MapInRAM ROUT
10 LDMIA v1, {v4, ip} ; v4 = addr of bank, ip = len+flags 10 LDMIA v1, {v4, ip} ; v4 = addr of bank, ip = len+flags
MOV ip, ip, LSR #12 MOV ip, ip, LSR #12
SUB v4, v2, v4 ; v4 = amount of bank used SUB v4, v2, v4 ; v4 = amount of bank used
RSBS v4, v4, ip, LSL #12 ; v4 = amount of bank left RSBS v4, v4, ip ; v4 = amount of bank left (pages)
LDREQ v2, [v1, #8]! ; move to next bank if 0 left LDREQ v2, [v1, #8]! ; move to next bank if 0 left
BEQ %BT10 BEQ %BT10
CMP v8, #-1 ; is this the first bank? CMP v8, #-1 ; is this the first bank?
MOVEQ v8, v2 ; remember it MOVEQ v8, v2 ; remember it
CMP v4, v5 ; sufficient in this bank? CMP v4, v5, LSR #12 ; sufficient in this bank?
MOVHS a4, v5 MOVHS a4, v5
MOVLO a4, v4 ; a4 = amount to take MOVLO a4, v4, LSL #12 ; a4 = amount to take
MOV a1, v2 ; set up parameters for MapIn call MOV a1, v2, LSL #12 ; set up parameters for MapIn call
MOV a2, v6 ; then move globals (in case MapIn MOV a2, v6 ; then move globals (in case MapIn
MOV a3, v7 ; needs to allocate for L2PT) MOV a3, v7 ; needs to allocate for L2PT)
ADD v2, v2, a4 ; advance physaddr ADD v2, v2, a4, LSR #12 ; advance physaddr
SUB v5, v5, a4 ; decrease wanted SUB v5, v5, a4 ; decrease wanted
ADD v6, v6, a4 ; advance address pointer ADD v6, v6, a4 ; advance log address pointer
BL Init_MapIn ; map in the RAM BL Init_MapIn ; map in the RAM
TEQ v5, #0 ; more memory still required? TEQ v5, #0 ; more memory still required?
BNE %BT10 BNE %BT10
...@@ -1835,7 +1849,7 @@ Init_MapInRAM_Clear ROUT ; same as Init_MapInRAM but also ...@@ -1835,7 +1849,7 @@ Init_MapInRAM_Clear ROUT ; same as Init_MapInRAM but also
; a2 = access permissions (see Init_MapIn) ; a2 = access permissions (see Init_MapIn)
; a3 = length (4K multiple) ; a3 = length (4K multiple)
; v1 -> current entry in PhysRamTable ; v1 -> current entry in PhysRamTable
; v2 = next physical address ; v2 = next physical address (page units)
; v3 -> L1PT ; v3 -> L1PT
; ;
; On exit: ; On exit:
...@@ -1872,12 +1886,12 @@ Init_MapInRAM_DMA ROUT ...@@ -1872,12 +1886,12 @@ Init_MapInRAM_DMA ROUT
; Map a range of physical addresses to a range of logical addresses. ; Map a range of physical addresses to a range of logical addresses.
; ;
; On entry: ; On entry:
; a1 = physical address ; a1 = physical address (32bit)
; a2 = logical address ; a2 = logical address
; a3 = DA flags ; a3 = DA flags
; a4 = area size (4K multiple) ; a4 = area size (4K multiple)
; v1 -> current entry in PhysRamTable ; v1 -> current entry in PhysRamTable
; v2 = last used physical address ; v2 = last used physical address (page units)
; v3 -> L1PT (or 0 if MMU on) ; v3 -> L1PT (or 0 if MMU on)
Init_MapIn ROUT Init_MapIn ROUT
...@@ -1955,7 +1969,7 @@ Init_MapIn ROUT ...@@ -1955,7 +1969,7 @@ Init_MapIn ROUT
; Map a logical page to a physical page, allocating L2PT as necessary. ; Map a logical page to a physical page, allocating L2PT as necessary.
; ;
; On entry: ; On entry: