[BACK]Return to psc.c CVS log [TXT][DIR] Up to [local] / sys / arch / mac68k / mac68k

Annotation of sys/arch/mac68k/mac68k/psc.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: psc.c,v 1.6 2004/12/14 14:50:55 martin Exp $  */
        !             2: /*     $NetBSD: psc.c,v 1.8 2004/03/26 12:15:46 wiz Exp $      */
        !             3:
        !             4:
        !             5: /*-
        !             6:  * Copyright (c) 1997 David Huang <khym@azeotrope.org>
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. The name of the author may not be used to endorse or promote products
        !            15:  *    derived from this software without specific prior written permission
        !            16:  *
        !            17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            19:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            20:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            21:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            22:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            23:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            24:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            25:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            26:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            27:  *
        !            28:  */
        !            29:
        !            30: /*
        !            31:  * This handles registration/unregistration of PSC (Peripheral
        !            32:  * Subsystem Controller) interrupts. The PSC is used only on the
        !            33:  * Centris/Quadra 660av and the Quadra 840av.
        !            34:  */
        !            35:
        !            36: #include <sys/param.h>
        !            37: #include <sys/systm.h>
        !            38:
        !            39: #include <machine/bus.h>
        !            40: #include <machine/cpu.h>
        !            41: #include <machine/psc.h>
        !            42:
        !            43: static void    psc_kill_dma(void);
        !            44: int            psc_lev3_intr(void *);
        !            45: static void    psc_lev3_noint(void *);
        !            46: int            psc_lev4_intr(void *);
        !            47: static int     psc_lev4_noint(void *);
        !            48: int            psc_lev5_intr(void *);
        !            49: static void    psc_lev5_noint(void *);
        !            50: int            psc_lev6_intr(void *);
        !            51: static void    psc_lev6_noint(void *);
        !            52:
        !            53: void   (*psc3_ihandler)(void *) = psc_lev3_noint;
        !            54: void   *psc3_iarg;
        !            55:
        !            56: int (*psc4_itab[4])(void *) = {
        !            57:        psc_lev4_noint, /* 0 */
        !            58:        psc_lev4_noint, /* 1 */
        !            59:        psc_lev4_noint, /* 2 */
        !            60:        psc_lev4_noint  /* 3 */
        !            61: };
        !            62:
        !            63: void *psc4_iarg[4] = {
        !            64:        (void *)0, (void *)1, (void *)2, (void *)3
        !            65: };
        !            66:
        !            67: void (*psc5_itab[2])(void *) = {
        !            68:        psc_lev5_noint, /* 0 */
        !            69:        psc_lev5_noint  /* 1 */
        !            70: };
        !            71:
        !            72: void *psc5_iarg[2] = {
        !            73:        (void *)0, (void *)1
        !            74: };
        !            75:
        !            76: void (*psc6_itab[3])(void *) = {
        !            77:        psc_lev6_noint, /* 0 */
        !            78:        psc_lev6_noint, /* 1 */
        !            79:        psc_lev6_noint  /* 2 */
        !            80: };
        !            81:
        !            82: void *psc6_iarg[3] = {
        !            83:        (void *)0, (void *)1, (void *)2
        !            84: };
        !            85:
        !            86: /*
        !            87:  * Make excessively sure that all PSC DMA is shut down.
        !            88:  */
        !            89: void
        !            90: psc_kill_dma()
        !            91: {
        !            92:        int     i;
        !            93:
        !            94:        for (i = 0; i < 9; i++) {
        !            95:                psc_reg2(PSC_CTLBASE + (i << 4)) = 0x8800;
        !            96:                psc_reg2(PSC_CTLBASE + (i << 4)) = 0x1000;
        !            97:                psc_reg2(PSC_CMDBASE + (i << 5)) = 0x1100;
        !            98:                psc_reg2(PSC_CMDBASE + (i << 5) + PSC_SET1) = 0x1100;
        !            99:        }
        !           100: }
        !           101:
        !           102: /*
        !           103:  * Setup the interrupt vectors and disable most of the PSC interrupts
        !           104:  */
        !           105: void
        !           106: psc_init()
        !           107: {
        !           108:        int     s, i;
        !           109:
        !           110:        /*
        !           111:         * Only Quadra AVs have a PSC.
        !           112:         */
        !           113:        if (current_mac_model->class == MACH_CLASSAV) {
        !           114:                s = splhigh();
        !           115:                psc_kill_dma();
        !           116:                intr_establish(psc_lev3_intr, NULL, 3, "psc");
        !           117:                intr_establish(psc_lev4_intr, NULL, 4, "psc");
        !           118:                intr_establish(psc_lev5_intr, NULL, 5, "psc");
        !           119:                intr_establish(psc_lev6_intr, NULL, 6, "psc");
        !           120:                for (i = 3; i < 7; i++) {
        !           121:                        /* Clear any flags */
        !           122:                        psc_reg1(PSC_ISR_BASE + 0x10 * i) = 0x0F;
        !           123:                        /* Clear any interrupt enable */
        !           124:                        psc_reg1(PSC_IER_BASE + 0x10 * i) = 0x0F;
        !           125:                }
        !           126:                psc_reg1(PSC_LEV4_IER) = 0x86; /* enable SCC */
        !           127:                splx(s);
        !           128:        }
        !           129: }
        !           130:
        !           131: int
        !           132: add_psc_lev3_intr(handler, arg)
        !           133:        void (*handler)(void *);
        !           134:        void *arg;
        !           135: {
        !           136:        int s;
        !           137:
        !           138:        s = splhigh();
        !           139:
        !           140:        psc3_ihandler = handler;
        !           141:        psc3_iarg = arg;
        !           142:
        !           143:        splx(s);
        !           144:
        !           145:        return 1;
        !           146: }
        !           147:
        !           148: int
        !           149: remove_psc_lev3_intr()
        !           150: {
        !           151:        return add_psc_lev3_intr(psc_lev3_noint, (void *)0);
        !           152: }
        !           153:
        !           154: int
        !           155: psc_lev3_intr(arg)
        !           156:        void *arg;
        !           157: {
        !           158:        u_int8_t intbits;
        !           159:
        !           160:        while ((intbits = psc_reg1(PSC_LEV3_ISR)) != psc_reg1(PSC_LEV3_ISR))
        !           161:                ;
        !           162:        intbits &= 0x1 & psc_reg1(PSC_LEV3_IER);
        !           163:
        !           164:        if (intbits)
        !           165:                psc3_ihandler(psc3_iarg);
        !           166:
        !           167:        return 0;
        !           168: }
        !           169:
        !           170: static void
        !           171: psc_lev3_noint(arg)
        !           172:        void *arg;
        !           173: {
        !           174: #ifdef DEBUG
        !           175:        printf("psc_lev3_noint\n");
        !           176: #endif
        !           177: }
        !           178:
        !           179: int
        !           180: psc_lev4_intr(arg)
        !           181:        void * arg;
        !           182: {
        !           183:        u_int8_t intbits, bitnum;
        !           184:        u_int mask;
        !           185:
        !           186:        while ((intbits = psc_reg1(PSC_LEV4_ISR)) != psc_reg1(PSC_LEV4_ISR))
        !           187:                ;
        !           188:        intbits &= 0xf & psc_reg1(PSC_LEV4_IER);
        !           189:
        !           190:        mask = 1;
        !           191:        bitnum = 0;
        !           192:        do {
        !           193:                if (intbits & mask)
        !           194:                        psc4_itab[bitnum](psc4_iarg[bitnum]);
        !           195:                mask <<= 1;
        !           196:        } while (intbits >= mask && ++bitnum);
        !           197:
        !           198:        return 0;
        !           199: }
        !           200:
        !           201: int
        !           202: add_psc_lev4_intr(dev, handler, arg)
        !           203:        int dev;
        !           204:        int (*handler)(void *);
        !           205:        void *arg;
        !           206: {
        !           207:        int s;
        !           208:
        !           209:        if ((dev < 0) || (dev > 3))
        !           210:                return 0;
        !           211:
        !           212:        s = splhigh();
        !           213:
        !           214:        psc4_itab[dev] = handler;
        !           215:        psc4_iarg[dev] = arg;
        !           216:
        !           217:        splx(s);
        !           218:
        !           219:        return 1;
        !           220: }
        !           221:
        !           222: int
        !           223: remove_psc_lev4_intr(dev)
        !           224:        int dev;
        !           225: {
        !           226:        return add_psc_lev4_intr(dev, psc_lev4_noint, (void *)dev);
        !           227: }
        !           228:
        !           229: int
        !           230: psc_lev4_noint(arg)
        !           231:        void *arg;
        !           232: {
        !           233: #ifdef DEBUG
        !           234:        printf("psc_lev4_noint: device %d\n", (int)arg);
        !           235: #endif
        !           236:        return 0;
        !           237: }
        !           238:
        !           239: int
        !           240: psc_lev5_intr(arg)
        !           241:        void *arg;
        !           242: {
        !           243:        u_int8_t intbits, bitnum;
        !           244:        u_int mask;
        !           245:
        !           246:        while ((intbits = psc_reg1(PSC_LEV5_ISR)) != psc_reg1(PSC_LEV5_ISR))
        !           247:                ;
        !           248:        intbits &= 0x3 & psc_reg1(PSC_LEV5_IER);
        !           249:
        !           250:        mask = 1;
        !           251:        bitnum = 0;
        !           252:        do {
        !           253:                if (intbits & mask)
        !           254:                        psc5_itab[bitnum](psc5_iarg[bitnum]);
        !           255:                mask <<= 1;
        !           256:        } while (intbits >= mask && ++bitnum);
        !           257:
        !           258:        return 0;
        !           259: }
        !           260:
        !           261: int
        !           262: add_psc_lev5_intr(dev, handler, arg)
        !           263:        int dev;
        !           264:        void (*handler)(void *);
        !           265:        void *arg;
        !           266: {
        !           267:        int s;
        !           268:
        !           269:        if ((dev < 0) || (dev > 1))
        !           270:                return 0;
        !           271:
        !           272:        s = splhigh();
        !           273:
        !           274:        psc5_itab[dev] = handler;
        !           275:        psc5_iarg[dev] = arg;
        !           276:
        !           277:        splx(s);
        !           278:
        !           279:        return 1;
        !           280: }
        !           281:
        !           282: int
        !           283: remove_psc_lev5_intr(dev)
        !           284:        int dev;
        !           285: {
        !           286:        return add_psc_lev5_intr(dev, psc_lev5_noint, (void *)dev);
        !           287: }
        !           288:
        !           289: void
        !           290: psc_lev5_noint(arg)
        !           291:        void *arg;
        !           292: {
        !           293: #ifdef DEBUG
        !           294:        printf("psc_lev5_noint: device %d\n", (int)arg);
        !           295: #endif
        !           296: }
        !           297:
        !           298: int
        !           299: psc_lev6_intr(arg)
        !           300:        void *arg;
        !           301: {
        !           302:        u_int8_t intbits, bitnum;
        !           303:        u_int mask;
        !           304:
        !           305:        while ((intbits = psc_reg1(PSC_LEV6_ISR)) != psc_reg1(PSC_LEV6_ISR))
        !           306:                ;
        !           307:        intbits &= 0x7 & psc_reg1(PSC_LEV6_IER);
        !           308:
        !           309:        mask = 1;
        !           310:        bitnum = 0;
        !           311:        do {
        !           312:                if (intbits & mask)
        !           313:                        psc6_itab[bitnum](psc6_iarg[bitnum]);
        !           314:                mask <<= 1;
        !           315:        } while (intbits >= mask && ++bitnum);
        !           316:
        !           317:        return 0;
        !           318: }
        !           319:
        !           320: int
        !           321: add_psc_lev6_intr(dev, handler, arg)
        !           322:        int dev;
        !           323:        void (*handler)(void *);
        !           324:        void *arg;
        !           325: {
        !           326:        int s;
        !           327:
        !           328:        if ((dev < 0) || (dev > 2))
        !           329:                return 0;
        !           330:
        !           331:        s = splhigh();
        !           332:
        !           333:        psc6_itab[dev] = handler;
        !           334:        psc6_iarg[dev] = arg;
        !           335:
        !           336:        splx(s);
        !           337:
        !           338:        return 1;
        !           339: }
        !           340:
        !           341: int
        !           342: remove_psc_lev6_intr(dev)
        !           343:        int dev;
        !           344: {
        !           345:        return add_psc_lev6_intr(dev, psc_lev6_noint, (void *)dev);
        !           346: }
        !           347:
        !           348: void
        !           349: psc_lev6_noint(arg)
        !           350:        void *arg;
        !           351: {
        !           352: #ifdef DEBUG
        !           353:        printf("psc_lev6_noint: device %d\n", (int)arg);
        !           354: #endif
        !           355: }

CVSweb