Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/macppc/pci - Completely rewrite how bus space tags ...



details:   https://anonhg.NetBSD.org/src/rev/5c83d9599632
branches:  trunk
changeset: 472702:5c83d9599632
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Wed May 05 04:37:19 1999 +0000

description:
- Completely rewrite how bus space tags for PCI space are set up.  Instead
of hard-coding them, decode the "ranges" property of the PCI bus node in
OpenFirmware.
- Do a little cleanup, and share some more code between the Bandit/Chaos
and MPC106.

XXX The bus_space(9) implementation for macppc really needs to be
rewritten.

diffstat:

 sys/arch/macppc/pci/bandit.c |  276 +++++++++++++++++++++++++++---------------
 1 files changed, 177 insertions(+), 99 deletions(-)

diffs (truncated from 380 to 300 lines):

diff -r 54ace56d8253 -r 5c83d9599632 sys/arch/macppc/pci/bandit.c
--- a/sys/arch/macppc/pci/bandit.c      Wed May 05 04:32:28 1999 +0000
+++ b/sys/arch/macppc/pci/bandit.c      Wed May 05 04:37:19 1999 +0000
@@ -1,4 +1,41 @@
-/*     $NetBSD: bandit.c,v 1.8 1999/03/29 12:12:03 tsubai Exp $        */
+/*     $NetBSD: bandit.c,v 1.9 1999/05/05 04:37:19 thorpej Exp $       */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the NetBSD
+ *     Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
 
 /*
  * Copyright 1991-1998 by Open Software Foundation, Inc. 
@@ -48,6 +85,7 @@
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 #include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_pci.h>
 
 #include <machine/bus.h>
 
@@ -75,10 +113,11 @@
 void
 pci_init()
 {
+
        scan_pci_devs();
 }
 
-void
+static void
 bandit_init(pc)
        pci_chipset_tag_t pc;
 {
@@ -89,108 +128,153 @@
        if ((pci_conf_read(pc, tag, PCI_ID_REG) & 0xffff) == 0xffff)
                return;
 
-       status  = pci_conf_read(pc, tag, PCI_REG_MODE_SELECT);
+       status = pci_conf_read(pc, tag, PCI_REG_MODE_SELECT);
 
        if ((status & PCI_MS_IO_COHERENT) == 0) {
                status |= PCI_MS_IO_COHERENT;
                pci_conf_write(pc, tag, PCI_REG_MODE_SELECT, status);
        }
-
-       return;
 }
 
 
-void
+static void
 scan_pci_devs()
 {
-       int node;
+       int reglen, node, child, n, is_bandit, is_mpc106;
        char name[64];
-       int n = 0;
-       u_int reg[2];
+       u_int32_t *p, reg[36];
 
        bzero(pci_bridges, sizeof(pci_bridges));
 
        node = OF_peer(0);
        node = OF_child(node);
 
-       while (node) {
+       for (n = 0; node != 0; node = OF_peer(node)) {
                if (OF_getprop(node, "name", name, sizeof(name)) <= 0)
                        continue;
-               if (strcmp(name, "bandit") == 0 ||
-                   strcmp(name, "chaos") == 0) {
-                       int child;
+
+               is_bandit = (strcmp(name, "bandit") == 0 ||
+                            strcmp(name, "chaos") == 0) ? 1 : 0;
+
+               /* XXX for now */
+               is_mpc106 = (strcmp(name, "pci") == 0) ? 1 : 0;
+
+               if (is_bandit == 0 && is_mpc106 == 0)
+                       continue;
+
+               /*
+                * Get the "ranges" property.  We're expecting 6 32-bit
+                * values for each address space:
+                *
+                *      phys.hi phys.mid phys.lo host size.hi size.lo
+                *
+                * Note that the MPC106 maps PCI memory space into
+                * two regions, one of which has a 24-bit addressing
+                * mode.  We don't know the order of the "ranges"
+                * property, but both Address Map modes of the MPC106
+                * map the 32-bit memory range at a lower host address
+                * than the 24-bit range.  We always pick the lower
+                * of the memory ranges for this reason.
+                */
+
+               pci_bridges[n].memt = (bus_space_tag_t) 0xffffffff;
+
+               reglen = OF_getproplen(node, "ranges");
+               if (reglen > sizeof(reg) || reglen <= 0 ||
+                   reglen % (6 * sizeof(u_int32_t)) != 0)
+                       continue;       /* eek */
+
+               reglen = OF_getprop(node, "ranges", reg, sizeof(reg));
 
