Subject: data corruption (Re: Binding more than one IP to a NIC)
To: None <port-cobalt@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-cobalt
Date: 11/08/2004 23:40:52
(subject changed)

In article <78a2305a0411071245689d1911@mail.gmail.com>
acruhl@gmail.com wrote:

> On Sun, 7 Nov 2004 21:28:06 +0100, Markus W Kilbinger
> <kilbi@rad.rwth-aachen.de> wrote:
> > >> Kevin Lahey <kml@patheticgeek.net> writes:
> > >> Looking at the kernel backtraces that I get when things go wrong,
> > >> it seems more like a MIPS-specific VM issue than a Tulip driver
> > >> issue. I agree that it is a problem.
> > 
> > My impression, too! (see
> > http://mail-index.netbsd.org/port-cobalt/2004/11/04/0000.html )
> > 
> > I've played with cobalt/cobalt/bus.c dcache handling during pci i/o
> > lst day; I still get corrupted files!
 :
> I think it was Izumi who said that the PCI implementation on the
> cobalt is weird and this is what was causing it. I don't know the
> details. They were talking for a while about getting a change into the
> machine independent code though, which is going to great lengths to
> get it fixed.

Well, AFAIK the problem on cobalt PCI implementation affects
memory mapped PCI devices (like siop), so I'm not sure if
it fixes your "data corruption" problem.
(patch attached, including MI changes filed in kern/27423)

On the other hand, there is a patch for MIPS r5k cache:
http://mail-index.netbsd.org/port-sgimips/2003/01/06/0001.html

Anyway, I also have a NetBSD/arc machine (R4400) running 2.0G
as file server and it has no data corruption for 2 months,
so I don't think there is MIPS _common_ VM issue, but
I also see some problem reports on r5k O2.
(I wonder if current mips pmap handles 2-way set associative
 cache on r5k CPUs)
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp

Index: arch/cobalt/dev/gt.c
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/dev/gt.c,v
retrieving revision 1.12
diff -u -r1.12 gt.c
--- arch/cobalt/dev/gt.c	30 Aug 2004 15:05:16 -0000	1.12
+++ arch/cobalt/dev/gt.c	8 Nov 2004 14:19:28 -0000
@@ -28,6 +28,9 @@
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: gt.c,v 1.12 2004/08/30 15:05:16 drochner Exp $");
 
+#include "opt_pci.h"
+#include "pci.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/ioctl.h>
@@ -42,18 +45,21 @@
 #include <sys/syslog.h>
 #include <sys/types.h>
 #include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/extent.h>
 
 #include <machine/autoconf.h>
 #include <machine/bus.h>
 #include <machine/intr.h>
 
 #include <dev/pci/pcivar.h>
+#ifdef PCI_NETBSD_CONFIGURE
+#include <dev/pci/pciconf.h>
+#endif
 
 #include <cobalt/cobalt/clockvar.h>
 #include <cobalt/dev/gtreg.h>
 
-#include "pci.h"
-
 struct gt_softc {
 	struct device	sc_dev;
 
@@ -117,6 +123,13 @@
 	pc->pc_bst = sc->sc_bst;
 	pc->pc_bsh = sc->sc_bsh;
 
+#ifdef PCI_NETBSD_CONFIGURE
+	pc->pc_ioext = extent_create("pciio", 0x10100000, 0x11ffffff,
+	    M_DEVBUF, NULL, 0, EX_NOWAIT);
+	pc->pc_memext = extent_create("pcimem", 0x12000000, 0x13ffffff,
+	    M_DEVBUF, NULL, 0, EX_NOWAIT);
+	pci_configure_bus(pc, pc->pc_ioext, pc->pc_memext, NULL, 0, 0);
+#endif
 	pba.pba_dmat = &pci_bus_dma_tag;
 	pba.pba_dmat64 = NULL;
 	pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
Index: arch/cobalt/include/pci_machdep.h
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/include/pci_machdep.h,v
retrieving revision 1.7
diff -u -r1.7 pci_machdep.h
--- arch/cobalt/include/pci_machdep.h	28 Aug 2004 13:33:31 -0000	1.7
+++ arch/cobalt/include/pci_machdep.h	8 Nov 2004 14:19:28 -0000
@@ -34,6 +34,7 @@
  * Machine-specific definitions for PCI autoconfiguration.
  */
 #define	__HAVE_PCIIDE_MACHDEP_COMPAT_INTR_ESTABLISH
+#define	__HAVE_PCI_CONF_HOOK
 
 /*
  * Forward declarations.
@@ -57,6 +58,9 @@
 struct cobalt_pci_chipset {
 	bus_space_tag_t pc_bst;		/* bus space tag for PCICFG regs */
 	bus_space_handle_t pc_bsh;	/* bus space handle for PCICFG regs */
+
+	struct extent *pc_memext;	/* PCI memory extent */
+	struct extent *pc_ioext;	/* PCI I/O extent */
 };
 
 /*
@@ -77,3 +81,6 @@
 void		*pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
 			int, int (*)(void *), void *);
 void		pci_intr_disestablish(pci_chipset_tag_t, void *);
+void		pci_conf_interrupt(pci_chipset_tag_t, int, int, int, int,
+			int *);
+int		pci_conf_hook(pci_chipset_tag_t, int, int, int, pcireg_t);
Index: arch/cobalt/pci/pci_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/pci/pci_machdep.c,v
retrieving revision 1.16
diff -u -r1.16 pci_machdep.c
--- arch/cobalt/pci/pci_machdep.c	28 Aug 2004 13:33:31 -0000	1.16
+++ arch/cobalt/pci/pci_machdep.c	8 Nov 2004 14:19:28 -0000
@@ -34,6 +34,7 @@
 #include <sys/systm.h>
 #include <sys/errno.h>
 #include <sys/device.h>
+#include <sys/extent.h>
 
 #define _COBALT_BUS_DMA_PRIVATE
 #include <machine/bus.h>
@@ -42,6 +43,7 @@
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcidevs.h>
+#include <dev/pci/pciconf.h>
 
 #include <cobalt/dev/gtreg.h>
 
@@ -224,3 +226,28 @@
 	cpu_intr_disestablish(cookie);
 	icu_intr_disestablish(cookie);
 }
+
+void
+pci_conf_interrupt(pci_chipset_tag_t pc, int bus, int dev, int pin, int swiz,
+    int *iline)
+{
+
+	/* not yet... */
+}
+
+int
+pci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func, pcireg_t id)
+{
+
+	/* Don't configure the bridge and PCI probe. */ 
+	if (PCI_VENDOR(id) == PCI_VENDOR_GALILEO &&
+	    PCI_PRODUCT(id) == PCI_PRODUCT_GALILEO_GT64011)
+	        return 0;
+
+	/* Don't configure device 9 */
+	if (dev == 9)
+		return 0;
+
+	return PCI_CONF_ALL & ~(PCI_CONF_MAP_ROM |
+	    PCI_COMMAND_SERR_ENABLE | PCI_COMMAND_PARITY_ENABLE);
+}
Index: dev/pci/pciconf.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pciconf.c,v
retrieving revision 1.23
diff -u -r1.23 pciconf.c
--- dev/pci/pciconf.c	17 Mar 2004 20:27:57 -0000	1.23
+++ dev/pci/pciconf.c	8 Nov 2004 14:19:28 -0000
@@ -705,10 +705,6 @@
 			    PRIu64 " req)\n", pi->size);
 			return -1;
 		}
-		if (!pb->io_32bit && pi->address > 0xFFFF) {
-			pi->address = 0;
-			pd->enable = 0;
-		}
 		if (pd->ppb && pi->reg == 0) {
 			pd->ppb->ioext = extent_create("pciconf", pi->address,
 			    pi->address + pi->size, M_DEVBUF, NULL, 0,
@@ -721,7 +717,12 @@
 			}
 			continue;
 		}
-		pd->enable |= PCI_CONF_ENABLE_IO;
+		if (!pb->io_32bit && pi->address > 0xFFFF) {
+			pi->address = 0;
+			pd->enable &= ~PCI_CONF_ENABLE_IO;
+		} else {
+			pd->enable |= PCI_CONF_ENABLE_IO;
+		}
 		if (pci_conf_debug) {
 			print_tag(pd->pc, pd->tag);
 			printf("Putting %" PRIu64 " I/O bytes @ %#" PRIx64
@@ -775,7 +776,7 @@
 		if (pm->prefetch && !pb->pmem_64bit &&
 		    pm->address > 0xFFFFFFFFULL) {
 			pm->address = 0;
-			pd->enable = 0;
+			pd->enable &= ~PCI_CONF_ENABLE_MEM;
 		} else {
 			pd->enable |= PCI_CONF_ENABLE_MEM;
 		}
@@ -1005,7 +1006,10 @@
 		class = pci_conf_read(pd->pc, pd->tag, PCI_CLASS_REG);
 		misc = pci_conf_read(pd->pc, pd->tag, PCI_BHLC_REG);
 		cmd = pci_conf_read(pd->pc, pd->tag, PCI_COMMAND_STATUS_REG);
-		cmd |= PCI_COMMAND_SERR_ENABLE | PCI_COMMAND_PARITY_ENABLE;
+		if (pd->enable & PCI_CONF_ENABLE_PARITY)
+			cmd |= PCI_COMMAND_PARITY_ENABLE;
+		if (pd->enable & PCI_CONF_ENABLE_SERR)
+			cmd |= PCI_COMMAND_SERR_ENABLE;
 		if (pb->fast_b2b)
 			cmd |= PCI_COMMAND_BACKTOBACK_ENABLE;
 		if (PCI_CLASS(class) != PCI_CLASS_BRIDGE ||
@@ -1022,7 +1026,8 @@
 			cmd |= PCI_COMMAND_MASTER_ENABLE;
 			ltim = MIN (pb->def_ltim, pb->max_ltim);
 		}
-		if (!(pd->enable)) {
+		if ((pd->enable &
+		    (PCI_CONF_ENABLE_MEM|PCI_CONF_ENABLE_IO)) == 0) {
 			print_tag(pd->pc, pd->tag);
 			printf("Disabled due to lack of resources.\n");
 			cmd &= ~(PCI_COMMAND_MASTER_ENABLE |
Index: dev/pci/pciconf.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pciconf.h,v
retrieving revision 1.7
diff -u -r1.7 pciconf.h
--- dev/pci/pciconf.h	28 Sep 2002 10:31:02 -0000	1.7
+++ dev/pci/pciconf.h	8 Nov 2004 14:19:29 -0000
@@ -55,5 +55,7 @@
 #define PCI_CONF_ENABLE_IO	0x08
 #define PCI_CONF_ENABLE_MEM	0x10
 #define PCI_CONF_ENABLE_BM	0x20
+#define PCI_CONF_ENABLE_PARITY	0x40
+#define PCI_CONF_ENABLE_SERR	0x80
 
-#define PCI_CONF_ALL		0x3f
+#define PCI_CONF_ALL		0xff