[BACK]Return to uba_sbi.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / uba

Annotation of sys/arch/vax/uba/uba_sbi.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: uba_sbi.c,v 1.4 2005/11/24 04:55:18 brad Exp $        */
                      2: /*     $NetBSD: uba_sbi.c,v 1.1 1999/06/21 16:23:01 ragge Exp $           */
                      3: /*
                      4:  * Copyright (c) 1996 Jonathan Stone.
                      5:  * Copyright (c) 1994, 1996 Ludd, University of Lule}, Sweden.
                      6:  * Copyright (c) 1982, 1986 The Regents of the University of California.
                      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. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
                     33:  *     @(#)uba.c       7.10 (Berkeley) 12/16/90
                     34:  *     @(#)autoconf.c  7.20 (Berkeley) 5/9/91
                     35:  */
                     36:
                     37: #include <sys/param.h>
                     38: #include <sys/device.h>
                     39: #include <sys/systm.h>
                     40: #include <sys/kernel.h>
                     41:
                     42: #define _VAX_BUS_DMA_PRIVATE
                     43: #include <machine/bus.h>
                     44: #include <machine/mtpr.h>
                     45: #include <machine/nexus.h>
                     46: #include <machine/cpu.h>
                     47: #include <machine/sgmap.h>
                     48: #include <machine/scb.h>
                     49:
                     50: #include <arch/vax/qbus/ubavar.h>
                     51:
                     52: #include <arch/vax/uba/uba_common.h>
                     53:
                     54: /* Some SBI-specific defines */
                     55: #define UBASIZE                (UBAPAGES * VAX_NBPG)
                     56: #define UMEMA8600(i)           (0x20100000+(i)*0x40000)
                     57: #define        UMEMB8600(i)    (0x22100000+(i)*0x40000)
                     58:
                     59: /*
                     60:  * Some status registers.
                     61:  */
                     62: #define UBACNFGR_UBIC  0x00010000      /* unibus init complete */
                     63: #define UBACNFGR_BITS \
                     64: "\40\40PARFLT\37WSQFLT\36URDFLT\35ISQFLT\34MXTFLT\33XMTFLT\30ADPDN\27ADPUP\23UBINIT\22UBPDN\21UBIC"
                     65:
                     66: #define UBACR_IFS      0x00000040      /* interrupt field switch */
                     67: #define UBACR_BRIE     0x00000020      /* BR interrupt enable */
                     68: #define UBACR_USEFIE   0x00000010      /* UNIBUS to SBI error field IE */
                     69: #define UBACR_SUEFIE   0x00000008      /* SBI to UNIBUS error field IE */
                     70: #define UBACR_ADINIT   0x00000001      /* adapter init */
                     71:
                     72: #define UBADPR_BNE     0x80000000      /* buffer not empty - purge */
                     73:
                     74: #define UBABRRVR_DIV    0x0000ffff      /* device interrupt vector field */
                     75:
                     76: #define UBASR_BITS \
                     77: "\20\13RDTO\12RDS\11CRD\10CXTER\7CXTMO\6DPPE\5IVMR\4MRPF\3LEB\2UBSTO\1UBSSYNTO"
                     78:
                     79: char    ubasr_bits[] = UBASR_BITS;
                     80:
                     81: /*
                     82:  * The DW780 are directly connected to the SBI on 11/780 and 8600.
                     83:  */
                     84: static int     dw780_match(struct device *, struct cfdata *, void *);
                     85: static void    dw780_attach(struct device *, struct device *, void *);
                     86: static void    dw780_init(struct uba_softc*);
                     87: static void    dw780_beforescan(struct uba_softc *);
                     88: static void    dw780_afterscan(struct uba_softc *);
                     89: static int     dw780_errchk(struct uba_softc *);
                     90: static void    uba_dw780int(int);
                     91: static  void   ubaerror(struct uba_softc *, int *, int *);
                     92: #ifdef notyet
                     93: static void    dw780_purge(struct uba_softc *, int);
                     94: #endif
                     95:
                     96: struct cfattach uba_sbi_ca = {
                     97:        sizeof(struct uba_vsoftc), dw780_match, dw780_attach
                     98: };
                     99:
                    100: extern struct vax_bus_space vax_mem_bus_space;
                    101:
                    102: volatile int svec;
                    103:
                    104: int
                    105: dw780_match(parent, cf, aux)
                    106:        struct device *parent;
                    107:        struct cfdata *cf;
                    108:        void *aux;
                    109: {
                    110:        struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
                    111:
                    112:        if ((cf->cf_loc[0] != sa->nexnum) && (cf->cf_loc[0] > -1 ))
                    113:                return 0;
                    114:        /*
                    115:         * The uba type is actually only telling where the uba
                    116:         * space is in nexus space.
                    117:         */
                    118:        if ((sa->type & ~3) != NEX_UBA0)
                    119:                return 0;
                    120:
                    121:        return 1;
                    122: }
                    123:
                    124: void
                    125: dw780_attach(parent, self, aux)
                    126:        struct device *parent, *self;
                    127:        void *aux;
                    128: {
                    129:        struct uba_vsoftc *sc = (void *)self;
                    130:        struct sbi_attach_args *sa = aux;
                    131:        int ubaddr = sa->type & 3;
                    132:        int i;
                    133:
                    134:        printf(": DW780\n");
                    135:        /*
                    136:         * Fill in bus specific data.
                    137:         */
                    138:        sc->uv_sc.uh_ubainit = dw780_init;
                    139: #ifdef notyet
                    140:        sc->uv_sc.uh_ubapurge = dw780_purge;
                    141: #endif
                    142:        sc->uv_sc.uh_beforescan = dw780_beforescan;
                    143:        sc->uv_sc.uh_afterscan = dw780_afterscan;
                    144:        sc->uv_sc.uh_errchk = dw780_errchk;
                    145:        sc->uv_sc.uh_iot = &vax_mem_bus_space;
                    146:        sc->uv_sc.uh_dmat = &sc->uv_dmat;
                    147:        sc->uv_uba = (void *)sa->nexaddr;
                    148:        sc->uh_ibase = VAX_NBPG + ubaddr * VAX_NBPG;
                    149:
                    150:        /*
                    151:         * Set up dispatch vectors for DW780.
                    152:         */
                    153:        for (i = 0; i < 4; i++)
                    154:                scb_vecalloc(256 + i * 64 + sa->nexnum * 4, uba_dw780int,
                    155:                    sc->uv_sc.uh_dev.dv_unit, SCB_ISTACK);
                    156:        /*
                    157:         * Fill in variables used by the sgmap system.
                    158:         */
                    159:        sc->uv_size = UBASIZE;          /* Size in bytes of Qbus space */
                    160:        sc->uv_addr = (paddr_t)sc->uv_uba->uba_map;
                    161:
                    162:        uba_dma_init(sc);
                    163:        uba_attach(&sc->uv_sc, (parent->dv_unit ? UMEMB8600(ubaddr) :
                    164:            UMEMA8600(ubaddr)) + (UBAPAGES * VAX_NBPG));
                    165: }
                    166:
                    167: void
                    168: dw780_beforescan(sc)
                    169:        struct uba_softc *sc;
                    170: {
                    171:        struct uba_vsoftc *vc = (void *)sc;
                    172:        volatile int *hej = &vc->uv_uba->uba_sr;
                    173:
                    174:        *hej = *hej;
                    175:        vc->uv_uba->uba_cr = UBACR_IFS|UBACR_BRIE;
                    176: }
                    177:
                    178: void
                    179: dw780_afterscan(sc)
                    180:        struct uba_softc *sc;
                    181: {
                    182:        struct uba_vsoftc *vc = (void *)sc;
                    183:
                    184:        vc->uv_uba->uba_cr = UBACR_IFS | UBACR_BRIE |
                    185:            UBACR_USEFIE | UBACR_SUEFIE |
                    186:            (vc->uv_uba->uba_cr & 0x7c000000);
                    187: }
                    188:
                    189:
                    190: int
                    191: dw780_errchk(sc)
                    192:        struct uba_softc *sc;
                    193: {
                    194:        struct uba_vsoftc *vc = (void *)sc;
                    195:        volatile int *hej = &vc->uv_uba->uba_sr;
                    196:
                    197:        if (*hej) {
                    198:                *hej = *hej;
                    199:                return 1;
                    200:        }
                    201:        return 0;
                    202: }
                    203:
                    204: void
                    205: uba_dw780int(uba)
                    206:        int     uba;
                    207: {
                    208:        int     br, vec, arg;
                    209:        struct  uba_vsoftc *vc = uba_cd.cd_devs[uba];
                    210:        struct  uba_regs *ur = vc->uv_uba;
                    211:        void    (*func)(int);
                    212:
                    213:        br = mfpr(PR_IPL);
                    214:        vec = ur->uba_brrvr[br - 0x14];
                    215:        if (vec <= 0) {
                    216:                ubaerror(&vc->uv_sc, &br, (int *)&vec);
                    217:                if (svec == 0)
                    218:                        return;
                    219:        }
                    220:        if (cold)
                    221:                scb_fake(vec + vc->uh_ibase, br);
                    222:        else {
                    223:                struct ivec_dsp *scb_vec = (struct ivec_dsp *)((int)scb + 512);
                    224:                func = scb_vec[vec/4].hoppaddr;
                    225:                arg = scb_vec[vec/4].pushlarg;
                    226:                (*func)(arg);
                    227:        }
                    228: }
                    229:
                    230: void
                    231: dw780_init(sc)
                    232:        struct uba_softc *sc;
                    233: {
                    234:        struct uba_vsoftc *vc = (void *)sc;
                    235:
                    236:        vc->uv_uba->uba_cr = UBACR_ADINIT;
                    237:        vc->uv_uba->uba_cr = UBACR_IFS|UBACR_BRIE|UBACR_USEFIE|UBACR_SUEFIE;
                    238:        while ((vc->uv_uba->uba_cnfgr & UBACNFGR_UBIC) == 0)
                    239:                ;
                    240: }
                    241:
                    242: #ifdef notyet
                    243: void
                    244: dw780_purge(sc, bdp)
                    245:        struct uba_softc *sc;
                    246:        int bdp;
                    247: {
                    248:        struct uba_vsoftc *vc = (void *)sc;
                    249:
                    250:        vc->uv_uba->uba_dpr[bdp] |= UBADPR_BNE;
                    251: }
                    252: #endif
                    253:
                    254: int    ubawedgecnt = 10;
                    255: int    ubacrazy = 500;
                    256: int    zvcnt_max = 5000;       /* in 8 sec */
                    257: int    ubaerrcnt;
                    258: /*
                    259:  * This routine is called by the locore code to process a UBA
                    260:  * error on an 11/780 or 8600. The arguments are passed
                    261:  * on the stack, and value-result (through some trickery).
                    262:  * In particular, the uvec argument is used for further
                    263:  * uba processing so the result aspect of it is very important.
                    264:  * It must not be declared register.
                    265:  */
                    266: /*ARGSUSED*/
                    267: void
                    268: ubaerror(uh, ipl, uvec)
                    269:        register struct uba_softc *uh;
                    270:        int *ipl, *uvec;
                    271: {
                    272:        struct uba_vsoftc *vc = (void *)uh;
                    273:        struct  uba_regs *uba = vc->uv_uba;
                    274:        register int sr, s;
                    275:
                    276:        if (*uvec == 0) {
                    277:                /*
                    278:                 * Declare dt as unsigned so that negative values
                    279:                 * are handled as >8 below, in case time was set back.
                    280:                 */
                    281:                u_long  dt = time.tv_sec - vc->uh_zvtime;
                    282:
                    283:                vc->uh_zvtotal++;
                    284:                if (dt > 8) {
                    285:                        vc->uh_zvtime = time.tv_sec;
                    286:                        vc->uh_zvcnt = 0;
                    287:                }
                    288:                if (++vc->uh_zvcnt > zvcnt_max) {
                    289:                        printf("%s: too many zero vectors (%d in <%d sec)\n",
                    290:                                vc->uv_sc.uh_dev.dv_xname, vc->uh_zvcnt, (int)dt + 1);
                    291:                        printf("\tIPL 0x%x\n\tcnfgr: %b  Adapter Code: 0x%x\n",
                    292:                                *ipl, uba->uba_cnfgr&(~0xff), UBACNFGR_BITS,
                    293:                                uba->uba_cnfgr&0xff);
                    294:                        printf("\tsr: %b\n\tdcr: %x (MIC %sOK)\n",
                    295:                                uba->uba_sr, ubasr_bits, uba->uba_dcr,
                    296:                                (uba->uba_dcr&0x8000000)?"":"NOT ");
                    297:                        ubareset(vc->uv_sc.uh_dev.dv_unit);
                    298:                }
                    299:                return;
                    300:        }
                    301:        if (uba->uba_cnfgr & NEX_CFGFLT) {
                    302:                printf("%s: sbi fault sr=%b cnfgr=%b\n",
                    303:                    vc->uv_sc.uh_dev.dv_xname, uba->uba_sr, ubasr_bits,
                    304:                    uba->uba_cnfgr, NEXFLT_BITS);
                    305:                ubareset(vc->uv_sc.uh_dev.dv_unit);
                    306:                *uvec = 0;
                    307:                return;
                    308:        }
                    309:        sr = uba->uba_sr;
                    310:        s = spluba();
                    311:        printf("%s: uba error sr=%b fmer=%x fubar=%o\n", vc->uv_sc.uh_dev.dv_xname,
                    312:            uba->uba_sr, ubasr_bits, uba->uba_fmer, 4*uba->uba_fubar);
                    313:        splx(s);
                    314:        uba->uba_sr = sr;
                    315:        *uvec &= UBABRRVR_DIV;
                    316:        if (++ubaerrcnt % ubawedgecnt == 0) {
                    317:                if (ubaerrcnt > ubacrazy)
                    318:                        panic("uba crazy");
                    319:                printf("ERROR LIMIT ");
                    320:                ubareset(vc->uv_sc.uh_dev.dv_unit);
                    321:                *uvec = 0;
                    322:        }
                    323: }

CVSweb