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
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)
© 2016 - 2026 Red Hat, Inc.