From ec426ff808cd421036f81ab34c0d5884743982aa Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Sun, 5 May 2013 11:06:37 +0200 Subject: hw/microblaze: Add support for loading initrd images Signed-off-by: Edgar E. Iglesias --- hw/microblaze/boot.c | 39 +++++++++++++++++++++++++++++++- hw/microblaze/boot.h | 4 +++- hw/microblaze/petalogix_ml605_mmu.c | 1 + hw/microblaze/petalogix_s3adsp1800_mmu.c | 4 +++- 4 files changed, 45 insertions(+), 3 deletions(-) (limited to 'hw/microblaze') diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c index 59be5b9f6a..2a7ea5c0f9 100644 --- a/hw/microblaze/boot.c +++ b/hw/microblaze/boot.c @@ -26,6 +26,7 @@ #include "qemu/option.h" #include "qemu/config-file.h" +#include "qemu/error-report.h" #include "qemu-common.h" #include "sysemu/device_tree.h" #include "sysemu/sysemu.h" @@ -39,6 +40,8 @@ static struct void (*machine_cpu_reset)(MicroBlazeCPU *); uint32_t bootstrap_pc; uint32_t cmdline; + uint32_t initrd_start; + uint32_t initrd_end; uint32_t fdt; } boot_info; @@ -49,6 +52,7 @@ static void main_cpu_reset(void *opaque) cpu_reset(CPU(cpu)); env->regs[5] = boot_info.cmdline; + env->regs[6] = boot_info.initrd_start; env->regs[7] = boot_info.fdt; env->sregs[SR_PC] = boot_info.bootstrap_pc; if (boot_info.machine_cpu_reset) { @@ -58,6 +62,8 @@ static void main_cpu_reset(void *opaque) static int microblaze_load_dtb(hwaddr addr, uint32_t ramsize, + uint32_t initrd_start, + uint32_t initrd_end, const char *kernel_cmdline, const char *dtb_filename) { @@ -80,6 +86,14 @@ static int microblaze_load_dtb(hwaddr addr, } } + if (initrd_start) { + qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start", + initrd_start); + + qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end", + initrd_end); + } + cpu_physical_memory_write(addr, fdt, fdt_size); return fdt_size; } @@ -90,7 +104,9 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr) } void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, - uint32_t ramsize, const char *dtb_filename, + uint32_t ramsize, + const char *initrd_filename, + const char *dtb_filename, void (*machine_cpu_reset)(MicroBlazeCPU *)) { QemuOpts *machine_opts; @@ -151,6 +167,25 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, high = (ddr_base + kernel_size + 3) & ~3; } + if (initrd_filename) { + int initrd_size; + uint32_t initrd_offset; + + high = ROUND_UP(high + kernel_size, 4); + boot_info.initrd_start = high; + initrd_offset = boot_info.initrd_start - ddr_base; + initrd_size = load_image_targphys(initrd_filename, + boot_info.initrd_start, + ram_size - initrd_offset); + if (initrd_size < 0) { + error_report("qemu: could not load initrd '%s'\n", + initrd_filename); + exit(EXIT_FAILURE); + } + boot_info.initrd_end = boot_info.initrd_start + initrd_size; + high = ROUND_UP(high + initrd_size, 4); + } + boot_info.cmdline = high + 4096; if (kernel_cmdline && strlen(kernel_cmdline)) { pstrcpy_targphys("cmdline", boot_info.cmdline, 256, kernel_cmdline); @@ -158,6 +193,8 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, /* Provide a device-tree. */ boot_info.fdt = boot_info.cmdline + 4096; microblaze_load_dtb(boot_info.fdt, ram_size, + boot_info.initrd_start, + boot_info.initrd_end, kernel_cmdline, dtb_filename); } diff --git a/hw/microblaze/boot.h b/hw/microblaze/boot.h index b14ef2b992..0eb7f8e4f6 100644 --- a/hw/microblaze/boot.h +++ b/hw/microblaze/boot.h @@ -4,7 +4,9 @@ #include "hw/hw.h" void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, - uint32_t ramsize, const char *dtb_filename, + uint32_t ramsize, + const char *initrd_filename, + const char *dtb_filename, void (*machine_cpu_reset)(MicroBlazeCPU *)); #endif /* __MICROBLAZE_BOOT __ */ diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c index 1c44231da9..10970e0f3f 100644 --- a/hw/microblaze/petalogix_ml605_mmu.c +++ b/hw/microblaze/petalogix_ml605_mmu.c @@ -177,6 +177,7 @@ petalogix_ml605_init(QEMUMachineInitArgs *args) } microblaze_load_kernel(cpu, ddr_base, ram_size, + args->initrd_filename, BINARY_DEVICE_TREE_FILE, machine_cpu_reset); diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c index 39ce2c46c0..ec6489c2d3 100644 --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c @@ -108,7 +108,9 @@ petalogix_s3adsp1800_init(QEMUMachineInitArgs *args) xilinx_ethlite_create(&nd_table[0], ETHLITE_BASEADDR, irq[1], 0, 0); microblaze_load_kernel(cpu, ddr_base, ram_size, - BINARY_DEVICE_TREE_FILE, machine_cpu_reset); + args->initrd_filename, + BINARY_DEVICE_TREE_FILE, + machine_cpu_reset); } static QEMUMachine petalogix_s3adsp1800_machine = { -- cgit v1.2.1