On Tue, Jun 16, 2026 at 6:42 AM Daniel Henrique Barboza
<[email protected]> wrote:
>
> Move all clint FDT generation to fdt-common.c reducing code repetition.
>
> Signed-off-by: Daniel Henrique Barboza <[email protected]>

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

Alistair

> ---
>  hw/riscv/fdt-common.c         | 33 +++++++++++++++++++++++++
>  hw/riscv/sifive_u.c           | 25 +++----------------
>  hw/riscv/spike.c              | 31 ++++-------------------
>  hw/riscv/virt.c               | 46 ++++++-----------------------------
>  include/hw/riscv/fdt-common.h |  5 ++++
>  5 files changed, 54 insertions(+), 86 deletions(-)
>
> diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c
> index 719c36e001..d2661ec389 100644
> --- a/hw/riscv/fdt-common.c
> +++ b/hw/riscv/fdt-common.c
> @@ -12,6 +12,7 @@
>  #include "system/device_tree.h"
>  #include "hw/core/boards.h"
>  #include "hw/riscv/fdt-common.h"
> +#include "target/riscv/cpu_bits.h"
>
>  void *create_board_device_tree(const char *model, const char *compatible,
>                                 int *fdt_size)
> @@ -50,3 +51,35 @@ void create_fdt_socket_memory(void *fdt, hwaddr addr, 
> uint64_t size,
>          qemu_fdt_setprop_cell(fdt, mem_name, "numa-node-id", socket_id);
>      }
>  }
> +
> +void create_fdt_socket_clint(void *fdt, hwaddr addr, uint64_t size,
> +                             int socket_id, uint32_t *intc_phandles,
> +                             int num_harts, bool numa_enabled)
> +{
> +    g_autofree uint32_t *clint_cells = g_new0(uint32_t, num_harts * 4);
> +    g_autofree char *clint_name = NULL;
> +    static const char * const clint_compat[2] = {
> +        "sifive,clint0", "riscv,clint0"
> +    };
> +
> +    for (int cpu = 0; cpu < num_harts; cpu++) {
> +        clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
> +        clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
> +        clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
> +        clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
> +    }
> +
> +    clint_name = g_strdup_printf("/soc/clint@%"HWADDR_PRIx, addr);
> +    qemu_fdt_add_subnode(fdt, clint_name);
> +    qemu_fdt_setprop_string_array(fdt, clint_name, "compatible",
> +                                  (char **)&clint_compat,
> +                                  ARRAY_SIZE(clint_compat));
> +    qemu_fdt_setprop_sized_cells(fdt, clint_name, "reg",
> +                                 2, addr, 2, size);
> +    qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
> +                     clint_cells, num_harts * sizeof(uint32_t) * 4);
> +
> +    if (numa_enabled) {
> +        qemu_fdt_setprop_cell(fdt, clint_name, "numa-node-id", socket_id);
> +    }
> +}
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index ce86989bc8..9a791b36d6 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -105,9 +105,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
> *memmap,
>      uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
>      uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
>      static const char * const ethclk_names[2] = { "pclk", "hclk" };
> -    static const char * const clint_compat[2] = {
> -        "sifive,clint0", "riscv,clint0"
> -    };
>      static const char * const plic_compat[2] = {
>          "sifive,plic-1.0.0", "riscv,plic0"
>      };
> @@ -180,25 +177,9 @@ static void create_fdt(SiFiveUState *s, const 
> MemMapEntry *memmap,
>          g_free(nodename);
>      }
>
> -    cells =  g_new0(uint32_t, ms->smp.cpus * 4);
> -    for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
> -        cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
> -        cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
> -        cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
> -        cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
> -    }
> -    nodename = g_strdup_printf("/soc/clint@%lx",
> -        (long)memmap[SIFIVE_U_DEV_CLINT].base);
> -    qemu_fdt_add_subnode(fdt, nodename);
> -    qemu_fdt_setprop_string_array(fdt, nodename, "compatible",
> -        (char **)&clint_compat, ARRAY_SIZE(clint_compat));
> -    qemu_fdt_setprop_cells(fdt, nodename, "reg",
> -        0x0, memmap[SIFIVE_U_DEV_CLINT].base,
> -        0x0, memmap[SIFIVE_U_DEV_CLINT].size);
> -    qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
> -        cells, ms->smp.cpus * sizeof(uint32_t) * 4);
> -    g_free(cells);
> -    g_free(nodename);
> +    create_fdt_socket_clint(fdt, memmap[SIFIVE_U_DEV_CLINT].base,
> +                            memmap[SIFIVE_U_DEV_CLINT].size, 0,
> +                            intc_phandles, ms->smp.cpus, false);
>
>      nodename = g_strdup_printf("/soc/otp@%lx",
>          (long)memmap[SIFIVE_U_DEV_OTP].base);
> diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
> index 82005ec163..b15188fb07 100644
> --- a/hw/riscv/spike.c
> +++ b/hw/riscv/spike.c
> @@ -58,13 +58,10 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
> *memmap,
>      unsigned long clint_addr;
>      int cpu, socket;
>      MachineState *ms = MACHINE(s);
> -    uint32_t *clint_cells;
>      uint32_t cpu_phandle, phandle = 1;
> -    char *clint_name, *clust_name;
> +    char *clust_name;
>      char *core_name, *cpu_name, *intc_name;
> -    static const char * const clint_compat[2] = {
> -        "sifive,clint0", "riscv,clint0"
> -    };
> +    bool numa_enabled = riscv_numa_enabled(ms);
>
>      fdt = ms->fdt = create_board_device_tree("ucbbar,spike-bare,qemu",
>          "ucbbar,spike-bare-dev", &fdt_size);
> @@ -136,29 +133,11 @@ static void create_fdt(SpikeState *s, const MemMapEntry 
> *memmap,
>          create_fdt_socket_memory(fdt, memaddr, memsize, socket,
>                                   riscv_numa_enabled(ms));
>
> -        clint_cells =  g_new0(uint32_t, s->soc[socket].num_harts * 4);
> -
> -        for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
> -            clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
> -            clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
> -            clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
> -            clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
> -        }
> -
>          clint_addr = memmap[SPIKE_CLINT].base +
>              (memmap[SPIKE_CLINT].size * socket);
> -        clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr);
> -        qemu_fdt_add_subnode(fdt, clint_name);
> -        qemu_fdt_setprop_string_array(fdt, clint_name, "compatible",
> -            (char **)&clint_compat, ARRAY_SIZE(clint_compat));
> -        qemu_fdt_setprop_cells(fdt, clint_name, "reg",
> -            0x0, clint_addr, 0x0, memmap[SPIKE_CLINT].size);
> -        qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
> -            clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
> -        riscv_socket_fdt_write_id(ms, clint_name, socket);
> -
> -        g_free(clint_name);
> -        g_free(clint_cells);
> +        create_fdt_socket_clint(fdt, clint_addr, memmap[SPIKE_CLINT].size,
> +                                socket, intc_phandles,
> +                                s->soc[socket].num_harts, numa_enabled);
>          g_free(clust_name);
>      }
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index df3eadef78..b134f11266 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -302,42 +302,6 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, 
> int socket,
>      }
>  }
>
> -static void create_fdt_socket_clint(RISCVVirtState *s,
> -                                    int socket,
> -                                    uint32_t *intc_phandles)
> -{
> -    int cpu;
> -    g_autofree char *clint_name = NULL;
> -    g_autofree uint32_t *clint_cells = NULL;
> -    hwaddr clint_addr;
> -    MachineState *ms = MACHINE(s);
> -    static const char * const clint_compat[2] = {
> -        "sifive,clint0", "riscv,clint0"
> -    };
> -
> -    clint_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
> -
> -    for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
> -        clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
> -        clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
> -        clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
> -        clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
> -    }
> -
> -    clint_addr = s->memmap[VIRT_CLINT].base +
> -                 s->memmap[VIRT_CLINT].size * socket;
> -    clint_name = g_strdup_printf("/soc/clint@%"HWADDR_PRIx, clint_addr);
> -    qemu_fdt_add_subnode(ms->fdt, clint_name);
> -    qemu_fdt_setprop_string_array(ms->fdt, clint_name, "compatible",
> -                                  (char **)&clint_compat,
> -                                  ARRAY_SIZE(clint_compat));
> -    qemu_fdt_setprop_sized_cells(ms->fdt, clint_name, "reg",
> -        2, clint_addr, 2, s->memmap[VIRT_CLINT].size);
> -    qemu_fdt_setprop(ms->fdt, clint_name, "interrupts-extended",
> -        clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
> -    riscv_socket_fdt_write_id(ms, clint_name, socket);
> -}
> -
>  static void create_fdt_socket_aclint(RISCVVirtState *s,
>                                       int socket,
>                                       uint32_t *intc_phandles)
> @@ -728,6 +692,7 @@ static void create_fdt_sockets(RISCVVirtState *s,
>      uint32_t xplic_phandles[MAX_NODES];
>      g_autofree uint32_t *intc_phandles = NULL;
>      int socket_count = riscv_socket_count(ms);
> +    bool numa_enabled = riscv_numa_enabled(ms);
>
>      qemu_fdt_add_subnode(ms->fdt, "/cpus");
>      qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
> @@ -762,8 +727,13 @@ static void create_fdt_sockets(RISCVVirtState *s,
>              create_fdt_socket_aclint(s, socket,
>                                       &intc_phandles[phandle_pos]);
>          } else if (tcg_enabled()) {
> -            create_fdt_socket_clint(s, socket,
> -                                    &intc_phandles[phandle_pos]);
> +            hwaddr clintaddr = s->memmap[VIRT_CLINT].base +
> +                               s->memmap[VIRT_CLINT].size * socket;
> +
> +            create_fdt_socket_clint(ms->fdt, clintaddr,
> +                                    s->memmap[VIRT_CLINT].size,
> +                                    socket, &intc_phandles[phandle_pos],
> +                                    s->soc[socket].num_harts, numa_enabled);
>          }
>      }
>
> diff --git a/include/hw/riscv/fdt-common.h b/include/hw/riscv/fdt-common.h
> index 81689f418b..6e81d6cd6c 100644
> --- a/include/hw/riscv/fdt-common.h
> +++ b/include/hw/riscv/fdt-common.h
> @@ -13,4 +13,9 @@ void *create_board_device_tree(const char *model, const 
> char *compatible,
>                                 int *fdt_size);
>  void create_fdt_socket_memory(void *fdt, hwaddr addr, uint64_t size,
>                                int socket_id, bool numa_enabled);
> +void create_fdt_clint(void *fdt, hwaddr addr, uint64_t size,
> +                      uint32_t *intc_phandles, int num_harts);
> +void create_fdt_socket_clint(void *fdt, hwaddr addr, uint64_t size,
> +                             int socket_id, uint32_t *intc_phandles,
> +                             int num_harts, bool numa_enabled);
>  #endif
> --
> 2.43.0
>
>

Reply via email to