|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982,1987,1988 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)machdep.c 7.1 (Berkeley) 5/26/88 ! 7: */ ! 8: ! 9: #include "param.h" ! 10: #include "systm.h" ! 11: #include "dir.h" ! 12: #include "user.h" ! 13: #include "kernel.h" ! 14: #include "map.h" ! 15: #include "vm.h" ! 16: #include "proc.h" ! 17: #include "buf.h" ! 18: #include "reboot.h" ! 19: #include "conf.h" ! 20: #include "inode.h" ! 21: #include "file.h" ! 22: #include "text.h" ! 23: #include "clist.h" ! 24: #include "callout.h" ! 25: #include "cmap.h" ! 26: #include "malloc.h" ! 27: #include "mbuf.h" ! 28: #include "msgbuf.h" ! 29: #include "quota.h" ! 30: ! 31: #include "cpu.h" ! 32: #include "reg.h" ! 33: #include "pte.h" ! 34: #include "psl.h" ! 35: #include "mem.h" ! 36: #include "mtpr.h" ! 37: #include "cp.h" ! 38: ! 39: #include "../tahoevba/vbavar.h" ! 40: ! 41: /* ! 42: * Declare these as initialized data so we can patch them. ! 43: */ ! 44: int nswbuf = 0; ! 45: #ifdef NBUF ! 46: int nbuf = NBUF; ! 47: #else ! 48: int nbuf = 0; ! 49: #endif ! 50: #ifdef BUFPAGES ! 51: int bufpages = BUFPAGES; ! 52: #else ! 53: int bufpages = 0; ! 54: #endif ! 55: #include "yc.h" ! 56: #if NCY > 0 ! 57: #include "../tahoevba/cyreg.h" ! 58: #endif ! 59: int msgbufmapped; /* set when safe to use msgbuf */ ! 60: ! 61: /* ! 62: * Machine-dependent startup code ! 63: */ ! 64: startup(firstaddr) ! 65: int firstaddr; ! 66: { ! 67: register int unixsize; ! 68: register unsigned i; ! 69: register struct pte *pte; ! 70: int mapaddr, j; ! 71: register caddr_t v; ! 72: int maxbufs, base, residual; ! 73: ! 74: /* ! 75: * Initialize error message buffer (at end of core). ! 76: */ ! 77: maxmem -= btoc(sizeof (struct msgbuf)); ! 78: pte = msgbufmap; ! 79: for (i = 0; i < btoc(sizeof (struct msgbuf)); i++) ! 80: *(int *)pte++ = PG_V | PG_KW | (maxmem + i); ! 81: mtpr(TBIA, 1); ! 82: msgbufmapped = 1; ! 83: #ifdef KADB ! 84: kdb_init(); /* startup kernel debugger */ ! 85: #endif ! 86: /* ! 87: * Good {morning,afternoon,evening,night}. ! 88: */ ! 89: printf(version); ! 90: printf("real mem = %d\n", ctob(physmem)); ! 91: ! 92: /* ! 93: * Allocate space for system data structures. ! 94: * The first available real memory address is in "firstaddr". ! 95: * The first available kernel virtual address is in "v". ! 96: * As pages of kernel virtual memory are allocated, "v" is incremented. ! 97: * As pages of memory are allocated and cleared, ! 98: * "firstaddr" is incremented. ! 99: * An index into the kernel page table corresponding to the ! 100: * virtual memory address maintained in "v" is kept in "mapaddr". ! 101: */ ! 102: v = (caddr_t)(0xc0000000 | (firstaddr * NBPG)); ! 103: #define valloc(name, type, num) \ ! 104: (name) = (type *)v; v = (caddr_t)((name)+(num)) ! 105: #define valloclim(name, type, num, lim) \ ! 106: (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) ! 107: #if NCY > 0 ! 108: /* ! 109: * Allocate raw buffers for tapemaster controllers ! 110: * first, as they need buffers in the first megabyte. ! 111: */ ! 112: valloc(cybuf, char, NCY * CYMAXIO); ! 113: #endif ! 114: valloclim(inode, struct inode, ninode, inodeNINODE); ! 115: valloclim(file, struct file, nfile, fileNFILE); ! 116: valloclim(proc, struct proc, nproc, procNPROC); ! 117: valloclim(text, struct text, ntext, textNTEXT); ! 118: valloc(cfree, struct cblock, nclist); ! 119: valloc(callout, struct callout, ncallout); ! 120: valloc(swapmap, struct map, nswapmap = nproc * 2); ! 121: valloc(argmap, struct map, ARGMAPSIZE); ! 122: valloc(kernelmap, struct map, nproc); ! 123: valloc(mbmap, struct map, nmbclusters/4); ! 124: valloc(namecache, struct namecache, nchsize); ! 125: valloc(kmemmap, struct map, ekmempt - kmempt); ! 126: valloc(kmemusage, struct kmemusage, ekmempt - kmempt); ! 127: #ifdef QUOTA ! 128: valloclim(quota, struct quota, nquota, quotaNQUOTA); ! 129: valloclim(dquot, struct dquot, ndquot, dquotNDQUOT); ! 130: #endif ! 131: ! 132: /* ! 133: * Determine how many buffers to allocate. ! 134: * Use 10% of memory for the first 2 Meg, 5% of the remaining ! 135: * memory. Insure a minimum of 16 buffers. ! 136: * We allocate 1/2 as many swap buffer headers as file i/o buffers. ! 137: */ ! 138: if (bufpages == 0) ! 139: if (physmem < (2 * 1024 * 1024)) ! 140: bufpages = physmem / 10 / CLSIZE; ! 141: else ! 142: bufpages = ((2 * 1024 * 1024 + physmem) / 20) / CLSIZE; ! 143: if (nbuf == 0) { ! 144: nbuf = bufpages / 2; ! 145: if (nbuf < 16) ! 146: nbuf = 16; ! 147: } ! 148: if (nswbuf == 0) { ! 149: nswbuf = (nbuf / 2) &~ 1; /* force even */ ! 150: if (nswbuf > 256) ! 151: nswbuf = 256; /* sanity */ ! 152: } ! 153: valloc(swbuf, struct buf, nswbuf); ! 154: ! 155: /* ! 156: * Now the amount of virtual memory remaining for buffers ! 157: * can be calculated, estimating needs for the cmap. ! 158: */ ! 159: ncmap = (maxmem*NBPG - ((int)v &~ 0xc0000000)) / ! 160: (CLBYTES + sizeof(struct cmap)) + 2; ! 161: maxbufs = ((SYSPTSIZE * NBPG) - ! 162: ((int)(v + ncmap * sizeof(struct cmap)) - 0xc0000000)) / ! 163: (MAXBSIZE + sizeof(struct buf)); ! 164: if (maxbufs < 16) ! 165: panic("sys pt too small"); ! 166: if (nbuf > maxbufs) { ! 167: printf("SYSPTSIZE limits number of buffers to %d\n", maxbufs); ! 168: nbuf = maxbufs; ! 169: } ! 170: if (bufpages > nbuf * (MAXBSIZE / CLBYTES)) ! 171: bufpages = nbuf * (MAXBSIZE / CLBYTES); ! 172: valloc(buf, struct buf, nbuf); ! 173: ! 174: /* ! 175: * Allocate space for core map. ! 176: * Allow space for all of phsical memory minus the amount ! 177: * dedicated to the system. The amount of physical memory ! 178: * dedicated to the system is the total virtual memory of ! 179: * the system thus far, plus core map, buffer pages, ! 180: * and buffer headers not yet allocated. ! 181: * Add 2: 1 because the 0th entry is unused, 1 for rounding. ! 182: */ ! 183: ncmap = (maxmem*NBPG - ((int)(v + bufpages*CLBYTES) &~ 0xc0000000)) / ! 184: (CLBYTES + sizeof(struct cmap)) + 2; ! 185: valloclim(cmap, struct cmap, ncmap, ecmap); ! 186: ! 187: /* ! 188: * Clear space allocated thus far, and make r/w entries ! 189: * for the space in the kernel map. ! 190: */ ! 191: unixsize = btoc((int)v &~ 0xc0000000); ! 192: while (firstaddr < unixsize) { ! 193: *(int *)(&Sysmap[firstaddr]) = PG_V | PG_KW | firstaddr; ! 194: clearseg((unsigned)firstaddr); ! 195: firstaddr++; ! 196: } ! 197: ! 198: /* ! 199: * Now allocate buffers proper. They are different than the above ! 200: * in that they usually occupy more virtual memory than physical. ! 201: */ ! 202: v = (caddr_t) ((int)(v + PGOFSET) &~ PGOFSET); ! 203: valloc(buffers, char, MAXBSIZE * nbuf); ! 204: base = bufpages / nbuf; ! 205: residual = bufpages % nbuf; ! 206: mapaddr = firstaddr; ! 207: for (i = 0; i < residual; i++) { ! 208: for (j = 0; j < (base + 1) * CLSIZE; j++) { ! 209: *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr; ! 210: clearseg((unsigned)firstaddr); ! 211: firstaddr++; ! 212: } ! 213: mapaddr += MAXBSIZE / NBPG; ! 214: } ! 215: for (i = residual; i < nbuf; i++) { ! 216: for (j = 0; j < base * CLSIZE; j++) { ! 217: *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr; ! 218: clearseg((unsigned)firstaddr); ! 219: firstaddr++; ! 220: } ! 221: mapaddr += MAXBSIZE / NBPG; ! 222: } ! 223: ! 224: unixsize = btoc((int)v &~ 0xc0000000); ! 225: if (firstaddr >= physmem - 8*UPAGES) ! 226: panic("no memory"); ! 227: mtpr(TBIA, 1); /* After we just cleared it all! */ ! 228: ! 229: /* ! 230: * Initialize callouts ! 231: */ ! 232: callfree = callout; ! 233: for (i = 1; i < ncallout; i++) ! 234: callout[i-1].c_next = &callout[i]; ! 235: ! 236: /* ! 237: * Initialize memory allocator and swap ! 238: * and user page table maps. ! 239: * ! 240: * THE USER PAGE TABLE MAP IS CALLED ``kernelmap'' ! 241: * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME. ! 242: */ ! 243: meminit(firstaddr, maxmem); ! 244: maxmem = freemem; ! 245: printf("avail mem = %d\n", ctob(maxmem)); ! 246: printf("using %d buffers containing %d bytes of memory\n", ! 247: nbuf, bufpages * CLBYTES); ! 248: rminit(kernelmap, (long)USRPTSIZE, (long)1, ! 249: "usrpt", nproc); ! 250: rminit(mbmap, (long)(nmbclusters * CLSIZE), (long)CLSIZE, ! 251: "mbclusters", nmbclusters/4); ! 252: kmeminit(); /* now safe to do malloc/free */ ! 253: intenable = 1; /* Enable interrupts from now on */ ! 254: ! 255: /* ! 256: * Set up CPU-specific registers, cache, etc. ! 257: */ ! 258: initcpu(); ! 259: ! 260: /* ! 261: * Set up buffers, so they can be used to read disk labels. ! 262: */ ! 263: bhinit(); ! 264: binit(); ! 265: ! 266: /* ! 267: * Configure the system. ! 268: */ ! 269: configure(); ! 270: } ! 271: ! 272: #ifdef PGINPROF ! 273: /* ! 274: * Return the difference (in microseconds) ! 275: * between the current time and a previous ! 276: * time as represented by the arguments. ! 277: * If there is a pending clock interrupt ! 278: * which has not been serviced due to high ! 279: * ipl, return error code. ! 280: */ ! 281: /*ARGSUSED*/ ! 282: vmtime(otime, olbolt, oicr) ! 283: register int otime, olbolt, oicr; ! 284: { ! 285: ! 286: return (((time.tv_sec-otime)*60 + lbolt-olbolt)*16667); ! 287: } ! 288: #endif ! 289: ! 290: /* ! 291: * Send an interrupt to process. ! 292: * ! 293: * Stack is set up to allow sigcode stored ! 294: * in u. to call routine, followed by kcall ! 295: * to sigreturn routine below. After sigreturn ! 296: * resets the signal mask, the stack, and the ! 297: * frame pointer, it returns to the user ! 298: * specified pc, psl. ! 299: */ ! 300: sendsig(p, sig, mask) ! 301: int (*p)(), sig, mask; ! 302: { ! 303: register struct sigcontext *scp; ! 304: register int *regs; ! 305: register struct sigframe { ! 306: int sf_signum; ! 307: int sf_code; ! 308: struct sigcontext *sf_scp; ! 309: int (*sf_handler)(); ! 310: int sf_regs[6]; /* r0-r5 */ ! 311: struct sigcontext *sf_scpcopy; ! 312: } *fp; ! 313: int oonstack; ! 314: ! 315: regs = u.u_ar0; ! 316: oonstack = u.u_onstack; ! 317: /* ! 318: * Allocate and validate space for the signal handler ! 319: * context. Note that if the stack is in P0 space, the ! 320: * call to grow() is a nop, and the useracc() check ! 321: * will fail if the process has not already allocated ! 322: * the space with a `brk'. ! 323: */ ! 324: if (!u.u_onstack && (u.u_sigonstack & sigmask(sig))) { ! 325: scp = (struct sigcontext *)u.u_sigsp - 1; ! 326: u.u_onstack = 1; ! 327: } else ! 328: scp = (struct sigcontext *)regs[SP] - 1; ! 329: fp = (struct sigframe *)scp - 1; ! 330: if ((int)fp <= USRSTACK - ctob(u.u_ssize)) ! 331: (void) grow((unsigned)fp); ! 332: if (useracc((caddr_t)fp, sizeof (*fp) + sizeof (*scp), B_WRITE) == 0) { ! 333: /* ! 334: * Process has trashed its stack; give it an illegal ! 335: * instruction to halt it in its tracks. ! 336: */ ! 337: u.u_signal[SIGILL] = SIG_DFL; ! 338: sig = sigmask(SIGILL); ! 339: u.u_procp->p_sigignore &= ~sig; ! 340: u.u_procp->p_sigcatch &= ~sig; ! 341: u.u_procp->p_sigmask &= ~sig; ! 342: psignal(u.u_procp, SIGILL); ! 343: return; ! 344: } ! 345: /* ! 346: * Build the argument list for the signal handler. ! 347: */ ! 348: fp->sf_signum = sig; ! 349: if (sig == SIGILL || sig == SIGFPE) { ! 350: fp->sf_code = u.u_code; ! 351: u.u_code = 0; ! 352: } else ! 353: fp->sf_code = 0; ! 354: fp->sf_scp = scp; ! 355: fp->sf_handler = p; ! 356: /* ! 357: * Build the callf argument frame to be used to call sigreturn. ! 358: */ ! 359: fp->sf_scpcopy = scp; ! 360: /* ! 361: * Build the signal context to be used by sigreturn. ! 362: */ ! 363: scp->sc_onstack = oonstack; ! 364: scp->sc_mask = mask; ! 365: scp->sc_sp = regs[SP]; ! 366: scp->sc_fp = regs[FP]; ! 367: scp->sc_pc = regs[PC]; ! 368: scp->sc_ps = regs[PS]; ! 369: regs[SP] = (int)fp; ! 370: regs[PC] = (int)u.u_pcb.pcb_sigc; ! 371: } ! 372: ! 373: /* ! 374: * System call to cleanup state after a signal ! 375: * has been taken. Reset signal mask and ! 376: * stack state from context left by sendsig (above). ! 377: * Return to previous pc and psl as specified by ! 378: * context left by sendsig. Check carefully to ! 379: * make sure that the user has not modified the ! 380: * psl to gain improper priviledges or to cause ! 381: * a machine fault. ! 382: */ ! 383: sigreturn() ! 384: { ! 385: struct a { ! 386: struct sigcontext *sigcntxp; ! 387: }; ! 388: register struct sigcontext *scp; ! 389: register int *regs = u.u_ar0; ! 390: ! 391: scp = ((struct a *)(u.u_ap))->sigcntxp; ! 392: if (useracc((caddr_t)scp, sizeof (*scp), 0) == 0) { ! 393: u.u_error = EINVAL; ! 394: return; ! 395: } ! 396: if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_IS)) != 0 || ! 397: (scp->sc_ps & (PSL_PRVMOD|PSL_CURMOD)) != (PSL_PRVMOD|PSL_CURMOD)) { ! 398: u.u_error = EINVAL; ! 399: return; ! 400: } ! 401: u.u_eosys = JUSTRETURN; ! 402: u.u_onstack = scp->sc_onstack & 01; ! 403: u.u_procp->p_sigmask = scp->sc_mask &~ ! 404: (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP)); ! 405: regs[FP] = scp->sc_fp; ! 406: regs[SP] = scp->sc_sp; ! 407: regs[PC] = scp->sc_pc; ! 408: regs[PS] = scp->sc_ps; ! 409: } ! 410: ! 411: /* XXX - BEGIN 4.2 COMPATIBILITY */ ! 412: /* ! 413: * Compatibility with 4.2 kcall $139 used by longjmp() ! 414: */ ! 415: osigcleanup() ! 416: { ! 417: register struct sigcontext *scp; ! 418: register int *regs = u.u_ar0; ! 419: ! 420: scp = (struct sigcontext *)fuword((caddr_t)regs[SP]); ! 421: if ((int)scp == -1) ! 422: return; ! 423: if (useracc((caddr_t)scp, 3 * sizeof (int), 0) == 0) ! 424: return; ! 425: u.u_onstack = scp->sc_onstack & 01; ! 426: u.u_procp->p_sigmask = scp->sc_mask &~ ! 427: (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP)); ! 428: regs[SP] = scp->sc_sp; ! 429: } ! 430: /* XXX - END 4.2 COMPATIBILITY */ ! 431: ! 432: int waittime = -1; ! 433: ! 434: boot(arghowto) ! 435: int arghowto; ! 436: { ! 437: register long dummy; /* r12 is reserved */ ! 438: register int howto; /* r11 == how to boot */ ! 439: register int devtype; /* r10 == major of root dev */ ! 440: extern char *panicstr; ! 441: ! 442: howto = arghowto; ! 443: if ((howto&RB_NOSYNC) == 0 && waittime < 0 && bfreelist[0].b_forw) { ! 444: register struct buf *bp; ! 445: int iter, nbusy; ! 446: ! 447: waittime = 0; ! 448: (void) splnet(); ! 449: printf("syncing disks... "); ! 450: /* ! 451: * Release inodes held by texts before update. ! 452: */ ! 453: if (panicstr == 0) ! 454: xumount(NODEV); ! 455: update(); ! 456: ! 457: for (iter = 0; iter < 20; iter++) { ! 458: nbusy = 0; ! 459: for (bp = &buf[nbuf]; --bp >= buf; ) ! 460: if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY) ! 461: nbusy++; ! 462: if (nbusy == 0) ! 463: break; ! 464: printf("%d ", nbusy); ! 465: DELAY(40000 * iter); ! 466: } ! 467: if (nbusy) ! 468: printf("giving up\n"); ! 469: else ! 470: printf("done\n"); ! 471: DELAY(10000); /* wait for printf to finish */ ! 472: } ! 473: mtpr(IPL, 0x1f); /* extreme priority */ ! 474: devtype = major(rootdev); ! 475: *(int *)CPBFLG = howto; ! 476: if (howto&RB_HALT) { ! 477: printf("halting (in tight loop); hit ~h\n\n"); ! 478: mtpr(IPL, 0x1f); ! 479: for (;;) ! 480: ; ! 481: } else { ! 482: if (howto & RB_DUMP) { ! 483: doadump(); /* CPBOOT's itsself */ ! 484: /*NOTREACHED*/ ! 485: } ! 486: tocons(CPBOOT); ! 487: } ! 488: #ifdef lint ! 489: dummy = 0; dummy = dummy; ! 490: printf("howto %d, devtype %d\n", arghowto, devtype); ! 491: #endif ! 492: for (;;) ! 493: asm("halt"); ! 494: /*NOTREACHED*/ ! 495: } ! 496: ! 497: struct cpdcb_o cpcontrol; ! 498: ! 499: /* ! 500: * Send the given comand ('c') to the console processor. ! 501: * Assumed to be one of the last things the OS does before ! 502: * halting or rebooting. ! 503: */ ! 504: tocons(c) ! 505: { ! 506: register timeout; ! 507: ! 508: cpcontrol.cp_hdr.cp_unit = CPUNIT; ! 509: cpcontrol.cp_hdr.cp_comm = (char)c; ! 510: if (c != CPBOOT) ! 511: cpcontrol.cp_hdr.cp_count = 1; /* Just for sanity */ ! 512: else { ! 513: cpcontrol.cp_hdr.cp_count = 4; ! 514: *(int *)cpcontrol.cp_buf = 0; /* r11 value for reboot */ ! 515: } ! 516: timeout = 100000; /* Delay loop */ ! 517: while (timeout-- && (cnlast->cp_unit&CPDONE) == 0) ! 518: uncache(&cnlast->cp_unit); ! 519: /* give up, force it to listen */ ! 520: mtpr(CPMDCB, vtoph((struct proc *)0, (unsigned)&cpcontrol)); ! 521: } ! 522: ! 523: #if CLSIZE != 1 ! 524: /* ! 525: * Invalidate single all pte's in a cluster ! 526: */ ! 527: tbiscl(v) ! 528: unsigned v; ! 529: { ! 530: register caddr_t addr; /* must be first reg var */ ! 531: register int i; ! 532: ! 533: addr = ptob(v); ! 534: for (i = 0; i < CLSIZE; i++) { ! 535: mtpr(TBIS, addr); ! 536: addr += NBPG; ! 537: } ! 538: } ! 539: #endif ! 540: ! 541: int dumpmag = 0x8fca0101; /* magic number for savecore */ ! 542: int dumpsize = 0; /* also for savecore */ ! 543: /* ! 544: * Doadump comes here after turning off memory management and ! 545: * getting on the dump stack, either when called above, or by ! 546: * the auto-restart code. ! 547: */ ! 548: dumpsys() ! 549: { ! 550: ! 551: if (dumpdev == NODEV) ! 552: return; ! 553: #ifdef notdef ! 554: if ((minor(dumpdev)&07) != 1) ! 555: return; ! 556: #endif ! 557: dumpsize = physmem; ! 558: printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); ! 559: printf("dump "); ! 560: switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { ! 561: ! 562: case ENXIO: ! 563: printf("device bad\n"); ! 564: break; ! 565: ! 566: case EFAULT: ! 567: printf("device not ready\n"); ! 568: break; ! 569: ! 570: case EINVAL: ! 571: printf("area improper\n"); ! 572: break; ! 573: ! 574: case EIO: ! 575: printf("i/o error\n"); ! 576: break; ! 577: ! 578: default: ! 579: printf("succeeded\n"); ! 580: break; ! 581: } ! 582: printf("\n\n"); ! 583: DELAY(1000); ! 584: tocons(CPBOOT); ! 585: } ! 586: ! 587: /* ! 588: * Bus error 'recovery' code. ! 589: * Print out the buss frame and then give up. ! 590: * (More information from special registers can be printed here.) ! 591: */ ! 592: ! 593: /* ! 594: * Frame for bus error ! 595: */ ! 596: struct buserframe { ! 597: int which_bus; /* primary or secondary */ ! 598: int memerreg; /* memory error register */ ! 599: int trp_pc; /* trapped pc */ ! 600: int trp_psl; /* trapped psl */ ! 601: }; ! 602: ! 603: char *mem_errcd[8] = { ! 604: "Unknown error code 0", ! 605: "Address parity error", /* APE */ ! 606: "Data parity error", /* DPE */ ! 607: "Data check error", /* DCE */ ! 608: "Versabus timeout", /* VTO */ ! 609: "Versabus error", /* VBE */ ! 610: "Non-existent memory", /* NEM */ ! 611: "Unknown error code 7", ! 612: }; ! 613: ! 614: buserror(v) ! 615: caddr_t v; ! 616: { ! 617: register struct buserframe *busef = (struct buserframe *)v; ! 618: register long reg; ! 619: ! 620: printf("bus error, address %x, psl %x\n", ! 621: busef->trp_pc, busef->trp_psl); ! 622: reg = busef->memerreg; ! 623: printf("mear %x %s\n", ! 624: ((reg&MEAR)>>16)&0xffff, mem_errcd[reg & ERRCD]); ! 625: if (reg&AXE) ! 626: printf("adapter external error\n"); ! 627: printf("error master: %s\n", reg&ERM ? "versabus" : "tahoe"); ! 628: if (reg&IVV) ! 629: printf("illegal interrupt vector from ipl %d\n", (reg>>2)&7); ! 630: reg = busef->which_bus; ! 631: printf("mcbr %x versabus type %x\n", ! 632: ((reg&MCBR)>>16)&0xffff, reg & 0xffc3); ! 633: if ((busef->memerreg&IVV) == 0) ! 634: panic("buserror"); ! 635: } ! 636: ! 637: microtime(tvp) ! 638: register struct timeval *tvp; ! 639: { ! 640: int s = splhigh(); ! 641: ! 642: *tvp = time; ! 643: tvp->tv_usec += tick; ! 644: while (tvp->tv_usec > 1000000) { ! 645: tvp->tv_sec++; ! 646: tvp->tv_usec -= 1000000; ! 647: } ! 648: splx(s); ! 649: } ! 650: ! 651: initcpu() ! 652: { ! 653: register struct proc *p; ! 654: ! 655: p = &proc[0]; ! 656: #define initkey(which, p, index) \ ! 657: which/**/_cache[index] = 1, which/**/_cnt[index] = 1; \ ! 658: p->p_/**/which = index; ! 659: initkey(ckey, p, MAXCKEY); ! 660: initkey(dkey, p, MAXDKEY); ! 661: } ! 662: ! 663: /* ! 664: * Clear registers on exec ! 665: */ ! 666: setregs(entry) ! 667: u_long entry; ! 668: { ! 669: ! 670: #ifdef notdef ! 671: /* should pass args to init on the stack */ ! 672: for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];) ! 673: *rp++ = 0; ! 674: #endif ! 675: u.u_ar0[FP] = 0; /* bottom of the fp chain */ ! 676: u.u_ar0[PC] = entry + 2; ! 677: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.