mb/emu/qemu-sbsa: Add GIC ITS and IORT for PCI MSI support

The QEMU sbsa-ref machine has a GICv3 ITS at 0x44081000 that handles
MSI/MSI-X translation for PCI devices. Without describing the ITS in
ACPI tables, Linux cannot set up MSI interrupts, causing warnings like:

  WARNING: CPU: 1 PID: 1 at drivers/pci/msi/msi.h:121 pci_msi_setup_msi_irqs+0x40/0x58
  xhci_hcd 0000:00:04.0: xHCI Host Controller

Add GIC ITS base address to the address map and implement
platform_get_gic_its() so the common MADT generation code emits
a GIC ITS entry.

Select ACPI_IORT and implement acpi_soc_fill_iort() to generate an
IORT table with an ITS Group node and a Root Complex node that maps
all PCI RIDs 1:1 to ITS device IDs.

Tested with Fedora 41 and a qemu-xhci USB controller.

Change-Id: I9366968aac855dae808f6f0c73f1d3ec644bbeff
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/91668
Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Arthur Heymans 2026-03-13 13:42:06 +01:00 committed by Matt DeVillier
commit bf037f3961
3 changed files with 42 additions and 0 deletions

View file

@ -21,6 +21,7 @@ config BOARD_SPECIFIC_OPTIONS
select PCI select PCI
select HAVE_ACPI_TABLES select HAVE_ACPI_TABLES
select ACPI_GTDT select ACPI_GTDT
select ACPI_IORT
select ACPI_COMMON_MADT_GICC_V3 select ACPI_COMMON_MADT_GICC_V3
select GENERATE_SMBIOS_TABLES select GENERATE_SMBIOS_TABLES

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h> #include <acpi/acpi.h>
#include <acpi/acpi_iort.h>
#include <mainboard/addressmap.h> #include <mainboard/addressmap.h>
@ -24,6 +25,45 @@ uintptr_t platform_get_gicr_base(void)
return SBSA_GIC_REDIST; return SBSA_GIC_REDIST;
} }
static uintptr_t gic_its[] = {
SBSA_GIC_ITS,
};
int platform_get_gic_its(uintptr_t **base)
{
*base = gic_its;
return ARRAY_SIZE(gic_its);
}
unsigned long acpi_soc_fill_iort(acpi_iort_t *iort, unsigned long current)
{
acpi_iort_node_t *its, *rc;
u32 its_reference;
u32 identifiers[] = {0}; /* GIC ITS ID 0 */
/* ITS Group node */
current = acpi_iort_its_entry(current, iort, &its, 1, identifiers);
its_reference = (unsigned long)its - (unsigned long)iort;
/* Root Complex node for PCIe host bridge (segment 0) */
current = acpi_iort_rc_entry(current, iort, &rc,
0, /* memory_properties */
0, /* ats_attribute */
0, /* pci_segment_number */
0x30, /* memory_address_limit (48-bit) */
0); /* pasid_capabilities */
/* Map all PCI RIDs (0-0xFFFF) 1:1 to ITS device IDs */
current = acpi_iort_id_map_entry(current, rc,
0, /* input_base */
0x10000, /* id_count (65536 RIDs) */
0, /* output_base */
its_reference, /* output_reference */
0); /* flags */
return current;
}
#define SEC_EL1_TIMER_GISV 0x1d #define SEC_EL1_TIMER_GISV 0x1d
#define NONSEC_EL1_TIMER_GSIV 0x1e #define NONSEC_EL1_TIMER_GSIV 0x1e
#define VIRTUAL_TIMER_GSIV 0x1b #define VIRTUAL_TIMER_GSIV 0x1b

View file

@ -16,6 +16,7 @@
#define SBSA_GPIO_BASE 0x60020000 #define SBSA_GPIO_BASE 0x60020000
#define SBSA_SECURE_UART_BASE 0x60030000 #define SBSA_SECURE_UART_BASE 0x60030000
#define SBSA_SMMU_BASE 0x60050000 #define SBSA_SMMU_BASE 0x60050000
#define SBSA_GIC_ITS 0x44081000
#define SBSA_AHCI_BASE 0x60100000 #define SBSA_AHCI_BASE 0x60100000
#define SBSA_EHCI_BASE 0x60110000 #define SBSA_EHCI_BASE 0x60110000
#define SBSA_SECMEM_BASE 0x20000000 #define SBSA_SECMEM_BASE 0x20000000