All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board
@ 2022-04-07  2:04 Alistair Francis
  2022-04-07  2:04 ` [PATCH v2 1/6] hw/riscv: virt: Add a machine done notifier Alistair Francis
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Alistair Francis @ 2022-04-07  2:04 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel
  Cc: peter.maydell, qemu-arm, richard.henderson, Edgar E. Iglesias,
	Alistair Francis, alistair23, Palmer Dabbelt, bmeng.cn, Bin Meng,
	Alistair Francis

From: Alistair Francis <alistair.francis@wdc.com>

This series adds support for connecting TPM devices to the RISC-V virt
board. This is similar to how it works for the ARM virt board.

This was tested by first creating an emulated TPM device:

    swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \
        --ctrl type=unixio,path=swtpm-sock

Then launching QEMU with:

    -chardev socket,id=chrtpm,path=swtpm-sock \
    -tpmdev emulator,id=tpm0,chardev=chrtpm \
    -device tpm-tis-device,tpmdev=tpm0

The TPM device can be seen in the memory tree and the generated device
tree.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/942

Alistair Francis (6):
  hw/riscv: virt: Add a machine done notifier
  hw/core: Move the ARM sysbus-fdt to core
  hw/riscv: virt: Create a platform bus
  hw/riscv: virt: Add support for generateing platform FDT entries
  hw/riscv: virt: Add device plug support
  hw/riscv: Enable TPM backends

 include/hw/{arm => core}/sysbus-fdt.h |   0
 include/hw/riscv/virt.h               |   8 +-
 hw/arm/virt.c                         |   2 +-
 hw/arm/xlnx-versal-virt.c             |   1 -
 hw/{arm => core}/sysbus-fdt.c         |   2 +-
 hw/riscv/virt.c                       | 312 +++++++++++++++++---------
 hw/arm/meson.build                    |   1 -
 hw/core/meson.build                   |   1 +
 hw/riscv/Kconfig                      |   2 +
 9 files changed, 221 insertions(+), 108 deletions(-)
 rename include/hw/{arm => core}/sysbus-fdt.h (100%)
 rename hw/{arm => core}/sysbus-fdt.c (99%)

-- 
2.35.1



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 1/6] hw/riscv: virt: Add a machine done notifier
  2022-04-07  2:04 [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board Alistair Francis
@ 2022-04-07  2:04 ` Alistair Francis
  2022-04-15 15:25     ` Andrew Bresticker
  2022-04-07  2:04 ` [PATCH v2 2/6] hw/core: Move the ARM sysbus-fdt to core Alistair Francis
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Alistair Francis @ 2022-04-07  2:04 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel
  Cc: peter.maydell, qemu-arm, richard.henderson, Edgar E. Iglesias,
	Alistair Francis, alistair23, Palmer Dabbelt, bmeng.cn, Bin Meng,
	Alistair Francis

From: Alistair Francis <alistair.francis@wdc.com>

Move the binary and device tree loading code to the machine done
notifier. This allows us to prepare for editing the device tree as part
of the notifier.

This is based on similar code in the ARM virt machine.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/riscv/virt.h |   1 +
 hw/riscv/virt.c         | 180 +++++++++++++++++++++-------------------
 2 files changed, 97 insertions(+), 84 deletions(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 78b058ec86..8b8db3fb7c 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -45,6 +45,7 @@ struct RISCVVirtState {
     MachineState parent;
 
     /*< public >*/
+    Notifier machine_done;
     RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
     DeviceState *irqchip[VIRT_SOCKETS_MAX];
     PFlashCFI01 *flash[2];
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index da50cbed43..3f065b540e 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1156,6 +1156,99 @@ 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;
+
+    /* create device tree */
+    create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
+               riscv_is_32bit(&s->soc[0]));
+
+    /*
+     * Only direct boot kernel is currently supported for KVM VM,
+     * so the "-bios" parameter is ignored and treated like "-bios none"
+     * when KVM is enabled.
+     */
+    if (kvm_enabled()) {
+        g_free(machine->firmware);
+        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;
@@ -1163,10 +1256,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;
 
@@ -1296,92 +1385,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 ignored and treated like "-bios none"
-     * when KVM is enabled.
-     */
-    if (kvm_enabled()) {
-        g_free(machine->firmware);
-        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);
 
@@ -1417,6 +1426,9 @@ static void virt_machine_init(MachineState *machine)
                                   drive_get(IF_PFLASH, 0, i));
     }
     virt_flash_map(s, system_memory);
