PERFORCE change 191064 for review
John Baldwin
jhb at FreeBSD.org
Tue Apr 5 11:04:13 UTC 2011
http://p4web.freebsd.org/@@191064?ac=10
Change 191064 by jhb at 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
More information about the p4-projects
mailing list