Skip site navigation (1)Skip section navigation (2)
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>