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 6.26 (Berkeley) 05/27/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) || setroot() == 0) 117 setconf(); 118 #else 119 (void) setroot(); 120 #endif 121 /* 122 * Configure swap area and related system 123 * parameter based on device(s) used. 124 */ 125 swapconf(); 126 cold = 0; 127 memenable(); 128 return; 129 } 130 printf("cpu type %d not configured\n", cpusid.cpuany.cp_type); 131 asm("halt"); 132 } 133 134 /* 135 * Probe the main IO bus(es). 136 * The percpu structure gives us a handle on the addresses and/or types. 137 */ 138 probeio(pcpu) 139 register struct percpu *pcpu; 140 { 141 register struct iobus *iob; 142 int ioanum; 143 144 ioanum = 0; 145 for (iob = pcpu->pc_io; ioanum < pcpu->pc_nioa; ioanum++, iob++) { 146 147 switch (iob->io_type) { 148 149 #if VAX780 || VAX750 || VAX730 || VAX630 150 case IO_SBI780: 151 case IO_CMI750: 152 case IO_XXX730: 153 case IO_QBUS: 154 probenexi((struct nexusconnect *)iob->io_details); 155 break; 156 #endif 157 158 #if VAX8600 159 case IO_ABUS: 160 probe_Abus(ioanum, iob); 161 break; 162 #endif 163 default: 164 if (iob->io_addr) { 165 printf( 166 "IO adaptor %d, type %d, at address 0x%x is unsupported\n", 167 ioanum, iob->io_type, iob->io_addr); 168 } else 169 printf("IO adaptor %d, type %d, is unsupported\n", 170 ioanum, iob->io_type); 171 break; 172 } 173 } 174 } 175 176 #if VAX8600 177 probe_Abus(ioanum, iob) 178 register struct iobus *iob; 179 { 180 register struct ioa *ioap; 181 union ioacsr ioacsr; 182 int type; 183 struct sbia_regs *sbiaregs; 184 185 ioap = &ioa[ioanum]; 186 ioaccess(iob->io_addr, Ioamap[ioanum], iob->io_size); 187 if (badaddr((caddr_t)ioap, 4)) 188 return; 189 ioacsr.ioa_csr = ioap->ioacsr.ioa_csr; 190 type = ioacsr.ioa_type & IOA_TYPMSK; 191 192 switch (type) { 193 194 case IOA_SBIA: 195 printf("SBIA%d at IO adaptor %d address 0x%x\n", 196 nsbi, ioanum, iob->io_addr); 197 probenexi((struct nexusconnect *)iob->io_details); 198 nsbi++; 199 sbiaregs = (struct sbia_regs *)ioap; 200 sbiaregs->sbi_errsum = -1; 201 sbiaregs->sbi_error = 0x1000; 202 sbiaregs->sbi_fltsts = 0xc0000; 203 break; 204 205 default: 206 printf("IOA%d at address 0x%x is unsupported (type = 0x%x)\n", 207 ioanum, iob->io_addr, ioacsr.ioa_type); 208 break; 209 } 210 } 211 #endif 212 213 /* 214 * Probe nexus space, finding the interconnects 215 * and setting up and probing mba's and uba's for devices. 216 */ 217 /*ARGSUSED*/ 218 probenexi(pnc) 219 register struct nexusconnect *pnc; 220 { 221 register struct nexus *nxv; 222 struct nexus *nxp = pnc->psb_nexbase; 223 union nexcsr nexcsr; 224 int i; 225 226 nexnum = 0, nxv = &nexus[nsbi * NNEXSBI]; 227 for (; nexnum < pnc->psb_nnexus; nexnum++, nxp++, nxv++) { 228 ioaccess((caddr_t)nxp, Nexmap[nsbi * NNEXSBI + nexnum], 229 sizeof(struct nexus)); 230 if (badaddr((caddr_t)nxv, 4)) 231 continue; 232 if (pnc->psb_nextype && pnc->psb_nextype[nexnum] != NEX_ANY) 233 nexcsr.nex_csr = pnc->psb_nextype[nexnum]; 234 else 235 nexcsr = nxv->nexcsr; 236 if (nexcsr.nex_csr&NEX_APD) 237 continue; 238 switch (nexcsr.nex_type) { 239 240 case NEX_MBA: 241 printf("mba%d at tr%d\n", nummba, nexnum); 242 if (nummba >= NMBA) { 243 printf("%d mba's", nummba++); 244 goto unconfig; 245 } 246 #if NMBA > 0 247 mbafind(nxv, nxp); 248 nummba++; 249 #endif 250 break; 251 252 case NEX_UBA0: 253 case NEX_UBA1: 254 case NEX_UBA2: 255 case NEX_UBA3: 256 printf("uba%d at tr%d\n", numuba, nexnum); 257 #if VAX750 258 if (numuba >= 2 && cpu == VAX_750) { 259 printf("More than 2 UBA's"); 260 goto unsupp; 261 } 262 #endif 263 if (numuba >= NUBA) { 264 printf("%d uba's", ++numuba); 265 goto unconfig; 266 } 267 #if defined(VAX780) || defined(VAX8600) 268 if ((cpu == VAX_780) || (cpu == VAX_8600)) 269 setscbnex(ubaintv[numuba]); 270 #endif 271 i = nexcsr.nex_type - NEX_UBA0; 272 unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp, 273 umem[numuba], pnc->psb_umaddr[i], UMEMmap[numuba], 274 pnc->psb_haveubasr); 275 #if defined(VAX780) || defined(VAX8600) 276 if ((cpu == VAX_780) || (cpu == VAX_8600)) 277 ((struct uba_regs *)nxv)->uba_cr = 278 UBACR_IFS|UBACR_BRIE| 279 UBACR_USEFIE|UBACR_SUEFIE| 280 (((struct uba_regs *)nxv)->uba_cr&0x7c000000); 281 #endif 282 numuba++; 283 break; 284 285 case NEX_DR32: 286 /* there can be more than one... are there other codes??? */ 287 printf("dr32"); 288 goto unsupp; 289 290 case NEX_MEM4: 291 case NEX_MEM4I: 292 case NEX_MEM16: 293 case NEX_MEM16I: 294 printf("mcr%d at tr%d\n", nmcr, nexnum); 295 if (nmcr >= 4) { 296 printf("5 mcr's"); 297 goto unsupp; 298 } 299 switch (cpu) { 300 case VAX_780: 301 mcrtype[nmcr] = M780C; 302 break; 303 case VAX_750: 304 mcrtype[nmcr] = M750; 305 break; 306 case VAX_730: 307 mcrtype[nmcr] = M730; 308 break; 309 } 310 mcraddr[nmcr++] = (struct mcr *)nxv; 311 break; 312 313 case NEX_MEM64I: 314 case NEX_MEM64L: 315 case NEX_MEM64LI: 316 case NEX_MEM256I: 317 case NEX_MEM256L: 318 case NEX_MEM256LI: 319 printf("mcr%d (el) at tr%d\n", nmcr, nexnum); 320 if (nmcr >= 4) { 321 printf("5 mcr's"); 322 goto unsupp; 323 } 324 if (cpu == VAX_780) 325 mcrtype[nmcr] = M780EL; 326 mcraddr[nmcr++] = (struct mcr *)nxv; 327 if (nexcsr.nex_type != NEX_MEM64I && 328 nexcsr.nex_type != NEX_MEM256I) 329 break; 330 /* fall into ... */ 331 332 case NEX_MEM64U: 333 case NEX_MEM64UI: 334 case NEX_MEM256U: 335 case NEX_MEM256UI: 336 printf("mcr%d (eu) at tr%d\n", nmcr, nexnum); 337 if (nmcr >= 4) { 338 printf("5 mcr's"); 339 goto unsupp; 340 } 341 if (cpu == VAX_780) 342 mcrtype[nmcr] = M780EU; 343 mcraddr[nmcr++] = (struct mcr *)nxv; 344 break; 345 346 case NEX_MPM0: 347 case NEX_MPM1: 348 case NEX_MPM2: 349 case NEX_MPM3: 350 printf("mpm"); 351 goto unsupp; 352 353 case NEX_CI: 354 printf("ci"); 355 goto unsupp; 356 357 default: 358 printf("nexus type %x", nexcsr.nex_type); 359 unsupp: 360 printf(" unsupported (at tr %d)\n", nexnum); 361 continue; 362 unconfig: 363 printf(" not configured\n"); 364 continue; 365 } 366 } 367 if (nummba > NMBA) 368 nummba = NMBA; 369 if (numuba > NUBA) 370 numuba = NUBA; 371 } 372 373 #if NMBA > 0 374 struct mba_device *mbaconfig(); 375 /* 376 * Find devices attached to a particular mba 377 * and look for each device found in the massbus 378 * initialization tables. 379 */ 380 mbafind(nxv, nxp) 381 struct nexus *nxv, *nxp; 382 { 383 register struct mba_regs *mdp; 384 register struct mba_drv *mbd; 385 register struct mba_device *mi; 386 register struct mba_slave *ms; 387 int dn, dt, sn; 388 struct mba_device fnd; 389 390 mdp = (struct mba_regs *)nxv; 391 mba_hd[nummba].mh_mba = mdp; 392 mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp; 393 setscbnex(mbaintv[nummba]); 394 fnd.mi_mba = mdp; 395 fnd.mi_mbanum = nummba; 396 for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) { 397 if ((mbd->mbd_ds&MBDS_DPR) == 0) 398 continue; 399 mdp->mba_sr |= MBSR_NED; /* si kludge */ 400 dt = mbd->mbd_dt & 0xffff; 401 if (dt == 0) 402 continue; 403 if (mdp->mba_sr&MBSR_NED) 404 continue; /* si kludge */ 405 if (dt == MBDT_MOH) 406 continue; 407 fnd.mi_drive = dn; 408 #define qeq(a, b) ( a == b || a == '?' ) 409 if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP)) 410 for (sn = 0; sn < 8; sn++) { 411 mbd->mbd_tc = sn; 412 for (ms = mbsinit; ms->ms_driver; ms++) 413 if (ms->ms_driver == mi->mi_driver && 414 ms->ms_alive == 0 && 415 qeq(ms->ms_ctlr, mi->mi_unit) && 416 qeq(ms->ms_slave, sn) && 417 (*ms->ms_driver->md_slave)(mi, ms, sn)) { 418 printf("%s%d at %s%d slave %d\n" 419 , ms->ms_driver->md_sname 420 , ms->ms_unit 421 , mi->mi_driver->md_dname 422 , mi->mi_unit 423 , sn 424 ); 425 ms->ms_alive = 1; 426 ms->ms_ctlr = mi->mi_unit; 427 ms->ms_slave = sn; 428 } 429 } 430 } 431 mdp->mba_cr = MBCR_INIT; 432 mdp->mba_cr = MBCR_IE; 433 } 434 435 /* 436 * Have found a massbus device; 437 * see if it is in the configuration table. 438 * If so, fill in its data. 439 */ 440 struct mba_device * 441 mbaconfig(ni, type) 442 register struct mba_device *ni; 443 register int type; 444 { 445 register struct mba_device *mi; 446 register short *tp; 447 register struct mba_hd *mh; 448 449 for (mi = mbdinit; mi->mi_driver; mi++) { 450 if (mi->mi_alive) 451 continue; 452 tp = mi->mi_driver->md_type; 453 for (mi->mi_type = 0; *tp; tp++, mi->mi_type++) 454 if (*tp == (type&MBDT_TYPE)) 455 goto found; 456 continue; 457 found: 458 #define match(fld) (ni->fld == mi->fld || mi->fld == '?') 459 if (!match(mi_drive) || !match(mi_mbanum)) 460 continue; 461 printf("%s%d at mba%d drive %d\n", 462 mi->mi_driver->md_dname, mi->mi_unit, 463 ni->mi_mbanum, ni->mi_drive); 464 mi->mi_alive = 1; 465 mh = &mba_hd[ni->mi_mbanum]; 466 mi->mi_hd = mh; 467 mh->mh_mbip[ni->mi_drive] = mi; 468 mh->mh_ndrive++; 469 mi->mi_mba = ni->mi_mba; 470 mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive]; 471 mi->mi_mbanum = ni->mi_mbanum; 472 mi->mi_drive = ni->mi_drive; 473 /* 474 * If drive has never been seen before, 475 * give it a dkn for statistics. 476 */ 477 if (mi->mi_driver->md_info[mi->mi_unit] == 0) { 478 mi->mi_driver->md_info[mi->mi_unit] = mi; 479 if (mi->mi_dk && dkn < DK_NDRIVE) 480 mi->mi_dk = dkn++; 481 else 482 mi->mi_dk = -1; 483 } 484 (*mi->mi_driver->md_attach)(mi); 485 return (mi); 486 } 487 return (0); 488 } 489 #endif 490 491 /* 492 * Fixctlrmask fixes the masks of the driver ctlr routines 493 * which otherwise save r10 and r11 where the interrupt and br 494 * level are passed through. 495 */ 496 fixctlrmask() 497 { 498 register struct uba_ctlr *um; 499 register struct uba_device *ui; 500 register struct uba_driver *ud; 501 #define phys(a,b) ((b)(((int)(a))&0x7fffffff)) 502 503 for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++) 504 *phys(ud->ud_probe, short *) &= ~0xc00; 505 for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++) 506 *phys(ud->ud_probe, short *) &= ~0xc00; 507 } 508 509 /* 510 * Find devices on a UNIBUS. 511 * Uses per-driver routine to set <br,cvec> into <r11,r10>, 512 * and then fills in the tables, with help from a per-driver 513 * slave initialization routine. 514 */ 515 unifind(vubp, pubp, vumem, pumem, memmap, haveubasr) 516 struct uba_regs *vubp, *pubp; 517 caddr_t vumem, pumem; 518 struct pte *memmap; 519 int haveubasr; 520 { 521 #ifndef lint 522 register int br, cvec; /* MUST BE r11, r10 */ 523 #else 524 /* 525 * Lint doesn't realize that these 526 * can be initialized asynchronously 527 * when devices interrupt. 528 */ 529 register int br = 0, cvec = 0; 530 #endif 531 register struct uba_device *ui; 532 register struct uba_ctlr *um; 533 u_short *reg, *ap, addr; 534 struct uba_hd *uhp; 535 struct uba_driver *udp; 536 int i, (**ivec)(); 537 caddr_t ualloc, zmemall(); 538 extern int catcher[256]; 539 540 #if VAX630 541 /* 542 * The map registers start right at 20088000 on the 543 * ka630, so we have to subtract out the 2k offset to make the 544 * pointers work.. 545 */ 546 if (cpu == VAX_630) { 547 vubp = (struct uba_regs *)(((u_long)vubp)-0x800); 548 pubp = (struct uba_regs *)(((u_long)pubp)-0x800); 549 } 550 #endif 551 /* 552 * Initialize the UNIBUS, by freeing the map 553 * registers and the buffered data path registers 554 */ 555 uhp = &uba_hd[numuba]; 556 uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map)); 557 ubainitmaps(uhp); 558 559 /* 560 * Save virtual and physical addresses 561 * of adaptor, and allocate and initialize 562 * the UNIBUS interrupt vector. 563 */ 564 uhp->uh_uba = vubp; 565 uhp->uh_physuba = pubp; 566 /* 567 * On the 8600, can't use UNIvec; 568 * the vectors for the second SBI overlap it. 569 */ 570 if (cpu == VAX_8600) 571 uhp->uh_vec = (int(**)())calloc(512); 572 else if (numuba == 0) 573 uhp->uh_vec = UNIvec; 574 #if NUBA > 1 575 else if (numuba == 1) 576 uhp->uh_vec = UNI1vec; 577 else 578 uhp->uh_vec = (int(**)())calloc(512); 579 #endif 580 for (i = 0; i < 128; i++) 581 uhp->uh_vec[i] = 582 scbentry(&catcher[i*2], SCB_ISTACK); 583 /* 584 * Set last free interrupt vector for devices with 585 * programmable interrupt vectors. Use is to decrement 586 * this number and use result as interrupt vector. 587 */ 588 uhp->uh_lastiv = 0x200; 589 590 #if VAX630 591 /* 592 * Kludge time again. The q22 memory and device reg. address spaces 593 * are not physically contiguous, so we need 2 loops to map them 594 * into contiguous virtual space. 595 */ 596 if (cpu == VAX_630) { 597 ioaccess(pumem, memmap, (UBAPAGES-16)*NBPG); 598 ioaccess(0x20000000, memmap+(UBAPAGES-16), 16*NBPG); 599 } else 600 #endif 601 ioaccess(pumem, memmap, UBAPAGES * NBPG); 602 #if defined(VAX780) || defined(VAX8600) 603 if (haveubasr) { 604 vubp->uba_sr = vubp->uba_sr; 605 vubp->uba_cr = UBACR_IFS|UBACR_BRIE; 606 } 607 #endif 608 /* 609 * First configure devices that have unibus memory, 610 * allowing them to allocate the correct map registers. 611 */ 612 ubameminit(numuba); 613 /* 614 * Grab some memory to record the umem address space we allocate, 615 * so we can be sure not to place two devices at the same address. 616 * 617 * We could use just 1/8 of this (we only want a 1 bit flag) but 618 * we are going to give it back anyway, and that would make the 619 * code here bigger (which we can't give back), so ... 620 * 621 * One day, someone will make a unibus with something other than 622 * an 8K i/o address space, & screw this totally. 623 */ 624 ualloc = zmemall(memall, 8*1024); 625 if (ualloc == (caddr_t)0) 626 panic("no mem for unifind"); 627 628 /* 629 * Map the first page of UNIBUS i/o 630 * space to the first page of memory 631 * for devices which will need to dma 632 * output to produce an interrupt. 633 */ 634 *(int *)(&vubp->uba_map[0]) = UBAMR_MRV; 635 636 #define ubaoff(off) ((off)&0x1fff) 637 #define ubaddr(off) (u_short *)((int)vumem + (ubaoff(off)|0x3e000)) 638 /* 639 * Check each unibus mass storage controller. 640 * For each one which is potentially on this uba, 641 * see if it is really there, and if it is record it and 642 * then go looking for slaves. 643 */ 644 for (um = ubminit; udp = um->um_driver; um++) { 645 if (um->um_ubanum != numuba && um->um_ubanum != '?') 646 continue; 647 addr = (u_short)um->um_addr; 648 /* 649 * use the particular address specified first, 650 * or if it is given as "0", of there is no device 651 * at that address, try all the standard addresses 652 * in the driver til we find it 653 */ 654 for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { 655 656 if (ualloc[ubaoff(addr)]) 657 continue; 658 reg = ubaddr(addr); 659 if (badaddr((caddr_t)reg, 2)) 660 continue; 661 #if defined(VAX780) || defined(VAX8600) 662 if (haveubasr && vubp->uba_sr) { 663 vubp->uba_sr = vubp->uba_sr; 664 continue; 665 } 666 #endif 667 cvec = 0x200; 668 i = (*udp->ud_probe)(reg, um->um_ctlr, um); 669 #if defined(VAX780) || defined(VAX8600) 670 if (haveubasr && vubp->uba_sr) { 671 vubp->uba_sr = vubp->uba_sr; 672 continue; 673 } 674 #endif 675 if (i == 0) 676 continue; 677 printf("%s%d at uba%d csr %o ", 678 udp->ud_mname, um->um_ctlr, numuba, addr); 679 if (cvec == 0) { 680 printf("zero vector\n"); 681 continue; 682 } 683 if (cvec == 0x200) { 684 printf("didn't interrupt\n"); 685 continue; 686 } 687 printf("vec %o, ipl %x\n", cvec, br); 688 um->um_alive = 1; 689 um->um_ubanum = numuba; 690 um->um_hd = &uba_hd[numuba]; 691 um->um_addr = (caddr_t)reg; 692 udp->ud_minfo[um->um_ctlr] = um; 693 for (ivec = um->um_intr; *ivec; ivec++) { 694 um->um_hd->uh_vec[cvec/4] = 695 scbentry(*ivec, SCB_ISTACK); 696 cvec += 4; 697 } 698 for (ui = ubdinit; ui->ui_driver; ui++) { 699 if (ui->ui_driver != udp || ui->ui_alive || 700 ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' || 701 ui->ui_ubanum != numuba && ui->ui_ubanum != '?') 702 continue; 703 if ((*udp->ud_slave)(ui, reg)) { 704 ui->ui_alive = 1; 705 ui->ui_ctlr = um->um_ctlr; 706 ui->ui_ubanum = numuba; 707 ui->ui_hd = &uba_hd[numuba]; 708 ui->ui_addr = (caddr_t)reg; 709 ui->ui_physaddr = pumem + ubdevreg(addr); 710 if (ui->ui_dk && dkn < DK_NDRIVE) 711 ui->ui_dk = dkn++; 712 else 713 ui->ui_dk = -1; 714 ui->ui_mi = um; 715 /* ui_type comes from driver */ 716 udp->ud_dinfo[ui->ui_unit] = ui; 717 printf("%s%d at %s%d slave %d\n", 718 udp->ud_dname, ui->ui_unit, 719 udp->ud_mname, um->um_ctlr, ui->ui_slave); 720 (*udp->ud_attach)(ui); 721 } 722 } 723 break; 724 } 725 } 726 /* 727 * Now look for non-mass storage peripherals. 728 */ 729 for (ui = ubdinit; udp = ui->ui_driver; ui++) { 730 if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' || 731 ui->ui_alive || ui->ui_slave != -1) 732 continue; 733 addr = (u_short)ui->ui_addr; 734 735 for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { 736 737 if (ualloc[ubaoff(addr)]) 738 continue; 739 reg = ubaddr(addr); 740 if (badaddr((caddr_t)reg, 2)) 741 continue; 742 #if defined(VAX780) || defined(VAX8600) 743 if (haveubasr && vubp->uba_sr) { 744 vubp->uba_sr = vubp->uba_sr; 745 continue; 746 } 747 #endif 748 cvec = 0x200; 749 i = (*udp->ud_probe)(reg, ui); 750 #if defined(VAX780) || defined(VAX8600) 751 if (haveubasr && vubp->uba_sr) { 752 vubp->uba_sr = vubp->uba_sr; 753 continue; 754 } 755 #endif 756 if (i == 0) 757 continue; 758 printf("%s%d at uba%d csr %o ", 759 ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr); 760 if (cvec == 0) { 761 printf("zero vector\n"); 762 continue; 763 } 764 if (cvec == 0x200) { 765 printf("didn't interrupt\n"); 766 continue; 767 } 768 printf("vec %o, ipl %x\n", cvec, br); 769 while (--i >= 0) 770 ualloc[ubaoff(addr+i)] = 1; 771 ui->ui_hd = &uba_hd[numuba]; 772 for (ivec = ui->ui_intr; *ivec; ivec++) { 773 ui->ui_hd->uh_vec[cvec/4] = 774 scbentry(*ivec, SCB_ISTACK); 775 cvec += 4; 776 } 777 ui->ui_alive = 1; 778 ui->ui_ubanum = numuba; 779 ui->ui_addr = (caddr_t)reg; 780 ui->ui_physaddr = pumem + ubdevreg(addr); 781 ui->ui_dk = -1; 782 /* ui_type comes from driver */ 783 udp->ud_dinfo[ui->ui_unit] = ui; 784 (*udp->ud_attach)(ui); 785 break; 786 } 787 } 788 789 #ifdef AUTO_DEBUG 790 printf("Unibus allocation map"); 791 for (i = 0; i < 8*1024; ) { 792 register n, m; 793 794 if ((i % 128) == 0) { 795 printf("\n%6o:", i); 796 for (n = 0; n < 128; n++) 797 if (ualloc[i+n]) 798 break; 799 if (n == 128) { 800 i += 128; 801 continue; 802 } 803 } 804 805 for (n = m = 0; n < 16; n++) { 806 m <<= 1; 807 m |= ualloc[i++]; 808 } 809 810 printf(" %4x", m); 811 } 812 printf("\n"); 813 #endif 814 815 wmemfree(ualloc, 8*1024); 816 } 817 818 setscbnex(fn) 819 int (*fn)(); 820 { 821 register struct scb *scbp = &scb; 822 823 scbp = (struct scb *)((caddr_t)scbp + nsbi * 512); 824 scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] = 825 scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] = 826 scbentry(fn, SCB_ISTACK); 827 } 828 829 /* 830 * Make an IO register area accessible at physical address physa 831 * by mapping kernel ptes starting at pte. 832 */ 833 ioaccess(physa, pte, size) 834 caddr_t physa; 835 register struct pte *pte; 836 int size; 837 { 838 register int i = btop(size); 839 register unsigned v = btop(physa); 840 841 do 842 *(int *)pte++ = PG_V|PG_KW|v++; 843 while (--i > 0); 844 mtpr(TBIA, 0); 845 } 846 847 /* 848 * Configure swap space and related parameters. 849 */ 850 swapconf() 851 { 852 register struct swdevt *swp; 853 register int nblks; 854 855 for (swp = swdevt; swp->sw_dev; swp++) { 856 if (bdevsw[major(swp->sw_dev)].d_psize) { 857 nblks = 858 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); 859 if (swp->sw_nblks == 0 || swp->sw_nblks > nblks) 860 swp->sw_nblks = nblks; 861 } 862 } 863 if (!cold) /* in case called for mba device */ 864 return; 865 if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize) 866 dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - physmem; 867 if (dumplo < 0) 868 dumplo = 0; 869 } 870 871 #define DOSWAP /* Change swdevt, argdev, and dumpdev too */ 872 u_long bootdev; /* should be dev_t, but not until 32 bits */ 873 874 static char devname[][2] = { 875 'h','p', /* 0 = hp */ 876 0,0, /* 1 = ht */ 877 'u','p', /* 2 = up */ 878 'r','k', /* 3 = hk */ 879 0,0, /* 4 = sw */ 880 0,0, /* 5 = tm */ 881 0,0, /* 6 = ts */ 882 0,0, /* 7 = mt */ 883 0,0, /* 8 = tu */ 884 'r','a', /* 9 = ra */ 885 0,0, /* 10 = ut */ 886 'r','b', /* 11 = rb */ 887 0,0, /* 12 = uu */ 888 0,0, /* 13 = rx */ 889 'r','l', /* 14 = rl */ 890 }; 891 892 #define PARTITIONMASK 0x7 893 #define PARTITIONSHIFT 3 894 895 /* 896 * Attempt to find the device from which we were booted. 897 * If we can do so, and not instructed not to do so, 898 * change rootdev to correspond to the load device. 899 */ 900 setroot() 901 { 902 int majdev, mindev, unit, part, adaptor; 903 dev_t temp, orootdev; 904 struct swdevt *swp; 905 906 if (boothowto & RB_DFLTROOT || 907 (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 908 return (0); 909 majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 910 if (majdev > sizeof(devname) / sizeof(devname[0])) 911 return (0); 912 adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK; 913 part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 914 unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; 915 if (majdev == 0) { /* MBA device */ 916 #if NMBA > 0 917 register struct mba_device *mbap; 918 int mask; 919 920 /* 921 * The MBA number used at boot time is not necessarily the same as the 922 * MBA number used by the kernel. In order to change the rootdev we need to 923 * convert the boot MBA number to the kernel MBA number. The address space 924 * for an MBA used by the boot code is 0x20010000 + 0x2000 * MBA_number 925 * on the 78? and 86?0, 0xf28000 + 0x2000 * MBA_number on the 750. 926 * Therefore we can search the mba_hd table for the MBA that has the physical 927 * address corresponding to the boot MBA number. 928 */ 929 #define PHYSADRSHFT 13 930 #define PHYSMBAMASK780 0x7 931 #define PHYSMBAMASK750 0x3 932 933 switch (cpu) { 934 935 case VAX_780: 936 case VAX_8600: 937 default: 938 mask = PHYSMBAMASK780; 939 break; 940 941 case VAX_750: 942 mask = PHYSMBAMASK750; 943 break; 944 } 945 for (mbap = mbdinit; mbap->mi_driver; mbap++) 946 if (mbap->mi_alive && mbap->mi_drive == unit && 947 (((long)mbap->mi_hd->mh_physmba >> PHYSADRSHFT) 948 & mask) == adaptor) 949 break; 950 if (mbap->mi_driver == 0) 951 return (0); 952 mindev = mbap->mi_unit; 953 #else 954 return (0); 955 #endif 956 } else { 957 register struct uba_device *ubap; 958 959 for (ubap = ubdinit; ubap->ui_driver; ubap++) 960 if (ubap->ui_alive && ubap->ui_slave == unit && 961 ubap->ui_ubanum == adaptor && 962 ubap->ui_driver->ud_dname[0] == devname[majdev][0] && 963 ubap->ui_driver->ud_dname[1] == devname[majdev][1]) 964 break; 965 966 if (ubap->ui_driver == 0) 967 return (0); 968 mindev = ubap->ui_unit; 969 } 970 mindev = (mindev << PARTITIONSHIFT) + part; 971 orootdev = rootdev; 972 rootdev = makedev(majdev, mindev); 973 /* 974 * If the original rootdev is the same as the one 975 * just calculated, don't need to adjust the swap configuration. 976 */ 977 if (rootdev == orootdev) 978 return (1); 979 980 printf("Changing root device to %c%c%d%c\n", 981 devname[majdev][0], devname[majdev][1], 982 mindev >> PARTITIONSHIFT, part + 'a'); 983 984 #ifdef DOSWAP 985 mindev &= ~PARTITIONMASK; 986 for (swp = swdevt; swp->sw_dev; swp++) { 987 if (majdev == major(swp->sw_dev) && 988 mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { 989 temp = swdevt[0].sw_dev; 990 swdevt[0].sw_dev = swp->sw_dev; 991 swp->sw_dev = temp; 992 break; 993 } 994 } 995 if (swp->sw_dev == 0) 996 return (1); 997 998 /* 999 * If argdev and dumpdev were the same as the old primary swap 1000 * device, move them to the new primary swap device. 1001 */ 1002 if (temp == dumpdev) 1003 dumpdev = swdevt[0].sw_dev; 1004 if (temp == argdev) 1005 argdev = swdevt[0].sw_dev; 1006 #endif 1007 return (1); 1008 } 1009