Commit fb127e47 authored by Jeffrey Lee's avatar Jeffrey Lee Committed by ROOL

Fix OS_Memory 7 for discontiguous RAM

The current OS_Memory 7 implementation uses an address range structure
returned by HAL_PhysInfo to decide which part of the physical address
arrangement table to overwrite with RAM information. I suspect the
original intention was for OS_Memory to use this address range to avoid
marking the VRAM as DRAM (HAL_PhysInfo is expected to fill in the VRAM
itself). But by overwriting everything between the start and the end
address, OS_Memory will also overwrite any non-RAM areas which are
sandwiched between RAM banks, e.g. the VideoCore-owned RAM on Pi models
with >1GB RAM. There's also the problem that the address range returned
by the HAL is using 32bit addresses, so it won't work as-is for RAM
located above the 4GB barrier.

Fix these issues by reworking the routine so that it ignores the address
range returned by the HAL and instead detects VRAM by checking the
IsVRAM flag in the PhysRamTable entry. And for detecting if the ROM is
running from RAM, instead of using the address range we can rely on the
flag available via OS_ReadSysInfo 8 (i.e. HAL_PlatformInfo), like
OS_Memory 8 does.

Also add a simple BASIC program (Dev.PhysInfo) to allow easy checking of
HAL & OS physical address arrangement tables.

Version 6.41. Tagged as 'Kernel-6_41'
parent 0634b535
......@@ -9,12 +9,12 @@
GBLS Module_ApplicationDate
GBLS Module_HelpVersion
GBLS Module_ComponentName
Module_MajorVersion SETS "6.40"
Module_Version SETA 640
Module_MajorVersion SETS "6.41"
Module_Version SETA 641
Module_MinorVersion SETS ""
Module_Date SETS "01 Jul 2020"
Module_ApplicationDate SETS "01-Jul-20"
Module_Date SETS "11 Jul 2020"
Module_ApplicationDate SETS "11-Jul-20"
Module_ComponentName SETS "Kernel"
Module_FullVersion SETS "6.40"
Module_HelpVersion SETS "6.40 (01 Jul 2020)"
Module_FullVersion SETS "6.41"
Module_HelpVersion SETS "6.41 (11 Jul 2020)"
END
/* (6.40)
/* (6.41)
*
* This file is automatically maintained by srccommit, do not edit manually.
*
*/
#define Module_MajorVersion_CMHG 6.40
#define Module_MajorVersion_CMHG 6.41
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 01 Jul 2020
#define Module_Date_CMHG 11 Jul 2020
#define Module_MajorVersion "6.40"
#define Module_Version 640
#define Module_MajorVersion "6.41"
#define Module_Version 641
#define Module_MinorVersion ""
#define Module_Date "01 Jul 2020"
#define Module_Date "11 Jul 2020"
#define Module_ApplicationDate "01-Jul-20"
#define Module_ApplicationDate "11-Jul-20"
#define Module_ComponentName "Kernel"
#define Module_FullVersion "6.40"
#define Module_HelpVersion "6.40 (01 Jul 2020)"
#define Module_LibraryVersionInfo "6:40"
#define Module_FullVersion "6.41"
#define Module_HelpVersion "6.41 (11 Jul 2020)"
#define Module_LibraryVersionInfo "6:41"
......@@ -557,59 +557,32 @@ MemoryReadPhys ROUT
SUB sp, sp, #8
MOV r2, sp
CallHAL HAL_PhysInfo ; fills in everything except DRAM
LDR r0, [sp], #4
LDR r11, [sp], #4
ADD sp, sp, #8 ; We don't use this address range any more
; r0 to r11 is DRAM or not present.
LDR r1, [sp, #4] ; Get table address back
ADD r1, r1, r0, LSR #ByteShift
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.
LDR r6, =ZeroPage+CamEntriesPointer
LDR r7, [r6]
ADD r7, r7, #CAM_PageFlags ; Point to PPL entries.
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
LDR r7, [r6, #CamEntriesPointer-PhysRamTable]
ADD r7, r7, #CAM_PageFlags ; Point to PPL entries.
LDR r8, [r6, #MaxCamEntry-PhysRamTable]
10
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
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
TST r10, #OSAddRAM_IsVRAM ; If not DRAM then
ADDNE r5, r5, r10, LSR #12 ; adjust current page number
BNE %BT10 ; and try next block.
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)
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
20
SUBS r4, r4, #4 ; Reduce shift.
MOVCS r3, r3, LSR #4 ; If more space in current word then shift it.
......@@ -617,9 +590,6 @@ MemoryReadPhys ROUT
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 #CAM_EntrySizeLog2] ; Page is there so get PPL and determine if it's available or not.
TST lr, #PageFlags_Unavailable
TSTEQ lr, #PageFlags_Reserved
......@@ -627,55 +597,39 @@ MemoryReadPhys ROUT
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.
B %BT10
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
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
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 r11 is not present.
MOV r6, r0
ADD lr, r11, #1
RSBS r2, r2, lr
MOVNE r0, r1
LDRNE r1, =NotPresent :OR: NotAvailable
MOVNE r2, r2, LSR #ByteShift
BLNE memset
; If softloaded (ie ROM image is wholely within DRAM area returned
; by HAL_PhysInfo), mark that as unavailable DRAM.
; 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
LDR r0, =ZeroPage
LDR r0, [r0, #ROMPhysAddr]
LDR r1, [sp, #4]
CMP r0, r6
ADDHS lr, r0, #OSROM_ImageSize*1024
SUBHS lr, lr, #1
CMPHS r11, lr
ADDHS r0, r1, r0, LSR #ByteShift
LDRHS r1, =DRAM_Pattern :OR: NotAvailable
MOVHS r2, #(OSROM_ImageSize*1024) :SHR: ByteShift
BLHS memset
ADD r0, r1, r0, LSR #ByteShift
LDR r1, =DRAM_Pattern :OR: NotAvailable
MOV r2, #(OSROM_ImageSize*1024) :SHR: ByteShift
BL memset
40
CLRV
EXIT
fill_words
STR r3, [r1], #4
SUBS r2, r2, #1
BNE fill_words
MOV pc, lr
;----------------------------------------------------------------------------------------
; MemoryAmounts
;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment