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/boot.h | 1 + openbios-devel/arch/sparc32/lib.c | 11 +++++++++++ openbios-devel/arch/sparc32/openbios.c | 12 +++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/openbios-devel/arch/sparc32/boot.h b/openbios-devel/arch/sparc32/boot.h index 55e391a..d099241 100644 --- a/openbios-devel/arch/sparc32/boot.h +++ b/openbios-devel/arch/sparc32/boot.h @@ -39,3 +39,4 @@ extern struct linux_mlist_v0 *ptavail;
void ob_init_mmu(void); void init_mmu_swift(void); +void clear_memory(unsigned long start, unsigned long end); diff --git a/openbios-devel/arch/sparc32/lib.c b/openbios-devel/arch/sparc32/lib.c index d27b604..08b8133 100644 --- a/openbios-devel/arch/sparc32/lib.c +++ b/openbios-devel/arch/sparc32/lib.c @@ -283,6 +283,17 @@ static void ignore_dfault_addr(void) PUSH(pointer2cell(&ignore_dfault)); }
+/* Clear all physical memory between start and end */ +void clear_memory(unsigned long start, unsigned long end) +{ + unsigned long addr; + + for (addr = start; addr < end; addr+=4) { + __asm__ __volatile__ ("sta %%g0, [%0] %1\n\t" : : + "r" (addr), "i" (ASI_M_BYPASS)); + } +} + void ob_init_mmu(void) { diff --git a/openbios-devel/arch/sparc32/openbios.c b/openbios-devel/arch/sparc32/openbios.c index 6f4ee45..7273b6a 100644 --- a/openbios-devel/arch/sparc32/openbios.c +++ b/openbios-devel/arch/sparc32/openbios.c @@ -814,7 +814,9 @@ arch_init( void ) uint32_t temp; uint16_t machine_id; char buf[256]; - unsigned long mem_size; + unsigned long mem_size, start; + ofmem_t *ofmem = ofmem_arch_get_private(); + range_t *r;
fw_cfg_init();
@@ -882,6 +884,14 @@ arch_init( void ) } qemu_cmdline = (uint32_t)cmdline;
+ printk("Initialising memory..."); + start = 0; + for (r = ofmem->phys_range; r->next; r = r->next) { + clear_memory(start, r->start - start); + start = r->start + r->size; + } + printk(" done\n"); + /* Setup nvram variables */ push_str("/options"); fword("find-device");