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