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