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: }

Defined functions

configure defined in line 90; never used
fixctlrmask defined in line 497; used 2 times
ioaccess defined in line 834; used 5 times
mbaconfig defined in line 441; used 4 times
mbafind defined in line 381; used 1 times
probe_Abus defined in line 178; used 1 times
probeio defined in line 139; used 1 times
probenexi defined in line 219; used 2 times
setroot defined in line 901; used 2 times
setscbnex defined in line 819; used 2 times
swapconf defined in line 851; used 2 times
unifind defined in line 516; used 1 times

Defined variables

bootdev defined in line 873; used 7 times
cold defined in line 49; used 2 times
cpuspeed defined in line 53; used 1 times
devname defined in line 875; used 6 times
dkn defined in line 52; used 4 times
nexnum defined in line 50; used 16 times
nsbi defined in line 51; used 5 times
uba_hd defined in line 83; used 4 times

Defined macros

DOSWAP defined in line 872; used 1 times
PARTITIONMASK defined in line 893; used 2 times
PARTITIONSHIFT defined in line 894; used 2 times
PHYSADRSHFT defined in line 930; used 1 times
PHYSMBAMASK750 defined in line 932; used 1 times
PHYSMBAMASK780 defined in line 931; used 1 times
match defined in line 459; used 2 times
  • in line 460(2)
phys defined in line 502; used 4 times
qeq defined in line 409; used 2 times
ubaddr defined in line 638; used 2 times
ubaoff defined in line 637; used 4 times
Last modified: 1986-06-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3271
Valid CSS Valid XHTML 1.0 Strict