+
+    s->machine_done.notify = virt_machine_done;
+    qemu_add_machine_init_done_notifier(&s->machine_done);
 }
 
 static void virt_machine_instance_init(Object *obj)
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 2/6] hw/core: Move the ARM sysbus-fdt to core
  2022-04-07  2:04 [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board Alistair Francis
  2022-04-07  2:04 ` [PATCH v2 1/6] hw/riscv: virt: Add a machine done notifier Alistair Francis
@ 2022-04-07  2:04 ` Alistair Francis
  2022-04-07  2:04 ` [PATCH v2 3/6] hw/riscv: virt: Create a platform bus Alistair Francis
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Alistair Francis @ 2022-04-07  2:04 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel
  Cc: peter.maydell, qemu-arm, richard.henderson, Edgar E. Iglesias,
	Alistair Francis, alistair23, Palmer Dabbelt, bmeng.cn, Bin Meng,
	Alistair Francis

From: Alistair Francis <alistair.francis@wdc.com>

The ARM virt machine currently uses sysbus-fdt to create device tree
entries for dynamically created MMIO devices.

The RISC-V virt machine can also benefit from this, so move the code to
the core directory.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/{arm => core}/sysbus-fdt.h | 0
 hw/arm/virt.c                         | 2 +-
 hw/arm/xlnx-versal-virt.c             | 1 -
 hw/{arm => core}/sysbus-fdt.c         | 2 +-
 hw/arm/meson.build                    | 1 -
 hw/core/meson.build                   | 1 +
 6 files changed, 3 insertions(+), 4 deletions(-)
 rename include/hw/{arm => core}/sysbus-fdt.h (100%)
 rename hw/{arm => core}/sysbus-fdt.c (99%)

diff --git a/include/hw/arm/sysbus-fdt.h b/include/hw/core/sysbus-fdt.h
similarity index 100%
rename from include/hw/arm/sysbus-fdt.h
rename to include/hw/core/sysbus-fdt.h
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d2e5ecd234..cfababa292 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -56,7 +56,7 @@
 #include "qemu/module.h"
 #include "hw/pci-host/gpex.h"
 #include "hw/virtio/virtio-pci.h"
-#include "hw/arm/sysbus-fdt.h"
+#include "hw/core/sysbus-fdt.h"
 #include "hw/platform-bus.h"
 #include "hw/qdev-properties.h"
 #include "hw/arm/fdt.h"
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 7c7baff8b7..bc20af4ba8 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -15,7 +15,6 @@
 #include "sysemu/device_tree.h"
 #include "hw/boards.h"
 #include "hw/sysbus.h"
-#include "hw/arm/sysbus-fdt.h"
 #include "hw/arm/fdt.h"
 #include "cpu.h"
 #include "hw/qdev-properties.h"
diff --git a/hw/arm/sysbus-fdt.c b/hw/core/sysbus-fdt.c
similarity index 99%
rename from hw/arm/sysbus-fdt.c
rename to hw/core/sysbus-fdt.c
index 48c5fe9bf1..19d22cbe73 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/core/sysbus-fdt.c
@@ -27,7 +27,7 @@
 #ifdef CONFIG_LINUX
 #include <linux/vfio.h>
 #endif
-#include "hw/arm/sysbus-fdt.h"
+#include "hw/core/sysbus-fdt.h"
 #include "qemu/error-report.h"
 #include "sysemu/device_tree.h"
 #include "sysemu/tpm.h"
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 721a8eb8be..122e5dd992 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -1,6 +1,5 @@
 arm_ss = ss.source_set()
 arm_ss.add(files('boot.c'), fdt)
-arm_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('sysbus-fdt.c'))
 arm_ss.add(when: 'CONFIG_ARM_VIRT', if_true: files('virt.c'))
 arm_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
 arm_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic_boards.c'))
diff --git a/hw/core/meson.build b/hw/core/meson.build
index 0f884d6fd4..7a4d02b6c0 100644
--- a/hw/core/meson.build
+++ b/hw/core/meson.build
@@ -33,6 +33,7 @@ softmmu_ss.add(when: 'CONFIG_PTIMER', if_true: files('ptimer.c'))
 softmmu_ss.add(when: 'CONFIG_REGISTER', if_true: files('register.c'))
 softmmu_ss.add(when: 'CONFIG_SPLIT_IRQ', if_true: files('split-irq.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('stream.c'))
+softmmu_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('sysbus-fdt.c'))
 
 softmmu_ss.add(files(
   'cpu-sysemu.c',
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 3/6] hw/riscv: virt: Create a platform bus
  2022-04-07  2:04 [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board Alistair Francis
  2022-04-07  2:04 ` [PATCH v2 1/6] hw/riscv: virt: Add a machine done notifier Alistair Francis
  2022-04-07  2:04 ` [PATCH v2 2/6] hw/core: Move the ARM sysbus-fdt to core Alistair Francis
@ 2022-04-07  2:04 ` Alistair Francis
  2022-04-07  2:04 ` [PATCH v2 4/6] hw/riscv: virt: Add support for generateing platform FDT entries Alistair Francis
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Alistair Francis @ 2022-04-07  2:04 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel
  Cc: peter.maydell, qemu-arm, richard.henderson, Edgar E. Iglesias,
	Alistair Francis, alistair23, Palmer Dabbelt, bmeng.cn, Bin Meng,
	Alistair Francis

From: Alistair Francis <alistair.francis@wdc.com>

Create a platform bus to allow dynamic devices to be connected. This is
based on the ARM implementation.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/riscv/virt.h |  7 ++++-
 hw/riscv/virt.c         | 68 +++++++++++++++++++++++++++++------------
 hw/riscv/Kconfig        |  1 +
 3 files changed, 56 insertions(+), 20 deletions(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 8b8db3fb7c..984e55c77f 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -46,6 +46,7 @@ struct RISCVVirtState {
 
     /*< public >*/
     Notifier machine_done;
+    DeviceState *platform_bus_dev;
     RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
     DeviceState *irqchip[VIRT_SOCKETS_MAX];
     PFlashCFI01 *flash[2];
@@ -76,6 +77,7 @@ enum {
     VIRT_DRAM,
     VIRT_PCIE_MMIO,
     VIRT_PCIE_PIO,
+    VIRT_PLATFORM_BUS,
     VIRT_PCIE_ECAM
 };
 
@@ -85,9 +87,12 @@ enum {
     VIRTIO_IRQ = 1, /* 1 to 8 */
     VIRTIO_COUNT = 8,
     PCIE_IRQ = 0x20, /* 32 to 35 */
-    VIRTIO_NDEV = 0x35 /* Arbitrary maximum number of interrupts */
+    VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 96 */
+    VIRTIO_NDEV = 96 /* Arbitrary maximum number of interrupts */
 };
 
+#define VIRT_PLATFORM_BUS_NUM_IRQS 32
+
 #define VIRT_IRQCHIP_IPI_MSI 1
 #define VIRT_IRQCHIP_NUM_MSIS 255
 #define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 3f065b540e..b066725be6 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -37,6 +37,7 @@
 #include "hw/intc/riscv_imsic.h"
 #include "hw/intc/sifive_plic.h"
 #include "hw/misc/sifive_test.h"
+#include "hw/platform-bus.h"
 #include "chardev/char.h"
 #include "sysemu/device_tree.h"
 #include "sysemu/sysemu.h"
@@ -68,25 +69,26 @@
 #endif
 
 static const MemMapEntry virt_memmap[] = {
-    [VIRT_DEBUG] =       {        0x0,         0x100 },
-    [VIRT_MROM] =        {     0x1000,        0xf000 },
-    [VIRT_TEST] =        {   0x100000,        0x1000 },
-    [VIRT_RTC] =         {   0x101000,        0x1000 },
-    [VIRT_CLINT] =       {  0x2000000,       0x10000 },
-    [VIRT_ACLINT_SSWI] = {  0x2F00000,        0x4000 },
-    [VIRT_PCIE_PIO] =    {  0x3000000,       0x10000 },
-    [VIRT_PLIC] =        {  0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
-    [VIRT_APLIC_M] =     {  0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) },
-    [VIRT_APLIC_S] =     {  0xd000000, APLIC_SIZE(VIRT_CPUS_MAX) },
-    [VIRT_UART0] =       { 0x10000000,         0x100 },
-    [VIRT_VIRTIO] =      { 0x10001000,        0x1000 },
-    [VIRT_FW_CFG] =      { 0x10100000,          0x18 },
-    [VIRT_FLASH] =       { 0x20000000,     0x4000000 },
-    [VIRT_IMSIC_M] =     { 0x24000000, VIRT_IMSIC_MAX_SIZE },
-    [VIRT_IMSIC_S] =     { 0x28000000, VIRT_IMSIC_MAX_SIZE },
-    [VIRT_PCIE_ECAM] =   { 0x30000000,    0x10000000 },
-    [VIRT_PCIE_MMIO] =   { 0x40000000,    0x40000000 },
-    [VIRT_DRAM] =        { 0x80000000,           0x0 },
+    [VIRT_DEBUG] =        {        0x0,         0x100 },
+    [VIRT_MROM] =         {     0x1000,        0xf000 },
+    [VIRT_TEST] =         {   0x100000,        0x1000 },
+    [VIRT_RTC] =          {   0x101000,        0x1000 },
+    [VIRT_CLINT] =        {  0x2000000,       0x10000 },
+    [VIRT_ACLINT_SSWI] =  {  0x2F00000,        0x4000 },
+    [VIRT_PCIE_PIO] =     {  0x3000000,       0x10000 },
+    [VIRT_PLATFORM_BUS] = {  0x4000000,     0x2000000 },
+    [VIRT_PLIC] =         {  0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
+    [VIRT_APLIC_M] =      {  0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) },
+    [VIRT_APLIC_S] =      {  0xd000000, APLIC_SIZE(VIRT_CPUS_MAX) },
+    [VIRT_UART0] =        { 0x10000000,         0x100 },
+    [VIRT_VIRTIO] =       { 0x10001000,        0x1000 },
+    [VIRT_FW_CFG] =       { 0x10100000,          0x18 },
+    [VIRT_FLASH] =        { 0x20000000,     0x4000000 },
+    [VIRT_IMSIC_M] =      { 0x24000000, VIRT_IMSIC_MAX_SIZE },
+    [VIRT_IMSIC_S] =      { 0x28000000, VIRT_IMSIC_MAX_SIZE },
+    [VIRT_PCIE_ECAM] =    { 0x30000000,    0x10000000 },
+    [VIRT_PCIE_MMIO] =    { 0x40000000,    0x40000000 },
+    [VIRT_DRAM] =         { 0x80000000,           0x0 },
 };
 
 /* PCIe high mmio is fixed for RV32 */
@@ -1156,6 +1158,32 @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
     return aplic_m;
 }
 
+static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
+{
+    DeviceState *dev;
+    SysBusDevice *sysbus;
+    const MemMapEntry *memmap = virt_memmap;
+    int i;
+    MemoryRegion *sysmem = get_system_memory();
+
+    dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
+    dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
+    qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS);
+    qdev_prop_set_uint32(dev, "mmio_size", memmap[VIRT_PLATFORM_BUS].size);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+    s->platform_bus_dev = dev;
+
+    sysbus = SYS_BUS_DEVICE(dev);
+    for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) {
+        int irq = VIRT_PLATFORM_BUS_IRQ + i;
+        sysbus_connect_irq(sysbus, i, qdev_get_gpio_in(irqchip, irq));
+    }
+
+    memory_region_add_subregion(sysmem,
+                                memmap[VIRT_PLATFORM_BUS].base,
+                                sysbus_mmio_get_region(sysbus, 0));
+}
+
 static
 void virt_machine_done(Notifier *notifier, void *data)
 {
@@ -1411,6 +1439,8 @@ static void virt_machine_init(MachineState *machine)
                    memmap[VIRT_PCIE_PIO].base,
                    DEVICE(pcie_irqchip));
 
+    create_platform_bus(s, DEVICE(mmio_irqchip));
+
     serial_mm_init(system_memory, memmap[VIRT_UART0].base,
         0, qdev_get_gpio_in(DEVICE(mmio_irqchip), UART0_IRQ), 399193,
         serial_hd(0), DEVICE_LITTLE_ENDIAN);
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 91bb9d21c4..da790f5936 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -48,6 +48,7 @@ config RISCV_VIRT
     select SIFIVE_TEST
     select VIRTIO_MMIO
     select FW_CFG_DMA
+    select PLATFORM_BUS
 
 config SIFIVE_E
     bool
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 4/6] hw/riscv: virt: Add support for generateing platform FDT entries
  2022-04-07  2:04 [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board Alistair Francis
                   ` (2 preceding siblings ...)
  2022-04-07  2:04 ` [PATCH v2 3/6] hw/riscv: virt: Create a platform bus Alistair Francis
@ 2022-04-07  2:04 ` Alistair Francis
  2022-04-07  2:04 ` [PATCH v2 5/6] hw/riscv: virt: Add device plug support Alistair Francis
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Alistair Francis @ 2022-04-07  2:04 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel
  Cc: peter.maydell, qemu-arm, richard.henderson, Edgar E. Iglesias,
	Alistair Francis, alistair23, Palmer Dabbelt, bmeng.cn, Bin Meng,
	Alistair Francis

From: Alistair Francis <alistair.francis@wdc.com>

Similar to the ARM virt machine add support for adding device tree
entries for dynamically created devices.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 hw/riscv/virt.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index b066725be6..eba8495e9a 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -28,6 +28,7 @@
 #include "hw/qdev-properties.h"
 #include "hw/char/serial.h"
 #include "target/riscv/cpu.h"
+#include "hw/core/sysbus-fdt.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/virt.h"
 #include "hw/riscv/boot.h"
@@ -411,6 +412,12 @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
         qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0);
         qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0);
         riscv_socket_fdt_write_id(mc, mc->fdt, name, socket);
+
+        platform_bus_add_all_fdt_nodes(mc->fdt, name,
+                                       memmap[VIRT_PLATFORM_BUS].base,
+                                       memmap[VIRT_PLATFORM_BUS].size,
+                                       VIRT_PLATFORM_BUS_IRQ);
+
         g_free(name);
     }
 
@@ -469,6 +476,12 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
     riscv_socket_fdt_write_id(mc, mc->fdt, plic_name, socket);
     qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle",
         plic_phandles[socket]);
+
+    platform_bus_add_all_fdt_nodes(mc->fdt, plic_name,
+                                   memmap[VIRT_PLATFORM_BUS].base,
+                                   memmap[VIRT_PLATFORM_BUS].size,
+                                   VIRT_PLATFORM_BUS_IRQ);
+
     g_free(plic_name);
 
     g_free(plic_cells);
@@ -546,6 +559,12 @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
             IMSIC_MMIO_GROUP_MIN_SHIFT);
     }
     qemu_fdt_setprop_cell(mc->fdt, imsic_name, "phandle", *msi_m_phandle);
+
+    platform_bus_add_all_fdt_nodes(mc->fdt, imsic_name,
+                                   memmap[VIRT_PLATFORM_BUS].base,
+                                   memmap[VIRT_PLATFORM_BUS].size,
+                                   VIRT_PLATFORM_BUS_IRQ);
+
     g_free(imsic_name);
 
     /* S-level IMSIC node */
@@ -683,6 +702,12 @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
         VIRT_IRQCHIP_NUM_SOURCES);
     riscv_socket_fdt_write_id(mc, mc->fdt, aplic_name, socket);
     qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_s_phandle);
+
+    platform_bus_add_all_fdt_nodes(mc->fdt, aplic_name,
+                                   memmap[VIRT_PLATFORM_BUS].base,
+                                   memmap[VIRT_PLATFORM_BUS].size,
+                                   VIRT_PLATFORM_BUS_IRQ);
+
     g_free(aplic_name);
 
     g_free(aplic_cells);
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 5/6] hw/riscv: virt: Add device plug support
  2022-04-07  2:04 [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board Alistair Francis
                   ` (3 preceding siblings ...)
  2022-04-07  2:04 ` [PATCH v2 4/6] hw/riscv: virt: Add support for generateing platform FDT entries Alistair Francis
@ 2022-04-07  2:04 ` Alistair Francis
  2022-04-07  2:04 ` [PATCH v2 6/6] hw/riscv: Enable TPM backends Alistair Francis
  2022-04-07 13:30   ` Edgar E. Iglesias
  6 siblings, 0 replies; 13+ messages in thread
From: Alistair Francis @ 2022-04-07  2:04 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel
  Cc: peter.maydell, qemu-arm, richard.henderson, Edgar E. Iglesias,
	Alistair Francis, alistair23, Palmer Dabbelt, bmeng.cn, Bin Meng,
	Alistair Francis

From: Alistair Francis <alistair.francis@wdc.com>

Add support for plugging in devices, this was tested with the TPM
device.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 hw/riscv/virt.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index eba8495e9a..bec83d26fd 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1564,10 +1564,37 @@ static void virt_set_aclint(Object *obj, bool value, Error **errp)
     s->have_aclint = value;
 }
 
