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