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>
This commit is contained in:
Daniel Henrique Barboza
2026-06-15 17:37:27 -03:00
committed by Alistair Francis
parent b6cdd8f13e
commit 0d37a88d47
5 changed files with 54 additions and 86 deletions

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

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