|
@@ -1162,6 +1162,100 @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
|
|
|
return aplic_m;
|
|
|
}
|
|
|
|
|
|
+static void virt_machine_done(Notifier *notifier, void *data)
|
|
|
+{
|
|
|
+ RISCVVirtState *s = container_of(notifier, RISCVVirtState,
|
|
|
+ machine_done);
|
|
|
+ const MemMapEntry *memmap = virt_memmap;
|
|
|
+ MachineState *machine = MACHINE(s);
|
|
|
+ target_ulong start_addr = memmap[VIRT_DRAM].base;
|
|
|
+ target_ulong firmware_end_addr, kernel_start_addr;
|
|
|
+ uint32_t fdt_load_addr;
|
|
|
+ uint64_t kernel_entry;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Only direct boot kernel is currently supported for KVM VM,
|
|
|
+ * so the "-bios" parameter is not supported when KVM is enabled.
|
|
|
+ */
|
|
|
+ if (kvm_enabled()) {
|
|
|
+ if (machine->firmware) {
|
|
|
+ if (strcmp(machine->firmware, "none")) {
|
|
|
+ error_report("Machine mode firmware is not supported in "
|
|
|
+ "combination with KVM.");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ machine->firmware = g_strdup("none");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (riscv_is_32bit(&s->soc[0])) {
|
|
|
+ firmware_end_addr = riscv_find_and_load_firmware(machine,
|
|
|
+ RISCV32_BIOS_BIN, start_addr, NULL);
|
|
|
+ } else {
|
|
|
+ firmware_end_addr = riscv_find_and_load_firmware(machine,
|
|
|
+ RISCV64_BIOS_BIN, start_addr, NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (machine->kernel_filename) {
|
|
|
+ kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
|
|
|
+ firmware_end_addr);
|
|
|
+
|
|
|
+ kernel_entry = riscv_load_kernel(machine->kernel_filename,
|
|
|
+ kernel_start_addr, NULL);
|
|
|
+
|
|
|
+ if (machine->initrd_filename) {
|
|
|
+ hwaddr start;
|
|
|
+ hwaddr end = riscv_load_initrd(machine->initrd_filename,
|
|
|
+ machine->ram_size, kernel_entry,
|
|
|
+ &start);
|
|
|
+ qemu_fdt_setprop_cell(machine->fdt, "/chosen",
|
|
|
+ "linux,initrd-start", start);
|
|
|
+ qemu_fdt_setprop_cell(machine->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)) {
|
|
|
+ /*
|
|
|
+ * Pflash was supplied, let's overwrite the address we jump to after
|
|
|
+ * reset to the base of the flash.
|
|
|
+ */
|
|
|
+ start_addr = virt_memmap[VIRT_FLASH].base;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
|
|
|
+ * tree cannot be altered and we get FDT_ERR_NOSPACE.
|
|
|
+ */
|
|
|
+ s->fw_cfg = create_fw_cfg(machine);
|
|
|
+ rom_set_fw(s->fw_cfg);
|
|
|
+
|
|
|
+ /* Compute the fdt load address in dram */
|
|
|
+ fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
|
|
|
+ machine->ram_size, machine->fdt);
|
|
|
+ /* load the reset vector */
|
|
|
+ riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr,
|
|
|
+ virt_memmap[VIRT_MROM].base,
|
|
|
+ virt_memmap[VIRT_MROM].size, kernel_entry,
|
|
|
+ fdt_load_addr, machine->fdt);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Only direct boot kernel is currently supported for KVM VM,
|
|
|
+ * So here setup kernel start address and fdt address.
|
|
|
+ * TODO:Support firmware loading and integrate to TCG start
|
|
|
+ */
|
|
|
+ if (kvm_enabled()) {
|
|
|
+ riscv_setup_direct_kernel(kernel_entry, fdt_load_addr);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void virt_machine_init(MachineState *machine)
|
|
|
{
|
|
|
const MemMapEntry *memmap = virt_memmap;
|
|
@@ -1169,10 +1263,6 @@ static void virt_machine_init(MachineState *machine)
|
|
|
MemoryRegion *system_memory = get_system_memory();
|
|
|
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
|
|
|
char *soc_name;
|
|
|
- target_ulong start_addr = memmap[VIRT_DRAM].base;
|
|
|
- target_ulong firmware_end_addr, kernel_start_addr;
|
|
|
- uint32_t fdt_load_addr;
|
|
|
- uint64_t kernel_entry;
|
|
|
DeviceState *mmio_irqchip, *virtio_irqchip, *pcie_irqchip;
|
|
|
int i, base_hartid, hart_count;
|
|
|
|
|
@@ -1302,98 +1392,12 @@ static void virt_machine_init(MachineState *machine)
|
|
|
memory_region_add_subregion(system_memory, memmap[VIRT_DRAM].base,
|
|
|
machine->ram);
|
|
|
|
|
|
- /* create device tree */
|
|
|
- create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
|
|
|
- riscv_is_32bit(&s->soc[0]));
|
|
|
-
|
|
|
/* boot rom */
|
|
|
memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom",
|
|
|
memmap[VIRT_MROM].size, &error_fatal);
|
|
|
memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base,
|
|
|
mask_rom);
|
|
|
|
|
|
- /*
|
|
|
- * Only direct boot kernel is currently supported for KVM VM,
|
|
|
- * so the "-bios" parameter is not supported when KVM is enabled.
|
|
|
- */
|
|
|
- if (kvm_enabled()) {
|
|
|
- if (machine->firmware) {
|
|
|
- if (strcmp(machine->firmware, "none")) {
|
|
|
- error_report("Machine mode firmware is not supported in "
|
|
|
- "combination with KVM.");
|
|
|
- exit(1);
|
|
|
- }
|
|
|
- } else {
|
|
|
- machine->firmware = g_strdup("none");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (riscv_is_32bit(&s->soc[0])) {
|
|
|
- firmware_end_addr = riscv_find_and_load_firmware(machine,
|
|
|
- RISCV32_BIOS_BIN, start_addr, NULL);
|
|
|
- } else {
|
|
|
- firmware_end_addr = riscv_find_and_load_firmware(machine,
|
|
|
- RISCV64_BIOS_BIN, start_addr, NULL);
|
|
|
- }
|
|
|
-
|
|
|
- if (machine->kernel_filename) {
|
|
|
- kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
|
|
|
- firmware_end_addr);
|
|
|
-
|
|
|
- kernel_entry = riscv_load_kernel(machine->kernel_filename,
|
|
|
- kernel_start_addr, NULL);
|
|
|
-
|
|
|
- if (machine->initrd_filename) {
|
|
|
- hwaddr start;
|
|
|
- hwaddr end = riscv_load_initrd(machine->initrd_filename,
|
|
|
- machine->ram_size, kernel_entry,
|
|
|
- &start);
|
|
|
- qemu_fdt_setprop_cell(machine->fdt, "/chosen",
|
|
|
- "linux,initrd-start", start);
|
|
|
- qemu_fdt_setprop_cell(machine->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)) {
|
|
|
- /*
|
|
|
- * Pflash was supplied, let's overwrite the address we jump to after
|
|
|
- * reset to the base of the flash.
|
|
|
- */
|
|
|
- start_addr = virt_memmap[VIRT_FLASH].base;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
|
|
|
- * tree cannot be altered and we get FDT_ERR_NOSPACE.
|
|
|
- */
|
|
|
- s->fw_cfg = create_fw_cfg(machine);
|
|
|
- rom_set_fw(s->fw_cfg);
|
|
|
-
|
|
|
- /* Compute the fdt load address in dram */
|
|
|
- fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
|
|
|
- machine->ram_size, machine->fdt);
|
|
|
- /* load the reset vector */
|
|
|
- riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr,
|
|
|
- virt_memmap[VIRT_MROM].base,
|
|
|
- virt_memmap[VIRT_MROM].size, kernel_entry,
|
|
|
- fdt_load_addr, machine->fdt);
|
|
|
-
|
|
|
- /*
|
|
|
- * Only direct boot kernel is currently supported for KVM VM,
|
|
|
- * So here setup kernel start address and fdt address.
|
|
|
- * TODO:Support firmware loading and integrate to TCG start
|
|
|
- */
|
|
|
- if (kvm_enabled()) {
|
|
|
- riscv_setup_direct_kernel(kernel_entry, fdt_load_addr);
|
|
|
- }
|
|
|
-
|
|
|
/* SiFive Test MMIO device */
|
|
|
sifive_test_create(memmap[VIRT_TEST].base);
|
|
|
|
|
@@ -1429,6 +1433,13 @@ static void virt_machine_init(MachineState *machine)
|
|
|
drive_get(IF_PFLASH, 0, i));
|
|
|
}
|
|
|
virt_flash_map(s, system_memory);
|
|
|
+
|
|
|
+ /* create device tree */
|
|
|
+ create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
|
|
|
+ riscv_is_32bit(&s->soc[0]));
|
|
|
+
|
|
|
+ s->machine_done.notify = virt_machine_done;
|
|
|
+ qemu_add_machine_init_done_notifier(&s->machine_done);
|
|
|
}
|
|
|
|
|
|
static void virt_machine_instance_init(Object *obj)
|