aboutsummaryrefslogtreecommitdiff
path: root/hw/riscv/boot.c
diff options
context:
space:
mode:
authorAtish Patra <atish.patra@wdc.com>2020-07-01 11:39:46 -0700
committerAlistair Francis <alistair.francis@wdc.com>2020-07-13 17:25:37 -0700
commit43cf723adca9a5e188c664c3b606a585192a599c (patch)
treeb9e8397567d10b3a4dc41640dec663b52a77be27 /hw/riscv/boot.c
parent2c44bbf32cda5fbf85b697e3a12127f59d2c2e80 (diff)
riscv: Unify Qemu's reset vector code path
Currently, all riscv machines except sifive_u have identical reset vector code implementations with memory addresses being different for all machines. They can be easily combined into a single function in common code. Move it to common function and let all the machines use the common function. Signed-off-by: Atish Patra <atish.patra@wdc.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Bin Meng <bin.meng@windriver.com> Tested-by: Bin Meng <bin.meng@windriver.com> Message-Id: <20200701183949.398134-2-atish.patra@wdc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'hw/riscv/boot.c')
-rw-r--r--hw/riscv/boot.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index adb421b91b..3df802380a 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -26,8 +26,11 @@
#include "hw/loader.h"
#include "hw/riscv/boot.h"
#include "elf.h"
+#include "sysemu/device_tree.h"
#include "sysemu/qtest.h"
+#include <libfdt.h>
+
#if defined(TARGET_RISCV32)
# define KERNEL_BOOT_ADDRESS 0x80400000
#else
@@ -155,3 +158,46 @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
return *start + size;
}
+
+void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
+ hwaddr rom_size, void *fdt)
+{
+ int i;
+
+ /* reset vector */
+ uint32_t reset_vec[8] = {
+ 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
+ 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */
+ 0xf1402573, /* csrr a0, mhartid */
+#if defined(TARGET_RISCV32)
+ 0x0182a283, /* lw t0, 24(t0) */
+#elif defined(TARGET_RISCV64)
+ 0x0182b283, /* ld t0, 24(t0) */
+#endif
+ 0x00028067, /* jr t0 */
+ 0x00000000,
+ start_addr, /* start: .dword */
+ 0x00000000,
+ /* dtb: */
+ };
+
+ /* copy in the reset vector in little_endian byte order */
+ for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
+ reset_vec[i] = cpu_to_le32(reset_vec[i]);
+ }
+ rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
+ rom_base, &address_space_memory);
+
+ /* copy in the device tree */
+ if (fdt_pack(fdt) || fdt_totalsize(fdt) >
+ rom_size - sizeof(reset_vec)) {
+ error_report("not enough space to store device-tree");
+ exit(1);
+ }
+ qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
+ rom_add_blob_fixed_as("mrom.fdt", fdt, fdt_totalsize(fdt),
+ rom_base + sizeof(reset_vec),
+ &address_space_memory);
+
+ return;
+}