qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-riscv] [PATCH v2 3/4] RISC-V: Honor entry point in loaded ELF firm


From: Stefan O'Rear
Subject: [Qemu-riscv] [PATCH v2 3/4] RISC-V: Honor entry point in loaded ELF firmware
Date: Sun, 16 Dec 2018 18:12:26 -0500

The virt board is changed to use the firmware address from the
loaded firmware or combined firmware+kernel. This is normally
equal to the DRAM base address of 0x8000_0000, however now it
is possible to boot firmware at different load addresses because
the reset code jumps to the actual firmware entry address.

Signed-off-by: Michael Clark <address@hidden>
Signed-off-by: Stefan O'Rear <address@hidden>
---
 hw/riscv/boot.c         |  9 ++++++---
 hw/riscv/virt.c         | 17 ++++++++++++++---
 include/hw/riscv/boot.h |  2 +-
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 54e3139..e51e7f9 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -87,15 +87,18 @@ static void riscv_load_initrd(const char *filename, 
uint64_t mem_size,
     }
 }
 
-void riscv_load_firmware_kernel_initrd(MachineState *machine, void *fdt)
+hwaddr riscv_load_firmware_kernel_initrd(MachineState *machine, void *fdt)
 {
-    if (machine->kernel_filename) {
-        uint64_t firmware_entry = load_kernel(machine->kernel_filename);
+    hwaddr firmware_entry = 0;
 
+    if (machine->kernel_filename) {
+        firmware_entry = load_kernel(machine->kernel_filename);
         if (machine->initrd_filename) {
             /* load separate initrd */
             riscv_load_initrd(machine->initrd_filename, machine->ram_size,
                               firmware_entry, fdt);
         }
     }
+
+    return firmware_entry;
 }
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4c2e894..38979f7 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -235,6 +235,7 @@ static void riscv_virt_board_init(MachineState *machine)
     size_t plic_hart_config_len;
     int i;
     void *fdt;
+    hwaddr firmware_entry;
 
     /* Initialize SOC */
     object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
@@ -261,7 +262,17 @@ static void riscv_virt_board_init(MachineState *machine)
     memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base,
                                 mask_rom);
 
-    riscv_load_firmware_kernel_initrd(machine, fdt);
+    /*
+     * combined firmware and kernel: -kernel bbl_vmlimux
+     * separate firmware and kernel: -bios bbl -kernel vmlinux
+     * firmware, kernel and ramdisk: -bios bbl -kernel vmlinux -initrd 
initramfs
+     */
+    firmware_entry = riscv_load_firmware_kernel_initrd(machine, fdt);
+
+    if (firmware_entry == 0) {
+        firmware_entry = memmap[VIRT_DRAM].base;
+    }
+
     /* reset vector */
     uint32_t reset_vec[8] = {
         0x00000297,                  /* 1:  auipc  t0, %pcrel_hi(dtb) */
@@ -274,8 +285,8 @@ static void riscv_virt_board_init(MachineState *machine)
 #endif
         0x00028067,                  /*     jr     t0 */
         0x00000000,
-        memmap[VIRT_DRAM].base,      /* start: .dword memmap[VIRT_DRAM].base */
-        0x00000000,
+        firmware_entry,              /* .word firmware_entry */
+        firmware_entry >> 32,
                                      /* dtb: */
     };
 
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 92948f3..3af21fc 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -19,6 +19,6 @@
 #ifndef HW_RISCV_BOOT_H
 #define HW_RISCV_BOOT_H
 
-void riscv_load_firmware_kernel_initrd(MachineState *machine, void *fdt);
+hwaddr riscv_load_firmware_kernel_initrd(MachineState *machine, void *fdt);
 
 #endif
-- 
2.8.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]