Re: [PATCH 1/2] hw/riscv: Make s-mode IMSIC stride explicit
Portia Stephens <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 24/8/2026 1:05 PM, Joel Stanley wrote:
> 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]>
> ---
> 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 565f91accc09..3b6d7f962506 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 ed8916002945..c33a3b32bd45 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 d808bcc11c34..88c375684412 100644
> --- a/hw/riscv/tt_atlantis.c
> +++ b/hw/riscv/tt_atlantis.c
> @@ -37,8 +37,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
> @@ -231,18 +235,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 d58656f70d1b..42d28f4f5a02 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],
Reviewed-by: Portia Stephens <[email protected]>