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