This patchset contains some minor SPARC32 fixups, including clearing all physical RAM on startup. This fixes rebooting under Solaris which evidently doesn't clear memory for some key internal memory structures before attempting to use them at boot.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
v2: - Move physical memory initialisation to early startup
Mark Cave-Ayland (4): SPARC32: minor tidy-up for boot.c SPARC32: fix initialisation of L1 page table SPARC32: mark pre-loaded kernel image memory as being in use SPARC32: clear physical memory upon startup
openbios-devel/arch/sparc32/boot.c | 5 +---- openbios-devel/arch/sparc32/entry.S | 37 ++++++++++++++++++++++++++++++++ openbios-devel/arch/sparc32/lib.c | 2 +- openbios-devel/arch/sparc32/openbios.c | 7 +++++- 4 files changed, 45 insertions(+), 6 deletions(-)
This commit doesn't have any functional changes but removes some debugging printks accidentally included by a previous commit, plus adds a +1 offset back onto the size of tail prommap entry to ensure that it is correctly aligned.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/boot.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/openbios-devel/arch/sparc32/boot.c b/openbios-devel/arch/sparc32/boot.c index c309891..49ec4cf 100644 --- a/openbios-devel/arch/sparc32/boot.c +++ b/openbios-devel/arch/sparc32/boot.c @@ -147,9 +147,6 @@ static void setup_romvec(void) (**pp).start_adr = (char *)intprop_ptr[1]; (**pp).num_bytes = intprop_ptr[2];
- printk("start_adr: %x\n", (int)(**pp).start_adr); - printk("num_bytes: %x\n", (**pp).num_bytes); - intprop_ptr += 3; }
@@ -180,7 +177,7 @@ static void setup_romvec(void) (**pp).num_bytes = (intprop_ptr[4] + intprop_ptr[5]) - (intprop_ptr[1] + intprop_ptr[2]); } else { /* Tail (size from top of virtual memory) */ - (**pp).num_bytes = 0xffffffffUL - (intprop_ptr[1] + intprop_ptr[2]); + (**pp).num_bytes = 0xffffffffUL - (intprop_ptr[1] + intprop_ptr[2]) + 1; }
intprop_ptr += 3;
Since l1 is a pointer to an array of longs, the increment size should be 1 (element) and not 4 (bytes). While this shouldn't have an effect when booting an image from fresh, it meant that the L1 page table contained old entries after a reboot.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/openbios-devel/arch/sparc32/lib.c b/openbios-devel/arch/sparc32/lib.c index af1812d..d27b604 100644 --- a/openbios-devel/arch/sparc32/lib.c +++ b/openbios-devel/arch/sparc32/lib.c @@ -367,7 +367,7 @@ init_mmu_swift(void) for (i = 1; i < NCTX_SWIFT; i++) { context_table[i] = SRMMU_ET_INVALID; } - for (i = 0; i < 256; i += 4) { + for (i = 0; i < 256; i++) { l1[i] = SRMMU_ET_INVALID; }
This is to ensure that a client OS reading the memory lists from the PROM won't consider its own memory space available.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/openbios.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/openbios-devel/arch/sparc32/openbios.c b/openbios-devel/arch/sparc32/openbios.c index 32255b6..6f4ee45 100644 --- a/openbios-devel/arch/sparc32/openbios.c +++ b/openbios-devel/arch/sparc32/openbios.c @@ -865,9 +865,14 @@ arch_init( void ) romvec = init_openprom();
kernel_size = fw_cfg_read_i32(FW_CFG_KERNEL_SIZE); - if (kernel_size) + if (kernel_size) { kernel_image = fw_cfg_read_i32(FW_CFG_KERNEL_ADDR);
+ /* Mark the kernel memory as in use */ + ofmem_claim_phys(PAGE_ALIGN(kernel_image), PAGE_ALIGN(kernel_size), 0); + ofmem_claim_virt(PAGE_ALIGN(kernel_image), PAGE_ALIGN(kernel_size), 0); + } + kernel_cmdline = (const char *) fw_cfg_read_i32(FW_CFG_KERNEL_CMDLINE); if (kernel_cmdline) { cmdline = strdup(kernel_cmdline);
This is to work around a bug in Solaris which appears not to explicitly clear some of its internal kmem structures (particularly its pagelists) on boot. The result of this is that Solaris will initially boot fine, until a reboot/reset is initiated.
When this occurs, the kmem structures contain whatever junk was previously left in memory during initialisation causing a panic. The fix is to clear physical memory on startup (as OBP appears to do) so that the kmem intialisation code behaves correctly.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/entry.S | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/openbios-devel/arch/sparc32/entry.S b/openbios-devel/arch/sparc32/entry.S index d95a308..72cb338 100644 --- a/openbios-devel/arch/sparc32/entry.S +++ b/openbios-devel/arch/sparc32/entry.S @@ -122,7 +122,44 @@ entry: or %g3, %g4, %g1 ! %g1 contains end of memory
+ ! Get kernel address from configuration device + ! NB: little endian format + mov FW_CFG_KERNEL_ADDR, %g2 + sub %g5, 2, %g5 + stha %g2, [%g5] CFG_ASI + add %g5, 2, %g5 + lduba [%g5] CFG_ASI, %g4 + + lduba [%g5] CFG_ASI, %g3 + sll %g3, 8, %g3 + or %g3, %g4, %g4 + + lduba [%g5] CFG_ASI, %g3 + sll %g3, 16, %g3 + or %g3, %g4, %g4 + + lduba [%g5] CFG_ASI, %g3 + sll %g3, 24, %g3 + or %g3, %g4, %g4 + + ! If kernel address is set, don't clear from base of RAM in order to + ! leave the kernel image intact + mov 0, %g6 + cmp %g4, 0 + beq clear_mem + nop + + ! Start from 16M + set 0x1000000, %g6 + +clear_mem: + sta %g0, [%g6] ASI_M_BYPASS + add %g6, 0x4, %g6 + cmp %g6, %g1 + bl clear_mem + nop
+clear_done: ! Start of private memory in %g6 set 0x2000, %g3 sub %g1, %g3, %g6