From owner-svn-src-head@freebsd.org Mon Jun 22 10:49:51 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 5B6543479C5; Mon, 22 Jun 2020 10:49:51 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49r5lM1QxMz4Z2l; Mon, 22 Jun 2020 10:49:51 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 2C5FECEF6; Mon, 22 Jun 2020 10:49:51 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05MAnpJk039280; Mon, 22 Jun 2020 10:49:51 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05MAnpJs039279; Mon, 22 Jun 2020 10:49:51 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <202006221049.05MAnpJs039279@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Mon, 22 Jun 2020 10:49:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r362493 - head/sys/dev/pci X-SVN-Group: head X-SVN-Commit-Author: andrew X-SVN-Commit-Paths: head/sys/dev/pci X-SVN-Commit-Revision: 362493 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jun 2020 10:49:51 -0000 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));