diff mbox

[10/10] hw/microblaze: Add support for loading initrd images

Message ID 1382648937-14769-11-git-send-email-edgar.iglesias@gmail.com
State New
Headers show

Commit Message

Edgar E. Iglesias Oct. 24, 2013, 9:08 p.m. UTC
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 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(-)
diff mbox

Patch

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 = {