aboutsummaryrefslogtreecommitdiff
path: root/hw/riscv/virt.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/riscv/virt.c')
-rw-r--r--hw/riscv/virt.c63
1 files changed, 20 insertions, 43 deletions
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index f7630c8a89..55a907bb35 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -39,12 +39,9 @@
#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "sysemu/sysemu.h"
-#include "exec/address-spaces.h"
#include "hw/pci/pci.h"
#include "hw/pci-host/gpex.h"
-#include <libfdt.h>
-
#if defined(TARGET_RISCV32)
# define BIOS_FILENAME "opensbi-riscv32-virt-fw_jump.bin"
#else
@@ -56,18 +53,18 @@ static const struct MemmapEntry {
hwaddr size;
} virt_memmap[] = {
[VIRT_DEBUG] = { 0x0, 0x100 },
- [VIRT_MROM] = { 0x1000, 0x11000 },
+ [VIRT_MROM] = { 0x1000, 0xf000 },
[VIRT_TEST] = { 0x100000, 0x1000 },
[VIRT_RTC] = { 0x101000, 0x1000 },
[VIRT_CLINT] = { 0x2000000, 0x10000 },
+ [VIRT_PCIE_PIO] = { 0x3000000, 0x10000 },
[VIRT_PLIC] = { 0xc000000, 0x4000000 },
[VIRT_UART0] = { 0x10000000, 0x100 },
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
- [VIRT_DRAM] = { 0x80000000, 0x0 },
- [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
- [VIRT_PCIE_PIO] = { 0x03000000, 0x00010000 },
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
+ [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
+ [VIRT_DRAM] = { 0x80000000, 0x0 },
};
#define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
@@ -481,6 +478,8 @@ static void virt_machine_init(MachineState *machine)
char *plic_hart_config;
size_t plic_hart_config_len;
target_ulong start_addr = memmap[VIRT_DRAM].base;
+ uint32_t fdt_load_addr;
+ uint64_t kernel_entry;
int i;
unsigned int smp_cpus = machine->smp.cpus;
@@ -512,8 +511,7 @@ static void virt_machine_init(MachineState *machine)
memmap[VIRT_DRAM].base, NULL);
if (machine->kernel_filename) {
- uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
- NULL);
+ kernel_entry = riscv_load_kernel(machine->kernel_filename, NULL);
if (machine->initrd_filename) {
hwaddr start;
@@ -525,6 +523,12 @@ static void virt_machine_init(MachineState *machine)
qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
end);
}
+ } else {
+ /*
+ * If dynamic firmware is used, it doesn't know where is the next mode
+ * if kernel argument is not set.
+ */
+ kernel_entry = 0;
}
if (drive_get(IF_PFLASH, 0, 0)) {
@@ -535,40 +539,13 @@ static void virt_machine_init(MachineState *machine)
start_addr = virt_memmap[VIRT_FLASH].base;
}
- /* 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),
- memmap[VIRT_MROM].base, &address_space_memory);
-
- /* copy in the device tree */
- if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) >
- memmap[VIRT_MROM].size - sizeof(reset_vec)) {
- error_report("not enough space to store device-tree");
- exit(1);
- }
- qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt));
- rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt),
- memmap[VIRT_MROM].base + sizeof(reset_vec),
- &address_space_memory);
+ /* Compute the fdt load address in dram */
+ fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
+ machine->ram_size, s->fdt);
+ /* load the reset vector */
+ riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base,
+ virt_memmap[VIRT_MROM].size, kernel_entry,
+ fdt_load_addr, s->fdt);
/* create PLIC hart topology configuration string */
plic_hart_config_len = (strlen(VIRT_PLIC_HART_CONFIG) + 1) * smp_cpus;