hw/riscv/aia: Provide number of irq sources
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. Reviewed-by: Nutty Liu <nutty.liu@hotmail.com> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Joel Stanley <joel@jms.id.au> Message-ID: <20260630024952.1520546-5-joel@jms.id.au> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Joel Stanley committed
Jun 30, 2026 at 12:19 UTC
2a4d7ad49bc849e2c655ad2120033fc0f4129cd0
5 files changed
+26
-13
hw/riscv/aia.c
+6
-2
@@ -25,6 +25,7 @@ uint32_t imsic_num_bits(uint32_t count)
25
}
26
27
DeviceState *riscv_create_aia(bool msimode, int aia_guests,
28
+ uint16_t num_sources,
29
const MemMapEntry *aplic_m,
30
const MemMapEntry *aplic_s,
31
const MemMapEntry *imsic_m,
@@ -38,6 +39,9 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
39
DeviceState *aplic_s_dev = NULL;
40
DeviceState *aplic_m_dev = NULL;
41
42
+ /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */
43
+ g_assert(num_sources <= 1023);
44
+
45
if (msimode) {
46
if (!kvm_enabled()) {
47
/* Per-socket M-level IMSICs */
@@ -66,7 +70,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
70
aplic_m->size,
71
(msimode) ? 0 : base_hartid,
72
(msimode) ? 0 : hart_count,
69
- VIRT_IRQCHIP_NUM_SOURCES,
73
+ num_sources,
74
num_prio_bits,
75
msimode, true, NULL);
76
}
@@ -77,7 +81,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guests,
81
aplic_s->size,
82
(msimode) ? 0 : base_hartid,
83
(msimode) ? 0 : hart_count,
80
- VIRT_IRQCHIP_NUM_SOURCES,
84
+ num_sources,
85
num_prio_bits,
86
msimode, false, aplic_m_dev);
87
hw/riscv/aia.h
+1
-2
@@ -11,11 +11,10 @@
11
12
#include "exec/hwaddr.h"
13
14
-#define VIRT_IRQCHIP_NUM_SOURCES 96
15
-
14
uint32_t imsic_num_bits(uint32_t count);
15
16
DeviceState *riscv_create_aia(bool msimode, int aia_guests,
17
+ uint16_t num_sources,
18
const MemMapEntry *aplic_m,
19
const MemMapEntry *aplic_s,
20
const MemMapEntry *imsic_m,
hw/riscv/virt-acpi-build.c
+16
-9
@@ -148,6 +148,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
148
}
149
150
static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
151
+ uint16_t num_sources,
152
uint64_t mmio_base, uint64_t mmio_size,
153
const char *hid)
154
{
@@ -155,9 +156,12 @@ static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
156
uint32_t gsi_base;
157
uint8_t socket;
158
159
+ /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */
160
+ g_assert(num_sources <= 1023);
161
+
162
for (socket = 0; socket < socket_count; socket++) {
163
plic_aplic_addr = mmio_base + mmio_size * socket;
160
- gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
164
+ gsi_base = num_sources * socket;
165
Aml *dev = aml_device("IC%.02X", socket);
166
aml_append(dev, aml_name_decl("_HID", aml_string("%s", hid)));
167
aml_append(dev, aml_name_decl("_UID", aml_int(socket)));
@@ -476,10 +480,13 @@ static void build_dsdt(GArray *table_data,
480
socket_count = riscv_socket_count(ms);
481
482
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
479
- acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_PLIC].base,
480
- memmap[VIRT_PLIC].size, "RSCV0001");
483
+ acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
484
+ memmap[VIRT_PLIC].base,
485
+ memmap[VIRT_PLIC].size,
486
+ "RSCV0001");
487
} else {
482
- acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_APLIC_S].base,
488
+ acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources,
489
+ memmap[VIRT_APLIC_S].base,
490
memmap[VIRT_APLIC_S].size, "RSCV0002");
491
}
492
@@ -496,15 +503,15 @@ static void build_dsdt(GArray *table_data,
503
} else if (socket_count == 2) {
504
virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
505
memmap[VIRT_VIRTIO].size,
499
- VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
506
+ VIRTIO_IRQ + s->num_sources, 0,
507
VIRTIO_COUNT);
501
- acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES);
508
+ acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources);
509
} else {
510
virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base,
511
memmap[VIRT_VIRTIO].size,
505
- VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0,
512
+ VIRTIO_IRQ + s->num_sources, 0,
513
VIRTIO_COUNT);
507
- acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 2);
514
+ acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources * 2);
515
}
516
517
aml_append(dsdt, scope);
@@ -583,7 +590,7 @@ static void build_madt(GArray *table_data,
590
for (socket = 0; socket < riscv_socket_count(ms); socket++) {
591
aplic_addr = s->memmap[VIRT_APLIC_S].base +
592
s->memmap[VIRT_APLIC_S].size * socket;
586
- gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
593
+ gsi_base = s->num_sources * socket;
594
build_append_int_noprefix(table_data, 0x1A, 1); /* Type */
595
build_append_int_noprefix(table_data, 36, 1); /* Length */
596
build_append_int_noprefix(table_data, 1, 1); /* Version */
hw/riscv/virt.c
+2
@@ -1401,6 +1401,7 @@ static void virt_machine_init(MachineState *machine)
1401
} else {
1402
s->irqchip[i] = riscv_create_aia(s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC,
1403
s->aia_guests,
1404
+ s->num_sources,
1405
&s->memmap[VIRT_APLIC_M],
1406
&s->memmap[VIRT_APLIC_S],
1407
&s->memmap[VIRT_IMSIC_M],
@@ -1557,6 +1558,7 @@ static void virt_machine_instance_init(Object *obj)
1558
s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
1559
s->acpi = ON_OFF_AUTO_AUTO;
1560
s->iommu_sys = ON_OFF_AUTO_AUTO;
1561
+ s->num_sources = VIRT_IRQCHIP_NUM_SOURCES;
1562
}
1563
1564
static char *virt_get_aia_guests(Object *obj, Error **errp)
include/hw/riscv/virt.h
+1
@@ -64,6 +64,7 @@ struct RISCVVirtState {
64
struct GPEXHost *gpex_host;
65
OnOffAuto iommu_sys;
66
uint16_t pci_iommu_bdf;
67
+ uint16_t num_sources;
68
};
69
70
enum {