Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/powerpc/booke/pci Deal with PCIe/PCI hoses with mor...



details:   https://anonhg.NetBSD.org/src/rev/146a18ee24e6
branches:  trunk
changeset: 780950:146a18ee24e6
user:      matt <matt%NetBSD.org@localhost>
date:      Mon Aug 13 00:52:45 2012 +0000

description:
Deal with PCIe/PCI hoses with more than one window so the bus_space
encompasses all of it and reserves those portions not assigned so
no one can allocate from them.

diffstat:

 sys/arch/powerpc/booke/pci/pq3pci.c |  78 +++++++++++++++++++++++++++---------
 1 files changed, 59 insertions(+), 19 deletions(-)

diffs (154 lines):

diff -r b101b918ca91 -r 146a18ee24e6 sys/arch/powerpc/booke/pci/pq3pci.c
--- a/sys/arch/powerpc/booke/pci/pq3pci.c       Sun Aug 12 22:20:32 2012 +0000
+++ b/sys/arch/powerpc/booke/pci/pq3pci.c       Mon Aug 13 00:52:45 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pq3pci.c,v 1.13 2012/07/18 19:38:26 matt Exp $ */
+/*     $NetBSD: pq3pci.c,v 1.14 2012/08/13 00:52:45 matt Exp $ */
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -44,7 +44,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: pq3pci.c,v 1.13 2012/07/18 19:38:26 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pq3pci.c,v 1.14 2012/08/13 00:52:45 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -193,6 +193,10 @@
 
 struct pq3pci_bst {
        struct powerpc_bus_space bs_tag;
+       uint8_t bs_numwin;
+       bus_addr_t bs_base[3];
+       bus_addr_t bs_offset[3];
+       bus_addr_t bs_limit[3];
        char bs_name[16];
        char bs_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8)] __aligned(8);
 };
@@ -381,8 +385,8 @@
        uint32_t powar;
 };
 
-static bool
-pq3pci_owin_setup(struct pq3pci_softc *sc, u_int winnum,
+static void
+pq3pci_owin_record(struct pq3pci_softc *sc, u_int winnum,
        const struct pq3pci_owin *owin)
 {
        const bool io_win = (owin->powar & PEXOWAR_RTT) == PEXOWAR_RTT_IO;
@@ -391,12 +395,25 @@
            | ((uint64_t)owin->potear << (32+12));
        const uint64_t local_base = (uint64_t)owin->powbar << 12;
        const u_int win_size_log2 = PEXIWAR_IWS_GET(owin->powar) + 1;
+       u_int slot;
 
        bs->bs_tag.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN
            | (io_win ? _BUS_SPACE_IO_TYPE : _BUS_SPACE_MEM_TYPE);
-       bs->bs_tag.pbs_base = pci_base;
-       bs->bs_tag.pbs_offset = local_base - pci_base;
-       bs->bs_tag.pbs_limit = bs->bs_tag.pbs_base + (1ULL << win_size_log2);
+
+       for (slot = 0; slot < bs->bs_numwin; slot++) {
+               if (pci_base < bs->bs_base[slot]) {
+                       for (size_t j = slot; j < bs->bs_numwin; j++) {
+                               bs->bs_base[j+1] = bs->bs_base[j];
+                               bs->bs_offset[j+1] = bs->bs_offset[j];
+                               bs->bs_limit[j+1] = bs->bs_limit[j];
+                       }
+                       break;
+               }
+       }
+       bs->bs_base[slot] = pci_base;
+       bs->bs_offset[slot] = local_base - pci_base;
+       bs->bs_limit[slot] = pci_base + (1ULL << win_size_log2);
+       bs->bs_numwin++;
 
 #if 0
        const char units[] = " KMGTP";
@@ -409,9 +426,20 @@
            (owin->powar & PEXOWAR_RTT) == PEXOWAR_RTT_IO ? "I/O" : "memory",
            local_base, pci_base);
 #endif
+}
 
-       snprintf(bs->bs_name, sizeof(bs->bs_name), "%s-%s@%u",
-           device_xname(sc->sc_dev), io_win ? "io" : "mem", winnum);
+static bool
+pq3pci_owin_init(struct pq3pci_softc *sc, struct pq3pci_bst *bs, bool io_win)
+{
+       if (bs->bs_numwin == 0)
+               return true;
+
+       bs->bs_tag.pbs_base = bs->bs_base[0];
+       bs->bs_tag.pbs_offset = bs->bs_offset[0];
+       bs->bs_tag.pbs_limit = bs->bs_limit[bs->bs_numwin - 1];
+
+       snprintf(bs->bs_name, sizeof(bs->bs_name), "%s-%s",
+           device_xname(sc->sc_dev), io_win ? "io" : "mem");
 
 #if 0
        printf("%s: %s: base=%#x offset=%#x limit=%#x\n", __func__, bs->bs_name,
@@ -425,6 +453,19 @@
                    bs->bs_name, error);
                return false;
        }
+       for (size_t slot = 1; slot < bs->bs_numwin; slot++) {
+               if (bs->bs_limit[slot - 1] < bs->bs_base[slot]) {
+                       error = extent_alloc_region(bs->bs_tag.pbs_extent,
+                           bs->bs_limit[slot - 1],
+                           bs->bs_base[slot] - bs->bs_limit[slot - 1],
+                           EX_WAITOK);
+                       if (error) {
+                               aprint_error(": failed to hole in %s bus space: %d\n",
+                                   bs->bs_name, error);
+                               return false;
+                       }
+               }
+       }
        aprint_debug_dev(sc->sc_dev, "bus space %s created\n", bs->bs_name);
        sc->sc_pba_flags |=
            io_win ? PCI_FLAGS_IO_OKAY : PCI_FLAGS_MEM_OKAY;
@@ -732,10 +773,13 @@
 #endif
                if (owin.powar & PEXOWAR_EN) {
                        valid_owins++;
-                       if (!pq3pci_owin_setup(sc, i, &owin))
-                               return;
+                       pq3pci_owin_record(sc, i, &owin);
                }
        }
+       if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true)
+           || !pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) {
+               return;
+       }
 #ifndef PCI_NETBSD_CONFIGURE
        if (valid_owins == 0) {
                aprint_normal(": %s controller%s\n", buf,
@@ -837,10 +881,8 @@
                bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR1, owin1.potear);
                bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR1, owin1.powbar);
                bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR1, owin1.powar);
-               if (!pq3pci_owin_setup(sc, 1, &owin1)) {
-                       aprint_error(
-                           ": error creating bus space for %s\n",
-                           "PCI memory");
+               pq3pci_owin_record(sc, 1, &owin1);
+               if (!pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false) {
                        return;
                }
 
@@ -864,10 +906,8 @@
                bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR2, owin2.potear);
                bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR2, owin2.powbar);
                bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR2, owin2.powar);
-               if (!pq3pci_owin_setup(sc, 2, &owin2)) {
-                       aprint_error(
-                           ": error creating bus space for %s\n",
-                           "PCI I/O space");
+               pq3pci_owin_record(sc, 2, &owin1);
+               if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true) {
                        return;
                }
 



Home | Main Index | Thread Index | Old Index