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