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 <[email protected]>
---

Reviewed-by: Daniel Henrique Barboza <[email protected]>


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)


Reply via email to