From owner-svn-src-stable-11@freebsd.org Sat Oct 15 09:09:27 2016 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 46D3FC123D3; Sat, 15 Oct 2016 09:09:27 +0000 (UTC) (envelope-from mmel@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 mx1.freebsd.org (Postfix) with ESMTPS id 0899422D; Sat, 15 Oct 2016 09:09:26 +0000 (UTC) (envelope-from mmel@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9F99QMd052458; Sat, 15 Oct 2016 09:09:26 GMT (envelope-from mmel@FreeBSD.org) Received: (from mmel@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9F99Qvi052455; Sat, 15 Oct 2016 09:09:26 GMT (envelope-from mmel@FreeBSD.org) Message-Id: <201610150909.u9F99Qvi052455@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mmel set sender to mmel@FreeBSD.org using -f From: Michal Meloun Date: Sat, 15 Oct 2016 09:09:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r307347 - stable/11/sys/dev/ofw X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 15 Oct 2016 09:09:27 -0000 Author: mmel Date: Sat Oct 15 09:09:25 2016 New Revision: 307347 URL: https://svnweb.freebsd.org/changeset/base/307347 Log: MFC r302951,r302952,r304071: r302951: OFWPCI: Improve resource handling. - add new rman for prefetchable memory. Is used only if given 'ranges' property contains prefetchable memory range. r302952: OFWPCI: Add support for NEW_PCIB. r304071: OFWPCI: Don't strip RF_ACTIVE from flags when parent bus method is called. Modified: stable/11/sys/dev/ofw/ofwpci.c stable/11/sys/dev/ofw/ofwpci.h Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/ofw/ofwpci.c ============================================================================== --- stable/11/sys/dev/ofw/ofwpci.c Sat Oct 15 08:52:42 2016 (r307346) +++ stable/11/sys/dev/ofw/ofwpci.c Sat Oct 15 09:09:25 2016 (r307347) @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -94,6 +95,7 @@ static phandle_t ofw_pci_get_node(device * local methods */ static int ofw_pci_fill_ranges(phandle_t, struct ofw_pci_range *); +static struct rman *ofw_pci_get_rman(struct ofw_pci_softc *, int, u_int); /* * Driver methods. @@ -137,13 +139,14 @@ ofw_pci_init(device_t dev) phandle_t node; u_int32_t busrange[2]; struct ofw_pci_range *rp; - int error; + int i, error; struct ofw_pci_cell_info *cell_info; node = ofw_bus_get_node(dev); sc = device_get_softc(dev); sc->sc_initialized = 1; sc->sc_range = NULL; + sc->sc_pci_domain = device_get_unit(dev); cell_info = (struct ofw_pci_cell_info *)malloc(sizeof(*cell_info), M_DEVBUF, M_WAITOK | M_ZERO); @@ -201,17 +204,27 @@ ofw_pci_init(device_t dev) } sc->sc_mem_rman.rm_type = RMAN_ARRAY; - sc->sc_mem_rman.rm_descr = "PCI Memory"; + sc->sc_mem_rman.rm_descr = "PCI Non Prefetchable Memory"; error = rman_init(&sc->sc_mem_rman); if (error != 0) { device_printf(dev, "rman_init() failed. error = %d\n", error); goto out; } - for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange && - rp->pci_hi != 0; rp++) { + sc->sc_pmem_rman.rm_type = RMAN_ARRAY; + sc->sc_pmem_rman.rm_descr = "PCI Prefetchable Memory"; + error = rman_init(&sc->sc_pmem_rman); + if (error != 0) { + device_printf(dev, "rman_init() failed. error = %d\n", error); + goto out; + } + + for (i = 0; i < sc->sc_nrange; i++) { error = 0; + rp = sc->sc_range + i; + if (sc->sc_range_mask & ((uint64_t)1 << i)) + continue; switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { case OFW_PCI_PHYS_HI_SPACE_CONFIG: break; @@ -221,8 +234,14 @@ ofw_pci_init(device_t dev) break; case OFW_PCI_PHYS_HI_SPACE_MEM32: case OFW_PCI_PHYS_HI_SPACE_MEM64: - error = rman_manage_region(&sc->sc_mem_rman, rp->pci, - rp->pci + rp->size - 1); + if (rp->pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) { + sc->sc_have_pmem = 1; + error = rman_manage_region(&sc->sc_pmem_rman, + rp->pci, rp->pci + rp->size - 1); + } else { + error = rman_manage_region(&sc->sc_mem_rman, + rp->pci, rp->pci + rp->size - 1); + } break; } @@ -244,6 +263,7 @@ out: free(sc->sc_range, M_DEVBUF); rman_fini(&sc->sc_io_rman); rman_fini(&sc->sc_mem_rman); + rman_fini(&sc->sc_pmem_rman); return (error); } @@ -318,7 +338,7 @@ ofw_pci_read_ivar(device_t dev, device_t switch (which) { case PCIB_IVAR_DOMAIN: - *result = device_get_unit(dev); + *result = sc->sc_pci_domain; return (0); case PCIB_IVAR_BUS: *result = sc->sc_bus; @@ -385,28 +405,23 @@ ofw_pci_alloc_resource(device_t bus, dev struct rman *rm; int needactivate; + needactivate = flags & RF_ACTIVE; flags &= ~RF_ACTIVE; sc = device_get_softc(bus); - switch (type) { - case SYS_RES_MEMORY: - rm = &sc->sc_mem_rman; - break; - - case SYS_RES_IOPORT: - rm = &sc->sc_io_rman; - break; - - case SYS_RES_IRQ: - return (bus_alloc_resource(bus, type, rid, start, end, count, - flags)); +#if defined(NEW_PCIB) && defined(PCI_RES_BUS) + if (type == PCI_RES_BUS) { + return (pci_domain_alloc_bus(sc->sc_pci_domain, child, rid, + start, end, count, flags | needactivate)); + } +#endif - default: - device_printf(bus, "unknown resource request from %s\n", - device_get_nameunit(child)); - return (NULL); + rm = ofw_pci_get_rman(sc, type, flags); + if (rm == NULL) { + return (bus_generic_alloc_resource(bus, child, type, rid, + start, end, count, flags | needactivate)); } rv = rman_reserve_resource(rm, start, end, count, flags, child); @@ -435,15 +450,30 @@ static int ofw_pci_release_resource(device_t bus, device_t child, int type, int rid, struct resource *res) { + struct ofw_pci_softc *sc; + struct rman *rm; + int error; - if (rman_get_flags(res) & RF_ACTIVE) { - int error; + sc = device_get_softc(bus); + +#if defined(NEW_PCIB) && defined(PCI_RES_BUS) + if (type == PCI_RES_BUS) + return (pci_domain_release_bus(sc->sc_pci_domain, child, rid, + res)); +#endif + rm = ofw_pci_get_rman(sc, type, rman_get_flags(res)); + if (rm == NULL) { + return (bus_generic_release_resource(bus, child, type, rid, + res)); + } + KASSERT(rman_is_region_manager(res, rm), ("rman mismatch")); + + if (rman_get_flags(res) & RF_ACTIVE) { error = bus_deactivate_resource(child, type, rid, res); if (error != 0) return (error); } - return (rman_release_resource(res)); } @@ -454,63 +484,62 @@ ofw_pci_activate_resource(device_t bus, struct ofw_pci_softc *sc; bus_space_handle_t handle; bus_space_tag_t tag; + struct ofw_pci_range *rp; + vm_paddr_t start; + int space; int rv; sc = device_get_softc(bus); - if (type == SYS_RES_IRQ) { - return (bus_activate_resource(bus, type, rid, res)); + if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY) { + return (bus_generic_activate_resource(bus, child, type, rid, + res)); } - if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { - struct ofw_pci_range *rp; - vm_paddr_t start; - int space; - - start = (vm_paddr_t)rman_get_start(res); - - /* - * Map this through the ranges list - */ - for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange && - rp->pci_hi != 0; rp++) { - if (start < rp->pci || start >= rp->pci + rp->size) - continue; - - switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { - case OFW_PCI_PHYS_HI_SPACE_IO: - space = SYS_RES_IOPORT; - break; - case OFW_PCI_PHYS_HI_SPACE_MEM32: - case OFW_PCI_PHYS_HI_SPACE_MEM64: - space = SYS_RES_MEMORY; - break; - default: - space = -1; - } - if (type == space) { - start += (rp->host - rp->pci); - break; + start = (vm_paddr_t)rman_get_start(res); + + /* + * Map this through the ranges list + */ + for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange && + rp->pci_hi != 0; rp++) { + if (start < rp->pci || start >= rp->pci + rp->size) + continue; + + switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { + case OFW_PCI_PHYS_HI_SPACE_IO: + space = SYS_RES_IOPORT; + break; + case OFW_PCI_PHYS_HI_SPACE_MEM32: + case OFW_PCI_PHYS_HI_SPACE_MEM64: + space = SYS_RES_MEMORY; + break; + default: + space = -1; } + + if (type == space) { + start += (rp->host - rp->pci); + break; } + } - if (bootverbose) - printf("ofw_pci mapdev: start %jx, len %jd\n", - (rman_res_t)start, rman_get_size(res)); - - tag = BUS_GET_BUS_TAG(child, child); - if (tag == NULL) - return (ENOMEM); - - rman_set_bustag(res, tag); - rv = bus_space_map(tag, start, - rman_get_size(res), 0, &handle); - if (rv != 0) - return (ENOMEM); + if (bootverbose) + printf("ofw_pci mapdev: start %jx, len %jd\n", + (rman_res_t)start, rman_get_size(res)); + + tag = BUS_GET_BUS_TAG(child, child); + if (tag == NULL) + return (ENOMEM); + + rman_set_bustag(res, tag); + rv = bus_space_map(tag, start, + rman_get_size(res), 0, &handle); + if (rv != 0) + return (ENOMEM); - rman_set_bushandle(res, handle); - rman_set_virtual(res, (void *)handle); /* XXX for powerpc only ? */ - } + rman_set_bushandle(res, handle); + rman_set_virtual(res, (void *)handle); /* XXX for powerpc only ? */ return (rman_activate_resource(res)); } @@ -528,17 +557,19 @@ static int ofw_pci_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *res) { + struct ofw_pci_softc *sc; + vm_size_t psize; - /* - * If this is a memory resource, unmap it. - */ - if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) { - u_int32_t psize; + sc = device_get_softc(bus); - psize = rman_get_size(res); - pmap_unmapdev((vm_offset_t)rman_get_virtual(res), psize); + if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY) { + return (bus_generic_deactivate_resource(bus, child, type, rid, + res)); } + psize = rman_get_size(res); + pmap_unmapdev((vm_offset_t)rman_get_virtual(res), psize); + return (rman_deactivate_resource(res)); } @@ -550,24 +581,20 @@ ofw_pci_adjust_resource(device_t bus, de struct ofw_pci_softc *sc; sc = device_get_softc(bus); - KASSERT(!(rman_get_flags(res) & RF_ACTIVE), - ("active resources cannot be adjusted")); - if (rman_get_flags(res) & RF_ACTIVE) - return (EINVAL); +#if defined(NEW_PCIB) && defined(PCI_RES_BUS) + if (type == PCI_RES_BUS) + return (pci_domain_adjust_bus(sc->sc_pci_domain, child, res, + start, end)); +#endif - switch (type) { - case SYS_RES_MEMORY: - rm = &sc->sc_mem_rman; - break; - case SYS_RES_IOPORT: - rm = &sc->sc_io_rman; - break; - default: - return (ENXIO); + rm = ofw_pci_get_rman(sc, type, rman_get_flags(res)); + if (rm == NULL) { + return (bus_generic_adjust_resource(bus, child, type, res, + start, end)); } - - if (!rman_is_region_manager(res, rm)) - return (EINVAL); + KASSERT(rman_is_region_manager(res, rm), ("rman mismatch")); + KASSERT(!(rman_get_flags(res) & RF_ACTIVE), + ("active resources cannot be adjusted")); return (rman_adjust_resource(res, start, end)); } @@ -629,3 +656,22 @@ ofw_pci_fill_ranges(phandle_t node, stru free(base_ranges, M_DEVBUF); return (nranges); } + +static struct rman * +ofw_pci_get_rman(struct ofw_pci_softc *sc, int type, u_int flags) +{ + + switch (type) { + case SYS_RES_IOPORT: + return (&sc->sc_io_rman); + case SYS_RES_MEMORY: + if (sc->sc_have_pmem && (flags & RF_PREFETCHABLE)) + return (&sc->sc_pmem_rman); + else + return (&sc->sc_mem_rman); + default: + break; + } + + return (NULL); +} Modified: stable/11/sys/dev/ofw/ofwpci.h ============================================================================== --- stable/11/sys/dev/ofw/ofwpci.h Sat Oct 15 08:52:42 2016 (r307346) +++ stable/11/sys/dev/ofw/ofwpci.h Sat Oct 15 09:09:25 2016 (r307347) @@ -60,15 +60,19 @@ struct ofw_pci_softc { int sc_bus; int sc_initialized; int sc_quirks; + int sc_have_pmem; struct ofw_pci_range *sc_range; int sc_nrange; + uint64_t sc_range_mask; struct ofw_pci_cell_info *sc_cell_info; struct rman sc_io_rman; struct rman sc_mem_rman; + struct rman sc_pmem_rman; bus_space_tag_t sc_memt; bus_dma_tag_t sc_dmat; + int sc_pci_domain; struct ofw_bus_iinfo sc_pci_iinfo; };