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

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

1.1       nbrk        1: /* $OpenBSD: tc_3000_500.c,v 1.13 2006/03/04 12:33:17 miod Exp $ */
                      2: /* $NetBSD: tc_3000_500.c,v 1.24 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: #include <machine/rpb.h>
                     39:
                     40: #include <dev/tc/tcvar.h>
                     41: #include <alpha/tc/tc_conf.h>
                     42: #include <alpha/tc/tc_3000_500.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: void   tc_3000_500_intr_setup(void);
                     52: void   tc_3000_500_intr_establish(struct device *, void *,
                     53:            tc_intrlevel_t, int (*)(void *), void *);
                     54: void   tc_3000_500_intr_disestablish(struct device *, void *);
                     55: void   tc_3000_500_iointr(void *, unsigned long);
                     56:
                     57: int    tc_3000_500_intrnull(void *);
                     58: int    tc_3000_500_fb_cnattach(u_int64_t);
                     59:
                     60: #define C(x)   ((void *)(u_long)x)
                     61: #define        KV(x)   (ALPHA_PHYS_TO_K0SEG(x))
                     62:
                     63: struct tc_slotdesc tc_3000_500_slots[] = {
                     64:        { KV(0x100000000), C(TC_3000_500_DEV_OPT0), },  /* 0 - opt slot 0 */
                     65:        { KV(0x120000000), C(TC_3000_500_DEV_OPT1), },  /* 1 - opt slot 1 */
                     66:        { KV(0x140000000), C(TC_3000_500_DEV_OPT2), },  /* 2 - opt slot 2 */
                     67:        { KV(0x160000000), C(TC_3000_500_DEV_OPT3), },  /* 3 - opt slot 3 */
                     68:        { KV(0x180000000), C(TC_3000_500_DEV_OPT4), },  /* 4 - opt slot 4 */
                     69:        { KV(0x1a0000000), C(TC_3000_500_DEV_OPT5), },  /* 5 - opt slot 5 */
                     70:        { KV(0x1c0000000), C(TC_3000_500_DEV_BOGUS), }, /* 6 - TCDS ASIC */
                     71:        { KV(0x1e0000000), C(TC_3000_500_DEV_BOGUS), }, /* 7 - IOCTL ASIC */
                     72: };
                     73: int tc_3000_500_nslots =
                     74:     sizeof(tc_3000_500_slots) / sizeof(tc_3000_500_slots[0]);
                     75:
                     76: struct tc_builtin tc_3000_500_graphics_builtins[] = {
                     77:        { "FLAMG-IO",   7, 0x00000000, C(TC_3000_500_DEV_IOASIC),       },
                     78:        { "PMAGB-BA",   7, 0x02000000, C(TC_3000_500_DEV_CXTURBO),      },
                     79:        { "PMAZ-DS ",   6, 0x00000000, C(TC_3000_500_DEV_TCDS),         },
                     80: };
                     81: int tc_3000_500_graphics_nbuiltins = sizeof(tc_3000_500_graphics_builtins) /
                     82:     sizeof(tc_3000_500_graphics_builtins[0]);
                     83:
                     84: struct tc_builtin tc_3000_500_nographics_builtins[] = {
                     85:        { "FLAMG-IO",   7, 0x00000000, C(TC_3000_500_DEV_IOASIC),       },
                     86:        { "PMAZ-DS ",   6, 0x00000000, C(TC_3000_500_DEV_TCDS),         },
                     87: };
                     88: int tc_3000_500_nographics_nbuiltins = sizeof(tc_3000_500_nographics_builtins) /
                     89:     sizeof(tc_3000_500_nographics_builtins[0]);
                     90:
                     91: u_int32_t tc_3000_500_intrbits[TC_3000_500_NCOOKIES] = {
                     92:        TC_3000_500_IR_OPT0,
                     93:        TC_3000_500_IR_OPT1,
                     94:        TC_3000_500_IR_OPT2,
                     95:        TC_3000_500_IR_OPT3,
                     96:        TC_3000_500_IR_OPT4,
                     97:        TC_3000_500_IR_OPT5,
                     98:        TC_3000_500_IR_TCDS,
                     99:        TC_3000_500_IR_IOASIC,
                    100:        TC_3000_500_IR_CXTURBO,
                    101: };
                    102:
                    103: struct tcintr {
                    104:        int     (*tci_func)(void *);
                    105:        void    *tci_arg;
                    106:        struct evcount tci_count;
                    107:        char    tci_name[12];
                    108: } tc_3000_500_intr[TC_3000_500_NCOOKIES];
                    109:
                    110: u_int32_t tc_3000_500_imask;   /* intrs we want to ignore; mirrors IMR. */
                    111:
                    112: void
                    113: tc_3000_500_intr_setup()
                    114: {
                    115:        u_long i;
                    116:
                    117:        /*
                    118:         * Disable all slot interrupts.  Note that this cannot
                    119:         * actually disable CXTurbo, TCDS, and IOASIC interrupts.
                    120:         */
                    121:        tc_3000_500_imask = *(volatile u_int32_t *)TC_3000_500_IMR_READ;
                    122:        for (i = 0; i < TC_3000_500_NCOOKIES; i++)
                    123:                tc_3000_500_imask |= tc_3000_500_intrbits[i];
                    124:        *(volatile u_int32_t *)TC_3000_500_IMR_WRITE = tc_3000_500_imask;
                    125:        tc_mb();
                    126:
                    127:         /*
                    128:         * Set up interrupt handlers.
                    129:         */
                    130:         for (i = 0; i < TC_3000_500_NCOOKIES; i++) {
                    131:                tc_3000_500_intr[i].tci_func = tc_3000_500_intrnull;
                    132:                tc_3000_500_intr[i].tci_arg = (void *)i;
                    133:                snprintf(tc_3000_500_intr[i].tci_name,
                    134:                    sizeof tc_3000_500_intr[i].tci_name, "tc slot %u", i);
                    135:                evcount_attach(&tc_3000_500_intr[i].tci_count,
                    136:                    tc_3000_500_intr[i].tci_name, NULL, &evcount_intr);
                    137:         }
                    138: }
                    139:
                    140: void
                    141: tc_3000_500_intr_establish(tcadev, cookie, level, func, arg)
                    142:        struct device *tcadev;
                    143:        void *cookie, *arg;
                    144:        tc_intrlevel_t level;
                    145:        int (*func)(void *);
                    146: {
                    147:        u_long dev = (u_long)cookie;
                    148:
                    149: #ifdef DIAGNOSTIC
                    150:        /* XXX bounds-check cookie. */
                    151: #endif
                    152:
                    153:        if (tc_3000_500_intr[dev].tci_func != tc_3000_500_intrnull)
                    154:                panic("tc_3000_500_intr_establish: cookie %lu twice", dev);
                    155:
                    156:        tc_3000_500_intr[dev].tci_func = func;
                    157:        tc_3000_500_intr[dev].tci_arg = arg;
                    158:
                    159:        tc_3000_500_imask &= ~tc_3000_500_intrbits[dev];
                    160:        *(volatile u_int32_t *)TC_3000_500_IMR_WRITE = tc_3000_500_imask;
                    161:        tc_mb();
                    162: }
                    163:
                    164: void
                    165: tc_3000_500_intr_disestablish(tcadev, cookie)
                    166:        struct device *tcadev;
                    167:        void *cookie;
                    168: {
                    169:        u_long dev = (u_long)cookie;
                    170:
                    171: #ifdef DIAGNOSTIC
                    172:        /* XXX bounds-check cookie. */
                    173: #endif
                    174:
                    175:        if (tc_3000_500_intr[dev].tci_func == tc_3000_500_intrnull)
                    176:                panic("tc_3000_500_intr_disestablish: cookie %lu bad intr",
                    177:                    dev);
                    178:
                    179:        tc_3000_500_imask |= tc_3000_500_intrbits[dev];
                    180:        *(volatile u_int32_t *)TC_3000_500_IMR_WRITE = tc_3000_500_imask;
                    181:        tc_mb();
                    182:
                    183:        tc_3000_500_intr[dev].tci_func = tc_3000_500_intrnull;
                    184:        tc_3000_500_intr[dev].tci_arg = (void *)dev;
                    185: }
                    186:
                    187: int
                    188: tc_3000_500_intrnull(val)
                    189:        void *val;
                    190: {
                    191:
                    192:        panic("tc_3000_500_intrnull: uncaught TC intr for cookie %ld",
                    193:            (u_long)val);
                    194: }
                    195:
                    196: void
                    197: tc_3000_500_iointr(arg, vec)
                    198:         void *arg;
                    199:         unsigned long vec;
                    200: {
                    201:         u_int32_t ir;
                    202:        int ifound;
                    203:
                    204: #ifdef DIAGNOSTIC
                    205:        int s;
                    206:        if (vec != 0x800)
                    207:                panic("INVALID ASSUMPTION: vec 0x%lx, not 0x800", vec);
                    208:        s = splhigh();
                    209:        if (s != ALPHA_PSL_IPL_IO)
                    210:                panic("INVALID ASSUMPTION: IPL %d, not %d", s,
                    211:                    ALPHA_PSL_IPL_IO);
                    212:        splx(s);
                    213: #endif
                    214:
                    215:        do {
                    216:                tc_syncbus();
                    217:                ir = *(volatile u_int32_t *)TC_3000_500_IR_CLEAR;
                    218:
                    219:                /* Ignore interrupts that we haven't enabled. */
                    220:                ir &= ~(tc_3000_500_imask & 0x1ff);
                    221:
                    222:                ifound = 0;
                    223:
                    224: #define        CHECKINTR(slot)                                                 \
                    225:                if (ir & tc_3000_500_intrbits[slot]) {                  \
                    226:                        ifound = 1;                                     \
                    227:                        tc_3000_500_intr[slot].tci_count.ec_count++;    \
                    228:                        (*tc_3000_500_intr[slot].tci_func)              \
                    229:                            (tc_3000_500_intr[slot].tci_arg);           \
                    230:                }
                    231:                /* Do them in order of priority; highest slot # first. */
                    232:                CHECKINTR(TC_3000_500_DEV_CXTURBO);
                    233:                CHECKINTR(TC_3000_500_DEV_IOASIC);
                    234:                CHECKINTR(TC_3000_500_DEV_TCDS);
                    235:                CHECKINTR(TC_3000_500_DEV_OPT5);
                    236:                CHECKINTR(TC_3000_500_DEV_OPT4);
                    237:                CHECKINTR(TC_3000_500_DEV_OPT3);
                    238:                CHECKINTR(TC_3000_500_DEV_OPT2);
                    239:                CHECKINTR(TC_3000_500_DEV_OPT1);
                    240:                CHECKINTR(TC_3000_500_DEV_OPT0);
                    241: #undef CHECKINTR
                    242:
                    243: #ifdef DIAGNOSTIC
                    244: #define PRINTINTR(msg, bits)                                           \
                    245:        if (ir & bits)                                                  \
                    246:                printf(msg);
                    247:                PRINTINTR("Second error occurred\n", TC_3000_500_IR_ERR2);
                    248:                PRINTINTR("DMA buffer error\n", TC_3000_500_IR_DMABE);
                    249:                PRINTINTR("DMA cross 2K boundary\n", TC_3000_500_IR_DMA2K);
                    250:                PRINTINTR("TC reset in progress\n", TC_3000_500_IR_TCRESET);
                    251:                PRINTINTR("TC parity error\n", TC_3000_500_IR_TCPAR);
                    252:                PRINTINTR("DMA tag error\n", TC_3000_500_IR_DMATAG);
                    253:                PRINTINTR("Single-bit error\n", TC_3000_500_IR_DMASBE);
                    254:                PRINTINTR("Double-bit error\n", TC_3000_500_IR_DMADBE);
                    255:                PRINTINTR("TC I/O timeout\n", TC_3000_500_IR_TCTIMEOUT);
                    256:                PRINTINTR("DMA block too long\n", TC_3000_500_IR_DMABLOCK);
                    257:                PRINTINTR("Invalid I/O address\n", TC_3000_500_IR_IOADDR);
                    258:                PRINTINTR("DMA scatter/gather invalid\n", TC_3000_500_IR_DMASG);
                    259:                PRINTINTR("Scatter/gather parity error\n",
                    260:                    TC_3000_500_IR_SGPAR);
                    261: #undef PRINTINTR
                    262: #endif
                    263:        } while (ifound);
                    264: }
                    265:
                    266: #if NWSDISPLAY > 0
                    267: /*
                    268:  * tc_3000_500_fb_cnattach --
                    269:  *     Attempt to map the CTB output device to a slot and attach the
                    270:  * framebuffer as the output side of the console.
                    271:  */
                    272: int
                    273: tc_3000_500_fb_cnattach(turbo_slot)
                    274:        u_int64_t turbo_slot;
                    275: {
                    276:        u_int32_t output_slot;
                    277:
                    278:        output_slot = turbo_slot & 0xffffffff;
                    279:
                    280:        if (output_slot >= tc_3000_500_nslots) {
                    281:                return EINVAL;
                    282:        }
                    283:
                    284:        if (hwrpb->rpb_variation & SV_GRAPHICS) {
                    285:                if (output_slot == 0) {
                    286: #if NSFB > 0
                    287:                        sfb_cnattach(KV(0x1e0000000) + 0x02000000);
                    288:                        return 0;
                    289: #else
                    290:                        return ENXIO;
                    291: #endif
                    292:                }
                    293:        } else {
                    294:                /*
                    295:                 * Slots 0-2 in the tc_3000_500_slots array are only
                    296:                 * on the 500 models that also have the CXTurbo
                    297:                 * (500/800/900) and a total of 6 TC slots.  For the
                    298:                 * 400/600/700, slots 0-2 are in table locations 3-5, so
                    299:                 * offset the CTB slot by 3 to get the address in our table.
                    300:                 */
                    301:                output_slot += 3;
                    302:        }
                    303:        return tc_fb_cnattach(tc_3000_500_slots[output_slot-1].tcs_addr);
                    304: }
                    305: #endif /* NWSDISPLAY */
                    306:
                    307: #if 0
                    308: /*
                    309:  * tc_3000_500_ioslot --
                    310:  *     Set the PBS bits for devices on the TC.
                    311:  */
                    312: void
                    313: tc_3000_500_ioslot(slot, flags, set)
                    314:        u_int32_t slot, flags;
                    315:        int set;
                    316: {
                    317:        volatile u_int32_t *iosp;
                    318:        u_int32_t ios;
                    319:        int s;
                    320:
                    321:        iosp = (volatile u_int32_t *)TC_3000_500_IOSLOT;
                    322:        ios = *iosp;
                    323:        flags <<= (slot * 3);
                    324:        if (set)
                    325:                ios |= flags;
                    326:        else
                    327:                ios &= ~flags;
                    328:        s = splhigh();
                    329:        *iosp = ios;
                    330:        tc_mb();
                    331:        splx(s);
                    332: }
                    333: #endif

CVSweb