+               for (p = reg; reglen > 0;
+                    reglen -= (6 * sizeof(u_int32_t)), p += 6) {
+                       switch (p[0] & OFW_PCI_PHYS_HI_SPACEMASK) {
+                       case OFW_PCI_PHYS_HI_SPACE_IO:
+                               pci_bridges[n].iot =
+                                   (bus_space_tag_t) p[3];
+                               break;
+
+                       case OFW_PCI_PHYS_HI_SPACE_MEM32:
+#if 0  /* XXX XXX XXX */
+                               if (pci_bridges[n].memt >
+                                   (bus_space_tag_t)p[3])
+                                       pci_bridges[n].memt =
+                                           (bus_space_tag_t) p[3];
+#else
+                               /*
+                                * XXX The Power Mac firmware seems to
+                                * XXX include the PCI memory space base
+                                * XXX in the device's BARs.  We can remove
+                                * XXX this kludge from here once we
+                                * XXX fix the bus_space(9) implelentation.
+                                */
+                               pci_bridges[n].memt = (bus_space_tag_t) 0;
+#endif
+                               break;
+
+                       /* XXX What about OFW_PCI_PHYS_HI_SPACE_MEM64? */
+                       }
+               }
+
+               /*
+                * The "bus-range" property tells us our PCI bus number.
+                */
+               if (OF_getprop(node, "bus-range", reg, sizeof(reg)) != 8)
+                       continue;
+
+               pci_bridges[n].bus = reg[0];
+
+               /*
+                * Map the PCI configuration space access registers,
+                * and perform any PCI-Host bridge initialization.
+                */
+               if (is_bandit) {
+                       /* XXX magic numbers */
                        if (OF_getprop(node, "reg", reg, sizeof(reg)) != 8)
                                continue;
-
-                       pci_bridges[n].iot  = (bus_space_tag_t)reg[0];
                        pci_bridges[n].addr = mapiodev(reg[0] + 0x800000, 4);
                        pci_bridges[n].data = mapiodev(reg[0] + 0xc00000, 4);
                        pci_bridges[n].pc = n;
-
-                       if (OF_getprop(node, "bus-range",
-                                      reg, sizeof(reg)) != 8) {
-                               pci_bridges[n].addr = NULL;
-                               continue;
-                       }
-                       pci_bridges[n].bus = reg[0];
-
                        bandit_init(n);
-
-                       child = OF_child(node);
-                       while (child) {
-                               config_slot(child, n, -1);
-                               child = OF_peer(child);
-                       }
-                       n++;
-               }
-               if (strcmp(name, "pci") == 0) { /* XXX This is not a bandit :) */
-                       int child;
-
-                       if (OF_getprop(node, "reg", reg, sizeof(reg)) != 8)
-                               continue;
-
-                       pci_bridges[n].iot  = (bus_space_tag_t)reg[0];
-                       pci_bridges[n].addr = mapiodev(0xfec00000, 4); /* XXX */
-                       pci_bridges[n].data = mapiodev(0xfee00000, 4); /* XXX */
+               } else if (is_mpc106) {
+                       /* XXX magic numbers */
+                       pci_bridges[n].addr = mapiodev(0xfec00000, 4);
+                       pci_bridges[n].data = mapiodev(0xfee00000, 4);
                        pci_bridges[n].pc = PCI_CHIPSET_MPC106; /* for now */
-
-                       if (OF_getprop(node, "bus-range",
-                                      reg, sizeof(reg)) != 8) {
-                               pci_bridges[n].addr = NULL;
-                               continue;
-                       }
-                       pci_bridges[n].bus = reg[0];
-
-                       child = OF_child(node);
-                       while (child) {
-                               config_slot(child, pci_bridges[n].pc, -1);
-                               child = OF_peer(child);
-                       }
-                       n++;
                }
 
-               node = OF_peer(node);
+               /*
+                * Configure all of the PCI devices attached to this
+                * PCI-Host bridge.
+                */
+               child = OF_child(node);
+               while (child) {
+                       config_slot(child, pci_bridges[n].pc, -1);
+                       child = OF_peer(child);
+               }
+
+               /* Bridge found, increment bridge instance. */
+               n++;
        }
 }
 
-void
+static void
 config_slot(node, pc, irq)
        int node;
        pci_chipset_tag_t pc;
        int irq;
 {
        pcitag_t tag;
-       int sp, intr, csr;
+       pcireg_t csr, intr;
+       int i, sz;
        int bus, dev, func;
-       int sz;
-       u_int reg[40], *rp;
+       u_int32_t reg[40], *rp;
        char name[16];
        struct {
-               u_int device;
-               u_int junk[3];
-               u_int intrnode;
-               u_int interrupt;
+               u_int32_t device;
+               u_int32_t junk[3];
+               u_int32_t intrnode;
+               u_int32_t interrupt;
        } imap[16];
 
        bzero(name, sizeof(name));
@@ -211,37 +295,39 @@
        if (sz < 4)
                return;
 
-       /*
-        * npt000ss bbbbbbbb dddddfff rrrrrrrr
-        *
-        * ss   space code (01:I/O, 10:32bit mem)
-        * b... 8-bit Bus Number
-        * d... 5-bit Device Number
-        * f... 3-bit Function Number
-        * r... 8-bit Register Number
-        */
-       rp = &reg[0];
-       bus = (*rp >> 16) & 0xff;
-       dev = (*rp >> 11) & 0x1f;
-       func = (*rp >> 8) & 0x07;
+       rp = reg;



Home | Main Index | Thread Index | Old Index