|
|
1.1 ! root 1: /* machdep.c 6.2 83/10/02 */ ! 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: #ifdef SYS5 ! 29: #include "../h/msg.h" ! 30: #endif SYS5 ! 31: ! 32: #include "../machine/mem.h" ! 33: #include "../machine/mtpr.h" ! 34: #include "../machine/cp.h" ! 35: #include "../vba/vbavar.h" ! 36: ! 37: #ifdef AUDITTRAIL ! 38: #include "../h/audit.h" ! 39: #endif AUDITTRAIL ! 40: ! 41: int icode[] = ! 42: /* pushab argp */ ! 43: /* pushab file */ ! 44: /* pushl $2 */ ! 45: /* movab (sp),fp */ ! 46: /* kcall $exec */ ! 47: /* here: brb here */ ! 48: /* .file: .ascii "/etc/" */ ! 49: /* args: .ascii "init\0" */ ! 50: /* .align 2 */ ! 51: /* argp: .long args */ ! 52: /* .long 0 */ ! 53: { ! 54: 0xf9af19f9, ! 55: 0xaf09dd02, ! 56: 0xe96e5dcf, ! 57: 0x0b11fe2f, ! 58: 0x6574632f, ! 59: 0x696e6974, ! 60: 0x00000000, ! 61: 0x00000014, ! 62: 0x00000000, ! 63: }; ! 64: int szicode = sizeof(icode); ! 65: ! 66: /* ! 67: * Declare these as initialized data so we can patch them. ! 68: */ ! 69: int nbuf = 0; ! 70: int nswbuf = 0; ! 71: int bufpages = 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: register int mapaddr, j; ! 83: register caddr_t v; ! 84: register int maxbufs, base, residual; ! 85: extern char etext; ! 86: ! 87: /* ! 88: * Initialize error message buffer (at end of core). ! 89: */ ! 90: maxmem -= btoc(sizeof (struct msgbuf)); ! 91: pte = msgbufmap; ! 92: for (i = 0; i < btoc(sizeof (struct msgbuf)); i++) ! 93: *(int *)pte++ = PG_V | PG_KW | (maxmem + i); ! 94: mtpr(1,TBIA); ! 95: ! 96: /* ! 97: * Good {morning,afternoon,evening,night}. ! 98: */ ! 99: printf(version); ! 100: printf("real mem = %d\n", ctob(maxmem)); ! 101: ! 102: /* ! 103: * Determine how many buffers to allocate. ! 104: * Use 10% of memory, with min of 16. ! 105: * We allocate 1/2 as many swap buffer headers as file i/o buffers. ! 106: */ ! 107: maxbufs = ((SYSPTSIZE * NBPG) - (5 * (int)(&etext - 0xc0000000))) / ! 108: MAXBSIZE; ! 109: if (bufpages == 0) ! 110: bufpages = (physmem * NBPG) / 10 / CLBYTES; ! 111: if (nbuf == 0) { ! 112: nbuf = bufpages / 2; ! 113: if (nbuf < 16) ! 114: nbuf = 16; ! 115: if (nbuf > maxbufs) ! 116: nbuf = maxbufs; ! 117: } ! 118: if (bufpages > nbuf * (MAXBSIZE / CLBYTES)) ! 119: bufpages = nbuf * (MAXBSIZE / CLBYTES); ! 120: if (nswbuf == 0) { ! 121: nswbuf = (nbuf / 2) &~ 1; /* force even */ ! 122: if (nswbuf > 256) ! 123: nswbuf = 256; /* sanity */ ! 124: } ! 125: ! 126: /* ! 127: * Allocate space for system data structures. ! 128: * The first available real memory address is in "firstaddr". ! 129: * As pages of memory are allocated, "firstaddr" is incremented. ! 130: * The first available kernel virtual address is in "v". ! 131: * As pages of kernel virtual memory are allocated, "v" is incremented. ! 132: * An index into the kernel page table corresponding to the ! 133: * virtual memory address maintained in "v" is kept in "mapaddr". ! 134: */ ! 135: mapaddr = firstaddr; ! 136: v = (caddr_t)(0xc0000000 | (firstaddr * NBPG)); ! 137: #define valloc(name, type, num) \ ! 138: (name) = (type *)(v); (v) = (caddr_t)((name)+(num)) ! 139: #define valloclim(name, type, num, lim) \ ! 140: (name) = (type *)(v); (v) = (caddr_t)((lim) = ((name)+(num))) ! 141: valloc(buffers, char, MAXBSIZE * nbuf); ! 142: base = bufpages / nbuf; ! 143: residual = bufpages % nbuf; ! 144: for (i = 0; i < residual; i++) { ! 145: for (j = 0; j < (base + 1) * CLSIZE; j++) { ! 146: *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr; ! 147: clearseg((unsigned)firstaddr); ! 148: firstaddr++; ! 149: } ! 150: mapaddr += MAXBSIZE / NBPG; ! 151: } ! 152: for (i = residual; i < nbuf; i++) { ! 153: for (j = 0; j < base * CLSIZE; j++) { ! 154: *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr; ! 155: clearseg((unsigned)firstaddr); ! 156: firstaddr++; ! 157: } ! 158: mapaddr += MAXBSIZE / NBPG; ! 159: } ! 160: valloc(buf, struct buf, nbuf); ! 161: valloc(swbuf, struct buf, nswbuf); ! 162: valloclim(inode, struct inode, ninode, inodeNINODE); ! 163: valloclim(file, struct file, nfile, fileNFILE); ! 164: valloclim(proc, struct proc, nproc, procNPROC); ! 165: valloclim(text, struct text, ntext, textNTEXT); ! 166: #ifdef SYS5 ! 167: valloclim(shmem, struct shmid_ds, nshmem, shmemNSHMEM); ! 168: #endif SYS5 ! 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 SYS5 ! 176: valloc(msgmap, struct map, MSGMAP); ! 177: #endif SYS5 ! 178: #ifdef QUOTA ! 179: valloclim(quota, struct quota, nquota, quotaNQUOTA); ! 180: valloclim(dquot, struct dquot, ndquot, dquotNDQUOT); ! 181: #endif ! 182: ! 183: #ifdef AUDITTRAIL ! 184: valloc(audbuf, struct audbuf, naudbuf); ! 185: #endif AUDITTRAIL ! 186: /* ! 187: * Now allocate space for core map ! 188: * Allow space for all of phsical memory minus the amount ! 189: * dedicated to the system. The amount of physical memory ! 190: * dedicated to the system is the total virtual memory of ! 191: * the system minus the space in the buffers which is not ! 192: * allocated real memory. ! 193: */ ! 194: ncmap = (physmem*NBPG - ((int)v &~ 0xc0000000) + ! 195: (nbuf * MAXBSIZE - bufpages * CLBYTES)) / ! 196: (NBPG*CLSIZE + sizeof (struct cmap)); ! 197: valloclim(cmap, struct cmap, ncmap, ecmap); ! 198: if ((((int)(ecmap+1))&~0xc0000000) > SYSPTSIZE*NBPG) ! 199: panic("sys pt too small"); ! 200: ! 201: /* ! 202: * Clear allocated space, and make r/w entries ! 203: * for the space in the kernel map. ! 204: */ ! 205: unixsize = btoc((int)(ecmap+1) &~ 0xc0000000); ! 206: for (i = mapaddr; i < unixsize; i++) { ! 207: *(int *)(&Sysmap[i]) = PG_V | PG_KW | firstaddr; ! 208: clearseg((unsigned)firstaddr); ! 209: firstaddr++; ! 210: } ! 211: if (firstaddr >= physmem - 8*UPAGES) ! 212: panic("no memory"); ! 213: mtpr(1,TBIA); ! 214: ! 215: /* ! 216: * Initialize callouts ! 217: */ ! 218: callfree = callout; ! 219: for (i = 1; i < ncallout; i++) ! 220: callout[i-1].c_next = &callout[i]; ! 221: ! 222: /* ! 223: * Initialize memory allocator and swap ! 224: * and user page table maps. ! 225: * ! 226: * THE USER PAGE TABLE MAP IS CALLED ``kernelmap'' ! 227: * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME. ! 228: */ ! 229: meminit(firstaddr, maxmem); ! 230: maxmem = freemem; ! 231: printf("avail mem = %d\n", ctob(maxmem)); ! 232: printf("using %d buffers containing %d bytes of memory\n", ! 233: nbuf, bufpages * CLBYTES); ! 234: rminit(kernelmap, (long)USRPTSIZE, (long)1, ! 235: "usrpt", nproc); ! 236: rminit(mbmap, (long)((nmbclusters - 1) * CLSIZE), (long)CLSIZE, ! 237: "mbclusters", nmbclusters/4); ! 238: #ifdef SYS5 ! 239: rminit(msgmap, (long)MSGSEG, (long)1, "msgmap", MSGMAP); ! 240: #endif SYS5 ! 241: intenable = 1; /* Enable interrupts from now on */ ! 242: /* ! 243: * Configure the system. ! 244: */ ! 245: configure(); ! 246: } ! 247: ! 248: #ifdef PGINPROF ! 249: /* ! 250: * Return the difference (in microseconds) ! 251: * between the current time and a previous ! 252: * time as represented by the arguments. ! 253: * If there is a pending clock interrupt ! 254: * which has not been serviced due to high ! 255: * ipl, return error code. ! 256: */ ! 257: vmtime(otime, olbolt, oicr) ! 258: register int otime, olbolt, oicr; ! 259: { ! 260: return(((time.tv_sec-otime)*60 + lbolt-olbolt)*16667); ! 261: } ! 262: #endif ! 263: ! 264: /* ! 265: * Send an interrupt to process. ! 266: * ! 267: * Stack is set up to allow sigcode stored ! 268: * in u. to call routine, followed by chmk ! 269: * to sigcleanup routine below. After sigcleanup ! 270: * resets the signal mask and the stack, it ! 271: * returns to user who then unwinds with the ! 272: * rei at the bottom of sigcode. ! 273: */ ! 274: sendsig(p, sig, sigmask) ! 275: int (*p)(), sig, sigmask; ! 276: { ! 277: register struct sigcontext *scp; /* know to be r12 */ ! 278: register int *regs; ! 279: register struct sigframe { ! 280: int sf_signum; ! 281: int sf_code; ! 282: struct sigcontext *sf_scp; ! 283: int (*sf_handler)(); ! 284: int r1; ! 285: int r0; ! 286: struct sigcontext *sf_scpcopy; ! 287: } *fp; /* known to be r10 */ ! 288: int oonstack; ! 289: ! 290: regs = u.u_ar0; ! 291: oonstack = u.u_onstack; ! 292: scp = (struct sigcontext *)regs[SP] - 1; ! 293: #define mask(s) (1<<((s)-1)) ! 294: if (!u.u_onstack && (u.u_sigonstack & mask(sig))) { ! 295: fp = (struct sigframe *)u.u_sigsp - 1; ! 296: u.u_onstack = 1; ! 297: } else ! 298: fp = (struct sigframe *)scp - 1; ! 299: /* ! 300: * Must build signal handler context on stack to be returned to ! 301: * so that rei instruction in sigcode will pop ps and pc ! 302: * off correct stack. The remainder of the signal state ! 303: * used in calling the handler must be placed on the stack ! 304: * on which the handler is to operate so that the calls ! 305: * in sigcode will save the registers and such correctly. ! 306: */ ! 307: if (!oonstack && (int)fp <= USRSTACK - ctob(u.u_ssize)) ! 308: grow((unsigned)fp); ! 309: ; ! 310: #ifndef lint ! 311: asm("probew $1,(r10),$7*4"); ! 312: asm("jeql bad"); ! 313: #else ! 314: if (useracc((caddr_t)fp, sizeof (struct sigframe), 1)) ! 315: goto bad; ! 316: #endif ! 317: if (!u.u_onstack && (int)scp <= USRSTACK - ctob(u.u_ssize)) ! 318: grow((unsigned)scp); ! 319: ; /* Avoid asm() label botch */ ! 320: #ifndef lint ! 321: asm("probew $1,(r12),$5*4"); ! 322: asm("beql bad"); ! 323: #else ! 324: if (useracc((caddr_t)scp, sizeof (struct sigcontext), 1)) ! 325: goto bad; ! 326: #endif ! 327: fp->sf_signum = sig; ! 328: if (sig == SIGILL || sig == SIGFPE) { ! 329: fp->sf_code = u.u_code; ! 330: u.u_code = 0; ! 331: } else ! 332: fp->sf_code = 0; ! 333: fp->sf_scp = scp; ! 334: fp->sf_handler = p; ! 335: fp->r1 = regs[R1]; /* These are not saved by the C compiler */ ! 336: fp->r0 = regs[R0]; ! 337: /* ! 338: * Duplicate the pointer to the sigcontext structure. ! 339: * This one doesn't get popped by the ret, and is used ! 340: * by sigcleanup to reset the signal state on inward return. ! 341: */ ! 342: fp->sf_scpcopy = scp; ! 343: /* sigcontext goes on previous stack */ ! 344: scp->sc_onstack = oonstack; ! 345: scp->sc_mask = sigmask; ! 346: /* setup rei */ ! 347: scp->sc_sp = (int)&scp->sc_pc; ! 348: scp->sc_pc = regs[PC]; ! 349: scp->sc_ps = regs[PS]; ! 350: regs[SP] = (int)fp; ! 351: regs[PC] = (int)u.u_pcb.pcb_sigc; ! 352: return; ! 353: ! 354: asm("bad:"); ! 355: bad: ! 356: /* ! 357: * Process has trashed its stack; give it an illegal ! 358: * instruction to halt it in its tracks. ! 359: */ ! 360: u.u_signal[SIGILL] = SIG_DFL; ! 361: sig = mask(SIGILL); ! 362: u.u_procp->p_sigignore &= ~sig; ! 363: u.u_procp->p_sigcatch &= ~sig; ! 364: u.u_procp->p_sigmask &= ~sig; ! 365: psignal(u.u_procp, SIGILL); ! 366: } ! 367: ! 368: /* ! 369: * Routine to cleanup state after a signal ! 370: * has been taken. Reset signal mask and ! 371: * stack state from context left by sendsig (above). ! 372: * Pop these values in preparation for rei which ! 373: * follows return from this routine. ! 374: */ ! 375: sigcleanup() ! 376: { ! 377: register struct sigcontext *scp; /* known as R12 */ ! 378: ! 379: scp = (struct sigcontext *)fuword((caddr_t)u.u_ar0[SP]); ! 380: if ((int)scp == -1) ! 381: return; ! 382: #ifndef lint ! 383: ; /* Avoid asm() label botch */ ! 384: /* only probe 12 here because that's all we need */ ! 385: asm("prober $1,(r12),$12"); ! 386: asm("bnequ 1f; ret; 1:"); ! 387: #else ! 388: if (useracc((caddr_t)scp, sizeof (*scp), 0)) ! 389: return; ! 390: #endif ! 391: u.u_onstack = scp->sc_onstack & 01; ! 392: u.u_procp->p_sigmask = ! 393: scp->sc_mask &~ (mask(SIGKILL)|mask(SIGCONT)|mask(SIGSTOP)); ! 394: u.u_ar0[SP] = scp->sc_sp; ! 395: } ! 396: #undef mask ! 397: ! 398: int waittime = -1; ! 399: ! 400: boot(paniced, arghowto) ! 401: int paniced, arghowto; ! 402: { ! 403: register long dummy; ! 404: register int howto; /* r11 == how to boot */ ! 405: register int devtype; /* r10 == major of root dev */ ! 406: ! 407: #ifdef lint ! 408: howto = 0; devtype = 0; ! 409: printf("howto %d, devtype %d\n", arghowto, devtype); ! 410: #endif ! 411: if (paniced == RB_PANIC) { ! 412: register unsigned i, n, *fp, pc; ! 413: fp = (unsigned *)&paniced - 1; ! 414: while(((int)fp&03)==0 && ((pc = fp[-2])&0xc0000000)==0xc0000000) { ! 415: printf("%x (", fp); ! 416: if(fp[-1] == 0x1fff0004) /* trap */ ! 417: n = 6; ! 418: else ! 419: n = (fp[-1]&0xffff)/4; ! 420: for(i=1; i<n; i++) { ! 421: if(i > 1) ! 422: printf(","); ! 423: printf("%x", fp[i]); ! 424: } ! 425: printf(") from %x\n", pc); ! 426: if(fp[-1] == 0x1fff0004) { /* trap */ ! 427: printf("regs: "); ! 428: for(i= -15; i<=-3; i++) { ! 429: if(i > -15) ! 430: printf(","); ! 431: printf("%x", fp[i]); ! 432: } ! 433: printf("\n"); ! 434: } ! 435: fp = *(unsigned **)fp; ! 436: if (fp == NULL) break; ! 437: } ! 438: } ! 439: (void) spl1(); ! 440: howto = arghowto; ! 441: if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) { ! 442: waittime = 0; ! 443: update(); ! 444: printf("syncing disks... "); ! 445: #ifdef notdef ! 446: DELAY(10000000); ! 447: #else ! 448: { register struct buf *bp; ! 449: int iter, nbusy, oldnbusy; ! 450: ! 451: printf ("\tBlocks to sync : "); ! 452: oldnbusy = 0; ! 453: for (;;) { ! 454: DELAY(1000); ! 455: nbusy = 0; ! 456: for (bp = &buf[nbuf]; --bp >= buf; ) ! 457: if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY) ! 458: nbusy++; ! 459: if (nbusy == 0) ! 460: break; ! 461: if (nbusy != oldnbusy) { ! 462: iter = 0; ! 463: printf("%d ", nbusy); ! 464: oldnbusy = nbusy; ! 465: } else { ! 466: if (++iter >= 100) { ! 467: printf (" - disk I/O stopped (?), giving up\n"); ! 468: DELAY(10000); ! 469: break; ! 470: } ! 471: } ! 472: } ! 473: } ! 474: #endif ! 475: printf("done\n\n"); ! 476: } ! 477: splx(0x1f); /* extreme priority */ ! 478: devtype = major(rootdev); ! 479: if (howto&RB_HALT) { ! 480: printf("halting (in tight loop); hit <return>~h\n\n"); ! 481: mtpr(0x1f,IPL); ! 482: for (;;) ! 483: ; ! 484: } else { ! 485: if (paniced == RB_PANIC) { ! 486: doadump(); /* TXDB_BOOT's itsself */ ! 487: /*NOTREACHED*/ ! 488: } ! 489: tocons(CPBOOT); ! 490: } ! 491: for (;;) ! 492: asm("halt"); ! 493: /*NOTREACHED*/ ! 494: } ! 495: ! 496: ! 497: ! 498: /* ! 499: * Send the given comand ('c') to the console processor. ! 500: * Assumed to be one of the last things the OS does before ! 501: * halting or rebooting. ! 502: */ ! 503: ! 504: struct cphdr *lasthdr; /* Available in "dev/cons.c" */ ! 505: ! 506: struct cpdcb_o cpcontrol; ! 507: ! 508: tocons(command) ! 509: int command; ! 510: { ! 511: ! 512: int timeout; ! 513: ! 514: cpcontrol.cp_hdr.cp_unit = CPUNIT; ! 515: cpcontrol.cp_hdr.cp_comm = (char) command; ! 516: if (command != CPBOOT) ! 517: cpcontrol.cp_hdr.cp_count = 1; /* Just for sanity */ ! 518: else { ! 519: cpcontrol.cp_hdr.cp_count = 4; ! 520: *(int *)cpcontrol.cp_buf = 0; /* r11 value for reboot */ ! 521: } ! 522: timeout = 100000; /* Delay loop */ ! 523: while (timeout-- && !(lasthdr->cp_unit & CPDONE)) ! 524: uncache(&lasthdr->cp_unit); ! 525: /* Give up, force it to listen */ ! 526: mtpr ( vtoph(0, &cpcontrol), CPMDCB); ! 527: } ! 528: ! 529: /* ! 530: * Invalidate single all pte's in a cluster ! 531: */ ! 532: tbiscl(v) ! 533: unsigned v; ! 534: { ! 535: register caddr_t addr; /* must be first reg var */ ! 536: register int i; ! 537: ! 538: addr = ptob(v); ! 539: for (i = 0; i < CLSIZE; i++) { ! 540: mtpr(addr, TBIS); ! 541: addr += NBPG; ! 542: } ! 543: } ! 544: ! 545: int dumpmag = 0x8fca0101; /* magic number for savecore */ ! 546: int dumpsize = 0; /* also for savecore */ ! 547: /* ! 548: * Doadump comes here after turning off memory management and ! 549: * getting on the dump stack, either when called above, or by ! 550: * the auto-restart code. ! 551: */ ! 552: dumpsys() ! 553: { ! 554: ! 555: #ifdef notdef ! 556: if ((minor(dumpdev)&07) != 1) ! 557: return; ! 558: #endif ! 559: dumpsize = physmem; ! 560: printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); ! 561: printf("dump "); ! 562: switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { ! 563: ! 564: case ENXIO: ! 565: printf("device bad\n"); ! 566: break; ! 567: ! 568: case EFAULT: ! 569: printf("device not ready\n"); ! 570: break; ! 571: ! 572: case EINVAL: ! 573: printf("area improper\n"); ! 574: break; ! 575: ! 576: case EIO: ! 577: printf("i/o error\n"); ! 578: break; ! 579: ! 580: default: ! 581: printf("succeeded\n"); ! 582: break; ! 583: } ! 584: printf("Rebooting the system ...\n\n"); ! 585: tocons(CPBOOT); ! 586: } ! 587: ! 588: ! 589: /* ! 590: * Bus error 'recovery' code. ! 591: * Print out the buss frame and then give up. ! 592: * (More information from special registers can be printed here.) ! 593: * ! 594: */ ! 595: ! 596: /* ! 597: * Frame for bus error ! 598: */ ! 599: struct buserframe { ! 600: int which_bus; /* primary or secondary */ ! 601: int memerreg; /* memory error register */ ! 602: int trp_pc; /* trapped pc */ ! 603: int trp_psl; /* trapped psl */ ! 604: }; ! 605: ! 606: buserror(busef) ! 607: caddr_t busef; ! 608: { ! 609: register struct buserframe *frameptr; ! 610: register long hardreg; ! 611: ! 612: ! 613: frameptr = (struct buserframe *)busef; ! 614: printf("bus error at address %x, psl = %x\n", ! 615: frameptr->trp_pc,frameptr->trp_psl); ! 616: hardreg = frameptr->memerreg; ! 617: printf("\tMEAR = %x\n",((hardreg&MEAR)>>16)&0xffff); ! 618: switch (hardreg & ERRCD){ ! 619: case (APE): printf("\tAdress parity error.Should not reach this point!! \n"); ! 620: break; ! 621: case (DPE): printf("\tData parity error.\n"); ! 622: break; ! 623: case (DCE): printf("\tData check error.\n"); ! 624: break; ! 625: case (VTO): printf("\tVersabus timeout.\n"); ! 626: break; ! 627: case (VBE): printf("\tVersabus error.Should not reach this point!! \n"); ! 628: break; ! 629: case (NEM): printf("\tNon existent memory.\n"); ! 630: break; ! 631: default: printf("\tUnknown error code: %x\n", ! 632: hardreg&ERRCD); ! 633: } ! 634: if (hardreg&AXE) printf("\tAdapter external error\n"); ! 635: printf ("\tError master : "); ! 636: if (hardreg&ERM) printf("Versabus\n"); ! 637: else printf ("Tahoe\n"); ! 638: if (hardreg&IVV) ! 639: printf("\tIllegal interrupt vector, from ipl %d\n", ! 640: (hardreg >> 2) & 7); ! 641: ! 642: hardreg = frameptr->which_bus; ! 643: printf("\tMCBR = %x\n", ((hardreg&MCBR)>>16)&0xffff); ! 644: printf("\tVersabus type : %x\n", hardreg&0xffc3); ! 645: if (frameptr->memerreg&IVV) return; ! 646: panic("buserror"); ! 647: } ! 648: ! 649: ! 650: physstrat(bp, strat, prio) ! 651: struct buf *bp; ! 652: int (*strat)(), prio; ! 653: { ! 654: int s; ! 655: ! 656: (*strat)(bp); ! 657: /* pageout daemon doesn't wait for pushed pages */ ! 658: if (bp->b_flags & B_DIRTY) ! 659: return; ! 660: s = spl8(); ! 661: while ((bp->b_flags & B_DONE) == 0) ! 662: sleep((caddr_t)bp, prio); ! 663: splx(s); ! 664: } ! 665: ! 666: ! 667: /*ARGSUSED*/ ! 668: mtpr (value, regno) ! 669: { ! 670: asm("mtpr 4(fp), 8(fp)"); ! 671: } ! 672: ! 673: /*ARGSUSED*/ ! 674: int ! 675: mfpr (regno) ! 676: { ! 677: asm("mfpr 4(fp),r0"); ! 678: #ifdef lint ! 679: return(0); ! 680: #endif ! 681: } ! 682:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.