diff options
author | Edgar E. Iglesias <edgar.iglesias@gmail.com> | 2013-05-05 11:06:37 +0200 |
---|---|---|
committer | Edgar E. Iglesias <edgar.iglesias@gmail.com> | 2013-10-24 22:56:48 +0200 |
commit | ec426ff808cd421036f81ab34c0d5884743982aa (patch) | |
tree | be3323c544d92684c74cf78f50b56ed754ffcfc7 /hw/microblaze | |
parent | d0b022a0e9dcf574d56243f6039d675ba80dba16 (diff) | |
download | qemu-ec426ff808cd421036f81ab34c0d5884743982aa.zip qemu-ec426ff808cd421036f81ab34c0d5884743982aa.tar.gz qemu-ec426ff808cd421036f81ab34c0d5884743982aa.tar.bz2 |
hw/microblaze: Add support for loading initrd images
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Diffstat (limited to 'hw/microblaze')
-rw-r--r-- | hw/microblaze/boot.c | 39 | ||||
-rw-r--r-- | hw/microblaze/boot.h | 4 | ||||
-rw-r--r-- | hw/microblaze/petalogix_ml605_mmu.c | 1 | ||||
-rw-r--r-- | hw/microblaze/petalogix_s3adsp1800_mmu.c | 4 |
4 files changed, 45 insertions, 3 deletions
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c index 59be5b9..2a7ea5c 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 b14ef2b..0eb7f8e 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 1c44231..10970e0 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 39ce2c4..ec6489c 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 = { |