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