Annotation of 43BSDReno/sys/tahoe/autoconf.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1986, 1988 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.4 (Berkeley) 6/28/90
                      7:  */
                      8: 
                      9: /*
                     10:  * Setup the system to run on the current machine.
                     11:  *
                     12:  * Configure() is called at boot time and initializes the vba 
                     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: #include "param.h"
                     18: #include "systm.h"
                     19: #include "map.h"
                     20: #include "buf.h"
                     21: #include "dkstat.h"
                     22: #include "vm.h"
                     23: #include "conf.h"
                     24: #include "dmap.h"
                     25: #include "reboot.h"
                     26: #include "malloc.h"
                     27: 
                     28: #include "pte.h"
                     29: #include "mem.h"
                     30: #include "mtpr.h"
                     31: #include "scb.h"
                     32: 
                     33: #include "vba.h"
                     34: 
                     35: #include "../tahoevba/vbavar.h"
                     36: #include "../tahoevba/vbaparam.h"
                     37: 
                     38: /*
                     39:  * The following several variables are related to
                     40:  * the configuration process, and are used in initializing
                     41:  * the machine.
                     42:  */
                     43: int    dkn;            /* number of iostat dk numbers assigned so far */
                     44: int    cold;           /* cold start flag initialized in locore.s */
                     45: 
                     46: /*
                     47:  * This allocates the space for the per-vba information.
                     48:  */
                     49: struct vba_hd vba_hd[NVBA];
                     50: 
                     51: /*
                     52:  * Determine i/o configuration for a machine.
                     53:  */
                     54: configure()
                     55: {
                     56:        register int *ip;
                     57:        extern caddr_t Sysbase;
                     58: 
                     59:        vbafind(numvba, (caddr_t)vmem, VMEMmap);
                     60:        numvba++;
                     61:        /*
                     62:         * Write protect the scb.  It is strange
                     63:         * that this code is here, but this is as soon
                     64:         * as we are done mucking with it, and the
                     65:         * write-enable was done in assembly language
                     66:         * to which we will never return.
                     67:         */
                     68:        ip = (int *)&Sysmap[2]; *ip &= ~PG_PROT; *ip |= PG_KR;
                     69:        mtpr(TBIS, Sysbase+2*NBPG);
                     70: #if GENERIC
                     71:        if ((boothowto & RB_ASKNAME) == 0)
                     72:                setroot();
                     73:        setconf();
                     74: #else
                     75:        setroot();
                     76: #endif
                     77:        /*
                     78:         * Configure swap area and related system
                     79:         * parameter based on device(s) used.
                     80:         */
                     81:        swapconf();
                     82:        cold = 0;
                     83: }
                     84: 
                     85: /*
                     86:  * Make the controllers accessible at physical address phys
                     87:  * by mapping kernel ptes starting at pte.
                     88:  */
                     89: vbaccess(pte, iobase, n)
                     90:        register struct pte *pte;
                     91:        caddr_t iobase;
                     92:        register int n;
                     93: {
                     94:        register unsigned v = btop(iobase);
                     95:        
                     96:        do
                     97:                *(int *)pte++ = PG_V|PG_KW|v++;
                     98:        while (--n > 0);
                     99:        mtpr(TBIA, 0);
                    100: }
                    101: 
                    102: /*
                    103:  * Fixctlrmask fixes the masks of the driver ctlr routines
                    104:  * which otherwise save r11 and r12 where the interrupt and br
                    105:  * level are passed through.
                    106:  */
                    107: fixctlrmask()
                    108: {
                    109:        register struct vba_ctlr *vm;
                    110:        register struct vba_device *vi;
                    111:        register struct vba_driver *vd;
                    112: #define        phys(a,b) ((b)(((int)(a))&~0xc0000000))
                    113: 
                    114:        vm = phys(vbminit, struct vba_ctlr *);
                    115:        for (; vd = phys(vm->um_driver, struct vba_driver *); vm++)
                    116:                *phys(vd->ud_probe, short *) &= ~0x1800;
                    117:        vi = phys(vbdinit, struct vba_device *);
                    118:        for (; vd = phys(vi->ui_driver, struct vba_driver *); vi++)
                    119:                *phys(vd->ud_probe, short *) &= ~0x1800;
                    120: }
                    121: 
                    122: /*
                    123:  * Find devices on the VERSAbus.
                    124:  * Uses per-driver routine to see who is on the bus
                    125:  * and then fills in the tables, with help from a per-driver
                    126:  * slave initialization routine.
                    127:  */
                    128: vbafind(vban, vumem, memmap)
                    129:        int vban;
                    130:        caddr_t vumem;
                    131:        struct pte memmap[];
                    132: {
                    133:        register int br, cvec;                  /* must be r12, r11 */
                    134:        register struct vba_device *ui;
                    135:        register struct vba_ctlr *um;
                    136:        u_short *reg;
                    137:        long addr, *ap;
                    138:        struct vba_hd *vhp;
                    139:        struct vba_driver *udp;
                    140:        int i, octlr, (**ivec)();
                    141:        caddr_t valloc;
                    142:        extern quad catcher[SCB_LASTIV];
                    143: 
                    144: #ifdef lint
                    145:        br = 0; cvec = 0;
                    146: #endif
                    147:        vhp = &vba_hd[vban];
                    148:        /*
                    149:         * Make the controllers accessible at physical address phys
                    150:         * by mapping kernel ptes starting at pte.
                    151:         */
                    152:        vbaccess(memmap, (caddr_t)VBIOBASE, (int)VBIOSIZE);
                    153:        printf("vba%d at %x\n", vban, VBIOBASE);
                    154:        /*
                    155:         * Setup scb device entries to point into catcher array.
                    156:         */
                    157:        for (i = 0; i < SCB_LASTIV; i++)
                    158:                scb.scb_devint[i] = (int (*)())((int)&catcher[i]);
                    159:        /*
                    160:         * Set last free interrupt vector for devices with
                    161:         * programmable interrupt vectors.  Use is to decrement
                    162:         * this number and use result as interrupt vector.
                    163:         */
                    164:        vhp->vh_lastiv = SCB_LASTIV;
                    165:        /*
                    166:         * Grab some memory to record the address space we allocate,
                    167:         * so we can be sure not to place two devices at the same address.
                    168:         * Register I/O space is allocated in 256-byte sections,
                    169:         * and memory I/O space is in 4Kb sections.  We record allocations
                    170:         * in 256-byte sections.
                    171:         *
                    172:         * We could use just 1/8 of this (we only want a 1 bit flag) but
                    173:         * we are going to give it back anyway, and that would make the
                    174:         * code here bigger (which we can't give back), so ...
                    175:         */
                    176: #define        VSECT(a)        ((a) / 0x100)
                    177: #define        VSIZE(s)        (((s) + 0xff) / 0x100)
                    178: #define        VALLOC(a)       (valloc[VSECT(vboff(a))])
                    179: #define        VMAPSIZE        VSIZE(ctob(VBIOSIZE))
                    180:        valloc = (caddr_t)malloc((u_long)(VMAPSIZE), M_TEMP, M_NOWAIT);
                    181:        if (valloc == (caddr_t)0)
                    182:                panic("no mem for vbafind");
                    183:        bzero(valloc, VMAPSIZE);
                    184: 
                    185:        /*
                    186:         * Check each VERSAbus mass storage controller.
                    187:         * For each one which is potentially on this vba,
                    188:         * see if it is really there, and if it is record it and
                    189:         * then go looking for slaves.
                    190:         */
                    191: #define        vbaddr(off)     (u_short *)(vumem + vboff(off))
                    192:        for (um = vbminit; udp = um->um_driver; um++) {
                    193:                if (um->um_vbanum != vban && um->um_vbanum != '?')
                    194:                        continue;
                    195:                /*
                    196:                 * Use the particular address specified first,
                    197:                 * or if it is given as "0", if there is no device
                    198:                 * at that address, try all the standard addresses
                    199:                 * in the driver until we find it.
                    200:                 */
                    201:                addr = (long)um->um_addr;
                    202:            for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
                    203:                if (VBIOMAPPED(addr)) {
                    204:                        if (VALLOC(addr))
                    205:                                continue;
                    206:                        reg = vbaddr(addr);
                    207:                } else
                    208:                        reg = (u_short *)addr;
                    209:                um->um_hd = vhp;
                    210:                cvec = SCB_LASTIV, cold &= ~0x2;
                    211:                i = (*udp->ud_probe)(reg, um);
                    212:                cold |= 0x2;
                    213:                if (i == 0)
                    214:                        continue;
                    215:                printf("%s%d at vba%d csr %x ",
                    216:                    udp->ud_mname, um->um_ctlr, vban, addr);
                    217:                if (cvec < 0 && vhp->vh_lastiv == cvec) {
                    218:                        printf("no space for vector(s)\n");
                    219:                        continue;
                    220:                }
                    221:                if (cvec == SCB_LASTIV) {
                    222:                        printf("didn't interrupt\n");
                    223:                        continue;
                    224:                }
                    225:                printf("vec %x, ipl %x\n", cvec, br);
                    226:                csralloc(valloc, addr, i);
                    227:                um->um_alive = 1;
                    228:                um->um_vbanum = vban;
                    229:                um->um_addr = (caddr_t)reg;
                    230:                udp->ud_minfo[um->um_ctlr] = um;
                    231:                for (ivec = um->um_intr; *ivec; ivec++)
                    232:                        ((long *)&scb)[cvec++] = (long)*ivec;
                    233:                for (ui = vbdinit; ui->ui_driver; ui++) {
                    234:                        if (ui->ui_driver != udp || ui->ui_alive ||
                    235:                            ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
                    236:                            ui->ui_vbanum != vban && ui->ui_vbanum != '?')
                    237:                                continue;
                    238:                        octlr = ui->ui_ctlr, ui->ui_ctlr = um->um_ctlr;
                    239:                        if ((*udp->ud_slave)(ui, reg)) {
                    240:                                ui->ui_alive = 1;
                    241:                                ui->ui_ctlr = um->um_ctlr;
                    242:                                ui->ui_vbanum = vban;
                    243:                                ui->ui_addr = (caddr_t)reg;
                    244:                                ui->ui_physaddr = (caddr_t)addr;
                    245:                                if (ui->ui_dk && dkn < DK_NDRIVE)
                    246:                                        ui->ui_dk = dkn++;
                    247:                                else
                    248:                                        ui->ui_dk = -1;
                    249:                                ui->ui_mi = um;
                    250:                                ui->ui_hd = vhp;
                    251:                                /* ui_type comes from driver */
                    252:                                udp->ud_dinfo[ui->ui_unit] = ui;
                    253:                                printf("%s%d at %s%d slave %d",
                    254:                                    udp->ud_dname, ui->ui_unit,
                    255:                                    udp->ud_mname, um->um_ctlr,
                    256:                                    ui->ui_slave);
                    257:                                (*udp->ud_attach)(ui);
                    258:                                printf("\n");
                    259:                        } else
                    260:                                ui->ui_ctlr = octlr;
                    261:                }
                    262:                break;
                    263:            }
                    264:        }
                    265:        /*
                    266:         * Now look for non-mass storage peripherals.
                    267:         */
                    268:        for (ui = vbdinit; udp = ui->ui_driver; ui++) {
                    269:                if (ui->ui_vbanum != vban && ui->ui_vbanum != '?' ||
                    270:                    ui->ui_alive || ui->ui_slave != -1)
                    271:                        continue;
                    272:                addr = (long)ui->ui_addr;
                    273:            for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
                    274:                if (VBIOMAPPED(addr)) {
                    275:                        if (VALLOC(addr))
                    276:                                continue;
                    277:                        reg = vbaddr(addr);
                    278:                } else
                    279:                        reg = (u_short *)addr;
                    280:                ui->ui_hd = vhp;
                    281:                cvec = SCB_LASTIV, cold &= ~0x2;
                    282:                i = (*udp->ud_probe)(reg, ui);
                    283:                cold |= 0x2;
                    284:                if (i == 0)
                    285:                        continue;
                    286:                printf("%s%d at vba%d csr %x ",
                    287:                    ui->ui_driver->ud_dname, ui->ui_unit, vban, addr);
                    288:                if (ui->ui_intr) {
                    289:                        if (cvec < 0 && vhp->vh_lastiv == cvec) {
                    290:                                printf("no space for vector(s)\n");
                    291:                                continue;
                    292:                        }
                    293:                        if (cvec == SCB_LASTIV) {
                    294:                                printf("didn't interrupt\n");
                    295:                                continue;
                    296:                        }
                    297:                        printf("vec %x, ipl %x\n", cvec, br);
                    298:                        for (ivec = ui->ui_intr; *ivec; ivec++)
                    299:                                ((long *)&scb)[cvec++] = (long)*ivec;
                    300:                } else
                    301:                        printf("no interrupts\n");
                    302:                csralloc(valloc, addr, i);
                    303:                ui->ui_alive = 1;
                    304:                ui->ui_vbanum = vban;
                    305:                if (VBIOMAPPED(addr))
                    306:                        ui->ui_addr = (caddr_t)reg;
                    307:                ui->ui_physaddr = (caddr_t)addr;
                    308:                ui->ui_dk = -1;
                    309:                /* ui_type comes from driver */
                    310:                udp->ud_dinfo[ui->ui_unit] = ui;
                    311:                (*udp->ud_attach)(ui);
                    312:                break;
                    313:            }
                    314:        }
                    315:        free(valloc, M_TEMP);
                    316: }
                    317: 
                    318: /*
                    319:  * Mark addresses starting at addr and continuing
                    320:  * size bytes as allocated in the map.
                    321:  * Warn if the new allocation overlaps a previous allocation.
                    322:  */
                    323: csralloc(valloc, addr, size)
                    324:        caddr_t valloc;
                    325:        long addr;
                    326:        register int size;
                    327: {
                    328:        register caddr_t p;
                    329:        int warned = 0;
                    330: 
                    331:        if (!VBIOMAPPED(addr))
                    332:                return;
                    333:        size = VSIZE(size);
                    334:        p = &VALLOC(addr) + size;
                    335:        while (--size >= 0) {
                    336:                if (*--p && !warned) {
                    337:                        printf(
                    338:        "WARNING: device registers overlap those for a previous device\n");
                    339:                        warned = 1;
                    340:                }
                    341:                *p = 1;
                    342:        }
                    343: }
                    344: 
                    345: /*
                    346:  * Tahoe VERSAbus adapator support routines.
                    347:  */
                    348: 
                    349: caddr_t        vbcur = (caddr_t)&vbbase;
                    350: int    vbx = 0;
                    351: /*
                    352:  * Allocate page tables for mapping intermediate i/o buffers.
                    353:  * Called by device drivers during autoconfigure.
                    354:  */
                    355: vbmapalloc(npf, ppte, putl)
                    356:        int npf;
                    357:        struct pte **ppte;
                    358:        caddr_t *putl;
                    359: {
                    360: 
                    361:        if (vbcur + npf*NBPG > (caddr_t)&vbend)
                    362:                return (0);
                    363:        *ppte = &VBmap[vbx];
                    364:        *putl = vbcur;
                    365:        vbx += npf;
                    366:        vbcur += npf*NBPG;
                    367:        return (1);
                    368: }
                    369: 
                    370: caddr_t        vbmcur = (caddr_t)&vmem1;
                    371: int    vbmx = 0;
                    372: /*
                    373:  * Allocate page tables and map VERSAbus i/o space.
                    374:  * Called by device drivers during autoconfigure.
                    375:  */
                    376: vbmemalloc(npf, addr, ppte, putl)
                    377:        int npf;
                    378:        caddr_t addr;
                    379:        struct pte **ppte;
                    380:        caddr_t *putl;
                    381: {
                    382: 
                    383:        if (vbmcur + npf*NBPG > (caddr_t)&vmemend)
                    384:                return (0);
                    385:        *ppte = &VMEMmap1[vbmx];
                    386:        *putl = vbmcur;
                    387:        vbmx += npf;
                    388:        vbmcur += npf*NBPG;
                    389:        vbaccess(*ppte, addr, npf);             /* map i/o space */
                    390:        return (1);
                    391: }
                    392: 
                    393: /*
                    394:  * Configure swap space and related parameters.
                    395:  */
                    396: swapconf()
                    397: {
                    398:        register struct swdevt *swp;
                    399:        register int nblks;
                    400: 
                    401:        for (swp = swdevt; swp->sw_dev; swp++)
                    402:                if (bdevsw[major(swp->sw_dev)].d_psize) {
                    403:                        nblks =
                    404:                          (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
                    405:                        if (nblks != -1 &&
                    406:                            (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
                    407:                                swp->sw_nblks = nblks;
                    408:                }
                    409:        dumpconf();
                    410: }
                    411: 
                    412: #define        DOSWAP                  /* change swdevt, argdev, and dumpdev too */
                    413: u_long bootdev;                /* should be dev_t, but not until 32 bits */
                    414: 
                    415: static char devname[][2] = {
                    416:        0,0,            /* 0 = ud */
                    417:        'd','k',        /* 1 = vd */
                    418:        0,0,            /* 2 = xp */
                    419: };
                    420: 
                    421: #define        PARTITIONMASK   0x7
                    422: #define        PARTITIONSHIFT  3
                    423: 
                    424: /*
                    425:  * Attempt to find the device from which we were booted.
                    426:  * If we can do so, and not instructed not to do so,
                    427:  * change rootdev to correspond to the load device.
                    428:  */
                    429: setroot()
                    430: {
                    431:        int  majdev, mindev, unit, part, controller, adaptor;
                    432:        dev_t temp, orootdev;
                    433:        struct swdevt *swp;
                    434: 
                    435:        if (boothowto & RB_DFLTROOT ||
                    436:            (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
                    437:                return;
                    438:        majdev = B_TYPE(bootdev);
                    439:        if (majdev >= sizeof(devname) / sizeof(devname[0]))
                    440:                return;
                    441:        adaptor = B_ADAPTOR(bootdev);
                    442:        controller = B_CONTROLLER(bootdev);
                    443:        part = B_PARTITION(bootdev);
                    444:        unit = B_UNIT(bootdev);
                    445:        /*
                    446:         * Search Versabus devices.
                    447:         *
                    448:         * WILL HAVE TO DISTINGUISH VME/VERSABUS SOMETIME
                    449:         */
                    450:        {
                    451:                register struct vba_device *vbap;
                    452: 
                    453:                for (vbap = vbdinit; vbap->ui_driver; vbap++)
                    454:                        if (vbap->ui_alive && vbap->ui_slave == unit &&
                    455:                           vbap->ui_ctlr == controller &&
                    456:                           vbap->ui_vbanum == adaptor &&
                    457:                           vbap->ui_driver->ud_dname[0] == devname[majdev][0] &&
                    458:                           vbap->ui_driver->ud_dname[1] == devname[majdev][1])
                    459:                                break;
                    460:                if (vbap->ui_driver == 0)
                    461:                        return;
                    462:                mindev = vbap->ui_unit;
                    463:        }
                    464:        mindev = (mindev << PARTITIONSHIFT) + part;
                    465:        orootdev = rootdev;
                    466:        rootdev = makedev(majdev, mindev);
                    467:        /*
                    468:         * If the original rootdev is the same as the one
                    469:         * just calculated, don't need to adjust the swap configuration.
                    470:         */
                    471:        if (rootdev == orootdev)
                    472:                return;
                    473:        printf("changing root device to %c%c%d%c\n",
                    474:                devname[majdev][0], devname[majdev][1],
                    475:                mindev >> PARTITIONSHIFT, part + 'a');
                    476: #ifdef DOSWAP
                    477:        mindev &= ~PARTITIONMASK;
                    478:        for (swp = swdevt; swp->sw_dev; swp++) {
                    479:                if (majdev == major(swp->sw_dev) &&
                    480:                    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
                    481:                        temp = swdevt[0].sw_dev;
                    482:                        swdevt[0].sw_dev = swp->sw_dev;
                    483:                        swp->sw_dev = temp;
                    484:                        break;
                    485:                }
                    486:        }
                    487:        if (swp->sw_dev == 0)
                    488:                return;
                    489:        /*
                    490:         * If argdev and dumpdev were the same as the old primary swap
                    491:         * device, move them to the new primary swap device.
                    492:         */
                    493:        if (temp == dumpdev)
                    494:                dumpdev = swdevt[0].sw_dev;
                    495:        if (temp == argdev)
                    496:                argdev = swdevt[0].sw_dev;
                    497: #endif
                    498: }

unix.superglobalmegacorp.com

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