|
|
1.1 ! root 1: /* machdep.c 4.36 81/05/09 */ ! 2: ! 3: #include "../h/param.h" ! 4: #include "../h/systm.h" ! 5: #include "../h/dir.h" ! 6: #include "../h/user.h" ! 7: #include "../h/map.h" ! 8: #include "../h/reg.h" ! 9: #include "../h/mtpr.h" ! 10: #include "../h/clock.h" ! 11: #include "../h/pte.h" ! 12: #include "../h/vm.h" ! 13: #include "../h/lnode.h" ! 14: #include "../h/proc.h" ! 15: #include "../h/psl.h" ! 16: #include "../h/buf.h" ! 17: #include "../h/nexus.h" ! 18: #include "../h/ubavar.h" ! 19: #include "../h/ubareg.h" ! 20: #include "../h/cons.h" ! 21: #include "../h/reboot.h" ! 22: #include "../h/conf.h" ! 23: #include "../h/mem.h" ! 24: #include "../h/cpu.h" ! 25: #include "../h/inode.h" ! 26: #include "../h/file.h" ! 27: #include "../h/text.h" ! 28: #include "../h/callout.h" ! 29: #include "../h/cmap.h" ! 30: #include <frame.h> ! 31: #include "../h/rpb.h" ! 32: #include <time.h> ! 33: ! 34: int icode[] = ! 35: { ! 36: 0x9f19af9f, /* pushab [&"init",0]; pushab */ ! 37: 0x02dd09af, /* "/etc/init"; pushl $2 */ ! 38: 0xbc5c5ed0, /* movl sp,ap; chmk */ ! 39: 0x2ffe110b, /* $exec; brb .; "/ */ ! 40: 0x2f637465, /* etc/ */ ! 41: 0x74696e69, /* init" */ ! 42: 0x00000000, /* \0\0\0"; 0 */ ! 43: 0x00000014, /* [&"init", */ ! 44: 0x00000000, /* 0] */ ! 45: }; ! 46: int szicode = sizeof(icode); ! 47: ! 48: /* ! 49: * Declare these as initialized data so we can patch them. ! 50: */ ! 51: int nbuf = 0; ! 52: int nswbuf = 0; ! 53: ! 54: /* ! 55: * Machine-dependent startup code ! 56: */ ! 57: startup(firstaddr) ! 58: int firstaddr; ! 59: { ! 60: register int unixsize; ! 61: register unsigned i; ! 62: register struct pte *pte; ! 63: register caddr_t v; ! 64: ! 65: /* ! 66: * Initialize error message buffer (at end of core). ! 67: */ ! 68: maxmem -= CLSIZE; ! 69: pte = msgbufmap; ! 70: for (i = 0; i < CLSIZE; i++) ! 71: *(int *)pte++ = PG_V | PG_KW | (maxmem + i); ! 72: mtpr(TBIA, 1); ! 73: ! 74: /* ! 75: * Good {morning,afternoon,evening,night}. ! 76: */ ! 77: printf(version); ! 78: ! 79: /* ! 80: * First determine how many buffers are reasonable. ! 81: * Current alg is 32 per megabyte, with min of 32. ! 82: * We allocate 1/2 as many swap buffer headers as file i/o buffers. ! 83: */ ! 84: if (nbuf == 0) { ! 85: nbuf = (32 * physmem) / btoc(1024*1024); ! 86: if (nbuf < 32) ! 87: nbuf = 32; ! 88: } ! 89: if (nswbuf == 0) { ! 90: nswbuf = (nbuf / 2) &~ 1; /* force even */ ! 91: if (nswbuf > 256) ! 92: nswbuf = 256; /* sanity */ ! 93: } ! 94: printf("real mem = %d nbuf = %d nswbuf = %d\n", ctob(maxmem), ! 95: nbuf, nswbuf); ! 96: ! 97: /* ! 98: * Allocate space for system data structures. ! 99: */ ! 100: v = (caddr_t)(0x80000000 | (firstaddr * NBPG)); ! 101: #define valloc(name, type, num) \ ! 102: (name) = (type *)(v); (v) = (caddr_t)((name)+(num)) ! 103: #define valloclim(name, type, num, lim) \ ! 104: (name) = (type *)(v); (v) = (caddr_t)((lim) = ((name)+(num))) ! 105: valloc(buffers, char, BUFSIZE*nbuf); ! 106: valloc(buf, struct buf, nbuf); ! 107: valloc(swbuf, struct buf, nswbuf); ! 108: valloc(swsize, short, nswbuf); /* note: nswbuf is even */ ! 109: valloc(swpf, int, nswbuf); ! 110: valloclim(inode, struct inode, ninode, inodeNINODE); ! 111: valloclim(file, struct file, nfile, fileNFILE); ! 112: valloclim(proc, struct proc, nproc, procNPROC); ! 113: valloclim(text, struct text, ntext, textNTEXT); ! 114: valloclim(lnodes, struct kern_lnode, maxusers, lnodesMAXUSERS); ! 115: valloc(callout, struct callout, ncallout); ! 116: valloc(swapmap, struct map, nswapmap = nproc * 2); ! 117: valloc(argmap, struct map, ARGMAPSIZE); ! 118: valloc(kernelmap, struct map, nproc); ! 119: ! 120: /* ! 121: * Now allocate space for core map ! 122: */ ! 123: ncmap = (physmem*NBPG - ((int)v &~ 0x80000000)) / ! 124: (NBPG*CLSIZE + sizeof (struct cmap)); ! 125: valloclim(cmap, struct cmap, ncmap, ecmap); ! 126: if ((((int)(ecmap+1))&~0x80000000) > SYSPTSIZE*NBPG) ! 127: panic("sys pt too small"); ! 128: ! 129: /* ! 130: * Clear allocated space, and make r/w entries ! 131: * for the space in the kernel map. ! 132: */ ! 133: unixsize = btoc((int)(ecmap+1) &~ 0x80000000); ! 134: if (unixsize >= physmem - 8*UPAGES) ! 135: panic("no memory"); ! 136: for (i = firstaddr; i < unixsize; i++) { ! 137: *(int *)(&Sysmap[i]) = PG_V | PG_KW | i; ! 138: clearseg(i); ! 139: } ! 140: mtpr(TBIA, 1); ! 141: ! 142: /* ! 143: * Initialize callouts ! 144: */ ! 145: callfree = callout; ! 146: for (i = 1; i < ncallout; i++) ! 147: callout[i-1].c_next = &callout[i]; ! 148: ! 149: /* ! 150: * Initialize memory allocator and swap ! 151: * and user page table maps. ! 152: * ! 153: * THE USER PAGE TABLE MAP IS CALLED ``kernelmap'' ! 154: * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME. ! 155: */ ! 156: meminit(unixsize, maxmem); ! 157: maxmem = freemem; ! 158: printf("avail mem = %d\n", ctob(maxmem)); ! 159: rminit(kernelmap, USRPTSIZE, 1, "usrpt", nproc); ! 160: ! 161: /* ! 162: * Configure the system. ! 163: */ ! 164: configure(); ! 165: ! 166: /* ! 167: * Clear restart inhibit flags. ! 168: */ ! 169: tocons(TXDB_CWSI); ! 170: tocons(TXDB_CCSI); ! 171: } ! 172: ! 173: /* ! 174: * set up a physical address ! 175: * into users virtual address space. ! 176: */ ! 177: sysphys() ! 178: { ! 179: ! 180: if(!suser()) ! 181: return; ! 182: u.u_error = EINVAL; ! 183: } ! 184: ! 185: /* ! 186: * Initialze the clock, based on the time base which is, e.g. ! 187: * from a filesystem. Base provides the time to within six months, ! 188: * and the time of year clock provides the rest. ! 189: */ ! 190: clkinit(base) ! 191: time_t base; ! 192: { ! 193: register unsigned todr = mfpr(TODR); ! 194: long deltat; ! 195: int year = YRREF; ! 196: unsigned secyr; ! 197: ! 198: #ifdef MVAX ! 199: /* ! 200: * Get the MicroVAX-II's toy register. ! 201: * Convert it to the time format that the todr is ! 202: * normally kept in. ! 203: */ ! 204: if( cpu == M_VAX ) { ! 205: todr = gettoy(); ! 206: for (;;) { ! 207: secyr = SECYR; ! 208: if (LEAPYEAR(year)) ! 209: secyr += SECDAY; ! 210: if (todr < secyr) ! 211: break; ! 212: todr -= secyr; ! 213: year++; ! 214: } ! 215: year = YRREF; ! 216: todr = TODRZERO + todr*100; ! 217: } ! 218: #endif MVAX ! 219: if (base < 5*SECYR) { ! 220: printf("WARNING: preposterous time in file system"); ! 221: time = 6*SECYR + 186*SECDAY + SECDAY/2; ! 222: clkset(); ! 223: goto check; ! 224: } ! 225: /* ! 226: * Have been told that VMS keeps time internally with base TODRZERO. ! 227: * If this is correct, then this routine and VMS should maintain ! 228: * the same date, and switching shouldn't be painful. ! 229: * (Unfortunately, VMS keeps local time, so when you run UNIX ! 230: * and VMS, VMS runs on GMT...). ! 231: */ ! 232: if (todr < TODRZERO) { ! 233: printf("WARNING: todr too small"); ! 234: time = base; ! 235: /* ! 236: * Believe the time in the file system for lack of ! 237: * anything better, resetting the TODR. ! 238: */ ! 239: clkset(); ! 240: goto check; ! 241: } ! 242: /* ! 243: * Sneak to within 6 month of the time in the filesystem, ! 244: * by starting with the time of the year suggested by the TODR, ! 245: * and advancing through succesive years. Adding the number of ! 246: * seconds in the current year takes us to the end of the current year ! 247: * and then around into the next year to the same position. ! 248: */ ! 249: for (time = (todr-TODRZERO)/100; time < base-SECYR/2; time += SECYR) { ! 250: if (LEAPYEAR(year)) ! 251: time += SECDAY; ! 252: year++; ! 253: } ! 254: ! 255: /* ! 256: * The hardware and software clocks are now in sync, so it is ! 257: * safe to call clkset() to get its side effect, which is to ! 258: * initialize yearbase. ! 259: */ ! 260: clkset(); ! 261: ! 262: /* ! 263: * See if we gained/lost two or more days; ! 264: * if so, assume something is amiss. ! 265: */ ! 266: deltat = time - base; ! 267: if (deltat < 0) ! 268: deltat = -deltat; ! 269: if (deltat < 2*SECDAY) ! 270: return; ! 271: printf("WARNING: clock %s %d days", ! 272: time < base ? "lost" : "gained", deltat / SECDAY); ! 273: check: ! 274: printf(" -- CHECK AND RESET THE DATE!\n"); ! 275: } ! 276: ! 277: /* Time in seconds from the epoch to the start of the current year */ ! 278: time_t yearbase; ! 279: ! 280: /* ! 281: * Reset the TODR based on the time value; used when the TODR ! 282: * has a preposterous value and also when the time is reset ! 283: * by the stime system call. Also called when the TODR goes past ! 284: * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight) ! 285: * to wrap the TODR around. ! 286: * ! 287: * Side effect: yearbase is set appropriately. ! 288: */ ! 289: ! 290: clkset() ! 291: { ! 292: int year = YRREF; ! 293: unsigned secyr; ! 294: unsigned yrtime = time; ! 295: ! 296: yearbase = 0; ! 297: ! 298: /* ! 299: * Whittle the time down to an offset in the current year, ! 300: * by subtracting off whole years as long as possible. ! 301: */ ! 302: #ifdef MVAX ! 303: if( cpu == M_VAX ) { ! 304: settoy( yrtime ); ! 305: return; ! 306: } ! 307: #endif MVAX ! 308: for (;;) { ! 309: secyr = SECYR; ! 310: if (LEAPYEAR(year)) ! 311: secyr += SECDAY; ! 312: if (yrtime < secyr) ! 313: break; ! 314: yrtime -= secyr; ! 315: yearbase += secyr; ! 316: year++; ! 317: } ! 318: mtpr(TODR, TODRZERO + yrtime*100); ! 319: } ! 320: ! 321: #ifdef MVAX ! 322: /* ! 323: * This routine sets the time of year clock on the MicroVAX-II. ! 324: */ ! 325: static int dmsize[12] = ! 326: { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; ! 327: ! 328: #define dysize(A) (((A)%4)? 365: 366) ! 329: ! 330: gettoy() ! 331: { ! 332: int i, sec=0; ! 333: struct tm tm; ! 334: int s; ! 335: register struct qb_regs *qb_regs = (struct qb_regs *)nexus; ! 336: ! 337: /* ! 338: * Copy the toy register contents into tm so that we can ! 339: * work with. The toy must be completely read in 2.5 millisecs. ! 340: * ! 341: * ! 342: * Wait for update in progress to be done. ! 343: */ ! 344: while( qb_regs->qb_toycsra & QBT_UIP ) ! 345: ; ! 346: s = spl7(); ! 347: tm.tm_sec = qb_regs->qb_toysecs; ! 348: tm.tm_min = qb_regs->qb_toymins; ! 349: tm.tm_hour = qb_regs->qb_toyhours; ! 350: tm.tm_mday = qb_regs->qb_toyday; ! 351: tm.tm_mon = qb_regs->qb_toymonth; ! 352: tm.tm_year = qb_regs->qb_toyyear; ! 353: splx( s ); ! 354: /* ! 355: * sanity check the clock ! 356: */ ! 357: if( tm.tm_sec < 0 || tm.tm_sec >59 || ! 358: tm.tm_min < 0 || tm.tm_min > 59 || ! 359: tm.tm_hour < 0 || tm.tm_hour > 23 || ! 360: tm.tm_mday < 1 || tm.tm_mday > 31 || ! 361: tm.tm_mon < 1 || tm.tm_mon >12 || ! 362: tm.tm_year < 70 || tm.tm_year > 99 ) ! 363: return 0; ! 364: /* ! 365: * Added up the seconds since the epoch ! 366: */ ! 367: tm.tm_year += 1900; ! 368: for (i = 1970; i < tm.tm_year; i++) ! 369: sec += dysize(i); ! 370: /* ! 371: * Leap tm.tm_year ! 372: */ ! 373: if (dysize(tm.tm_year) == 366 && tm.tm_mon >= 3) ! 374: sec++; ! 375: /* ! 376: * Do the current tm.tm_year ! 377: */ ! 378: for( i=0 ; i < tm.tm_mon-1 ; i++ ) ! 379: sec += dmsize[i]; ! 380: sec += tm.tm_mday-1; ! 381: sec = 24*sec + tm.tm_hour; ! 382: sec = 60*sec + tm.tm_min; ! 383: sec = 60*sec + tm.tm_sec; ! 384: return (sec); ! 385: } ! 386: ! 387: /* ! 388: * This routine is used to set the MicroVAX-II toy register. ! 389: */ ! 390: settoy( tim ) ! 391: { ! 392: register int d0, d1; ! 393: long hms, day; ! 394: register int *tp; ! 395: struct tm xtime; ! 396: int s; ! 397: register struct qb_regs *qb_regs = (struct qb_regs *)nexus; ! 398: ! 399: /* ! 400: * break initial number into days ! 401: */ ! 402: hms = tim % 86400; ! 403: day = tim / 86400; ! 404: if (hms<0) { ! 405: hms += 86400; ! 406: day -= 1; ! 407: } ! 408: tp = (int *)&xtime; ! 409: ! 410: /* ! 411: * generate hours:minutes:seconds ! 412: */ ! 413: *tp++ = hms%60; ! 414: d1 = hms/60; ! 415: *tp++ = d1%60; ! 416: d1 /= 60; ! 417: *tp++ = d1; ! 418: ! 419: /* ! 420: * year number ! 421: */ ! 422: if (day>=0) for(d1=70; day >= dysize(d1); d1++) ! 423: day -= dysize(d1); ! 424: else for (d1=70; day<0; d1--) ! 425: day += dysize(d1-1); ! 426: xtime.tm_year = d1; ! 427: xtime.tm_yday = d0 = day; ! 428: ! 429: /* ! 430: * generate month ! 431: */ ! 432: ! 433: if (dysize(d1)==366) ! 434: dmsize[1] = 29; ! 435: for(d1=0; d0 >= dmsize[d1]; d1++) ! 436: d0 -= dmsize[d1]; ! 437: dmsize[1] = 28; ! 438: *tp++ = d0+1; ! 439: *tp++ = d1+1; ! 440: xtime.tm_isdst = 0; ! 441: /* ! 442: * Copy the time into the toy. ! 443: */ ! 444: qb_regs->qb_toycsrb = QBT_SETUP; ! 445: s = spl7(); ! 446: qb_regs->qb_toysecs = xtime.tm_sec; ! 447: qb_regs->qb_toymins = xtime.tm_min; ! 448: qb_regs->qb_toyhours = xtime.tm_hour; ! 449: qb_regs->qb_toyday = xtime.tm_mday; ! 450: qb_regs->qb_toymonth = xtime.tm_mon; ! 451: qb_regs->qb_toyyear = xtime.tm_year; ! 452: splx( s ); ! 453: /* ! 454: * Start the clock again. ! 455: */ ! 456: qb_regs->qb_toycsra = QBT_SETA; ! 457: qb_regs->qb_toycsrb = QBT_SETB; ! 458: } ! 459: #endif MVAX ! 460: ! 461: ! 462: unsigned trimprof[3]; ! 463: ! 464: /* ! 465: * Tweak the rate of the software clock ! 466: * to track the hardware clock accurately. ! 467: * This routine is called once a second, ! 468: * immediately after 'time' has been incremented. ! 469: */ ! 470: clktrim() ! 471: { ! 472: register long delta; ! 473: register long incr; ! 474: register unsigned todr = mfpr(TODR); ! 475: ! 476: #ifdef MVAX ! 477: /* ! 478: * Get the MicroVAX-II's toy register. ! 479: * Convert it to the time format that the todr is ! 480: * normally kept in. ! 481: */ ! 482: if( cpu == M_VAX ) { ! 483: int year = YRREF; ! 484: unsigned secyr; ! 485: ! 486: todr = gettoy(); ! 487: for (;;) { ! 488: secyr = SECYR; ! 489: if (LEAPYEAR(year)) ! 490: secyr += SECDAY; ! 491: if (todr < secyr) ! 492: break; ! 493: todr -= secyr; ! 494: year++; ! 495: } ! 496: todr = TODRZERO + todr*100; ! 497: } ! 498: #endif MVAX ! 499: ! 500: delta = 100 * (time - yearbase) - todr + TODRZERO; ! 501: ! 502: /* ! 503: * If delta > 0, the software clock is running fast. ! 504: * It is measured in centiseconds, the units of the ! 505: * hardware clock. If delta is non-zero, we will ! 506: * stretch or shrink each tick by 111 microseconds ! 507: * from the nominal, for a drift of about 2/3 of a ! 508: * percent. This should result by changing delta by ! 509: * about 2/3 each second, thus making it very unlikely ! 510: * that we will overshoot delta == 0. On the other ! 511: * hand, we will be able to absorb 16 minutes of drift ! 512: * each day. We also count each kind of tweak. ! 513: */ ! 514: ! 515: incr = -16667; /* -1/60 of a second, in microseconds */ ! 516: if (delta > 0) { ! 517: incr -= 111; ! 518: trimprof[2]++; ! 519: } else if (delta < 0) { ! 520: incr += 111; ! 521: trimprof[0]++; ! 522: } else { ! 523: trimprof[1]++; ! 524: } ! 525: ! 526: /* tell the hardware about it */ ! 527: /* unfortunately this does nothing on the MVAX */ ! 528: mtpr (NICR, incr); ! 529: } ! 530: ! 531: /* ! 532: * This system call sets the time of year clock without touching ! 533: * the software clock. It returns the previous clock value. If ! 534: * the argument is zero or the caller is not the super-user, it ! 535: * does not change the clock. ! 536: */ ! 537: settod() ! 538: { ! 539: register struct a { ! 540: long unsigned tod; ! 541: } *uap; ! 542: register unsigned todr = mfpr(TODR); ! 543: ! 544: #ifdef MVAX ! 545: /* ! 546: * Get the MicroVAX-II's toy register. ! 547: * Convert it to the time format that the todr is ! 548: * normally kept in. ! 549: */ ! 550: if( cpu == M_VAX ) { ! 551: int year = YRREF; ! 552: unsigned secyr; ! 553: ! 554: todr = gettoy(); ! 555: for (;;) { ! 556: secyr = SECYR; ! 557: if (LEAPYEAR(year)) ! 558: secyr += SECDAY; ! 559: if (todr < secyr) ! 560: break; ! 561: todr -= secyr; ! 562: year++; ! 563: } ! 564: todr = TODRZERO + todr*100; ! 565: } ! 566: #endif MVAX ! 567: ! 568: uap = (struct a *) u.u_ap; ! 569: u.u_r.r_val1 = todr; ! 570: #ifdef MVAX ! 571: if (uap->tod != 0 && suser() && cpu == M_VAX) { ! 572: settoy(uap->tod); ! 573: return; ! 574: } ! 575: #endif MVAX ! 576: if (uap->tod != 0 && suser()) ! 577: mtpr (TODR, uap->tod); ! 578: } ! 579: ! 580: /* ! 581: * Return the difference (in microseconds) ! 582: * between the current time and a previous ! 583: * time as represented by the arguments. ! 584: * If there is a pending clock interrupt ! 585: * which has not been serviced due to high ! 586: * ipl, return error code. ! 587: */ ! 588: vmtime(otime, olbolt, oicr) ! 589: register int otime, olbolt, oicr; ! 590: { ! 591: ! 592: if (mfpr(ICCS)&ICCS_INT) ! 593: return(-1); ! 594: else ! 595: return(((time-otime)*60 + lbolt-olbolt)*16667 + mfpr(ICR)-oicr); ! 596: } ! 597: ! 598: /* ! 599: * Send an interrupt to process ! 600: * ! 601: * SHOULD CHANGE THIS TO PASS ONE MORE WORK SO THAT ALL INFORMATION ! 602: * PROVIDED BY HARDWARE IS AVAILABLE TO THE USER PROCESS. ! 603: */ ! 604: sendsig(p, n) ! 605: int (*p)(); ! 606: { ! 607: register int *usp, *regs; ! 608: ! 609: regs = u.u_ar0; ! 610: usp = (int *)regs[SP]; ! 611: usp -= 5; ! 612: if ((int)usp <= USRSTACK - ctob(u.u_ssize)) ! 613: (void) grow((unsigned)usp); ! 614: ; /* Avoid asm() label botch */ ! 615: #ifndef lint ! 616: asm("probew $3,$20,(r11)"); ! 617: asm("beql bad"); ! 618: #else ! 619: if (useracc((caddr_t)usp, 0x20, 1)) ! 620: goto bad; ! 621: #endif ! 622: *usp++ = n; ! 623: if (n == SIGILL || n == SIGFPE) { ! 624: *usp++ = u.u_code; ! 625: u.u_code = 0; ! 626: } else ! 627: *usp++ = 0; ! 628: *usp++ = (int)p; ! 629: *usp++ = regs[PC]; ! 630: *usp++ = regs[PS]; ! 631: regs[SP] = (int)(usp - 5); ! 632: regs[PS] &= ~(PSL_CM|PSL_FPD); ! 633: regs[PC] = (int)u.u_pcb.pcb_sigc; ! 634: return; ! 635: ! 636: asm("bad:"); ! 637: bad: ! 638: /* ! 639: * Process has trashed its stack; give it an illegal ! 640: * instruction to halt it in its tracks. ! 641: */ ! 642: u.u_signal[SIGILL] = SIG_DFL; ! 643: u.u_procp->p_siga0 &= ~(1<<(SIGILL-1)); ! 644: u.u_procp->p_siga1 &= ~(1<<(SIGILL-1)); ! 645: psignal(u.u_procp, SIGILL); ! 646: } ! 647: ! 648: int userreg[] = {R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, AP, FP, SP, PC}; ! 649: ! 650: dorti() ! 651: { ! 652: struct frame frame; ! 653: register int sp; ! 654: register int reg, mask; ! 655: ! 656: (void) copyin((caddr_t)u.u_ar0[FP], (caddr_t)&frame, sizeof (frame)); ! 657: sp = u.u_ar0[FP] + sizeof (frame); ! 658: u.u_ar0[PC] = frame.fr_savpc; ! 659: u.u_ar0[FP] = frame.fr_savfp; ! 660: u.u_ar0[AP] = frame.fr_savap; ! 661: mask = frame.fr_mask; ! 662: for (reg = 0; reg <= 11; reg++) { ! 663: if (mask&1) { ! 664: u.u_ar0[userreg[reg]] = fuword((caddr_t)sp); ! 665: sp += 4; ! 666: } ! 667: mask >>= 1; ! 668: } ! 669: sp += frame.fr_spa; ! 670: u.u_ar0[PS] = (u.u_ar0[PS] & 0xffff0000) | frame.fr_psw; ! 671: if (frame.fr_s) ! 672: sp += 4 + 4 * (fuword((caddr_t)sp) & 0xff); ! 673: /* phew, now the rei */ ! 674: u.u_ar0[PC] = fuword((caddr_t)sp); ! 675: sp += 4; ! 676: u.u_ar0[PS] = fuword((caddr_t)sp); ! 677: sp += 4; ! 678: u.u_ar0[PS] |= PSL_USERSET; ! 679: u.u_ar0[PS] &= ~PSL_USERCLR; ! 680: u.u_ar0[SP] = (int)sp; ! 681: } ! 682: ! 683: /* ! 684: * Invalidate single all pte's in a cluster ! 685: */ ! 686: tbiscl(v) ! 687: unsigned v; ! 688: { ! 689: register caddr_t addr; /* must be first reg var */ ! 690: register int i; ! 691: ! 692: asm(".set TBIS,58"); ! 693: addr = ptob(v); ! 694: for (i = 0; i < CLSIZE; i++) { ! 695: #ifdef lint ! 696: mtpr(TBIS, addr); ! 697: #else ! 698: asm("mtpr r11,$TBIS"); ! 699: #endif ! 700: addr += NBPG; ! 701: } ! 702: } ! 703: ! 704: int waittime = -1; ! 705: ! 706: boot(arghowto) ! 707: int arghowto; ! 708: { ! 709: register int howto; /* r11 == how to boot */ ! 710: register int devtype; /* r10 == major of root dev */ ! 711: ! 712: howto = arghowto; ! 713: if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) { ! 714: waittime = 0; ! 715: update(); ! 716: printf("syncing disks... "); ! 717: while (++waittime <= 5) ! 718: sleep((caddr_t)&lbolt, PZERO); ! 719: printf("done\n"); ! 720: } ! 721: splx(0x1f); /* extreme priority */ ! 722: devtype = major(rootdev); ! 723: if (howto&RB_HALT) { ! 724: #ifdef MVAX ! 725: if( cpu == M_VAX ) { ! 726: ((struct qb_regs *)nexus)->qb_cpmbx = RB_HALTMD; ! 727: for (;;) ! 728: asm ("halt"); ! 729: } ! 730: #endif MVAX ! 731: printf("halting (in tight loop); hit\n\t^P\n\tHALT\n\n"); ! 732: mtpr(IPL, 0x1f); ! 733: for (;;) ! 734: ; ! 735: } else { ! 736: if ((howto & RB_PANIC) != 0) ! 737: doadump(); ! 738: tocons(TXDB_BOOT); ! 739: } ! 740: #if defined(VAX750) || defined(VAX7ZZ) || defined(MVAX) ! 741: if (cpu != VAX_780) ! 742: { asm("movl r11,r5"); } /* boot flags go in r5 */ ! 743: #endif ! 744: #ifdef MVAX ! 745: if( cpu == M_VAX ) ! 746: ((struct qb_regs *)nexus)->qb_cpmbx = RB_REBOOT; ! 747: #endif ! 748: for (;;) ! 749: asm("halt"); ! 750: /*NOTREACHED*/ ! 751: } ! 752: ! 753: tocons(c) ! 754: { ! 755: ! 756: while ((mfpr(TXCS)&TXCS_RDY) == 0) ! 757: continue; ! 758: mtpr(TXDB, c); ! 759: } ! 760: ! 761: /* ! 762: * Doadump comes here after turning off memory management and ! 763: * getting on the dump stack, either when called above, or by ! 764: * the auto-restart code. ! 765: */ ! 766: dumpsys() ! 767: { ! 768: int dstat; ! 769: rpb.rp_flag = 1; ! 770: if ((minor(dumpdev)&07) != 1) ! 771: return; ! 772: printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); ! 773: printf("dump "); ! 774: switch (dstat = (*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { ! 775: ! 776: case ENXIO: ! 777: printf("device bad\n"); ! 778: break; ! 779: ! 780: case EFAULT: ! 781: printf("device not ready\n"); ! 782: break; ! 783: ! 784: case EINVAL: ! 785: printf("area improper\n"); ! 786: break; ! 787: ! 788: case EIO: ! 789: printf("i/o error\n"); ! 790: break; ! 791: ! 792: default: ! 793: printf("unexpected error %d\n", dstat); ! 794: break; ! 795: ! 796: case 0: ! 797: printf("succeeded\n"); ! 798: break; ! 799: } ! 800: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.