diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2002-05-02 22:56:08 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2002-05-02 22:56:08 +0000 |
commit | f69ff2bae348f49f6e5fccbf1594b839e98792ef (patch) | |
tree | 984c07207f03eebcb847988db98df196a848c27e /sys/arch/alpha/tc/ioasic.c | |
parent | d7aff648af7518e317842f78e06a3d197eca9629 (diff) |
Big TURBOchannel support catchup from NetBSD, part 1.
A few local changes and tweaks remain.
This bring DEC 3000 machines back in the game, but framebuffers are still
not supported at the moment.
Thanks to ericj@ and nate@ for supplying me a DEC 3000 for testing.
Diffstat (limited to 'sys/arch/alpha/tc/ioasic.c')
-rw-r--r-- | sys/arch/alpha/tc/ioasic.c | 262 |
1 files changed, 125 insertions, 137 deletions
diff --git a/sys/arch/alpha/tc/ioasic.c b/sys/arch/alpha/tc/ioasic.c index d95660442b6..a66b8eaf010 100644 --- a/sys/arch/alpha/tc/ioasic.c +++ b/sys/arch/alpha/tc/ioasic.c @@ -1,5 +1,42 @@ -/* $OpenBSD: ioasic.c,v 1.8 2002/03/14 01:26:28 millert Exp $ */ -/* $NetBSD: ioasic.c,v 1.10 1996/12/05 01:39:41 cgd Exp $ */ +/* $OpenBSD: ioasic.c,v 1.9 2002/05/02 22:56:06 miod Exp $ */ +/* $NetBSD: ioasic.c,v 1.34 2000/07/18 06:10:06 thorpej Exp $ */ + +/*- + * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ /* * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. @@ -32,33 +69,21 @@ #include <sys/kernel.h> #include <sys/systm.h> #include <sys/device.h> +#include <sys/malloc.h> #include <machine/autoconf.h> +#include <machine/bus.h> #include <machine/pte.h> #include <machine/rpb.h> -#ifndef EVCNT_COUNTERS #include <machine/intrcnt.h> -#endif #include <dev/tc/tcvar.h> -#include <alpha/tc/ioasicreg.h> +#include <dev/tc/ioasicreg.h> #include <dev/tc/ioasicvar.h> -struct ioasic_softc { - struct device sc_dv; - - tc_addr_t sc_base; - void *sc_cookie; -}; - /* Definition of the driver for autoconfig. */ -#ifdef __BROKEN_INDIRECT_CONFIG int ioasicmatch(struct device *, void *, void *); -#else -int ioasicmatch(struct device *, struct cfdata *, void *); -#endif void ioasicattach(struct device *, struct device *, void *); -int ioasicprint(void *, const char *); struct cfattach ioasic_ca = { sizeof(struct ioasic_softc), ioasicmatch, ioasicattach, @@ -82,24 +107,26 @@ int ioasic_intrnull(void *); #define IOASIC_NCOOKIES 4 -struct ioasic_dev { - char *iad_modname; - tc_offset_t iad_offset; - void *iad_cookie; - u_int32_t iad_intrbits; -} ioasic_devs[] = { - /* XXX lance name */ - { "lance", 0x000c0000, C(IOASIC_DEV_LANCE), IOASIC_INTR_LANCE, }, - { "z8530 ", 0x00100000, C(IOASIC_DEV_SCC0), IOASIC_INTR_SCC_0, }, - { "z8530 ", 0x00180000, C(IOASIC_DEV_SCC1), IOASIC_INTR_SCC_1, }, - { "TOY_RTC ", 0x00200000, C(IOASIC_DEV_BOGUS), 0, }, - { "AMD79c30", 0x00240000, C(IOASIC_DEV_ISDN), IOASIC_INTR_ISDN, }, +struct ioasic_dev ioasic_devs[] = { + { "PMAD-BA ", IOASIC_SLOT_3_START, C(IOASIC_DEV_LANCE), + IOASIC_INTR_LANCE, }, + { "z8530 ", IOASIC_SLOT_4_START, C(IOASIC_DEV_SCC0), + IOASIC_INTR_SCC_0, }, + { "z8530 ", IOASIC_SLOT_6_START, C(IOASIC_DEV_SCC1), + IOASIC_INTR_SCC_1, }, + { "TOY_RTC ", IOASIC_SLOT_8_START, C(IOASIC_DEV_BOGUS), + 0, }, + { "AMD79c30", IOASIC_SLOT_9_START, C(IOASIC_DEV_ISDN), + IOASIC_INTR_ISDN_TXLOAD | IOASIC_INTR_ISDN_RXLOAD, }, }; int ioasic_ndevs = sizeof(ioasic_devs) / sizeof(ioasic_devs[0]); struct ioasicintr { int (*iai_func)(void *); void *iai_arg; +#ifdef EVCNT_COUNTERS + struct evcnt iai_evcnt; +#endif } ioasicintrs[IOASIC_NCOOKIES]; tc_addr_t ioasic_base; /* XXX XXX XXX */ @@ -107,17 +134,10 @@ tc_addr_t ioasic_base; /* XXX XXX XXX */ /* There can be only one. */ int ioasicfound; -extern int cputype; - int ioasicmatch(parent, cfdata, aux) struct device *parent; -#ifdef __BROKEN_INDIRECT_CONFIG - void *cfdata; -#else - struct cfdata *cfdata; -#endif - void *aux; + void *cfdata, *aux; { struct tc_attach_args *ta = aux; @@ -142,20 +162,30 @@ ioasicattach(parent, self, aux) { struct ioasic_softc *sc = (struct ioasic_softc *)self; struct tc_attach_args *ta = aux; - struct ioasicdev_attach_args ioasicdev; - u_long i; +#ifdef DEC_3000_300 + u_long ssr; +#endif + u_long i, imsk; + const struct evcnt *pevcnt; + char *cp; ioasicfound = 1; - sc->sc_base = ta->ta_addr; - ioasic_base = sc->sc_base; /* XXX XXX XXX */ - sc->sc_cookie = ta->ta_cookie; + sc->sc_bst = ta->ta_memt; + if (bus_space_map(ta->ta_memt, ta->ta_addr, + 0x400000, 0, &sc->sc_bsh)) { + printf("%s: unable to map device\n", sc->sc_dv.dv_xname); + return; + } + sc->sc_dmat = ta->ta_dmat; + + ioasic_base = sc->sc_base = ta->ta_addr; /* XXX XXX XXX */ #ifdef DEC_3000_300 if (cputype == ST_DEC_3000_300) { - *(volatile u_int *)IOASIC_REG_CSR(sc->sc_base) |= - IOASIC_CSR_FASTMODE; - tc_mb(); + ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR); + ssr |= IOASIC_CSR_FASTMODE; + bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr); printf(": slow mode\n"); } else #endif @@ -165,57 +195,34 @@ ioasicattach(parent, self, aux) * Turn off all device interrupt bits. * (This does _not_ include 3000/300 TC option slot bits. */ + imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK); for (i = 0; i < ioasic_ndevs; i++) - *(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &= - ~ioasic_devs[i].iad_intrbits; - tc_mb(); + imsk &= ~ioasic_devs[i].iad_intrbits; + bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk); /* * Set up interrupt handlers. */ + pevcnt = tc_intr_evcnt(parent, ta->ta_cookie); for (i = 0; i < IOASIC_NCOOKIES; i++) { ioasicintrs[i].iai_func = ioasic_intrnull; ioasicintrs[i].iai_arg = (void *)i; + + cp = malloc(12, M_DEVBUF, M_NOWAIT); + if (cp == NULL) + panic("ioasicattach"); + sprintf(cp, "slot %lu", i); +#ifdef EVCNT_COUNTERS + evcnt_attach_dynamic(&ioasicintrs[i].iai_evcnt, + EVCNT_TYPE_INTR, pevcnt, self->dv_xname, cp); +#endif } - tc_intr_establish(parent, sc->sc_cookie, TC_IPL_NONE, ioasic_intr, sc); + tc_intr_establish(parent, ta->ta_cookie, TC_IPL_NONE, ioasic_intr, sc); - /* + /* * Try to configure each device. */ - for (i = 0; i < ioasic_ndevs; i++) { - strncpy(ioasicdev.iada_modname, ioasic_devs[i].iad_modname, - TC_ROM_LLEN); - ioasicdev.iada_modname[TC_ROM_LLEN] = '\0'; - ioasicdev.iada_offset = ioasic_devs[i].iad_offset; - ioasicdev.iada_addr = sc->sc_base + ioasic_devs[i].iad_offset; - ioasicdev.iada_cookie = ioasic_devs[i].iad_cookie; - - /* Tell the autoconfig machinery we've found the hardware. */ - config_found(self, &ioasicdev, ioasicprint); - } -} - -int -ioasicprint(aux, pnp) - void *aux; - const char *pnp; -{ - struct ioasicdev_attach_args *d = aux; - - if (pnp) - printf("%s at %s", d->iada_modname, pnp); - printf(" offset 0x%lx", (long)d->iada_offset); - return (UNCONF); -} - -int -ioasic_submatch(match, d) - struct cfdata *match; - struct ioasicdev_attach_args *d; -{ - - return ((match->ioasiccf_offset == d->iada_offset) || - (match->ioasiccf_offset == IOASIC_OFFSET_UNKNOWN)); + ioasic_attach_devs(sc, ioasic_devs, ioasic_ndevs); } void @@ -225,7 +232,8 @@ ioasic_intr_establish(ioa, cookie, level, func, arg) tc_intrlevel_t level; int (*func)(void *); { - u_long dev, i; + struct ioasic_softc *sc = (void *)ioasic_cd.cd_devs[0]; + u_long dev, i, imsk; dev = (u_long)cookie; #ifdef DIAGNOSTIC @@ -233,7 +241,7 @@ ioasic_intr_establish(ioa, cookie, level, func, arg) #endif if (ioasicintrs[dev].iai_func != ioasic_intrnull) - panic("ioasic_intr_establish: cookie %d twice", dev); + panic("ioasic_intr_establish: cookie %lu twice", dev); ioasicintrs[dev].iai_func = func; ioasicintrs[dev].iai_arg = arg; @@ -244,9 +252,10 @@ ioasic_intr_establish(ioa, cookie, level, func, arg) break; if (i == ioasic_ndevs) panic("ioasic_intr_establish: invalid cookie."); - *(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) |= - ioasic_devs[i].iad_intrbits; - tc_mb(); + + imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK); + imsk |= ioasic_devs[i].iad_intrbits; + bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk); } void @@ -254,7 +263,8 @@ ioasic_intr_disestablish(ioa, cookie) struct device *ioa; void *cookie; { - u_long dev, i; + struct ioasic_softc *sc = (void *)ioasic_cd.cd_devs[0]; + u_long dev, i, imsk; dev = (u_long)cookie; #ifdef DIAGNOSTIC @@ -262,7 +272,7 @@ ioasic_intr_disestablish(ioa, cookie) #endif if (ioasicintrs[dev].iai_func == ioasic_intrnull) - panic("ioasic_intr_disestablish: cookie %d missing intr", dev); + panic("ioasic_intr_disestablish: cookie %lu missing intr", dev); /* Enable interrupts for the device. */ for (i = 0; i < ioasic_ndevs; i++) @@ -270,9 +280,10 @@ ioasic_intr_disestablish(ioa, cookie) break; if (i == ioasic_ndevs) panic("ioasic_intr_disestablish: invalid cookie."); - *(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &= - ~ioasic_devs[i].iad_intrbits; - tc_mb(); + + imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK); + imsk &= ~ioasic_devs[i].iad_intrbits; + bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk); ioasicintrs[dev].iai_func = ioasic_intrnull; ioasicintrs[dev].iai_arg = (void *)dev; @@ -288,8 +299,7 @@ ioasic_intrnull(val) } /* - * asic_intr -- - * ASIC interrupt handler. + * ASIC interrupt handler. */ int ioasic_intr(val) @@ -298,66 +308,44 @@ ioasic_intr(val) register struct ioasic_softc *sc = val; register int ifound; int gifound; - u_int32_t sir; - volatile u_int32_t *sirp; - - sirp = (volatile u_int32_t *)IOASIC_REG_INTR(sc->sc_base); + u_int32_t sir, osir; gifound = 0; do { ifound = 0; tc_syncbus(); - sir = *sirp; + osir = sir = + bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_INTR); #ifdef EVCNT_COUNTERS - /* No interrupt counting via evcnt counters */ - XXX BREAK HERE XXX -#else /* !EVCNT_COUNTERS */ +#define INCRINTRCNT(slot) ioasicintrs[slot].iai_evcnt.ev_count++ +#else #define INCRINTRCNT(slot) intrcnt[INTRCNT_IOASIC + slot]++ -#endif /* EVCNT_COUNTERS */ +#endif /* XXX DUPLICATION OF INTERRUPT BIT INFORMATION... */ -#define CHECKINTR(slot, bits) \ - if (sir & bits) { \ +#define CHECKINTR(slot, bits, clear) \ + if (sir & (bits)) { \ ifound = 1; \ INCRINTRCNT(slot); \ (*ioasicintrs[slot].iai_func) \ (ioasicintrs[slot].iai_arg); \ + if (clear) \ + sir &= ~(bits); \ } - CHECKINTR(IOASIC_DEV_SCC0, IOASIC_INTR_SCC_0); - CHECKINTR(IOASIC_DEV_SCC1, IOASIC_INTR_SCC_1); - CHECKINTR(IOASIC_DEV_LANCE, IOASIC_INTR_LANCE); - CHECKINTR(IOASIC_DEV_ISDN, IOASIC_INTR_ISDN); + CHECKINTR(IOASIC_DEV_SCC0, IOASIC_INTR_SCC_0, 0); + CHECKINTR(IOASIC_DEV_SCC1, IOASIC_INTR_SCC_1, 0); + CHECKINTR(IOASIC_DEV_LANCE, IOASIC_INTR_LANCE, 0); + CHECKINTR(IOASIC_DEV_ISDN, IOASIC_INTR_ISDN_TXLOAD | + IOASIC_INTR_ISDN_RXLOAD | IOASIC_INTR_ISDN_OVRUN, 1); + + if (sir != osir) + bus_space_write_4(sc->sc_bst, sc->sc_bsh, + IOASIC_INTR, sir); gifound |= ifound; } while (ifound); return (gifound); } - -/* XXX */ -char * -ioasic_lance_ether_address() -{ - - return (u_char *)IOASIC_SYS_ETHER_ADDRESS(ioasic_base); -} - -void -ioasic_lance_dma_setup(v) - void *v; -{ - volatile u_int32_t *ldp; - tc_addr_t tca; - - tca = (tc_addr_t)v; - - ldp = (volatile u_int *)IOASIC_REG_LANCE_DMAPTR(ioasic_base); - *ldp = ((tca << 3) & ~(tc_addr_t)0x1f) | ((tca >> 29) & 0x1f); - tc_wmb(); - - *(volatile u_int32_t *)IOASIC_REG_CSR(ioasic_base) |= - IOASIC_CSR_DMAEN_LANCE; - tc_mb(); -} |