From: Ralf Ramsauer <[email protected]> virt and sifive_u now describe a hart's PLIC contexts with the same rule: a machine context unless the hart runs under KVM, where there is no M-mode, and a supervisor context if the hart has supervisor mode. Writing that rule down twice is what let the virt device tree drift away from riscv_plic_hart_config_string().
This makes the sifive_u device tree ask whether KVM is in use, which it did not do before. Its PLIC device already does, so the two now agree. Signed-off-by: Ralf Ramsauer <[email protected]> --- Cleanup, not a fix. Can be dropped, the rest does not depend on it. 1-3 are unchanged since v2 and carry your Reviewed-by. v3: - take has_m_mode as a parameter, the boards keep the accelerator considerations and the fdt helper just writes what it is told (Daniel) - virt.c uses one has_m_mode local for the allocation and the call hw/riscv/fdt-common.c | 18 ++++++++++++++++++ hw/riscv/sifive_u.c | 12 ++++-------- hw/riscv/virt.c | 16 ++++++---------- include/hw/riscv/fdt-common.h | 3 +++ 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c index ce2dcb43b4..503d818dd0 100644 --- a/hw/riscv/fdt-common.c +++ b/hw/riscv/fdt-common.c @@ -212,6 +212,24 @@ riscv_create_fdt_socket_cpu_sifive(void *fdt, char *clust_name, phandle, intc_phandles, false, false); } +uint32_t riscv_plic_hart_fdt_cells(uint32_t *cells, RISCVCPU *hart, + uint32_t intc_phandle, bool has_m_mode) +{ + uint32_t len = 0; + + if (has_m_mode) { + cells[len++] = cpu_to_be32(intc_phandle); + cells[len++] = cpu_to_be32(IRQ_M_EXT); + } + + if (riscv_cpu_has_supervisor_mode(hart)) { + cells[len++] = cpu_to_be32(intc_phandle); + cells[len++] = cpu_to_be32(IRQ_S_EXT); + } + + return len; +} + void riscv_create_fdt_plic(void *fdt, hwaddr addr, uint64_t size, uint32_t plic_phandle, uint32_t int_cells, uint32_t addr_cells, uint32_t *plic_cells, diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 8f50c67a14..be194f8aec 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -58,6 +58,7 @@ #include "chardev/char.h" #include "net/eth.h" #include "system/device_tree.h" +#include "system/kvm.h" #include "system/runstate.h" #include "system/system.h" @@ -201,14 +202,9 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap, for (cpu = 0; cpu < ms->smp.cpus; cpu++) { /* cpu 0 is the management hart that does not have S-mode */ hart = cpu ? &s->soc.u_cpus.harts[cpu - 1] : &s->soc.e_cpus.harts[0]; - - cells[cells_length++] = cpu_to_be32(intc_phandles[cpu]); - cells[cells_length++] = cpu_to_be32(IRQ_M_EXT); - - if (riscv_cpu_has_supervisor_mode(hart)) { - cells[cells_length++] = cpu_to_be32(intc_phandles[cpu]); - cells[cells_length++] = cpu_to_be32(IRQ_S_EXT); - } + cells_length += riscv_plic_hart_fdt_cells(&cells[cells_length], hart, + intc_phandles[cpu], + !kvm_enabled()); } riscv_create_fdt_plic(fdt, memmap[SIFIVE_U_DEV_PLIC].base, diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index a2851b506d..ece8ef0070 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -152,24 +152,20 @@ static void create_fdt_socket_plic(RISCVVirtState *s, unsigned long plic_addr = s->memmap[VIRT_PLIC].base + (s->memmap[VIRT_PLIC].size * socket); bool numa_enabled = riscv_numa_enabled(MACHINE(s)); + bool has_m_mode = !kvm_enabled(); uint32_t cells_length; plic_name = g_strdup_printf("/soc/interrupt-controller@%lx", plic_addr); plic_cells = g_new0(uint32_t, - s->soc[socket].num_harts * (kvm_enabled() ? 2 : 4)); + s->soc[socket].num_harts * (has_m_mode ? 4 : 2)); cells_length = 0; for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { - if (!kvm_enabled()) { - plic_cells[cells_length++] = cpu_to_be32(intc_phandles[cpu]); - plic_cells[cells_length++] = cpu_to_be32(IRQ_M_EXT); - } - - if (riscv_cpu_has_supervisor_mode(&s->soc[socket].harts[cpu])) { - plic_cells[cells_length++] = cpu_to_be32(intc_phandles[cpu]); - plic_cells[cells_length++] = cpu_to_be32(IRQ_S_EXT); - } + cells_length += riscv_plic_hart_fdt_cells(&plic_cells[cells_length], + &s->soc[socket].harts[cpu], + intc_phandles[cpu], + has_m_mode); } plic_phandles[socket] = (*phandle)++; diff --git a/include/hw/riscv/fdt-common.h b/include/hw/riscv/fdt-common.h index eb9db8278d..58e635e9ed 100644 --- a/include/hw/riscv/fdt-common.h +++ b/include/hw/riscv/fdt-common.h @@ -93,6 +93,9 @@ void riscv_create_fdt_socket_cpu_sifive(void *fdt, char *clust_name, int socket_hartid_base, uint32_t *phandle, uint32_t *intc_phandles); +/* Describe one hart's PLIC contexts, returns the number of cells written */ +uint32_t riscv_plic_hart_fdt_cells(uint32_t *cells, RISCVCPU *hart, + uint32_t intc_phandle, bool has_m_mode); void riscv_create_fdt_plic(void *fdt, hwaddr addr, uint64_t size, uint32_t plic_phandle, uint32_t int_cells, uint32_t addr_cells, uint32_t *plic_cells, base-commit: 81ce3a87737aa50716c42db8886082d12783e0a1 prerequisite-patch-id: 70f23581616a275c2b659d655418184163a0c37c prerequisite-patch-id: e0d267d9d4940408ecf478a14f7cbffd069b9666 prerequisite-patch-id: 0164dcda18a619b9f4a6f84eedcc5fe1e8c92eb9 -- 2.54.0
