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.

 hw/riscv/fdt-common.c         | 20 ++++++++++++++++++++
 hw/riscv/sifive_u.c           | 10 ++--------
 hw/riscv/virt.c               | 12 +++---------
 include/hw/riscv/fdt-common.h |  3 +++
 4 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c
index ce2dcb43b4..70f96734b4 100644
--- a/hw/riscv/fdt-common.c
+++ b/hw/riscv/fdt-common.c
@@ -10,6 +10,7 @@
 
 #include "qemu/error-report.h"
 #include "system/device_tree.h"
+#include "system/kvm.h"
 #include "hw/core/boards.h"
 #include "hw/core/sysbus-fdt.h"
 #include "hw/riscv/fdt-common.h"
@@ -212,6 +213,25 @@ 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)
+{
+    uint32_t len = 0;
+
+    /* harts running under KVM have no M-mode */
+    if (!kvm_enabled()) {
+        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..456b6da3e6 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -201,14 +201,8 @@ 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]);
     }
 
     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..a325891dca 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -161,15 +161,9 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
     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]);
     }
 
     plic_phandles[socket] = (*phandle)++;
diff --git a/include/hw/riscv/fdt-common.h b/include/hw/riscv/fdt-common.h
index eb9db8278d..14116a95cf 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);
 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,
-- 
2.54.0


Reply via email to