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