diff options
author | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-03-08 09:51:29 +0000 |
---|---|---|
committer | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-03-08 09:51:29 +0000 |
commit | 513f789f6b187faf1fd533dc6972bbfa021c4381 (patch) | |
tree | cf863f75e7513ed1a29d456a611c4bd2f6c9df8f /hw/ppc_newworld.c | |
parent | 7e12f65678b5d6af9ee0fc30322be3b289c87709 (diff) |
Use firmware configuration instead of NVRAM (initial patch by Aurelien Jarno)
Use firmware configuration device for boot device, kernel, initrd and
kernel command line parameters on PPC, Sparc32 and Sparc64.
Update OpenBIOS images to r479 which supports the change.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6777 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/ppc_newworld.c')
-rw-r--r-- | hw/ppc_newworld.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index b28586485b..4a33ebde09 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -78,6 +78,12 @@ static CPUReadMemoryFunc *unin_read[] = { &unin_readl, }; +static int fw_cfg_boot_set(void *opaque, const char *boot_device) +{ + fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); + return 0; +} + /* PowerPC Mac99 hardware initialisation */ static void ppc_core99_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, @@ -167,9 +173,24 @@ static void ppc_core99_init (ram_addr_t ram_size, int vga_ram_size, } if (linux_boot) { + uint64_t lowaddr = 0; kernel_base = KERNEL_LOAD_ADDR; - /* now we can load the kernel */ - kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base); + + /* Now we can load the kernel. The first step tries to load the kernel + supposing PhysAddr = 0x00000000. If that was wrong the kernel is + loaded again, the new PhysAddr being computed from lowaddr. */ + kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL); + if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) { + kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr, + NULL, 0, NULL); + } + if (kernel_size < 0) + kernel_size = load_aout(kernel_filename, kernel_base, + ram_size - kernel_base); + if (kernel_size < 0) + kernel_size = load_image_targphys(kernel_filename, + kernel_base, + ram_size - kernel_base); if (kernel_size < 0) { cpu_abort(env, "qemu: could not load kernel '%s'\n", kernel_filename); @@ -321,6 +342,18 @@ static void ppc_core99_init (ram_addr_t ram_size, int vga_ram_size, fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_MAC99); + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); + if (kernel_cmdline) { + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR); + pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline); + } else { + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); + } + fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base); + fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); + fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device); + qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); } QEMUMachine core99_machine = { |