|
|
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: #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: * Stack is set up to allow sigcode stored ! 250: * in u. to call routine, followed by chmk ! 251: * to sigcleanup routine below. After sigcleanup ! 252: * resets the signal mask and the stack, it ! 253: * returns to user who then unwinds with the ! 254: * rei at the bottom of sigcode. ! 255: */ ! 256: sendsig(p, sig, sigmask) ! 257: int (*p)(), sig, sigmask; ! 258: { ! 259: register struct sigcontext *scp; /* know to be r11 */ ! 260: register int *regs; ! 261: register struct sigframe { ! 262: int sf_signum; ! 263: int sf_code; ! 264: struct sigcontext *sf_scp; ! 265: int (*sf_handler)(); ! 266: struct sigcontext *sf_scpcopy; ! 267: } *fp; /* known to be r9 */ ! 268: int oonstack; ! 269: ! 270: regs = u.u_ar0; ! 271: oonstack = u.u_onstack; ! 272: scp = (struct sigcontext *)regs[SP] - 1; ! 273: #define mask(s) (1<<((s)-1)) ! 274: if (!u.u_onstack && (u.u_sigonstack & mask(sig))) { ! 275: fp = (struct sigframe *)u.u_sigsp - 1; ! 276: u.u_onstack = 1; ! 277: } else ! 278: fp = (struct sigframe *)scp - 1; ! 279: /* ! 280: * Must build signal handler context on stack to be returned to ! 281: * so that rei instruction in sigcode will pop ps and pc ! 282: * off correct stack. The remainder of the signal state ! 283: * used in calling the handler must be placed on the stack ! 284: * on which the handler is to operate so that the calls ! 285: * in sigcode will save the registers and such correctly. ! 286: */ ! 287: if (!oonstack && (int)fp <= USRSTACK - ctob(u.u_ssize)) ! 288: grow((unsigned)fp); ! 289: ; ! 290: #ifndef lint ! 291: asm("probew $3,$20,(r9)"); ! 292: asm("jeql bad"); ! 293: #else ! 294: if (useracc((caddr_t)fp, sizeof (struct sigframe), 1)) ! 295: goto bad; ! 296: #endif ! 297: if (!u.u_onstack && (int)scp <= USRSTACK - ctob(u.u_ssize)) ! 298: grow((unsigned)scp); ! 299: ; /* Avoid asm() label botch */ ! 300: #ifndef lint ! 301: asm("probew $3,$20,(r11)"); ! 302: asm("beql bad"); ! 303: #else ! 304: if (useracc((caddr_t)scp, sizeof (struct sigcontext), 1)) ! 305: goto bad; ! 306: #endif ! 307: fp->sf_signum = sig; ! 308: if (sig == SIGILL || sig == SIGFPE) { ! 309: fp->sf_code = u.u_code; ! 310: u.u_code = 0; ! 311: } else ! 312: fp->sf_code = 0; ! 313: fp->sf_scp = scp; ! 314: fp->sf_handler = p; ! 315: /* ! 316: * Duplicate the pointer to the sigcontext structure. ! 317: * This one doesn't get popped by the ret, and is used ! 318: * by sigcleanup to reset the signal state on inward return. ! 319: */ ! 320: fp->sf_scpcopy = scp; ! 321: /* sigcontext goes on previous stack */ ! 322: scp->sc_onstack = oonstack; ! 323: scp->sc_mask = sigmask; ! 324: /* setup rei */ ! 325: scp->sc_sp = (int)&scp->sc_pc; ! 326: scp->sc_pc = regs[PC]; ! 327: scp->sc_ps = regs[PS]; ! 328: regs[SP] = (int)fp; ! 329: regs[PS] &= ~(PSL_CM|PSL_FPD); ! 330: regs[PC] = (int)u.u_pcb.pcb_sigc; ! 331: return; ! 332: ! 333: asm("bad:"); ! 334: bad: ! 335: /* ! 336: * Process has trashed its stack; give it an illegal ! 337: * instruction to halt it in its tracks. ! 338: */ ! 339: u.u_signal[SIGILL] = SIG_DFL; ! 340: sig = mask(SIGILL); ! 341: u.u_procp->p_sigignore &= ~sig; ! 342: u.u_procp->p_sigcatch &= ~sig; ! 343: u.u_procp->p_sigmask &= ~sig; ! 344: psignal(u.u_procp, SIGILL); ! 345: } ! 346: ! 347: /* ! 348: * Routine to cleanup state after a signal ! 349: * has been taken. Reset signal mask and ! 350: * stack state from context left by sendsig (above). ! 351: * Pop these values in preparation for rei which ! 352: * follows return from this routine. ! 353: */ ! 354: sigcleanup() ! 355: { ! 356: register struct sigcontext *scp; ! 357: ! 358: scp = (struct sigcontext *)fuword((caddr_t)u.u_ar0[SP]); ! 359: if ((int)scp == -1) ! 360: return; ! 361: #ifndef lint ! 362: /* only probe 12 here because that's all we need */ ! 363: asm("prober $3,$12,(r11)"); ! 364: asm("bnequ 1f; ret; 1:"); ! 365: #else ! 366: if (useracc((caddr_t)scp, sizeof (*scp), 0)) ! 367: return; ! 368: #endif ! 369: u.u_onstack = scp->sc_onstack & 01; ! 370: u.u_procp->p_sigmask = ! 371: scp->sc_mask &~ (mask(SIGKILL)|mask(SIGCONT)|mask(SIGSTOP)); ! 372: u.u_ar0[SP] = scp->sc_sp; ! 373: } ! 374: #undef mask ! 375: ! 376: #ifdef notdef ! 377: dorti() ! 378: { ! 379: struct frame frame; ! 380: register int sp; ! 381: register int reg, mask; ! 382: extern int ipcreg[]; ! 383: ! 384: (void) copyin((caddr_t)u.u_ar0[FP], (caddr_t)&frame, sizeof (frame)); ! 385: sp = u.u_ar0[FP] + sizeof (frame); ! 386: u.u_ar0[PC] = frame.fr_savpc; ! 387: u.u_ar0[FP] = frame.fr_savfp; ! 388: u.u_ar0[AP] = frame.fr_savap; ! 389: mask = frame.fr_mask; ! 390: for (reg = 0; reg <= 11; reg++) { ! 391: if (mask&1) { ! 392: u.u_ar0[ipcreg[reg]] = fuword((caddr_t)sp); ! 393: sp += 4; ! 394: } ! 395: mask >>= 1; ! 396: } ! 397: sp += frame.fr_spa; ! 398: u.u_ar0[PS] = (u.u_ar0[PS] & 0xffff0000) | frame.fr_psw; ! 399: if (frame.fr_s) ! 400: sp += 4 + 4 * (fuword((caddr_t)sp) & 0xff); ! 401: /* phew, now the rei */ ! 402: u.u_ar0[PC] = fuword((caddr_t)sp); ! 403: sp += 4; ! 404: u.u_ar0[PS] = fuword((caddr_t)sp); ! 405: sp += 4; ! 406: u.u_ar0[PS] |= PSL_USERSET; ! 407: u.u_ar0[PS] &= ~PSL_USERCLR; ! 408: u.u_ar0[SP] = (int)sp; ! 409: } ! 410: #endif ! 411: ! 412: /* ! 413: * Memenable enables the memory controlle corrected data reporting. ! 414: * This runs at regular intervals, turning on the interrupt. ! 415: * The interrupt is turned off, per memory controller, when error ! 416: * reporting occurs. Thus we report at most once per memintvl. ! 417: */ ! 418: int memintvl = MEMINTVL; ! 419: ! 420: memenable() ! 421: { ! 422: register struct mcr *mcr; ! 423: register int m; ! 424: ! 425: for (m = 0; m < nmcr; m++) { ! 426: mcr = mcraddr[m]; ! 427: switch (cpu) { ! 428: #if VAX780 ! 429: case VAX_780: ! 430: M780_ENA(mcr); ! 431: break; ! 432: #endif ! 433: #if VAX750 ! 434: case VAX_750: ! 435: M750_ENA(mcr); ! 436: break; ! 437: #endif ! 438: #if VAX730 ! 439: case VAX_730: ! 440: M730_ENA(mcr); ! 441: break; ! 442: #endif ! 443: } ! 444: } ! 445: if (memintvl > 0) ! 446: timeout(memenable, (caddr_t)0, memintvl*hz); ! 447: } ! 448: ! 449: /* ! 450: * Memerr is the interrupt routine for corrected read data ! 451: * interrupts. It looks to see which memory controllers have ! 452: * unreported errors, reports them, and disables further ! 453: * reporting for a time on those controller. ! 454: */ ! 455: memerr() ! 456: { ! 457: register struct mcr *mcr; ! 458: register int m; ! 459: ! 460: for (m = 0; m < nmcr; m++) { ! 461: mcr = mcraddr[m]; ! 462: switch (cpu) { ! 463: #if VAX780 ! 464: case VAX_780: ! 465: if (M780_ERR(mcr)) { ! 466: printf("mcr%d: soft ecc addr %x syn %x\n", ! 467: m, M780_ADDR(mcr), M780_SYN(mcr)); ! 468: #ifdef TRENDATA ! 469: memlog(m, mcr); ! 470: #endif ! 471: M780_INH(mcr); ! 472: } ! 473: break; ! 474: #endif ! 475: #if VAX750 ! 476: case VAX_750: ! 477: if (M750_ERR(mcr)) { ! 478: struct mcr amcr; ! 479: amcr.mc_reg[0] = mcr->mc_reg[0]; ! 480: printf("mcr%d: soft ecc addr %x syn %x\n", ! 481: m, M750_ADDR(&amcr), M750_SYN(&amcr)); ! 482: M750_INH(mcr); ! 483: } ! 484: break; ! 485: #endif ! 486: #if VAX730 ! 487: case VAX_730: { ! 488: register int mcreg = mcr->mc_reg[1]; ! 489: ! 490: if (mcreg & M730_CRD) { ! 491: struct mcr amcr; ! 492: amcr.mc_reg[0] = mcr->mc_reg[0]; ! 493: printf("mcr%d: soft ecc addr %x syn %x\n", ! 494: m, M730_ADDR(&amcr), M730_SYN(&amcr)); ! 495: M730_INH(mcr); ! 496: } ! 497: break; ! 498: } ! 499: #endif ! 500: } ! 501: } ! 502: } ! 503: ! 504: #ifdef TRENDATA ! 505: /* ! 506: * Figure out what chip to replace on Trendata boards. ! 507: * Assumes all your memory is Trendata or the non-Trendata ! 508: * memory never fails.. ! 509: */ ! 510: struct { ! 511: u_char m_syndrome; ! 512: char m_chip[4]; ! 513: } memlogtab[] = { ! 514: 0x01, "C00", 0x02, "C01", 0x04, "C02", 0x08, "C03", ! 515: 0x10, "C04", 0x19, "L01", 0x1A, "L02", 0x1C, "L04", ! 516: 0x1F, "L07", 0x20, "C05", 0x38, "L00", 0x3B, "L03", ! 517: 0x3D, "L05", 0x3E, "L06", 0x40, "C06", 0x49, "L09", ! 518: 0x4A, "L10", 0x4c, "L12", 0x4F, "L15", 0x51, "L17", ! 519: 0x52, "L18", 0x54, "L20", 0x57, "L23", 0x58, "L24", ! 520: 0x5B, "L27", 0x5D, "L29", 0x5E, "L30", 0x68, "L08", ! 521: 0x6B, "L11", 0x6D, "L13", 0x6E, "L14", 0x70, "L16", ! 522: 0x73, "L19", 0x75, "L21", 0x76, "L22", 0x79, "L25", ! 523: 0x7A, "L26", 0x7C, "L28", 0x7F, "L31", 0x80, "C07", ! 524: 0x89, "U01", 0x8A, "U02", 0x8C, "U04", 0x8F, "U07", ! 525: 0x91, "U09", 0x92, "U10", 0x94, "U12", 0x97, "U15", ! 526: 0x98, "U16", 0x9B, "U19", 0x9D, "U21", 0x9E, "U22", ! 527: 0xA8, "U00", 0xAB, "U03", 0xAD, "U05", 0xAE, "U06", ! 528: 0xB0, "U08", 0xB3, "U11", 0xB5, "U13", 0xB6, "U14", ! 529: 0xB9, "U17", 0xBA, "U18", 0xBC, "U20", 0xBF, "U23", ! 530: 0xC1, "U25", 0xC2, "U26", 0xC4, "U28", 0xC7, "U31", ! 531: 0xE0, "U24", 0xE3, "U27", 0xE5, "U29", 0xE6, "U30" ! 532: }; ! 533: ! 534: memlog (m, mcr) ! 535: int m; ! 536: struct mcr *mcr; ! 537: { ! 538: register i; ! 539: ! 540: switch (cpu) { ! 541: ! 542: #if VAX780 ! 543: case VAX_780: ! 544: for (i = 0; i < (sizeof (memlogtab) / sizeof (memlogtab[0])); i++) ! 545: if ((u_char)(M780_SYN(mcr)) == memlogtab[i].m_syndrome) { ! 546: printf ( ! 547: "mcr%d: replace %s chip in %s bank of memory board %d (0-15)\n", ! 548: m, ! 549: memlogtab[i].m_chip, ! 550: (M780_ADDR(mcr) & 0x8000) ? "upper" : "lower", ! 551: (M780_ADDR(mcr) >> 16)); ! 552: return; ! 553: } ! 554: printf ("mcr%d: multiple errors, not traceable\n", m); ! 555: break; ! 556: #endif ! 557: } ! 558: } ! 559: #endif ! 560: ! 561: /* ! 562: * Invalidate single all pte's in a cluster ! 563: */ ! 564: tbiscl(v) ! 565: unsigned v; ! 566: { ! 567: register caddr_t addr; /* must be first reg var */ ! 568: register int i; ! 569: ! 570: asm(".set TBIS,58"); ! 571: addr = ptob(v); ! 572: for (i = 0; i < CLSIZE; i++) { ! 573: #ifdef lint ! 574: mtpr(TBIS, addr); ! 575: #else ! 576: asm("mtpr r11,$TBIS"); ! 577: #endif ! 578: addr += NBPG; ! 579: } ! 580: } ! 581: ! 582: int waittime = -1; ! 583: ! 584: boot(paniced, arghowto) ! 585: int paniced, arghowto; ! 586: { ! 587: register int howto; /* r11 == how to boot */ ! 588: register int devtype; /* r10 == major of root dev */ ! 589: ! 590: #ifdef lint ! 591: howto = 0; devtype = 0; ! 592: printf("howto %d, devtype %d\n", arghowto, devtype); ! 593: #endif ! 594: (void) spl1(); ! 595: howto = arghowto; ! 596: if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) { ! 597: waittime = 0; ! 598: update(); ! 599: printf("syncing disks... "); ! 600: #ifdef notdef ! 601: DELAY(10000000); ! 602: #else ! 603: { register struct buf *bp; ! 604: int iter, nbusy; ! 605: ! 606: for (iter = 0; iter < 20; iter++) { ! 607: nbusy = 0; ! 608: for (bp = &buf[nbuf]; --bp >= buf; ) ! 609: if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY) ! 610: nbusy++; ! 611: if (nbusy == 0) ! 612: break; ! 613: printf("%d ", nbusy); ! 614: } ! 615: } ! 616: #endif ! 617: printf("done\n"); ! 618: } ! 619: splx(0x1f); /* extreme priority */ ! 620: devtype = major(rootdev); ! 621: if (howto&RB_HALT) { ! 622: printf("halting (in tight loop); hit\n\t^P\n\tHALT\n\n"); ! 623: mtpr(IPL, 0x1f); ! 624: for (;;) ! 625: ; ! 626: } else { ! 627: if (paniced == RB_PANIC) { ! 628: doadump(); /* TXDB_BOOT's itsself */ ! 629: /*NOTREACHED*/ ! 630: } ! 631: tocons(TXDB_BOOT); ! 632: } ! 633: #if defined(VAX750) || defined(VAX730) ! 634: if (cpu != VAX_780) ! 635: { asm("movl r11,r5"); } /* boot flags go in r5 */ ! 636: #endif ! 637: for (;;) ! 638: asm("halt"); ! 639: /*NOTREACHED*/ ! 640: } ! 641: ! 642: tocons(c) ! 643: { ! 644: ! 645: while ((mfpr(TXCS)&TXCS_RDY) == 0) ! 646: continue; ! 647: mtpr(TXDB, c); ! 648: } ! 649: ! 650: int dumpmag = 0x8fca0101; /* magic number for savecore */ ! 651: int dumpsize = 0; /* also for savecore */ ! 652: /* ! 653: * Doadump comes here after turning off memory management and ! 654: * getting on the dump stack, either when called above, or by ! 655: * the auto-restart code. ! 656: */ ! 657: dumpsys() ! 658: { ! 659: ! 660: rpb.rp_flag = 1; ! 661: #ifdef notdef ! 662: if ((minor(dumpdev)&07) != 1) ! 663: return; ! 664: #endif ! 665: dumpsize = physmem; ! 666: printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); ! 667: printf("dump "); ! 668: switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { ! 669: ! 670: case ENXIO: ! 671: printf("device bad\n"); ! 672: break; ! 673: ! 674: case EFAULT: ! 675: printf("device not ready\n"); ! 676: break; ! 677: ! 678: case EINVAL: ! 679: printf("area improper\n"); ! 680: break; ! 681: ! 682: case EIO: ! 683: printf("i/o error"); ! 684: break; ! 685: ! 686: default: ! 687: printf("succeeded"); ! 688: break; ! 689: } ! 690: } ! 691: ! 692: /* ! 693: * Machine check error recovery code. ! 694: * Print out the machine check frame and then give up. ! 695: */ ! 696: #if defined(VAX780) || defined(VAX750) ! 697: char *mc780[] = { ! 698: "cp read", "ctrl str par", "cp tbuf par", "cp cache par", ! 699: "cp rdtimo", "cp rds", "ucode lost", 0, ! 700: 0, 0, "ib tbuf par", 0, ! 701: "ib rds", "ib rd timo", 0, "ib cache par" ! 702: }; ! 703: #define MC750_TBPAR 4 ! 704: #endif ! 705: #if VAX730 ! 706: #define NMC730 12 ! 707: char *mc730[] = { ! 708: "tb par", "bad retry", "bad intr id", "cant write ptem", ! 709: "unkn mcr err", "iib rd err", "nxm ref", "cp rds", ! 710: "unalgn ioref", "nonlw ioref", "bad ioaddr", "unalgn ubaddr", ! 711: }; ! 712: #endif ! 713: ! 714: /* ! 715: * Frame for each cpu ! 716: */ ! 717: struct mc780frame { ! 718: int mc8_bcnt; /* byte count == 0x28 */ ! 719: int mc8_summary; /* summary parameter (as above) */ ! 720: int mc8_cpues; /* cpu error status */ ! 721: int mc8_upc; /* micro pc */ ! 722: int mc8_vaviba; /* va/viba register */ ! 723: int mc8_dreg; /* d register */ ! 724: int mc8_tber0; /* tbuf error reg 0 */ ! 725: int mc8_tber1; /* tbuf error reg 1 */ ! 726: int mc8_timo; /* timeout address divided by 4 */ ! 727: int mc8_parity; /* parity */ ! 728: int mc8_sbier; /* sbi error register */ ! 729: int mc8_pc; /* trapped pc */ ! 730: int mc8_psl; /* trapped psl */ ! 731: }; ! 732: struct mc750frame { ! 733: int mc5_bcnt; /* byte count == 0x28 */ ! 734: int mc5_summary; /* summary parameter (as above) */ ! 735: int mc5_va; /* virtual address register */ ! 736: int mc5_errpc; /* error pc */ ! 737: int mc5_mdr; ! 738: int mc5_svmode; /* saved mode register */ ! 739: int mc5_rdtimo; /* read lock timeout */ ! 740: int mc5_tbgpar; /* tb group parity error register */ ! 741: int mc5_cacherr; /* cache error register */ ! 742: int mc5_buserr; /* bus error register */ ! 743: int mc5_mcesr; /* machine check status register */ ! 744: int mc5_pc; /* trapped pc */ ! 745: int mc5_psl; /* trapped psl */ ! 746: }; ! 747: struct mc730frame { ! 748: int mc3_bcnt; /* byte count == 0xc */ ! 749: int mc3_summary; /* summary parameter */ ! 750: int mc3_parm[2]; /* parameter 1 and 2 */ ! 751: int mc3_pc; /* trapped pc */ ! 752: int mc3_psl; /* trapped psl */ ! 753: }; ! 754: ! 755: machinecheck(cmcf) ! 756: caddr_t cmcf; ! 757: { ! 758: register u_int type = ((struct mc780frame *)cmcf)->mc8_summary; ! 759: ! 760: printf("machine check %x: ", type); ! 761: switch (cpu) { ! 762: #if VAX780 ! 763: case VAX_780: ! 764: #endif ! 765: #if VAX750 ! 766: case VAX_750: ! 767: #endif ! 768: #if defined(VAX780) || defined(VAX750) ! 769: printf("%s%s\n", mc780[type&0xf], ! 770: (type&0xf0) ? " abort" : " fault"); ! 771: break; ! 772: #endif ! 773: #if VAX730 ! 774: case VAX_730: ! 775: if (type < NMC730) ! 776: printf("%s", mc730[type]); ! 777: printf("\n"); ! 778: break; ! 779: #endif ! 780: } ! 781: switch (cpu) { ! 782: #if VAX780 ! 783: case VAX_780: { ! 784: register struct mc780frame *mcf = (struct mc780frame *)cmcf; ! 785: register int sbifs; ! 786: printf("\tcpues %x upc %x va/viba %x dreg %x tber %x %x\n", ! 787: mcf->mc8_cpues, mcf->mc8_upc, mcf->mc8_vaviba, ! 788: mcf->mc8_dreg, mcf->mc8_tber0, mcf->mc8_tber1); ! 789: sbifs = mfpr(SBIFS); ! 790: printf("\ttimo %x parity %x sbier %x pc %x psl %x sbifs %x\n", ! 791: mcf->mc8_timo*4, mcf->mc8_parity, mcf->mc8_sbier, ! 792: mcf->mc8_pc, mcf->mc8_psl, sbifs); ! 793: /* THE FUNNY BITS IN THE FOLLOWING ARE FROM THE ``BLACK */ ! 794: /* BOOK'' AND SHOULD BE PUT IN AN ``sbi.h'' */ ! 795: mtpr(SBIFS, sbifs &~ 0x2000000); ! 796: mtpr(SBIER, mfpr(SBIER) | 0x70c0); ! 797: break; ! 798: } ! 799: #endif ! 800: #if VAX750 ! 801: case VAX_750: { ! 802: register struct mc750frame *mcf = (struct mc750frame *)cmcf; ! 803: printf("\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n", ! 804: mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode, ! 805: mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr); ! 806: printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n", ! 807: mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl, ! 808: mfpr(MCSR)); ! 809: mtpr(MCESR, 0xf); ! 810: if ((mcf->mc5_mcesr&0xf) == MC750_TBPAR) { ! 811: printf("tbuf par: flushing and returning\n"); ! 812: mtpr(TBIA, 0); ! 813: return; ! 814: } ! 815: break; ! 816: } ! 817: #endif ! 818: #if VAX730 ! 819: case VAX_730: { ! 820: register struct mc730frame *mcf = (struct mc730frame *)cmcf; ! 821: printf("params %x,%x pc %x psl %x mcesr %x\n", ! 822: mcf->mc3_parm[0], mcf->mc3_parm[1], ! 823: mcf->mc3_pc, mcf->mc3_psl, mfpr(MCESR)); ! 824: mtpr(MCESR, 0xf); ! 825: break; ! 826: } ! 827: #endif ! 828: } ! 829: memerr(); ! 830: panic("mchk"); ! 831: } ! 832: ! 833: #ifdef notdef ! 834: microtime(tvp) ! 835: struct timeval *tvp; ! 836: { ! 837: int s = spl7(); ! 838: ! 839: tvp->tv_sec = time.tv_sec; ! 840: tvp->tv_usec = (lbolt+1)*16667 + mfpr(ICR); ! 841: while (tvp->tv_usec > 1000000) { ! 842: tvp->tv_sec++; ! 843: tvp->tv_usec -= 1000000; ! 844: } ! 845: splx(s); ! 846: } ! 847: #endif ! 848: ! 849: physstrat(bp, strat, prio) ! 850: struct buf *bp; ! 851: int (*strat)(), prio; ! 852: { ! 853: int s; ! 854: ! 855: (*strat)(bp); ! 856: /* pageout daemon doesn't wait for pushed pages */ ! 857: if (bp->b_flags & B_DIRTY) ! 858: return; ! 859: s = spl6(); ! 860: while ((bp->b_flags & B_DONE) == 0) ! 861: sleep((caddr_t)bp, prio); ! 862: splx(s); ! 863: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.