qemu-riscv
[Top][All Lists]
Advanced

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

Re: [PATCH for-8.2] hw/riscv/virt.c: do create_fdt() earlier, add finali


From: Alistair Francis
Subject: Re: [PATCH for-8.2] hw/riscv/virt.c: do create_fdt() earlier, add finalize_fdt()
Date: Tue, 21 Nov 2023 13:44:05 +1000

On Sat, Nov 11, 2023 at 3:26 AM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:
>
> Commit 49554856f0 fixed a problem, where TPM devices were not appearing
> in the FDT, by delaying the FDT creation up until virt_machine_done().
> This create a side effect (see gitlab #1925) - devices that need access
> to the '/chosen' FDT node during realize() stopped working because, at
> that point, we don't have a FDT.
>
> This happens because our FDT creation is monolithic, but it doesn't need
> to be. We can add the needed FDT components for realize() time and, at
> the same time, do another FDT round where we account for dynamic sysbus
> devices.  In other words, the problem fixed by 49554856f0 could also be
> fixed by postponing only create_fdt_sockets() and its dependencies,
> leaving everything else from create_fdt() to be done during init().
>
> Split the FDT creation in two parts:
>
> - create_fdt(), now moved back to virt_machine_init(), will create FDT
>   nodes that doesn't depend on additional (dynamic) devices from the
>   sysbus;
>
> - a new finalize_fdt() step is added, where create_fdt_sockets() and
>   friends is executed, accounting for the dynamic sysbus devices that
>   were added during realize().
>
> This will make both use cases happy: TPM devices are still working as
> intended, and devices such as 'guest-loader' have a FDT to work on
> during realize().
>
> Fixes: 49554856f0 ("riscv: Generate devicetree only after machine 
> initialization is complete")
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1925
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  hw/riscv/virt.c | 71 +++++++++++++++++++++++++++++--------------------
>  1 file changed, 42 insertions(+), 29 deletions(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index c7fc97e273..d2eac24156 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -962,7 +962,6 @@ static void create_fdt_uart(RISCVVirtState *s, const 
> MemMapEntry *memmap,
>          qemu_fdt_setprop_cells(ms->fdt, name, "interrupts", UART0_IRQ, 0x4);
>      }
>
> -    qemu_fdt_add_subnode(ms->fdt, "/chosen");
>      qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", name);
>      g_free(name);
>  }
> @@ -1023,11 +1022,29 @@ static void create_fdt_fw_cfg(RISCVVirtState *s, 
> const MemMapEntry *memmap)
>      g_free(nodename);
>  }
>
> -static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
> +static void finalize_fdt(RISCVVirtState *s)
>  {
> -    MachineState *ms = MACHINE(s);
>      uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
>      uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1;
> +
> +    create_fdt_sockets(s, virt_memmap, &phandle, &irq_mmio_phandle,
> +                       &irq_pcie_phandle, &irq_virtio_phandle,
> +                       &msi_pcie_phandle);
> +
> +    create_fdt_virtio(s, virt_memmap, irq_virtio_phandle);
> +
> +    create_fdt_pcie(s, virt_memmap, irq_pcie_phandle, msi_pcie_phandle);
> +
> +    create_fdt_reset(s, virt_memmap, &phandle);
> +
> +    create_fdt_uart(s, virt_memmap, irq_mmio_phandle);
> +
> +    create_fdt_rtc(s, virt_memmap, irq_mmio_phandle);
> +}
> +
> +static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
> +{
> +    MachineState *ms = MACHINE(s);
>      uint8_t rng_seed[32];
>
>      ms->fdt = create_device_tree(&s->fdt_size);
> @@ -1047,28 +1064,16 @@ static void create_fdt(RISCVVirtState *s, const 
> MemMapEntry *memmap)
>      qemu_fdt_setprop_cell(ms->fdt, "/soc", "#size-cells", 0x2);
>      qemu_fdt_setprop_cell(ms->fdt, "/soc", "#address-cells", 0x2);
>
> -    create_fdt_sockets(s, memmap, &phandle, &irq_mmio_phandle,
> -                       &irq_pcie_phandle, &irq_virtio_phandle,
> -                       &msi_pcie_phandle);
> -
> -    create_fdt_virtio(s, memmap, irq_virtio_phandle);
> -
> -    create_fdt_pcie(s, memmap, irq_pcie_phandle, msi_pcie_phandle);
> -
> -    create_fdt_reset(s, memmap, &phandle);
> -
> -    create_fdt_uart(s, memmap, irq_mmio_phandle);
> -
> -    create_fdt_rtc(s, memmap, irq_mmio_phandle);
> -
> -    create_fdt_flash(s, memmap);
> -    create_fdt_fw_cfg(s, memmap);
> -    create_fdt_pmu(s);
> +    qemu_fdt_add_subnode(ms->fdt, "/chosen");
>
>      /* Pass seed to RNG */
>      qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
>      qemu_fdt_setprop(ms->fdt, "/chosen", "rng-seed",
>                       rng_seed, sizeof(rng_seed));
> +
> +    create_fdt_flash(s, memmap);
> +    create_fdt_fw_cfg(s, memmap);
> +    create_fdt_pmu(s);
>  }
>
>  static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
> @@ -1257,15 +1262,12 @@ static void virt_machine_done(Notifier *notifier, 
> void *data)
>      uint64_t kernel_entry = 0;
>      BlockBackend *pflash_blk0;
>
> -    /* load/create device tree */
> -    if (machine->dtb) {
> -        machine->fdt = load_device_tree(machine->dtb, &s->fdt_size);
> -        if (!machine->fdt) {
> -            error_report("load_device_tree() failed");
> -            exit(1);
> -        }
> -    } else {
> -        create_fdt(s, memmap);
> +    /*
> +     * An user provided dtb must include everything, including
> +     * dynamic sysbus devices. Our FDT needs to be finalized.
> +     */
> +    if (machine->dtb == NULL) {
> +        finalize_fdt(s);
>      }
>
>      /*
> @@ -1541,6 +1543,17 @@ static void virt_machine_init(MachineState *machine)
>      }
>      virt_flash_map(s, system_memory);
>
> +    /* load/create device tree */
> +    if (machine->dtb) {
> +        machine->fdt = load_device_tree(machine->dtb, &s->fdt_size);
> +        if (!machine->fdt) {
> +            error_report("load_device_tree() failed");
> +            exit(1);
> +        }
> +    } else {
> +        create_fdt(s, memmap);
> +    }
> +
>      s->machine_done.notify = virt_machine_done;
>      qemu_add_machine_init_done_notifier(&s->machine_done);
>  }
> --
> 2.41.0
>
>



reply via email to

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