mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:17 +00:00
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:
committed by
Alistair Francis
parent
b6cdd8f13e
commit
0d37a88d47
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user