[BACK]Return to ioasic.c CVS log [TXT][DIR] Up to [local] / sys / arch / alpha / tc

Annotation of sys/arch/alpha/tc/ioasic.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: ioasic.c,v 1.12 2006/03/04 12:33:17 miod Exp $ */
                      2: /* $NetBSD: ioasic.c,v 1.34 2000/07/18 06:10:06 thorpej Exp $ */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                     10:  * NASA Ames Research Center.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *     This product includes software developed by the NetBSD
                     23:  *     Foundation, Inc. and its contributors.
                     24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     25:  *    contributors may be used to endorse or promote products derived
                     26:  *    from this software without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     38:  * POSSIBILITY OF SUCH DAMAGE.
                     39:  */
                     40:
                     41: /*
                     42:  * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
                     43:  * All rights reserved.
                     44:  *
                     45:  * Author: Keith Bostic, Chris G. Demetriou
                     46:  *
                     47:  * Permission to use, copy, modify and distribute this software and
                     48:  * its documentation is hereby granted, provided that both the copyright
                     49:  * notice and this permission notice appear in all copies of the
                     50:  * software, derivative works or modified versions, and any portions
                     51:  * thereof, and that both notices appear in supporting documentation.
                     52:  *
                     53:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     54:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
                     55:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     56:  *
                     57:  * Carnegie Mellon requests users of this software to return to
                     58:  *
                     59:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     60:  *  School of Computer Science
                     61:  *  Carnegie Mellon University
                     62:  *  Pittsburgh PA 15213-3890
                     63:  *
                     64:  * any improvements or extensions that they make and grant Carnegie the
                     65:  * rights to redistribute these changes.
                     66:  */
                     67:
                     68: #include <sys/param.h>
                     69: #include <sys/kernel.h>
                     70: #include <sys/systm.h>
                     71: #include <sys/device.h>
                     72: #include <sys/malloc.h>
                     73:
                     74: #include <machine/autoconf.h>
                     75: #include <machine/bus.h>
                     76: #include <machine/pte.h>
                     77: #include <machine/rpb.h>
                     78:
                     79: #include <dev/tc/tcvar.h>
                     80: #include <dev/tc/ioasicreg.h>
                     81: #include <dev/tc/ioasicvar.h>
                     82:
                     83: /* Definition of the driver for autoconfig. */
                     84: int    ioasicmatch(struct device *, void *, void *);
                     85: void   ioasicattach(struct device *, struct device *, void *);
                     86:
                     87: struct cfattach ioasic_ca = {
                     88:        sizeof(struct ioasic_softc), ioasicmatch, ioasicattach,
                     89: };
                     90:
                     91: struct cfdriver ioasic_cd = {
                     92:        NULL, "ioasic", DV_DULL,
                     93: };
                     94:
                     95: int    ioasic_intr(void *);
                     96: int    ioasic_intrnull(void *);
                     97:
                     98: #define        C(x)    ((void *)(x))
                     99:
                    100: #define        IOASIC_DEV_LANCE        0
                    101: #define        IOASIC_DEV_SCC0         1
                    102: #define        IOASIC_DEV_SCC1         2
                    103: #define        IOASIC_DEV_ISDN         3
                    104:
                    105: #define        IOASIC_DEV_BOGUS        -1
                    106:
                    107: #define        IOASIC_NCOOKIES         4
                    108:
                    109: struct ioasic_dev ioasic_devs[] = {
                    110:        { "PMAD-BA ", IOASIC_SLOT_3_START, C(IOASIC_DEV_LANCE),
                    111:          IOASIC_INTR_LANCE, },
                    112:        { "z8530   ", IOASIC_SLOT_4_START, C(IOASIC_DEV_SCC0),
                    113:          IOASIC_INTR_SCC_0, },
                    114:        { "z8530   ", IOASIC_SLOT_6_START, C(IOASIC_DEV_SCC1),
                    115:          IOASIC_INTR_SCC_1, },
                    116:        { "TOY_RTC ", IOASIC_SLOT_8_START, C(IOASIC_DEV_BOGUS),
                    117:          0, },
                    118:        { "AMD79c30", IOASIC_SLOT_9_START, C(IOASIC_DEV_ISDN),
                    119:          IOASIC_INTR_ISDN_TXLOAD | IOASIC_INTR_ISDN_RXLOAD,  },
                    120: };
                    121: int ioasic_ndevs = sizeof(ioasic_devs) / sizeof(ioasic_devs[0]);
                    122:
                    123: struct ioasicintr {
                    124:        int     (*iai_func)(void *);
                    125:        void    *iai_arg;
                    126:        struct evcount iai_count;
                    127:        char    iai_name[16];
                    128: } ioasicintrs[IOASIC_NCOOKIES];
                    129:
                    130: tc_addr_t ioasic_base;         /* XXX XXX XXX */
                    131:
                    132: /* There can be only one. */
                    133: int ioasicfound;
                    134:
                    135: int
                    136: ioasicmatch(parent, cfdata, aux)
                    137:        struct device *parent;
                    138:        void *cfdata, *aux;
                    139: {
                    140:        struct tc_attach_args *ta = aux;
                    141:
                    142:        /* Make sure that we're looking for this type of device. */
                    143:        if (strncmp("FLAMG-IO", ta->ta_modname, TC_ROM_LLEN))
                    144:                return (0);
                    145:
                    146:        /* Check that it can actually exist. */
                    147:        if ((cputype != ST_DEC_3000_500) && (cputype != ST_DEC_3000_300))
                    148:                panic("ioasicmatch: how did we get here?");
                    149:
                    150:        if (ioasicfound)
                    151:                return (0);
                    152:
                    153:        return (1);
                    154: }
                    155:
                    156: void
                    157: ioasicattach(parent, self, aux)
                    158:        struct device *parent, *self;
                    159:        void *aux;
                    160: {
                    161:        struct ioasic_softc *sc = (struct ioasic_softc *)self;
                    162:        struct tc_attach_args *ta = aux;
                    163: #ifdef DEC_3000_300
                    164:        u_long ssr;
                    165: #endif
                    166:        u_long i, imsk;
                    167:
                    168:        ioasicfound = 1;
                    169:
                    170:        sc->sc_bst = ta->ta_memt;
                    171:        if (bus_space_map(ta->ta_memt, ta->ta_addr,
                    172:                        0x400000, 0, &sc->sc_bsh)) {
                    173:                printf("%s: unable to map device\n", sc->sc_dv.dv_xname);
                    174:                return;
                    175:        }
                    176:        sc->sc_dmat = ta->ta_dmat;
                    177:
                    178:        ioasic_base = sc->sc_base = ta->ta_addr; /* XXX XXX XXX */
                    179:
                    180: #ifdef DEC_3000_300
                    181:        if (cputype == ST_DEC_3000_300) {
                    182:                ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
                    183:                ssr |= IOASIC_CSR_FASTMODE;
                    184:                bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
                    185:                printf(": slow mode\n");
                    186:        } else
                    187: #endif
                    188:                printf(": fast mode\n");
                    189:
                    190:        /*
                    191:         * Turn off all device interrupt bits.
                    192:         * (This does _not_ include 3000/300 TC option slot bits.
                    193:         */
                    194:        imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK);
                    195:        for (i = 0; i < ioasic_ndevs; i++)
                    196:                imsk &= ~ioasic_devs[i].iad_intrbits;
                    197:        bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk);
                    198:
                    199:        /*
                    200:         * Set up interrupt handlers.
                    201:         */
                    202:        for (i = 0; i < IOASIC_NCOOKIES; i++) {
                    203:                ioasicintrs[i].iai_func = ioasic_intrnull;
                    204:                ioasicintrs[i].iai_arg = (void *)i;
                    205:                snprintf(ioasicintrs[i].iai_name,
                    206:                    sizeof ioasicintrs[i].iai_name, "ioasic slot %u", i);
                    207:                evcount_attach(&ioasicintrs[i].iai_count,
                    208:                    ioasicintrs[i].iai_name, NULL, &evcount_intr);
                    209:        }
                    210:        tc_intr_establish(parent, ta->ta_cookie, TC_IPL_NONE, ioasic_intr, sc);
                    211:
                    212:        /*
                    213:         * Try to configure each device.
                    214:         */
                    215:        ioasic_attach_devs(sc, ioasic_devs, ioasic_ndevs);
                    216: }
                    217:
                    218: void
                    219: ioasic_intr_establish(ioa, cookie, level, func, arg)
                    220:        struct device *ioa;
                    221:        void *cookie, *arg;
                    222:        tc_intrlevel_t level;
                    223:        int (*func)(void *);
                    224: {
                    225:        struct ioasic_softc *sc = (void *)ioasic_cd.cd_devs[0];
                    226:        u_long dev, i, imsk;
                    227:
                    228:        dev = (u_long)cookie;
                    229: #ifdef DIAGNOSTIC
                    230:        /* XXX check cookie. */
                    231: #endif
                    232:
                    233:        if (ioasicintrs[dev].iai_func != ioasic_intrnull)
                    234:                panic("ioasic_intr_establish: cookie %lu twice", dev);
                    235:
                    236:        ioasicintrs[dev].iai_func = func;
                    237:        ioasicintrs[dev].iai_arg = arg;
                    238:
                    239:        /* Enable interrupts for the device. */
                    240:        for (i = 0; i < ioasic_ndevs; i++)
                    241:                if (ioasic_devs[i].iad_cookie == cookie)
                    242:                        break;
                    243:        if (i == ioasic_ndevs)
                    244:                panic("ioasic_intr_establish: invalid cookie.");
                    245:
                    246:        imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK);
                    247:         imsk |= ioasic_devs[i].iad_intrbits;
                    248:         bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk);
                    249: }
                    250:
                    251: void
                    252: ioasic_intr_disestablish(ioa, cookie)
                    253:        struct device *ioa;
                    254:        void *cookie;
                    255: {
                    256:        struct ioasic_softc *sc = (void *)ioasic_cd.cd_devs[0];
                    257:        u_long dev, i, imsk;
                    258:
                    259:        dev = (u_long)cookie;
                    260: #ifdef DIAGNOSTIC
                    261:        /* XXX check cookie. */
                    262: #endif
                    263:
                    264:        if (ioasicintrs[dev].iai_func == ioasic_intrnull)
                    265:                panic("ioasic_intr_disestablish: cookie %lu missing intr", dev);
                    266:
                    267:        /* Enable interrupts for the device. */
                    268:        for (i = 0; i < ioasic_ndevs; i++)
                    269:                if (ioasic_devs[i].iad_cookie == cookie)
                    270:                        break;
                    271:        if (i == ioasic_ndevs)
                    272:                panic("ioasic_intr_disestablish: invalid cookie.");
                    273:
                    274:        imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK);
                    275:        imsk &= ~ioasic_devs[i].iad_intrbits;
                    276:        bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk);
                    277:
                    278:        ioasicintrs[dev].iai_func = ioasic_intrnull;
                    279:        ioasicintrs[dev].iai_arg = (void *)dev;
                    280: }
                    281:
                    282: int
                    283: ioasic_intrnull(val)
                    284:        void *val;
                    285: {
                    286:
                    287:        panic("ioasic_intrnull: uncaught IOASIC intr for cookie %ld",
                    288:            (u_long)val);
                    289: }
                    290:
                    291: /*
                    292:  * ASIC interrupt handler.
                    293:  */
                    294: int
                    295: ioasic_intr(val)
                    296:        void *val;
                    297: {
                    298:        register struct ioasic_softc *sc = val;
                    299:        register int ifound;
                    300:        int gifound;
                    301:        u_int32_t sir, osir;
                    302:
                    303:        gifound = 0;
                    304:        do {
                    305:                ifound = 0;
                    306:                tc_syncbus();
                    307:
                    308:                osir = sir =
                    309:                    bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_INTR);
                    310:
                    311:                /* XXX DUPLICATION OF INTERRUPT BIT INFORMATION... */
                    312: #define        CHECKINTR(slot, bits, clear)                                    \
                    313:                if (sir & (bits)) {                                     \
                    314:                        ifound = 1;                                     \
                    315:                        ioasicintrs[slot].iai_count.ec_count++;         \
                    316:                        (*ioasicintrs[slot].iai_func)                   \
                    317:                            (ioasicintrs[slot].iai_arg);                \
                    318:                        if (clear)                                      \
                    319:                                sir &= ~(bits);                         \
                    320:                }
                    321:                CHECKINTR(IOASIC_DEV_SCC0, IOASIC_INTR_SCC_0, 0);
                    322:                CHECKINTR(IOASIC_DEV_SCC1, IOASIC_INTR_SCC_1, 0);
                    323:                CHECKINTR(IOASIC_DEV_LANCE, IOASIC_INTR_LANCE, 0);
                    324:                CHECKINTR(IOASIC_DEV_ISDN, IOASIC_INTR_ISDN_TXLOAD |
                    325:                    IOASIC_INTR_ISDN_RXLOAD | IOASIC_INTR_ISDN_OVRUN, 1);
                    326:
                    327:                if (sir != osir)
                    328:                        bus_space_write_4(sc->sc_bst, sc->sc_bsh,
                    329:                            IOASIC_INTR, sir);
                    330:
                    331:                gifound |= ifound;
                    332:        } while (ifound);
                    333:
                    334:        return (gifound);
                    335: }

CVSweb