1 /* machdep.c 4.71 82/11/13 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/kernel.h" 8 #include "../h/map.h" 9 #include "../h/reg.h" 10 #include "../h/pte.h" 11 #include "../h/vm.h" 12 #include "../h/proc.h" 13 #include "../h/psl.h" 14 #include "../h/buf.h" 15 #include "../h/reboot.h" 16 #include "../h/conf.h" 17 #include "../h/inode.h" 18 #include "../h/file.h" 19 #include "../h/text.h" 20 #include "../h/clist.h" 21 #include "../h/callout.h" 22 #include "../h/cmap.h" 23 #include <frame.h> 24 #include "../h/mbuf.h" 25 #include "../h/msgbuf.h" 26 #include "../h/quota.h" 27 28 #include "../vax/cons.h" 29 #include "../vax/cpu.h" 30 #include "../vax/mem.h" 31 #include "../vax/mtpr.h" 32 #include "../vax/rpb.h" 33 #include "../vaxuba/ubavar.h" 34 #include "../vaxuba/ubareg.h" 35 36 int icode[] = 37 { 38 0x9f19af9f, /* pushab [&"init",0]; pushab */ 39 0x02dd09af, /* "/etc/init"; pushl $2 */ 40 0xbc5c5ed0, /* movl sp,ap; chmk */ 41 0x2ffe110b, /* $exec; brb .; "/ */ 42 0x2f637465, /* etc/ */ 43 0x74696e69, /* init" */ 44 0x00000000, /* \0\0\0"; 0 */ 45 0x00000014, /* [&"init", */ 46 0x00000000, /* 0] */ 47 }; 48 int szicode = sizeof(icode); 49 50 #ifdef MUSH 51 int mcode[] = 52 { 53 0x9f19af9f, /* pushab [&"mush",0]; pushab */ 54 0x02dd09af, /* "/etc/mush"; pushl $2 */ 55 0xbc5c5ed0, /* movl sp,ap; chmk */ 56 0x2f01bc0b, /* $exec; chmk $exit; "/ */ 57 0x2f637465, /* etc/ */ 58 0x6873756d, /* mush" */ 59 0x00000000, /* \0\0\0"; 0 */ 60 0x00000014, /* [&"mush", */ 61 0x00000000, /* 0] */ 62 }; 63 int szmcode = sizeof(mcode); 64 #endif 65 66 /* 67 * Declare these as initialized data so we can patch them. 68 */ 69 int nbuf = 0; 70 int nswbuf = 0; 71 72 /* 73 * Machine-dependent startup code 74 */ 75 startup(firstaddr) 76 int firstaddr; 77 { 78 register int unixsize; 79 register unsigned i; 80 register struct pte *pte; 81 int mapaddr, j; 82 register caddr_t v; 83 84 /* 85 * Initialize error message buffer (at end of core). 86 */ 87 maxmem -= btoc(sizeof (struct msgbuf)); 88 pte = msgbufmap; 89 for (i = 0; i < btoc(sizeof (struct msgbuf)); i++) 90 *(int *)pte++ = PG_V | PG_KW | (maxmem + i); 91 mtpr(TBIA, 1); 92 93 /* 94 * Good {morning,afternoon,evening,night}. 95 */ 96 printf(version); 97 printf("real mem = %d\n", ctob(maxmem)); 98 99 /* 100 * Determine how many buffers to allocate. 101 * Use 10% of memory, with min of 16. 102 * We allocate 1/2 as many swap buffer headers as file i/o buffers. 103 */ 104 if (nbuf == 0) { 105 nbuf = ((physmem * NBPG) / 10) / (2 * CLBYTES); 106 if (nbuf < 16) 107 nbuf = 16; 108 } 109 if (nswbuf == 0) { 110 nswbuf = (nbuf / 2) &~ 1; /* force even */ 111 if (nswbuf > 256) 112 nswbuf = 256; /* sanity */ 113 } 114 115 /* 116 * Allocate space for system data structures. 117 * The first available real memory address is in "firstaddr". 118 * As pages of memory are allocated, "firstaddr" is incremented. 119 * The first available kernel virtual address is in "v". 120 * As pages of kernel virtual memory are allocated, "v" is incremented. 121 * An index into the kernel page table corresponding to the 122 * virtual memory address maintained in "v" is kept in "mapaddr". 123 */ 124 mapaddr = firstaddr; 125 v = (caddr_t)(0x80000000 | (firstaddr * NBPG)); 126 #define valloc(name, type, num) \ 127 (name) = (type *)(v); (v) = (caddr_t)((name)+(num)) 128 #define valloclim(name, type, num, lim) \ 129 (name) = (type *)(v); (v) = (caddr_t)((lim) = ((name)+(num))) 130 valloc(buffers, char, MAXBSIZE * nbuf); 131 for (i = 0; i < nbuf; i++) { 132 for (j = 0; j < 2 * CLSIZE; j++) { 133 *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr; 134 clearseg((unsigned)firstaddr); 135 firstaddr++; 136 } 137 mapaddr += MAXBSIZE / NBPG; 138 } 139 valloc(buf, struct buf, nbuf); 140 valloc(swbuf, struct buf, nswbuf); 141 valloc(swsize, short, nswbuf); /* note: nswbuf is even */ 142 valloc(swpf, int, nswbuf); 143 valloclim(inode, struct inode, ninode, inodeNINODE); 144 valloclim(file, struct file, nfile, fileNFILE); 145 valloclim(proc, struct proc, nproc, procNPROC); 146 valloclim(text, struct text, ntext, textNTEXT); 147 valloc(cfree, struct cblock, nclist); 148 valloc(callout, struct callout, ncallout); 149 valloc(swapmap, struct map, nswapmap = nproc * 2); 150 valloc(argmap, struct map, ARGMAPSIZE); 151 valloc(kernelmap, struct map, nproc); 152 valloc(mbmap, struct map, nmbclusters/4); 153 #ifdef QUOTA 154 valloclim(quota, struct quota, nquota, quotaNQUOTA); 155 valloclim(dquot, struct dquot, ndquot, dquotNDQUOT); 156 #endif 157 /* 158 * Now allocate space for core map 159 * Allow space for all of phsical memory minus the amount 160 * dedicated to the system. The amount of physical memory 161 * dedicated to the system is the total virtual memory of 162 * the system minus the space in the buffers which is not 163 * allocated real memory. 164 */ 165 ncmap = (physmem*NBPG - ((int)v &~ 0x80000000) + 166 (nbuf * (MAXBSIZE - 2 * CLBYTES))) / 167 (NBPG*CLSIZE + sizeof (struct cmap)); 168 valloclim(cmap, struct cmap, ncmap, ecmap); 169 if ((((int)(ecmap+1))&~0x80000000) > SYSPTSIZE*NBPG) 170 panic("sys pt too small"); 171 172 /* 173 * Clear allocated space, and make r/w entries 174 * for the space in the kernel map. 175 */ 176 unixsize = btoc((int)(ecmap+1) &~ 0x80000000); 177 for (i = mapaddr; i < unixsize; i++) { 178 *(int *)(&Sysmap[i]) = PG_V | PG_KW | firstaddr; 179 clearseg((unsigned)firstaddr); 180 firstaddr++; 181 } 182 if (firstaddr >= physmem - 8*UPAGES) 183 panic("no memory"); 184 mtpr(TBIA, 1); 185 186 /* 187 * Initialize callouts 188 */ 189 callfree = callout; 190 for (i = 1; i < ncallout; i++) 191 callout[i-1].c_next = &callout[i]; 192 193 /* 194 * Initialize memory allocator and swap 195 * and user page table maps. 196 * 197 * THE USER PAGE TABLE MAP IS CALLED ``kernelmap'' 198 * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME. 199 */ 200 meminit(firstaddr, maxmem); 201 maxmem = freemem; 202 printf("avail mem = %d\n", ctob(maxmem)); 203 rminit(kernelmap, (long)USRPTSIZE, (long)1, 204 "usrpt", nproc); 205 rminit(mbmap, (long)((nmbclusters - 1) * CLSIZE), (long)CLSIZE, 206 "mbclusters", nmbclusters/4); 207 208 /* 209 * Configure the system. 210 */ 211 configure(); 212 213 /* 214 * Clear restart inhibit flags. 215 */ 216 tocons(TXDB_CWSI); 217 tocons(TXDB_CCSI); 218 } 219 220 #ifdef PGINPROF 221 /* 222 * Return the difference (in microseconds) 223 * between the current time and a previous 224 * time as represented by the arguments. 225 * If there is a pending clock interrupt 226 * which has not been serviced due to high 227 * ipl, return error code. 228 */ 229 vmtime(otime, olbolt, oicr) 230 register int otime, olbolt, oicr; 231 { 232 233 if (mfpr(ICCS)&ICCS_INT) 234 return(-1); 235 else 236 return(((time.tv_sec-otime)*60 + lbolt-olbolt)*16667 + mfpr(ICR)-oicr); 237 } 238 #endif 239 240 /* 241 * Send an interrupt to process 242 * 243 * SHOULD CHANGE THIS TO PASS ONE MORE WORD SO THAT ALL INFORMATION 244 * PROVIDED BY HARDWARE IS AVAILABLE TO THE USER PROCESS. 245 */ 246 sendsig(p, n) 247 int (*p)(); 248 { 249 register int *usp, *regs; 250 251 regs = u.u_ar0; 252 usp = (int *)regs[SP]; 253 usp -= 5; 254 if ((int)usp <= USRSTACK - ctob(u.u_ssize)) 255 (void) grow((unsigned)usp); 256 ; /* Avoid asm() label botch */ 257 #ifndef lint 258 asm("probew $3,$20,(r11)"); 259 asm("beql bad"); 260 #else 261 if (useracc((caddr_t)usp, 0x20, 1)) 262 goto bad; 263 #endif 264 *usp++ = n; 265 if (n == SIGILL || n == SIGFPE) { 266 *usp++ = u.u_code; 267 u.u_code = 0; 268 } else 269 *usp++ = 0; 270 *usp++ = (int)p; 271 *usp++ = regs[PC]; 272 *usp++ = regs[PS]; 273 regs[SP] = (int)(usp - 5); 274 regs[PS] &= ~(PSL_CM|PSL_FPD); 275 regs[PC] = (int)u.u_pcb.pcb_sigc; 276 return; 277 278 asm("bad:"); 279 bad: 280 /* 281 * Process has trashed its stack; give it an illegal 282 * instruction to halt it in its tracks. 283 */ 284 u.u_signal[SIGILL] = SIG_DFL; 285 u.u_procp->p_siga0 &= ~(1<<(SIGILL-1)); 286 u.u_procp->p_siga1 &= ~(1<<(SIGILL-1)); 287 psignal(u.u_procp, SIGILL); 288 } 289 290 dorti() 291 { 292 struct frame frame; 293 register int sp; 294 register int reg, mask; 295 extern int ipcreg[]; 296 297 (void) copyin((caddr_t)u.u_ar0[FP], (caddr_t)&frame, sizeof (frame)); 298 sp = u.u_ar0[FP] + sizeof (frame); 299 u.u_ar0[PC] = frame.fr_savpc; 300 u.u_ar0[FP] = frame.fr_savfp; 301 u.u_ar0[AP] = frame.fr_savap; 302 mask = frame.fr_mask; 303 for (reg = 0; reg <= 11; reg++) { 304 if (mask&1) { 305 u.u_ar0[ipcreg[reg]] = fuword((caddr_t)sp); 306 sp += 4; 307 } 308 mask >>= 1; 309 } 310 sp += frame.fr_spa; 311 u.u_ar0[PS] = (u.u_ar0[PS] & 0xffff0000) | frame.fr_psw; 312 if (frame.fr_s) 313 sp += 4 + 4 * (fuword((caddr_t)sp) & 0xff); 314 /* phew, now the rei */ 315 u.u_ar0[PC] = fuword((caddr_t)sp); 316 sp += 4; 317 u.u_ar0[PS] = fuword((caddr_t)sp); 318 sp += 4; 319 u.u_ar0[PS] |= PSL_USERSET; 320 u.u_ar0[PS] &= ~PSL_USERCLR; 321 u.u_ar0[SP] = (int)sp; 322 } 323 324 /* 325 * Memenable enables the memory controlle corrected data reporting. 326 * This runs at regular intervals, turning on the interrupt. 327 * The interrupt is turned off, per memory controller, when error 328 * reporting occurs. Thus we report at most once per memintvl. 329 */ 330 int memintvl = MEMINTVL; 331 332 memenable() 333 { 334 register struct mcr *mcr; 335 register int m; 336 337 for (m = 0; m < nmcr; m++) { 338 mcr = mcraddr[m]; 339 switch (cpu) { 340 #if VAX780 341 case VAX_780: 342 M780_ENA(mcr); 343 break; 344 #endif 345 #if VAX750 346 case VAX_750: 347 M750_ENA(mcr); 348 break; 349 #endif 350 #if VAX730 351 case VAX_730: 352 M730_ENA(mcr); 353 break; 354 #endif 355 } 356 } 357 if (memintvl > 0) 358 timeout(memenable, (caddr_t)0, memintvl); 359 } 360 361 /* 362 * Memerr is the interrupt routine for corrected read data 363 * interrupts. It looks to see which memory controllers have 364 * unreported errors, reports them, and disables further 365 * reporting for a time on those controller. 366 */ 367 memerr() 368 { 369 register struct mcr *mcr; 370 register int m; 371 372 for (m = 0; m < nmcr; m++) { 373 mcr = mcraddr[m]; 374 switch (cpu) { 375 #if VAX780 376 case VAX_780: 377 if (M780_ERR(mcr)) { 378 printf("mcr%d: soft ecc addr %x syn %x\n", 379 m, M780_ADDR(mcr), M780_SYN(mcr)); 380 #ifdef TRENDATA 381 memlog(m, mcr); 382 #endif 383 M780_INH(mcr); 384 } 385 break; 386 #endif 387 #if VAX750 388 case VAX_750: 389 if (M750_ERR(mcr)) { 390 printf("mcr%d: soft ecc addr %x syn %x\n", 391 m, M750_ADDR(mcr), M750_SYN(mcr)); 392 M750_INH(mcr); 393 } 394 break; 395 #endif 396 #if VAX730 397 case VAX_730: 398 if (M730_ERR(mcr)) { 399 struct mcr amcr; 400 amcr.mc_reg[0] = mcr->mc_reg[0]; 401 printf("mcr%d: soft ecc addr %x syn %x\n", 402 m, M730_ADDR(&amcr), M730_SYN(&amcr)); 403 M730_INH(mcr); 404 } 405 break; 406 #endif 407 } 408 } 409 } 410 411 #ifdef TRENDATA 412 /* 413 * Figure out what chip to replace on Trendata boards. 414 * Assumes all your memory is Trendata or the non-Trendata 415 * memory never fails.. 416 */ 417 struct { 418 u_char m_syndrome; 419 char m_chip[4]; 420 } memlogtab[] = { 421 0x01, "C00", 0x02, "C01", 0x04, "C02", 0x08, "C03", 422 0x10, "C04", 0x19, "L01", 0x1A, "L02", 0x1C, "L04", 423 0x1F, "L07", 0x20, "C05", 0x38, "L00", 0x3B, "L03", 424 0x3D, "L05", 0x3E, "L06", 0x40, "C06", 0x49, "L09", 425 0x4A, "L10", 0x4c, "L12", 0x4F, "L15", 0x51, "L17", 426 0x52, "L18", 0x54, "L20", 0x57, "L23", 0x58, "L24", 427 0x5B, "L27", 0x5D, "L29", 0x5E, "L30", 0x68, "L08", 428 0x6B, "L11", 0x6D, "L13", 0x6E, "L14", 0x70, "L16", 429 0x73, "L19", 0x75, "L21", 0x76, "L22", 0x79, "L25", 430 0x7A, "L26", 0x7C, "L28", 0x7F, "L31", 0x80, "C07", 431 0x89, "U01", 0x8A, "U02", 0x8C, "U04", 0x8F, "U07", 432 0x91, "U09", 0x92, "U10", 0x94, "U12", 0x97, "U15", 433 0x98, "U16", 0x9B, "U19", 0x9D, "U21", 0x9E, "U22", 434 0xA8, "U00", 0xAB, "U03", 0xAD, "U05", 0xAE, "U06", 435 0xB0, "U08", 0xB3, "U11", 0xB5, "U13", 0xB6, "U14", 436 0xB9, "U17", 0xBA, "U18", 0xBC, "U20", 0xBF, "U23", 437 0xC1, "U25", 0xC2, "U26", 0xC4, "U28", 0xC7, "U31", 438 0xE0, "U24", 0xE3, "U27", 0xE5, "U29", 0xE6, "U30" 439 }; 440 441 memlog (m, mcr) 442 int m; 443 struct mcr *mcr; 444 { 445 register i; 446 447 switch (cpu) { 448 449 #if VAX780 450 case VAX_780: 451 for (i = 0; i < (sizeof (memlogtab) / sizeof (memlogtab[0])); i++) 452 if ((u_char)(M780_SYN(mcr)) == memlogtab[i].m_syndrome) { 453 printf ( 454 "mcr%d: replace %s chip in %s bank of memory board %d (0-15)\n", 455 m, 456 memlogtab[i].m_chip, 457 (M780_ADDR(mcr) & 0x8000) ? "upper" : "lower", 458 (M780_ADDR(mcr) >> 16)); 459 return; 460 } 461 printf ("mcr%d: multiple errors, not traceable\n", m); 462 break; 463 #endif 464 } 465 } 466 #endif 467 468 /* 469 * Invalidate single all pte's in a cluster 470 */ 471 tbiscl(v) 472 unsigned v; 473 { 474 register caddr_t addr; /* must be first reg var */ 475 register int i; 476 477 asm(".set TBIS,58"); 478 addr = ptob(v); 479 for (i = 0; i < CLSIZE; i++) { 480 #ifdef lint 481 mtpr(TBIS, addr); 482 #else 483 asm("mtpr r11,$TBIS"); 484 #endif 485 addr += NBPG; 486 } 487 } 488 489 int waittime = -1; 490 491 boot(paniced, arghowto) 492 int paniced, arghowto; 493 { 494 register int howto; /* r11 == how to boot */ 495 register int devtype; /* r10 == major of root dev */ 496 497 #ifdef lint 498 howto = 0; devtype = 0; 499 printf("howto %d, devtype %d\n", arghowto, devtype); 500 #endif 501 (void) spl1(); 502 howto = arghowto; 503 if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) { 504 waittime = 0; 505 update(); 506 printf("syncing disks... "); 507 #ifdef notdef 508 { register struct buf *bp; 509 int iter, nbusy; 510 511 for (iter = 0; iter < 10; iter++) { 512 nbusy = 0; 513 for (bp = &buf[nbuf]; --bp >= buf; ) 514 if (bp->b_flags & B_BUSY) 515 nbusy++; 516 if (nbusy == 0) 517 break; 518 printf("%d ", nbusy); 519 } 520 } 521 #else 522 DELAY(10000000); 523 #endif 524 printf("done\n"); 525 } 526 splx(0x1f); /* extreme priority */ 527 devtype = major(rootdev); 528 if (howto&RB_HALT) { 529 printf("halting (in tight loop); hit\n\t^P\n\tHALT\n\n"); 530 mtpr(IPL, 0x1f); 531 for (;;) 532 ; 533 } else { 534 if (paniced == RB_PANIC) { 535 doadump(); /* TXDB_BOOT's itsself */ 536 /*NOTREACHED*/ 537 } 538 tocons(TXDB_BOOT); 539 } 540 #if defined(VAX750) || defined(VAX730) 541 if (cpu != VAX_780) 542 { asm("movl r11,r5"); } /* boot flags go in r5 */ 543 #endif 544 for (;;) 545 asm("halt"); 546 /*NOTREACHED*/ 547 } 548 549 tocons(c) 550 { 551 552 while ((mfpr(TXCS)&TXCS_RDY) == 0) 553 continue; 554 mtpr(TXDB, c); 555 } 556 557 /* 558 * Doadump comes here after turning off memory management and 559 * getting on the dump stack, either when called above, or by 560 * the auto-restart code. 561 */ 562 dumpsys() 563 { 564 565 rpb.rp_flag = 1; 566 if ((minor(dumpdev)&07) != 1) 567 return; 568 printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); 569 printf("dump "); 570 switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { 571 572 case ENXIO: 573 printf("device bad\n"); 574 break; 575 576 case EFAULT: 577 printf("device not ready\n"); 578 break; 579 580 case EINVAL: 581 printf("area improper\n"); 582 break; 583 584 case EIO: 585 printf("i/o error"); 586 break; 587 588 default: 589 printf("succeeded"); 590 break; 591 } 592 } 593 594 /* 595 * Machine check error recovery code. 596 * Print out the machine check frame and then give up. 597 */ 598 #if defined(VAX780) || defined(VAX750) 599 char *mc780[] = { 600 "cp read", "ctrl str par", "cp tbuf par", "cp cache par", 601 "cp rdtimo", "cp rds", "ucode lost", 0, 602 0, 0, "ib tbuf par", 0, 603 "ib rds", "ib rd timo", 0, "ib cache par" 604 }; 605 #define MC780_TBPAR 2 606 #define MC750_TBPAR 2 607 #endif 608 #if VAX730 609 #define NMC730 12 610 char *mc730[] = { 611 "tb par", "bad retry", "bad intr id", "cant write ptem", 612 "unkn mcr err", "iib rd err", "nxm ref", "cp rds", 613 "unalgn ioref", "nonlw ioref", "bad ioaddr", "unalgn ubaddr", 614 }; 615 #define MC730_TBPAR 0 616 #endif 617 618 /* 619 * Frame for each cpu 620 */ 621 struct mc780frame { 622 int mc8_bcnt; /* byte count == 0x28 */ 623 int mc8_summary; /* summary parameter (as above) */ 624 int mc8_cpues; /* cpu error status */ 625 int mc8_upc; /* micro pc */ 626 int mc8_vaviba; /* va/viba register */ 627 int mc8_dreg; /* d register */ 628 int mc8_tber0; /* tbuf error reg 0 */ 629 int mc8_tber1; /* tbuf error reg 1 */ 630 int mc8_timo; /* timeout address divided by 4 */ 631 int mc8_parity; /* parity */ 632 int mc8_sbier; /* sbi error register */ 633 int mc8_pc; /* trapped pc */ 634 int mc8_psl; /* trapped psl */ 635 }; 636 struct mc750frame { 637 int mc5_bcnt; /* byte count == 0x28 */ 638 int mc5_summary; /* summary parameter (as above) */ 639 int mc5_va; /* virtual address register */ 640 int mc5_errpc; /* error pc */ 641 int mc5_mdr; 642 int mc5_svmode; /* saved mode register */ 643 int mc5_rdtimo; /* read lock timeout */ 644 int mc5_tbgpar; /* tb group parity error register */ 645 int mc5_cacherr; /* cache error register */ 646 int mc5_buserr; /* bus error register */ 647 int mc5_mcesr; /* machine check status register */ 648 int mc5_pc; /* trapped pc */ 649 int mc5_psl; /* trapped psl */ 650 }; 651 struct mc730frame { 652 int mc3_bcnt; /* byte count == 0xc */ 653 int mc3_summary; /* summary parameter */ 654 int mc3_parm[2]; /* parameter 1 and 2 */ 655 int mc3_pc; /* trapped pc */ 656 int mc3_psl; /* trapped psl */ 657 }; 658 659 machinecheck(cmcf) 660 caddr_t cmcf; 661 { 662 register u_int type = ((struct mc780frame *)cmcf)->mc8_summary; 663 664 printf("machine check %x: ", type); 665 switch (cpu) { 666 #if VAX780 667 case VAX_780: 668 #endif 669 #if VAX750 670 case VAX_750: 671 #endif 672 #if defined(VAX780) || defined(VAX750) 673 printf("%s%s\n", mc780[type&0xf], 674 (type&0xf0) ? " abort" : " fault"); 675 break; 676 #endif 677 #if VAX730 678 case VAX_730: 679 if (type < NMC730) 680 printf("%s", mc730[type]); 681 printf("\n"); 682 break; 683 #endif 684 } 685 switch (cpu) { 686 #if VAX780 687 case VAX_780: { 688 register struct mc780frame *mcf = (struct mc780frame *)cmcf; 689 register int sbifs; 690 printf("\tcpues %x upc %x va/viba %x dreg %x tber %x %x\n", 691 mcf->mc8_cpues, mcf->mc8_upc, mcf->mc8_vaviba, 692 mcf->mc8_dreg, mcf->mc8_tber0, mcf->mc8_tber1); 693 sbifs = mfpr(SBIFS); 694 printf("\ttimo %x parity %x sbier %x pc %x psl %x sbifs %x\n", 695 mcf->mc8_timo*4, mcf->mc8_parity, mcf->mc8_sbier, 696 mcf->mc8_pc, mcf->mc8_psl, sbifs); 697 /* THE FUNNY BITS IN THE FOLLOWING ARE FROM THE ``BLACK */ 698 /* BOOK'' AND SHOULD BE PUT IN AN ``sbi.h'' */ 699 mtpr(SBIFS, sbifs &~ 0x2000000); 700 mtpr(SBIER, mfpr(SBIER) | 0x70c0); 701 break; 702 } 703 #endif 704 #if VAX750 705 case VAX_750: { 706 register struct mc750frame *mcf = (struct mc750frame *)cmcf; 707 printf("\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n", 708 mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode, 709 mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr); 710 printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n", 711 mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl, 712 mfpr(MCSR)); 713 mtpr(MCESR, 0xf); 714 if ((type&0xf)==MC750_TBPAR) { 715 printf("tbuf par!?!: flushing and returning\n"); 716 mtpr(TBIA, 0); 717 return; 718 } 719 break; 720 } 721 #endif 722 #if VAX730 723 case VAX_730: { 724 register struct mc730frame *mcf = (struct mc730frame *)cmcf; 725 printf("params %x,%x pc %x psl %x mcesr %x\n", 726 mcf->mc3_parm[0], mcf->mc3_parm[1], 727 mcf->mc3_pc, mcf->mc3_psl, mfpr(MCESR)); 728 mtpr(MCESR, 0xf); 729 break; 730 } 731 #endif 732 } 733 memerr(); 734 panic("mchk"); 735 } 736 737 #ifdef notdef 738 microtime(tvp) 739 struct timeval *tvp; 740 { 741 int s = spl7(); 742 743 tvp->tv_sec = time.tv_sec; 744 tvp->tv_usec = (lbolt+1)*16667 + mfpr(ICR); 745 while (tvp->tv_usec > 1000000) { 746 tvp->tv_sec++; 747 tvp->tv_usec -= 1000000; 748 } 749 splx(s); 750 } 751 #endif 752 753 physstrat(bp, strat, prio) 754 struct buf *bp; 755 int (*strat)(), prio; 756 { 757 int s; 758 759 (*strat)(bp); 760 s = spl6(); 761 while ((bp->b_flags & B_DONE) == 0) 762 sleep((caddr_t)bp, prio); 763 splx(s); 764 } 765