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