Annotation of researchv10no/sys/md/ubastar.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * unibus adapter routines for DW780
        !             3:  */
        !             4: 
        !             5: #include "sys/param.h"
        !             6: #include "sys/ubaddr.h"
        !             7: #include "sys/nexus.h"
        !             8: #include "sys/nxaddr.h"
        !             9: #include "sys/map.h"
        !            10: #include "sys/uba.h"
        !            11: #include "sys/pte.h"
        !            12: #include "sys/vmparam.h"
        !            13: 
        !            14: extern struct uba uba[];
        !            15: extern long ubavoff[];
        !            16: extern long *ubavreg[];
        !            17: extern long ubazvec[];
        !            18: extern struct nxaddr ubaaddr[];
        !            19: extern int ubacnt;
        !            20: 
        !            21: /*
        !            22:  * 0x2000 bytes of nexus space, followed by the address window
        !            23:  */
        !            24: 
        !            25: #define        NMAP    496
        !            26: #define        NBDP    15
        !            27: 
        !            28: struct ubadev {
        !            29:        long cnfgr;             /* configuration register */
        !            30:        long uacr;              /* adapter control */
        !            31:        long uasr;              /* adapter status */
        !            32:        long dcr;               /* diag stuff */
        !            33:        long fmer;              /* failed map entry */
        !            34:        long fubar;             /* failed unibus addr */
        !            35:        long junk0[2];
        !            36:        long bufsel[4];
        !            37:        long brrvr[4];          /* vectors for each BR */
        !            38:        long dpr[16];           /* data path registers */
        !            39:        long junk1[0x1e0];
        !            40:        long mreg[512];         /* unibus map registers; last 16 unused */
        !            41:        long junk2[0x400];
        !            42:        char ubspace[NXWSIZE];
        !            43: };
        !            44: 
        !            45: /*
        !            46:  * bits in uacr
        !            47:  */
        !            48: #define        ADINIT  0x1             /* adapter init */
        !            49: #define        CNFIE   0x4             /* config IE */
        !            50: #define        SUEFIE  0x8             /* SBI to UNIBUS error IE */
        !            51: #define        USEFIE  0x10            /* UNIBUS to SBI error IE */
        !            52: #define        BRIE    0x20            /* BR interrupt enable */
        !            53: #define        IFS     0x40            /* pass UNIBUS interrupts to SBI */
        !            54: 
        !            55: #define        UBAIE   (IFS|BRIE|USEFIE|SUEFIE|CNFIE)
        !            56: 
        !            57: /*
        !            58:  * bits in cnfgr
        !            59:  */
        !            60: #define        PARFLT  0x80000000      /* SBI Parity Fault */
        !            61: #define        WSQFLT  0x40000000      /* SBI Write Sequence Fault */
        !            62: #define        URDFLT  0x20000000      /* SBI Unexpected Read Fault */
        !            63: #define        ISQFLT  0x10000000      /* SBI Interlock Sequence Fault */
        !            64: #define        MXTFLT  0x8000000       /* SBI Multiple Transmitter Fault */
        !            65: #define        XMTFLT  0x4000000       /* UBA is transmit faulter */
        !            66: #define        UBIC    0x10000         /* init complete */
        !            67: 
        !            68: #define        CFGFLT  (PARFLT|WSQFLT|URDFLT|ISQFLT|MXTFLT|XMTFLT)
        !            69: 
        !            70: /*
        !            71:  * bits in uasr
        !            72:  */
        !            73: #define        DPPE    0x20            /* Data Path Parity Error */
        !            74: #define        IVMR    0x10            /* Invalid Map Register */
        !            75: #define        MRPF    0x8             /* Map Register Parity Failure */
        !            76: #define        UBSSYNTO 0x1            /* unibus SSYN timeout */
        !            77: 
        !            78: #define        BADMAP  (MRPF|IVMR|DPPE)        /* bits indicating mapping reg problem */
        !            79: 
        !            80: /*
        !            81:  * bits in the data path register
        !            82:  */
        !            83: 
        !            84: #define        BNE     0x80000000      /* purge datapath */
        !            85: #define        BTE     0x40000000      /* bdp transfer error */
        !            86: 
        !            87: /*
        !            88:  * bits in map register
        !            89:  */
        !            90: 
        !            91: #define        MPAGE   0x7ffff         /* physical page number */
        !            92: #define        BO      0x2000000       /* offset address by one */
        !            93: #define        MRV     0x80000000      /* map register valid */
        !            94: #define        PSHIFT  21              /* shift data path number this much */
        !            95: 
        !            96: #define        INITTIME 50000          /* time to stall waiting for UNIBUS init */
        !            97:                                /* 25ms nominal; 50000 for VAX-11/785 */
        !            98: 
        !            99: /*
        !           100:  * return the register address for a unibus device
        !           101:  */
        !           102: 
        !           103: caddr_t
        !           104: ubaddr(up)
        !           105: register struct ubaddr *up;
        !           106: {
        !           107:        register struct uba *ub;
        !           108: 
        !           109:        if (up->ubno < 0 || up->ubno > ubacnt) {
        !           110:                printf("bad ubano %d\n", up->ubno);
        !           111:                return (0);
        !           112:        }
        !           113:        ub = &uba[up->ubno];
        !           114:        if ((ub->flags & UBINIT) == 0)
        !           115:                if (ubstart(up->ubno) == 0)
        !           116:                        return (0);
        !           117:        return ((caddr_t)&ub->addr->ubspace[up->uboff]);
        !           118: }
        !           119: 
        !           120: /*
        !           121:  * init the unibus adapter
        !           122:  */
        !           123: 
        !           124: ubstart(u)
        !           125: int u;
        !           126: {
        !           127:        register struct uba *ub;
        !           128: 
        !           129:        ub = &uba[u];
        !           130:        if ((ub->addr = (struct ubadev *)nxaddr(&ubaaddr[u])) == 0)
        !           131:                return (0);
        !           132:        if (badaddr(&ub->addr->cnfgr, sizeof(long))) {
        !           133:                printf("ub%d not responding\n", u);
        !           134:                return (0);
        !           135:        }
        !           136:        rminit(ub->map, UBNMAP, NMAP-1, 1);     /* NMAP-1 because can't alloc 0 */
        !           137:        ub->path = ((1<<NBDP)-1)<<1;
        !           138:        if (ubmstart(u) == 0)
        !           139:                return (0);
        !           140:        ubinit(u);
        !           141:        ub->flags |= UBINIT;
        !           142:        return (1);
        !           143: }
        !           144: 
        !           145: /*
        !           146:  * init the unibus adapter hardware
        !           147:  */
        !           148: 
        !           149: ubinit(u)
        !           150: int u;
        !           151: {
        !           152:        register struct uba *ub;
        !           153:        register struct ubadev *up;
        !           154:        register int i;
        !           155:        register long *p;
        !           156: 
        !           157:        ub = &uba[u];
        !           158:        up = ub->addr;
        !           159:        up->uacr = ADINIT;
        !           160:        for (i = 0; i < INITTIME; i++)
        !           161:                if (up->cnfgr & UBIC)
        !           162:                        break;
        !           163:        if ((up->cnfgr & UBIC) == 0) {
        !           164:                printf("ub%d not ready\n", u);
        !           165:                return (0);
        !           166:        }
        !           167:        ubavoff[u] = ubaaddr[u].voff;
        !           168:        ubavreg[u] = &up->brrvr[0];
        !           169:        up->cnfgr = up->cnfgr;          /* clear power-up latches */
        !           170:        up->uacr = UBAIE;
        !           171:        for (i = 0, p = ub->addr->mreg; i < NMAP; i++)
        !           172:                *p++ = 0;
        !           173:        ubminit(u);
        !           174:        return (1);
        !           175: }
        !           176: 
        !           177: /*
        !           178:  * determine whether a particular address,
        !           179:  * which happens to be in UNIBUS space,
        !           180:  * exists
        !           181:  */
        !           182: ubbadaddr(u, a, s)
        !           183: int u, s;
        !           184: caddr_t a;
        !           185: {
        !           186:        register int p;
        !           187:        register struct ubadev *up;
        !           188: 
        !           189:        if (u < 0 || u >= ubacnt)
        !           190:                return (1);
        !           191:        up = uba[u].addr;
        !           192:        p = spl7();
        !           193:        /* perhaps disable SBI-to-UNIBUS interrupts? */
        !           194:        up->uasr = up->uasr;    /* clear errors */
        !           195:        s = badaddr(a, s);
        !           196:        if (up->uasr & UBSSYNTO)        /* or perhaps any error? */
        !           197:                s = 1;
        !           198:        up->uasr = up->uasr;    /* clear errors again */
        !           199:        splx(p);
        !           200:        return (s);
        !           201: }
        !           202: 
        !           203: /*
        !           204:  * get/put a single byte to a particular unibus address
        !           205:  * intended for use by ECC code
        !           206:  * work it out from first principles,
        !           207:  * because UNIBUS adapter may loop and hang otherwise
        !           208:  */
        !           209: 
        !           210: static long
        !           211: ubphys(ubno, addr)
        !           212: unsigned int ubno;
        !           213: uaddr_t addr;
        !           214: {
        !           215:        register struct uba *ub;
        !           216:        register int pg;
        !           217:        register long m;
        !           218: 
        !           219:        if (ubno >= ubacnt)
        !           220:                panic("ubphys");
        !           221:        ub = &uba[ubno];
        !           222:        if (ub->addr == NULL)
        !           223:                panic("ubphys");
        !           224:        pg = addr / NBPG;
        !           225:        if (pg >= NMAP)
        !           226:                return (-1);    /* addr too big */
        !           227:        m = ub->addr->mreg[pg];
        !           228:        if ((m & MRV) == 0)
        !           229:                return (-1);    /* invalid */
        !           230:        return ((m & MPAGE) * NBPG + addr % NBPG);
        !           231: }
        !           232: 
        !           233: int
        !           234: ubgetc(ubno, addr)
        !           235: unsigned int ubno;
        !           236: uaddr_t addr;
        !           237: {
        !           238:        register long phys;
        !           239: 
        !           240:        phys = ubphys(ubno, addr);
        !           241:        if (phys < 0)
        !           242:                return (-1);
        !           243:        return (phgetc(phys));
        !           244: }
        !           245: 
        !           246: int
        !           247: ubputc(ubno, addr, c)
        !           248: unsigned int ubno;
        !           249: uaddr_t addr;
        !           250: char c;
        !           251: {
        !           252:        register long phys;
        !           253: 
        !           254:        phys = ubphys(ubno, addr);
        !           255:        if (phys < 0)
        !           256:                return (-1);
        !           257:        return (phputc(phys, c));
        !           258: }
        !           259: 
        !           260: /*
        !           261:  * unibus adapter interrupts
        !           262:  * here only on non-device interrupts:
        !           263:  * passive release, or adapter has something to say
        !           264:  *
        !           265:  * -- assertion:
        !           266:  * to get here, we must read the BRRVR,
        !           267:  * which means ubavreg is set up,
        !           268:  * which means uba.addr is set up
        !           269:  */
        !           270: 
        !           271: uba0int(u, vec)
        !           272: int u;
        !           273: {
        !           274:        register struct ubadev *up;
        !           275:        long cnfgr, uasr, fubar, fmer;
        !           276: 
        !           277:        if (vec == 0) {                 /* passive release */
        !           278:                ubazvec[u]++;
        !           279:                return;
        !           280:        }
        !           281:        up = uba[u].addr;
        !           282:        cnfgr = up->cnfgr;
        !           283:        uasr = up->uasr;
        !           284:        fubar = up->fubar<<2;
        !           285:        fmer = up->fmer;
        !           286:        up->uasr = uasr;
        !           287:        up->cnfgr = cnfgr;
        !           288:        if (cnfgr & CFGFLT) {   /* does this really happen? */
        !           289:                printf("ub%d: SBI fault cnfgr%x sr%x\n", u, cnfgr, uasr);
        !           290:                return;
        !           291:        }
        !           292:        printf("ub%d: cfg%x sr%x fubar %o\n", u, cnfgr, uasr, fubar);
        !           293:        if (uasr & BADMAP)
        !           294:                printf("fmer %x\n", fmer);
        !           295: }
        !           296: 
        !           297: /*
        !           298:  * allocate a buffered data path
        !           299:  * return the ddp if none available
        !           300:  */
        !           301: int ubnopath;
        !           302: 
        !           303: int
        !           304: ubmapath(u)
        !           305: int u;
        !           306: {
        !           307:        register struct uba *ub;
        !           308:        register int path;
        !           309:        register int s;
        !           310: 
        !           311:        ub = &uba[u];
        !           312:        s = spl6();
        !           313:        for (path = NBDP; path > 0; path--)
        !           314:                if (ub->path & (1<<path)) {
        !           315:                        ub->path &=~ (1<<path);
        !           316:                        break;
        !           317:                }
        !           318:        splx(s);
        !           319:        if (path == 0)
        !           320:                ubnopath++;
        !           321:        return (path);
        !           322: }
        !           323: 
        !           324: ubmflush(u, path)
        !           325: int u;
        !           326: int path;
        !           327: {
        !           328:        register long *reg;
        !           329: 
        !           330:        if (path == 0)
        !           331:                return;
        !           332:        reg = &uba[u].addr->dpr[path];
        !           333:        *reg |= BNE;
        !           334:        DELAY(2);
        !           335:        if (*reg & BTE) {
        !           336:                printf("ub%d bdp%d err %x\n", u, path, *reg);
        !           337:                *reg = *reg;
        !           338:        }
        !           339: }
        !           340: 
        !           341: /*
        !           342:  * fill in a piece of unibus map
        !           343:  * return the address of the base
        !           344:  */
        !           345: 
        !           346: uaddr_t
        !           347: ubmsetmap(u, p, nreg, um)
        !           348: int u;
        !           349: register struct pte *p;
        !           350: register int nreg;
        !           351: ubm_t um;
        !           352: {
        !           353:        register long *m;
        !           354:        register long x;
        !           355: 
        !           356:        m = &uba[u].addr->mreg[ubmfirst(um)];
        !           357:        x = (ubmpath(um)<<PSHIFT)|MRV;
        !           358:        if (nreg > ubmsize(um)-1)
        !           359:                panic("ubmsetmap");
        !           360:        while (--nreg >= 0)
        !           361:                *m++ = p++->pg_pfnum | x;
        !           362:        *m = 0;
        !           363:        return (ctob(ubmfirst(um)));
        !           364: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.