Annotation of 43BSD/sys/vax/autoconf.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982,1986 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  *
                      6:  *     @(#)autoconf.c  7.1 (Berkeley) 6/6/86
                      7:  */
                      8: 
                      9: /*
                     10:  * Setup the system to run on the current machine.
                     11:  *
                     12:  * Configure() is called at boot time and initializes the uba and mba
                     13:  * device tables and the memory controller monitoring.  Available
                     14:  * devices are determined (from possibilities mentioned in ioconf.c),
                     15:  * and the drivers are initialized.
                     16:  */
                     17: 
                     18: #include "mba.h"
                     19: #include "uba.h"
                     20: 
                     21: #include "pte.h"
                     22: 
                     23: #include "param.h"
                     24: #include "systm.h"
                     25: #include "map.h"
                     26: #include "buf.h"
                     27: #include "dk.h"
                     28: #include "vm.h"
                     29: #include "conf.h"
                     30: #include "dmap.h"
                     31: #include "reboot.h"
                     32: 
                     33: #include "cpu.h"
                     34: #include "mem.h"
                     35: #include "mtpr.h"
                     36: #include "nexus.h"
                     37: #include "scb.h"
                     38: #include "ioa.h"
                     39: #include "../vaxmba/mbareg.h"
                     40: #include "../vaxmba/mbavar.h"
                     41: #include "../vaxuba/ubareg.h"
                     42: #include "../vaxuba/ubavar.h"
                     43: 
                     44: /*
                     45:  * The following several variables are related to
                     46:  * the configuration process, and are used in initializing
                     47:  * the machine.
                     48:  */
                     49: int    cold;           /* if 1, still working on cold-start */
                     50: int    nexnum;         /* current nexus number */
                     51: int    nsbi;           /* current sbi number */
                     52: int    dkn;            /* number of iostat dk numbers assigned so far */
                     53: int    cpuspeed = 1;   /* relative cpu speed */
                     54: 
                     55: /*
                     56:  * Addresses of the (locore) routines which bootstrap us from
                     57:  * hardware traps to C code.  Filled into the system control block
                     58:  * as necessary.
                     59:  */
                     60: #if NMBA > 0
                     61: int    (*mbaintv[4])() =       { Xmba0int, Xmba1int, Xmba2int, Xmba3int };
                     62: #if NMBA > 4
                     63:        Need to expand the table for more than 4 massbus adaptors
                     64: #endif
                     65: #endif
                     66: #if defined(VAX780) || defined(VAX8600)
                     67: int    (*ubaintv[])() =
                     68: {
                     69:        Xua0int, Xua1int, Xua2int, Xua3int,
                     70: #if NUBA > 4
                     71:        Xua4int, Xua5int, Xua6int, Xua7int,
                     72: #endif
                     73: #if NUBA > 8
                     74:        Need to expand the table for more than 8 unibus adaptors
                     75: #endif
                     76: };
                     77: #endif
                     78: 
                     79: /*
                     80:  * This allocates the space for the per-uba information,
                     81:  * such as buffered data path usage.
                     82:  */
                     83: struct uba_hd uba_hd[NUBA];
                     84: 
                     85: /*
                     86:  * Determine mass storage and memory configuration for a machine.
                     87:  * Get cpu type, and then switch out to machine specific procedures
                     88:  * which will probe adaptors to see what is out there.
                     89:  */
                     90: configure()
                     91: {
                     92:        union cpusid cpusid;
                     93:        register struct percpu *ocp;
                     94:        register int *ip;
                     95:        extern char Sysbase[];
                     96: 
                     97:        cpusid.cpusid = mfpr(SID);
                     98:        for (ocp = percpu; ocp->pc_cputype; ocp++)
                     99:                if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
                    100:                        cpuspeed = ocp->pc_cpuspeed;
                    101:                        probeio(ocp);
                    102:                        /*
                    103:                         * Write protect the scb and UNIBUS interrupt vectors.
                    104:                         * It is strange that this code is here, but this is
                    105:                         * as soon as we are done mucking with it, and the
                    106:                         * write-enable was done in assembly language
                    107:                         * to which we will never return.
                    108:                         */
                    109:                        ip = (int *)Sysmap + 1; *ip &= ~PG_PROT; *ip |= PG_KR;
                    110:                        ip++; *ip &= ~PG_PROT; *ip |= PG_KR;
                    111: #if NUBA > 1
                    112:                        ip++; *ip &= ~PG_PROT; *ip |= PG_KR;
                    113: #endif
                    114:                        mtpr(TBIS, Sysbase);
                    115: #if GENERIC
                    116:                        if ((boothowto & RB_ASKNAME) == 0)
                    117:                                setroot();
                    118:                        setconf();
                    119: #else
                    120:                        setroot();
                    121: #endif
                    122:                        /*
                    123:                         * Configure swap area and related system
                    124:                         * parameter based on device(s) used.
                    125:                         */
                    126:                        swapconf();
                    127:                        cold = 0;
                    128:                        memenable();
                    129:                        return;
                    130:                }
                    131:        printf("cpu type %d not configured\n", cpusid.cpuany.cp_type);
                    132:        asm("halt");
                    133: }
                    134: 
                    135: /*
                    136:  * Probe the main IO bus(es).
                    137:  * The percpu structure gives us a handle on the addresses and/or types.
                    138:  */
                    139: probeio(pcpu)
                    140:        register struct percpu *pcpu;
                    141: {
                    142:        register struct iobus *iob;
                    143:        int ioanum;
                    144: 
                    145:        ioanum = 0;
                    146:        for (iob = pcpu->pc_io; ioanum < pcpu->pc_nioa; ioanum++, iob++) {
                    147: 
                    148:                switch (iob->io_type) {
                    149: 
                    150: #if VAX780 || VAX750 || VAX730 || VAX630
                    151:                case IO_SBI780:
                    152:                case IO_CMI750:
                    153:                case IO_XXX730:
                    154:                case IO_QBUS:
                    155:                        probenexi((struct nexusconnect *)iob->io_details);
                    156:                        break;
                    157: #endif
                    158: 
                    159: #if VAX8600
                    160:                case IO_ABUS:
                    161:                        probe_Abus(ioanum, iob);
                    162:                        break;
                    163: #endif
                    164:                default:
                    165:                        if (iob->io_addr) {
                    166:                            printf(
                    167:                "IO adaptor %d, type %d, at address 0x%x is unsupported\n",
                    168:                                ioanum, iob->io_type, iob->io_addr);
                    169:                        } else
                    170:                            printf("IO adaptor %d, type %d, is unsupported\n",
                    171:                                ioanum, iob->io_type);
                    172:                        break;
                    173:                }
                    174:        }
                    175: }
                    176: 
                    177: #if VAX8600
                    178: probe_Abus(ioanum, iob)
                    179:        register struct iobus *iob;
                    180: {
                    181:        register struct ioa *ioap;
                    182:        union ioacsr ioacsr;
                    183:        int type;
                    184:        struct sbia_regs *sbiaregs;
                    185: 
                    186:        ioap = &ioa[ioanum];
                    187:        ioaccess(iob->io_addr, Ioamap[ioanum], iob->io_size);
                    188:        if (badaddr((caddr_t)ioap, 4))
                    189:                return;
                    190:        ioacsr.ioa_csr = ioap->ioacsr.ioa_csr;
                    191:        type = ioacsr.ioa_type & IOA_TYPMSK;
                    192: 
                    193:        switch (type) {
                    194: 
                    195:        case IOA_SBIA:
                    196:                printf("SBIA%d at IO adaptor %d address 0x%x\n",
                    197:                    nsbi, ioanum, iob->io_addr);
                    198:                probenexi((struct nexusconnect *)iob->io_details);
                    199:                nsbi++;
                    200:                sbiaregs = (struct sbia_regs *)ioap;
                    201:                sbiaregs->sbi_errsum = -1;
                    202:                sbiaregs->sbi_error = 0x1000;
                    203:                sbiaregs->sbi_fltsts = 0xc0000;
                    204:                break;
                    205: 
                    206:        default:
                    207:                printf("IOA%d at address 0x%x is unsupported (type = 0x%x)\n",
                    208:                    ioanum, iob->io_addr, ioacsr.ioa_type);
                    209:                break;
                    210:        }
                    211: }
                    212: #endif
                    213: 
                    214: /*
                    215:  * Probe nexus space, finding the interconnects
                    216:  * and setting up and probing mba's and uba's for devices.
                    217:  */
                    218: /*ARGSUSED*/
                    219: probenexi(pnc)
                    220:        register struct nexusconnect *pnc;
                    221: {
                    222:        register struct nexus *nxv;
                    223:        struct nexus *nxp = pnc->psb_nexbase;
                    224:        union nexcsr nexcsr;
                    225:        int i;
                    226:        
                    227:        nexnum = 0, nxv = &nexus[nsbi * NNEXSBI];
                    228:        for (; nexnum < pnc->psb_nnexus; nexnum++, nxp++, nxv++) {
                    229:                ioaccess((caddr_t)nxp, Nexmap[nsbi * NNEXSBI + nexnum],
                    230:                     sizeof(struct nexus));
                    231:                if (badaddr((caddr_t)nxv, 4))
                    232:                        continue;
                    233:                if (pnc->psb_nextype && pnc->psb_nextype[nexnum] != NEX_ANY)
                    234:                        nexcsr.nex_csr = pnc->psb_nextype[nexnum];
                    235:                else
                    236:                        nexcsr = nxv->nexcsr;
                    237:                if (nexcsr.nex_csr&NEX_APD)
                    238:                        continue;
                    239:                switch (nexcsr.nex_type) {
                    240: 
                    241:                case NEX_MBA:
                    242:                        printf("mba%d at tr%d\n", nummba, nexnum);
                    243:                        if (nummba >= NMBA) {
                    244:                                printf("%d mba's", nummba++);
                    245:                                goto unconfig;
                    246:                        }
                    247: #if NMBA > 0
                    248:                        mbafind(nxv, nxp);
                    249:                        nummba++;
                    250: #endif
                    251:                        break;
                    252: 
                    253:                case NEX_UBA0:
                    254:                case NEX_UBA1:
                    255:                case NEX_UBA2:
                    256:                case NEX_UBA3:
                    257:                        printf("uba%d at tr%d\n", numuba, nexnum);
                    258: #if VAX750
                    259:                        if (numuba >= 2 && cpu == VAX_750) {
                    260:                                printf("More than 2 UBA's");
                    261:                                goto unsupp;
                    262:                        }
                    263: #endif
                    264:                        if (numuba >= NUBA) {
                    265:                                printf("%d uba's", ++numuba);
                    266:                                goto unconfig;
                    267:                        }
                    268: #if defined(VAX780) || defined(VAX8600)
                    269:                        if ((cpu == VAX_780) || (cpu == VAX_8600))
                    270:                                setscbnex(ubaintv[numuba]);
                    271: #endif
                    272:                        i = nexcsr.nex_type - NEX_UBA0;
                    273:                        unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp,
                    274:                            umem[numuba], pnc->psb_umaddr[i], UMEMmap[numuba],
                    275:                            pnc->psb_haveubasr);
                    276: #if defined(VAX780) || defined(VAX8600)
                    277:                        if ((cpu == VAX_780) || (cpu == VAX_8600))
                    278:                                ((struct uba_regs *)nxv)->uba_cr =
                    279:                                    UBACR_IFS|UBACR_BRIE|
                    280:                                    UBACR_USEFIE|UBACR_SUEFIE|
                    281:                                    (((struct uba_regs *)nxv)->uba_cr&0x7c000000);
                    282: #endif
                    283:                        numuba++;
                    284:                        break;
                    285: 
                    286:                case NEX_DR32:
                    287:                /* there can be more than one... are there other codes??? */
                    288:                        printf("dr32");
                    289:                        goto unsupp;
                    290: 
                    291:                case NEX_MEM4:
                    292:                case NEX_MEM4I:
                    293:                case NEX_MEM16:
                    294:                case NEX_MEM16I:
                    295:                        printf("mcr%d at tr%d\n", nmcr, nexnum);
                    296:                        if (nmcr >= 4) {
                    297:                                printf("5 mcr's");
                    298:                                goto unsupp;
                    299:                        }
                    300:                        switch (cpu) {
                    301:                        case VAX_780:
                    302:                                mcrtype[nmcr] = M780C;
                    303:                                break;
                    304:                        case VAX_750:
                    305:                                mcrtype[nmcr] = M750;
                    306:                                break;
                    307:                        case VAX_730:
                    308:                                mcrtype[nmcr] = M730;
                    309:                                break;
                    310:                        }
                    311:                        mcraddr[nmcr++] = (struct mcr *)nxv;
                    312:                        break;
                    313: 
                    314:                case NEX_MEM64I:
                    315:                case NEX_MEM64L:
                    316:                case NEX_MEM64LI:
                    317:                case NEX_MEM256I:
                    318:                case NEX_MEM256L:
                    319:                case NEX_MEM256LI:
                    320:                        printf("mcr%d (el) at tr%d\n", nmcr, nexnum);
                    321:                        if (nmcr >= 4) {
                    322:                                printf("5 mcr's");
                    323:                                goto unsupp;
                    324:                        }
                    325:                        if (cpu == VAX_780)
                    326:                                mcrtype[nmcr] = M780EL;
                    327:                        mcraddr[nmcr++] = (struct mcr *)nxv;
                    328:                        if (nexcsr.nex_type != NEX_MEM64I && 
                    329:                          nexcsr.nex_type != NEX_MEM256I)
                    330:                                break;
                    331:                        /* fall into ... */
                    332: 
                    333:                case NEX_MEM64U:
                    334:                case NEX_MEM64UI:
                    335:                case NEX_MEM256U:
                    336:                case NEX_MEM256UI:
                    337:                        printf("mcr%d (eu) at tr%d\n", nmcr, nexnum);
                    338:                        if (nmcr >= 4) {
                    339:                                printf("5 mcr's");
                    340:                                goto unsupp;
                    341:                        }
                    342:                        if (cpu == VAX_780)
                    343:                                mcrtype[nmcr] = M780EU;
                    344:                        mcraddr[nmcr++] = (struct mcr *)nxv;
                    345:                        break;
                    346: 
                    347:                case NEX_MPM0:
                    348:                case NEX_MPM1:
                    349:                case NEX_MPM2:
                    350:                case NEX_MPM3:
                    351:                        printf("mpm");
                    352:                        goto unsupp;
                    353: 
                    354:                case NEX_CI:
                    355:                        printf("ci");
                    356:                        goto unsupp;
                    357: 
                    358:                default:
                    359:                        printf("nexus type %x", nexcsr.nex_type);
                    360: unsupp:
                    361:                        printf(" unsupported (at tr %d)\n", nexnum);
                    362:                        continue;
                    363: unconfig:
                    364:                        printf(" not configured\n");
                    365:                        continue;
                    366:                }
                    367:        }
                    368:        if (nummba > NMBA)
                    369:                nummba = NMBA;
                    370:        if (numuba > NUBA)
                    371:                numuba = NUBA;
                    372: }
                    373: 
                    374: #if NMBA > 0
                    375: struct mba_device *mbaconfig();
                    376: /*
                    377:  * Find devices attached to a particular mba
                    378:  * and look for each device found in the massbus
                    379:  * initialization tables.
                    380:  */
                    381: mbafind(nxv, nxp)
                    382:        struct nexus *nxv, *nxp;
                    383: {
                    384:        register struct mba_regs *mdp;
                    385:        register struct mba_drv *mbd;
                    386:        register struct mba_device *mi;
                    387:        register struct mba_slave *ms;
                    388:        int dn, dt, sn;
                    389:        struct mba_device fnd;
                    390: 
                    391:        mdp = (struct mba_regs *)nxv;
                    392:        mba_hd[nummba].mh_mba = mdp;
                    393:        mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
                    394:        setscbnex(mbaintv[nummba]);
                    395:        fnd.mi_mba = mdp;
                    396:        fnd.mi_mbanum = nummba;
                    397:        for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
                    398:                if ((mbd->mbd_ds&MBDS_DPR) == 0)
                    399:                        continue;
                    400:                mdp->mba_sr |= MBSR_NED;                /* si kludge */
                    401:                dt = mbd->mbd_dt & 0xffff;
                    402:                if (dt == 0)
                    403:                        continue;
                    404:                if (mdp->mba_sr&MBSR_NED)
                    405:                        continue;                       /* si kludge */
                    406:                if (dt == MBDT_MOH)
                    407:                        continue;
                    408:                fnd.mi_drive = dn;
                    409: #define        qeq(a, b)       ( a == b || a == '?' )
                    410:                if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP))
                    411:                    for (sn = 0; sn < 8; sn++) {
                    412:                        mbd->mbd_tc = sn;
                    413:                        for (ms = mbsinit; ms->ms_driver; ms++)
                    414:                            if (ms->ms_driver == mi->mi_driver &&
                    415:                                ms->ms_alive == 0 && 
                    416:                                qeq(ms->ms_ctlr, mi->mi_unit) &&
                    417:                                qeq(ms->ms_slave, sn) &&
                    418:                                (*ms->ms_driver->md_slave)(mi, ms, sn)) {
                    419:                                        printf("%s%d at %s%d slave %d\n"
                    420:                                            , ms->ms_driver->md_sname
                    421:                                            , ms->ms_unit
                    422:                                            , mi->mi_driver->md_dname
                    423:                                            , mi->mi_unit
                    424:                                            , sn
                    425:                                        );
                    426:                                        ms->ms_alive = 1;
                    427:                                        ms->ms_ctlr = mi->mi_unit;
                    428:                                        ms->ms_slave = sn;
                    429:                                }
                    430:                    }
                    431:        }
                    432:        mdp->mba_cr = MBCR_INIT;
                    433:        mdp->mba_cr = MBCR_IE;
                    434: }
                    435: 
                    436: /*
                    437:  * Have found a massbus device;
                    438:  * see if it is in the configuration table.
                    439:  * If so, fill in its data.
                    440:  */
                    441: struct mba_device *
                    442: mbaconfig(ni, type)
                    443:        register struct mba_device *ni;
                    444:        register int type;
                    445: {
                    446:        register struct mba_device *mi;
                    447:        register short *tp;
                    448:        register struct mba_hd *mh;
                    449: 
                    450:        for (mi = mbdinit; mi->mi_driver; mi++) {
                    451:                if (mi->mi_alive)
                    452:                        continue;
                    453:                tp = mi->mi_driver->md_type;
                    454:                for (mi->mi_type = 0; *tp; tp++, mi->mi_type++)
                    455:                        if (*tp == (type&MBDT_TYPE))
                    456:                                goto found;
                    457:                continue;
                    458: found:
                    459: #define        match(fld)      (ni->fld == mi->fld || mi->fld == '?')
                    460:                if (!match(mi_drive) || !match(mi_mbanum))
                    461:                        continue;
                    462:                printf("%s%d at mba%d drive %d\n",
                    463:                    mi->mi_driver->md_dname, mi->mi_unit,
                    464:                    ni->mi_mbanum, ni->mi_drive);
                    465:                mi->mi_alive = 1;
                    466:                mh = &mba_hd[ni->mi_mbanum];
                    467:                mi->mi_hd = mh;
                    468:                mh->mh_mbip[ni->mi_drive] = mi;
                    469:                mh->mh_ndrive++;
                    470:                mi->mi_mba = ni->mi_mba;
                    471:                mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive];
                    472:                mi->mi_mbanum = ni->mi_mbanum;
                    473:                mi->mi_drive = ni->mi_drive;
                    474:                /*
                    475:                 * If drive has never been seen before,
                    476:                 * give it a dkn for statistics.
                    477:                 */
                    478:                if (mi->mi_driver->md_info[mi->mi_unit] == 0) {
                    479:                        mi->mi_driver->md_info[mi->mi_unit] = mi;
                    480:                        if (mi->mi_dk && dkn < DK_NDRIVE)
                    481:                                mi->mi_dk = dkn++;
                    482:                        else
                    483:                                mi->mi_dk = -1;
                    484:                }
                    485:                (*mi->mi_driver->md_attach)(mi);
                    486:                return (mi);
                    487:        }
                    488:        return (0);
                    489: }
                    490: #endif
                    491: 
                    492: /*
                    493:  * Fixctlrmask fixes the masks of the driver ctlr routines
                    494:  * which otherwise save r10 and r11 where the interrupt and br
                    495:  * level are passed through.
                    496:  */
                    497: fixctlrmask()
                    498: {
                    499:        register struct uba_ctlr *um;
                    500:        register struct uba_device *ui;
                    501:        register struct uba_driver *ud;
                    502: #define        phys(a,b) ((b)(((int)(a))&0x7fffffff))
                    503: 
                    504:        for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++)
                    505:                *phys(ud->ud_probe, short *) &= ~0xc00;
                    506:        for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++)
                    507:                *phys(ud->ud_probe, short *) &= ~0xc00;
                    508: }
                    509: 
                    510: /*
                    511:  * Find devices on a UNIBUS.
                    512:  * Uses per-driver routine to set <br,cvec> into <r11,r10>,
                    513:  * and then fills in the tables, with help from a per-driver
                    514:  * slave initialization routine.
                    515:  */
                    516: unifind(vubp, pubp, vumem, pumem, memmap, haveubasr)
                    517:        struct uba_regs *vubp, *pubp;
                    518:        caddr_t vumem, pumem;
                    519:        struct pte *memmap;
                    520:        int haveubasr;
                    521: {
                    522: #ifndef lint
                    523:        register int br, cvec;                  /* MUST BE r11, r10 */
                    524: #else
                    525:        /*
                    526:         * Lint doesn't realize that these
                    527:         * can be initialized asynchronously
                    528:         * when devices interrupt.
                    529:         */
                    530:        register int br = 0, cvec = 0;
                    531: #endif
                    532:        register struct uba_device *ui;
                    533:        register struct uba_ctlr *um;
                    534:        u_short *reg, *ap, addr;
                    535:        struct uba_hd *uhp;
                    536:        struct uba_driver *udp;
                    537:        int i, (**ivec)();
                    538:        caddr_t ualloc, zmemall();
                    539:        extern int catcher[256];
                    540: 
                    541: #if VAX630
                    542:        /*
                    543:         * The map registers start right at 20088000 on the
                    544:         * ka630, so we have to subtract out the 2k offset to make the
                    545:         * pointers work..
                    546:         */
                    547:        if (cpu == VAX_630) {
                    548:                vubp = (struct uba_regs *)(((u_long)vubp)-0x800);
                    549:                pubp = (struct uba_regs *)(((u_long)pubp)-0x800);
                    550:        }
                    551: #endif
                    552:        /*
                    553:         * Initialize the UNIBUS, by freeing the map
                    554:         * registers and the buffered data path registers
                    555:         */
                    556:        uhp = &uba_hd[numuba];
                    557:        uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map));
                    558:        ubainitmaps(uhp);
                    559: 
                    560:        /*
                    561:         * Save virtual and physical addresses
                    562:         * of adaptor, and allocate and initialize
                    563:         * the UNIBUS interrupt vector.
                    564:         */
                    565:        uhp->uh_uba = vubp;
                    566:        uhp->uh_physuba = pubp;
                    567:        /*
                    568:         * On the 8600, can't use UNIvec;
                    569:         * the vectors for the second SBI overlap it.
                    570:         */
                    571:        if (cpu == VAX_8600)
                    572:                uhp->uh_vec = (int(**)())calloc(512);
                    573:        else if (numuba == 0)
                    574:                uhp->uh_vec = UNIvec;
                    575: #if NUBA > 1
                    576:        else if (numuba == 1)
                    577:                uhp->uh_vec = UNI1vec;
                    578:        else
                    579:                uhp->uh_vec = (int(**)())calloc(512);
                    580: #endif
                    581:        for (i = 0; i < 128; i++)
                    582:                uhp->uh_vec[i] =
                    583:                    scbentry(&catcher[i*2], SCB_ISTACK);
                    584:        /*
                    585:         * Set last free interrupt vector for devices with
                    586:         * programmable interrupt vectors.  Use is to decrement
                    587:         * this number and use result as interrupt vector.
                    588:         */
                    589:        uhp->uh_lastiv = 0x200;
                    590: 
                    591: #if VAX630
                    592:        /*
                    593:         * Kludge time again. The q22 memory and device reg. address spaces
                    594:         * are not physically contiguous, so we need 2 loops to map them
                    595:         * into contiguous virtual space.
                    596:         */
                    597:        if (cpu == VAX_630) {
                    598:                ioaccess(pumem, memmap, (UBAPAGES-16)*NBPG);
                    599:                ioaccess(0x20000000, memmap+(UBAPAGES-16), 16*NBPG);
                    600:        } else
                    601: #endif
                    602:                ioaccess(pumem, memmap, UBAPAGES * NBPG);
                    603: #if defined(VAX780) || defined(VAX8600)
                    604:        if (haveubasr) {
                    605:                vubp->uba_sr = vubp->uba_sr;
                    606:                vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
                    607:        }
                    608: #endif
                    609:        /*
                    610:         * First configure devices that have unibus memory,
                    611:         * allowing them to allocate the correct map registers.
                    612:         */
                    613:        ubameminit(numuba);
                    614:        /*
                    615:         * Grab some memory to record the umem address space we allocate,
                    616:         * so we can be sure not to place two devices at the same address.
                    617:         *
                    618:         * We could use just 1/8 of this (we only want a 1 bit flag) but
                    619:         * we are going to give it back anyway, and that would make the
                    620:         * code here bigger (which we can't give back), so ...
                    621:         *
                    622:         * One day, someone will make a unibus with something other than
                    623:         * an 8K i/o address space, & screw this totally.
                    624:         */
                    625:        ualloc = zmemall(memall, 8*1024);
                    626:        if (ualloc == (caddr_t)0)
                    627:                panic("no mem for unifind");
                    628: 
                    629:        /*
                    630:         * Map the first page of UNIBUS i/o
                    631:         * space to the first page of memory
                    632:         * for devices which will need to dma
                    633:         * output to produce an interrupt.
                    634:         */
                    635:        *(int *)(&vubp->uba_map[0]) = UBAMR_MRV;
                    636: 
                    637: #define        ubaoff(off)     ((off)&0x1fff)
                    638: #define        ubaddr(off)     (u_short *)((int)vumem + (ubaoff(off)|0x3e000))
                    639:        /*
                    640:         * Check each unibus mass storage controller.
                    641:         * For each one which is potentially on this uba,
                    642:         * see if it is really there, and if it is record it and
                    643:         * then go looking for slaves.
                    644:         */
                    645:        for (um = ubminit; udp = um->um_driver; um++) {
                    646:                if (um->um_ubanum != numuba && um->um_ubanum != '?')
                    647:                        continue;
                    648:                addr = (u_short)um->um_addr;
                    649:                /*
                    650:                 * use the particular address specified first,
                    651:                 * or if it is given as "0", of there is no device
                    652:                 * at that address, try all the standard addresses
                    653:                 * in the driver til we find it
                    654:                 */
                    655:            for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
                    656: 
                    657:                if (ualloc[ubaoff(addr)])
                    658:                        continue;
                    659:                reg = ubaddr(addr);
                    660:                if (badaddr((caddr_t)reg, 2))
                    661:                        continue;
                    662: #if defined(VAX780) || defined(VAX8600)
                    663:                if (haveubasr && vubp->uba_sr) {
                    664:                        vubp->uba_sr = vubp->uba_sr;
                    665:                        continue;
                    666:                }
                    667: #endif
                    668:                cvec = 0x200;
                    669:                i = (*udp->ud_probe)(reg, um->um_ctlr, um);
                    670: #if defined(VAX780) || defined(VAX8600)
                    671:                if (haveubasr && vubp->uba_sr) {
                    672:                        vubp->uba_sr = vubp->uba_sr;
                    673:                        continue;
                    674:                }
                    675: #endif
                    676:                if (i == 0)
                    677:                        continue;
                    678:                printf("%s%d at uba%d csr %o ",
                    679:                    udp->ud_mname, um->um_ctlr, numuba, addr);
                    680:                if (cvec == 0) {
                    681:                        printf("zero vector\n");
                    682:                        continue;
                    683:                }
                    684:                if (cvec == 0x200) {
                    685:                        printf("didn't interrupt\n");
                    686:                        continue;
                    687:                }
                    688:                printf("vec %o, ipl %x\n", cvec, br);
                    689:                um->um_alive = 1;
                    690:                um->um_ubanum = numuba;
                    691:                um->um_hd = &uba_hd[numuba];
                    692:                um->um_addr = (caddr_t)reg;
                    693:                udp->ud_minfo[um->um_ctlr] = um;
                    694:                for (ivec = um->um_intr; *ivec; ivec++) {
                    695:                        um->um_hd->uh_vec[cvec/4] =
                    696:                            scbentry(*ivec, SCB_ISTACK);
                    697:                        cvec += 4;
                    698:                }
                    699:                for (ui = ubdinit; ui->ui_driver; ui++) {
                    700:                        if (ui->ui_driver != udp || ui->ui_alive ||
                    701:                            ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
                    702:                            ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
                    703:                                continue;
                    704:                        if ((*udp->ud_slave)(ui, reg)) {
                    705:                                ui->ui_alive = 1;
                    706:                                ui->ui_ctlr = um->um_ctlr;
                    707:                                ui->ui_ubanum = numuba;
                    708:                                ui->ui_hd = &uba_hd[numuba];
                    709:                                ui->ui_addr = (caddr_t)reg;
                    710:                                ui->ui_physaddr = pumem + ubdevreg(addr);
                    711:                                if (ui->ui_dk && dkn < DK_NDRIVE)
                    712:                                        ui->ui_dk = dkn++;
                    713:                                else
                    714:                                        ui->ui_dk = -1;
                    715:                                ui->ui_mi = um;
                    716:                                /* ui_type comes from driver */
                    717:                                udp->ud_dinfo[ui->ui_unit] = ui;
                    718:                                printf("%s%d at %s%d slave %d\n",
                    719:                                    udp->ud_dname, ui->ui_unit,
                    720:                                    udp->ud_mname, um->um_ctlr, ui->ui_slave);
                    721:                                (*udp->ud_attach)(ui);
                    722:                        }
                    723:                }
                    724:                break;
                    725:            }
                    726:        }
                    727:        /*
                    728:         * Now look for non-mass storage peripherals.
                    729:         */
                    730:        for (ui = ubdinit; udp = ui->ui_driver; ui++) {
                    731:                if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' ||
                    732:                    ui->ui_alive || ui->ui_slave != -1)
                    733:                        continue;
                    734:                addr = (u_short)ui->ui_addr;
                    735: 
                    736:            for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
                    737:                
                    738:                if (ualloc[ubaoff(addr)])
                    739:                        continue;
                    740:                reg = ubaddr(addr);
                    741:                if (badaddr((caddr_t)reg, 2))
                    742:                        continue;
                    743: #if defined(VAX780) || defined(VAX8600)
                    744:                if (haveubasr && vubp->uba_sr) {
                    745:                        vubp->uba_sr = vubp->uba_sr;
                    746:                        continue;
                    747:                }
                    748: #endif
                    749:                cvec = 0x200;
                    750:                i = (*udp->ud_probe)(reg, ui);
                    751: #if defined(VAX780) || defined(VAX8600)
                    752:                if (haveubasr && vubp->uba_sr) {
                    753:                        vubp->uba_sr = vubp->uba_sr;
                    754:                        continue;
                    755:                }
                    756: #endif
                    757:                if (i == 0)
                    758:                        continue;
                    759:                printf("%s%d at uba%d csr %o ",
                    760:                    ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
                    761:                if (cvec == 0) {
                    762:                        printf("zero vector\n");
                    763:                        continue;
                    764:                }
                    765:                if (cvec == 0x200) {
                    766:                        printf("didn't interrupt\n");
                    767:                        continue;
                    768:                }
                    769:                printf("vec %o, ipl %x\n", cvec, br);
                    770:                while (--i >= 0)
                    771:                        ualloc[ubaoff(addr+i)] = 1;
                    772:                ui->ui_hd = &uba_hd[numuba];
                    773:                for (ivec = ui->ui_intr; *ivec; ivec++) {
                    774:                        ui->ui_hd->uh_vec[cvec/4] =
                    775:                            scbentry(*ivec, SCB_ISTACK);
                    776:                        cvec += 4;
                    777:                }
                    778:                ui->ui_alive = 1;
                    779:                ui->ui_ubanum = numuba;
                    780:                ui->ui_addr = (caddr_t)reg;
                    781:                ui->ui_physaddr = pumem + ubdevreg(addr);
                    782:                ui->ui_dk = -1;
                    783:                /* ui_type comes from driver */
                    784:                udp->ud_dinfo[ui->ui_unit] = ui;
                    785:                (*udp->ud_attach)(ui);
                    786:                break;
                    787:            }
                    788:        }
                    789: 
                    790: #ifdef AUTO_DEBUG
                    791:        printf("Unibus allocation map");
                    792:        for (i = 0; i < 8*1024; ) {
                    793:                register n, m;
                    794: 
                    795:                if ((i % 128) == 0) {
                    796:                        printf("\n%6o:", i);
                    797:                        for (n = 0; n < 128; n++)
                    798:                                if (ualloc[i+n])
                    799:                                        break;
                    800:                        if (n == 128) {
                    801:                                i += 128;
                    802:                                continue;
                    803:                        }
                    804:                }
                    805: 
                    806:                for (n = m = 0; n < 16; n++) {
                    807:                        m <<= 1;
                    808:                        m |= ualloc[i++];
                    809:                }
                    810: 
                    811:                printf(" %4x", m);
                    812:        }
                    813:        printf("\n");
                    814: #endif
                    815: 
                    816:        wmemfree(ualloc, 8*1024);
                    817: }
                    818: 
                    819: setscbnex(fn)
                    820:        int (*fn)();
                    821: {
                    822:        register struct scb *scbp = &scb;
                    823: 
                    824:        scbp = (struct scb *)((caddr_t)scbp + nsbi * 512);
                    825:        scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] =
                    826:            scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] =
                    827:                scbentry(fn, SCB_ISTACK);
                    828: }
                    829: 
                    830: /*
                    831:  * Make an IO register area accessible at physical address physa
                    832:  * by mapping kernel ptes starting at pte.
                    833:  */
                    834: ioaccess(physa, pte, size)
                    835:        caddr_t physa;
                    836:        register struct pte *pte;
                    837:        int size;
                    838: {
                    839:        register int i = btop(size);
                    840:        register unsigned v = btop(physa);
                    841:        
                    842:        do
                    843:                *(int *)pte++ = PG_V|PG_KW|v++;
                    844:        while (--i > 0);
                    845:        mtpr(TBIA, 0);
                    846: }
                    847: 
                    848: /*
                    849:  * Configure swap space and related parameters.
                    850:  */
                    851: swapconf()
                    852: {
                    853:        register struct swdevt *swp;
                    854:        register int nblks;
                    855: 
                    856:        for (swp = swdevt; swp->sw_dev; swp++) {
                    857:                if (bdevsw[major(swp->sw_dev)].d_psize) {
                    858:                        nblks =
                    859:                            (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
                    860:                        if (swp->sw_nblks == 0 || swp->sw_nblks > nblks)
                    861:                                swp->sw_nblks = nblks;
                    862:                }
                    863:        }
                    864:        if (!cold)                      /* in case called for mba device */
                    865:                return;
                    866:        if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize)
                    867:                dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - physmem;
                    868:        if (dumplo < 0)
                    869:                dumplo = 0;
                    870: }
                    871: 
                    872: #define        DOSWAP                  /* Change swdevt, argdev, and dumpdev too */
                    873: u_long bootdev;                /* should be dev_t, but not until 32 bits */
                    874: 
                    875: static char devname[][2] = {
                    876:        'h','p',        /* 0 = hp */
                    877:        0,0,            /* 1 = ht */
                    878:        'u','p',        /* 2 = up */
                    879:        'r','k',        /* 3 = hk */
                    880:        0,0,            /* 4 = sw */
                    881:        0,0,            /* 5 = tm */
                    882:        0,0,            /* 6 = ts */
                    883:        0,0,            /* 7 = mt */
                    884:        0,0,            /* 8 = tu */
                    885:        'r','a',        /* 9 = ra */
                    886:        0,0,            /* 10 = ut */
                    887:        'r','b',        /* 11 = rb */
                    888:        0,0,            /* 12 = uu */
                    889:        0,0,            /* 13 = rx */
                    890:        'r','l',        /* 14 = rl */
                    891: };
                    892: 
                    893: #define        PARTITIONMASK   0x7
                    894: #define        PARTITIONSHIFT  3
                    895: 
                    896: /*
                    897:  * Attempt to find the device from which we were booted.
                    898:  * If we can do so, and not instructed not to do so,
                    899:  * change rootdev to correspond to the load device.
                    900:  */
                    901: setroot()
                    902: {
                    903:        int  majdev, mindev, unit, part, adaptor;
                    904:        dev_t temp, orootdev;
                    905:        struct swdevt *swp;
                    906: 
                    907:        if (boothowto & RB_DFLTROOT ||
                    908:            (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
                    909:                return;
                    910:        majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
                    911:        if (majdev > sizeof(devname) / sizeof(devname[0]))
                    912:                return;
                    913:        adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
                    914:        part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
                    915:        unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
                    916:        if (majdev == 0) {      /* MBA device */
                    917: #if NMBA > 0
                    918:                register struct mba_device *mbap;
                    919:                int mask;
                    920: 
                    921: /*
                    922:  * The MBA number used at boot time is not necessarily the same as the
                    923:  * MBA number used by the kernel.  In order to change the rootdev we need to
                    924:  * convert the boot MBA number to the kernel MBA number.  The address space
                    925:  * for an MBA used by the boot code is 0x20010000 + 0x2000 * MBA_number
                    926:  * on the 78? and 86?0, 0xf28000 + 0x2000 * MBA_number on the 750.
                    927:  * Therefore we can search the mba_hd table for the MBA that has the physical
                    928:  * address corresponding to the boot MBA number.
                    929:  */
                    930: #define        PHYSADRSHFT     13
                    931: #define        PHYSMBAMASK780  0x7
                    932: #define        PHYSMBAMASK750  0x3
                    933: 
                    934:                switch (cpu) {
                    935: 
                    936:                case VAX_780:
                    937:                case VAX_8600:
                    938:                default:
                    939:                        mask = PHYSMBAMASK780;
                    940:                        break;
                    941: 
                    942:                case VAX_750:
                    943:                        mask = PHYSMBAMASK750;
                    944:                        break;
                    945:                }
                    946:                for (mbap = mbdinit; mbap->mi_driver; mbap++)
                    947:                        if (mbap->mi_alive && mbap->mi_drive == unit &&
                    948:                            (((long)mbap->mi_hd->mh_physmba >> PHYSADRSHFT)
                    949:                              & mask) == adaptor)
                    950:                                break;
                    951:                if (mbap->mi_driver == 0)
                    952:                        return;
                    953:                mindev = mbap->mi_unit;
                    954: #else
                    955:                return;
                    956: #endif
                    957:        } else {
                    958:                register struct uba_device *ubap;
                    959: 
                    960:                for (ubap = ubdinit; ubap->ui_driver; ubap++)
                    961:                        if (ubap->ui_alive && ubap->ui_slave == unit &&
                    962:                           ubap->ui_ubanum == adaptor &&
                    963:                           ubap->ui_driver->ud_dname[0] == devname[majdev][0] &&
                    964:                           ubap->ui_driver->ud_dname[1] == devname[majdev][1])
                    965:                                break;
                    966: 
                    967:                if (ubap->ui_driver == 0)
                    968:                        return;
                    969:                mindev = ubap->ui_unit;
                    970:        }
                    971:        mindev = (mindev << PARTITIONSHIFT) + part;
                    972:        orootdev = rootdev;
                    973:        rootdev = makedev(majdev, mindev);
                    974:        /*
                    975:         * If the original rootdev is the same as the one
                    976:         * just calculated, don't need to adjust the swap configuration.
                    977:         */
                    978:        if (rootdev == orootdev)
                    979:                return;
                    980: 
                    981:        printf("Changing root device to %c%c%d%c\n",
                    982:                devname[majdev][0], devname[majdev][1],
                    983:                mindev >> PARTITIONSHIFT, part + 'a');
                    984: 
                    985: #ifdef DOSWAP
                    986:        mindev &= ~PARTITIONMASK;
                    987:        for (swp = swdevt; swp->sw_dev; swp++) {
                    988:                if (majdev == major(swp->sw_dev) &&
                    989:                    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
                    990:                        temp = swdevt[0].sw_dev;
                    991:                        swdevt[0].sw_dev = swp->sw_dev;
                    992:                        swp->sw_dev = temp;
                    993:                        break;
                    994:                }
                    995:        }
                    996:        if (swp->sw_dev == 0)
                    997:                return;
                    998: 
                    999:        /*
                   1000:         * If argdev and dumpdev were the same as the old primary swap
                   1001:         * device, move them to the new primary swap device.
                   1002:         */
                   1003:        if (temp == dumpdev)
                   1004:                dumpdev = swdevt[0].sw_dev;
                   1005:        if (temp == argdev)
                   1006:                argdev = swdevt[0].sw_dev;
                   1007: #endif
                   1008: }

unix.superglobalmegacorp.com

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