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