Subject: re: E250 support?
To: Mark Blackman <mark.blackman@netscalibur.co.uk>
From: matthew green <mrg@eterna.com.au>
List: port-sparc64
Date: 02/12/2001 13:57:24
try ftp.netbsd.org:/pub/NetBSD/arch/sparc64/kernels/NetBSD-1.5R-2
it was built with this patch:
Index: arch/sparc64/dev/simba.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/dev/simba.c,v
retrieving revision 1.2
diff -p -p -u -r1.2 simba.c
--- arch/sparc64/dev/simba.c 2000/05/24 20:27:52 1.2
+++ arch/sparc64/dev/simba.c 2001/02/11 18:09:28
@@ -135,6 +135,9 @@ simba_attach(parent, self, aux)
pba.pba_bus = PPB_BUSINFO_SECONDARY(busdata);
pba.pba_intrswiz = pa->pa_intrswiz;
pba.pba_intrtag = pa->pa_intrtag;
+#ifdef __PCI_OFW_BINDING
+ pba.pba_node = pa->pa_node;
+#endif
config_found(self, &pba, simba_print);
}
Index: arch/sparc64/dev/psycho.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/dev/psycho.c,v
retrieving revision 1.28
diff -p -p -u -r1.28 psycho.c
--- arch/sparc64/dev/psycho.c 2000/12/04 20:29:34 1.28
+++ arch/sparc64/dev/psycho.c 2001/02/11 18:09:29
@@ -209,6 +209,9 @@ psycho_attach(parent, self, aux)
pba.pba_dmat = sc->sc_psycho_this->pp_dmat;
pba.pba_iot = sc->sc_psycho_this->pp_iot;
pba.pba_memt = sc->sc_psycho_this->pp_memt;
+#ifdef __PCI_OFW_BINDING
+ pba.pba_node = sc->sc_node;
+#endif
config_found(self, &pba, psycho_print);
}
Index: arch/sparc64/include/pci_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/include/pci_machdep.h,v
retrieving revision 1.5
diff -p -p -u -r1.5 pci_machdep.h
--- arch/sparc64/include/pci_machdep.h 2000/12/28 22:59:10 1.5
+++ arch/sparc64/include/pci_machdep.h 2001/02/11 18:09:29
@@ -65,4 +65,7 @@ void *pci_intr_establish(pci_chipset_ta
int, int (*)(void *), void *);
void pci_intr_disestablish(pci_chipset_tag_t, void *);
+/* want pci_attach_args{}->pa_node */
+#define __PCI_OFW_BINDING
+
#endif /* _MACHINE_PCI_MACHDEP_H_ */
Index: dev/pci/pci.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/pci.c,v
retrieving revision 1.49
diff -p -p -u -r1.49 pci.c
--- dev/pci/pci.c 2000/06/28 16:08:48 1.49
+++ dev/pci/pci.c 2001/02/11 18:09:29
@@ -45,6 +45,11 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
+#ifdef __PCI_OFW_BINDING
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_pci.h>
+#endif
+
#ifdef PCI_CONFIG_DUMP
int pci_config_dump = 1;
#else
@@ -72,11 +77,9 @@ struct cfattach pci_ca = {
sizeof(struct pci_softc), pcimatch, pciattach
};
-#ifdef __PCI_OFW_BINDING
-void pci_ofw_probe_bus __P((struct device *));
-#else
+void pci_probe_function(struct device *, struct pci_attach_args *,
+ pci_chipset_tag_t, int, int);
void pci_probe_bus __P((struct device *));
-#endif
int pciprint __P((void *, const char *));
int pcisubmatch __P((struct device *, struct cfdata *, void *));
@@ -133,16 +136,124 @@ pcimatch(parent, cf, aux)
return 1;
}
-#ifdef __PCI_OFW_BINDING
+/*
+ * Probe a single function. Call by both the generic and OFW bus probe
+ * routines.
+ */
void
-pci_ofw_probe_bus(self)
+pci_probe_function(self, pa, pc, device, function)
struct device *self;
+ struct pci_attach_args *pa;
+ pci_chipset_tag_t pc;
+ int device, function;
{
+ pcireg_t tag, intr, csr, id, class;
struct pci_softc *sc = (struct pci_softc *)self;
+ int bus = sc->sc_bus;
+ int pin;
+
+ tag = pci_make_tag(pc, bus, device, function);
+ id = pci_conf_read(pc, tag, PCI_ID_REG);
+ csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
+ class = pci_conf_read(pc, tag, PCI_CLASS_REG);
+ intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
+
+ /* Invalid vendor ID value? */
+ if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
+ return;
+ /* XXX Not invalid, but we've done this ~forever. */
+ if (PCI_VENDOR(id) == 0)
+ return;
+
+ pa->pa_iot = sc->sc_iot;
+ pa->pa_memt = sc->sc_memt;
+ pa->pa_dmat = sc->sc_dmat;
+ pa->pa_pc = pc;
+ pa->pa_device = device;
+ pa->pa_function = function;
+ pa->pa_tag = tag;
+ pa->pa_id = id;
+ pa->pa_class = class;
+
+ /* From here on is identical to non-OFW version */
+ /*
+ * Set up memory, I/O enable, and PCI command flags
+ * as appropriate.
+ */
+ pa->pa_flags = sc->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 (bus == 0) {
+ pa->pa_intrswiz = 0;
+ pa->pa_intrtag = pa->pa_tag;
+ } else {
+ pa->pa_intrswiz = sc->sc_intrswiz + device;
+ pa->pa_intrtag = sc->sc_intrtag;
+ }
+ pin = PCI_INTERRUPT_PIN(intr);
+ if (pin == PCI_INTERRUPT_PIN_NONE) {
+ /* no interrupt */
+ pa->pa_intrpin = 0;
+ } else {
+ /*
+ * swizzle it based on the number of
+ * busses we're behind and our device
+ * number.
+ */
+ pa->pa_intrpin = /* XXX */
+ ((pin + pa->pa_intrswiz - 1) % 4) + 1;
+ }
+ pa->pa_intrline = PCI_INTERRUPT_LINE(intr);
+
+ config_found_sm(self, pa, pciprint, pcisubmatch);
+}
+
+#ifdef __PCI_OFW_BINDING
+static __inline pcireg_t pci_OF_getpropint(int node, char *prop);
+
+static __inline pcireg_t
+pci_OF_getpropint(node, prop)
int node;
+ char *prop;
+{
+ int it, len;
+
+ if ((len = OF_getproplen(node, prop)) != sizeof(it) ||
+ OF_getprop(node, prop, &it, sizeof(it)) == 0)
+ return (pcireg_t)~0;
+
+ return (pcireg_t)it;
+
+}
+void
+pci_probe_bus(self)
+ struct device *self;
+{
+ struct pci_softc *sc = (struct pci_softc *)self;
+ struct ofw_pci_register reg0;
+ struct pci_attach_args pa;
+ int node, bus, device, function, len;
+ pci_chipset_tag_t pc;
+
+ bus = sc->sc_bus;
+ pc = sc->sc_pc;
for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) {
+ len = OF_getproplen(node, "reg");
+ if (len <= 0)
+ continue;
+ if (OF_getprop(node, "reg", (void *)®0, sizeof(reg0)) != len)
+ panic("pci_probe_bus: OF_getprop len botch");
+
+ device = OFW_PCI_PHYS_HI_DEVICE(reg0.phys_hi);
+ function = OFW_PCI_PHYS_HI_FUNCTION(reg0.phys_hi);
+
+ pa.pa_node = node;
+ pci_probe_function(self, &pa, pc, device, function);
}
}
#else
@@ -164,9 +275,8 @@ pci_probe_bus(self)
for (device = 0; device < maxndevs; device++) {
pcitag_t tag;
- pcireg_t id, class, intr, bhlcr, csr;
+ pcireg_t id, bhlcr;
struct pci_attach_args pa;
- int pin;
tag = pci_make_tag(pc, bus, device, 0);
id = pci_conf_read(pc, tag, PCI_ID_REG);
@@ -188,64 +298,8 @@ pci_probe_bus(self)
else
nfunctions = 1;
- for (function = 0; function < nfunctions; function++) {
- tag = pci_make_tag(pc, bus, device, function);
- id = pci_conf_read(pc, tag, PCI_ID_REG);
- csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
- class = pci_conf_read(pc, tag, PCI_CLASS_REG);
- intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
-
- /* Invalid vendor ID value? */
- if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
- continue;
- /* XXX Not invalid, but we've done this ~forever. */
- if (PCI_VENDOR(id) == 0)
- continue;
-
- pa.pa_iot = iot;
- pa.pa_memt = memt;
- pa.pa_dmat = sc->sc_dmat;
- pa.pa_pc = pc;
- 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_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 (bus == 0) {
- pa.pa_intrswiz = 0;
- pa.pa_intrtag = tag;
- } else {
- pa.pa_intrswiz = sc->sc_intrswiz + device;
- pa.pa_intrtag = sc->sc_intrtag;
- }
- pin = PCI_INTERRUPT_PIN(intr);
- if (pin == PCI_INTERRUPT_PIN_NONE) {
- /* no interrupt */
- pa.pa_intrpin = 0;
- } else {
- /*
- * swizzle it based on the number of
- * busses we're behind and our device
- * number.
- */
- pa.pa_intrpin = /* XXX */
- ((pin + pa.pa_intrswiz - 1) % 4) + 1;
- }
- pa.pa_intrline = PCI_INTERRUPT_LINE(intr);
-
- config_found_sm(self, &pa, pciprint, pcisubmatch);
- }
+ for (function = 0; function < nfunctions; function++)
+ pci_probe_function(self, &pa, pc, device, function);
}
}
#endif
@@ -309,11 +363,8 @@ pciattach(parent, self, aux)
sc->sc_flags = pba->pba_flags;
#ifdef __PCI_OFW_BINDING
sc->sc_node = pba->pba_node;
-
- pci_ofw_probe_bus(self);
-#else
- pci_probe_bus(self);
#endif
+ pci_probe_bus(self);
}
int
Index: dev/pci/ppb.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/pci/ppb.c,v
retrieving revision 1.19
diff -p -p -u -r1.19 ppb.c
--- dev/pci/ppb.c 1999/11/04 19:04:04 1.19
+++ dev/pci/ppb.c 2001/02/11 18:09:29
@@ -117,6 +117,9 @@ ppbattach(parent, self, aux)
pba.pba_bus = PPB_BUSINFO_SECONDARY(busdata);
pba.pba_intrswiz = pa->pa_intrswiz;
pba.pba_intrtag = pa->pa_intrtag;
+#ifdef __PCI_OFW_BINDING
+ pba.pba_node = pa->pa_node;
+#endif
config_found(self, &pba, ppbprint);
}
Index: dev/ofw/ofw_pci.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ofw/ofw_pci.h,v
retrieving revision 1.2
diff -p -p -u -r1.2 ofw_pci.h
--- dev/ofw/ofw_pci.h 1999/05/05 08:09:34 1.2
+++ dev/ofw/ofw_pci.h 2001/02/11 18:09:30
@@ -87,4 +87,20 @@
#define OFW_PCI_PHYS_HI_SPACE_MEM32 0x02000000
#define OFW_PCI_PHYS_HI_SPACE_MEM64 0x03000000
+#define OFW_PCI_PHYS_HI_DEVICE(hi) \
+ (((hi) & OFW_PCI_PHYS_HI_DEVICEMASK) >> OFW_PCI_PHYS_HI_DEVICESHIFT)
+#define OFW_PCI_PHYS_HI_FUNCTION(hi) \
+ (((hi) & OFW_PCI_PHYS_HI_FUNCTIONMASK) >> OFW_PCI_PHYS_HI_FUNCTIONSHIFT)
+
+/*
+ * This has the 3 32bit cell values, plus 2 more to make up a 64-bit size.
+ */
+struct ofw_pci_register {
+ u_int32_t phys_hi;
+ u_int32_t phys_mid;
+ u_int32_t phys_lo;
+ u_int32_t size_hi;
+ u_int32_t size_lo;
+};
+
#endif /* _DEV_OFW_OFW_PCI_H_ */