Author: mcayland
Date: Wed Mar 11 23:58:20 2015
New Revision: 1334
URL: http://tracker.coreboot.org/trac/openbios/changeset/1334
Log:
SPARC32: clear physical memory upon startup
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(a)ilande.co.uk>
Modified:
trunk/openbios-devel/arch/sparc32/entry.S
Modified: trunk/openbios-devel/arch/sparc32/entry.S
==============================================================================
--- trunk/openbios-devel/arch/sparc32/entry.S Wed Mar 11 23:58:18 2015 (r1333)
+++ trunk/openbios-devel/arch/sparc32/entry.S Wed Mar 11 23:58:20 2015 (r1334)
@@ -122,7 +122,44 @@
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
Author: mcayland
Date: Wed Mar 11 23:58:18 2015
New Revision: 1333
URL: http://tracker.coreboot.org/trac/openbios/changeset/1333
Log:
SPARC32: mark pre-loaded kernel image memory as being in use
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(a)ilande.co.uk>
Modified:
trunk/openbios-devel/arch/sparc32/openbios.c
Modified: trunk/openbios-devel/arch/sparc32/openbios.c
==============================================================================
--- trunk/openbios-devel/arch/sparc32/openbios.c Wed Mar 11 23:58:15 2015 (r1332)
+++ trunk/openbios-devel/arch/sparc32/openbios.c Wed Mar 11 23:58:18 2015 (r1333)
@@ -865,9 +865,14 @@
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);
Author: mcayland
Date: Wed Mar 11 23:58:15 2015
New Revision: 1332
URL: http://tracker.coreboot.org/trac/openbios/changeset/1332
Log:
SPARC32: fix initialisation of L1 page table
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(a)ilande.co.uk>
Modified:
trunk/openbios-devel/arch/sparc32/lib.c
Modified: trunk/openbios-devel/arch/sparc32/lib.c
==============================================================================
--- trunk/openbios-devel/arch/sparc32/lib.c Wed Mar 11 23:58:13 2015 (r1331)
+++ trunk/openbios-devel/arch/sparc32/lib.c Wed Mar 11 23:58:15 2015 (r1332)
@@ -367,7 +367,7 @@
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;
}