diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/sun4u.c | 97 |
1 files changed, 55 insertions, 42 deletions
diff --git a/hw/sun4u.c b/hw/sun4u.c index 5e1da4c432..47ff3eb9c5 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -148,6 +148,56 @@ static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, return 0; } +static unsigned long sun4u_load_kernel(const char *kernel_filename, + const char *initrd_filename, + ram_addr_t RAM_size, long *initrd_size) +{ + int linux_boot; + unsigned int i; + long kernel_size; + + linux_boot = (kernel_filename != NULL); + + kernel_size = 0; + if (linux_boot) { + kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL); + if (kernel_size < 0) + kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR, + RAM_size - KERNEL_LOAD_ADDR); + if (kernel_size < 0) + kernel_size = load_image_targphys(kernel_filename, + KERNEL_LOAD_ADDR, + RAM_size - KERNEL_LOAD_ADDR); + if (kernel_size < 0) { + fprintf(stderr, "qemu: could not load kernel '%s'\n", + kernel_filename); + exit(1); + } + + /* load initrd */ + *initrd_size = 0; + if (initrd_filename) { + *initrd_size = load_image_targphys(initrd_filename, + INITRD_LOAD_ADDR, + RAM_size - INITRD_LOAD_ADDR); + if (*initrd_size < 0) { + fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", + initrd_filename); + exit(1); + } + } + if (*initrd_size > 0) { + for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) { + if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS + stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR); + stl_phys(KERNEL_LOAD_ADDR + i + 20, *initrd_size); + break; + } + } + } + } + return kernel_size; +} void pic_info(Monitor *mon) { @@ -503,7 +553,6 @@ static void sun4uv_init(ram_addr_t RAM_size, { CPUState *env; m48t59_t *nvram; - int linux_boot; unsigned int i; long initrd_size, kernel_size; PCIBus *pci_bus, *pci_bus2, *pci_bus3; @@ -513,8 +562,6 @@ static void sun4uv_init(ram_addr_t RAM_size, BlockDriverState *fd[MAX_FD]; void *fw_cfg; - linux_boot = (kernel_filename != NULL); - /* init CPUs */ env = cpu_devinit(cpu_model, hwdef); @@ -523,45 +570,6 @@ static void sun4uv_init(ram_addr_t RAM_size, prom_init(hwdef->prom_addr, bios_name); - kernel_size = 0; - initrd_size = 0; - if (linux_boot) { - /* XXX: put correct offset */ - kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL); - if (kernel_size < 0) - kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR, - ram_size - KERNEL_LOAD_ADDR); - if (kernel_size < 0) - kernel_size = load_image_targphys(kernel_filename, - KERNEL_LOAD_ADDR, - ram_size - KERNEL_LOAD_ADDR); - if (kernel_size < 0) { - fprintf(stderr, "qemu: could not load kernel '%s'\n", - kernel_filename); - exit(1); - } - - /* load initrd */ - if (initrd_filename) { - initrd_size = load_image_targphys(initrd_filename, - INITRD_LOAD_ADDR, - ram_size - INITRD_LOAD_ADDR); - if (initrd_size < 0) { - fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", - initrd_filename); - exit(1); - } - } - if (initrd_size > 0) { - for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) { - if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS - stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR); - stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size); - break; - } - } - } - } irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS); pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, @@ -621,6 +629,11 @@ static void sun4uv_init(ram_addr_t RAM_size, } floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd); nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59); + + initrd_size = 0; + kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename, + ram_size, &initrd_size); + sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices, KERNEL_LOAD_ADDR, kernel_size, kernel_cmdline, |