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]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.