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