svn commit: r362493 - head/sys/dev/pci

Andrew Turner andrew at FreeBSD.org
Mon Jun 22 10:49:51 UTC 2020


Author: andrew
Date: Mon Jun 22 10:49:50 2020
New Revision: 362493
URL: https://svnweb.freebsd.org/changeset/base/362493

Log:
  Translaate the PCI address when activating a resource
  
  When the PCI address != physical address we need to translate from the
  former to the latter before passing to the parent to map into the kernels
  virtual address space.
  
  Sponsored by:	Innovate UK

Modified:
  head/sys/dev/pci/pci_host_generic.c

Modified: head/sys/dev/pci/pci_host_generic.c
==============================================================================
--- head/sys/dev/pci/pci_host_generic.c	Mon Jun 22 10:32:41 2020	(r362492)
+++ head/sys/dev/pci/pci_host_generic.c	Mon Jun 22 10:49:50 2020	(r362493)
@@ -324,13 +324,11 @@ pci_host_generic_core_release_resource(device_t dev, d
 	return (bus_generic_release_resource(dev, child, type, rid, res));
 }
 
-struct resource *
-pci_host_generic_core_alloc_resource(device_t dev, device_t child, int type,
-    int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
+static bool
+generic_pcie_translate_resource(device_t dev, int type, rman_res_t start,
+    rman_res_t end, rman_res_t *new_start, rman_res_t *new_end)
 {
 	struct generic_pcie_core_softc *sc;
-	struct resource *res;
-	struct rman *rm;
 	uint64_t phys_base;
 	uint64_t pci_base;
 	uint64_t size;
@@ -338,19 +336,6 @@ pci_host_generic_core_alloc_resource(device_t dev, dev
 	bool found;
 
 	sc = device_get_softc(dev);
-
-#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
-	if (type == PCI_RES_BUS) {
-		return (pci_domain_alloc_bus(sc->ecam, child, rid, start, end,
-		    count, flags));
-	}
-#endif
-
-	rm = generic_pcie_rman(sc, type, flags);
-	if (rm == NULL)
-		return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
-		    type, rid, start, end, count, flags));
-
 	/* Translate the address from a PCI address to a physical address */
 	switch (type) {
 	case SYS_RES_IOPORT:
@@ -378,25 +363,57 @@ pci_host_generic_core_alloc_resource(device_t dev, dev
 			}
 
 			if (type == space) {
-				start = start - pci_base + phys_base;
-				end = end - pci_base + phys_base;
+				*new_start = start - pci_base + phys_base;
+				*new_end = end - pci_base + phys_base;
 				found = true;
 				break;
 			}
 		}
-		if (!found) {
-			device_printf(dev,
-			    "Failed to allocate %s resource %jx-%jx for %s\n",
-			    type == SYS_RES_IOPORT ? "IOPORT" : "MEMORY",
-			    (uintmax_t)start, (uintmax_t)end,
-			    device_get_nameunit(child));
-			return (NULL);
-		}
 		break;
 	default:
+		/* No translation for non-memory types */
+		*new_start = start;
+		*new_end = end;
+		found = true;
 		break;
 	}
 
+	return (found);
+}
+
+struct resource *
+pci_host_generic_core_alloc_resource(device_t dev, device_t child, int type,
+    int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
+{
+	struct generic_pcie_core_softc *sc;
+	struct resource *res;
+	struct rman *rm;
+	rman_res_t phys_start, phys_end;
+
+	sc = device_get_softc(dev);
+
+#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
+	if (type == PCI_RES_BUS) {
+		return (pci_domain_alloc_bus(sc->ecam, child, rid, start, end,
+		    count, flags));
+	}
+#endif
+
+	rm = generic_pcie_rman(sc, type, flags);
+	if (rm == NULL)
+		return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+		    type, rid, start, end, count, flags));
+
+	/* Translate the address from a PCI address to a physical address */
+	if (!generic_pcie_translate_resource(dev, type, start, end, &phys_start,
+	    &phys_end)) {
+		device_printf(dev,
+		    "Failed to translate resource %jx-%jx type %x for %s\n",
+		    (uintmax_t)start, (uintmax_t)end, type,
+		    device_get_nameunit(child));
+		return (NULL);
+	}
+
 	if (bootverbose) {
 		device_printf(dev,
 		    "rman_reserve_resource: start=%#jx, end=%#jx, count=%#jx\n",
@@ -430,12 +447,21 @@ generic_pcie_activate_resource(device_t dev, device_t 
     int rid, struct resource *r)
 {
 	struct generic_pcie_core_softc *sc;
+	rman_res_t start, end;
 	int res;
 
 	sc = device_get_softc(dev);
 
 	if ((res = rman_activate_resource(r)) != 0)
 		return (res);
+
+	start = rman_get_start(r);
+	end = rman_get_end(r);
+	if (!generic_pcie_translate_resource(dev, type, start, end, &start,
+	    &end))
+		return (EINVAL);
+	rman_set_start(r, start);
+	rman_set_end(r, end);
 
 	return (BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, type,
 	    rid, r));


More information about the svn-src-all mailing list