+static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
+                                                        DeviceState *dev)
+{
+    MachineClass *mc = MACHINE_GET_CLASS(machine);
+
+    if (device_is_dynamic_sysbus(mc, dev)) {
+        return HOTPLUG_HANDLER(machine);
+    }
+    return NULL;
+}
+
+static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
+                                        DeviceState *dev, Error **errp)
+{
+    RISCVVirtState *s = RISCV_VIRT_MACHINE(hotplug_dev);
+
+    if (s->platform_bus_dev) {
+        MachineClass *mc = MACHINE_GET_CLASS(s);
+
+        if (device_is_dynamic_sysbus(mc, dev)) {
+            platform_bus_link_device(PLATFORM_BUS_DEVICE(s->platform_bus_dev),
+                                     SYS_BUS_DEVICE(dev));
+        }
+    }
+}
+
 static void virt_machine_class_init(ObjectClass *oc, void *data)
 {
     char str[128];
     MachineClass *mc = MACHINE_CLASS(oc);
+    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
 
     mc->desc = "RISC-V VirtIO board";
     mc->init = virt_machine_init;
@@ -1579,6 +1606,10 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
     mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
     mc->numa_mem_supported = true;
     mc->default_ram_id = "riscv_virt_board.ram";
+    assert(!mc->get_hotplug_handler);
+    mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
+
+    hc->plug = virt_machine_device_plug_cb;
 
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
 
@@ -1609,6 +1640,10 @@ static const TypeInfo virt_machine_typeinfo = {
     .class_init = virt_machine_class_init,
     .instance_init = virt_machine_instance_init,
     .instance_size = sizeof(RISCVVirtState),
+    .interfaces = (InterfaceInfo[]) {
+         { TYPE_HOTPLUG_HANDLER },
+         { }
+    },
 };
 
 static void virt_machine_init_register_types(void)
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2 6/6] hw/riscv: Enable TPM backends
  2022-04-07  2:04 [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board Alistair Francis
                   ` (4 preceding siblings ...)
  2022-04-07  2:04 ` [PATCH v2 5/6] hw/riscv: virt: Add device plug support Alistair Francis
@ 2022-04-07  2:04 ` Alistair Francis
  2022-04-07 13:30   ` Edgar E. Iglesias
  6 siblings, 0 replies; 13+ messages in thread
From: Alistair Francis @ 2022-04-07  2:04 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel
  Cc: peter.maydell, qemu-arm, richard.henderson, Edgar E. Iglesias,
	Alistair Francis, alistair23, Palmer Dabbelt, bmeng.cn, Bin Meng,
	Alistair Francis

From: Alistair Francis <alistair.francis@wdc.com>

Imply the TPM sysbus devices. This allows users to add TPM devices to
the RISC-V virt board.

This was tested by first creating an emulated TPM device:

    swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \
        --ctrl type=unixio,path=swtpm-sock

Then launching QEMU with:

    -chardev socket,id=chrtpm,path=swtpm-sock \
    -tpmdev emulator,id=tpm0,chardev=chrtpm \
    -device tpm-tis-device,tpmdev=tpm0

The TPM device can be seen in the memory tree and the generated device
tree.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/942
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 hw/riscv/virt.c  | 4 ++++
 hw/riscv/Kconfig | 1 +
 2 files changed, 5 insertions(+)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index bec83d26fd..e435b1f118 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -43,6 +43,7 @@
 #include "sysemu/device_tree.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
+#include "sysemu/tpm.h"
 #include "hw/pci/pci.h"
 #include "hw/pci-host/gpex.h"
 #include "hw/display/ramfb.h"
@@ -1612,6 +1613,9 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
     hc->plug = virt_machine_device_plug_cb;
 
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
+#ifdef CONFIG_TPM
+    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
+#endif
 
     object_class_property_add_bool(oc, "aclint", virt_get_aclint,
                                    virt_set_aclint);
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index da790f5936..79ff61c464 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -34,6 +34,7 @@ config RISCV_VIRT
     imply PCI_DEVICES
     imply VIRTIO_VGA
     imply TEST_DEVICES
+    imply TPM_TIS_SYSBUS
     select RISCV_NUMA
     select GOLDFISH_RTC
     select MSI_NONBROKEN
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board
  2022-04-07  2:04 [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board Alistair Francis
@ 2022-04-07 13:30   ` Edgar E. Iglesias
  2022-04-07  2:04 ` [PATCH v2 2/6] hw/core: Move the ARM sysbus-fdt to core Alistair Francis
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Edgar E. Iglesias @ 2022-04-07 13:30 UTC (permalink / raw)
  To: Alistair Francis
  Cc: peter.maydell, Alistair Francis, Bin Meng, qemu-riscv,
	Alistair Francis, richard.henderson, qemu-devel, qemu-arm,
	Palmer Dabbelt, alistair23, bmeng.cn

On Thu, Apr 07, 2022 at 12:04:26PM +1000, Alistair Francis wrote:
> From: Alistair Francis <alistair.francis@wdc.com>
> 
> This series adds support for connecting TPM devices to the RISC-V virt
> board. This is similar to how it works for the ARM virt board.
> 
> This was tested by first creating an emulated TPM device:
> 
>     swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \
>         --ctrl type=unixio,path=swtpm-sock
> 
> Then launching QEMU with:
> 
>     -chardev socket,id=chrtpm,path=swtpm-sock \
>     -tpmdev emulator,id=tpm0,chardev=chrtpm \
>     -device tpm-tis-device,tpmdev=tpm0
> 
> The TPM device can be seen in the memory tree and the generated device
> tree.

Hi Alistair!

You've got a typo in the subject of patch 4/6 "generating".

On the series:
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com>

Cheers,
Edgar


> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/942
> 
> Alistair Francis (6):
>   hw/riscv: virt: Add a machine done notifier
>   hw/core: Move the ARM sysbus-fdt to core
>   hw/riscv: virt: Create a platform bus
>   hw/riscv: virt: Add support for generateing platform FDT entries
>   hw/riscv: virt: Add device plug support
>   hw/riscv: Enable TPM backends
> 
>  include/hw/{arm => core}/sysbus-fdt.h |   0
>  include/hw/riscv/virt.h               |   8 +-
>  hw/arm/virt.c                         |   2 +-
>  hw/arm/xlnx-versal-virt.c             |   1 -
>  hw/{arm => core}/sysbus-fdt.c         |   2 +-
>  hw/riscv/virt.c                       | 312 +++++++++++++++++---------
>  hw/arm/meson.build                    |   1 -
>  hw/core/meson.build                   |   1 +
>  hw/riscv/Kconfig                      |   2 +
>  9 files changed, 221 insertions(+), 108 deletions(-)
>  rename include/hw/{arm => core}/sysbus-fdt.h (100%)
>  rename hw/{arm => core}/sysbus-fdt.c (99%)
> 
> -- 
> 2.35.1
> 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board
@ 2022-04-07 13:30   ` Edgar E. Iglesias
  0 siblings, 0 replies; 13+ messages in thread
From: Edgar E. Iglesias @ 2022-04-07 13:30 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-riscv, qemu-devel, peter.maydell, qemu-arm,
	richard.henderson, Alistair Francis, alistair23, Palmer Dabbelt,
	bmeng.cn, Bin Meng, Alistair Francis

On Thu, Apr 07, 2022 at 12:04:26PM +1000, Alistair Francis wrote:
> From: Alistair Francis <alistair.francis@wdc.com>
> 
> This series adds support for connecting TPM devices to the RISC-V virt
> board. This is similar to how it works for the ARM virt board.
> 
> This was tested by first creating an emulated TPM device:
> 
>     swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \
>         --ctrl type=unixio,path=swtpm-sock
> 
> Then launching QEMU with:
> 
>     -chardev socket,id=chrtpm,path=swtpm-sock \
>     -tpmdev emulator,id=tpm0,chardev=chrtpm \
>     -device tpm-tis-device,tpmdev=tpm0
> 
> The TPM device can be seen in the memory tree and the generated device
> tree.

Hi Alistair!

You've got a typo in the subject of patch 4/6 "generating".

On the series:
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com>

Cheers,
Edgar


> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/942
> 
> Alistair Francis (6):
>   hw/riscv: virt: Add a machine done notifier
>   hw/core: Move the ARM sysbus-fdt to core
>   hw/riscv: virt: Create a platform bus
>   hw/riscv: virt: Add support for generateing platform FDT entries
>   hw/riscv: virt: Add device plug support
>   hw/riscv: Enable TPM backends
> 
>  include/hw/{arm => core}/sysbus-fdt.h |   0
>  include/hw/riscv/virt.h               |   8 +-
>  hw/arm/virt.c                         |   2 +-
>  hw/arm/xlnx-versal-virt.c             |   1 -
>  hw/{arm => core}/sysbus-fdt.c         |   2 +-
>  hw/riscv/virt.c                       | 312 +++++++++++++++++---------
>  hw/arm/meson.build                    |   1 -
>  hw/core/meson.build                   |   1 +
>  hw/riscv/Kconfig                      |   2 +
>  9 files changed, 221 insertions(+), 108 deletions(-)
>  rename include/hw/{arm => core}/sysbus-fdt.h (100%)
>  rename hw/{arm => core}/sysbus-fdt.c (99%)
> 
> -- 
> 2.35.1
> 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 1/6] hw/riscv: virt: Add a machine done notifier
  2022-04-07  2:04 ` [PATCH v2 1/6] hw/riscv: virt: Add a machine done notifier Alistair Francis
@ 2022-04-15 15:25     ` Andrew Bresticker
  0 siblings, 0 replies; 13+ messages in thread
From: Andrew Bresticker @ 2022-04-15 15:25 UTC (permalink / raw)
  To: Alistair Francis
  Cc: peter.maydell, Alistair Francis, Bin Meng, qemu-riscv,
	Alistair Francis, richard.henderson, qemu-devel, qemu-arm,
	Palmer Dabbelt, alistair23, Edgar E. Iglesias, bmeng.cn

Hi Alistair,

On Wed, Apr 6, 2022 at 10:05 PM Alistair Francis
<alistair.francis@opensource.wdc.com> wrote:
>
> From: Alistair Francis <alistair.francis@wdc.com>
>
> Move the binary and device tree loading code to the machine done
> notifier. This allows us to prepare for editing the device tree as part
> of the notifier.
>
> This is based on similar code in the ARM virt machine.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  include/hw/riscv/virt.h |   1 +
>  hw/riscv/virt.c         | 180 +++++++++++++++++++++-------------------
>  2 files changed, 97 insertions(+), 84 deletions(-)
>
> diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> index 78b058ec86..8b8db3fb7c 100644
> --- a/include/hw/riscv/virt.h
> +++ b/include/hw/riscv/virt.h
> @@ -45,6 +45,7 @@ struct RISCVVirtState {
>      MachineState parent;
>
>      /*< public >*/
> +    Notifier machine_done;
>      RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
>      DeviceState *irqchip[VIRT_SOCKETS_MAX];
>      PFlashCFI01 *flash[2];
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index da50cbed43..3f065b540e 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -1156,6 +1156,99 @@ 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;
> +
> +    /* create device tree */
> +    create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
> +               riscv_is_32bit(&s->soc[0]));

Creating the initial FDT in machine_init() is still useful for
allowing guest-loader to add its FDT nodes. Yes it's currently broken
because the FDT is finalized in machine_init(), but it'll remain
broken after this patch :) How about splitting it up like the ARM virt
machine and leaving FDT creation in machine_init() while doing the
dynamic additions / finalization in the machine_done notifier? Happy
to send a separate patch for that if you prefer.

-Andrew

> +
> +    /*
> +     * Only direct boot kernel is currently supported for KVM VM,
> +     * so the "-bios" parameter is ignored and treated like "-bios none"
> +     * when KVM is enabled.
> +     */
> +    if (kvm_enabled()) {
> +        g_free(machine->firmware);
> +        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;
> @@ -1163,10 +1256,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;
>
> @@ -1296,92 +1385,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 ignored and treated like "-bios none"
> -     * when KVM is enabled.
> -     */
> -    if (kvm_enabled()) {
> -        g_free(machine->firmware);
> -        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);
>
> @@ -1417,6 +1426,9 @@ static void virt_machine_init(MachineState *machine)
>                                    drive_get(IF_PFLASH, 0, i));
>      }
>      virt_flash_map(s, system_memory);
> +
> +    s->machine_done.notify = virt_machine_done;
> +    qemu_add_machine_init_done_notifier(&s->machine_done);
>  }
>
>  static void virt_machine_instance_init(Object *obj)
> --
> 2.35.1
>
>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 1/6] hw/riscv: virt: Add a machine done notifier
@ 2022-04-15 15:25     ` Andrew Bresticker
  0 siblings, 0 replies; 13+ messages in thread
From: Andrew Bresticker @ 2022-04-15 15:25 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-riscv, qemu-devel, peter.maydell, qemu-arm,
	richard.henderson, Edgar E. Iglesias, Alistair Francis,
	alistair23, Palmer Dabbelt, bmeng.cn, Bin Meng, Alistair Francis

Hi Alistair,

On Wed, Apr 6, 2022 at 10:05 PM Alistair Francis
<alistair.francis@opensource.wdc.com> wrote:
>
> From: Alistair Francis <alistair.francis@wdc.com>
>
> Move the binary and device tree loading code to the machine done
> notifier. This allows us to prepare for editing the device tree as part
> of the notifier.
>
> This is based on similar code in the ARM virt machine.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  include/hw/riscv/virt.h |   1 +
>  hw/riscv/virt.c         | 180 +++++++++++++++++++++-------------------
>  2 files changed, 97 insertions(+), 84 deletions(-)
>
> diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> index 78b058ec86..8b8db3fb7c 100644
> --- a/include/hw/riscv/virt.h
> +++ b/include/hw/riscv/virt.h
> @@ -45,6 +45,7 @@ struct RISCVVirtState {
>      MachineState parent;
>
>      /*< public >*/
> +    Notifier machine_done;
>      RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
>      DeviceState *irqchip[VIRT_SOCKETS_MAX];
>      PFlashCFI01 *flash[2];
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index da50cbed43..3f065b540e 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -1156,6 +1156,99 @@ 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;
> +
> +    /* create device tree */
> +    create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
> +               riscv_is_32bit(&s->soc[0]));

Creating the initial FDT in machine_init() is still useful for
allowing guest-loader to add its FDT nodes. Yes it's currently broken
because the FDT is finalized in machine_init(), but it'll remain
broken after this patch :) How about splitting it up like the ARM virt
machine and leaving FDT creation in machine_init() while doing the
dynamic additions / finalization in the machine_done notifier? Happy
to send a separate patch for that if you prefer.

-Andrew

> +
> +    /*
> +     * Only direct boot kernel is currently supported for KVM VM,
> +     * so the "-bios" parameter is ignored and treated like "-bios none"
> +     * when KVM is enabled.
> +     */
> +    if (kvm_enabled()) {
> +        g_free(machine->firmware);
> +        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;
> @@ -1163,10 +1256,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;
>
> @@ -1296,92 +1385,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 ignored and treated like "-bios none"
> -     * when KVM is enabled.
> -     */
> -    if (kvm_enabled()) {
> -        g_free(machine->firmware);
> -        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);
>
> @@ -1417,6 +1426,9 @@ static void virt_machine_init(MachineState *machine)
>                                    drive_get(IF_PFLASH, 0, i));
>      }
>      virt_flash_map(s, system_memory);
> +
> +    s->machine_done.notify = virt_machine_done;
> +    qemu_add_machine_init_done_notifier(&s->machine_done);
>  }
>
>  static void virt_machine_instance_init(Object *obj)
> --
> 2.35.1
>
>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 1/6] hw/riscv: virt: Add a machine done notifier
  2022-04-15 15:25     ` Andrew Bresticker
@ 2022-04-19  4:50       ` Alistair Francis
  -1 siblings, 0 replies; 13+ messages in thread
