Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64/dev Add the ofpci driver.
details: https://anonhg.NetBSD.org/src/rev/124c272b76fd
branches: trunk
changeset: 526587:124c272b76fd
user: eeh <eeh%NetBSD.org@localhost>
date: Mon May 06 19:39:51 2002 +0000
description:
Add the ofpci driver.
diffstat:
sys/arch/sparc64/dev/ofpci.c | 274 ++++++++++++++++++++++++++++++++++++++++
sys/arch/sparc64/dev/ofpcivar.h | 47 ++++++
2 files changed, 321 insertions(+), 0 deletions(-)
diffs (truncated from 329 to 300 lines):
diff -r b6e368406d15 -r 124c272b76fd sys/arch/sparc64/dev/ofpci.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sparc64/dev/ofpci.c Mon May 06 19:39:51 2002 +0000
@@ -0,0 +1,274 @@
+/* $NetBSD: ofpci.c,v 1.1 2002/05/06 19:39:51 eeh Exp $ */
+
+/*
+ * Copyright (c) 2002 Eduardo Horvath. All rights reserved.
+ *
+ * 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 Charles M. Hannum.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+/*
+ * OF PCI bus autoconfiguration.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ofpci.c,v 1.1 2002/05/06 19:39:51 eeh Exp $");
+
+#include "opt_pci.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_pci.h>
+
+#include <sparc64/dev/ofpcivar.h>
+
+extern int pci_config_dump;
+
+#ifdef DEBUG
+int ofpci_debug = 0;
+#define DPRINTF(l, s) do { if (ofpci_debug & l) printf s; } while (0)
+#else
+#define DPRINTF(l, s)
+#endif
+
+int ofpcimatch __P((struct device *, struct cfdata *, void *));
+void ofpciattach __P((struct device *, struct device *, void *));
+void ofpci_attach_device __P((struct device *, int, pci_chipset_tag_t, int));
+
+/* We use these for simplicity. */
+extern int pciprint __P((void *, const char *));
+extern int pcisubmatch __P((struct device *, struct cfdata *, void *));
+
+struct cfattach ofpci_ca = {
+ sizeof(struct ofpci_softc), ofpcimatch, ofpciattach
+};
+
+/* Provide pci_cd to make the pci driver happy since it's not in ioconf.c. */
+struct cfdriver pci_cd = {
+ NULL, "pci", DV_DULL
+};
+
+static char *getname(int );
+
+static char *
+getname(int node)
+{
+ static char name[30];
+
+ name[0] = name[29] = 0;
+ OF_getprop(node, "name", name, sizeof(name));
+ return (name);
+}
+
+int
+ofpcimatch(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct pcibus_attach_args *pba = aux;
+
+ DPRINTF(1, ("ofpcimatch: pba %s cd %s\n",
+ pba->pba_busname, cf->cf_driver->cd_name));
+
+ if (strcmp(pba->pba_busname, cf->cf_driver->cd_name))
+ return (0);
+
+ /* Check the locators */
+ if (cf->pcibuscf_bus != PCIBUS_UNK_BUS &&
+ cf->pcibuscf_bus != pba->pba_bus)
+ return (0);
+
+ /* sanity */
+ if (pba->pba_bus < 0 || pba->pba_bus > 255)
+ return (0);
+
+ /*
+ * XXX check other (hardware?) indicators
+ */
+ DPRINTF(1, ("ofpcimatch: success\n"));
+
+ return 1;
+}
+
+void
+ofpci_attach_device(struct device *self, int node,
+ pci_chipset_tag_t pc, int bus)
+{
+ struct ofpci_softc *sc = (struct ofpci_softc *)self;
+ struct pci_attach_args pa;
+ pcitag_t tag;
+ int id, class, intr, bhlcr, csr;
+ int device, function;
+ struct ofw_pci_register reg;
+
+ if (OF_getprop(node, "reg", (void *)®, sizeof(reg)) < sizeof(reg))
+ panic("ofpciattach: %s regs too small\n", getname(node));
+
+ if (bus != OFW_PCI_PHYS_HI_BUS(reg.phys_hi))
+ panic("ofpciattach: %s wrong bus", getname(node));
+ device = OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi);
+ function = OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi);
+
+ tag = ofpci_make_tag(pc, node, bus, device, function);
+ id = pci_conf_read(pc, tag, PCI_ID_REG);
+
+ if (OF_getprop(node, "class-code", &class, sizeof(class))
+ != sizeof(class))
+ panic("ofpciattach: %s no device class", getname(node));
+
+ class = pci_conf_read(pc, tag, PCI_CLASS_REG);
+
+ /* We may not have any interrupts */
+ intr = 0;
+ OF_getprop(node, "interrupts", &intr, sizeof(intr));
+
+
+ /* Invalid vendor ID value? */
+ if (PCI_VENDOR(id) == PCI_VENDOR_INVALID || PCI_VENDOR(id) == 0)
+ panic("ofpciattach: %s invalid vendor", getname(node));
+
+ csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
+ bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
+
+ pa.pa_iot = sc->sc_pcis.sc_iot;
+ pa.pa_memt = sc->sc_pcis.sc_memt;
+ pa.pa_dmat = sc->sc_pcis.sc_dmat;
+ pa.pa_pc = pc;
+ pa.pa_bus = bus;
+ pa.pa_device = device;
+ pa.pa_function = function;
+ pa.pa_tag = tag;
+ pa.pa_id = id;
+ pa.pa_class = class;
+
+ /*
+ * Set up memory, I/O enable, and PCI command flags
+ * as appropriate.
+ */
+ pa.pa_flags = sc->sc_pcis.sc_flags;
+ if ((csr & PCI_COMMAND_IO_ENABLE) == 0)
+ pa.pa_flags &= ~PCI_FLAGS_IO_ENABLED;
+ if ((csr & PCI_COMMAND_MEM_ENABLE) == 0)
+ pa.pa_flags &= ~PCI_FLAGS_MEM_ENABLED;
+
+ /*
+ * If the cache line size is not configured, then
+ * clear the MRL/MRM/MWI command-ok flags.
+ */
+ if (PCI_CACHELINE(bhlcr) == 0)
+ pa.pa_flags &= ~(PCI_FLAGS_MRL_OKAY|
+ PCI_FLAGS_MRM_OKAY|PCI_FLAGS_MWI_OKAY);
+
+ /*
+ * XXXX
+ * We'll just store the interrupts property in the pa_intrswiz
+ * field since it happens to be the right size.
+ */
+ pa.pa_intrswiz = intr;
+
+ config_found_sm(self, &pa, pciprint, pcisubmatch);
+}
+
+void
+ofpciattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct pcibus_attach_args *pba = aux;
+ struct ofpcibus_attach_args *opba = aux;
+ struct ofpci_softc *sc = (struct ofpci_softc *)self;
+ int io_enabled, mem_enabled, mrl_enabled, mrm_enabled, mwi_enabled;
+ int bus;
+ pci_chipset_tag_t pc;
+ int node;
+ static const char *sep = "";
+
+DPRINTF(1, ("ofpciattach: entry\n"));
+ printf("\n");
+
+ io_enabled = (pba->pba_flags & PCI_FLAGS_IO_ENABLED);
+ mem_enabled = (pba->pba_flags & PCI_FLAGS_MEM_ENABLED);
+ mrl_enabled = (pba->pba_flags & PCI_FLAGS_MRL_OKAY);
+ mrm_enabled = (pba->pba_flags & PCI_FLAGS_MRM_OKAY);
+ mwi_enabled = (pba->pba_flags & PCI_FLAGS_MWI_OKAY);
+
+ if (io_enabled == 0 && mem_enabled == 0) {
+ printf("%s: no spaces enabled!\n", self->dv_xname);
+ return;
+ }
+
+#define PRINT(s) do { printf("%s%s", sep, s); sep = ", "; } while (0)
+
+ printf("%s: ", self->dv_xname);
+
+ if (io_enabled)
+ PRINT("i/o space");
+ if (mem_enabled)
+ PRINT("memory space");
+ printf(" enabled");
+
+ if (mrl_enabled || mrm_enabled || mwi_enabled) {
+ if (mrl_enabled)
+ PRINT("rd/line");
+ if (mrm_enabled)
+ PRINT("rd/mult");
+ if (mwi_enabled)
+ PRINT("wr/inv");
+ printf(" ok");
+ }
+
+ printf("\n");
+
+#undef PRINT
+
+ sc->sc_pcis.sc_iot = pba->pba_iot;
+ sc->sc_pcis.sc_memt = pba->pba_memt;
+ sc->sc_pcis.sc_dmat = pba->pba_dmat;
+ sc->sc_pcis.sc_pc = pba->pba_pc;
+ sc->sc_pcis.sc_bus = pba->pba_bus;
+ sc->sc_pcis.sc_maxndevs = pci_bus_maxdevs(pba->pba_pc, pba->pba_bus);
+ sc->sc_pcis.sc_intrswiz = pba->pba_intrswiz;
+ sc->sc_pcis.sc_intrtag = pba->pba_intrtag;
+ sc->sc_pcis.sc_flags = pba->pba_flags;
+ sc->sc_node = opba->opba_node;
+
+ /* Now walk the OF device tree and attach all child nodes. */
+ pc = sc->sc_pcis.sc_pc;
+ bus = sc->sc_pcis.sc_bus;
+ for (node = OF_child(sc->sc_node); node != 0 && node != -1;
+ node = OF_peer(node)) {
+ DPRINTF(1, ("ofpciattach: attaching %s\n", getname(node)));
+ ofpci_attach_device(self, node, pc, bus);
+ }
+}
+
diff -r b6e368406d15 -r 124c272b76fd sys/arch/sparc64/dev/ofpcivar.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sparc64/dev/ofpcivar.h Mon May 06 19:39:51 2002 +0000
@@ -0,0 +1,47 @@
+/* $NetBSD: ofpcivar.h,v 1.1 2002/05/06 19:39:51 eeh Exp $ */
+
+/*
+ * Copyright (c) 2002 Eduardo Horvath
+ * All rights reserved.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
Home |
Main Index |
Thread Index |
Old Index