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;
+}