@samitouri / QOSamiQemu / commits / 2a4d7ad49b

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 {