Annotation of researchv8dc/sys/dev/autoconf.c, revision 1.1.1.1

1.1       root        1: /*     autoconf.c      1.3     81/10/07        */
                      2: /*     autoconf.c      4.31    81/07/05        */
                      3: 
                      4: /*
                      5:  * Setup the system to run on the current machine.
                      6:  *
                      7:  * Configure() is called at boot time and initializes the uba and mba
                      8:  * device tables and the memory controller monitoring.  Available
                      9:  * devices are determined (from possibilities mentioned in ioconf.c),
                     10:  * and the drivers are initialized.
                     11:  *
                     12:  * N.B.: A lot of the conditionals based on processor type say
                     13:  *     #if VAX780
                     14:  * and
                     15:  *     #if VAX750
                     16:  * which may be incorrect after more processors are introduced if they
                     17:  * are like either of these machines.
                     18:  *
                     19:  * TODO:
                     20:  *     use pcpu info about whether a ubasr exists
                     21:  */
                     22: 
                     23: #include "mba.h"
                     24: 
                     25: #include "../h/param.h"
                     26: #include "../h/systm.h"
                     27: #include "../h/map.h"
                     28: #include "../h/nexus.h"
                     29: #include "../h/pte.h"
                     30: #include "../h/buf.h"
                     31: #include "../h/mbareg.h"
                     32: #include "../h/mbavar.h"
                     33: #include "../h/dk.h"
                     34: #include "../h/vm.h"
                     35: #include "../h/ubareg.h"
                     36: #include "../h/ubavar.h"
                     37: #include "../h/mtpr.h"
                     38: #include "../h/cpu.h"
                     39: #include "../h/scb.h"
                     40: #include "../h/mem.h"
                     41: 
                     42: /*
                     43:  * The following several variables are related to
                     44:  * the configuration process, and are used in initializing
                     45:  * the machine.
                     46:  */
                     47: int    cold;           /* if 1, still working on cold-start */
                     48: int    nexnum;         /* current nexus number */
                     49: int    dkn;            /* number of iostat dk numbers assigned so far */
                     50: 
                     51: /*
                     52:  * Addresses of the (locore) routines which bootstrap us from
                     53:  * hardware traps to C code.  Filled into the system control block
                     54:  * as necessary.
                     55:  */
                     56: #if NMBA > 0
                     57: int    (*mbaintv[4])() =       { Xmba0int, Xmba1int, Xmba2int, Xmba3int };
                     58: #endif
                     59: #if VAX780
                     60: int    (*ubaintv[4])() =       { Xua0int, Xua1int, Xua2int, Xua3int };
                     61: #endif
                     62: 
                     63: /*
                     64:  * This allocates the space for the per-uba information,
                     65:  * such as buffered data path usage.
                     66:  */
                     67: struct uba_hd uba_hd[MAXNUBA];
                     68: 
                     69: /*
                     70:  * Determine mass storage and memory configuration for a machine.
                     71:  * Get cpu type, and then switch out to machine specific procedures
                     72:  * which will probe adaptors to see what is out there.
                     73:  */
                     74: configure()
                     75: {
                     76:        union cpusid cpusid;
                     77:        register struct percpu *ocp;
                     78:        register int *ip;
                     79:        extern char Sysbase[];
                     80: 
                     81:        cpusid.cpusid = mfpr(SID);
                     82:        for (ocp = percpu; ocp->pc_cputype; ocp++)
                     83:                if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
                     84:                        probenexus(ocp);
                     85:                        /*
                     86:                         * Write protect the scb.  It is strange
                     87:                         * that this code is here, but this is as soon
                     88:                         * as we are done mucking with it, and the
                     89:                         * write-enable was done in assembly language
                     90:                         * to which we will never return.
                     91:                         */
                     92:                        ip = (int *)Sysmap; *ip &= ~PG_PROT; *ip |= PG_KR;
                     93:                        mtpr(TBIS, Sysbase);
                     94: #if GENERIC
                     95:                        setconf();
                     96: #endif
                     97:                        cold = 0;
                     98:                        memenable();
                     99:                        return;
                    100:                }
                    101:        printf("cpu type %d not configured\n", cpusid.cpuany.cp_type);
                    102:        asm("halt");
                    103: }
                    104: 
                    105: /*
                    106:  * Probe nexus space, finding the interconnects
                    107:  * and setting up and probing mba's and uba's for devices.
                    108:  */
                    109: /*ARGSUSED*/
                    110: probenexus(pcpu)
                    111:        register struct percpu *pcpu;
                    112: {
                    113:        register struct nexus *nxv;
                    114:        struct nexus *nxp = pcpu->pc_nexbase;
                    115:        union nexcsr nexcsr;
                    116:        int i;
                    117:        
                    118:        nexnum = 0, nxv = nexus;
                    119:        for (; nexnum < pcpu->pc_nnexus; nexnum++, nxp++, nxv++) {
                    120:                nxaccess(nxp, Nexmap[nexnum]);
                    121:                if (badaddr((caddr_t)nxv, 4))
                    122:                        continue;
                    123:                if (pcpu->pc_nextype && pcpu->pc_nextype[nexnum] != NEX_ANY)
                    124:                        nexcsr.nex_csr = pcpu->pc_nextype[nexnum];
                    125:                else
                    126:                        nexcsr = nxv->nexcsr;
                    127:                if (nexcsr.nex_csr&NEX_APD)
                    128:                        continue;
                    129:                switch (nexcsr.nex_type) {
                    130: 
                    131:                case NEX_MBA:
                    132:                        printf("mba%d at tr%d\n", nummba, nexnum);
                    133:                        if (nummba >= NMBA) {
                    134:                                printf("%d mba's", nummba);
                    135:                                goto unconfig;
                    136:                        }
                    137: #if NMBA > 0
                    138:                        mbafind(nxv, nxp);
                    139:                        nummba++;
                    140: #endif
                    141:                        break;
                    142: 
                    143:                case NEX_UBA0:
                    144:                case NEX_UBA1:
                    145:                case NEX_UBA2:
                    146:                case NEX_UBA3:
                    147:                        printf("uba%d at tr%d\n", numuba, nexnum);
                    148: #if VAX750             /* temp until this is fixed right */
                    149:                        if (numuba > 0) {
                    150: #else
                    151:                        if (numuba >= 4) {
                    152: #endif
                    153:                                printf("%d uba's", numuba);
                    154:                                goto unsupp;
                    155:                        }
                    156: #if VAX780
                    157:                        if (cpu == VAX_780)
                    158:                                setscbnex(ubaintv[numuba]);
                    159: #endif
                    160:                        i = nexcsr.nex_type - NEX_UBA0;
                    161:                        unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp,
                    162:                            umem[i], pcpu->pc_umaddr[i], UMEMmap[i]);
                    163: #if VAX780
                    164:                        if (cpu == VAX_780)
                    165:                                ((struct uba_regs *)nxv)->uba_cr =
                    166:                                    UBACR_IFS|UBACR_BRIE|
                    167:                                    UBACR_USEFIE|UBACR_SUEFIE;
                    168: #endif
                    169:                        numuba++;
                    170:                        break;
                    171: 
                    172:                case NEX_DR32:
                    173:                /* there can be more than one... are there other codes??? */
                    174:                        printf("dr32");
                    175:                        goto unsupp;
                    176: 
                    177:                case NEX_MEM4:
                    178:                case NEX_MEM4I:
                    179:                case NEX_MEM16:
                    180:                case NEX_MEM16I:
                    181:                        printf("mcr%d at tr%d\n", nmcr, nexnum);
                    182:                        if (nmcr >= 4) {
                    183:                                printf("5 mcr's");
                    184:                                goto unsupp;
                    185:                        }
                    186:                        mcraddr[nmcr++] = (struct mcr *)nxv;
                    187:                        break;
                    188: 
                    189:                case NEX_MPM0:
                    190:                case NEX_MPM1:
                    191:                case NEX_MPM2:
                    192:                case NEX_MPM3:
                    193:                        printf("mpm");
                    194:                        goto unsupp;
                    195: 
                    196:                default:
                    197:                        printf("nexus type %x", nexcsr.nex_type);
                    198: unsupp:
                    199:                        printf(" unsupported (at tr %d)\n", nexnum);
                    200:                        continue;
                    201: unconfig:
                    202:                        printf(" not configured\n");
                    203:                        continue;
                    204:                }
                    205:        }
                    206: #if VAX780
                    207:        if (cpu == VAX_780)
                    208:                { int ubawatch(); timeout(ubawatch, (caddr_t)0, hz); }
                    209: #endif
                    210: }
                    211: 
                    212: #if NMBA > 0
                    213: struct mba_device *mbaconfig();
                    214: /*
                    215:  * Find devices attached to a particular mba
                    216:  * and look for each device found in the massbus
                    217:  * initialization tables.
                    218:  */
                    219: mbafind(nxv, nxp)
                    220:        struct nexus *nxv, *nxp;
                    221: {
                    222:        register struct mba_regs *mdp;
                    223:        register struct mba_drv *mbd;
                    224:        register struct mba_device *mi;
                    225:        register struct mba_slave *ms;
                    226:        int dn, dt;
                    227:        struct mba_device fnd;
                    228: 
                    229:        mdp = (struct mba_regs *)nxv;
                    230:        mba_hd[nummba].mh_mba = mdp;
                    231:        mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
                    232:        setscbnex(mbaintv[nummba]);
                    233:        fnd.mi_mba = mdp;
                    234:        fnd.mi_mbanum = nummba;
                    235:        for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
                    236:                dt = mbd->mbd_dt & 0xffff;
                    237:                if (dt == 0)
                    238:                        continue;
                    239:                if (dt == MBDT_MOH)
                    240:                        continue;
                    241:                fnd.mi_drive = dn;
                    242:                if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP)) {
                    243:                        for (ms = mbsinit; ms->ms_driver; ms++)
                    244:                        if (ms->ms_driver == mi->mi_driver && ms->ms_alive == 0 && 
                    245:                            (ms->ms_ctlr == mi->mi_unit || ms->ms_ctlr=='?')) {
                    246:                                if ((*ms->ms_driver->md_slave)(mi, ms)) {
                    247:                                        printf("%s%d at %s%d slave %d\n",
                    248:                                            ms->ms_driver->md_sname,
                    249:                                            ms->ms_unit,
                    250:                                            mi->mi_driver->md_dname,
                    251:                                            mi->mi_unit,
                    252:                                            ms->ms_slave);
                    253:                                        ms->ms_alive = 1;
                    254:                                        ms->ms_ctlr = mi->mi_unit;
                    255:                                }
                    256:                        }
                    257:                }
                    258:        }
                    259:        mdp->mba_cr = MBCR_INIT;
                    260:        mdp->mba_cr = MBCR_IE;
                    261: }
                    262: 
                    263: /*
                    264:  * Have found a massbus device;
                    265:  * see if it is in the configuration table.
                    266:  * If so, fill in its data.
                    267:  */
                    268: struct mba_device *
                    269: mbaconfig(ni, type)
                    270:        register struct mba_device *ni;
                    271:        register int type;
                    272: {
                    273:        register struct mba_device *mi;
                    274:        register short *tp;
                    275:        register struct mba_hd *mh;
                    276: 
                    277:        for (mi = mbdinit; mi->mi_driver; mi++) {
                    278:                if (mi->mi_alive)
                    279:                        continue;
                    280:                tp = mi->mi_driver->md_type;
                    281:                for (mi->mi_type = 0; *tp; tp++, mi->mi_type++)
                    282:                        if (*tp == (type&MBDT_TYPE))
                    283:                                goto found;
                    284:                continue;
                    285: found:
                    286: #define        match(fld)      (ni->fld == mi->fld || mi->fld == '?')
                    287:                if (!match(mi_drive) || !match(mi_mbanum))
                    288:                        continue;
                    289:                printf("%s%d at mba%d drive %d",
                    290:                    mi->mi_driver->md_dname, mi->mi_unit,
                    291:                    ni->mi_mbanum, ni->mi_drive);
                    292:                printf("\n");
                    293:                mi->mi_alive = 1;
                    294:                mh = &mba_hd[ni->mi_mbanum];
                    295:                mi->mi_hd = mh;
                    296:                mh->mh_mbip[ni->mi_drive] = mi;
                    297:                mh->mh_ndrive++;
                    298:                mi->mi_mba = ni->mi_mba;
                    299:                mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive];
                    300:                mi->mi_driver->md_info[mi->mi_unit] = mi;
                    301:                mi->mi_mbanum = ni->mi_mbanum;
                    302:                mi->mi_drive = ni->mi_drive;
                    303:                if (mi->mi_dk && dkn < DK_NDRIVE)
                    304:                        mi->mi_dk = dkn++;
                    305:                else
                    306:                        mi->mi_dk = -1;
                    307:                (*mi->mi_driver->md_attach)(mi);
                    308:                return (mi);
                    309:        }
                    310:        return (0);
                    311: }
                    312: #endif
                    313: 
                    314: /*
                    315:  * Fixctlrmask fixes the masks of the driver ctlr routines
                    316:  * which otherwise save r10 and r11 where the interrupt and br
                    317:  * level are passed through.
                    318:  */
                    319: fixctlrmask()
                    320: {
                    321:        register struct uba_ctlr *um;
                    322:        register struct uba_device *ui;
                    323:        register struct uba_driver *ud;
                    324: #define        phys(a,b) ((b)(((int)(a))&0x7fffffff))
                    325: 
                    326:        for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++)
                    327:                *phys(ud->ud_probe, short *) &= ~0xc00;
                    328:        for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++)
                    329:                *phys(ud->ud_probe, short *) &= ~0xc00;
                    330: }
                    331: 
                    332: /*
                    333:  * Find devices on a UNIBUS.
                    334:  * Uses per-driver routine to set <br,cvec> into <r11,r10>,
                    335:  * and then fills in the tables, with help from a per-driver
                    336:  * slave initialization routine.
                    337:  */
                    338: unifind(vubp, pubp, vumem, pumem, memmap)
                    339:        struct uba_regs *vubp, *pubp;
                    340:        caddr_t vumem, pumem;
                    341:        struct pte *memmap;
                    342: {
                    343: #ifndef lint
                    344:        register int br, cvec;                  /* MUST BE r11, r10 */
                    345: #else
                    346:        /*
                    347:         * Lint doesn't realize that these
                    348:         * can be initialized asynchronously
                    349:         * when devices interrupt.
                    350:         */
                    351:        register int br = 0, cvec = 0;
                    352: #endif
                    353:        register struct uba_device *ui;
                    354:        register struct uba_ctlr *um;
                    355:        u_short *reg, addr;
                    356:        struct uba_hd *uhp;
                    357:        struct uba_driver *udp;
                    358:        int i, (**ivec)(), haveubasr = 0;
                    359: 
                    360:        /*
                    361:         * Initialize the UNIBUS, by freeing the map
                    362:         * registers and the buffered data path registers
                    363:         */
                    364:        uhp = &uba_hd[numuba];
                    365:        uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map));
                    366: #ifdef ETHERNET
                    367:        rminit(uhp->uh_map, NUBMREG-64, 1, "uba", UAMSIZ);
                    368: #endif ETHERNET
                    369:        rminit(uhp->uh_map, NUBMREG, 1, "uba", UAMSIZ);
                    370:        switch (cpu) {
                    371: #if VAX780
                    372:        case VAX_780:
                    373:                uhp->uh_bdpfree = (1<<NBDP780) - 1;
                    374:                haveubasr = 1;
                    375:                break;
                    376: #endif
                    377: #if VAX750
                    378:        case VAX_750:
                    379:                uhp->uh_bdpfree = (1<<NBDP750) - 1;
                    380:                break;
                    381: #endif
                    382: #if VAX7ZZ
                    383:        case VAX_7ZZ:
                    384:                break;
                    385: #endif
                    386:        }
                    387: 
                    388:        /*
                    389:         * Save virtual and physical addresses
                    390:         * of adaptor, and allocate and initialize
                    391:         * the UNIBUS interrupt vector.
                    392:         */
                    393:        uhp->uh_uba = vubp;
                    394:        uhp->uh_physuba = pubp;
                    395: /* HAVE TO DO SOMETHING SPECIAL FOR SECOND UNIBUS ON COMETS HERE */
                    396:        if (numuba == 0)
                    397:                uhp->uh_vec = UNIvec;
                    398:        else
                    399:                uhp->uh_vec = (int(**)())calloc(512);
                    400:        for (i = 0; i < 128; i++)
                    401:                uhp->uh_vec[i] =
                    402:                    scbentry(&catcher[i*2], SCB_ISTACK);
                    403:        /*
                    404:         * Set last free interrupt vector for devices with
                    405:         * programmable interrupt vectors.  Use is to decrement
                    406:         * this number and use result as interrupt vector.
                    407:         */
                    408:        uhp->uh_lastiv = 0x200;
                    409: 
                    410:        /* THIS IS A CHEAT: USING THE FACT THAT UMEM and NEXI ARE SAME SIZE */
                    411:        nxaccess((struct nexus *)pumem, memmap);
                    412: #ifdef ETHERNET
                    413:        if(numuba == 0) {               /*****EC ON UBA0 ONLY!!!*****/
                    414:                extern struct pte ECmap[];
                    415:                ecaccess((struct nexus *)(pumem-(24*1024)), ECmap);
                    416:        }
                    417: #endif ETHERNET
                    418: #if VAX780
                    419:        if (haveubasr) {
                    420:                vubp->uba_sr = vubp->uba_sr;
                    421:                vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
                    422:        }
                    423: #endif
                    424: 
                    425:        /*
                    426:         * Map the first page of UNIBUS i/o
                    427:         * space to the first page of memory
                    428:         * for devices which will need to dma
                    429:         * output to produce an interrupt.
                    430:         */
                    431:        *(int *)(&vubp->uba_map[0]) = UBAMR_MRV;
                    432: 
                    433: #define        ubaddr(off)     (u_short *)((int)vumem + ((off)&0x1fff))
                    434:        /*
                    435:         * Check each unibus mass storage controller.
                    436:         * For each one which is potentially on this uba,
                    437:         * see if it is really there, and if it is record it and
                    438:         * then go looking for slaves.
                    439:         */
                    440:        for (um = ubminit; udp = um->um_driver; um++) {
                    441:                if (um->um_ubanum != numuba && um->um_ubanum != '?')
                    442:                        continue;
                    443:                addr = (u_short)um->um_addr;
                    444:                reg = ubaddr(addr);
                    445:                if (badaddr((caddr_t)reg, 2)) {
                    446:                        printf("uba%d %s%d badaddr\n", numuba, udp->ud_mname,
                    447:                                um->um_ctlr);
                    448:                        continue;
                    449:                }
                    450: #if VAX780
                    451:                if (haveubasr && vubp->uba_sr) {
                    452:                        vubp->uba_sr = vubp->uba_sr;
                    453:                        continue;
                    454:                }
                    455: #endif
                    456:                cvec = 0x200;
                    457:                i = (*udp->ud_probe)(reg, um->um_ctlr);
                    458: #ifdef CHAOS
                    459:                /*
                    460:                ** Since the cold-boot-time stray interrupt catcher in
                    461:                ** locore.s leaves the processor at the priority level
                    462:                ** of the interrupt (yes, even after the rei), we must
                    463:                ** restore it here.
                    464:                */
                    465:                (void) spl0();
                    466: #endif CHAOS
                    467: #if VAX780
                    468:                if (haveubasr && vubp->uba_sr) {
                    469:                        vubp->uba_sr = vubp->uba_sr;
                    470:                        continue;
                    471:                }
                    472: #endif
                    473:                if (i == 0)
                    474:                        continue;
                    475:                printf("%s%d uba%d csr %o ",
                    476:                    udp->ud_mname, um->um_ctlr, numuba, addr);
                    477:                if (cvec == 0) {
                    478:                        printf("zero vector\n");
                    479:                        continue;
                    480:                }
                    481:                if (cvec == 0x200) {
                    482:                        printf("didn't interrupt\n");
                    483:                        continue;
                    484:                }
                    485:                printf("vec 0%o ipl x%x\n", cvec, br);
                    486:                um->um_alive = 1;
                    487:                um->um_ubanum = numuba;
                    488:                um->um_hd = &uba_hd[numuba];
                    489:                um->um_addr = (caddr_t)reg;
                    490:                udp->ud_minfo[um->um_ctlr] = um;
                    491:                for (ivec = um->um_intr; *ivec; ivec++) {
                    492:                        um->um_hd->uh_vec[cvec/4] =
                    493:                            scbentry(*ivec, SCB_ISTACK);
                    494:                        cvec += 4;
                    495:                }
                    496:                for (ui = ubdinit; ui->ui_driver; ui++) {
                    497:                        if (ui->ui_driver != udp || ui->ui_alive ||
                    498:                            ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
                    499:                            ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
                    500:                                continue;
                    501:                        if ((*udp->ud_slave)(ui, reg)) {
                    502:                                ui->ui_alive = 1;
                    503:                                ui->ui_ctlr = um->um_ctlr;
                    504:                                ui->ui_ubanum = numuba;
                    505:                                ui->ui_hd = &uba_hd[numuba];
                    506:                                ui->ui_addr = (caddr_t)reg;
                    507:                                ui->ui_physaddr = pumem + (addr&0x1fff);
                    508:                                if (ui->ui_dk && dkn < DK_NDRIVE)
                    509:                                        ui->ui_dk = dkn++;
                    510:                                else
                    511:                                        ui->ui_dk = -1;
                    512:                                ui->ui_mi = um;
                    513:                                /* ui_type comes from driver */
                    514:                                udp->ud_dinfo[ui->ui_unit] = ui;
                    515:                                printf("%s%d at %s%d sl%d ",
                    516:                                    udp->ud_dname, ui->ui_unit,
                    517:                                    udp->ud_mname, um->um_ctlr, ui->ui_slave);
                    518:                                (*udp->ud_attach)(ui);
                    519:                        }
                    520:                }
                    521:        }
                    522:        /*
                    523:         * Now look for non-mass storage peripherals.
                    524:         */
                    525:        for (ui = ubdinit; udp = ui->ui_driver; ui++) {
                    526:                if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' ||
                    527:                    ui->ui_alive || ui->ui_slave != -1)
                    528:                        continue;
                    529:                addr = (u_short)ui->ui_addr;
                    530:                reg = ubaddr(addr);
                    531:                if (badaddr((caddr_t)reg, 2)) {
                    532:                        printf("%s%d not found at uba%d csr %o\n",
                    533:                            ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
                    534:                        continue;
                    535:                }
                    536: #if VAX780
                    537:                if (haveubasr && vubp->uba_sr) {
                    538:                        vubp->uba_sr = vubp->uba_sr;
                    539:                        continue;
                    540:                }
                    541: #endif
                    542:                cvec = 0x200;
                    543:                i = (*udp->ud_probe)(reg, um->um_ctlr);
                    544: #ifdef CHAOS
                    545:                /*
                    546:                ** Since the cold-boot-time stray interrupt catcher in
                    547:                ** locore.s leaves the processor at the priority level
                    548:                ** of the interrupt (yes, even after the rei), we must
                    549:                ** restore it here.
                    550:                */
                    551:                (void) spl0();
                    552: #endif CHAOS
                    553: #if VAX780
                    554:                if (haveubasr && vubp->uba_sr) {
                    555:                        vubp->uba_sr = vubp->uba_sr;
                    556:                        continue;
                    557:                }
                    558: #endif
                    559:                if (i == 0)
                    560:                        continue;
                    561:                printf("%s%d at uba%d csr %o ",
                    562:                    ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
                    563:                if (cvec == 0) {
                    564:                        printf("zero vector\n");
                    565:                        continue;
                    566:                }
                    567:                if (cvec == 0x200) {
                    568:                        printf("didn't interrupt\n");
                    569:                        continue;
                    570:                }
                    571:                printf("vec 0%o ipl x%x\n", cvec, br);
                    572:                ui->ui_hd = &uba_hd[numuba];
                    573:                for (ivec = ui->ui_intr; *ivec; ivec++) {
                    574:                        ui->ui_hd->uh_vec[cvec/4] =
                    575:                            scbentry(*ivec, SCB_ISTACK);
                    576:                        cvec += 4;
                    577:                }
                    578:                ui->ui_alive = 1;
                    579:                ui->ui_ubanum = numuba;
                    580:                ui->ui_addr = (caddr_t)reg;
                    581:                ui->ui_physaddr = pumem + (addr&0x1fff);
                    582:                ui->ui_dk = -1;
                    583:                /* ui_type comes from driver */
                    584:                udp->ud_dinfo[ui->ui_unit] = ui;
                    585:                (*udp->ud_attach)(ui);
                    586:        }
                    587: }
                    588: 
                    589: setscbnex(fn)
                    590:        int (*fn)();
                    591: {
                    592:        register struct scb *scbp = &scb;
                    593: 
                    594:        scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] =
                    595:            scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] =
                    596:                scbentry(fn, SCB_ISTACK);
                    597: }
                    598: 
                    599: /*
                    600:  * Make a nexus accessible at physical address phys
                    601:  * by mapping kernel ptes starting at pte.
                    602:  *
                    603:  * WE LEAVE ALL NEXI MAPPED; THIS IS PERHAPS UNWISE
                    604:  * SINCE MISSING NEXI DONT RESPOND.  BUT THEN AGAIN
                    605:  * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE.
                    606:  */
                    607: nxaccess(physa, pte)
                    608:        struct nexus *physa;
                    609:        register struct pte *pte;
                    610: {
                    611:        register int i = btop(sizeof (struct nexus));
                    612:        register unsigned v = btop(physa);
                    613:        
                    614:        do
                    615:                *(int *)pte++ = PG_V|PG_KW|v++;
                    616:        while (--i > 0);
                    617:        mtpr(TBIA, 0);
                    618: }
                    619: #ifdef ETHERNET
                    620: ecaccess(physa, pte)
                    621:        struct  nexus *physa;
                    622:        register struct pte *pte;
                    623: {
                    624:        register int i = 64;
                    625:        register unsigned v = btop(physa);
                    626: 
                    627:        do
                    628:                *(int *)pte++ = PG_V | PG_KW | v++;
                    629:        while(--i);
                    630: }
                    631: #endif ETHERNET

unix.superglobalmegacorp.com

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