1 /* autoconf.c 4.45 82/12/17 */ 2 3 /* 4 * Setup the system to run on the current machine. 5 * 6 * Configure() is called at boot time and initializes the uba and mba 7 * device tables and the memory controller monitoring. Available 8 * devices are determined (from possibilities mentioned in ioconf.c), 9 * and the drivers are initialized. 10 * 11 * N.B.: A lot of the conditionals based on processor type say 12 * #if VAX780 13 * and 14 * #if VAX750 15 * which may be incorrect after more processors are introduced if they 16 * are like either of these machines. 17 * 18 * TODO: 19 * use pcpu info about whether a ubasr exists 20 */ 21 22 #include "mba.h" 23 24 #include "../machine/pte.h" 25 26 #include "../h/param.h" 27 #include "../h/systm.h" 28 #include "../h/map.h" 29 #include "../h/buf.h" 30 #include "../h/dk.h" 31 #include "../h/vm.h" 32 33 #include "../vax/cpu.h" 34 #include "../vax/mem.h" 35 #include "../vax/mtpr.h" 36 #include "../vax/nexus.h" 37 #include "../vax/scb.h" 38 #include "../vaxmba/mbareg.h" 39 #include "../vaxmba/mbavar.h" 40 #include "../vaxuba/ubareg.h" 41 #include "../vaxuba/ubavar.h" 42 43 /* 44 * The following several variables are related to 45 * the configuration process, and are used in initializing 46 * the machine. 47 */ 48 int cold; /* if 1, still working on cold-start */ 49 int nexnum; /* current nexus number */ 50 int dkn; /* number of iostat dk numbers assigned so far */ 51 52 /* 53 * Addresses of the (locore) routines which bootstrap us from 54 * hardware traps to C code. Filled into the system control block 55 * as necessary. 56 */ 57 #if NMBA > 0 58 int (*mbaintv[4])() = { Xmba0int, Xmba1int, Xmba2int, Xmba3int }; 59 #endif 60 #if VAX780 61 int (*ubaintv[4])() = { Xua0int, Xua1int, Xua2int, Xua3int }; 62 #endif 63 64 /* 65 * This allocates the space for the per-uba information, 66 * such as buffered data path usage. 67 */ 68 struct uba_hd uba_hd[MAXNUBA]; 69 70 /* 71 * Determine mass storage and memory configuration for a machine. 72 * Get cpu type, and then switch out to machine specific procedures 73 * which will probe adaptors to see what is out there. 74 */ 75 configure() 76 { 77 union cpusid cpusid; 78 register struct percpu *ocp; 79 register int *ip; 80 extern char Sysbase[]; 81 82 cpusid.cpusid = mfpr(SID); 83 for (ocp = percpu; ocp->pc_cputype; ocp++) 84 if (ocp->pc_cputype == cpusid.cpuany.cp_type) { 85 probenexus(ocp); 86 /* 87 * Write protect the scb. It is strange 88 * that this code is here, but this is as soon 89 * as we are done mucking with it, and the 90 * write-enable was done in assembly language 91 * to which we will never return. 92 */ 93 ip = (int *)Sysmap; *ip &= ~PG_PROT; *ip |= PG_KR; 94 mtpr(TBIS, Sysbase); 95 #if GENERIC 96 setconf(); 97 #endif 98 cold = 0; 99 memenable(); 100 return; 101 } 102 printf("cpu type %d not configured\n", cpusid.cpuany.cp_type); 103 asm("halt"); 104 } 105 106 /* 107 * Probe nexus space, finding the interconnects 108 * and setting up and probing mba's and uba's for devices. 109 */ 110 /*ARGSUSED*/ 111 probenexus(pcpu) 112 register struct percpu *pcpu; 113 { 114 register struct nexus *nxv; 115 struct nexus *nxp = pcpu->pc_nexbase; 116 union nexcsr nexcsr; 117 int i; 118 119 nexnum = 0, nxv = nexus; 120 for (; nexnum < pcpu->pc_nnexus; nexnum++, nxp++, nxv++) { 121 nxaccess(nxp, Nexmap[nexnum]); 122 if (badaddr((caddr_t)nxv, 4)) 123 continue; 124 if (pcpu->pc_nextype && pcpu->pc_nextype[nexnum] != NEX_ANY) 125 nexcsr.nex_csr = pcpu->pc_nextype[nexnum]; 126 else 127 nexcsr = nxv->nexcsr; 128 if (nexcsr.nex_csr&NEX_APD) 129 continue; 130 switch (nexcsr.nex_type) { 131 132 case NEX_MBA: 133 printf("mba%d at tr%d\n", nummba, nexnum); 134 if (nummba >= NMBA) { 135 printf("%d mba's", nummba); 136 goto unconfig; 137 } 138 #if NMBA > 0 139 mbafind(nxv, nxp); 140 nummba++; 141 #endif 142 break; 143 144 case NEX_UBA0: 145 case NEX_UBA1: 146 case NEX_UBA2: 147 case NEX_UBA3: 148 printf("uba%d at tr%d\n", numuba, nexnum); 149 if (numuba >= 4) { 150 printf("5 uba's"); 151 goto unsupp; 152 } 153 #if VAX780 154 if (cpu == VAX_780) 155 setscbnex(ubaintv[numuba]); 156 #endif 157 i = nexcsr.nex_type - NEX_UBA0; 158 unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp, 159 umem[i], pcpu->pc_umaddr[i], UMEMmap[i]); 160 #if VAX780 161 if (cpu == VAX_780) 162 ((struct uba_regs *)nxv)->uba_cr = 163 UBACR_IFS|UBACR_BRIE| 164 UBACR_USEFIE|UBACR_SUEFIE| 165 (((struct uba_regs *)nxv)->uba_cr&0x7c000000); 166 #endif 167 numuba++; 168 break; 169 170 case NEX_DR32: 171 /* there can be more than one... are there other codes??? */ 172 printf("dr32"); 173 goto unsupp; 174 175 case NEX_MEM4: 176 case NEX_MEM4I: 177 case NEX_MEM16: 178 case NEX_MEM16I: 179 printf("mcr%d at tr%d\n", nmcr, nexnum); 180 if (nmcr >= 4) { 181 printf("5 mcr's"); 182 goto unsupp; 183 } 184 mcraddr[nmcr++] = (struct mcr *)nxv; 185 break; 186 187 case NEX_MPM0: 188 case NEX_MPM1: 189 case NEX_MPM2: 190 case NEX_MPM3: 191 printf("mpm"); 192 goto unsupp; 193 194 default: 195 printf("nexus type %x", nexcsr.nex_type); 196 unsupp: 197 printf(" unsupported (at tr %d)\n", nexnum); 198 continue; 199 unconfig: 200 printf(" not configured\n"); 201 continue; 202 } 203 } 204 } 205 206 #if NMBA > 0 207 struct mba_device *mbaconfig(); 208 /* 209 * Find devices attached to a particular mba 210 * and look for each device found in the massbus 211 * initialization tables. 212 */ 213 mbafind(nxv, nxp) 214 struct nexus *nxv, *nxp; 215 { 216 register struct mba_regs *mdp; 217 register struct mba_drv *mbd; 218 register struct mba_device *mi; 219 register struct mba_slave *ms; 220 int dn, dt, sn; 221 struct mba_device fnd; 222 223 mdp = (struct mba_regs *)nxv; 224 mba_hd[nummba].mh_mba = mdp; 225 mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp; 226 setscbnex(mbaintv[nummba]); 227 fnd.mi_mba = mdp; 228 fnd.mi_mbanum = nummba; 229 for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) { 230 if ((mbd->mbd_ds&MBDS_DPR) == 0) 231 continue; 232 mdp->mba_sr |= MBSR_NED; /* si kludge */ 233 dt = mbd->mbd_dt & 0xffff; 234 if (dt == 0) 235 continue; 236 if (mdp->mba_sr&MBSR_NED) 237 continue; /* si kludge */ 238 if (dt == MBDT_MOH) 239 continue; 240 fnd.mi_drive = dn; 241 #define qeq(a, b) ( a == b || a == '?' ) 242 if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP)) 243 for (sn = 0; sn < 8; sn++) { 244 mbd->mbd_tc = sn; 245 for (ms = mbsinit; ms->ms_driver; ms++) 246 if (ms->ms_driver == mi->mi_driver && 247 ms->ms_alive == 0 && 248 qeq(ms->ms_ctlr, mi->mi_unit) && 249 qeq(ms->ms_slave, sn) && 250 (*ms->ms_driver->md_slave)(mi, ms, sn)) { 251 printf("%s%d at %s%d slave %d\n" 252 , ms->ms_driver->md_sname 253 , ms->ms_unit 254 , mi->mi_driver->md_dname 255 , mi->mi_unit 256 , sn 257 ); 258 ms->ms_alive = 1; 259 ms->ms_ctlr = mi->mi_unit; 260 ms->ms_slave = sn; 261 } 262 } 263 } 264 mdp->mba_cr = MBCR_INIT; 265 mdp->mba_cr = MBCR_IE; 266 } 267 268 /* 269 * Have found a massbus device; 270 * see if it is in the configuration table. 271 * If so, fill in its data. 272 */ 273 struct mba_device * 274 mbaconfig(ni, type) 275 register struct mba_device *ni; 276 register int type; 277 { 278 register struct mba_device *mi; 279 register short *tp; 280 register struct mba_hd *mh; 281 282 for (mi = mbdinit; mi->mi_driver; mi++) { 283 if (mi->mi_alive) 284 continue; 285 tp = mi->mi_driver->md_type; 286 for (mi->mi_type = 0; *tp; tp++, mi->mi_type++) 287 if (*tp == (type&MBDT_TYPE)) 288 goto found; 289 continue; 290 found: 291 #define match(fld) (ni->fld == mi->fld || mi->fld == '?') 292 if (!match(mi_drive) || !match(mi_mbanum)) 293 continue; 294 printf("%s%d at mba%d drive %d\n", 295 mi->mi_driver->md_dname, mi->mi_unit, 296 ni->mi_mbanum, ni->mi_drive); 297 mi->mi_alive = 1; 298 mh = &mba_hd[ni->mi_mbanum]; 299 mi->mi_hd = mh; 300 mh->mh_mbip[ni->mi_drive] = mi; 301 mh->mh_ndrive++; 302 mi->mi_mba = ni->mi_mba; 303 mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive]; 304 mi->mi_mbanum = ni->mi_mbanum; 305 mi->mi_drive = ni->mi_drive; 306 /* 307 * If drive has never been seen before, 308 * give it a dkn for statistics. 309 */ 310 if (mi->mi_driver->md_info[mi->mi_unit] == 0) { 311 mi->mi_driver->md_info[mi->mi_unit] = mi; 312 if (mi->mi_dk && dkn < DK_NDRIVE) 313 mi->mi_dk = dkn++; 314 else 315 mi->mi_dk = -1; 316 } 317 (*mi->mi_driver->md_attach)(mi); 318 return (mi); 319 } 320 return (0); 321 } 322 #endif 323 324 /* 325 * Fixctlrmask fixes the masks of the driver ctlr routines 326 * which otherwise save r10 and r11 where the interrupt and br 327 * level are passed through. 328 */ 329 fixctlrmask() 330 { 331 register struct uba_ctlr *um; 332 register struct uba_device *ui; 333 register struct uba_driver *ud; 334 #define phys(a,b) ((b)(((int)(a))&0x7fffffff)) 335 336 for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++) 337 *phys(ud->ud_probe, short *) &= ~0xc00; 338 for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++) 339 *phys(ud->ud_probe, short *) &= ~0xc00; 340 } 341 342 /* 343 * Find devices on a UNIBUS. 344 * Uses per-driver routine to set <br,cvec> into <r11,r10>, 345 * and then fills in the tables, with help from a per-driver 346 * slave initialization routine. 347 */ 348 unifind(vubp, pubp, vumem, pumem, memmap) 349 struct uba_regs *vubp, *pubp; 350 caddr_t vumem, pumem; 351 struct pte *memmap; 352 { 353 #ifndef lint 354 register int br, cvec; /* MUST BE r11, r10 */ 355 #else 356 /* 357 * Lint doesn't realize that these 358 * can be initialized asynchronously 359 * when devices interrupt. 360 */ 361 register int br = 0, cvec = 0; 362 #endif 363 register struct uba_device *ui; 364 register struct uba_ctlr *um; 365 u_short *reg, *ap, addr; 366 struct uba_hd *uhp; 367 struct uba_driver *udp; 368 int i, (**ivec)(), haveubasr; 369 caddr_t ualloc, zmemall(); 370 extern int catcher[256]; 371 372 /* 373 * Initialize the UNIBUS, by freeing the map 374 * registers and the buffered data path registers 375 */ 376 uhp = &uba_hd[numuba]; 377 uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map)); 378 ubainitmaps(uhp); 379 haveubasr = cpu == VAX_780; 380 381 /* 382 * Save virtual and physical addresses 383 * of adaptor, and allocate and initialize 384 * the UNIBUS interrupt vector. 385 */ 386 uhp->uh_uba = vubp; 387 uhp->uh_physuba = pubp; 388 /* HAVE TO DO SOMETHING SPECIAL FOR SECOND UNIBUS ON COMETS HERE */ 389 if (numuba == 0) 390 uhp->uh_vec = UNIvec; 391 else 392 uhp->uh_vec = (int(**)())calloc(512); 393 for (i = 0; i < 128; i++) 394 uhp->uh_vec[i] = 395 scbentry(&catcher[i*2], SCB_ISTACK); 396 /* 397 * Set last free interrupt vector for devices with 398 * programmable interrupt vectors. Use is to decrement 399 * this number and use result as interrupt vector. 400 */ 401 uhp->uh_lastiv = 0x200; 402 403 ubaaccess(pumem, memmap); 404 #if VAX780 405 if (haveubasr) { 406 vubp->uba_sr = vubp->uba_sr; 407 vubp->uba_cr = UBACR_IFS|UBACR_BRIE; 408 } 409 #endif 410 /* 411 * Grab some memory to record the umem address space we allocate, 412 * so we can be sure not to place two devices at the same address. 413 * 414 * We could use just 1/8 of this (we only want a 1 bit flag) but 415 * we are going to give it back anyway, and that would make the 416 * code here bigger (which we can't give back), so ... 417 * 418 * One day, someone will make a unibus with something other than 419 * an 8K i/o address space, & screw this totally. 420 */ 421 ualloc = zmemall(memall, 8*1024); 422 if (ualloc == (caddr_t)0) 423 panic("no mem for unifind"); 424 425 /* 426 * Map the first page of UNIBUS i/o 427 * space to the first page of memory 428 * for devices which will need to dma 429 * output to produce an interrupt. 430 */ 431 *(int *)(&vubp->uba_map[0]) = UBAMR_MRV; 432 433 #define ubaoff(off) ((off)&0x1fff) 434 #define ubaddr(off) (u_short *)((int)vumem + (ubaoff(off)|0x3e000)) 435 /* 436 * Check each unibus mass storage controller. 437 * For each one which is potentially on this uba, 438 * see if it is really there, and if it is record it and 439 * then go looking for slaves. 440 */ 441 for (um = ubminit; udp = um->um_driver; um++) { 442 if (um->um_ubanum != numuba && um->um_ubanum != '?') 443 continue; 444 addr = (u_short)um->um_addr; 445 /* 446 * use the particular address specified first, 447 * or if it is given as "0", of there is no device 448 * at that address, try all the standard addresses 449 * in the driver til we find it 450 */ 451 for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { 452 453 if (ualloc[ubaoff(addr)]) 454 continue; 455 reg = ubaddr(addr); 456 if (badaddr((caddr_t)reg, 2)) 457 continue; 458 #if VAX780 459 if (haveubasr && vubp->uba_sr) { 460 vubp->uba_sr = vubp->uba_sr; 461 continue; 462 } 463 #endif 464 cvec = 0x200; 465 i = (*udp->ud_probe)(reg); 466 #if VAX780 467 if (haveubasr && vubp->uba_sr) { 468 vubp->uba_sr = vubp->uba_sr; 469 continue; 470 } 471 #endif 472 if (i == 0) 473 continue; 474 printf("%s%d at uba%d csr %o ", 475 udp->ud_mname, um->um_ctlr, numuba, addr); 476 if (cvec == 0) { 477 printf("zero vector\n"); 478 continue; 479 } 480 if (cvec == 0x200) { 481 printf("didn't interrupt\n"); 482 continue; 483 } 484 printf("vec %o, ipl %x\n", cvec, br); 485 um->um_alive = 1; 486 um->um_ubanum = numuba; 487 um->um_hd = &uba_hd[numuba]; 488 um->um_addr = (caddr_t)reg; 489 udp->ud_minfo[um->um_ctlr] = um; 490 for (ivec = um->um_intr; *ivec; ivec++) { 491 um->um_hd->uh_vec[cvec/4] = 492 scbentry(*ivec, SCB_ISTACK); 493 cvec += 4; 494 } 495 for (ui = ubdinit; ui->ui_driver; ui++) { 496 if (ui->ui_driver != udp || ui->ui_alive || 497 ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' || 498 ui->ui_ubanum != numuba && ui->ui_ubanum != '?') 499 continue; 500 if ((*udp->ud_slave)(ui, reg)) { 501 ui->ui_alive = 1; 502 ui->ui_ctlr = um->um_ctlr; 503 ui->ui_ubanum = numuba; 504 ui->ui_hd = &uba_hd[numuba]; 505 ui->ui_addr = (caddr_t)reg; 506 ui->ui_physaddr = pumem + ubdevreg(addr); 507 if (ui->ui_dk && dkn < DK_NDRIVE) 508 ui->ui_dk = dkn++; 509 else 510 ui->ui_dk = -1; 511 ui->ui_mi = um; 512 /* ui_type comes from driver */ 513 udp->ud_dinfo[ui->ui_unit] = ui; 514 printf("%s%d at %s%d slave %d\n", 515 udp->ud_dname, ui->ui_unit, 516 udp->ud_mname, um->um_ctlr, ui->ui_slave); 517 (*udp->ud_attach)(ui); 518 } 519 } 520 break; 521 } 522 } 523 /* 524 * Now look for non-mass storage peripherals. 525 */ 526 for (ui = ubdinit; udp = ui->ui_driver; ui++) { 527 if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' || 528 ui->ui_alive || ui->ui_slave != -1) 529 continue; 530 addr = (u_short)ui->ui_addr; 531 532 for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { 533 534 if (ualloc[ubaoff(addr)]) 535 continue; 536 reg = ubaddr(addr); 537 if (badaddr((caddr_t)reg, 2)) 538 continue; 539 #if VAX780 540 if (haveubasr && vubp->uba_sr) { 541 vubp->uba_sr = vubp->uba_sr; 542 continue; 543 } 544 #endif 545 cvec = 0x200; 546 i = (*udp->ud_probe)(reg, um->um_ctlr); 547 #if VAX780 548 if (haveubasr && vubp->uba_sr) { 549 vubp->uba_sr = vubp->uba_sr; 550 continue; 551 } 552 #endif 553 if (i == 0) 554 continue; 555 printf("%s%d at uba%d csr %o ", 556 ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr); 557 if (cvec == 0) { 558 printf("zero vector\n"); 559 continue; 560 } 561 if (cvec == 0x200) { 562 printf("didn't interrupt\n"); 563 continue; 564 } 565 printf("vec %o, ipl %x\n", cvec, br); 566 while (--i >= 0) 567 ualloc[ubaoff(addr+i)] = 1; 568 ui->ui_hd = &uba_hd[numuba]; 569 for (ivec = ui->ui_intr; *ivec; ivec++) { 570 ui->ui_hd->uh_vec[cvec/4] = 571 scbentry(*ivec, SCB_ISTACK); 572 cvec += 4; 573 } 574 ui->ui_alive = 1; 575 ui->ui_ubanum = numuba; 576 ui->ui_addr = (caddr_t)reg; 577 ui->ui_physaddr = pumem + ubdevreg(addr); 578 ui->ui_dk = -1; 579 /* ui_type comes from driver */ 580 udp->ud_dinfo[ui->ui_unit] = ui; 581 (*udp->ud_attach)(ui); 582 break; 583 } 584 } 585 586 #ifdef AUTO_DEBUG 587 printf("Unibus allocation map"); 588 for (i = 0; i < 8*1024; ) { 589 register n, m; 590 591 if ((i % 128) == 0) { 592 printf("\n%6o:", i); 593 for (n = 0; n < 128; n++) 594 if (ualloc[i+n]) 595 break; 596 if (n == 128) { 597 i += 128; 598 continue; 599 } 600 } 601 602 for (n = m = 0; n < 16; n++) { 603 m <<= 1; 604 m |= ualloc[i++]; 605 } 606 607 printf(" %4x", m); 608 } 609 printf("\n"); 610 #endif 611 612 wmemfree(ualloc, 8*1024); 613 } 614 615 setscbnex(fn) 616 int (*fn)(); 617 { 618 register struct scb *scbp = &scb; 619 620 scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] = 621 scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] = 622 scbentry(fn, SCB_ISTACK); 623 } 624 625 /* 626 * Make a nexus accessible at physical address phys 627 * by mapping kernel ptes starting at pte. 628 * 629 * WE LEAVE ALL NEXI MAPPED; THIS IS PERHAPS UNWISE 630 * SINCE MISSING NEXI DONT RESPOND. BUT THEN AGAIN 631 * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE. 632 */ 633 nxaccess(physa, pte) 634 struct nexus *physa; 635 register struct pte *pte; 636 { 637 register int i = btop(sizeof (struct nexus)); 638 register unsigned v = btop(physa); 639 640 do 641 *(int *)pte++ = PG_V|PG_KW|v++; 642 while (--i > 0); 643 mtpr(TBIA, 0); 644 } 645 646 ubaaccess(pumem, pte) 647 caddr_t pumem; 648 register struct pte *pte; 649 { 650 register int i = 512; 651 register unsigned v = btop(pumem); 652 653 do 654 *(int *)pte++ = PG_V|PG_KW|v++; 655 while (--i > 0); 656 mtpr(TBIA, 0); 657 } 658