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));
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to