From: Alistair Francis @ 2022-04-19  4:50 UTC (permalink / raw)
  To: Andrew Bresticker
  Cc: Peter Maydell, Alistair Francis, Bin Meng, open list:RISC-V,
	Alistair Francis, Richard Henderson,
	qemu-devel@nongnu.org Developers, qemu-arm, Alistair Francis,
	Edgar E. Iglesias, Bin Meng, Palmer Dabbelt

On Sat, Apr 16, 2022 at 1:25 AM Andrew Bresticker <abrestic@rivosinc.com> wrote:
>
> Hi Alistair,
>
> On Wed, Apr 6, 2022 at 10:05 PM Alistair Francis
> <alistair.francis@opensource.wdc.com> wrote:
> >
> > From: Alistair Francis <alistair.francis@wdc.com>
> >
> > Move the binary and device tree loading code to the machine done
> > notifier. This allows us to prepare for editing the device tree as part
> > of the notifier.
> >
> > This is based on similar code in the ARM virt machine.
> >
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> >  include/hw/riscv/virt.h |   1 +
> >  hw/riscv/virt.c         | 180 +++++++++++++++++++++-------------------
> >  2 files changed, 97 insertions(+), 84 deletions(-)
> >
> > diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> > index 78b058ec86..8b8db3fb7c 100644
> > --- a/include/hw/riscv/virt.h
> > +++ b/include/hw/riscv/virt.h
> > @@ -45,6 +45,7 @@ struct RISCVVirtState {
> >      MachineState parent;
> >
> >      /*< public >*/
> > +    Notifier machine_done;
> >      RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
> >      DeviceState *irqchip[VIRT_SOCKETS_MAX];
> >      PFlashCFI01 *flash[2];
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index da50cbed43..3f065b540e 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -1156,6 +1156,99 @@ 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;
> > +
> > +    /* create device tree */
> > +    create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
> > +               riscv_is_32bit(&s->soc[0]));
>
> Creating the initial FDT in machine_init() is still useful for
> allowing guest-loader to add its FDT nodes. Yes it's currently broken
> because the FDT is finalized in machine_init(), but it'll remain
> broken after this patch :) How about splitting it up like the ARM virt
> machine and leaving FDT creation in machine_init() while doing the
> dynamic additions / finalization in the machine_done notifier? Happy
> to send a separate patch for that if you prefer.

