Annotation of researchv10no/sys/md/ubastar.c, revision 1.1.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.