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 > >
