Commit c40b2dba authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Teach the kernel about different memory attributes

Detail:
  Briefly, this set of changes:
  * Adjusts PhysRamTable so that it retains the flags passed in by the HAL from OS_AddRAM (by storing them in the lower 12 bits of the size field)
  * Sorts the non-VRAM entries of PhysRamTable by speed and DMA capability, to ensure optimal memory allocation during OS startup.
  * Adjust the initial memory allocation logic to allow the cursor/sound chunk and HAL noncacheable workspace to come from DMA capable memory
  * Extends OS_Memory 12 to accept a 'must be DMA capable' flag in bit 8 of R0. This is the same as available in ROL's OS.
  * Extends OS_DynamicArea 0 to allow the creation of dynamic areas that automatically allocate from DMA capable memory. In ROL's OS this was done by setting bit 12 of R4, but we're using bits 12-14 for specifying the cache policy, so instead bit 15 is used.
  * Fixes OS_ReadSysInfo 6 to return the correct DevicesEnd value now that the IRQ/device limit is computed at runtime
  File changes:
  * hdr/OSEntries - Add definitions of the various flags passed to OS_AddRAM by the HAL. Add a new flag, NoDMA, for memory which can't be used for DMA.
  * hdr/KernelWS - Tidy PhysRamTable definition a bit by removing all the DRAM bank definitions except the first - this makes it easier to search for code which is interacting with the table. Remove VRAMFlags, it's redundant now that the flags are kept in the table. Add DMA allocation info to InitWs.
  * s/AMBControl/memmap - Updated to mask out the flags from PhysRamTable when reading RAM block sizes.
  * s/ARM600 - Strip out a lot of IOMD specific pre-HAL code.
  * s/ChangeDyn - Updated to cope with the flags stored in PhysRamTable. Implement support for DMA-capable dynamic areas. Rewrite InitDynamicAreas to insert pages into the free pool in the right order so that the fastest memory will be taken from it first.
  * s/GetAll, s/Middle - Fix OS_ReadSysInfo 6 to return the correct HAL-specific DevicesEnd value
  * s/HAL - Significant rework of initial RAM allocation code to allow the kernel workspace to come from the fastest DMA incapable RAM, while also allowing allocation of DMA capable memory for HAL NCNB workspace & kernel cursor/sound chunks. ClearPhysRAM rewritten as part of this.
  * s/MemInfo - Updated to cope with the flags stored in PhysRamTable. Add support for the new OS_Memory 12 flag. Update OS_Memory 7 to not assume PhysRamTable entries are sorted in address order, and rip out the old pre-HAL IOMD implementation.
  * s/NewReset - Remove GetPagesFromFreePool option, assume TRUE (as this has been the case for the past 10+ years). Revise a few comments and strip dead code. Update to cope with PhysRamTable flags.
  * s/VMSAv6 - Remove a couple of unused definitions
  * s/vdu/vdudriver - Update to cope with PhysRamTable flags
Admin:
  Tested in Kinetic RiscPC ROM softload, Iyonix softload, & OMAP3


