svn commit: r343860 - head/sys/dev/pci
Jayachandran C.
jchandra at FreeBSD.org
Thu Feb 7 04:50:17 UTC 2019
Author: jchandra
Date: Thu Feb 7 04:50:16 2019
New Revision: 343860
URL: https://svnweb.freebsd.org/changeset/base/343860
Log:
pci_host_generic_acpi: use IORT data for MSI/MSI-X
Use the information from IORT parsing to translate the PCI RID to
GIC ITS device ID. And similarly, use the information to find the
PIC XREF identifier to be used for PCI devices.
Reviewed by: andrew
Differential Revision: https://reviews.freebsd.org/D18004
Modified:
head/sys/dev/pci/pci_host_generic_acpi.c
Modified: head/sys/dev/pci/pci_host_generic_acpi.c
==============================================================================
--- head/sys/dev/pci/pci_host_generic_acpi.c Thu Feb 7 03:58:29 2019 (r343859)
+++ head/sys/dev/pci/pci_host_generic_acpi.c Thu Feb 7 04:50:16 2019 (r343860)
@@ -348,14 +348,52 @@ generic_pcie_acpi_route_interrupt(device_t bus, device
return (acpi_pcib_route_interrupt(bus, dev, pin, &sc->ap_prt));
}
+static u_int
+generic_pcie_get_xref(device_t pci, device_t child)
+{
+ struct generic_pcie_acpi_softc *sc;
+ uintptr_t rid;
+ u_int xref, devid;
+ int err;
+
+ sc = device_get_softc(pci);
+ err = pcib_get_id(pci, child, PCI_ID_RID, &rid);
+ if (err != 0)
+ return (ACPI_MSI_XREF);
+ err = acpi_iort_map_pci_msi(sc->base.ecam, rid, &xref, &devid);
+ if (err != 0)
+ return (ACPI_MSI_XREF);
+ return (xref);
+}
+
+static u_int
+generic_pcie_map_id(device_t pci, device_t child, uintptr_t *id)
+{
+ struct generic_pcie_acpi_softc *sc;
+ uintptr_t rid;
+ u_int xref, devid;
+ int err;
+
+ sc = device_get_softc(pci);
+ err = pcib_get_id(pci, child, PCI_ID_RID, &rid);
+ if (err != 0)
+ return (err);
+ err = acpi_iort_map_pci_msi(sc->base.ecam, rid, &xref, &devid);
+ if (err == 0)
+ *id = devid;
+ else
+ *id = rid; /* RID not in IORT, likely FW bug, ignore */
+ return (0);
+}
+
static int
generic_pcie_acpi_alloc_msi(device_t pci, device_t child, int count,
int maxcount, int *irqs)
{
#if defined(INTRNG)
- return (intr_alloc_msi(pci, child, ACPI_MSI_XREF, count, maxcount,
- irqs));
+ return (intr_alloc_msi(pci, child, generic_pcie_get_xref(pci, child),
+ count, maxcount, irqs));
#else
return (ENXIO);
#endif
@@ -367,7 +405,8 @@ generic_pcie_acpi_release_msi(device_t pci, device_t c
{
#if defined(INTRNG)
- return (intr_release_msi(pci, child, ACPI_MSI_XREF, count, irqs));
+ return (intr_release_msi(pci, child, generic_pcie_get_xref(pci, child),
+ count, irqs));
#else
return (ENXIO);
#endif
@@ -379,7 +418,8 @@ generic_pcie_acpi_map_msi(device_t pci, device_t child
{
#if defined(INTRNG)
- return (intr_map_msi(pci, child, ACPI_MSI_XREF, irq, addr, data));
+ return (intr_map_msi(pci, child, generic_pcie_get_xref(pci, child), irq,
+ addr, data));
#else
return (ENXIO);
#endif
@@ -390,7 +430,8 @@ generic_pcie_acpi_alloc_msix(device_t pci, device_t ch
{
#if defined(INTRNG)
- return (intr_alloc_msix(pci, child, ACPI_MSI_XREF, irq));
+ return (intr_alloc_msix(pci, child, generic_pcie_get_xref(pci, child),
+ irq));
#else
return (ENXIO);
#endif
@@ -401,7 +442,8 @@ generic_pcie_acpi_release_msix(device_t pci, device_t
{
#if defined(INTRNG)
- return (intr_release_msix(pci, child, ACPI_MSI_XREF, irq));
+ return (intr_release_msix(pci, child, generic_pcie_get_xref(pci, child),
+ irq));
#else
return (ENXIO);
#endif
@@ -412,14 +454,8 @@ generic_pcie_acpi_get_id(device_t pci, device_t child,
uintptr_t *id)
{
- /*
- * Use the PCI RID to find the MSI ID for now, we support only 1:1
- * mapping
- *
- * On aarch64, more complex mapping would come from IORT table
- */
if (type == PCI_ID_MSI)
- return (pcib_get_id(pci, child, PCI_ID_RID, id));
+ return (generic_pcie_map_id(pci, child, id));
else
return (pcib_get_id(pci, child, type, id));
}
More information about the svn-src-all
mailing list