From: Joel Stanley <[email protected]>

Existing machines tightly coupled s-mode IMSIC stride with the guest
bits value. There need to be enough bits to describe the guest in
GEILEN, but that's a minimum bound and machines may choose to use a
larger stride. This change decouples the two and updates Atlantis and
Virt to use the new API.

AIA guest count used by the Atlantis machine was not correct. It looks
like a placeholder value was chosen in order to size the stride to
0x40000, but this gives the wrong guest count. From the (currently
internal) docs, the guest count is 5:

> |NUM_GEILEN|5 (0 - 64)|Number of supported guest index from the S-mode 
> interrupt domain|

Add that value to a define, and add a separate define for the stride, to
reduce the opportunity for future confusion.

Fixes: 7778f4b27bb1 ("hw/riscv: Add Tenstorrent Atlantis machine")
Signed-off-by: Joel Stanley <[email protected]>
Acked-by: Alistair Francis <[email protected]>
Reviewed-by: Portia Stephens <[email protected]>
Message-ID: <[email protected]>
Signed-off-by: Alistair Francis <[email protected]>
---
 hw/riscv/aia.h         |  1 +
 hw/riscv/aia.c         |  5 ++---
 hw/riscv/tt_atlantis.c | 19 +++++++++++--------
 hw/riscv/virt.c        |  2 ++
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h
index 565f91accc..3b6d7f9625 100644
--- a/hw/riscv/aia.h
+++ b/hw/riscv/aia.h
@@ -15,6 +15,7 @@ uint32_t imsic_num_bits(uint32_t count);
 
 DeviceState *riscv_create_aia(bool msimode, int aia_guests,
                              uint32_t m_imsic_stride,
+                             uint32_t s_imsic_stride,
                              uint16_t num_sources,
                              const MemMapEntry *aplic_m,
                              const MemMapEntry *aplic_s,
diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c
index ed89160029..c33a3b32bd 100644
--- a/hw/riscv/aia.c
+++ b/hw/riscv/aia.c
@@ -26,6 +26,7 @@ uint32_t imsic_num_bits(uint32_t count)
 
 DeviceState *riscv_create_aia(bool msimode, int aia_guests,
                              uint32_t m_imsic_stride,
+                             uint32_t s_imsic_stride,
                              uint16_t num_sources,
                              const MemMapEntry *aplic_m,
                              const MemMapEntry *aplic_s,
@@ -36,7 +37,6 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
 {
     int i;
     hwaddr addr = 0;
-    uint32_t guest_bits;
     DeviceState *aplic_s_dev = NULL;
     DeviceState *aplic_m_dev = NULL;
 
@@ -55,10 +55,9 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
         }
 
         /* Per-socket S-level IMSICs */
-        guest_bits = imsic_num_bits(aia_guests + 1);
         addr = imsic_s->base + socket * (1U << IMSIC_MMIO_GROUP_MIN_SHIFT);
         for (i = 0; i < hart_count; i++) {
-            riscv_imsic_create(addr + i * IMSIC_HART_SIZE(guest_bits),
+            riscv_imsic_create(addr + i * s_imsic_stride,
                                base_hartid + i, false, 1 + aia_guests,
                                num_msis);
         }
diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c
index 4fd8679ae1..fda848c3a6 100644
--- a/hw/riscv/tt_atlantis.c
+++ b/hw/riscv/tt_atlantis.c
@@ -36,8 +36,12 @@
 #define TT_IRQCHIP_NUM_MSIS       255
 #define TT_IRQCHIP_NUM_SOURCES    128
 #define TT_IRQCHIP_NUM_PRIO_BITS  3
-#define TT_IRQCHIP_GUESTS         63 /* aia_guests, gives guest_index_bits=6 */
-#define TT_IRQCHIP_MIMSIC_STRIDE  0x40000
+#define TT_IMSIC_GUESTS           5
+#define TT_IMSIC_STRIDE           0x40000 /* Same stride for M and S */
+#define TT_IMSIC_GUEST_BITS       6
+
+/* Stride is fixed by hardware, check it's consistent with guest bits. */
+QEMU_BUILD_BUG_ON(TT_IMSIC_STRIDE != (0x1000 << TT_IMSIC_GUEST_BITS));
 
 #define TT_ACLINT_MTIME_SIZE    0x8050
 #define TT_ACLINT_MTIME         0x0
@@ -230,18 +234,16 @@ static void create_fdt_cpu(TTAtlantisState *s, const 
MemMapEntry *memmap,
 
     create_fdt_aclint(s, intc_phandles);
 
-    uint32_t imsic_guest_bits = imsic_num_bits(TT_IRQCHIP_GUESTS + 1);
-
     /* M-level IMSIC node */
     uint32_t msi_m_phandle = next_phandle();
     create_fdt_one_imsic(fdt, &s->memmap[TT_ATL_MIMSIC], ms->smp.cpus,
                          intc_phandles, msi_m_phandle,
-                         IRQ_M_EXT, imsic_guest_bits);
+                         IRQ_M_EXT, TT_IMSIC_GUEST_BITS);
 
     /* S-level IMSIC node */
     create_fdt_one_imsic(fdt, &s->memmap[TT_ATL_SIMSIC], ms->smp.cpus,
                          intc_phandles, imsic_s_phandle,
-                         IRQ_S_EXT, imsic_guest_bits);
+                         IRQ_S_EXT, TT_IMSIC_GUEST_BITS);
 
     uint32_t aplic_m_phandle = next_phandle();
 
@@ -493,8 +495,9 @@ static void tt_atlantis_machine_init(MachineState *machine)
                             &error_abort);
     sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
 
-    s->irqchip = riscv_create_aia(true, TT_IRQCHIP_GUESTS,
-                                  TT_IRQCHIP_MIMSIC_STRIDE,
+    s->irqchip = riscv_create_aia(true, TT_IMSIC_GUESTS,
+                                  TT_IMSIC_STRIDE,
+                                  TT_IMSIC_STRIDE,
                                   TT_IRQCHIP_NUM_SOURCES,
                                   &s->memmap[TT_ATL_MAPLIC],
                                   &s->memmap[TT_ATL_SAPLIC],
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index a5d2452d97..c43a23af02 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1410,9 +1410,11 @@ static void virt_machine_init(MachineState *machine)
             s->irqchip[i] = virt_create_plic(s->memmap, i,
                                              base_hartid, hart_count);
         } else {
+            int imsic_bits = imsic_num_bits(s->aia_guests + 1);
             s->irqchip[i] = riscv_create_aia(s->aia_type == 
VIRT_AIA_TYPE_APLIC_IMSIC,
                                              s->aia_guests,
                                              IMSIC_HART_SIZE(0),
+                                             IMSIC_HART_SIZE(imsic_bits),
                                              s->num_sources,
                                              &s->memmap[VIRT_APLIC_M],
                                              &s->memmap[VIRT_APLIC_S],
-- 
2.55.0


Reply via email to