Version 5.35, 4.79.2.186. Tagged as 'Kernel-5_35-4_79_2_186'
parent 79a14eba
......@@ -13,11 +13,11 @@
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.185"
Module_Date SETS "24 Mar 2013"
Module_ApplicationDate SETS "24-Mar-13"
Module_MinorVersion SETS "4.79.2.186"
Module_Date SETS "28 Mar 2013"
Module_ApplicationDate SETS "28-Mar-13"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.35 (4.79.2.185)"
Module_HelpVersion SETS "5.35 (24 Mar 2013) 4.79.2.185"
Module_FullVersion SETS "5.35 (4.79.2.186)"
Module_HelpVersion SETS "5.35 (28 Mar 2013) 4.79.2.186"
END
......@@ -5,19 +5,19 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.185
#define Module_Date_CMHG 24 Mar 2013
#define Module_MinorVersion_CMHG 4.79.2.186
#define Module_Date_CMHG 28 Mar 2013
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.185"
#define Module_Date "24 Mar 2013"
#define Module_MinorVersion "4.79.2.186"
#define Module_Date "28 Mar 2013"
#define Module_ApplicationDate "24-Mar-13"
#define Module_ApplicationDate "28-Mar-13"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.35 (4.79.2.185)"
#define Module_HelpVersion "5.35 (24 Mar 2013) 4.79.2.185"
#define Module_FullVersion "5.35 (4.79.2.186)"
#define Module_HelpVersion "5.35 (28 Mar 2013) 4.79.2.186"
#define Module_LibraryVersionInfo "5:35"
......@@ -1004,8 +1004,11 @@ InitIRQHandler # 4 ; pointer to IRQ handler (LDR PC'ed from
InitIRQWs # 16 ; workspace for IRQ handler
InitUsedStart # 4 ; start of used pages (L2PT etc) not to be cleared
InitUsedEnd # 4 ; end of used pages
InitUsedBlock # 4 ; can't remember
InitUsedBlock # 4 ; current block in PhysRamTable
InitClearRamWs # 10*4
InitDMABlock # 8 ; block of DMAable memory extracted from PhysRamTable
InitDMAOffset # 4 ; offset+8 into PhysRamTable where memory was taken
InitDMAEnd # 4 ; current DMA alloc pos
AlignSpace 32 ; because we clear 32 at a time
InitWsEnd # 0
......@@ -1125,26 +1128,14 @@ Serv_AwkwardChain # 4 ;anchor for chain handling non-compliant mo
AlignSpace 32 ; skipped bit must start on 32-byte boundary (due to speedup)
SkippedTables # 0
PhysRamTable # 0 ; 6 pairs of words (physaddr, size) indicating
; RAM present in machine (NB normally you would need at most 5
; on IOMD machines, but the extra one is if a soft-loaded ROM image
; causes a bank to split
PhysRamTable # 0 ; Pairs of words (physaddr, size+flags)
; indicating RAM present in machine
; Unused entries have size of zero
VideoPhysAddr # 4 ; Address of video RAM (in the case of DRAM-only machines,
VideoSize # 4 ; this is actually a chunk out of DRAM)
DRAMPhysAddrA # 4 ; Next the DRAM - note that any banks with no memory
DRAMSizeA # 4 ; in them will be omitted from this table, so that
DRAMPhysAddrB # 4 ; eg DRAMPhysAddrA corresponds to the first bank with
DRAMSizeB # 4 ; DRAM in it, not necessarily bank 0
DRAMPhysAddrC # 4 ; If not all the slots are occupied, then
DRAMSizeC # 4 ; the remaining entries in this table have size fields
DRAMPhysAddrD # 4 ; of zero (and probably addresses of zero too)
DRAMSizeD # 4
DRAMPhysAddrE # 4
DRAMSizeE # 4
[ MorrisSupport
DRAMPhysAddrExtra # 8 * 12 ; The DRAM used with MORRIS can fragment into four
; blocks so allocate 3 extra word pairs per bank
]
VideoSizeFlags # 4 ; this is actually a chunk out of DRAM)
DRAMPhysAddrA # 4 ; Next the DRAM
DRAMSizeFlagsA # 4
# 8 * 16 ; Space for 17 DRAM banks + 1 VRAM bank total
PhysRamTableEnd # 0
DRAMPhysTableSize * (PhysRamTableEnd-DRAMPhysAddrA) / 8
......@@ -1153,7 +1144,6 @@ DRAMPhysTableSize * (PhysRamTableEnd-DRAMPhysAddrA) / 8
]
[ HAL
VRAMFlags # 4 ; Flags of VRAM block (from HAL's AddRAM call)
L2PTUsed # 4 ; Amount of memory used for L2PT
|
VRAMSize # 4 ; Amount of VRAM (in bytes) (may be more than 2M) (at &200 last time I checked)
......
......@@ -54,4 +54,11 @@ OSDecompHdr_WSSize # 4 ; Required workspace size (multiple of 4K)
OSDecompHdr_Code # 4 ; Offset from header start to decompression code
OSDecompHdr_size # 0
; OS_AddRAM flags
OSAddRAM_IsVRAM * 1:SHL:0
OSAddRAM_VRAMNotForGeneralUse * 1:SHL:1
OSAddRAM_NoDMA * 1:SHL:7 ; Don't allow any DMA here
OSAddRAM_Speed * 1:SHL:8 ; 4 bit value, higher = faster
END
......@@ -705,7 +705,8 @@ AMB_FindMemMapEntries ROUT
;initialise r0,r1,r2 as physical RAM chunk cache for AMB_r11topagenum routine
LDR r9,=ZeroPage+PhysRamTable
LDMIA r9,{r0,r1} ;r0,r1 := phys addr,size of chunk
ADD r1,r1,r0 ;r0,r1 := lowest addr,highest addr + 1 of chunk
MOV r1,r1,LSR #12
ADD r1,r0,r1,LSL #12 ;r0,r1 := lowest addr,highest addr + 1 of chunk
MOV r2,#0 ;r2 := first page number of chunk
LDR r10,=L2PT
......@@ -773,8 +774,9 @@ AMB_r11topagenum ROUT
ADDHS r11,r11,r0,LSR #Log2PageSize
ADDHS r2,r2,r1,LSR #Log2PageSize
BHS %BT20
ADD r1,r1,r0
MOV r1,r1,LSR #12
ADD r11,r11,r2
ADD r1,r0,r1,LSL #12
MOV pc,lr
LTORG
......
This diff is collapsed.
......@@ -112,17 +112,6 @@ FastCDA_Prof_ChangingEntry # 4
; R1 set to bytes moved.
;******************************************************************************
; The following flag controls the operation of ReadCMOSAndConfigure and FudgeConfigureRMA
;
; If false, then no memory is in the free pool to start off, and these routines just allocate pages
; starting at page R2, and update this on exit.
;
; If true, then routine InitDynamicAreas initially moves all non-static free memory into the free pool,
; and then the above routines just take pages off the end of that.
GBLL GetPagesFromFreePool ; whether ReadCMOSAndConfigure extract pages from the free pool
GetPagesFromFreePool SETL {TRUE}
AP_AppSpace * 0 ; user r/w, CB
AP_SysHeap * 0 ; user r/w, CB
AP_RMA * 0 ; user r/w, CB
......@@ -672,6 +661,7 @@ FindMemMapEntries_Code ROUT
LDMIA r5!, {r6,r7} ; load next address, size
SUB r6, r8, r6, LSR #12 ; number of pages into this bank
CMP r6, r7, LSR #12 ; if more than there are
BICCS r7, r7, #&F00
ADDCS r10, r10, r7, LSR #12-3 ; then advance CAM entry position
BCS %BT30 ; and loop to next bank
......@@ -813,15 +803,18 @@ CP_CB_WritebackReadAlloc * 2 ; Writeback cacheable, read allo
CP_CB_WritebackWriteAlloc * 3 ; Writeback cacheable, write allocate. If not available, WB/R.
CP_CB_AlternativeDCache * 4 ; Use XScale/SA11x0 mini-data cache. If not available, CB_Default.
DynAreaFlags_NeedsDMA * 1 :SHL: 15 ; only allocate from DMAable memory
;
; bits 15 nominally reserved for future DA flags expansion
; No more bits left for easy flag expansion. Will have to start claiming bits
; from 16 to 31, or shuffle some of the following flags further up
; (which should be safe in theory, as they all should be kernel private)
;
DynAreaFlags_AccessMask * DynAreaFlags_APBits :OR: DynAreaFlags_NotBufferable :OR: DynAreaFlags_NotCacheable :OR: DynAreaFlags_DoublyMapped :OR: DynAreaFlags_CPBits
;
; The following bits are only present in page flags
;
TempUncacheableShift * 16
PageFlags_TempUncacheableBits * 15 :SHL: TempUncacheableShift ; temporary count of uncacheability, used by DMA mgr
PageFlags_TempUncacheableBits * 15 :SHL: TempUncacheableShift ; temporary count of uncacheability, used by DMA mgr (via OS_Memory 0)
PageFlags_Unavailable * 1 :SHL: 20 ; physical page may not be requested by a PreShrink handler
;
; Temporary flags only used by kernel
......@@ -903,8 +896,9 @@ DynArea_ReturnError
; bit 10 = 1 => area may be sparsely mapped (only implemented if DA_Batman)
; bit 11 = 1 => area is bound to client application (allows areas to be overlayed in address space)
; not implemented yet, but declared in public API for Ursula
; bits 12..15 reserved for future DA flag expansion (should be 0)
; bits 16..31 reserved for internal page flags (should be 0)
; bits 12..14 => cache policy (if bits 4 or 5 set)
; bit 15 = 1 => area requires DMA capable pages (is bit 12 in ROL's OS!)
; bits 16..31 reserved for future expansion + internal page flags (should be 0)
;
; r5 = maximum size of area, or -1 for total RAM size
; r6 -> area handler routine
......@@ -2802,7 +2796,7 @@ ChocolateBlock_NOError
; out: -
;
InitDynamicAreas Entry "r0-r8,r11,r12"
InitDynamicAreas Entry "r0-r12"
LDR lr, =ZeroPage+AppSpaceDANode
ADR r0, InitAppSpaceTable
LDMIA r0, {r0-r8}
......@@ -2815,75 +2809,71 @@ InitDynamicAreas Entry "r0-r8,r11,r12"
STMIA lr, {r0-r8}
; We have to move all free pages (ie ones not occupied by the static pages) into the free pool
; The lowest numbered physical pages must be put in last, so that when ReadCMOSAndConfigure is
; called to put in the screen, it will get the pages starting at 0 (when the screen is created
; as a dynamic area, this limitation can be removed).
; We have to move all free pages (ie ones not occupied by the static pages)
; into the free pool.
; By default, pages will get taken from the end of the free pool when other
; dynamic areas are initialised or grown. So make sure that the slowest RAM
; is at the start of the free pool and the fastest is at the end; this is the
; reverse of the order in PhysRamTable.
; The free pages consist of two chunks of pages, each of which having consecutive physical page
; numbers. We start at MaxCamEntry and move back until we hit the end of the statics (which are
; at the start of the 1st non-video-RAM chunk). We then separately do the video RAM.
; The blocks of pages within the free pool are kept with consecutive physical
; page numbers; I'm not sure how important this is, but the old code did it.
; However instead of merely keeping the entire free pool in consecutive order,
; we need to process each PhysRamTable entry in turn, to allow us to place the
; fastest block at the end of the pool. Furthermore VRAM block is kept at the
; start of the pool - again to match old behaviour, although moving it elsewhere
; may not have any significant impact on the system
[ HAL
MOV r11, r3 ; r11 = PPL (inc CB) for free pool
MOV r6, r2 ; r6 = base address of free pool, ie where to put stuff
LDR r5, =ZeroPage ; r5 = amount of memory in free pool so far (and ptr to 0)
LDR r5, =ZeroPage
LDR r0, [r5, #InitUsedStart]
ADD r0, r0, #DRAMOffset_FirstFixed - DRAMOffset_L1PT
BL PhysAddrToPageNo
MOV r7, r0 ; r7 = page number of start of static chunk
LDR r0, [r5, #InitUsedEnd]
BL PhysAddrToPageNo
MOV r8, r0 ; r8 = page number of 1st page in 1st chunk not used for statics
LDR r2, [r5, #MaxCamEntry] ; r2 = 1st page to put in free pool
MOV r3, r6 ; r3 = base address of free pool, ie where to put stuff
SUB lr, r8, r7
SUB lr, r2, lr
ADD r3, r3, lr, LSL #12 ; r3 = end address of free pool
[ ZeroPage <> 0
MOV r5, #0
]
! 0, "Sort out static check in InitDynamicAreas"
10
CMP r2, r8 ; are we into statics already
SUBCC r2, r7, #1 ; if so, then move to last page of video RAM
MOVCC r8, #0 ; and move barrier so we never hit it again
BL BangCamUpdate
SUB r3, r3, #4096 ; advance logical address
ADD r5, r5, #4096
SUBS r2, r2, #1 ; decrement page number
BCS %BT10 ; if we haven't gone negative, then loop
|
MOV r11, r3 ; r11 = PPL (inc CB) for free pool
MOV r3, r2 ; r3 = base address of free pool, ie where to put stuff
LDR r5, =ZeroPage ; r5 = amount of memory in free pool so far (and ptr to 0)
LDR r2, [r5, #MaxCamEntry] ; r2 = 1st page to put in free pool
LDR r7, [r5, #VideoSize] ; r7 = size of video RAM
[ ZeroPage <> 0
MOV r5, #0
]
MOV r7, r7, LSR #12 ; r7 = page number of start of static chunk
ASSERT SoftCamMapSize = L2PTSize +4
LDR r0, =ZeroPage+L2PTSize
LDMIA r0, {r0, r8} ; r0 = L2PTSize, r8 = SoftCamMapSize
ADD r8, r8, r0 ; add sizes together
ADD r8, r8, #StaticPagesSize + UndStackSize ; + number of bytes used for other static bits
ADD r8, r7, r8, LSR #12 ; r8 = page number of 1st page in 1st chunk not used for statics
SUB r8, r0, #1 ; r8 = page number of last page in statics
ADD r9, r5, #PhysRamTable
LDMIA r9, {r0, r10} ; get VRAM info
ADD r9, r9, #PhysRamTableEnd-PhysRamTable ; skip to end
MOV r10, r10, LSR #12
LDR r5, [r5, #CamEntriesPointer]
ADD r5, r5, #4 ; r5 = base of PPLs
10
CMP r2, r8 ; are we into statics already
SUBCC r2, r7, #1 ; if so, then move to last page of video RAM
MOVCC r8, #0 ; and move barrier so we never hit it again
BL PhysAddrToPageNo
; Move r10 pages to r6 starting from r0
MOV r2, r0 ; get ready for BangCamUpdate
MOV r3, r6
15
CMP r2, r7
CMPHS r8, r2
BHS %FT20 ; page is in statics
; Check the CAM map to see if the page is already taken - this will detect the DMA regions, which aren't included in InitUsedStart/InitUsedEnd
LDR lr, [r5, r2, LSL #3]
TST lr, #PageFlags_Unavailable
BNE %FT20
BL BangCamUpdate
ADD r3, r3, #4096 ; advance logical address
ADD r5, r5, #4096
SUBS r2, r2, #1 ; decrement page number
BCS %BT10 ; if we haven't gone negative, then loop
]
LDR lr, =ZeroPage+FreePoolDANode ; may be used below to update DAList head ptr
STR r5, [lr, #DANode_Size] ; update size of free pool in node
ADD r3, r3, #4096
20
ADD r2, r2, #1
SUBS r10, r10, #1
BNE %BT15
; Advance to next PhysRamTable entry, working backwards
30
LDMDB r9!, {r0, r10}
MOVS r10, r10, LSR #12
BEQ %BT30
LDR lr, =ZeroPage+PhysRamTable
CMP lr, r9 ; stop once we hit first entry, it's already been processed
MOV r6, r3
BNE %BT10
; Left with r6 = end of free pool
LDR lr, =ZeroPage+FreePoolDANode
LDR r5, [lr, #DANode_Base]
SUB r5, r6, r5
STR r5, [lr, #DANode_Size]
; Now initialise the system heap by hand, so we can start creating dynamic areas
......@@ -3542,7 +3532,7 @@ AreaGrow ROUT
LDREQ r11, =ZeroPage+FreePoolDANode ; then start with free
LDR lr, [r12, #DANode_Flags] ; could this area require particular physical pages at all?
TST lr, #DynAreaFlags_NeedsSpecificPages
TST lr, #DynAreaFlags_NeedsSpecificPages+DynAreaFlags_NeedsDMA
BNE %FT70 ; [yes it could, so do it in lumps]
MOV r1, #0 ; no page block
......@@ -4696,7 +4686,12 @@ CallPostShrink Entry "r0,r3,r4, r12"
; endif
;
CallPreGrow Entry "r0,r4, r12"
CallPreGrow ROUT
Entry "r0,r4, r12"
LDR r0, [r12, #DANode_Flags]
TST r0, #DynAreaFlags_NeedsDMA ; if DMA needed
BNE %FT10 ; use special PreGrow
LDR r0, [r12, #DANode_Handler] ; check if no handler
CMP r0, #0 ; if none (V=0)
EXIT EQ ; then exit
......@@ -4711,6 +4706,7 @@ CallPreGrow Entry "r0,r4, r12"
FastCDA_ProfEnd CallPreGrow, r12, r4, lr
EXIT VC ; if no error then exit
05
TEQ r0, #0 ; if generic error returned (V still set)
ADREQL r0, ErrorBlock_ChDynamNotAllMoved ; then substitute real error message
[ International
......@@ -4719,6 +4715,51 @@ CallPreGrow Entry "r0,r4, r12"
STR r0, [sp]
EXIT
10
; Instead of calling the users PreGrow handler, walk PhysRamTable and
; the CAM map to look for some free DMAable pages
; Note that we don't guarantee physical contiguity - if you want that,
; just use OS_Memory 12 or PCI_RAMAlloc instead
Push "r1-r3"
LDR r0,=ZeroPage+PhysRamTable+4
MOV r2,#0 ; current page number
LDR r4,=ZeroPage+CamEntriesPointer
LDR r4,[r4]
ADD r4,r4,#4 ; -> base of PPLs
LDR r12,[r0],#8 ; get video chunk flags
20
ADD r2,r2,r12,LSR #12 ; advance page number
21
LDR r12,[r0],#8 ; get next chunk details
CMP r12,#0
BEQ %FT90
TST r12,#OSAddRAM_NoDMA
BNE %BT20
; Check the CAM map to see if any pages here are free
MOV r12,r12,LSR #12
30
LDR lr,[r4,r2,LSL #3]
TST lr,#PageFlags_Unavailable :OR: PageFlags_Required
STREQ r2,[r1],#12
SUBEQS r3,r3,#4096
BEQ %FT80
SUBS r12,r12,#1
ADD r2,r2,#1
BNE %BT30
B %BT21
80
; Success
CLRV
Pull "r1-r3"
EXIT
90
; Failure
SETV
Pull "r1-r3"
MOV r0,#0
B %BT05
; ***********************************************************************************
;
; CallPostGrow - Call post-grow routine
......@@ -5233,8 +5274,8 @@ PreShrink_Screen Entry "R0-R2,R4-R5"
[ HAL
LDR LR, =ZeroPage
LDR LR, [LR, #VRAMFlags] ;is VRAM suitable for general use?
TST LR, #2 ;if not - don't shrink screen memory
LDR LR, [LR, #VideoSizeFlags] ;is VRAM suitable for general use?
TST LR, #OSAddRAM_VRAMNotForGeneralUse ;if not - don't shrink screen memory
MOVNE R3, #0
]
SUB R2, R5, #1 ;make a page mask
......@@ -5279,5 +5320,6 @@ PostShrink_Screen Entry
; ************************************************************************
LTORG
END
......@@ -76,6 +76,7 @@
GET Hdr:PortMan
GET Hdr:SerialOp
GET Hdr:Keyboard
GET Hdr:OSRSI6
; now the main parts of the MOS
......
This diff is collapsed.
......@@ -394,6 +394,7 @@ meminfo_returncs
physical_to_ppn ROUT
LDR r9, =ZeroPage+PhysRamTable
MOV r3, #0 ; Start at page 0.
MOV r5, r5, LSR #12
10
CMP r7, r3 ; Stop if we run out of pages
[ No26bitCode
......@@ -403,12 +404,12 @@ physical_to_ppn ROUT
]
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
SUB r10, r5, r10, LSR #12 ; Determine if given address is in this block.
CMP r10, r11, LSR #12
ADDCS r3, r3, r11, LSR #12 ; Move on to next block.
BCS %BT10
ADD r3, r3, r10, LSR #12
ADD r3, r3, r10
[ No26bitCode
CLC
MOV pc, lr
......@@ -473,7 +474,6 @@ MemoryPhysSize
;
MemoryReadPhys ROUT
[ HAL
Entry "r0-r12"
AddressHAL
MOV r0, #PhysInfo_WriteTable
......@@ -489,20 +489,49 @@ MemoryReadPhys ROUT
MOV r2, r0 ; 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.
LDR r6, =ZeroPage+PhysRamTable
LDR r7, [r6, #CamEntriesPointer-PhysRamTable]
LDR r6, =ZeroPage+CamEntriesPointer
LDR r7, [r6]
ADD r7, r7, #4 ; Point to PPL entries.
LDR r8, [r6, #MaxCamEntry-PhysRamTable]
LDR r8, [r6, #MaxCamEntry-CamEntriesPointer]
MOV r5, #0 ; last block address processed + 1
Push "r5"
; Ugly logic to process PhysRamTable entries in address order instead of physical page order
10
Pull "r12"
MVN lr, #0
MOV r5, #0 ; Current page number.
Push "r5,lr"
LDR r6, =ZeroPage+PhysRamTable
MOV r10, #0
11
ADD r5, r5, r10, LSR #12
LDMIA r6!, {r9,r10} ; Get physical address and size of next block.
CMP r10, #0
BEQ %FT12
CMP r9, r0 ; If not DRAM then
CMPHS r11, r9
ADDLO r5, r5, r10, LSR #12 ; adjust current page number
BLO %BT10 ; and try next block.
ADD r10, r10, r9 ; Add amount of unused space between current and start of block.
BLO %BT11 ; try next block.
CMP r9, r12 ; have we processed this entry?
CMPHS lr, r9 ; is it the lowest one we've seen?
BLO %BT11 ; yes, try the next
; This is the best match so far
STMIA sp, {r5,r6} ; Remember page number & details ptr
MOV lr, r9 ; Remember base address
B %BT11
12
Pull "r5,r6"
CMP r6, #-1 ; did we find anything?
BEQ %FT40
LDMDB r6,{r9,r10}
ADD r12, r9, #1
Push "r12" ; Remember that we've processed up to here
; Now process this entry
MOV r10, r10, LSR #12
ADD r10, r9, r10, LSL #12 ; 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.
......@@ -524,9 +553,9 @@ MemoryReadPhys ROUT
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
B %BT10
40
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
......@@ -557,102 +586,6 @@ MemoryReadPhys ROUT
LDRHS r1, =DRAM_Pattern :OR: NotAvailable
MOVHS r2, #(OSROM_ImageSize*1024) :SHR: ByteShift
BLHS memset
|
Entry "r1-r10"
; &00000000 to OSROM_ImageSize*1024 is ROM.
MOV r2, #(OSROM_ImageSize*1024-&00000000) :SHR: WordShift
LDR r3, =ROM_Pattern :OR: NotAvailable
BL fill_words
; OSROM_ImageSize*1024 to &02000000 is allocated to ROM but is not present.
MOV r2, #(&02000000-OSROM_ImageSize*1024) :SHR: WordShift
LDR r3, =NotPresent :OR: NotAvailable
BL fill_words
; &02000000 to &02400000 is VRAM or not present.
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.