The previous attempt to fix this was wrong in that I misinterpreted what SILO was doing: whilst it detects a free region of memory for the kernel/initrd, it simply maps the areas at fixed addresses rather than allocating them.
Fixes: 3464681 "SPARC64: mark initrd memory as mapped and in use before booting kernel" Fixes: c21c366 "SPARC64: mark kernel memory as mapped and in use before booting kernel" Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc64/boot.c | 2 +- arch/sparc64/boot.h | 3 +++ arch/sparc64/openbios.c | 16 +++++++--------- 3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/arch/sparc64/boot.c b/arch/sparc64/boot.c index 43bd562..2534f13 100644 --- a/arch/sparc64/boot.c +++ b/arch/sparc64/boot.c @@ -37,7 +37,7 @@ void boot(void) unsigned long p4, unsigned long p5);
printk("[sparc64] Kernel already loaded\n"); - entry = (void *) (unsigned long)kernel_image; + entry = (void *) (unsigned long)(IMAGE_VIRT_ADDR + 0x4000); entry(0, 0, 0, 0, (unsigned long)&sparc64_of_client_interface); }
diff --git a/arch/sparc64/boot.h b/arch/sparc64/boot.h index a4f5c12..84a6db1 100644 --- a/arch/sparc64/boot.h +++ b/arch/sparc64/boot.h @@ -6,6 +6,9 @@ * the copyright and warranty status of this work. */
+#define INITRD_VIRT_ADDR 0x40c00000 +#define IMAGE_VIRT_ADDR 0x40000000 + // linux_load.c int linux_load(struct sys_info *info, const char *file, const char *cmdline);
diff --git a/arch/sparc64/openbios.c b/arch/sparc64/openbios.c index e9f4726..aa774c4 100644 --- a/arch/sparc64/openbios.c +++ b/arch/sparc64/openbios.c @@ -564,10 +564,8 @@ void arch_nvram_get(char *data) if (kernel_size) { kernel_image = fw_cfg_read_i64(FW_CFG_KERNEL_ADDR);
- /* Mark the kernel memory as mapped 1:1 and 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); - ofmem_map(PAGE_ALIGN(kernel_image), PAGE_ALIGN(kernel_image), PAGE_ALIGN(kernel_size), -1); + /* Map kernel memory the same as SILO */ + ofmem_map(PAGE_ALIGN(kernel_image) - 0x4000, IMAGE_VIRT_ADDR, PAGE_ALIGN(kernel_size), -1); }
size = fw_cfg_read_i32(FW_CFG_CMDLINE_SIZE); @@ -585,14 +583,14 @@ void arch_nvram_get(char *data) if (initrd_size) { initrd_image = fw_cfg_read_i32(FW_CFG_INITRD_ADDR);
- /* Mark initrd memory as mapped 1:1 and in use */ - ofmem_claim_phys(PAGE_ALIGN(initrd_image), PAGE_ALIGN(initrd_size), 0); - ofmem_claim_virt(PAGE_ALIGN(initrd_image), PAGE_ALIGN(initrd_size), 0); - ofmem_map(PAGE_ALIGN(initrd_image), PAGE_ALIGN(initrd_image), PAGE_ALIGN(initrd_size), -1); + /* Map initrd memory the same as SILO */ + ofmem_map(PAGE_ALIGN(initrd_image), INITRD_VIRT_ADDR, PAGE_ALIGN(initrd_size), -1); }
if (kernel_size) - printk("kernel addr %llx size %llx\n", kernel_image, kernel_size); + printk("kernel phys %llx virt %x size 0x%llx\n", kernel_image, IMAGE_VIRT_ADDR + 0x4000, kernel_size); + if (initrd_size) + printk("initrd phys %llx virt %x size 0x%llx\n", initrd_image, INITRD_VIRT_ADDR, initrd_size); if (size) printk("kernel cmdline %s\n", obio_cmdline);