Good point. I have left the create_fdt() call in machine_init(). Feel
free to add support for guest-loader editing FDT nodes

Alistair

>
> -Andrew
>
> > +
> > +    /*
> > +     * Only direct boot kernel is currently supported for KVM VM,
> > +     * so the "-bios" parameter is ignored and treated like "-bios none"
> > +     * when KVM is enabled.
> > +     */
> > +    if (kvm_enabled()) {
> > +        g_free(machine->firmware);
> > +        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;
> > @@ -1163,10 +1256,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;
> >
> > @@ -1296,92 +1385,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 ignored and treated like "-bios none"
> > -     * when KVM is enabled.
> > -     */
> > -    if (kvm_enabled()) {
> > -        g_free(machine->firmware);
> > -        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);
> >
> > @@ -1417,6 +1426,9 @@ static void virt_machine_init(MachineState *machine)
> >                                    drive_get(IF_PFLASH, 0, i));
> >      }
> >      virt_flash_map(s, system_memory);
> > +
> > +    s->machine_done.notify = virt_machine_done;
> > +    qemu_add_machine_init_done_notifier(&s->machine_done);
> >  }
> >
> >  static void virt_machine_instance_init(Object *obj)
> > --
> > 2.35.1
> >
> >


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 1/6] hw/riscv: virt: Add a machine done notifier
@ 2022-04-19  4:50       ` Alistair Francis
  0 siblings, 0 replies; 13+ messages in thread
From: Alistair Francis @ 2022-04-19  4:50 UTC (permalink / raw)
  To: Andrew Bresticker
  Cc: Alistair Francis, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Peter Maydell, qemu-arm,
	Richard Henderson, Edgar E. Iglesias, Alistair Francis,
	Palmer Dabbelt, Bin Meng, Bin Meng, Alistair Francis

On Sat, Apr 16, 2022 at 1:25 AM Andrew Bresticker <abrestic@rivosinc.com> wrote:
>
> Hi Alistair,
>
> On Wed, Apr 6, 2022 at 10:05 PM Alistair Francis
> <alistair.francis@opensource.wdc.com> wrote:
> >
> > From: Alistair Francis <alistair.francis@wdc.com>
> >
> > Move the binary and device tree loading code to the machine done
> > notifier. This allows us to prepare for editing the device tree as part
> > of the notifier.
> >
> > This is based on similar code in the ARM virt machine.
> >
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> >  include/hw/riscv/virt.h |   1 +
> >  hw/riscv/virt.c         | 180 +++++++++++++++++++++-------------------
> >  2 files changed, 97 insertions(+), 84 deletions(-)
> >
> > diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> > index 78b058ec86..8b8db3fb7c 100644
> > --- a/include/hw/riscv/virt.h
> > +++ b/include/hw/riscv/virt.h
> > @@ -45,6 +45,7 @@ struct RISCVVirtState {
> >      MachineState parent;
> >
> >      /*< public >*/
> > +    Notifier machine_done;
> >      RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
> >      DeviceState *irqchip[VIRT_SOCKETS_MAX];
> >      PFlashCFI01 *flash[2];
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index da50cbed43..3f065b540e 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -1156,6 +1156,99 @@ 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;
> > +
> > +    /* create device tree */
> > +    create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
> > +               riscv_is_32bit(&s->soc[0]));
>
> Creating the initial FDT in machine_init() is still useful for
> allowing guest-loader to add its FDT nodes. Yes it's currently broken
> because the FDT is finalized in machine_init(), but it'll remain
> broken after this patch :) How about splitting it up like the ARM virt
> machine and leaving FDT creation in machine_init() while doing the
> dynamic additions / finalization in the machine_done notifier? Happy
> to send a separate patch for that if you prefer.

Good point. I have left the create_fdt() call in machine_init(). Feel
free to add support for guest-loader editing FDT nodes

Alistair

>
> -Andrew
>
> > +
> > +    /*
> > +     * Only direct boot kernel is currently supported for KVM VM,
> > +     * so the "-bios" parameter is ignored and treated like "-bios none"
> > +     * when KVM is enabled.
> > +     */
> > +    if (kvm_enabled()) {
> > +        g_free(machine->firmware);
> > +        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;
> > @@ -1163,10 +1256,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;
> >
> > @@ -1296,92 +1385,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 ignored and treated like "-bios none"
> > -     * when KVM is enabled.
> > -     */
> > -    if (kvm_enabled()) {
> > -        g_free(machine->firmware);
> > -        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);
> >
> > @@ -1417,6 +1426,9 @@ static void virt_machine_init(MachineState *machine)
> >                                    drive_get(IF_PFLASH, 0, i));
> >      }
> >      virt_flash_map(s, system_memory);
> > +
> > +    s->machine_done.notify = virt_machine_done;
> > +    qemu_add_machine_init_done_notifier(&s->machine_done);
> >  }
> >
> >  static void virt_machine_instance_init(Object *obj)
> > --
> > 2.35.1
> >
> >


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2022-04-19  4:52 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-07  2:04 [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board Alistair Francis
2022-04-07  2:04 ` [PATCH v2 1/6] hw/riscv: virt: Add a machine done notifier Alistair Francis
2022-04-15 15:25   ` Andrew Bresticker
2022-04-15 15:25     ` Andrew Bresticker
2022-04-19  4:50     ` Alistair Francis
2022-04-19  4:50       ` Alistair Francis
2022-04-07  2:04 ` [PATCH v2 2/6] hw/core: Move the ARM sysbus-fdt to core Alistair Francis
2022-04-07  2:04 ` [PATCH v2 3/6] hw/riscv: virt: Create a platform bus Alistair Francis
2022-04-07  2:04 ` [PATCH v2 4/6] hw/riscv: virt: Add support for generateing platform FDT entries Alistair Francis
2022-04-07  2:04 ` [PATCH v2 5/6] hw/riscv: virt: Add device plug support Alistair Francis
2022-04-07  2:04 ` [PATCH v2 6/6] hw/riscv: Enable TPM backends Alistair Francis
2022-04-07 13:30 ` [PATCH v2 0/6] hw/riscv: Add TPM support to the virt board Edgar E. Iglesias
2022-04-07 13:30   ` Edgar E. Iglesias

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.