Date: Tue, 5 Apr 2011 11:04:12 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 191064 for review Message-ID: <201104051104.p35B4CTc021442@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@191064?ac=10 Change 191064 by jhb@jhb_kavik on 2011/04/05 11:03:35 Flesh out the new pcib_alloc_resource(). Need to add some bootverbose printfs next and then we can start trying it out. Affected files ... .. //depot/projects/pci/sys/dev/pci/pci_pci.c#7 edit Differences ... ==== //depot/projects/pci/sys/dev/pci/pci_pci.c#7 (text+ko) ==== @@ -110,7 +110,7 @@ { /* XXX: Can subtractive bridges still use windows? */ -#if 0 +#ifndef SUBTRACTIVE_WITH_WINDOWS /* Subtractive bridges don't manage resources. */ if (sc->flags & PCIB_SUBTRACTIVE) return (0); @@ -786,13 +786,22 @@ * The 'step' parameter is log_2 of the desired I/O window's alignment. */ static int -pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, u_long start, - u_long end, u_long count, u_int flags) +pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, + u_long start, u_long end, u_long count, u_int flags) { u_long align, start_free, end_free, front, back; int error, rid; /* + * Clamp the desired resource range to the maximum address + * this window supports. Reject impossible requests. + */ + if (end > w->max_address) + end = w->max_address; + if (start + count > end || start + count < start) + return (EINVAL); + + /* * If there is no resource at all, just try to allocate enough * aligned space for this resource. */ @@ -806,9 +815,8 @@ if (count < (1ul << w->step)) count = 1ul << w->step; rid = w->reg; - w->res = bus_alloc_resource(sc->dev, w == &sc->io ? - SYS_RES_IOPORT : SYS_RES_MEMORY, &rid, start, end, count, - flags); + w->res = bus_alloc_resource(sc->dev, type, &rid, start, end, + count, flags); if (w->res == NULL) return (ENXIO); goto updatewin; @@ -925,11 +933,106 @@ u_long start, u_long end, u_long count, u_int flags) { struct pcib_softc *sc; + struct resource *r; sc = device_get_softc(dev); + + /* + * VGA resources are decoded iff the VGA enable bit is set in + * the bridge control register. VGA resources do not fall into + * the resource windows and are passed up to the parent. + */ + if (type == SYS_RES_IOPORT && pci_is_vga_ioport_range(start, end) || + type == SYS_RES_MEMORY && pci_is_vga_memory_range(start, end)) { + if (sc->bridgectl & PCIB_BCR_VGA_ENABLE) + return (bus_generic_alloc_resource(dev, child, type, + rid, start, end, count, flags)); + else + return (NULL); + } + + /* + * XXX: Need similar handling for ISA resources subject to the + * ISA enable bit. + */ +#ifdef notyet + if (type == SYS_RES_IOPORT && pci_is_isa_ioport_range(start, end) || + type == SYS_RES_MEMORY && pci_is_isa_memory_range(start, end)) { + if (sc->bridgectl & PCIB_BCR_ISA_ENABLE) + return (bus_generic_alloc_resource(dev, child, type, + rid, start, end, count, flags)); + else + return (NULL); + } +#endif + +#ifndef SUBTRACTIVE_WITH_WINDOWS + /* + * XXX: What to do about subtractive bridges? Do they have windows? + */ + if (sc->flags & PCIB_SUBTRACTIVE) + return (bus_generic_alloc_resource(dev, child, type, rid, + stat, end, count, flags)); +#endif + switch (type) { - - + case SYS_RES_IOPORT: + r = pcib_suballoc_resource(sc, &sc->io, child, type, rid, start, + end, count, flags); + if (r != NULL) + break; +#ifdef SUBTRACTIVE_WITH_WINDOWS + if (sc->flags & PCIB_SUBTRACTIVE) + break; +#endif + if (pcib_grow_window(sc, &sc->io, type, start, end, count, + flags) == 0) + r = pcib_suballoc_resource(sc, &sc->io, child, type, + rid, start, end, count, flags); + break; + case SYS_RES_MEMORY: + /* + * For prefetchable resources, prefer the prefectable + * memory window, but fall back to the regular memory + * window if that fails. Try both windows before + * attempting to grow a window in case the firmware + * has used a range in the regular memory window to + * map a prefetchable BAR. + */ + if (flags & RF_PREFETCHABLE) { + r = pcib_suballoc_resource(sc, &sc->pmem, child, type, + rid, start, end, count, flags); + if (r != NULL) + break; + } + r = pcib_suballoc_resource(sc, &sc->mem, child, type, rid, + start, end, count, flags); + if (r != NULL) + break; +#ifdef SUBTRACTIVE_WITH_WINDOWS + if (sc->flags & PCIB_SUBTRACTIVE) + break; +#endif + if (flags & RF_PREFETCHABLE) { + if (pcib_grow_window(sc, &sc->pmem, type, start, end, + count, flags) == 0) { + r = pcib_suballoc_resource(sc, &sc->pmem, child, + type, rid, start, end, count, flags); + if (r != NULL) + break; + } + } + if (pcib_grow_window(sc, &sc->mem, type, start, end, count, + flags & ~RF_PREFETCHABLE) == 0) + r = pcib_suballoc_resource(sc, &sc->mem, child, type, + rid, start, end, count, flags); + break; + default: + return (bus_generic_alloc_resource(dev, child, type, rid, + stat, end, count, flags)); + } + return (r); +} #else /* * We have to trap resource allocation requests and ensure that the bridge
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104051104.p35B4CTc021442>