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

Annotation of sys/arch/alpha/tc/tc_3000_300.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: tc_3000_300.c,v 1.12 2006/03/04 12:33:17 miod Exp $ */
        !             2: /* $NetBSD: tc_3000_300.c,v 1.26 2001/07/27 00:25:21 thorpej Exp $ */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Author: Chris G. Demetriou
        !             9:  *
        !            10:  * Permission to use, copy, modify and distribute this software and
        !            11:  * its documentation is hereby granted, provided that both the copyright
        !            12:  * notice and this permission notice appear in all copies of the
        !            13:  * software, derivative works or modified versions, and any portions
        !            14:  * thereof, and that both notices appear in supporting documentation.
        !            15:  *
        !            16:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            17:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
        !            18:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            19:  *
        !            20:  * Carnegie Mellon requests users of this software to return to
        !            21:  *
        !            22:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
        !            23:  *  School of Computer Science
        !            24:  *  Carnegie Mellon University
        !            25:  *  Pittsburgh PA 15213-3890
        !            26:  *
        !            27:  * any improvements or extensions that they make and grant Carnegie the
        !            28:  * rights to redistribute these changes.
        !            29:  */
        !            30:
        !            31: #include <sys/param.h>
        !            32: #include <sys/systm.h>
        !            33: #include <sys/device.h>
        !            34: #include <sys/malloc.h>
        !            35:
        !            36: #include <machine/autoconf.h>
        !            37: #include <machine/pte.h>
        !            38:
        !            39: #include <dev/tc/tcvar.h>
        !            40: #include <dev/tc/ioasicreg.h>
        !            41: #include <alpha/tc/tc_conf.h>
        !            42: #include <alpha/tc/tc_3000_300.h>
        !            43:
        !            44: #include "wsdisplay.h"
        !            45: #include "sfb.h"
        !            46:
        !            47: #if NSFB > 0
        !            48: extern int     sfb_cnattach(tc_addr_t);
        !            49: #endif
        !            50:
        !            51: int    tc_3000_300_intrnull(void *);
        !            52:
        !            53: #define        C(x)    ((void *)(u_long)x)
        !            54: #define        KV(x)   (ALPHA_PHYS_TO_K0SEG(x))
        !            55:
        !            56: /*
        !            57:  * We have to read and modify the IOASIC registers directly, because
        !            58:  * the TC option slot interrupt request and mask bits are stored there,
        !            59:  * and the ioasic code isn't initted when we need to frob some interrupt
        !            60:  * bits.
        !            61:  */
        !            62: #define        DEC_3000_300_IOASIC_ADDR        KV(0x1a0000000)
        !            63:
        !            64: struct tc_slotdesc tc_3000_300_slots[] = {
        !            65:        { KV(0x100000000), C(TC_3000_300_DEV_OPT0), },  /* 0 - opt slot 0 */
        !            66:        { KV(0x120000000), C(TC_3000_300_DEV_OPT1), },  /* 1 - opt slot 1 */
        !            67:        { KV(0x140000000), C(TC_3000_300_DEV_BOGUS), }, /* 2 - unused */
        !            68:        { KV(0x160000000), C(TC_3000_300_DEV_BOGUS), }, /* 3 - unused */
        !            69:        { KV(0x180000000), C(TC_3000_300_DEV_BOGUS), }, /* 4 - TCDS ASIC */
        !            70:        { KV(0x1a0000000), C(TC_3000_300_DEV_BOGUS), }, /* 5 - IOCTL ASIC */
        !            71:        { KV(0x1c0000000), C(TC_3000_300_DEV_BOGUS), }, /* 6 - CXTurbo */
        !            72: };
        !            73: int tc_3000_300_nslots =
        !            74:     sizeof(tc_3000_300_slots) / sizeof(tc_3000_300_slots[0]);
        !            75:
        !            76: struct tc_builtin tc_3000_300_builtins[] = {
        !            77:        { "PMAGB-BA",   6, 0x02000000, C(TC_3000_300_DEV_CXTURBO),      },
        !            78:        { "FLAMG-IO",   5, 0x00000000, C(TC_3000_300_DEV_IOASIC),       },
        !            79:        { "PMAZ-DS ",   4, 0x00000000, C(TC_3000_300_DEV_TCDS),         },
        !            80: };
        !            81: int tc_3000_300_nbuiltins =
        !            82:     sizeof(tc_3000_300_builtins) / sizeof(tc_3000_300_builtins[0]);
        !            83:
        !            84: struct tcintr {
        !            85:        int     (*tci_func)(void *);
        !            86:        void    *tci_arg;
        !            87:        struct evcount tci_count;
        !            88:        char    tci_name[12];
        !            89: } tc_3000_300_intr[TC_3000_300_NCOOKIES];
        !            90:
        !            91: void
        !            92: tc_3000_300_intr_setup()
        !            93: {
        !            94:        volatile u_int32_t *imskp;
        !            95:        u_long i;
        !            96:
        !            97:        /*
        !            98:         * Disable all interrupts that we can (can't disable builtins).
        !            99:         */
        !           100:        imskp = (volatile u_int32_t *)(DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
        !           101:        *imskp &= ~(IOASIC_INTR_300_OPT0 | IOASIC_INTR_300_OPT1);
        !           102:
        !           103:        /*
        !           104:         * Set up interrupt handlers.
        !           105:         */
        !           106:        for (i = 0; i < TC_3000_300_NCOOKIES; i++) {
        !           107:                 tc_3000_300_intr[i].tci_func = tc_3000_300_intrnull;
        !           108:                 tc_3000_300_intr[i].tci_arg = (void *)i;
        !           109:                snprintf(tc_3000_300_intr[i].tci_name,
        !           110:                    sizeof tc_3000_300_intr[i].tci_name, "tc slot %u", i);
        !           111:                evcount_attach(&tc_3000_300_intr[i].tci_count,
        !           112:                    tc_3000_300_intr[i].tci_name, NULL, &evcount_intr);
        !           113:        }
        !           114: }
        !           115:
        !           116: void
        !           117: tc_3000_300_intr_establish(tcadev, cookie, level, func, arg)
        !           118:        struct device *tcadev;
        !           119:        void *cookie, *arg;
        !           120:        tc_intrlevel_t level;
        !           121:        int (*func)(void *);
        !           122: {
        !           123:        volatile u_int32_t *imskp;
        !           124:        u_long dev = (u_long)cookie;
        !           125:
        !           126: #ifdef DIAGNOSTIC
        !           127:        /* XXX bounds-check cookie. */
        !           128: #endif
        !           129:
        !           130:        if (tc_3000_300_intr[dev].tci_func != tc_3000_300_intrnull)
        !           131:                panic("tc_3000_300_intr_establish: cookie %lu twice", dev);
        !           132:
        !           133:        tc_3000_300_intr[dev].tci_func = func;
        !           134:        tc_3000_300_intr[dev].tci_arg = arg;
        !           135:
        !           136:        imskp = (volatile u_int32_t *)(DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
        !           137:        switch (dev) {
        !           138:        case TC_3000_300_DEV_OPT0:
        !           139:                *imskp |= IOASIC_INTR_300_OPT0;
        !           140:                break;
        !           141:        case TC_3000_300_DEV_OPT1:
        !           142:                *imskp |= IOASIC_INTR_300_OPT1;
        !           143:                break;
        !           144:        default:
        !           145:                /* interrupts for builtins always enabled */
        !           146:                break;
        !           147:        }
        !           148: }
        !           149:
        !           150: void
        !           151: tc_3000_300_intr_disestablish(tcadev, cookie)
        !           152:        struct device *tcadev;
        !           153:        void *cookie;
        !           154: {
        !           155:        volatile u_int32_t *imskp;
        !           156:        u_long dev = (u_long)cookie;
        !           157:
        !           158: #ifdef DIAGNOSTIC
        !           159:        /* XXX bounds-check cookie. */
        !           160: #endif
        !           161:
        !           162:        if (tc_3000_300_intr[dev].tci_func == tc_3000_300_intrnull)
        !           163:                panic("tc_3000_300_intr_disestablish: cookie %lu bad intr",
        !           164:                    dev);
        !           165:
        !           166:        imskp = (volatile u_int32_t *)(DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
        !           167:        switch (dev) {
        !           168:        case TC_3000_300_DEV_OPT0:
        !           169:                *imskp &= ~IOASIC_INTR_300_OPT0;
        !           170:                break;
        !           171:        case TC_3000_300_DEV_OPT1:
        !           172:                *imskp &= ~IOASIC_INTR_300_OPT1;
        !           173:                break;
        !           174:        default:
        !           175:                /* interrupts for builtins always enabled */
        !           176:                break;
        !           177:        }
        !           178:
        !           179:        tc_3000_300_intr[dev].tci_func = tc_3000_300_intrnull;
        !           180:        tc_3000_300_intr[dev].tci_arg = (void *)dev;
        !           181: }
        !           182:
        !           183: int
        !           184: tc_3000_300_intrnull(val)
        !           185:        void *val;
        !           186: {
        !           187:
        !           188:        panic("tc_3000_300_intrnull: uncaught TC intr for cookie %ld",
        !           189:            (u_long)val);
        !           190: }
        !           191:
        !           192: void
        !           193: tc_3000_300_iointr(arg, vec)
        !           194:        void *arg;
        !           195:        unsigned long vec;
        !           196: {
        !           197:        u_int32_t tcir, ioasicir, ioasicimr;
        !           198:        int ifound;
        !           199:
        !           200: #ifdef DIAGNOSTIC
        !           201:        int s;
        !           202:        if (vec != 0x800)
        !           203:                panic("INVALID ASSUMPTION: vec 0x%lx, not 0x800", vec);
        !           204:        s = splhigh();
        !           205:        if (s != ALPHA_PSL_IPL_IO)
        !           206:                panic("INVALID ASSUMPTION: IPL %d, not %d", s,
        !           207:                    ALPHA_PSL_IPL_IO);
        !           208:        splx(s);
        !           209: #endif
        !           210:
        !           211:        do {
        !           212:                tc_syncbus();
        !           213:
        !           214:                /* find out what interrupts/errors occurred */
        !           215:                tcir = *(volatile u_int32_t *)TC_3000_300_IR;
        !           216:                ioasicir = *(volatile u_int32_t *)
        !           217:                    (DEC_3000_300_IOASIC_ADDR + IOASIC_INTR);
        !           218:                ioasicimr = *(volatile u_int32_t *)
        !           219:                    (DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
        !           220:                tc_mb();
        !           221:
        !           222:                /* Ignore interrupts that aren't enabled out. */
        !           223:                ioasicir &= ioasicimr;
        !           224:
        !           225:                /* clear the interrupts/errors we found. */
        !           226:                *(volatile u_int32_t *)TC_3000_300_IR = tcir;
        !           227:                /* XXX can't clear TC option slot interrupts here? */
        !           228:                tc_wmb();
        !           229:
        !           230:                ifound = 0;
        !           231:
        !           232: #define        CHECKINTR(slot, flag)                                           \
        !           233:                if (flag) {                                             \
        !           234:                        ifound = 1;                                     \
        !           235:                        tc_3000_300_intr[slot].tci_count.ec_count++;    \
        !           236:                        (*tc_3000_300_intr[slot].tci_func)              \
        !           237:                            (tc_3000_300_intr[slot].tci_arg);           \
        !           238:                }
        !           239:                /* Do them in order of priority; highest slot # first. */
        !           240:                CHECKINTR(TC_3000_300_DEV_CXTURBO,
        !           241:                    tcir & TC_3000_300_IR_CXTURBO);
        !           242:                CHECKINTR(TC_3000_300_DEV_IOASIC,
        !           243:                    (tcir & TC_3000_300_IR_IOASIC) &&
        !           244:                    (ioasicir & ~(IOASIC_INTR_300_OPT1|IOASIC_INTR_300_OPT0)));
        !           245:                CHECKINTR(TC_3000_300_DEV_TCDS, tcir & TC_3000_300_IR_TCDS);
        !           246:                CHECKINTR(TC_3000_300_DEV_OPT1,
        !           247:                    ioasicir & IOASIC_INTR_300_OPT1);
        !           248:                CHECKINTR(TC_3000_300_DEV_OPT0,
        !           249:                    ioasicir & IOASIC_INTR_300_OPT0);
        !           250: #undef CHECKINTR
        !           251:
        !           252: #ifdef DIAGNOSTIC
        !           253: #define PRINTINTR(msg, bits)                                           \
        !           254:        if (tcir & bits)                                                \
        !           255:                printf(msg);
        !           256:                PRINTINTR("BCache tag parity error\n",
        !           257:                    TC_3000_300_IR_BCTAGPARITY);
        !           258:                PRINTINTR("TC overrun error\n", TC_3000_300_IR_TCOVERRUN);
        !           259:                PRINTINTR("TC I/O timeout\n", TC_3000_300_IR_TCTIMEOUT);
        !           260:                PRINTINTR("Bcache parity error\n",
        !           261:                    TC_3000_300_IR_BCACHEPARITY);
        !           262:                PRINTINTR("Memory parity error\n", TC_3000_300_IR_MEMPARITY);
        !           263: #undef PRINTINTR
        !           264: #endif
        !           265:        } while (ifound);
        !           266: }
        !           267:
        !           268: #if NWSDISPLAY > 0
        !           269: /*
        !           270:  * tc_3000_300_fb_cnattach --
        !           271:  *     Attempt to map the CTB output device to a slot and attach the
        !           272:  * framebuffer as the output side of the console.
        !           273:  */
        !           274: int
        !           275: tc_3000_300_fb_cnattach(turbo_slot)
        !           276:        u_int64_t turbo_slot;
        !           277: {
        !           278:        u_int32_t output_slot;
        !           279:
        !           280:        output_slot = turbo_slot & 0xffffffff;
        !           281:
        !           282:        if (output_slot >= tc_3000_300_nslots) {
        !           283:                return EINVAL;
        !           284:        }
        !           285:
        !           286:        if (output_slot == 0) {
        !           287: #if NSFB > 0
        !           288:                sfb_cnattach(KV(0x1c0000000) + 0x02000000);
        !           289:                return 0;
        !           290: #else
        !           291:                return ENXIO;
        !           292: #endif
        !           293:        }
        !           294:
        !           295:        return tc_fb_cnattach(tc_3000_300_slots[output_slot-1].tcs_addr);
        !           296: }
        !           297: #endif /* NWSDISPLAY */

CVSweb