|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982,1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)autoconf.c 7.15 (Berkeley) 5/26/88 ! 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: #include "kra.h" /* XXX wrong file */ ! 21: ! 22: #include "param.h" ! 23: #include "systm.h" ! 24: #include "map.h" ! 25: #include "buf.h" ! 26: #include "dkstat.h" ! 27: #include "vm.h" ! 28: #include "malloc.h" ! 29: #include "conf.h" ! 30: #include "dmap.h" ! 31: #include "reboot.h" ! 32: ! 33: #include "pte.h" ! 34: #include "cpu.h" ! 35: #include "mem.h" ! 36: #include "mtpr.h" ! 37: #include "nexus.h" ! 38: #include "scb.h" ! 39: #include "ioa.h" ! 40: #include "../vaxbi/bireg.h" ! 41: #include "../vaxmba/mbareg.h" ! 42: #include "../vaxmba/mbavar.h" ! 43: #include "../vaxuba/ubareg.h" ! 44: #include "../vaxuba/ubavar.h" ! 45: ! 46: /* ! 47: * The following several variables are related to ! 48: * the configuration process, and are used in initializing ! 49: * the machine. ! 50: */ ! 51: int cold; /* if 1, still working on cold-start */ ! 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: * RIDICULOUS! CONFIG SHOULD GENERATE AN ioconf.h FOR US, with ! 61: * mba glue also in `glue.s'. (Unibus adapter glue is special, though.) ! 62: */ ! 63: #if NMBA > 0 ! 64: int (*mbaintv[4])() = { Xmba0int, Xmba1int, Xmba2int, Xmba3int }; ! 65: #if NMBA > 4 ! 66: Need to expand the table for more than 4 massbus adaptors ! 67: #endif ! 68: #endif ! 69: #if defined(VAX780) || defined(VAX8600) ! 70: int (*ubaintv[])() = ! 71: { ! 72: Xua0int, Xua1int, Xua2int, Xua3int, ! 73: #if NUBA > 4 ! 74: Xua4int, Xua5int, Xua6int, Xua7int, ! 75: #endif ! 76: #if NUBA > 8 ! 77: Need to expand the table for more than 8 unibus adaptors ! 78: #endif ! 79: }; ! 80: #endif ! 81: #if NKDB > 0 ! 82: /* kdb50 driver does not appear in udminit[] (not without csr!) */ ! 83: int Xkdbintr0(); /* generated by autoconf */ ! 84: int (*kdbintv[])() = { Xkdbintr0 }; ! 85: #if NKDB > 1 ! 86: Need to expand the table for more than 1 KDB adapter ! 87: #endif ! 88: #endif ! 89: ! 90: /* ! 91: * This allocates the space for the per-uba information, ! 92: * such as buffered data path usage. ! 93: */ ! 94: struct uba_hd uba_hd[NUBA]; ! 95: ! 96: /* ! 97: * Determine mass storage and memory configuration for a machine. ! 98: * Get cpu type, and then switch out to machine specific procedures ! 99: * which will probe adaptors to see what is out there. ! 100: */ ! 101: configure() ! 102: { ! 103: union cpusid cpusid; ! 104: register struct percpu *ocp; ! 105: register struct pte *ip; ! 106: ! 107: cpusid.cpusid = mfpr(SID); ! 108: switch (cpusid.cpuany.cp_type) { ! 109: #if VAX8600 ! 110: case VAX_8600: ! 111: printf("VAX 8600, serial# %d(%d), hardware ECO level %d(%d)\n", ! 112: cpusid.cpu780.cp_sno, cpusid.cpu780.cp_plant, ! 113: cpusid.cpu780.cp_eco >> 4, cpusid.cpu780.cp_eco); ! 114: break; ! 115: #endif ! 116: #if VAX8200 ! 117: case VAX_8200: ! 118: printf("\ ! 119: VAX 82%c0, hardware rev %d, ucode patch rev %d, sec patch %d, ucode rev %d\n", ! 120: cpusid.cpu8200.cp_5 ? '5' : '0', ! 121: cpusid.cpu8200.cp_hrev, cpusid.cpu8200.cp_patch, ! 122: cpusid.cpu8200.cp_secp, cpusid.cpu8200.cp_urev); ! 123: mastercpu = mfpr(BINID); ! 124: break; ! 125: #endif ! 126: #if VAX780 ! 127: case VAX_780: ! 128: printf("\ ! 129: VAX 11/78%c, serial# %d(%d), hardware ECO level %d(%d)\n", ! 130: cpusid.cpu780.cp_5 ? '5' : '0', ! 131: cpusid.cpu780.cp_sno, cpusid.cpu780.cp_plant, ! 132: cpusid.cpu780.cp_eco >> 4, cpusid.cpu780.cp_eco); ! 133: break; ! 134: #endif ! 135: #if VAX750 ! 136: case VAX_750: ! 137: printf("VAX 11/750, hardware rev %d, ucode rev %d\n", ! 138: cpusid.cpu750.cp_hrev, cpusid.cpu750.cp_urev); ! 139: break; ! 140: #endif ! 141: #if VAX730 ! 142: case VAX_730: ! 143: printf("VAX 11/730, ucode rev %d\n", cpusid.cpu730.cp_urev); ! 144: break; ! 145: #endif ! 146: #if VAX630 ! 147: case VAX_630: ! 148: printf("MicroVAX-II\n"); ! 149: break; ! 150: #endif ! 151: } ! 152: for (ocp = percpu; ocp->pc_cputype; ocp++) ! 153: if (ocp->pc_cputype == cpusid.cpuany.cp_type) { ! 154: cpuspeed = ocp->pc_cpuspeed; ! 155: cpuops = ocp->pc_ops; ! 156: if (cpuops->cpu_init != NULL) ! 157: (*cpuops->cpu_init)(); ! 158: probeio(ocp); ! 159: /* ! 160: * Write protect the scb and UNIBUS interrupt vectors. ! 161: * It is strange that this code is here, but this is ! 162: * as soon as we are done mucking with it, and the ! 163: * write-enable was done in assembly language ! 164: * to which we will never return. ! 165: */ ! 166: for (ip = kvtopte(scb); ip < kvtopte(eUNIvec); ip++) { ! 167: *(int *)ip &= ~PG_PROT; ! 168: *(int *)ip |= PG_KR; ! 169: } ! 170: mtpr(TBIA, 0); ! 171: #if GENERIC ! 172: if ((boothowto & RB_ASKNAME) == 0) ! 173: setroot(); ! 174: setconf(); ! 175: #else ! 176: setroot(); ! 177: #endif ! 178: /* ! 179: * Configure swap area and related system ! 180: * parameter based on device(s) used. ! 181: */ ! 182: swapconf(); ! 183: cold = 0; ! 184: memenable(); ! 185: return; ! 186: } ! 187: printf("cpu type %d not configured\n", cpusid.cpuany.cp_type); ! 188: asm("halt"); ! 189: } ! 190: ! 191: #if VAX8600 || VAX780 || VAX750 || VAX730 ! 192: int nexnum; /* current nexus number */ ! 193: int nsbi; /* current sbi number */ ! 194: #endif ! 195: #if VAX8200 ! 196: int numkdb; /* current ``kdb'' number */ ! 197: int bi_nodes; /* XXX remembers found bi nodes */ ! 198: #endif ! 199: ! 200: /* ! 201: * Probe the main IO bus(es). ! 202: * The percpu structure gives us a handle on the addresses and/or types. ! 203: */ ! 204: probeio(pcpu) ! 205: register struct percpu *pcpu; ! 206: { ! 207: register struct iobus *iob; ! 208: int ioanum; ! 209: ! 210: ioanum = 0; ! 211: for (iob = pcpu->pc_io; ioanum < pcpu->pc_nioa; ioanum++, iob++) { ! 212: ! 213: switch (iob->io_type) { ! 214: ! 215: #if VAX630 ! 216: case IO_QBUS: ! 217: probeqbus((struct qbus *)iob->io_details); ! 218: break; ! 219: #endif ! 220: ! 221: #if VAX780 || VAX750 || VAX730 ! 222: case IO_SBI780: ! 223: case IO_CMI750: ! 224: case IO_XXX730: ! 225: probenexi((struct nexusconnect *)iob->io_details); ! 226: break; ! 227: #endif ! 228: ! 229: #if VAX8600 ! 230: case IO_ABUS: ! 231: probe_Abus(ioanum, iob); ! 232: break; ! 233: #endif ! 234: ! 235: #if VAX8200 ! 236: case IO_BI: ! 237: probe_bi((struct bibus *)iob->io_details); ! 238: break; ! 239: #endif ! 240: ! 241: default: ! 242: if (iob->io_addr) { ! 243: printf( ! 244: "IO adaptor %d, type %d, at address 0x%x is unsupported\n", ! 245: ioanum, iob->io_type, iob->io_addr); ! 246: } else ! 247: printf("IO adaptor %d, type %d, is unsupported\n", ! 248: ioanum, iob->io_type); ! 249: break; ! 250: } ! 251: } ! 252: } ! 253: ! 254: #if VAX8600 ! 255: probe_Abus(ioanum, iob) ! 256: register struct iobus *iob; ! 257: { ! 258: register struct ioa *ioap; ! 259: union ioacsr ioacsr; ! 260: int type; ! 261: struct sbia_regs *sbiaregs; ! 262: #ifdef notyet ! 263: int sbi1fail(), sbi1alert(), sbi1fault(), sbi1err(); ! 264: #endif ! 265: ! 266: ioap = &ioa[ioanum]; ! 267: ioaccess(iob->io_addr, Ioamap[ioanum], iob->io_size); ! 268: if (badaddr((caddr_t)ioap, 4)) ! 269: return; ! 270: ioacsr.ioa_csr = ioap->ioacsr.ioa_csr; ! 271: type = ioacsr.ioa_type & IOA_TYPMSK; ! 272: ! 273: switch (type) { ! 274: ! 275: case IOA_SBIA: ! 276: printf("SBIA%d at IO adaptor %d address 0x%x\n", ! 277: nsbi, ioanum, iob->io_addr); ! 278: #ifdef notyet ! 279: /* I AM NOT SURE THESE ARE IN THE SAME PLACES */ ! 280: if (nscb == 1) { ! 281: scb[1].scb_sbifail = scbentry(sbi1fail, SCB_ISTACK); ! 282: /* maybe not sbifail, maybe scb1.scb_cmrd */ ! 283: /* but how can I find out without a broken SBIA1? */ ! 284: scb[1].scb_sbialert = scbentry(sbi1alert, SCB_ISTACK); ! 285: scb[1].scb_sbifault = scbentry(sbi1fault, SCB_ISTACK); ! 286: scb[1].scb_sbierr = scbentry(sbi1err, SCB_ISTACK); ! 287: } ! 288: #endif ! 289: probenexi((struct nexusconnect *)iob->io_details); ! 290: nsbi++; ! 291: sbiaregs = (struct sbia_regs *)ioap; ! 292: sbiaregs->sbi_errsum = -1; ! 293: sbiaregs->sbi_error = 0x1000; ! 294: sbiaregs->sbi_fltsts = 0xc0000; ! 295: break; ! 296: ! 297: default: ! 298: printf("IOA%d at address 0x%x is unsupported (type = 0x%x)\n", ! 299: ioanum, iob->io_addr, ioacsr.ioa_type); ! 300: break; ! 301: } ! 302: } ! 303: #endif ! 304: ! 305: #if VAX8600 || VAX780 || VAX750 || VAX730 ! 306: /* ! 307: * Probe nexus space, finding the interconnects ! 308: * and setting up and probing mba's and uba's for devices. ! 309: */ ! 310: probenexi(pnc) ! 311: register struct nexusconnect *pnc; ! 312: { ! 313: register struct nexus *nxv; ! 314: struct nexus *nxp = pnc->psb_nexbase; ! 315: union nexcsr nexcsr; ! 316: int i; ! 317: ! 318: ioaccess((caddr_t)nxp, Nexmap[nsbi * NNEXSBI], ! 319: pnc->psb_nnexus * sizeof(struct nexus)); ! 320: nxv = &nexus[nsbi * NNEXSBI]; ! 321: for (nexnum = 0; nexnum < pnc->psb_nnexus; nexnum++, nxp++, nxv++) { ! 322: if (badaddr((caddr_t)nxv, 4)) ! 323: continue; ! 324: if (pnc->psb_nextype && pnc->psb_nextype[nexnum] != NEX_ANY) ! 325: nexcsr.nex_csr = pnc->psb_nextype[nexnum]; ! 326: else ! 327: nexcsr = nxv->nexcsr; ! 328: if (nexcsr.nex_csr&NEX_APD) ! 329: continue; ! 330: switch (nexcsr.nex_type) { ! 331: ! 332: case NEX_MBA: ! 333: printf("mba%d at tr%d\n", nummba, nexnum); ! 334: if (nummba >= NMBA) { ! 335: printf("%d mba's", ++nummba); ! 336: goto unconfig; ! 337: } ! 338: #if NMBA > 0 ! 339: mbafind(nxv, nxp); ! 340: nummba++; ! 341: #endif ! 342: break; ! 343: ! 344: case NEX_UBA0: ! 345: case NEX_UBA1: ! 346: case NEX_UBA2: ! 347: case NEX_UBA3: ! 348: printf("uba%d at tr%d\n", numuba, nexnum); ! 349: if (numuba >= NUBA) { ! 350: printf("%d uba's", ++numuba); ! 351: goto unconfig; ! 352: } ! 353: #if NUBA > 0 ! 354: #if VAX750 ! 355: if (numuba >= 2 && cpu == VAX_750) { ! 356: printf("More than 2 UBA's"); ! 357: goto unsupp; ! 358: } ! 359: #endif ! 360: #if defined(VAX780) || defined(VAX8600) ! 361: if (cpu == VAX_780 || cpu == VAX_8600) ! 362: setscbnex(ubaintv[numuba]); ! 363: #endif ! 364: i = nexcsr.nex_type - NEX_UBA0; ! 365: probeuba((struct uba_regs *)nxv, (struct uba_regs *)nxp, ! 366: pnc->psb_umaddr[i]); ! 367: #endif /* NUBA */ ! 368: break; ! 369: ! 370: case NEX_DR32: ! 371: /* there can be more than one... are there other codes??? */ ! 372: printf("dr32"); ! 373: goto unsupp; ! 374: ! 375: case NEX_MEM4: ! 376: case NEX_MEM4I: ! 377: case NEX_MEM16: ! 378: case NEX_MEM16I: ! 379: printf("mcr%d at tr%d\n", nmcr, nexnum); ! 380: if (nmcr >= MAXNMCR) { ! 381: printf("%d mcr's", ++nmcr); ! 382: goto unconfig; ! 383: } ! 384: switch (cpu) { ! 385: #if VAX780 ! 386: case VAX_780: ! 387: /* only ka780 code looks at type */ ! 388: mcrtype[nmcr] = M780C; ! 389: break; ! 390: #endif ! 391: default: ! 392: break; ! 393: } ! 394: mcraddr[nmcr++] = (caddr_t)nxv; ! 395: break; ! 396: ! 397: #if VAX780 ! 398: case NEX_MEM64I: ! 399: case NEX_MEM64L: ! 400: case NEX_MEM64LI: ! 401: case NEX_MEM256I: ! 402: case NEX_MEM256L: ! 403: case NEX_MEM256LI: ! 404: printf("mcr%d (el) at tr%d\n", nmcr, nexnum); ! 405: if (nmcr >= MAXNMCR) { ! 406: printf("%d mcr's", ++nmcr); ! 407: goto unconfig; ! 408: } ! 409: mcrtype[nmcr] = M780EL; ! 410: mcraddr[nmcr++] = (caddr_t)nxv; ! 411: if (nexcsr.nex_type != NEX_MEM64I && ! 412: nexcsr.nex_type != NEX_MEM256I) ! 413: break; ! 414: /* fall into ... */ ! 415: ! 416: case NEX_MEM64U: ! 417: case NEX_MEM64UI: ! 418: case NEX_MEM256U: ! 419: case NEX_MEM256UI: ! 420: printf("mcr%d (eu) at tr%d\n", nmcr, nexnum); ! 421: if (nmcr >= MAXNMCR) { ! 422: printf("%d mcr's", ++nmcr); ! 423: goto unconfig; ! 424: } ! 425: mcrtype[nmcr] = M780EU; ! 426: mcraddr[nmcr++] = (caddr_t)nxv; ! 427: break; ! 428: #endif ! 429: ! 430: case NEX_MPM0: ! 431: case NEX_MPM1: ! 432: case NEX_MPM2: ! 433: case NEX_MPM3: ! 434: printf("mpm"); ! 435: goto unsupp; ! 436: ! 437: case NEX_CI: ! 438: printf("ci"); ! 439: goto unsupp; ! 440: ! 441: default: ! 442: printf("nexus type %x", nexcsr.nex_type); ! 443: unsupp: ! 444: printf(" unsupported (at tr %d)\n", nexnum); ! 445: continue; ! 446: unconfig: ! 447: printf(" not configured\n"); ! 448: continue; ! 449: } ! 450: } ! 451: if (nummba > NMBA) ! 452: nummba = NMBA; ! 453: if (numuba > NUBA) ! 454: numuba = NUBA; ! 455: if (nmcr > MAXNMCR) ! 456: nmcr = MAXNMCR; ! 457: } ! 458: ! 459: setscbnex(fn) ! 460: int (*fn)(); ! 461: { ! 462: register struct scb *scbp = &scb[nsbi]; ! 463: ! 464: scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] = ! 465: scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] = ! 466: scbentry(fn, SCB_ISTACK); ! 467: } ! 468: #endif ! 469: ! 470: #include "bi.h" ! 471: #if NBI > 0 ! 472: /* ! 473: * Probe BI node space. ! 474: * ! 475: * THIS DEPENDS ON BI SPACE == NEXUS SPACE ! 476: * THIS WILL NOT WORK FOR MULTIPLE BIs ! 477: */ ! 478: probe_bi(p) ! 479: register struct bibus *p; ! 480: { ! 481: register struct bi_node *biv, *bip; ! 482: register int node; ! 483: short dtype; ! 484: ! 485: /* must ignore BI errors while configuring */ ! 486: bip = p->pbi_base; ! 487: ioaccess((caddr_t)bip, Nexmap[0], sizeof(*bip) * NNODEBI);/* XXX */ ! 488: printf("vaxbi0 at address 0x%x\n", bip); ! 489: biv = (struct bi_node *) &nexus[0]; /* XXX */ ! 490: for (node = 0; node < NNODEBI; node++, bip++, biv++) { ! 491: if (badaddr((caddr_t)biv, 4)) ! 492: continue; ! 493: bi_nodes |= 1 << node; /* XXX */ ! 494: dtype = biv->biic.bi_dtype; ! 495: /* clear bus errors */ ! 496: biv->biic.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN); ! 497: switch (dtype) { ! 498: ! 499: case BIDT_KA820: { ! 500: /* is this right?? */ ! 501: int cp5 = biv->biic.bi_revs & 0x8000 ? '5' : '0'; ! 502: ! 503: if (node != mastercpu) { ! 504: printf("slave ka82%c cpu", cp5); ! 505: goto unsupp; ! 506: } ! 507: printf("ka82%c cpu at node %x\n", cp5, node); ! 508: biv->biic.bi_intrdes = 1 << mastercpu; ! 509: biv->biic.bi_csr |= BICSR_SEIE | BICSR_HEIE; ! 510: break; ! 511: } ! 512: ! 513: case BIDT_DWBUA: ! 514: if (numuba >= NUBA || /*XXX*/numuba > 2) { ! 515: printf("%d uba's", ++numuba); ! 516: goto unconfig; ! 517: } ! 518: #if NUBA > 0 ! 519: printf("uba%d at node %x\n", numuba, node); ! 520: ! 521: /* ! 522: * Run a self test reset to drop any `old' errors, ! 523: * so that they cannot cause a BI bus error. ! 524: */ ! 525: (void) bi_selftest(&biv->biic); ! 526: ! 527: /* ! 528: * Enable interrupts. DWBUAs must have ! 529: * high priority. ! 530: */ ! 531: biv->biic.bi_intrdes = 1 << mastercpu; ! 532: biv->biic.bi_csr = (biv->biic.bi_csr&~BICSR_ARB_MASK) | ! 533: BICSR_ARB_HIGH; ! 534: probeuba((struct uba_regs *)biv, (struct uba_regs *)bip, ! 535: (caddr_t)UMEM8200(node)); ! 536: #endif /* NUBA */ ! 537: break; ! 538: ! 539: case BIDT_MS820: ! 540: printf("mcr%d at node %x\n", nmcr, node); ! 541: if (nmcr >= MAXNMCR) { ! 542: printf("%d mcr's", ++nmcr); ! 543: goto unconfig; ! 544: } ! 545: mcraddr[nmcr++] = (caddr_t)biv; ! 546: biv->biic.bi_intrdes = 1 << mastercpu; ! 547: biv->biic.bi_csr |= BICSR_SEIE | BICSR_HEIE; ! 548: break; ! 549: ! 550: case BIDT_KDB50: ! 551: if (numkdb >= NKDB) { ! 552: printf("%d kdb's", ++numkdb); ! 553: goto unconfig; ! 554: } ! 555: #if NKDB > 0 ! 556: printf("kdb%d at node %x\n", numkdb, node); ! 557: kdbconfig(numkdb, (struct biiregs *)biv, ! 558: (struct biiregs *)bip, ! 559: (int)&scb[0].scb_ipl15[node] - (int)&scb[0]); ! 560: scb[0].scb_ipl15[node] = ! 561: scbentry(kdbintv[numkdb], SCB_ISTACK); ! 562: kdbfind(numkdb); ! 563: #endif ! 564: numkdb++; ! 565: break; ! 566: ! 567: case BIDT_DEBNA: ! 568: case BIDT_DEBNK: ! 569: printf("debna/debnk ethernet"); ! 570: goto unsupp; ! 571: ! 572: default: ! 573: printf("node type 0x%x ", dtype); ! 574: unsupp: ! 575: printf(" unsupported (at node %x)\n", node); ! 576: break; ! 577: unconfig: ! 578: printf(" not configured (at node %x)\n", node); ! 579: continue; ! 580: } ! 581: #ifdef DO_EINTRCSR ! 582: biv->biic.bi_eintrcsr = BIEIC_IPL17 | ! 583: (int)&scb[0].scb_bierr - (int)&scb[0]; ! 584: /* but bi reset will need to restore this */ ! 585: #endif ! 586: } ! 587: if (numuba > NUBA) ! 588: numuba = NUBA; ! 589: if (numkdb > NKDB) ! 590: numkdb = NKDB; ! 591: if (nmcr > MAXNMCR) ! 592: nmcr = MAXNMCR; ! 593: } ! 594: ! 595: #if NKDB > 0 ! 596: /* ! 597: * Find drives attached to a particular KDB50. ! 598: */ ! 599: kdbfind(kdbnum) ! 600: int kdbnum; ! 601: { ! 602: extern struct uba_driver kdbdriver; ! 603: register struct uba_device *ui; ! 604: register struct uba_driver *udp = &kdbdriver; ! 605: int t; ! 606: ! 607: for (ui = ubdinit; ui->ui_driver; ui++) { ! 608: /* ui->ui_ubanum is trash */ ! 609: if (ui->ui_driver != udp || ui->ui_alive || ! 610: ui->ui_ctlr != kdbnum && ui->ui_ctlr != '?') ! 611: continue; ! 612: t = ui->ui_ctlr; ! 613: ui->ui_ctlr = kdbnum; ! 614: if ((*udp->ud_slave)(ui) == 0) { ! 615: ui->ui_ctlr = t; ! 616: continue; ! 617: } ! 618: ui->ui_alive = 1; ! 619: ui->ui_ubanum = -1; ! 620: ! 621: /* make these invalid so we can see if someone uses them */ ! 622: /* might as well make each one different too */ ! 623: ui->ui_hd = (struct uba_hd *)0xc0000010; ! 624: ui->ui_addr = (caddr_t)0xc0000014; ! 625: ui->ui_physaddr = (caddr_t)0xc0000018; ! 626: ui->ui_mi = (struct uba_ctlr *)0xc000001c; ! 627: ! 628: if (ui->ui_dk && dkn < DK_NDRIVE) ! 629: ui->ui_dk = dkn++; ! 630: else ! 631: ui->ui_dk = -1; ! 632: /* ui_type comes from driver */ ! 633: udp->ud_dinfo[ui->ui_unit] = ui; ! 634: printf("%s%d at %s%d slave %d\n", ! 635: udp->ud_dname, ui->ui_unit, ! 636: udp->ud_mname, ui->ui_ctlr, ui->ui_slave); ! 637: (*udp->ud_attach)(ui); ! 638: } ! 639: } ! 640: #endif /* NKDB > 0 */ ! 641: #endif /* NBI > 0 */ ! 642: ! 643: #if NMBA > 0 ! 644: struct mba_device *mbaconfig(); ! 645: /* ! 646: * Find devices attached to a particular mba ! 647: * and look for each device found in the massbus ! 648: * initialization tables. ! 649: */ ! 650: mbafind(nxv, nxp) ! 651: struct nexus *nxv, *nxp; ! 652: { ! 653: register struct mba_regs *mdp; ! 654: register struct mba_drv *mbd; ! 655: register struct mba_device *mi; ! 656: register struct mba_slave *ms; ! 657: int dn, dt, sn; ! 658: struct mba_device fnd; ! 659: ! 660: mdp = (struct mba_regs *)nxv; ! 661: mba_hd[nummba].mh_mba = mdp; ! 662: mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp; ! 663: setscbnex(mbaintv[nummba]); ! 664: mdp->mba_cr = MBCR_INIT; ! 665: mdp->mba_cr = MBCR_IE; ! 666: fnd.mi_mba = mdp; ! 667: fnd.mi_mbanum = nummba; ! 668: for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) { ! 669: if ((mbd->mbd_ds&MBDS_DPR) == 0) ! 670: continue; ! 671: mdp->mba_sr |= MBSR_NED; /* si kludge */ ! 672: dt = mbd->mbd_dt & 0xffff; ! 673: if (dt == 0) ! 674: continue; ! 675: if (mdp->mba_sr&MBSR_NED) ! 676: continue; /* si kludge */ ! 677: if (dt == MBDT_MOH) ! 678: continue; ! 679: fnd.mi_drive = dn; ! 680: #define qeq(a, b) ( a == b || a == '?' ) ! 681: if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP)) ! 682: for (sn = 0; sn < 8; sn++) { ! 683: mbd->mbd_tc = sn; ! 684: for (ms = mbsinit; ms->ms_driver; ms++) ! 685: if (ms->ms_driver == mi->mi_driver && ! 686: ms->ms_alive == 0 && ! 687: qeq(ms->ms_ctlr, mi->mi_unit) && ! 688: qeq(ms->ms_slave, sn) && ! 689: (*ms->ms_driver->md_slave)(mi, ms, sn)) { ! 690: printf("%s%d at %s%d slave %d\n" ! 691: , ms->ms_driver->md_sname ! 692: , ms->ms_unit ! 693: , mi->mi_driver->md_dname ! 694: , mi->mi_unit ! 695: , sn ! 696: ); ! 697: ms->ms_alive = 1; ! 698: ms->ms_ctlr = mi->mi_unit; ! 699: ms->ms_slave = sn; ! 700: break; ! 701: } ! 702: } ! 703: } ! 704: } ! 705: ! 706: /* ! 707: * Have found a massbus device; ! 708: * see if it is in the configuration table. ! 709: * If so, fill in its data. ! 710: */ ! 711: struct mba_device * ! 712: mbaconfig(ni, type) ! 713: register struct mba_device *ni; ! 714: register int type; ! 715: { ! 716: register struct mba_device *mi; ! 717: register short *tp; ! 718: register struct mba_hd *mh; ! 719: ! 720: for (mi = mbdinit; mi->mi_driver; mi++) { ! 721: if (mi->mi_alive) ! 722: continue; ! 723: tp = mi->mi_driver->md_type; ! 724: for (mi->mi_type = 0; *tp; tp++, mi->mi_type++) ! 725: if (*tp == (type&MBDT_TYPE)) ! 726: goto found; ! 727: continue; ! 728: found: ! 729: #define match(fld) (ni->fld == mi->fld || mi->fld == '?') ! 730: if (!match(mi_drive) || !match(mi_mbanum)) ! 731: continue; ! 732: printf("%s%d at mba%d drive %d", ! 733: mi->mi_driver->md_dname, mi->mi_unit, ! 734: ni->mi_mbanum, ni->mi_drive); ! 735: mi->mi_alive = 1; ! 736: mh = &mba_hd[ni->mi_mbanum]; ! 737: mi->mi_hd = mh; ! 738: mh->mh_mbip[ni->mi_drive] = mi; ! 739: mh->mh_ndrive++; ! 740: mi->mi_mba = ni->mi_mba; ! 741: mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive]; ! 742: mi->mi_mbanum = ni->mi_mbanum; ! 743: mi->mi_drive = ni->mi_drive; ! 744: /* ! 745: * If drive has never been seen before, ! 746: * give it a dkn for statistics. ! 747: */ ! 748: if (mi->mi_driver->md_info[mi->mi_unit] == 0) { ! 749: mi->mi_driver->md_info[mi->mi_unit] = mi; ! 750: if (mi->mi_dk && dkn < DK_NDRIVE) ! 751: mi->mi_dk = dkn++; ! 752: else ! 753: mi->mi_dk = -1; ! 754: } ! 755: (*mi->mi_driver->md_attach)(mi); ! 756: printf("\n"); ! 757: return (mi); ! 758: } ! 759: return (0); ! 760: } ! 761: #endif ! 762: ! 763: /* ! 764: * Fixctlrmask fixes the masks of the driver ctlr routines ! 765: * which otherwise save r10 and r11 where the interrupt and br ! 766: * level are passed through. ! 767: */ ! 768: fixctlrmask() ! 769: { ! 770: register struct uba_ctlr *um; ! 771: register struct uba_device *ui; ! 772: register struct uba_driver *ud; ! 773: #define phys(a,b) ((b)(((int)(a))&0x7fffffff)) ! 774: ! 775: for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++) ! 776: *phys(ud->ud_probe, short *) &= ~0xc00; ! 777: for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++) ! 778: *phys(ud->ud_probe, short *) &= ~0xc00; ! 779: } ! 780: ! 781: #ifdef QBA ! 782: /* ! 783: * Configure a Q-bus. ! 784: */ ! 785: probeqbus(qb) ! 786: struct qbus *qb; ! 787: { ! 788: register struct uba_hd *uhp = &uba_hd[numuba]; ! 789: ! 790: ioaccess((caddr_t)qb->qb_map, Nexmap[0], ! 791: qb->qb_memsize * sizeof (struct pte)); ! 792: uhp->uh_type = qb->qb_type; ! 793: uhp->uh_uba = (struct uba_regs *)0xc0000000; /* no uba adaptor regs */ ! 794: uhp->uh_mr = (struct pte *)&nexus[0]; ! 795: /* ! 796: * The map registers start right at 20088000 on the ! 797: * ka630, so we have to subtract out the 2k offset to make the ! 798: * pointers work.. ! 799: */ ! 800: uhp->uh_physuba = (struct uba_regs *)(((u_long)qb->qb_map)-0x800); ! 801: ! 802: uhp->uh_memsize = qb->qb_memsize; ! 803: ioaccess(qb->qb_maddr, UMEMmap[numuba], uhp->uh_memsize * NBPG); ! 804: uhp->uh_mem = umem[numuba]; ! 805: ! 806: /* ! 807: * The I/O page is mapped to the 8K of the umem address space ! 808: * immediately after the memory section that is mapped. ! 809: */ ! 810: ioaccess(qb->qb_iopage, UMEMmap[numuba] + uhp->uh_memsize, ! 811: UBAIOPAGES * NBPG); ! 812: uhp->uh_iopage = umem[numuba] + (uhp->uh_memsize * NBPG); ! 813: ! 814: unifind(uhp, qb->qb_iopage); ! 815: } ! 816: #endif ! 817: ! 818: #if NUBA > 0 ! 819: probeuba(vubp, pubp, pumem) ! 820: struct uba_regs *vubp, *pubp; ! 821: caddr_t pumem; ! 822: { ! 823: register struct uba_hd *uhp = &uba_hd[numuba]; ! 824: ! 825: /* ! 826: * Save virtual and physical addresses of adaptor. ! 827: */ ! 828: switch (cpu) { ! 829: #ifdef DW780 ! 830: case VAX_8600: ! 831: case VAX_780: ! 832: uhp->uh_type = DW780; ! 833: break; ! 834: #endif ! 835: #ifdef DW750 ! 836: case VAX_750: ! 837: uhp->uh_type = DW750; ! 838: break; ! 839: #endif ! 840: #ifdef DW730 ! 841: case VAX_730: ! 842: uhp->uh_type = DW730; ! 843: break; ! 844: #endif ! 845: #ifdef DWBUA ! 846: case VAX_8200: ! 847: uhp->uh_type = DWBUA; ! 848: break; ! 849: #endif ! 850: default: ! 851: panic("unknown UBA type"); ! 852: /*NOTREACHED*/ ! 853: } ! 854: uhp->uh_uba = vubp; ! 855: uhp->uh_physuba = pubp; ! 856: uhp->uh_mr = vubp->uba_map; ! 857: uhp->uh_memsize = UBAPAGES; ! 858: ! 859: ioaccess(pumem, UMEMmap[numuba], (UBAPAGES + UBAIOPAGES) * NBPG); ! 860: uhp->uh_mem = umem[numuba]; ! 861: uhp->uh_iopage = umem[numuba] + (uhp->uh_memsize * NBPG); ! 862: ! 863: unifind(uhp, pumem + (uhp->uh_memsize * NBPG)); ! 864: } ! 865: ! 866: /* ! 867: * Find devices on a UNIBUS. ! 868: * Uses per-driver routine to set <br,cvec> into <r11,r10>, ! 869: * and then fills in the tables, with help from a per-driver ! 870: * slave initialization routine. ! 871: */ ! 872: unifind(uhp0, pumem) ! 873: struct uba_hd *uhp0; ! 874: caddr_t pumem; ! 875: { ! 876: #ifndef lint ! 877: register int br, cvec; /* MUST BE r11, r10 */ ! 878: #else ! 879: /* ! 880: * Lint doesn't realize that these ! 881: * can be initialized asynchronously ! 882: * when devices interrupt. ! 883: */ ! 884: register int br = 0, cvec = 0; ! 885: #endif ! 886: register struct uba_device *ui; ! 887: register struct uba_ctlr *um; ! 888: register struct uba_hd *uhp = uhp0; ! 889: u_short *reg, *ap, addr; ! 890: struct uba_driver *udp; ! 891: int i, (**ivec)(); ! 892: caddr_t ualloc; ! 893: extern quad catcher[128]; ! 894: #if DW780 || DWBUA ! 895: struct uba_regs *vubp = uhp->uh_uba; ! 896: #endif ! 897: ! 898: /* ! 899: * Initialize the UNIBUS, by freeing the map ! 900: * registers and the buffered data path registers ! 901: */ ! 902: uhp->uh_map = (struct map *) ! 903: malloc((u_long)(UAMSIZ * sizeof (struct map)), M_DEVBUF, ! 904: M_NOWAIT); ! 905: if (uhp->uh_map == 0) ! 906: panic("no mem for unibus map"); ! 907: bzero((caddr_t)uhp->uh_map, (unsigned)(UAMSIZ * sizeof (struct map))); ! 908: ubainitmaps(uhp); ! 909: ! 910: /* ! 911: * Initialize space for the UNIBUS interrupt vectors. ! 912: * On the 8600, can't use first slot in UNIvec ! 913: * (the vectors for the second SBI overlap it); ! 914: * move each set of vectors forward. ! 915: */ ! 916: #if VAX8600 ! 917: if (cpu == VAX_8600) ! 918: uhp->uh_vec = UNIvec[numuba + 1]; ! 919: else ! 920: #endif ! 921: uhp->uh_vec = UNIvec[numuba]; ! 922: for (i = 0; i < 128; i++) ! 923: uhp->uh_vec[i] = scbentry(&catcher[i], SCB_ISTACK); ! 924: /* ! 925: * Set last free interrupt vector for devices with ! 926: * programmable interrupt vectors. Use is to decrement ! 927: * this number and use result as interrupt vector. ! 928: */ ! 929: uhp->uh_lastiv = 0x200; ! 930: ! 931: #ifdef DWBUA ! 932: if (uhp->uh_type == DWBUA) ! 933: BUA(vubp)->bua_offset = (int)uhp->uh_vec - (int)&scb[0]; ! 934: #endif ! 935: ! 936: #ifdef DW780 ! 937: if (uhp->uh_type == DW780) { ! 938: vubp->uba_sr = vubp->uba_sr; ! 939: vubp->uba_cr = UBACR_IFS|UBACR_BRIE; ! 940: } ! 941: #endif ! 942: /* ! 943: * First configure devices that have unibus memory, ! 944: * allowing them to allocate the correct map registers. ! 945: */ ! 946: ubameminit(numuba); ! 947: /* ! 948: * Grab some memory to record the umem address space we allocate, ! 949: * so we can be sure not to place two devices at the same address. ! 950: * ! 951: * We could use just 1/8 of this (we only want a 1 bit flag) but ! 952: * we are going to give it back anyway, and that would make the ! 953: * code here bigger (which we can't give back), so ... ! 954: * ! 955: * One day, someone will make a unibus with something other than ! 956: * an 8K i/o address space, & screw this totally. ! 957: */ ! 958: ualloc = (caddr_t)malloc((u_long)(8 * 1024), M_TEMP, M_NOWAIT); ! 959: if (ualloc == (caddr_t)0) ! 960: panic("no mem for unifind"); ! 961: bzero(ualloc, 8*1024); ! 962: ! 963: /* ! 964: * Map the first page of UNIBUS i/o ! 965: * space to the first page of memory ! 966: * for devices which will need to dma ! 967: * output to produce an interrupt. ! 968: */ ! 969: *(int *)(&uhp->uh_mr[0]) = UBAMR_MRV; ! 970: ! 971: #define ubaddr(uhp, off) (u_short *)((int)(uhp)->uh_iopage + ubdevreg(off)) ! 972: /* ! 973: * Check each unibus mass storage controller. ! 974: * For each one which is potentially on this uba, ! 975: * see if it is really there, and if it is record it and ! 976: * then go looking for slaves. ! 977: */ ! 978: for (um = ubminit; udp = um->um_driver; um++) { ! 979: if (um->um_ubanum != numuba && um->um_ubanum != '?' || ! 980: um->um_alive) ! 981: continue; ! 982: addr = (u_short)um->um_addr; ! 983: /* ! 984: * use the particular address specified first, ! 985: * or if it is given as "0", of there is no device ! 986: * at that address, try all the standard addresses ! 987: * in the driver til we find it ! 988: */ ! 989: for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { ! 990: ! 991: if (ualloc[ubdevreg(addr)]) ! 992: continue; ! 993: reg = ubaddr(uhp, addr); ! 994: if (badaddr((caddr_t)reg, 2)) ! 995: continue; ! 996: #ifdef DW780 ! 997: if (uhp->uh_type == DW780 && vubp->uba_sr) { ! 998: vubp->uba_sr = vubp->uba_sr; ! 999: continue; ! 1000: } ! 1001: #endif ! 1002: cvec = 0x200; ! 1003: i = (*udp->ud_probe)(reg, um->um_ctlr, um); ! 1004: #ifdef DW780 ! 1005: if (uhp->uh_type == DW780 && vubp->uba_sr) { ! 1006: vubp->uba_sr = vubp->uba_sr; ! 1007: continue; ! 1008: } ! 1009: #endif ! 1010: if (i == 0) ! 1011: continue; ! 1012: printf("%s%d at uba%d csr %o ", ! 1013: udp->ud_mname, um->um_ctlr, numuba, addr); ! 1014: if (cvec == 0) { ! 1015: printf("zero vector\n"); ! 1016: continue; ! 1017: } ! 1018: if (cvec == 0x200) { ! 1019: printf("didn't interrupt\n"); ! 1020: continue; ! 1021: } ! 1022: printf("vec %o, ipl %x\n", cvec, br); ! 1023: csralloc(ualloc, addr, i); ! 1024: um->um_alive = 1; ! 1025: um->um_ubanum = numuba; ! 1026: um->um_hd = uhp; ! 1027: um->um_addr = (caddr_t)reg; ! 1028: udp->ud_minfo[um->um_ctlr] = um; ! 1029: for (cvec /= 4, ivec = um->um_intr; *ivec; cvec++, ivec++) ! 1030: uhp->uh_vec[cvec] = scbentry(*ivec, SCB_ISTACK); ! 1031: for (ui = ubdinit; ui->ui_driver; ui++) { ! 1032: int t; ! 1033: ! 1034: if (ui->ui_driver != udp || ui->ui_alive || ! 1035: ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' || ! 1036: ui->ui_ubanum != numuba && ui->ui_ubanum != '?') ! 1037: continue; ! 1038: t = ui->ui_ctlr; ! 1039: ui->ui_ctlr = um->um_ctlr; ! 1040: if ((*udp->ud_slave)(ui, reg) == 0) ! 1041: ui->ui_ctlr = t; ! 1042: else { ! 1043: ui->ui_alive = 1; ! 1044: ui->ui_ubanum = numuba; ! 1045: ui->ui_hd = uhp; ! 1046: ui->ui_addr = (caddr_t)reg; ! 1047: ui->ui_physaddr = pumem + ubdevreg(addr); ! 1048: if (ui->ui_dk && dkn < DK_NDRIVE) ! 1049: ui->ui_dk = dkn++; ! 1050: else ! 1051: ui->ui_dk = -1; ! 1052: ui->ui_mi = um; ! 1053: /* ui_type comes from driver */ ! 1054: udp->ud_dinfo[ui->ui_unit] = ui; ! 1055: printf("%s%d at %s%d slave %d", ! 1056: udp->ud_dname, ui->ui_unit, ! 1057: udp->ud_mname, um->um_ctlr, ui->ui_slave); ! 1058: (*udp->ud_attach)(ui); ! 1059: printf("\n"); ! 1060: } ! 1061: } ! 1062: break; ! 1063: } ! 1064: } ! 1065: /* ! 1066: * Now look for non-mass storage peripherals. ! 1067: */ ! 1068: for (ui = ubdinit; udp = ui->ui_driver; ui++) { ! 1069: if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' || ! 1070: ui->ui_alive || ui->ui_slave != -1) ! 1071: continue; ! 1072: addr = (u_short)ui->ui_addr; ! 1073: ! 1074: for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { ! 1075: ! 1076: if (ualloc[ubdevreg(addr)]) ! 1077: continue; ! 1078: reg = ubaddr(uhp, addr); ! 1079: if (badaddr((caddr_t)reg, 2)) ! 1080: continue; ! 1081: #ifdef DW780 ! 1082: if (uhp->uh_type == DW780 && vubp->uba_sr) { ! 1083: vubp->uba_sr = vubp->uba_sr; ! 1084: continue; ! 1085: } ! 1086: #endif ! 1087: cvec = 0x200; ! 1088: i = (*udp->ud_probe)(reg, ui); ! 1089: #ifdef DW780 ! 1090: if (uhp->uh_type == DW780 && vubp->uba_sr) { ! 1091: vubp->uba_sr = vubp->uba_sr; ! 1092: continue; ! 1093: } ! 1094: #endif ! 1095: if (i == 0) ! 1096: continue; ! 1097: printf("%s%d at uba%d csr %o ", ! 1098: ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr); ! 1099: if (cvec == 0) { ! 1100: printf("zero vector\n"); ! 1101: continue; ! 1102: } ! 1103: if (cvec == 0x200) { ! 1104: printf("didn't interrupt\n"); ! 1105: continue; ! 1106: } ! 1107: printf("vec %o, ipl %x\n", cvec, br); ! 1108: csralloc(ualloc, addr, i); ! 1109: ui->ui_hd = uhp; ! 1110: for (cvec /= 4, ivec = ui->ui_intr; *ivec; cvec++, ivec++) ! 1111: uhp->uh_vec[cvec] = scbentry(*ivec, SCB_ISTACK); ! 1112: ui->ui_alive = 1; ! 1113: ui->ui_ubanum = numuba; ! 1114: ui->ui_addr = (caddr_t)reg; ! 1115: ui->ui_physaddr = pumem + ubdevreg(addr); ! 1116: ui->ui_dk = -1; ! 1117: /* ui_type comes from driver */ ! 1118: udp->ud_dinfo[ui->ui_unit] = ui; ! 1119: (*udp->ud_attach)(ui); ! 1120: break; ! 1121: } ! 1122: } ! 1123: ! 1124: #ifdef DW780 ! 1125: if (uhp->uh_type == DW780) ! 1126: uhp->uh_uba->uba_cr = UBACR_IFS | UBACR_BRIE | ! 1127: UBACR_USEFIE | UBACR_SUEFIE | ! 1128: (uhp->uh_uba->uba_cr & 0x7c000000); ! 1129: #endif ! 1130: numuba++; ! 1131: ! 1132: #ifdef AUTO_DEBUG ! 1133: printf("Unibus allocation map"); ! 1134: for (i = 0; i < 8*1024; ) { ! 1135: register n, m; ! 1136: ! 1137: if ((i % 128) == 0) { ! 1138: printf("\n%6o:", i); ! 1139: for (n = 0; n < 128; n++) ! 1140: if (ualloc[i+n]) ! 1141: break; ! 1142: if (n == 128) { ! 1143: i += 128; ! 1144: continue; ! 1145: } ! 1146: } ! 1147: ! 1148: for (n = m = 0; n < 16; n++) { ! 1149: m <<= 1; ! 1150: m |= ualloc[i++]; ! 1151: } ! 1152: ! 1153: printf(" %4x", m); ! 1154: } ! 1155: printf("\n"); ! 1156: #endif ! 1157: ! 1158: free(ualloc, M_TEMP); ! 1159: } ! 1160: #endif /* NUBA */ ! 1161: ! 1162: /* ! 1163: * Mark addresses starting at "addr" and continuing ! 1164: * "size" bytes as allocated in the map "ualloc". ! 1165: * Warn if the new allocation overlaps a previous allocation. ! 1166: */ ! 1167: static ! 1168: csralloc(ualloc, addr, size) ! 1169: caddr_t ualloc; ! 1170: u_short addr; ! 1171: register int size; ! 1172: { ! 1173: register caddr_t p; ! 1174: int warned = 0; ! 1175: ! 1176: p = &ualloc[ubdevreg(addr+size)]; ! 1177: while (--size >= 0) { ! 1178: if (*--p && !warned) { ! 1179: printf( ! 1180: "WARNING: device registers overlap those for a previous device!\n"); ! 1181: warned = 1; ! 1182: } ! 1183: *p = 1; ! 1184: } ! 1185: } ! 1186: ! 1187: /* ! 1188: * Make an IO register area accessible at physical address physa ! 1189: * by mapping kernel ptes starting at pte. ! 1190: */ ! 1191: ioaccess(physa, pte, size) ! 1192: caddr_t physa; ! 1193: register struct pte *pte; ! 1194: int size; ! 1195: { ! 1196: register int i = btoc(size); ! 1197: register unsigned v = btop(physa); ! 1198: ! 1199: do ! 1200: *(int *)pte++ = PG_V|PG_KW|v++; ! 1201: while (--i > 0); ! 1202: mtpr(TBIA, 0); ! 1203: } ! 1204: ! 1205: /* ! 1206: * Configure swap space and related parameters. ! 1207: */ ! 1208: swapconf() ! 1209: { ! 1210: register struct swdevt *swp; ! 1211: register int nblks; ! 1212: ! 1213: for (swp = swdevt; swp->sw_dev; swp++) ! 1214: if (bdevsw[major(swp->sw_dev)].d_psize) { ! 1215: nblks = ! 1216: (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); ! 1217: if (nblks != -1 && ! 1218: (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) ! 1219: swp->sw_nblks = nblks; ! 1220: } ! 1221: if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize) ! 1222: dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - physmem; ! 1223: if (dumplo < 0) ! 1224: dumplo = 0; ! 1225: } ! 1226: ! 1227: #define DOSWAP /* Change swdevt, argdev, and dumpdev too */ ! 1228: u_long bootdev; /* should be dev_t, but not until 32 bits */ ! 1229: ! 1230: static char devname[][2] = { ! 1231: 'h','p', /* 0 = hp */ ! 1232: 0,0, /* 1 = ht */ ! 1233: 'u','p', /* 2 = up */ ! 1234: 'r','k', /* 3 = hk */ ! 1235: 0,0, /* 4 = sw */ ! 1236: 0,0, /* 5 = tm */ ! 1237: 0,0, /* 6 = ts */ ! 1238: 0,0, /* 7 = mt */ ! 1239: 0,0, /* 8 = tu */ ! 1240: 'r','a', /* 9 = ra */ ! 1241: 0,0, /* 10 = ut */ ! 1242: 'r','b', /* 11 = rb */ ! 1243: 0,0, /* 12 = uu */ ! 1244: 0,0, /* 13 = rx */ ! 1245: 'r','l', /* 14 = rl */ ! 1246: 0,0, /* 15 = tmscp */ ! 1247: 'k','r', /* 16 = ra on kdb50 */ ! 1248: }; ! 1249: ! 1250: #define PARTITIONMASK 0x7 ! 1251: #define PARTITIONSHIFT 3 ! 1252: ! 1253: /* ! 1254: * Attempt to find the device from which we were booted. ! 1255: * If we can do so, and not instructed not to do so, ! 1256: * change rootdev to correspond to the load device. ! 1257: */ ! 1258: setroot() ! 1259: { ! 1260: int majdev, mindev, unit, part, controller, adaptor; ! 1261: dev_t temp, orootdev; ! 1262: struct swdevt *swp; ! 1263: ! 1264: if (boothowto & RB_DFLTROOT || ! 1265: (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) ! 1266: return; ! 1267: majdev = B_TYPE(bootdev); ! 1268: if (majdev >= sizeof(devname) / sizeof(devname[0])) ! 1269: return; ! 1270: adaptor = B_ADAPTOR(bootdev); ! 1271: controller = B_CONTROLLER(bootdev); ! 1272: part = B_PARTITION(bootdev); ! 1273: unit = B_UNIT(bootdev); ! 1274: if (majdev == 0) { /* MBA device */ ! 1275: #if NMBA > 0 ! 1276: register struct mba_device *mbap; ! 1277: int mask; ! 1278: ! 1279: /* ! 1280: * The MBA number used at boot time is not necessarily the same as the ! 1281: * MBA number used by the kernel. In order to change the rootdev we need to ! 1282: * convert the boot MBA number to the kernel MBA number. The address space ! 1283: * for an MBA used by the boot code is 0x20010000 + 0x2000 * MBA_number ! 1284: * on the 78? and 86?0, 0xf28000 + 0x2000 * MBA_number on the 750. ! 1285: * Therefore we can search the mba_hd table for the MBA that has the physical ! 1286: * address corresponding to the boot MBA number. ! 1287: */ ! 1288: #define PHYSADRSHFT 13 ! 1289: #define PHYSMBAMASK780 0x7 ! 1290: #define PHYSMBAMASK750 0x3 ! 1291: ! 1292: switch (cpu) { ! 1293: ! 1294: case VAX_780: ! 1295: case VAX_8600: ! 1296: default: ! 1297: mask = PHYSMBAMASK780; ! 1298: break; ! 1299: ! 1300: case VAX_750: ! 1301: mask = PHYSMBAMASK750; ! 1302: break; ! 1303: } ! 1304: for (mbap = mbdinit; mbap->mi_driver; mbap++) ! 1305: if (mbap->mi_alive && mbap->mi_drive == unit && ! 1306: (((long)mbap->mi_hd->mh_physmba >> PHYSADRSHFT) ! 1307: & mask) == adaptor) ! 1308: break; ! 1309: if (mbap->mi_driver == 0) ! 1310: return; ! 1311: mindev = mbap->mi_unit; ! 1312: #else ! 1313: return; ! 1314: #endif ! 1315: } else { ! 1316: register struct uba_device *ubap; ! 1317: ! 1318: for (ubap = ubdinit; ubap->ui_driver; ubap++) ! 1319: if (ubap->ui_alive && ubap->ui_slave == unit && ! 1320: ubap->ui_ctlr == controller && ! 1321: ubap->ui_ubanum == adaptor && ! 1322: ubap->ui_driver->ud_dname[0] == devname[majdev][0] && ! 1323: ubap->ui_driver->ud_dname[1] == devname[majdev][1]) ! 1324: break; ! 1325: ! 1326: if (ubap->ui_driver == 0) ! 1327: return; ! 1328: mindev = ubap->ui_unit; ! 1329: } ! 1330: mindev = (mindev << PARTITIONSHIFT) + part; ! 1331: orootdev = rootdev; ! 1332: rootdev = makedev(majdev, mindev); ! 1333: /* ! 1334: * If the original rootdev is the same as the one ! 1335: * just calculated, don't need to adjust the swap configuration. ! 1336: */ ! 1337: if (rootdev == orootdev) ! 1338: return; ! 1339: ! 1340: printf("Changing root device to %c%c%d%c\n", ! 1341: devname[majdev][0], devname[majdev][1], ! 1342: mindev >> PARTITIONSHIFT, part + 'a'); ! 1343: ! 1344: #ifdef DOSWAP ! 1345: mindev &= ~PARTITIONMASK; ! 1346: for (swp = swdevt; swp->sw_dev; swp++) { ! 1347: if (majdev == major(swp->sw_dev) && ! 1348: mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { ! 1349: temp = swdevt[0].sw_dev; ! 1350: swdevt[0].sw_dev = swp->sw_dev; ! 1351: swp->sw_dev = temp; ! 1352: break; ! 1353: } ! 1354: } ! 1355: if (swp->sw_dev == 0) ! 1356: return; ! 1357: ! 1358: /* ! 1359: * If argdev and dumpdev were the same as the old primary swap ! 1360: * device, move them to the new primary swap device. ! 1361: */ ! 1362: if (temp == dumpdev) ! 1363: dumpdev = swdevt[0].sw_dev; ! 1364: if (temp == argdev) ! 1365: argdev = swdevt[0].sw_dev; ! 1366: #endif ! 1367: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.