[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     ! 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