git: 9f24c7d54222 - main - dev: acpica: Add PCI device methods for aarch64
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 17 Sep 2026 09:56:04 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=9f24c7d5422285d2a89c50253c54aa1502f26dd7
commit 9f24c7d5422285d2a89c50253c54aa1502f26dd7
Author: Sarah Walker <sarah.walker2@arm.com>
AuthorDate: 2026-08-04 12:35:08 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2026-09-17 09:20:22 +0000
dev: acpica: Add PCI device methods for aarch64
Add pci_get_id() and pci_alloc_msi() device methods for aarch64 platforms.
Reviewed by: markj (earlier version), andrew
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D59169
---
sys/arm64/acpica/acpi_iort.c | 60 ++++++++++++++++++++++++++++++++++++++++++++
sys/dev/acpica/acpi.c | 39 ++++++++++++++++++++++++++++
sys/dev/acpica/acpivar.h | 2 ++
3 files changed, 101 insertions(+)
diff --git a/sys/arm64/acpica/acpi_iort.c b/sys/arm64/acpica/acpi_iort.c
index eef2575fe432..3ca1ff0e32df 100644
--- a/sys/arm64/acpica/acpi_iort.c
+++ b/sys/arm64/acpica/acpi_iort.c
@@ -763,6 +763,19 @@ acpi_iort_lookup_iwb_node(device_t bus, device_t child)
return (NULL);
}
+int
+acpi_iort_lookup_pci_id(device_t bus, device_t child, uintptr_t *devid)
+{
+ struct iort_node *node;
+
+ node = acpi_iort_lookup_iwb_node(bus, child);
+ if (!node)
+ return (ENODEV);
+
+ *devid = node->entries.mappings[0].outbase;
+ return (0);
+}
+
int
acpi_iort_lookup_its_from_iwb(device_t dev, int *its_id)
{
@@ -786,6 +799,53 @@ acpi_iort_lookup_its_from_iwb(device_t dev, int *its_id)
return (ENODEV);
}
+int
+acpi_iort_alloc_msi(device_t bus, device_t dev, int *count)
+{
+ int *irqs;
+ int irq_count;
+ int error;
+ int i;
+ int its_id;
+ u_int xref;
+ int pxm;
+
+ irq_count = *count;
+ irqs = mallocarray(irq_count, sizeof(int), M_DEVBUF, M_WAITOK | M_ZERO);
+
+ error = acpi_iort_lookup_its_from_iwb(dev, &its_id);
+ if (error)
+ return (error);
+
+ error = acpi_iort_its_lookup(its_id, &xref, &pxm);
+ if (error)
+ return (error);
+
+ error = intr_alloc_msi(bus, dev, xref, irq_count, irq_count, irqs);
+ if (error)
+ return (error);
+
+ for (i = 0; i < irq_count; i++) {
+ error = bus_generic_rl_set_resource(bus, dev, SYS_RES_IRQ,
+ i + 1, irqs[i], 1);
+ if (error != 0)
+ break;
+ }
+
+ *count = irq_count;
+
+ /* Clean up resources if something failed */
+ if (error != 0) {
+ for (int j = 0; j < i; j++) {
+ bus_generic_rl_delete_resource(bus, dev, SYS_RES_IRQ,
+ j + 1);
+ }
+ }
+
+ free(irqs, M_DEVBUF);
+ return (error);
+}
+
device_t
acpi_iort_get_iwb_dev(int iwb_id)
{
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 351969058d72..5b4a5024b891 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -158,6 +158,9 @@ static acpi_scan_children_t acpi_device_scan_children;
static isa_pnp_probe_t acpi_isa_pnp_probe;
+static pci_get_id_t acpi_pci_get_id;
+static pci_alloc_msi_t acpi_pci_alloc_msi;
+
static void acpi_reserve_resources(device_t dev);
static int acpi_sysres_alloc(device_t dev);
static uint32_t acpi_isa_get_logicalid(device_t dev);
@@ -251,6 +254,10 @@ static device_method_t acpi_methods[] = {
/* ISA emulation */
DEVMETHOD(isa_pnp_probe, acpi_isa_pnp_probe),
+ /* PCI emulation */
+ DEVMETHOD(pci_get_id, acpi_pci_get_id),
+ DEVMETHOD(pci_alloc_msi, acpi_pci_alloc_msi),
+
DEVMETHOD_END
};
@@ -2364,6 +2371,38 @@ acpi_isa_pnp_probe(device_t bus, device_t child, struct isa_pnp_id *ids)
return_VALUE (result);
}
+static int
+acpi_pci_get_id(device_t dev, device_t child, enum pci_id_type type,
+ uintptr_t *id)
+{
+ if (dev != device_get_parent(child))
+ return (EINVAL);
+
+ if (type != PCI_ID_MSI)
+ return (EINVAL);
+
+#ifdef __aarch64__
+ if (acpi_iort_lookup_pci_id(dev, child, id) == 0)
+ return (0);
+#endif
+
+ return (ENXIO);
+}
+
+static int
+acpi_pci_alloc_msi(device_t bus, device_t child, int *count)
+{
+ if (bus != device_get_parent(child))
+ return (EINVAL);
+
+#ifdef __aarch64__
+ if (acpi_iort_alloc_msi(bus, child, count) == 0)
+ return (0);
+#endif
+
+ return (ENXIO);
+}
+
/*
* Look for a MCFG table. If it is present, use the settings for
* domain (segment) 0 to setup PCI config space access via the memory
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
index 05d581b77fb9..550c6ceb9c97 100644
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -642,6 +642,8 @@ int acpi_iort_map_named_smmuv3(const char *devname, u_int rid,
uint64_t *xref, u_int *devid);
int acpi_iort_lookup_its_from_iwb(device_t dev, int *its_id);
device_t acpi_iort_get_iwb_dev(int iwb_id);
+int acpi_iort_lookup_pci_id(device_t bus, device_t child, uintptr_t *devid);
+int acpi_iort_alloc_msi(device_t bus, device_t child, int *count);
#endif
#endif /* _KERNEL */
#endif /* !_ACPIVAR_H_ */