From owner-p4-projects@FreeBSD.ORG Tue Apr 5 11:04:13 2011 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5521E1065672; Tue, 5 Apr 2011 11:04:13 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 17BB0106566C for ; Tue, 5 Apr 2011 11:04:13 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 036138FC0C for ; Tue, 5 Apr 2011 11:04:13 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id p35B4CGW021445 for ; Tue, 5 Apr 2011 11:04:12 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id p35B4CTc021442 for perforce@freebsd.org; Tue, 5 Apr 2011 11:04:12 GMT (envelope-from jhb@freebsd.org) Date: Tue, 5 Apr 2011 11:04:12 GMT Message-Id: <201104051104.p35B4CTc021442@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 191064 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Apr 2011 11:04:13 -0000 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