aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdgar E. Iglesias <edgar.iglesias@gmail.com>2013-05-05 11:06:37 +0200
committerEdgar E. Iglesias <edgar.iglesias@gmail.com>2013-10-24 22:56:48 +0200
commitec426ff808cd421036f81ab34c0d5884743982aa (patch)
treebe3323c544d92684c74cf78f50b56ed754ffcfc7
parentd0b022a0e9dcf574d56243f6039d675ba80dba16 (diff)
downloadqemu-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>
-rw-r--r--hw/microblaze/boot.c39
-rw-r--r--hw/microblaze/boot.h4
-rw-r--r--hw/microblaze/petalogix_ml605_mmu.c1
-rw-r--r--hw/microblaze/petalogix_s3adsp1800_mmu.c4
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 = {