On Tue, Jun 16, 2026 at 6:39 AM Daniel Henrique Barboza
<[email protected]> wrote:
>
> There's too much duplication between RISC-V boards and one of the most
> common culprits is the FDT functions.
>
> Add a new file for board FDT helpers.  Start by creating a helper that
> initializes the FDT and init it with the common board boilerplate.
>
> Signed-off-by: Daniel Henrique Barboza <[email protected]>

Reviewed-by: Alistair Francis <[email protected]>

Alistair

> ---
>  hw/riscv/fdt-common.c         | 37 +++++++++++++++++++++++++++++++++++
>  hw/riscv/meson.build          |  1 +
>  hw/riscv/sifive_u.c           | 20 +++----------------
>  hw/riscv/spike.c              | 19 +++---------------
>  hw/riscv/virt.c               | 19 +++---------------
>  include/hw/riscv/fdt-common.h | 14 +++++++++++++
>  6 files changed, 61 insertions(+), 49 deletions(-)
>  create mode 100644 hw/riscv/fdt-common.c
>  create mode 100644 include/hw/riscv/fdt-common.h
>
> diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c
> new file mode 100644
> index 0000000000..b155246998
> --- /dev/null
> +++ b/hw/riscv/fdt-common.c
> @@ -0,0 +1,37 @@
> +/*
> + * RISC-V board helpers for FDT generation.
> + *
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +
> +#include "qemu/error-report.h"
> +#include "system/device_tree.h"
> +#include "hw/riscv/fdt-common.h"
> +
> +void *create_board_device_tree(const char *model, const char *compatible,
> +                               int *fdt_size)
> +{
> +    void *fdt = create_device_tree(fdt_size);
> +
> +    if (!fdt) {
> +        error_report("create_device_tree() failed");
> +        exit(1);
> +    }
> +
> +    qemu_fdt_setprop_string(fdt, "/", "model", model);
> +    qemu_fdt_setprop_string(fdt, "/", "compatible", compatible);
> +    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
> +    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
> +
> +    qemu_fdt_add_subnode(fdt, "/soc");
> +    qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
> +    qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus");
> +    qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
> +    qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
> +
> +    return fdt;
> +}
> diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
> index 533472e22a..f19db0dd7f 100644
> --- a/hw/riscv/meson.build
> +++ b/hw/riscv/meson.build
> @@ -1,5 +1,6 @@
>  riscv_ss = ss.source_set()
>  riscv_ss.add(files('boot.c'))
> +riscv_ss.add(files('fdt-common.c'))
>  riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: files('numa.c'))
>  riscv_ss.add(files('riscv_hart.c'))
>  riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c'))
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 3abbd6c823..5d3b2751ad 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -52,6 +52,7 @@
>  #include "hw/riscv/sifive_u.h"
>  #include "hw/riscv/boot.h"
>  #include "hw/riscv/machines-qom.h"
> +#include "hw/riscv/fdt-common.h"
>  #include "hw/char/sifive_uart.h"
>  #include "hw/intc/riscv_aclint.h"
>  #include "hw/intc/sifive_plic.h"
> @@ -112,23 +113,8 @@ static void create_fdt(SiFiveUState *s, const 
> MemMapEntry *memmap,
>          "sifive,plic-1.0.0", "riscv,plic0"
>      };
>
> -    fdt = ms->fdt = create_device_tree(&s->fdt_size);
> -    if (!fdt) {
> -        error_report("create_device_tree() failed");
> -        exit(1);
> -    }
> -
> -    qemu_fdt_setprop_string(fdt, "/", "model", "SiFive HiFive Unleashed 
> A00");
> -    qemu_fdt_setprop_string(fdt, "/", "compatible",
> -                            "sifive,hifive-unleashed-a00");
> -    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
> -    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
> -
> -    qemu_fdt_add_subnode(fdt, "/soc");
> -    qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
> -    qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus");
> -    qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
> -    qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
> +    fdt = ms->fdt = create_board_device_tree("SiFive HiFive Unleashed A00",
> +        "sifive,hifive-unleashed-a00", &s->fdt_size);
>
>      hfclk_phandle = phandle++;
>      nodename = g_strdup_printf("/hfclk");
> diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
> index f9d00e0d5c..79c9bb041f 100644
> --- a/hw/riscv/spike.c
> +++ b/hw/riscv/spike.c
> @@ -32,6 +32,7 @@
>  #include "hw/riscv/riscv_hart.h"
>  #include "hw/riscv/spike.h"
>  #include "hw/riscv/boot.h"
> +#include "hw/riscv/fdt-common.h"
>  #include "hw/riscv/numa.h"
>  #include "hw/riscv/machines-qom.h"
>  #include "hw/char/riscv_htif.h"
> @@ -66,16 +67,8 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
> *memmap,
>          "sifive,clint0", "riscv,clint0"
>      };
>
> -    fdt = ms->fdt = create_device_tree(&fdt_size);
> -    if (!fdt) {
> -        error_report("create_device_tree() failed");
> -        exit(1);
> -    }
> -
> -    qemu_fdt_setprop_string(fdt, "/", "model", "ucbbar,spike-bare,qemu");
> -    qemu_fdt_setprop_string(fdt, "/", "compatible", "ucbbar,spike-bare-dev");
> -    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
> -    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
> +    fdt = ms->fdt = create_board_device_tree("ucbbar,spike-bare,qemu",
> +        "ucbbar,spike-bare-dev", &fdt_size);
>
>      qemu_fdt_add_subnode(fdt, "/htif");
>      qemu_fdt_setprop_string(fdt, "/htif", "compatible", "ucb,htif0");
> @@ -84,12 +77,6 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
> *memmap,
>              0x0, memmap[SPIKE_HTIF].base, 0x0, memmap[SPIKE_HTIF].size);
>      }
>
> -    qemu_fdt_add_subnode(fdt, "/soc");
> -    qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
> -    qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus");
> -    qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
> -    qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
> -
>      qemu_fdt_add_subnode(fdt, "/cpus");
>      qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency",
>          RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 0c489bb412..cb1d83fd48 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -36,6 +36,7 @@
>  #include "hw/riscv/riscv-iommu-bits.h"
>  #include "hw/riscv/virt.h"
>  #include "hw/riscv/boot.h"
> +#include "hw/riscv/fdt-common.h"
>  #include "hw/riscv/machines-qom.h"
>  #include "hw/riscv/numa.h"
>  #include "kvm/kvm_riscv.h"
> @@ -1150,22 +1151,8 @@ static void create_fdt(RISCVVirtState *s)
>      uint8_t rng_seed[32];
>      g_autofree char *name = NULL;
>
> -    ms->fdt = create_device_tree(&s->fdt_size);
> -    if (!ms->fdt) {
> -        error_report("create_device_tree() failed");
> -        exit(1);
> -    }
> -
> -    qemu_fdt_setprop_string(ms->fdt, "/", "model", "riscv-virtio,qemu");
> -    qemu_fdt_setprop_string(ms->fdt, "/", "compatible", "riscv-virtio");
> -    qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2);
> -    qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2);
> -
> -    qemu_fdt_add_subnode(ms->fdt, "/soc");
> -    qemu_fdt_setprop(ms->fdt, "/soc", "ranges", NULL, 0);
> -    qemu_fdt_setprop_string(ms->fdt, "/soc", "compatible", "simple-bus");
> -    qemu_fdt_setprop_cell(ms->fdt, "/soc", "#size-cells", 0x2);
> -    qemu_fdt_setprop_cell(ms->fdt, "/soc", "#address-cells", 0x2);
> +    ms->fdt = create_board_device_tree("riscv-virtio,qemu", "riscv-virtio",
> +                                       &s->fdt_size);
>
>      /*
>       * The "/soc/pci@..." node is needed for PCIE hotplugs
> diff --git a/include/hw/riscv/fdt-common.h b/include/hw/riscv/fdt-common.h
> new file mode 100644
> index 0000000000..adf9b33dfd
> --- /dev/null
> +++ b/include/hw/riscv/fdt-common.h
> @@ -0,0 +1,14 @@
> +/*
> + * RISC-V board helpers for FDT generation.
> + *
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef RISCV_VIRT_FDT_H
> +#define RISCV_VIRT_FDT_H
> +
> +void *create_board_device_tree(const char *model, const char *compatible,
> +                               int *fdt_size);
> +#endif
> --
> 2.43.0
>
>

Reply via email to