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