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