* [PATCH 2/2] hw/riscv/aia: Provide number of irq sources
2026-01-09 13:31 Joel Stanley
@ 2026-01-09 13:31 ` Joel Stanley
2026-01-13 12:27 ` Daniel Henrique Barboza
0 siblings, 1 reply; 11+ messages in thread
From: Joel Stanley @ 2026-01-09 13:31 UTC (permalink / raw)
To: Alistair Francis, Daniel Henrique Barboza, Sunil V L, qemu-devel
Cc: Weiwei Li, Liu Zhiwei, Michael Ellerman, Joel Stanley,
Nick Piggin, Anirudh Srinivasan, qemu-riscv
Instead of hard coding the number of IRQ sources used by the APLIC pass
it in as a parameter. This allows other machines to configure this as
required.
The maximum number of sources is 1023.
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
hw/riscv/aia.h | 1 +
include/hw/riscv/virt.h | 1 +
hw/riscv/aia.c | 5 +++--
hw/riscv/virt-acpi-build.c | 22 +++++++++++++---------
hw/riscv/virt.c | 2 ++
5 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h
index 50c48ea4d79c..a63a1ab293fe 100644
--- a/hw/riscv/aia.h
+++ b/hw/riscv/aia.h
@@ -48,6 +48,7 @@
uint32_t imsic_num_bits(uint32_t count);
DeviceState *riscv_create_aia(bool msimode, int aia_guests,
+ uint16_t num_sources,
const MemMapEntry *aplic_m,
const MemMapEntry *aplic_s,
const MemMapEntry *imsic_m,
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 25ec5c665780..fa7fe8d4f648 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -64,6 +64,7 @@ struct RISCVVirtState {
struct GPEXHost *gpex_host;
OnOffAuto iommu_sys;
uint16_t pci_iommu_bdf;
+ uint16_t num_sources;
};
enum {
diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c
index 0a89d7b49b7b..8d45a21f85e2 100644
--- a/hw/riscv/aia.c
+++ b/hw/riscv/aia.c
@@ -25,6 +25,7 @@ uint32_t imsic_num_bits(uint32_t count)
}
DeviceState *riscv_create_aia(bool msimode, int aia_guests,
+ uint16_t num_sources,
const MemMapEntry *aplic_m,
const MemMapEntry *aplic_s,
const MemMapEntry *imsic_m,
@@ -65,7 +66,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
aplic_m->size,
(msimode) ? 0 : base_hartid,
(msimode) ? 0 : hart_count,
- VIRT_IRQCHIP_NUM_SOURCES,
+ num_sources,
VIRT_IRQCHIP_NUM_PRIO_BITS,
msimode, true, NULL);
}
@@ -76,7 +77,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
aplic_s->size,
(msimode) ? 0 : base_hartid,
(msimode) ? 0 : hart_count,
- VIRT_IRQCHIP_NUM_SOURCES,
+ num_sources,
VIRT_IRQCHIP_NUM_PRIO_BITS,
msimode, false, aplic_m_dev);
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index b091a9df9e0f..8da60fe127c4 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -144,6 +144,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
}
static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
+ uint16_t num_sources,
uint64_t mmio_base, uint64_t mmio_size,
const char *hid)
{
@@ -153,7 +154,7 @@ static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
for (socket = 0; socket < socket_count; socket++) {
plic_aplic_addr = mmio_base + mmio_size * socket;
- gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
+ gsi_base = num_sources * socket;
Aml *dev = aml_device("IC%.02X", socket);
aml_append(dev, aml_name_decl("_HID", aml_string("%s", hid)));
aml_append(dev, aml_name_decl("_UID", aml_int(socket)));
@@ -469,10 +470,13 @@ static void build_dsdt(GArray *table_data,
socket_count = riscv_socket_count(ms);
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
- acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_PLIC].base,
- memmap[VIRT_PLIC].size, "RSCV0001");
+ acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
+ memmap[VIRT_PLIC].base,
+ memmap[VIRT_PLIC].size,
+ "RSCV0001");
} else {
- acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_APLIC_S].base,
+ acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
+ memmap[VIRT_APLIC_S].base,
memmap[VIRT_APLIC_S].size, "RSCV0002");
}
@@ -489,15 +493,15 @@ static void build_dsdt(GArray *table_data,
} else if (socket_count == 2) {
virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
memmap[VIRT_VIRTIO].size,
- VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
+ VIRTIO_IRQ + s->num_sources, 0,
VIRTIO_COUNT);
- acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES);
+ acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources);
} else {
virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
memmap[VIRT_VIRTIO].size,
- VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
+ VIRTIO_IRQ + s->num_sources, 0,
VIRTIO_COUNT);
- acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 2);
+ acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources * 2);
}
aml_append(dsdt, scope);
@@ -576,7 +580,7 @@ static void build_madt(GArray *table_data,
for (socket = 0; socket < riscv_socket_count(ms); socket++) {
aplic_addr = s->memmap[VIRT_APLIC_S].base +
s->memmap[VIRT_APLIC_S].size * socket;
- gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
+ gsi_base = s->num_sources * socket;
build_append_int_noprefix(table_data, 0x1A, 1); /* Type */
build_append_int_noprefix(table_data, 36, 1); /* Length */
build_append_int_noprefix(table_data, 1, 1); /* Version */
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 01115a0fb946..e5df5a5d4638 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1556,6 +1556,7 @@ static void virt_machine_init(MachineState *machine)
} else {
s->irqchip[i] = riscv_create_aia(s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC,
s->aia_guests,
+ s->num_sources,
&s->memmap[VIRT_APLIC_M],
&s->memmap[VIRT_APLIC_S],
&s->memmap[VIRT_IMSIC_M],
@@ -1690,6 +1691,7 @@ static void virt_machine_instance_init(Object *obj)
s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
s->acpi = ON_OFF_AUTO_AUTO;
s->iommu_sys = ON_OFF_AUTO_AUTO;
+ s->num_sources = VIRT_IRQCHIP_NUM_SOURCES;
}
static char *virt_get_aia_guests(Object *obj, Error **errp)
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] hw/riscv/aia: Provide number of irq sources
2026-01-09 13:31 ` [PATCH 2/2] hw/riscv/aia: Provide number of irq sources Joel Stanley
@ 2026-01-13 12:27 ` Daniel Henrique Barboza
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Henrique Barboza @ 2026-01-13 12:27 UTC (permalink / raw)
To: Joel Stanley, Alistair Francis, Sunil V L, qemu-devel
Cc: Weiwei Li, Liu Zhiwei, Michael Ellerman, Joel Stanley,
Nick Piggin, Anirudh Srinivasan, qemu-riscv
On 1/9/2026 10:31 AM, Joel Stanley wrote:
> Instead of hard coding the number of IRQ sources used by the APLIC pass
> it in as a parameter. This allows other machines to configure this as
> required.
>
> The maximum number of sources is 1023.
I suppose we always had this source limit but never really added a check
for it. Since you're parametrizing it, might as well add an early check
for it:
g_assert(num_sources <= 1023);
Inside riscv_create_aia() and acpi_dsdt_add_plic_aplic().
The rest LGTM. Thanks,
Daniel
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> hw/riscv/aia.h | 1 +
> include/hw/riscv/virt.h | 1 +
> hw/riscv/aia.c | 5 +++--
> hw/riscv/virt-acpi-build.c | 22 +++++++++++++---------
> hw/riscv/virt.c | 2 ++
> 5 files changed, 20 insertions(+), 11 deletions(-)
>
> diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h
> index 50c48ea4d79c..a63a1ab293fe 100644
> --- a/hw/riscv/aia.h
> +++ b/hw/riscv/aia.h
> @@ -48,6 +48,7 @@
> uint32_t imsic_num_bits(uint32_t count);
>
> DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> + uint16_t num_sources,
> const MemMapEntry *aplic_m,
> const MemMapEntry *aplic_s,
> const MemMapEntry *imsic_m,
> diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> index 25ec5c665780..fa7fe8d4f648 100644
> --- a/include/hw/riscv/virt.h
> +++ b/include/hw/riscv/virt.h
> @@ -64,6 +64,7 @@ struct RISCVVirtState {
> struct GPEXHost *gpex_host;
> OnOffAuto iommu_sys;
> uint16_t pci_iommu_bdf;
> + uint16_t num_sources;
> };
>
> enum {
> diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c
> index 0a89d7b49b7b..8d45a21f85e2 100644
> --- a/hw/riscv/aia.c
> +++ b/hw/riscv/aia.c
> @@ -25,6 +25,7 @@ uint32_t imsic_num_bits(uint32_t count)
> }
>
> DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> + uint16_t num_sources,
> const MemMapEntry *aplic_m,
> const MemMapEntry *aplic_s,
> const MemMapEntry *imsic_m,
> @@ -65,7 +66,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> aplic_m->size,
> (msimode) ? 0 : base_hartid,
> (msimode) ? 0 : hart_count,
> - VIRT_IRQCHIP_NUM_SOURCES,
> + num_sources,
> VIRT_IRQCHIP_NUM_PRIO_BITS,
> msimode, true, NULL);
> }
> @@ -76,7 +77,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> aplic_s->size,
> (msimode) ? 0 : base_hartid,
> (msimode) ? 0 : hart_count,
> - VIRT_IRQCHIP_NUM_SOURCES,
> + num_sources,
> VIRT_IRQCHIP_NUM_PRIO_BITS,
> msimode, false, aplic_m_dev);
>
> diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> index b091a9df9e0f..8da60fe127c4 100644
> --- a/hw/riscv/virt-acpi-build.c
> +++ b/hw/riscv/virt-acpi-build.c
> @@ -144,6 +144,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
> }
>
> static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
> + uint16_t num_sources,
> uint64_t mmio_base, uint64_t mmio_size,
> const char *hid)
> {
> @@ -153,7 +154,7 @@ static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
>
> for (socket = 0; socket < socket_count; socket++) {
> plic_aplic_addr = mmio_base + mmio_size * socket;
> - gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
> + gsi_base = num_sources * socket;
> Aml *dev = aml_device("IC%.02X", socket);
> aml_append(dev, aml_name_decl("_HID", aml_string("%s", hid)));
> aml_append(dev, aml_name_decl("_UID", aml_int(socket)));
> @@ -469,10 +470,13 @@ static void build_dsdt(GArray *table_data,
> socket_count = riscv_socket_count(ms);
>
> if (s->aia_type == VIRT_AIA_TYPE_NONE) {
> - acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_PLIC].base,
> - memmap[VIRT_PLIC].size, "RSCV0001");
> + acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
> + memmap[VIRT_PLIC].base,
> + memmap[VIRT_PLIC].size,
> + "RSCV0001");
> } else {
> - acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_APLIC_S].base,
> + acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
> + memmap[VIRT_APLIC_S].base,
> memmap[VIRT_APLIC_S].size, "RSCV0002");
> }
>
> @@ -489,15 +493,15 @@ static void build_dsdt(GArray *table_data,
> } else if (socket_count == 2) {
> virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
> memmap[VIRT_VIRTIO].size,
> - VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
> + VIRTIO_IRQ + s->num_sources, 0,
> VIRTIO_COUNT);
> - acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES);
> + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources);
> } else {
> virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
> memmap[VIRT_VIRTIO].size,
> - VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
> + VIRTIO_IRQ + s->num_sources, 0,
> VIRTIO_COUNT);
> - acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 2);
> + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources * 2);
> }
>
> aml_append(dsdt, scope);
> @@ -576,7 +580,7 @@ static void build_madt(GArray *table_data,
> for (socket = 0; socket < riscv_socket_count(ms); socket++) {
> aplic_addr = s->memmap[VIRT_APLIC_S].base +
> s->memmap[VIRT_APLIC_S].size * socket;
> - gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
> + gsi_base = s->num_sources * socket;
> build_append_int_noprefix(table_data, 0x1A, 1); /* Type */
> build_append_int_noprefix(table_data, 36, 1); /* Length */
> build_append_int_noprefix(table_data, 1, 1); /* Version */
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 01115a0fb946..e5df5a5d4638 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -1556,6 +1556,7 @@ static void virt_machine_init(MachineState *machine)
> } else {
> s->irqchip[i] = riscv_create_aia(s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC,
> s->aia_guests,
> + s->num_sources,
> &s->memmap[VIRT_APLIC_M],
> &s->memmap[VIRT_APLIC_S],
> &s->memmap[VIRT_IMSIC_M],
> @@ -1690,6 +1691,7 @@ static void virt_machine_instance_init(Object *obj)
> s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
> s->acpi = ON_OFF_AUTO_AUTO;
> s->iommu_sys = ON_OFF_AUTO_AUTO;
> + s->num_sources = VIRT_IRQCHIP_NUM_SOURCES;
> }
>
> static char *virt_get_aia_guests(Object *obj, Error **errp)
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 0/2] hw/riscv: Make virt AIA setup reusable
@ 2026-01-14 1:28 Joel Stanley
2026-01-14 1:28 ` [PATCH 1/2] hw/riscv/virt: Move AIA initialisation to helper file Joel Stanley
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Joel Stanley @ 2026-01-14 1:28 UTC (permalink / raw)
To: Alistair Francis, Daniel Henrique Barboza, Sunil V L, qemu-devel
Cc: Weiwei Li, Liu Zhiwei, Michael Ellerman, Joel Stanley,
Nick Piggin, Anirudh Srinivasan, qemu-riscv
v2: Add assert for number of irq sources
Sharing the AIA setup code looked like a good idea when I was
implementing a machine with AIA. It will be used by Atlantis initially.
Atlantis will use 128 IRQ sources so the second patch makes that
configurable as part of the setup. I initially changed it globally and
that broke the virt acpi tests as the number is encoded in acpi
blob.
Joel Stanley (2):
hw/riscv/virt: Move AIA initialisation to helper file
hw/riscv/aia: Provide number of irq sources
hw/riscv/aia.h | 59 ++++++++++++++++++++++++
include/hw/riscv/virt.h | 30 +------------
hw/riscv/aia.c | 92 ++++++++++++++++++++++++++++++++++++++
hw/riscv/virt-acpi-build.c | 27 +++++++----
hw/riscv/virt.c | 87 +++++------------------------------
hw/riscv/meson.build | 2 +-
6 files changed, 182 insertions(+), 115 deletions(-)
create mode 100644 hw/riscv/aia.h
create mode 100644 hw/riscv/aia.c
--
2.47.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/2] hw/riscv/virt: Move AIA initialisation to helper file
2026-01-14 1:28 [PATCH 0/2] hw/riscv: Make virt AIA setup reusable Joel Stanley
@ 2026-01-14 1:28 ` Joel Stanley
2026-01-28 4:35 ` Nutty.Liu
2026-01-14 1:28 ` [PATCH 2/2] hw/riscv/aia: Provide number of irq sources Joel Stanley
2026-01-14 2:03 ` [PATCH 0/2] hw/riscv: Make virt AIA setup reusable Joel Stanley
2 siblings, 1 reply; 11+ messages in thread
From: Joel Stanley @ 2026-01-14 1:28 UTC (permalink / raw)
To: Alistair Francis, Daniel Henrique Barboza, Sunil V L, qemu-devel
Cc: Weiwei Li, Liu Zhiwei, Michael Ellerman, Joel Stanley,
Nick Piggin, Anirudh Srinivasan, qemu-riscv,
Daniel Henrique Barboza
The AIA init will be used by any server class riscv machine. Separate it
out in order to share code with such systems.
Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
v2: add Daniel's r-b
---
hw/riscv/aia.h | 58 +++++++++++++++++++++++++
include/hw/riscv/virt.h | 29 -------------
hw/riscv/aia.c | 88 ++++++++++++++++++++++++++++++++++++++
hw/riscv/virt-acpi-build.c | 2 +
hw/riscv/virt.c | 85 ++++--------------------------------
hw/riscv/meson.build | 2 +-
6 files changed, 158 insertions(+), 106 deletions(-)
create mode 100644 hw/riscv/aia.h
create mode 100644 hw/riscv/aia.c
diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h
new file mode 100644
index 000000000000..50c48ea4d79c
--- /dev/null
+++ b/hw/riscv/aia.h
@@ -0,0 +1,58 @@
+/*
+ * QEMU RISC-V Advanced Interrupt Architecture (AIA)
+ *
+ * Copyright (C) 2019 Western Digital Corporation or its affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_RISCV_AIA_H
+#define HW_RISCV_AIA_H
+
+#include "exec/hwaddr.h"
+
+/*
+ * The virt machine physical address space used by some of the devices
+ * namely ACLINT, PLIC, APLIC, and IMSIC depend on number of Sockets,
+ * number of CPUs, and number of IMSIC guest files.
+ *
+ * Various limits defined by VIRT_SOCKETS_MAX_BITS, VIRT_CPUS_MAX_BITS,
+ * and VIRT_IRQCHIP_MAX_GUESTS_BITS are tuned for maximum utilization
+ * of virt machine physical address space.
+ */
+
+#define VIRT_SOCKETS_MAX_BITS 2
+#define VIRT_CPUS_MAX_BITS 9
+#define VIRT_CPUS_MAX (1 << VIRT_CPUS_MAX_BITS)
+#define VIRT_SOCKETS_MAX (1 << VIRT_SOCKETS_MAX_BITS)
+
+#define VIRT_IRQCHIP_NUM_MSIS 255
+#define VIRT_IRQCHIP_NUM_SOURCES 96
+#define VIRT_IRQCHIP_NUM_PRIO_BITS 3
+#define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
+#define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
+
+
+#define VIRT_IMSIC_GROUP_MAX_SIZE (1U << IMSIC_MMIO_GROUP_MIN_SHIFT)
+#if VIRT_IMSIC_GROUP_MAX_SIZE < \
+ IMSIC_GROUP_SIZE(VIRT_CPUS_MAX_BITS, VIRT_IRQCHIP_MAX_GUESTS_BITS)
+#error "Can't accommodate single IMSIC group in address space"
+#endif
+
+#define VIRT_IMSIC_MAX_SIZE (VIRT_SOCKETS_MAX * \
+ VIRT_IMSIC_GROUP_MAX_SIZE)
+#if 0x4000000 < VIRT_IMSIC_MAX_SIZE
+#error "Can't accommodate all IMSIC groups in address space"
+#endif
+
+uint32_t imsic_num_bits(uint32_t count);
+
+DeviceState *riscv_create_aia(bool msimode, int aia_guests,
+ const MemMapEntry *aplic_m,
+ const MemMapEntry *aplic_s,
+ const MemMapEntry *imsic_m,
+ const MemMapEntry *imsic_s,
+ int socket, int base_hartid, int hart_count);
+
+
+#endif
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 18a2a323a344..25ec5c665780 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -102,12 +102,6 @@ enum {
#define VIRT_PLATFORM_BUS_NUM_IRQS 32
-#define VIRT_IRQCHIP_NUM_MSIS 255
-#define VIRT_IRQCHIP_NUM_SOURCES 96
-#define VIRT_IRQCHIP_NUM_PRIO_BITS 3
-#define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
-#define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
-
#define VIRT_PLIC_PRIORITY_BASE 0x00
#define VIRT_PLIC_PENDING_BASE 0x1000
#define VIRT_PLIC_ENABLE_BASE 0x2000
@@ -135,28 +129,5 @@ enum {
bool virt_is_acpi_enabled(RISCVVirtState *s);
bool virt_is_iommu_sys_enabled(RISCVVirtState *s);
void virt_acpi_setup(RISCVVirtState *vms);
-uint32_t imsic_num_bits(uint32_t count);
-
-/*
- * The virt machine physical address space used by some of the devices
- * namely ACLINT, PLIC, APLIC, and IMSIC depend on number of Sockets,
- * number of CPUs, and number of IMSIC guest files.
- *
- * Various limits defined by VIRT_SOCKETS_MAX_BITS, VIRT_CPUS_MAX_BITS,
- * and VIRT_IRQCHIP_MAX_GUESTS_BITS are tuned for maximum utilization
- * of virt machine physical address space.
- */
-
-#define VIRT_IMSIC_GROUP_MAX_SIZE (1U << IMSIC_MMIO_GROUP_MIN_SHIFT)
-#if VIRT_IMSIC_GROUP_MAX_SIZE < \
- IMSIC_GROUP_SIZE(VIRT_CPUS_MAX_BITS, VIRT_IRQCHIP_MAX_GUESTS_BITS)
-#error "Can't accommodate single IMSIC group in address space"
-#endif
-
-#define VIRT_IMSIC_MAX_SIZE (VIRT_SOCKETS_MAX * \
- VIRT_IMSIC_GROUP_MAX_SIZE)
-#if 0x4000000 < VIRT_IMSIC_MAX_SIZE
-#error "Can't accommodate all IMSIC groups in address space"
-#endif
#endif
diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c
new file mode 100644
index 000000000000..0a89d7b49b7b
--- /dev/null
+++ b/hw/riscv/aia.c
@@ -0,0 +1,88 @@
+/*
+ * QEMU RISC-V Advanced Interrupt Architecture (AIA)
+ *
+ * Copyright (C) 2019 Western Digital Corporation or its affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "system/kvm.h"
+#include "hw/intc/riscv_aplic.h"
+#include "hw/intc/riscv_imsic.h"
+
+#include "aia.h"
+
+uint32_t imsic_num_bits(uint32_t count)
+{
+ uint32_t ret = 0;
+
+ while (BIT(ret) < count) {
+ ret++;
+ }
+
+ return ret;
+}
+
+DeviceState *riscv_create_aia(bool msimode, int aia_guests,
+ const MemMapEntry *aplic_m,
+ const MemMapEntry *aplic_s,
+ const MemMapEntry *imsic_m,
+ const MemMapEntry *imsic_s,
+ int socket, int base_hartid, int hart_count)
+{
+ int i;
+ hwaddr addr = 0;
+ uint32_t guest_bits;
+ DeviceState *aplic_s_dev = NULL;
+ DeviceState *aplic_m_dev = NULL;
+
+ if (msimode) {
+ if (!kvm_enabled()) {
+ /* Per-socket M-level IMSICs */
+ addr = imsic_m->base + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
+ for (i = 0; i < hart_count; i++) {
+ riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
+ base_hartid + i, true, 1,
+ VIRT_IRQCHIP_NUM_MSIS);
+ }
+ }
+
+ /* Per-socket S-level IMSICs */
+ guest_bits = imsic_num_bits(aia_guests + 1);
+ addr = imsic_s->base + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
+ for (i = 0; i < hart_count; i++) {
+ riscv_imsic_create(addr + i * IMSIC_HART_SIZE(guest_bits),
+ base_hartid + i, false, 1 + aia_guests,
+ VIRT_IRQCHIP_NUM_MSIS);
+ }
+ }
+
+ if (!kvm_enabled()) {
+ /* Per-socket M-level APLIC */
+ aplic_m_dev = riscv_aplic_create(aplic_m->base +
+ socket * aplic_m->size,
+ aplic_m->size,
+ (msimode) ? 0 : base_hartid,
+ (msimode) ? 0 : hart_count,
+ VIRT_IRQCHIP_NUM_SOURCES,
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
+ msimode, true, NULL);
+ }
+
+ /* Per-socket S-level APLIC */
+ aplic_s_dev = riscv_aplic_create(aplic_s->base +
+ socket * aplic_s->size,
+ aplic_s->size,
+ (msimode) ? 0 : base_hartid,
+ (msimode) ? 0 : hart_count,
+ VIRT_IRQCHIP_NUM_SOURCES,
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
+ msimode, false, aplic_m_dev);
+
+ if (kvm_enabled() && msimode) {
+ riscv_aplic_set_kvm_msicfgaddr(RISCV_APLIC(aplic_s_dev), addr);
+ }
+
+ return kvm_enabled() ? aplic_s_dev : aplic_m_dev;
+}
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index f1406cb68339..b091a9df9e0f 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -40,6 +40,8 @@
#include "qemu/error-report.h"
#include "system/reset.h"
+#include "aia.h"
+
#define ACPI_BUILD_TABLE_SIZE 0x20000
#define ACPI_BUILD_INTC_ID(socket, index) ((socket << 24) | (index))
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index bd8608ea5bfd..01115a0fb946 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -59,6 +59,8 @@
#include "hw/virtio/virtio-iommu.h"
#include "hw/uefi/var-service-api.h"
+#include "aia.h"
+
/* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */
static bool virt_use_kvm_aia_aplic_imsic(RISCVVirtAIAType aia_type)
{
@@ -509,17 +511,6 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
}
}
-uint32_t imsic_num_bits(uint32_t count)
-{
- uint32_t ret = 0;
-
- while (BIT(ret) < count) {
- ret++;
- }
-
- return ret;
-}
-
static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr,
uint32_t *intc_phandles, uint32_t msi_phandle,
bool m_mode, uint32_t imsic_guest_bits)
@@ -1302,68 +1293,6 @@ static DeviceState *virt_create_plic(const MemMapEntry *memmap, int socket,
memmap[VIRT_PLIC].size);
}
-static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
- const MemMapEntry *memmap, int socket,
- int base_hartid, int hart_count)
-{
- int i;
- hwaddr addr = 0;
- uint32_t guest_bits;
- DeviceState *aplic_s = NULL;
- DeviceState *aplic_m = NULL;
- bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
-
- if (msimode) {
- if (!kvm_enabled()) {
- /* Per-socket M-level IMSICs */
- addr = memmap[VIRT_IMSIC_M].base +
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
- for (i = 0; i < hart_count; i++) {
- riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
- base_hartid + i, true, 1,
- VIRT_IRQCHIP_NUM_MSIS);
- }
- }
-
- /* Per-socket S-level IMSICs */
- guest_bits = imsic_num_bits(aia_guests + 1);
- addr = memmap[VIRT_IMSIC_S].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
- for (i = 0; i < hart_count; i++) {
- riscv_imsic_create(addr + i * IMSIC_HART_SIZE(guest_bits),
- base_hartid + i, false, 1 + aia_guests,
- VIRT_IRQCHIP_NUM_MSIS);
- }
- }
-
- if (!kvm_enabled()) {
- /* Per-socket M-level APLIC */
- aplic_m = riscv_aplic_create(memmap[VIRT_APLIC_M].base +
- socket * memmap[VIRT_APLIC_M].size,
- memmap[VIRT_APLIC_M].size,
- (msimode) ? 0 : base_hartid,
- (msimode) ? 0 : hart_count,
- VIRT_IRQCHIP_NUM_SOURCES,
- VIRT_IRQCHIP_NUM_PRIO_BITS,
- msimode, true, NULL);
- }
-
- /* Per-socket S-level APLIC */
- aplic_s = riscv_aplic_create(memmap[VIRT_APLIC_S].base +
- socket * memmap[VIRT_APLIC_S].size,
- memmap[VIRT_APLIC_S].size,
- (msimode) ? 0 : base_hartid,
- (msimode) ? 0 : hart_count,
- VIRT_IRQCHIP_NUM_SOURCES,
- VIRT_IRQCHIP_NUM_PRIO_BITS,
- msimode, false, aplic_m);
-
- if (kvm_enabled() && msimode) {
- riscv_aplic_set_kvm_msicfgaddr(RISCV_APLIC(aplic_s), addr);
- }
-
- return kvm_enabled() ? aplic_s : aplic_m;
-}
-
static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
{
DeviceState *dev;
@@ -1625,9 +1554,13 @@ static void virt_machine_init(MachineState *machine)
s->irqchip[i] = virt_create_plic(s->memmap, i,
base_hartid, hart_count);
} else {
- s->irqchip[i] = virt_create_aia(s->aia_type, s->aia_guests,
- s->memmap, i, base_hartid,
- hart_count);
+ s->irqchip[i] = riscv_create_aia(s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC,
+ s->aia_guests,
+ &s->memmap[VIRT_APLIC_M],
+ &s->memmap[VIRT_APLIC_S],
+ &s->memmap[VIRT_IMSIC_M],
+ &s->memmap[VIRT_IMSIC_S],
+ i, base_hartid, hart_count);
}
/* Try to use different IRQCHIP instance based device type */
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
index 533472e22aef..e53c180d0d10 100644
--- a/hw/riscv/meson.build
+++ b/hw/riscv/meson.build
@@ -1,5 +1,5 @@
riscv_ss = ss.source_set()
-riscv_ss.add(files('boot.c'))
+riscv_ss.add(files('boot.c', 'aia.c'))
riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: files('numa.c'))
riscv_ss.add(files('riscv_hart.c'))
riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c'))
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/2] hw/riscv/aia: Provide number of irq sources
2026-01-14 1:28 [PATCH 0/2] hw/riscv: Make virt AIA setup reusable Joel Stanley
2026-01-14 1:28 ` [PATCH 1/2] hw/riscv/virt: Move AIA initialisation to helper file Joel Stanley
@ 2026-01-14 1:28 ` Joel Stanley
2026-01-14 11:07 ` Daniel Henrique Barboza
2026-01-28 4:35 ` Nutty.Liu
2026-01-14 2:03 ` [PATCH 0/2] hw/riscv: Make virt AIA setup reusable Joel Stanley
2 siblings, 2 replies; 11+ messages in thread
From: Joel Stanley @ 2026-01-14 1:28 UTC (permalink / raw)
To: Alistair Francis, Daniel Henrique Barboza, Sunil V L, qemu-devel
Cc: Weiwei Li, Liu Zhiwei, Michael Ellerman, Joel Stanley,
Nick Piggin, Anirudh Srinivasan, qemu-riscv
Instead of hard coding the number of IRQ sources used by the APLIC pass
it in as a parameter. This allows other machines to configure this as
required.
The maximum number of sources is 1023.
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
v2: Add assert for the number of irq sources
---
hw/riscv/aia.h | 1 +
include/hw/riscv/virt.h | 1 +
hw/riscv/aia.c | 8 ++++++--
hw/riscv/virt-acpi-build.c | 25 ++++++++++++++++---------
hw/riscv/virt.c | 2 ++
5 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h
index 50c48ea4d79c..a63a1ab293fe 100644
--- a/hw/riscv/aia.h
+++ b/hw/riscv/aia.h
@@ -48,6 +48,7 @@
uint32_t imsic_num_bits(uint32_t count);
DeviceState *riscv_create_aia(bool msimode, int aia_guests,
+ uint16_t num_sources,
const MemMapEntry *aplic_m,
const MemMapEntry *aplic_s,
const MemMapEntry *imsic_m,
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 25ec5c665780..fa7fe8d4f648 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -64,6 +64,7 @@ struct RISCVVirtState {
struct GPEXHost *gpex_host;
OnOffAuto iommu_sys;
uint16_t pci_iommu_bdf;
+ uint16_t num_sources;
};
enum {
diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c
index 0a89d7b49b7b..a9130896fba2 100644
--- a/hw/riscv/aia.c
+++ b/hw/riscv/aia.c
@@ -25,6 +25,7 @@ uint32_t imsic_num_bits(uint32_t count)
}
DeviceState *riscv_create_aia(bool msimode, int aia_guests,
+ uint16_t num_sources,
const MemMapEntry *aplic_m,
const MemMapEntry *aplic_s,
const MemMapEntry *imsic_m,
@@ -37,6 +38,9 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
DeviceState *aplic_s_dev = NULL;
DeviceState *aplic_m_dev = NULL;
+ /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */
+ g_assert(num_sources <= 1023);
+
if (msimode) {
if (!kvm_enabled()) {
/* Per-socket M-level IMSICs */
@@ -65,7 +69,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
aplic_m->size,
(msimode) ? 0 : base_hartid,
(msimode) ? 0 : hart_count,
- VIRT_IRQCHIP_NUM_SOURCES,
+ num_sources,
VIRT_IRQCHIP_NUM_PRIO_BITS,
msimode, true, NULL);
}
@@ -76,7 +80,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
aplic_s->size,
(msimode) ? 0 : base_hartid,
(msimode) ? 0 : hart_count,
- VIRT_IRQCHIP_NUM_SOURCES,
+ num_sources,
VIRT_IRQCHIP_NUM_PRIO_BITS,
msimode, false, aplic_m_dev);
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index b091a9df9e0f..350912903174 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -144,6 +144,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
}
static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
+ uint16_t num_sources,
uint64_t mmio_base, uint64_t mmio_size,
const char *hid)
{
@@ -151,9 +152,12 @@ static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
uint32_t gsi_base;
uint8_t socket;
+ /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */
+ g_assert(num_sources <= 1023);
+
for (socket = 0; socket < socket_count; socket++) {
plic_aplic_addr = mmio_base + mmio_size * socket;
- gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
+ gsi_base = num_sources * socket;
Aml *dev = aml_device("IC%.02X", socket);
aml_append(dev, aml_name_decl("_HID", aml_string("%s", hid)));
aml_append(dev, aml_name_decl("_UID", aml_int(socket)));
@@ -469,10 +473,13 @@ static void build_dsdt(GArray *table_data,
socket_count = riscv_socket_count(ms);
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
- acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_PLIC].base,
- memmap[VIRT_PLIC].size, "RSCV0001");
+ acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
+ memmap[VIRT_PLIC].base,
+ memmap[VIRT_PLIC].size,
+ "RSCV0001");
} else {
- acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_APLIC_S].base,
+ acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
+ memmap[VIRT_APLIC_S].base,
memmap[VIRT_APLIC_S].size, "RSCV0002");
}
@@ -489,15 +496,15 @@ static void build_dsdt(GArray *table_data,
} else if (socket_count == 2) {
virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
memmap[VIRT_VIRTIO].size,
- VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
+ VIRTIO_IRQ + s->num_sources, 0,
VIRTIO_COUNT);
- acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES);
+ acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources);
} else {
virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
memmap[VIRT_VIRTIO].size,
- VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
+ VIRTIO_IRQ + s->num_sources, 0,
VIRTIO_COUNT);
- acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 2);
+ acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources * 2);
}
aml_append(dsdt, scope);
@@ -576,7 +583,7 @@ static void build_madt(GArray *table_data,
for (socket = 0; socket < riscv_socket_count(ms); socket++) {
aplic_addr = s->memmap[VIRT_APLIC_S].base +
s->memmap[VIRT_APLIC_S].size * socket;
- gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
+ gsi_base = s->num_sources * socket;
build_append_int_noprefix(table_data, 0x1A, 1); /* Type */
build_append_int_noprefix(table_data, 36, 1); /* Length */
build_append_int_noprefix(table_data, 1, 1); /* Version */
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 01115a0fb946..e5df5a5d4638 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1556,6 +1556,7 @@ static void virt_machine_init(MachineState *machine)
} else {
s->irqchip[i] = riscv_create_aia(s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC,
s->aia_guests,
+ s->num_sources,
&s->memmap[VIRT_APLIC_M],
&s->memmap[VIRT_APLIC_S],
&s->memmap[VIRT_IMSIC_M],
@@ -1690,6 +1691,7 @@ static void virt_machine_instance_init(Object *obj)
s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
s->acpi = ON_OFF_AUTO_AUTO;
s->iommu_sys = ON_OFF_AUTO_AUTO;
+ s->num_sources = VIRT_IRQCHIP_NUM_SOURCES;
}
static char *virt_get_aia_guests(Object *obj, Error **errp)
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 0/2] hw/riscv: Make virt AIA setup reusable
2026-01-14 1:28 [PATCH 0/2] hw/riscv: Make virt AIA setup reusable Joel Stanley
2026-01-14 1:28 ` [PATCH 1/2] hw/riscv/virt: Move AIA initialisation to helper file Joel Stanley
2026-01-14 1:28 ` [PATCH 2/2] hw/riscv/aia: Provide number of irq sources Joel Stanley
@ 2026-01-14 2:03 ` Joel Stanley
2 siblings, 0 replies; 11+ messages in thread
From: Joel Stanley @ 2026-01-14 2:03 UTC (permalink / raw)
To: Alistair Francis, Daniel Henrique Barboza, Sunil V L, qemu-devel
Cc: Weiwei Li, Liu Zhiwei, Michael Ellerman, Joel Stanley,
Nick Piggin, Anirudh Srinivasan, qemu-riscv
Alistair,
On Wed, 14 Jan 2026 at 11:59, Joel Stanley <joel@jms.id.au> wrote:
>
> v2: Add assert for number of irq sources
I forgot to set V2 in the subject when sending this series. My
apologies, it's been a while between patches.
Let me know if a re-send would help.
Cheers,
Joel
>
> Sharing the AIA setup code looked like a good idea when I was
> implementing a machine with AIA. It will be used by Atlantis initially.
>
> Atlantis will use 128 IRQ sources so the second patch makes that
> configurable as part of the setup. I initially changed it globally and
> that broke the virt acpi tests as the number is encoded in acpi
> blob.
>
> Joel Stanley (2):
> hw/riscv/virt: Move AIA initialisation to helper file
> hw/riscv/aia: Provide number of irq sources
>
> hw/riscv/aia.h | 59 ++++++++++++++++++++++++
> include/hw/riscv/virt.h | 30 +------------
> hw/riscv/aia.c | 92 ++++++++++++++++++++++++++++++++++++++
> hw/riscv/virt-acpi-build.c | 27 +++++++----
> hw/riscv/virt.c | 87 +++++------------------------------
> hw/riscv/meson.build | 2 +-
> 6 files changed, 182 insertions(+), 115 deletions(-)
> create mode 100644 hw/riscv/aia.h
> create mode 100644 hw/riscv/aia.c
>
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] hw/riscv/aia: Provide number of irq sources
2026-01-14 1:28 ` [PATCH 2/2] hw/riscv/aia: Provide number of irq sources Joel Stanley
@ 2026-01-14 11:07 ` Daniel Henrique Barboza
2026-01-28 4:35 ` Nutty.Liu
1 sibling, 0 replies; 11+ messages in thread
From: Daniel Henrique Barboza @ 2026-01-14 11:07 UTC (permalink / raw)
To: Joel Stanley, Alistair Francis, Sunil V L, qemu-devel
Cc: Weiwei Li, Liu Zhiwei, Michael Ellerman, Joel Stanley,
Nick Piggin, Anirudh Srinivasan, qemu-riscv
On 1/13/2026 10:28 PM, Joel Stanley wrote:
> Instead of hard coding the number of IRQ sources used by the APLIC pass
> it in as a parameter. This allows other machines to configure this as
> required.
>
> The maximum number of sources is 1023.
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> v2: Add assert for the number of irq sources
> ---
> hw/riscv/aia.h | 1 +
> include/hw/riscv/virt.h | 1 +
> hw/riscv/aia.c | 8 ++++++--
> hw/riscv/virt-acpi-build.c | 25 ++++++++++++++++---------
> hw/riscv/virt.c | 2 ++
> 5 files changed, 26 insertions(+), 11 deletions(-)
>
> diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h
> index 50c48ea4d79c..a63a1ab293fe 100644
> --- a/hw/riscv/aia.h
> +++ b/hw/riscv/aia.h
> @@ -48,6 +48,7 @@
> uint32_t imsic_num_bits(uint32_t count);
>
> DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> + uint16_t num_sources,
> const MemMapEntry *aplic_m,
> const MemMapEntry *aplic_s,
> const MemMapEntry *imsic_m,
> diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> index 25ec5c665780..fa7fe8d4f648 100644
> --- a/include/hw/riscv/virt.h
> +++ b/include/hw/riscv/virt.h
> @@ -64,6 +64,7 @@ struct RISCVVirtState {
> struct GPEXHost *gpex_host;
> OnOffAuto iommu_sys;
> uint16_t pci_iommu_bdf;
> + uint16_t num_sources;
> };
>
> enum {
> diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c
> index 0a89d7b49b7b..a9130896fba2 100644
> --- a/hw/riscv/aia.c
> +++ b/hw/riscv/aia.c
> @@ -25,6 +25,7 @@ uint32_t imsic_num_bits(uint32_t count)
> }
>
> DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> + uint16_t num_sources,
> const MemMapEntry *aplic_m,
> const MemMapEntry *aplic_s,
> const MemMapEntry *imsic_m,
> @@ -37,6 +38,9 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> DeviceState *aplic_s_dev = NULL;
> DeviceState *aplic_m_dev = NULL;
>
> + /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */
> + g_assert(num_sources <= 1023);
> +
> if (msimode) {
> if (!kvm_enabled()) {
> /* Per-socket M-level IMSICs */
> @@ -65,7 +69,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> aplic_m->size,
> (msimode) ? 0 : base_hartid,
> (msimode) ? 0 : hart_count,
> - VIRT_IRQCHIP_NUM_SOURCES,
> + num_sources,
> VIRT_IRQCHIP_NUM_PRIO_BITS,
> msimode, true, NULL);
> }
> @@ -76,7 +80,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> aplic_s->size,
> (msimode) ? 0 : base_hartid,
> (msimode) ? 0 : hart_count,
> - VIRT_IRQCHIP_NUM_SOURCES,
> + num_sources,
> VIRT_IRQCHIP_NUM_PRIO_BITS,
> msimode, false, aplic_m_dev);
>
> diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> index b091a9df9e0f..350912903174 100644
> --- a/hw/riscv/virt-acpi-build.c
> +++ b/hw/riscv/virt-acpi-build.c
> @@ -144,6 +144,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
> }
>
> static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
> + uint16_t num_sources,
> uint64_t mmio_base, uint64_t mmio_size,
> const char *hid)
> {
> @@ -151,9 +152,12 @@ static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
> uint32_t gsi_base;
> uint8_t socket;
>
> + /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */
> + g_assert(num_sources <= 1023);
> +
> for (socket = 0; socket < socket_count; socket++) {
> plic_aplic_addr = mmio_base + mmio_size * socket;
> - gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
> + gsi_base = num_sources * socket;
> Aml *dev = aml_device("IC%.02X", socket);
> aml_append(dev, aml_name_decl("_HID", aml_string("%s", hid)));
> aml_append(dev, aml_name_decl("_UID", aml_int(socket)));
> @@ -469,10 +473,13 @@ static void build_dsdt(GArray *table_data,
> socket_count = riscv_socket_count(ms);
>
> if (s->aia_type == VIRT_AIA_TYPE_NONE) {
> - acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_PLIC].base,
> - memmap[VIRT_PLIC].size, "RSCV0001");
> + acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
> + memmap[VIRT_PLIC].base,
> + memmap[VIRT_PLIC].size,
> + "RSCV0001");
> } else {
> - acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_APLIC_S].base,
> + acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
> + memmap[VIRT_APLIC_S].base,
> memmap[VIRT_APLIC_S].size, "RSCV0002");
> }
>
> @@ -489,15 +496,15 @@ static void build_dsdt(GArray *table_data,
> } else if (socket_count == 2) {
> virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
> memmap[VIRT_VIRTIO].size,
> - VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
> + VIRTIO_IRQ + s->num_sources, 0,
> VIRTIO_COUNT);
> - acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES);
> + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources);
> } else {
> virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
> memmap[VIRT_VIRTIO].size,
> - VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
> + VIRTIO_IRQ + s->num_sources, 0,
> VIRTIO_COUNT);
> - acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 2);
> + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources * 2);
> }
>
> aml_append(dsdt, scope);
> @@ -576,7 +583,7 @@ static void build_madt(GArray *table_data,
> for (socket = 0; socket < riscv_socket_count(ms); socket++) {
> aplic_addr = s->memmap[VIRT_APLIC_S].base +
> s->memmap[VIRT_APLIC_S].size * socket;
> - gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
> + gsi_base = s->num_sources * socket;
> build_append_int_noprefix(table_data, 0x1A, 1); /* Type */
> build_append_int_noprefix(table_data, 36, 1); /* Length */
> build_append_int_noprefix(table_data, 1, 1); /* Version */
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 01115a0fb946..e5df5a5d4638 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -1556,6 +1556,7 @@ static void virt_machine_init(MachineState *machine)
> } else {
> s->irqchip[i] = riscv_create_aia(s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC,
> s->aia_guests,
> + s->num_sources,
> &s->memmap[VIRT_APLIC_M],
> &s->memmap[VIRT_APLIC_S],
> &s->memmap[VIRT_IMSIC_M],
> @@ -1690,6 +1691,7 @@ static void virt_machine_instance_init(Object *obj)
> s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
> s->acpi = ON_OFF_AUTO_AUTO;
> s->iommu_sys = ON_OFF_AUTO_AUTO;
> + s->num_sources = VIRT_IRQCHIP_NUM_SOURCES;
> }
>
> static char *virt_get_aia_guests(Object *obj, Error **errp)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] hw/riscv/virt: Move AIA initialisation to helper file
2026-01-14 1:28 ` [PATCH 1/2] hw/riscv/virt: Move AIA initialisation to helper file Joel Stanley
@ 2026-01-28 4:35 ` Nutty.Liu
0 siblings, 0 replies; 11+ messages in thread
From: Nutty.Liu @ 2026-01-28 4:35 UTC (permalink / raw)
To: Joel Stanley, Alistair Francis, Daniel Henrique Barboza,
Sunil V L, qemu-devel
Cc: Weiwei Li, Liu Zhiwei, Michael Ellerman, Joel Stanley,
Nick Piggin, Anirudh Srinivasan, qemu-riscv,
Daniel Henrique Barboza
On 1/14/2026 9:28 AM, Joel Stanley wrote:
> The AIA init will be used by any server class riscv machine. Separate it
> out in order to share code with such systems.
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> ---
> v2: add Daniel's r-b
> ---
> hw/riscv/aia.h | 58 +++++++++++++++++++++++++
> include/hw/riscv/virt.h | 29 -------------
> hw/riscv/aia.c | 88 ++++++++++++++++++++++++++++++++++++++
> hw/riscv/virt-acpi-build.c | 2 +
> hw/riscv/virt.c | 85 ++++--------------------------------
> hw/riscv/meson.build | 2 +-
> 6 files changed, 158 insertions(+), 106 deletions(-)
> create mode 100644 hw/riscv/aia.h
> create mode 100644 hw/riscv/aia.c
Reviewed-by: Nutty Liu<nutty.liu@hotmail.com>
Thanks,
Nutty
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] hw/riscv/aia: Provide number of irq sources
2026-01-14 1:28 ` [PATCH 2/2] hw/riscv/aia: Provide number of irq sources Joel Stanley
2026-01-14 11:07 ` Daniel Henrique Barboza
@ 2026-01-28 4:35 ` Nutty.Liu
2026-01-29 0:51 ` Nicholas Piggin
1 sibling, 1 reply; 11+ messages in thread
From: Nutty.Liu @ 2026-01-28 4:35 UTC (permalink / raw)
To: Joel Stanley, Alistair Francis, Daniel Henrique Barboza,
Sunil V L, qemu-devel
Cc: Weiwei Li, Liu Zhiwei, Michael Ellerman, Joel Stanley,
Nick Piggin, Anirudh Srinivasan, qemu-riscv
On 1/14/2026 9:28 AM, Joel Stanley wrote:
> Instead of hard coding the number of IRQ sources used by the APLIC pass
> it in as a parameter. This allows other machines to configure this as
> required.
>
> The maximum number of sources is 1023.
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> v2: Add assert for the number of irq sources
> ---
> hw/riscv/aia.h | 1 +
> include/hw/riscv/virt.h | 1 +
> hw/riscv/aia.c | 8 ++++++--
> hw/riscv/virt-acpi-build.c | 25 ++++++++++++++++---------
> hw/riscv/virt.c | 2 ++
> 5 files changed, 26 insertions(+), 11 deletions(-)
>
> diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h
> index 50c48ea4d79c..a63a1ab293fe 100644
> --- a/hw/riscv/aia.h
> +++ b/hw/riscv/aia.h
> @@ -48,6 +48,7 @@
> uint32_t imsic_num_bits(uint32_t count);
>
> DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> + uint16_t num_sources,
> const MemMapEntry *aplic_m,
> const MemMapEntry *aplic_s,
> const MemMapEntry *imsic_m,
> diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> index 25ec5c665780..fa7fe8d4f648 100644
> --- a/include/hw/riscv/virt.h
> +++ b/include/hw/riscv/virt.h
> @@ -64,6 +64,7 @@ struct RISCVVirtState {
> struct GPEXHost *gpex_host;
> OnOffAuto iommu_sys;
> uint16_t pci_iommu_bdf;
> + uint16_t num_sources;
> };
>
> enum {
> diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c
> index 0a89d7b49b7b..a9130896fba2 100644
> --- a/hw/riscv/aia.c
> +++ b/hw/riscv/aia.c
> @@ -25,6 +25,7 @@ uint32_t imsic_num_bits(uint32_t count)
> }
>
> DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> + uint16_t num_sources,
> const MemMapEntry *aplic_m,
> const MemMapEntry *aplic_s,
> const MemMapEntry *imsic_m,
> @@ -37,6 +38,9 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> DeviceState *aplic_s_dev = NULL;
> DeviceState *aplic_m_dev = NULL;
>
> + /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */
> + g_assert(num_sources <= 1023);
> +
How about the below check ?
g_assert(num_sources <= VIRT_IRQCHIP_NUM_SOURCES);
And modify VIRT_IRQCHIP_NUM_SOURCES in "aia.h" as below ?
#define VIRT_IRQCHIP_NUM_SOURCES 1023
Otherwise,
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Thanks,
Nutty
> if (msimode) {
> if (!kvm_enabled()) {
> /* Per-socket M-level IMSICs */
> @@ -65,7 +69,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> aplic_m->size,
> (msimode) ? 0 : base_hartid,
> (msimode) ? 0 : hart_count,
> - VIRT_IRQCHIP_NUM_SOURCES,
> + num_sources,
> VIRT_IRQCHIP_NUM_PRIO_BITS,
> msimode, true, NULL);
> }
> @@ -76,7 +80,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> aplic_s->size,
> (msimode) ? 0 : base_hartid,
> (msimode) ? 0 : hart_count,
> - VIRT_IRQCHIP_NUM_SOURCES,
> + num_sources,
> VIRT_IRQCHIP_NUM_PRIO_BITS,
> msimode, false, aplic_m_dev);
>
> diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> index b091a9df9e0f..350912903174 100644
> --- a/hw/riscv/virt-acpi-build.c
> +++ b/hw/riscv/virt-acpi-build.c
> @@ -144,6 +144,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
> }
>
> static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
> + uint16_t num_sources,
> uint64_t mmio_base, uint64_t mmio_size,
> const char *hid)
> {
> @@ -151,9 +152,12 @@ static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
> uint32_t gsi_base;
> uint8_t socket;
>
> + /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */
> + g_assert(num_sources <= 1023);
> +
> for (socket = 0; socket < socket_count; socket++) {
> plic_aplic_addr = mmio_base + mmio_size * socket;
> - gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
> + gsi_base = num_sources * socket;
> Aml *dev = aml_device("IC%.02X", socket);
> aml_append(dev, aml_name_decl("_HID", aml_string("%s", hid)));
> aml_append(dev, aml_name_decl("_UID", aml_int(socket)));
> @@ -469,10 +473,13 @@ static void build_dsdt(GArray *table_data,
> socket_count = riscv_socket_count(ms);
>
> if (s->aia_type == VIRT_AIA_TYPE_NONE) {
> - acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_PLIC].base,
> - memmap[VIRT_PLIC].size, "RSCV0001");
> + acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
> + memmap[VIRT_PLIC].base,
> + memmap[VIRT_PLIC].size,
> + "RSCV0001");
> } else {
> - acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_APLIC_S].base,
> + acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
> + memmap[VIRT_APLIC_S].base,
> memmap[VIRT_APLIC_S].size, "RSCV0002");
> }
>
> @@ -489,15 +496,15 @@ static void build_dsdt(GArray *table_data,
> } else if (socket_count == 2) {
> virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
> memmap[VIRT_VIRTIO].size,
> - VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
> + VIRTIO_IRQ + s->num_sources, 0,
> VIRTIO_COUNT);
> - acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES);
> + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources);
> } else {
> virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
> memmap[VIRT_VIRTIO].size,
> - VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
> + VIRTIO_IRQ + s->num_sources, 0,
> VIRTIO_COUNT);
> - acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 2);
> + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources * 2);
> }
>
> aml_append(dsdt, scope);
> @@ -576,7 +583,7 @@ static void build_madt(GArray *table_data,
> for (socket = 0; socket < riscv_socket_count(ms); socket++) {
> aplic_addr = s->memmap[VIRT_APLIC_S].base +
> s->memmap[VIRT_APLIC_S].size * socket;
> - gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
> + gsi_base = s->num_sources * socket;
> build_append_int_noprefix(table_data, 0x1A, 1); /* Type */
> build_append_int_noprefix(table_data, 36, 1); /* Length */
> build_append_int_noprefix(table_data, 1, 1); /* Version */
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 01115a0fb946..e5df5a5d4638 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -1556,6 +1556,7 @@ static void virt_machine_init(MachineState *machine)
> } else {
> s->irqchip[i] = riscv_create_aia(s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC,
> s->aia_guests,
> + s->num_sources,
> &s->memmap[VIRT_APLIC_M],
> &s->memmap[VIRT_APLIC_S],
> &s->memmap[VIRT_IMSIC_M],
> @@ -1690,6 +1691,7 @@ static void virt_machine_instance_init(Object *obj)
> s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
> s->acpi = ON_OFF_AUTO_AUTO;
> s->iommu_sys = ON_OFF_AUTO_AUTO;
> + s->num_sources = VIRT_IRQCHIP_NUM_SOURCES;
> }
>
> static char *virt_get_aia_guests(Object *obj, Error **errp)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] hw/riscv/aia: Provide number of irq sources
2026-01-28 4:35 ` Nutty.Liu
@ 2026-01-29 0:51 ` Nicholas Piggin
2026-03-11 3:52 ` Joel Stanley
0 siblings, 1 reply; 11+ messages in thread
From: Nicholas Piggin @ 2026-01-29 0:51 UTC (permalink / raw)
To: Nutty.Liu
Cc: Joel Stanley, Alistair Francis, Daniel Henrique Barboza,
Sunil V L, qemu-devel, Weiwei Li, Liu Zhiwei, Michael Ellerman,
Joel Stanley, Nick Piggin, Anirudh Srinivasan, qemu-riscv
On Wed, Jan 28, 2026 at 2:35 PM Nutty.Liu <nutty.liu@hotmail.com> wrote:
>
>
> On 1/14/2026 9:28 AM, Joel Stanley wrote:
> > Instead of hard coding the number of IRQ sources used by the APLIC pass
> > it in as a parameter. This allows other machines to configure this as
> > required.
> >
> > The maximum number of sources is 1023.
> >
> > Signed-off-by: Joel Stanley <joel@jms.id.au>
> > ---
> > v2: Add assert for the number of irq sources
> > ---
> > hw/riscv/aia.h | 1 +
> > include/hw/riscv/virt.h | 1 +
> > hw/riscv/aia.c | 8 ++++++--
> > hw/riscv/virt-acpi-build.c | 25 ++++++++++++++++---------
> > hw/riscv/virt.c | 2 ++
> > 5 files changed, 26 insertions(+), 11 deletions(-)
> >
> > diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h
> > index 50c48ea4d79c..a63a1ab293fe 100644
> > --- a/hw/riscv/aia.h
> > +++ b/hw/riscv/aia.h
> > @@ -48,6 +48,7 @@
> > uint32_t imsic_num_bits(uint32_t count);
> >
> > DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> > + uint16_t num_sources,
> > const MemMapEntry *aplic_m,
> > const MemMapEntry *aplic_s,
> > const MemMapEntry *imsic_m,
> > diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> > index 25ec5c665780..fa7fe8d4f648 100644
> > --- a/include/hw/riscv/virt.h
> > +++ b/include/hw/riscv/virt.h
> > @@ -64,6 +64,7 @@ struct RISCVVirtState {
> > struct GPEXHost *gpex_host;
> > OnOffAuto iommu_sys;
> > uint16_t pci_iommu_bdf;
> > + uint16_t num_sources;
> > };
> >
> > enum {
> > diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c
> > index 0a89d7b49b7b..a9130896fba2 100644
> > --- a/hw/riscv/aia.c
> > +++ b/hw/riscv/aia.c
> > @@ -25,6 +25,7 @@ uint32_t imsic_num_bits(uint32_t count)
> > }
> >
> > DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> > + uint16_t num_sources,
> > const MemMapEntry *aplic_m,
> > const MemMapEntry *aplic_s,
> > const MemMapEntry *imsic_m,
> > @@ -37,6 +38,9 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> > DeviceState *aplic_s_dev = NULL;
> > DeviceState *aplic_m_dev = NULL;
> >
> > + /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */
> > + g_assert(num_sources <= 1023);
> > +
> How about the below check ?
>
> g_assert(num_sources <= VIRT_IRQCHIP_NUM_SOURCES);
>
> And modify VIRT_IRQCHIP_NUM_SOURCES in "aia.h" as below ?
>
> #define VIRT_IRQCHIP_NUM_SOURCES 1023
The names should probably be changed as new code is added. AFAIKS VIRT
only comes
from the riscv virt machine which was the first to use it. E.g., use
something like
#define RISCV_APLIC_MAX_NR_SORUCES 1023
Thanks,
Nick
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] hw/riscv/aia: Provide number of irq sources
2026-01-29 0:51 ` Nicholas Piggin
@ 2026-03-11 3:52 ` Joel Stanley
0 siblings, 0 replies; 11+ messages in thread
From: Joel Stanley @ 2026-03-11 3:52 UTC (permalink / raw)
To: Nicholas Piggin
Cc: Nutty.Liu, Alistair Francis, Daniel Henrique Barboza, Sunil V L,
qemu-devel, Weiwei Li, Liu Zhiwei, Michael Ellerman, Joel Stanley,
Nick Piggin, Anirudh Srinivasan, qemu-riscv
On Thu, 29 Jan 2026 at 11:21, Nicholas Piggin <npiggin@tenstorrent.com> wrote:
>
> On Wed, Jan 28, 2026 at 2:35 PM Nutty.Liu <nutty.liu@hotmail.com> wrote:
> >
> >
> > On 1/14/2026 9:28 AM, Joel Stanley wrote:
> > > Instead of hard coding the number of IRQ sources used by the APLIC pass
> > > it in as a parameter. This allows other machines to configure this as
> > > required.
> > >
> > > The maximum number of sources is 1023.
> > >
> > > Signed-off-by: Joel Stanley <joel@jms.id.au>
> > > ---
> > > v2: Add assert for the number of irq sources
> > > ---
> > > hw/riscv/aia.h | 1 +
> > > include/hw/riscv/virt.h | 1 +
> > > hw/riscv/aia.c | 8 ++++++--
> > > hw/riscv/virt-acpi-build.c | 25 ++++++++++++++++---------
> > > hw/riscv/virt.c | 2 ++
> > > 5 files changed, 26 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h
> > > index 50c48ea4d79c..a63a1ab293fe 100644
> > > --- a/hw/riscv/aia.h
> > > +++ b/hw/riscv/aia.h
> > > @@ -48,6 +48,7 @@
> > > uint32_t imsic_num_bits(uint32_t count);
> > >
> > > DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> > > + uint16_t num_sources,
> > > const MemMapEntry *aplic_m,
> > > const MemMapEntry *aplic_s,
> > > const MemMapEntry *imsic_m,
> > > diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> > > index 25ec5c665780..fa7fe8d4f648 100644
> > > --- a/include/hw/riscv/virt.h
> > > +++ b/include/hw/riscv/virt.h
> > > @@ -64,6 +64,7 @@ struct RISCVVirtState {
> > > struct GPEXHost *gpex_host;
> > > OnOffAuto iommu_sys;
> > > uint16_t pci_iommu_bdf;
> > > + uint16_t num_sources;
> > > };
> > >
> > > enum {
> > > diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c
> > > index 0a89d7b49b7b..a9130896fba2 100644
> > > --- a/hw/riscv/aia.c
> > > +++ b/hw/riscv/aia.c
> > > @@ -25,6 +25,7 @@ uint32_t imsic_num_bits(uint32_t count)
> > > }
> > >
> > > DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> > > + uint16_t num_sources,
> > > const MemMapEntry *aplic_m,
> > > const MemMapEntry *aplic_s,
> > > const MemMapEntry *imsic_m,
> > > @@ -37,6 +38,9 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
> > > DeviceState *aplic_s_dev = NULL;
> > > DeviceState *aplic_m_dev = NULL;
> > >
> > > + /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */
> > > + g_assert(num_sources <= 1023);
> > > +
> > How about the below check ?
> >
> > g_assert(num_sources <= VIRT_IRQCHIP_NUM_SOURCES);
> >
> > And modify VIRT_IRQCHIP_NUM_SOURCES in "aia.h" as below ?
> >
> > #define VIRT_IRQCHIP_NUM_SOURCES 1023
I didn't bump this as it changes the ACPI blob for the virt machine.
This was noticed by a test.
A follow up could change the virt machine to support the max number of
sources if someone was interested.
> The names should probably be changed as new code is added. AFAIKS VIRT
> only comes
> from the riscv virt machine which was the first to use it. E.g., use
> something like
>
> #define RISCV_APLIC_MAX_NR_SORUCES 1023
Yes, that would be more sensible if future users were added.
Cheers,
Joel
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-03-11 3:53 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-14 1:28 [PATCH 0/2] hw/riscv: Make virt AIA setup reusable Joel Stanley
2026-01-14 1:28 ` [PATCH 1/2] hw/riscv/virt: Move AIA initialisation to helper file Joel Stanley
2026-01-28 4:35 ` Nutty.Liu
2026-01-14 1:28 ` [PATCH 2/2] hw/riscv/aia: Provide number of irq sources Joel Stanley
2026-01-14 11:07 ` Daniel Henrique Barboza
2026-01-28 4:35 ` Nutty.Liu
2026-01-29 0:51 ` Nicholas Piggin
2026-03-11 3:52 ` Joel Stanley
2026-01-14 2:03 ` [PATCH 0/2] hw/riscv: Make virt AIA setup reusable Joel Stanley
-- strict thread matches above, loose matches on Subject: below --
2026-01-09 13:31 Joel Stanley
2026-01-09 13:31 ` [PATCH 2/2] hw/riscv/aia: Provide number of irq sources Joel Stanley
2026-01-13 12:27 ` Daniel Henrique Barboza
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox