Module Name:    src
Committed By:   cliff
Date:           Mon Nov  9 10:05:06 UTC 2009

Modified Files:
        src/sys/arch/mips/rmi [matt-nb5-mips64]: rmixl_obio.c

Log Message:
- convert to CFATTACH_DECL_NEW & related
- add obio_dma_init_29() to allow DMA for addrs < 512MB
- obio_dma_init_32() and obio_dma_init_64() are TBD (#ifdef NOTYET)
- obio_bus_dmamap_sync() provides null DMA sync function, since
  DMA is cache coherent
- rmixl_addr_error_init() establishes ISR for address error interrupt


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.4 -r1.1.2.5 src/sys/arch/mips/rmi/rmixl_obio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/mips/rmi/rmixl_obio.c
diff -u src/sys/arch/mips/rmi/rmixl_obio.c:1.1.2.4 src/sys/arch/mips/rmi/rmixl_obio.c:1.1.2.5
--- src/sys/arch/mips/rmi/rmixl_obio.c:1.1.2.4	Tue Sep 15 03:04:03 2009
+++ src/sys/arch/mips/rmi/rmixl_obio.c	Mon Nov  9 10:05:06 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rmixl_obio.c,v 1.1.2.4 2009/09/15 03:04:03 cliff Exp $	*/
+/*	$NetBSD: rmixl_obio.c,v 1.1.2.5 2009/11/09 10:05:06 cliff Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
@@ -40,33 +40,51 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rmixl_obio.c,v 1.1.2.4 2009/09/15 03:04:03 cliff Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rmixl_obio.c,v 1.1.2.5 2009/11/09 10:05:06 cliff Exp $");
+
+#include "locators.h"
+#include "obio.h"
+#include "pci.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
+#include <sys/extent.h>
+#include <sys/malloc.h>
 
+#define _MIPS_BUS_DMA_PRIVATE
 #include <machine/bus.h>
 
+#include <machine/int_fmtio.h>
+
 #include <mips/rmi/rmixlreg.h>
 #include <mips/rmi/rmixlvar.h>
 #include <mips/rmi/rmixl_obiovar.h>
+#include <mips/rmi/rmixl_pcievar.h>
 
-#include "locators.h"
+#ifdef OBIO_DEBUG
+int obio_debug = OBIO_DEBUG;
+# define DPRINTF(x)	do { if (obio_debug) printf x ; } while (0)
+#else
+# define DPRINTF(x)
+#endif
 
-static int  obio_match(struct device *, struct cfdata *, void *);
-static void obio_attach(struct device *, struct device *, void *);
+static int  obio_match(device_t, cfdata_t, void *);
+static void obio_attach(device_t, device_t, void *);
 static int  obio_print(void *, const char *);
-static int  obio_search(struct device *, struct cfdata *, const int *, void *);
+static int  obio_search(device_t, cfdata_t, const int *, void *);
 static void obio_bus_init(struct obio_softc *);
+static void obio_dma_init_29(bus_dma_tag_t);
+static int  rmixl_addr_error_intr(void *);
+
 
-CFATTACH_DECL(obio, sizeof(struct obio_softc),
+CFATTACH_DECL_NEW(obio, sizeof(struct obio_softc),
     obio_match, obio_attach, NULL, NULL);
 
 int obio_found;
 
 static int
-obio_match(struct device * parent, struct cfdata *cf, void *aux)
+obio_match(device_t parent, cfdata_t cf, void *aux)
 {
 	if (obio_found)
 		return 0;
@@ -74,12 +92,13 @@
 }
 
 static void
-obio_attach(struct device * parent, struct device * self, void *aux)
+obio_attach(device_t parent, device_t self, void *aux)
 {
 	struct obio_softc *sc = device_private(self);
 	bus_addr_t ba;
 
 	obio_found = 1;
+	sc->sc_dev = self;
 
 	ba = (bus_addr_t)rmixl_configuration.rc_io_pbase;
 	KASSERT(ba != 0);
@@ -93,6 +112,7 @@
 	 * Attach on-board devices as specified in the kernel config file.
 	 */
 	config_search_ia(obio_search, self, "obio", NULL);
+
 }
 
 static int
@@ -100,20 +120,22 @@
 {
 	struct obio_attach_args *obio = aux;
 
-	aprint_normal(" addr 0x%08lx", obio->obio_addr);
-	if (obio->obio_size != OBIOCF_SIZE_DEFAULT)
-		aprint_normal("-0x%08lx", obio->obio_addr + (obio->obio_size - 1));
-	if (obio->obio_mult != OBIOCF_MULT)
+	if (obio->obio_addr != OBIOCF_ADDR_DEFAULT) {
+		aprint_normal(" addr 0x%08lx", obio->obio_addr);
+		if (obio->obio_size != OBIOCF_SIZE_DEFAULT)
+			aprint_normal("-0x%08lx",
+				obio->obio_addr + (obio->obio_size - 1));
+	}
+	if (obio->obio_mult != OBIOCF_MULT_DEFAULT)
 		aprint_normal(" mult %d", obio->obio_mult);
-	if (obio->obio_intr != -1)
+	if (obio->obio_intr != OBIOCF_INTR_DEFAULT)
 		aprint_normal(" intr %d", obio->obio_intr);
 
 	return (UNCONF);
 }
 
 static int
-obio_search(struct device * parent, struct cfdata *cf,
-	    const int *ldesc, void *aux)
+obio_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
 {
 	struct obio_softc *sc = device_private(parent);
 	struct obio_attach_args obio;
@@ -124,6 +146,9 @@
 	obio.obio_size = cf->cf_loc[OBIOCF_SIZE];
 	obio.obio_mult = cf->cf_loc[OBIOCF_MULT];
 	obio.obio_intr = cf->cf_loc[OBIOCF_INTR];
+	obio.obio_29bit_dmat = sc->sc_29bit_dmat;
+	obio.obio_32bit_dmat = sc->sc_32bit_dmat;
+	obio.obio_64bit_dmat = sc->sc_64bit_dmat;
 
 	if (config_match(parent, cf, &obio) > 0)
 		config_attach(parent, cf, &obio, obio_print);
@@ -134,6 +159,7 @@
 static void
 obio_bus_init(struct obio_softc *sc)
 {
+	struct rmixl_config *rcp = &rmixl_configuration;
 	static int done = 0;
 
 	if (done)
@@ -141,28 +167,184 @@
 	done = 1;
 
 	/* little endian space */
-	if (rmixl_configuration.rc_el_memt.bs_cookie == 0)
-		rmixl_el_bus_mem_init(&rmixl_configuration.rc_el_memt,
-			&rmixl_configuration);
+	if (rcp->rc_el_memt.bs_cookie == 0)
+		rmixl_el_bus_mem_init(&rcp->rc_el_memt, rcp);
 
 	/* big endian space */
-	if (rmixl_configuration.rc_eb_memt.bs_cookie == 0)
-		rmixl_eb_bus_mem_init(&rmixl_configuration.rc_eb_memt,
-			&rmixl_configuration);
+	if (rcp->rc_eb_memt.bs_cookie == 0)
+		rmixl_eb_bus_mem_init(&rcp->rc_eb_memt, rcp);
+
+	/* dma space for addr < 512MB */
+	if (rcp->rc_29bit_dmat._cookie == 0)
+		obio_dma_init_29(&rcp->rc_29bit_dmat);
 #ifdef NOTYET
 	/* dma space for addr < 4GB */
-	if (rmixl_configuration.rc_lt4G_dmat._cookie == 0)
-		rmixl_dma_init(&rmixl_configuration.rc_lt4G_dmat);
+	if (rcp->rc_32bit_dmat._cookie == 0)
+		obio_dma_init_32(&rcp->rc_32bit_dmat);
 	/* dma space for all memory, including >= 4GB */
-	if (rmixl_configuration.rc_ge4G_dmat._cookie == 0)
-		rmixl_dma_init(&rmixl_configuration.rc_ge4G_dmat);
+	if (rcp->rc_64bit_dmat._cookie == 0)
+		obio_dma_init_64(&rcp->rc_64bit_dmat);
 #endif
 
-	sc->sc_base = (bus_addr_t)rmixl_configuration.rc_io_pbase;
+	sc->sc_base = (bus_addr_t)rcp->rc_io_pbase;
 	sc->sc_size = (bus_size_t)RMIXL_IO_DEV_SIZE;
-	sc->sc_el_bst = (bus_space_tag_t)&rmixl_configuration.rc_el_memt;
-	sc->sc_eb_bst = (bus_space_tag_t)&rmixl_configuration.rc_eb_memt;
-	sc->sc_lt4G_dmat = &rmixl_configuration.rc_lt4G_dmat;
-	sc->sc_ge4G_dmat = &rmixl_configuration.rc_ge4G_dmat;
+	sc->sc_el_bst = (bus_space_tag_t)&rcp->rc_el_memt;
+	sc->sc_eb_bst = (bus_space_tag_t)&rcp->rc_eb_memt;
+	sc->sc_29bit_dmat = &rcp->rc_29bit_dmat;
+#ifdef NOTYET
+	sc->sc_32bit_dmat = &rcp->rc_32bit_dmat;
+	sc->sc_64bit_dmat = &rcp->rc_64bit_dmat;
+#else
+	sc->sc_32bit_dmat = NULL;
+	sc->sc_64bit_dmat = NULL;
+#endif
+}
+
+static void
+obio_bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
+    bus_size_t len, int ops)
+{
+	return;
+}
+
+static void
+obio_dma_init_29(bus_dma_tag_t t)
+{
+	t->_cookie = t;
+	t->_wbase = 0;
+	t->_physbase = 0;
+#if _LP64
+	t->_wsize = ~0;
+#else
+	t->_wsize = MIPS_KSEG1_START - MIPS_KSEG0_START;
+#endif
+	t->_dmamap_create = _bus_dmamap_create;
+	t->_dmamap_destroy = _bus_dmamap_destroy;
+	t->_dmamap_load = _bus_dmamap_load;
+	t->_dmamap_load_mbuf = _bus_dmamap_load_mbuf;
+	t->_dmamap_load_uio = _bus_dmamap_load_uio;
+	t->_dmamap_load_raw = _bus_dmamap_load_raw;
+	t->_dmamap_unload = _bus_dmamap_unload;
+
+	t->_dmamap_sync = obio_bus_dmamap_sync;
+
+	t->_dmamem_alloc = _bus_dmamem_alloc;
+	t->_dmamem_free = _bus_dmamem_free;
+	t->_dmamem_map = _bus_dmamem_map;
+	t->_dmamem_unmap = _bus_dmamem_unmap;
+	t->_dmamem_mmap = _bus_dmamem_mmap;
+}
+
+void
+rmixl_addr_error_init(void)
+{
+	uint32_t r;
+
+	/*
+	 * activate error addr detection on all (configurable) devices
+	 * preserve reserved bit fields
+	 * note some of these bits are read-only (writes are ignored)
+	 */
+	r = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_DEVICE_MASK);
+	r |= ~(__BITS(19,16) | __BITS(10,9) | __BITS(7,5));
+	RMIXL_IOREG_WRITE(RMIXL_ADDR_ERR_DEVICE_MASK, r);
+
+	/* 
+	 * enable the address error interrupts 
+	 * "upgrade" cache and CPU errors to A1
+	 */
+#define _ADDR_ERR_DEVSTAT_A1	(__BIT(8) | __BIT(1) | __BIT(0))
+#define _ADDR_ERR_RESV		\
+		(__BITS(31,21) | __BITS(15,14) | __BITS(10,9) | __BITS(7,2))
+#define _BITERR_INT_EN_RESV	(__BITS(31,8) | __BIT(4))
+
+	r = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR0_EN);
+	r &= _ADDR_ERR_RESV;
+	r |= ~_ADDR_ERR_RESV;
+	RMIXL_IOREG_WRITE(RMIXL_ADDR_ERR_AERR0_EN, r);
+
+	r = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR0_UPG);
+	r &= _ADDR_ERR_RESV;
+	r |= _ADDR_ERR_DEVSTAT_A1;
+	RMIXL_IOREG_WRITE(RMIXL_ADDR_ERR_AERR0_UPG, r);
+
+	/*
+	 * clear the log regs and the dev stat (interrupt status) regs
+	 * "Write any value to bit[0] to clear"
+	 */
+	r = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR1_CLEAR);
+	RMIXL_IOREG_WRITE(RMIXL_ADDR_ERR_AERR1_CLEAR, r);
+
+	/* 
+	 * enable the double bit error interrupts 
+	 * (assume reserved bits, which are read-only,  are ignored)
+	 */
+	r = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_BITERR_INT_EN);
+	r &= _BITERR_INT_EN_RESV;
+	r |= __BITS(7,5);
+	RMIXL_IOREG_WRITE(RMIXL_ADDR_ERR_BITERR_INT_EN, r);
+
+	/*
+	 * establish address error ISR
+	 * XXX assuming "int 16 (bridge_tb)" is out irq
+	 */
+	rmixl_intr_establish(16, IPL_HIGH, RMIXL_INTR_LEVEL, RMIXL_INTR_HIGH,
+		rmixl_addr_error_intr, NULL);
+}
+
+int
+rmixl_addr_error_check(void)
+{
+	uint32_t aerr0_devstat;
+	uint32_t aerr0_log1;
+	uint32_t aerr0_log2;
+	uint32_t aerr0_log3;
+	uint32_t aerr1_devstat;
+	uint32_t aerr1_log1;
+	uint32_t aerr1_log2;
+	uint32_t aerr1_log3;
+	uint32_t sbe_counts;
+	uint32_t dbe_counts;
+
+	aerr0_devstat = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR0_DEVSTAT);
+	aerr0_log1 = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR0_LOG1);
+	aerr0_log2 = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR0_LOG2);
+	aerr0_log3 = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR0_LOG3);
+
+	aerr1_devstat = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR1_DEVSTAT);
+	aerr1_log1 = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR1_LOG1);
+	aerr1_log2 = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR1_LOG2);
+	aerr1_log3 = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_AERR1_LOG3);
+
+	sbe_counts = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_SBE_COUNTS);
+	dbe_counts = RMIXL_IOREG_READ(RMIXL_ADDR_ERR_DBE_COUNTS);
+
+	if (aerr0_log1|aerr0_log2|aerr0_log3
+	   |aerr1_log1|aerr1_log2|aerr1_log3
+	   |dbe_counts) {
+		printf("aerr0: stat %#x, logs: %#x, %#x, %#x\n",
+			aerr0_devstat, aerr0_log1, aerr0_log2, aerr0_log2);
+		printf("aerr1: stat %#x, logs: %#x, %#x, %#x\n",
+			aerr1_devstat, aerr1_log1, aerr1_log2, aerr1_log2);
+		printf("1-bit errors: %#x, 2-bit errors: %#x\n",
+			sbe_counts, dbe_counts);
+		return 1;
+	}
+	return 0;
 }
 
+static int
+rmixl_addr_error_intr(void *arg)
+{
+	int err;
+
+	err = rmixl_addr_error_check();
+	if (err != 0) {
+#if DDB
+		printf("%s\n", __func__);
+		Debugger();
+#endif
+		panic("Address Error");
+	}
+	return 1;
+}

Reply via email to