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