[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

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