Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Feb 2019 04:50:16 +0000 (UTC)
From:      "Jayachandran C." <jchandra@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r343860 - head/sys/dev/pci
Message-ID:  <201902070450.x174oGHj052244@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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));
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201902070450.x174oGHj052244>