Commit 0d37a88d47 for qemu.org

commit 0d37a88d474e7c2f15d4698ce99e84c836100d20
Author: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Date:   Mon Jun 15 17:37:27 2026 -0300

    hw/riscv: add create_fdt_clint() helper

    Move all clint FDT generation to fdt-common.c reducing code repetition.

    Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
    Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
    Message-ID: <20260615203734.954428-8-daniel.barboza@oss.qualcomm.com>
    Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

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