|
|
1.1 ! root 1: /* ! 2: * machine-dependent init stuff; ! 3: * specific to VAX but general to all models ! 4: */ ! 5: ! 6: #include "sys/param.h" ! 7: #include "sys/systm.h" ! 8: #include "sys/user.h" ! 9: #include "sys/proc.h" ! 10: #include "sys/map.h" ! 11: #include "sys/reg.h" ! 12: #include "sys/mtpr.h" ! 13: #include "sys/clock.h" ! 14: #include "sys/pte.h" ! 15: #include "sys/vm.h" ! 16: #include "sys/psl.h" ! 17: #include "sys/buf.h" ! 18: #include "sys/reboot.h" ! 19: #include "sys/conf.h" ! 20: #include "sys/text.h" ! 21: #include "sys/cmap.h" ! 22: #include "sys/msgbuf.h" ! 23: ! 24: /* ! 25: * table of little bits of page table needed ! 26: * by various bits of code ! 27: * the right way to do this would be ! 28: * to have a pool, and hand space out dynamically ! 29: */ ! 30: ! 31: extern char *CADDR1, *CADDR2, *CADDR3; ! 32: extern struct pte *CMAP1, *CMAP2, *CMAP3, *mmap; ! 33: extern char *vmmap; ! 34: extern char *priobuf; ! 35: extern struct pte *Prbufmap; ! 36: ! 37: struct { ! 38: int npages; ! 39: struct pte **pmap; ! 40: caddr_t *pmem; ! 41: } mmlist[] = { ! 42: UPAGES, &Swapmap, (caddr_t *)&swaputl, ! 43: UPAGES, &Forkmap, (caddr_t *)&forkutl, ! 44: UPAGES, &Xswapmap, (caddr_t *)&xswaputl, ! 45: UPAGES, &Xswap2map, (caddr_t *)&xswap2utl, ! 46: UPAGES, &Pushmap, (caddr_t *)&pushutl, ! 47: UPAGES, &Prusrmap, (caddr_t *)&prusrutl, ! 48: CLSIZE, &Prbufmap, (caddr_t *)&priobuf, ! 49: CLSIZE, &msgbufmap, (caddr_t *)&msgbuf, ! 50: USRPTSIZE, &Usrptmap, (caddr_t *)&usrpt, ! 51: 1, &CMAP1, (caddr_t *)&CADDR1, ! 52: 1, &CMAP2, (caddr_t *)&CADDR2, ! 53: 1, &CMAP3, (caddr_t *)&CADDR3, ! 54: 1, &mmap, (caddr_t *)&vmmap, ! 55: -1 ! 56: }; ! 57: ! 58: struct pte *physspt; ! 59: struct pte *Sysmap; ! 60: struct pte *Usrptmap; ! 61: struct pte *usrpt; ! 62: ! 63: /* ! 64: * init the memory map ! 65: * called early on, well before main ! 66: * memory management is off ! 67: * ! 68: * the system page table is allocated here, out of free memory ! 69: * the theory is: ! 70: * map the static kernel first ! 71: * then any pseudo-dynamic data structures ! 72: * then the buffers ! 73: * then lay down the system page table ! 74: * then map io space ! 75: * ! 76: * subtlety: we generally want end and etext to be physical addresses. ! 77: * (long)&end & ~KSTART seems to be the only expression that is constant ! 78: * with and without the c optimizer. ! 79: */ ! 80: ! 81: mmapinit(hiaddr) ! 82: long hiaddr; ! 83: { ! 84: extern int end, etext; ! 85: extern char *iospace; ! 86: register int i; ! 87: register long *p; /* pun; really struct pte * */ ! 88: register long mtop; /* highest real memory address used */ ! 89: register long ptop; /* highest virtual address used */ ! 90: register long v; ! 91: ! 92: maxmem = physmem = btoc(hiaddr); ! 93: mtop = (long)&end & ~KSTART; ! 94: /* ! 95: * dynamic things: add to memtop, set addrs along the way ! 96: */ ! 97: if (nbuf == 0) { ! 98: nbuf = 32 * physmem / btoc(1024*1024); ! 99: if (nbuf < 32) ! 100: nbuf = 32; ! 101: } ! 102: buf = (struct buf *)(KSTART+mtop); ! 103: mtop += nbuf * sizeof(struct buf); ! 104: mtop = (mtop + NBPG - 1) & ~PGOFSET; ! 105: buffers = (char *)(KSTART+mtop); ! 106: mtop += nbuf * BUFSIZE; ! 107: /* ! 108: * cmaps; we'll slightly overestimate; too bad ! 109: */ ! 110: cmap = (struct cmap *)(KSTART+mtop); ! 111: ncmap = (physmem * NBPG - mtop)/(CLSIZE*NBPG + sizeof(struct cmap)); ! 112: mtop += ncmap * sizeof(struct cmap); ! 113: ecmap = (struct cmap *)(KSTART+mtop); ! 114: /* ! 115: * clear all the memory we just handed out ! 116: */ ! 117: p = (long *)((long)&end & ~KSTART); ! 118: while (p < (long *)mtop) ! 119: *p++ = 0; ! 120: /* ! 121: * now the things that aren't memory ! 122: * maps are relative to beginning of spt ! 123: */ ! 124: mtop = (mtop + NBPG - 1) & ~PGOFSET; ! 125: ptop = mtop; ! 126: for (i = 0; mmlist[i].npages >= 0; i++) { ! 127: *mmlist[i].pmem = (caddr_t)(ptop + KSTART); ! 128: *mmlist[i].pmap = (struct pte *)(btoc(ptop) * sizeof(struct pte)); ! 129: ptop += ctob(mmlist[i].npages); ! 130: } ! 131: iospace = (char *)(ptop + KSTART); ! 132: ptop += mchiopsize(); ! 133: Sysmap = (struct pte *)(ptop + KSTART); ! 134: physspt = (struct pte *)mtop; ! 135: p = (long *)mtop; ! 136: i = (int)&etext & ~KSTART; /* not - KSTART; optimizer gets it wrong */ ! 137: for (v = 0; v < mtop; v += NBPG) /* kernel text + data */ ! 138: if (v < i) ! 139: *p++ = PG_V|PG_KR|btoc(v); ! 140: else ! 141: *p++ = PG_V|PG_KW|btoc(v); ! 142: for (; v < ptop; v += NBPG) /* mystery maps */ ! 143: *p++ = 0; ! 144: ptop += (btoc(ptop) + btoc(btoc(ptop)*sizeof(struct pte)))*sizeof(struct pte); ! 145: for (i = btoc(mtop); v < ptop; v += NBPG, i++) /* spt */ ! 146: *p++ = PG_V|PG_KW|i; ! 147: firstfree = i + 1; ! 148: /* ! 149: * fix the random maps ! 150: */ ! 151: for (i = 0; mmlist[i].npages >= 0; i++) ! 152: *(long *)mmlist[i].pmap += (long)Sysmap; ! 153: mchiopinit(physspt + btoc(iospace - KSTART)); ! 154: p = (long *)(physspt + (msgbufmap - Sysmap)); ! 155: for (i = 0; i < btoc(sizeof(struct msgbuf)); i++) ! 156: *p++ = PG_V|PG_KW|(physmem - btoc(sizeof(struct msgbuf)) + i); ! 157: maxmem -= CLSIZE; ! 158: mtpr(SBR, mtop); ! 159: mtpr(SLR, btoc(ptop)); ! 160: } ! 161: ! 162: /* ! 163: * set up context for process 0: ! 164: * first page of free memory becomes page table ! 165: * next UPAGES become user block ! 166: * init the process control block slightly ! 167: * called before memory mapping is turned on ! 168: */ ! 169: ! 170: uctinit(kpc) ! 171: long kpc; ! 172: { ! 173: register long *p; /* pun: struct pte * */ ! 174: register int i; ! 175: register struct pcb *pp; ! 176: ! 177: p = (long *)ctob(firstfree); ! 178: for (i = 0; i < (UPAGES+1)*NBPG; i += sizeof(long)) ! 179: *p++ = 0; ! 180: p = (long *)(physspt + ((long)usrpt-KSTART)/NBPG); ! 181: *p = PG_V|PG_KW|firstfree; /* one page for first p0 page table */ ! 182: p = (long *)ctob(firstfree+1); ! 183: for (i = UPAGES; i > 0; --i) ! 184: *--p = PG_V|PG_URKW|firstfree+i; ! 185: pp = (struct pcb *)ctob(firstfree+1); ! 186: pp->pcb_p0br = usrpt; ! 187: pp->pcb_p0lr = 0 + AST_NONE; /* no p0 space mapped */ ! 188: pp->pcb_p1br = usrpt + NPTEPG - P1TOP; ! 189: pp->pcb_p1lr = P1TOP - UPAGES; ! 190: pp->pcb_ksp = KSTART; ! 191: pp->pcb_esp = pp->pcb_ssp = -1; /* something invalid */ ! 192: pp->pcb_usp = USRSTACK; ! 193: pp->pcb_psl = 0; /* mode (kernel,kernel), ipl 0 */ ! 194: pp->pcb_pc = kpc; ! 195: firstfree += UPAGES + 1; ! 196: mtpr(PCBB, pp); ! 197: } ! 198: ! 199: /* ! 200: * Machine-dependent startup code ! 201: * some of this is excessively specific to the paging code ! 202: */ ! 203: ! 204: int dmmin, dmmax, dmtext; ! 205: ! 206: startup() ! 207: { ! 208: register long maxsz; ! 209: register unsigned i; ! 210: register struct proc *p; ! 211: extern struct map kernelmap[]; ! 212: extern int kernelcnt; ! 213: extern char version[]; ! 214: ! 215: setrestart(); ! 216: printf("%s\n", version); ! 217: meminit(firstfree, maxmem); ! 218: maxmem = freemem; ! 219: printf("mem = %d\n", ctob(maxmem)); ! 220: rminit(kernelmap, kernelcnt, USRPTSIZE-1, 1); ! 221: /* ! 222: * dmmin fixed for now ! 223: * dmmax == first power of 2 larger than max?size/(NDMAP-1) ! 224: */ ! 225: dmmin = DMMIN; ! 226: maxsz = maxtsize / NXDAD; ! 227: for (i = 0x80000000; i; i >>= 1) ! 228: if (maxsz & i) ! 229: break; ! 230: i *= 2; ! 231: if (i < dmmin) ! 232: i = dmmin; ! 233: dmtext = i; ! 234: maxsz = maxdsize > maxssize ? maxdsize : maxssize; ! 235: maxsz /= NDMAP-1; ! 236: if (maxsz < dmtext) ! 237: maxsz = dmtext; ! 238: for (i = 0x80000000; i; i >>= 1) ! 239: if (maxsz & i) ! 240: break; ! 241: i *= 2; ! 242: if (i < dmmin) ! 243: i = dmmin; ! 244: dmmax = i; ! 245: maxpgio *= nswdevt; ! 246: /* ! 247: * set up vm aspects of first process ! 248: */ ! 249: p = &proc[0]; ! 250: p->p_p0br = (struct pte *)mfpr(P0BR); ! 251: p->p_szpt = 1; ! 252: p->p_addr = uaddr(p); ! 253: setredzone(p->p_addr, (caddr_t)&u); ! 254: u.u_pcb.pcb_szpt = CLSIZE; ! 255: } ! 256: ! 257: /* ! 258: * init unix time ! 259: * base is some nearly correct number, e.g. from a filesystem. ! 260: * try to get something better from the VAX time-of-year clock, ! 261: * which contains the number of .01-second clicks in the current year ! 262: */ ! 263: clkinit(base) ! 264: time_t base; ! 265: { ! 266: register unsigned long todr; ! 267: int year = YRREF; ! 268: ! 269: todr = gettodr(); ! 270: if (todr < TODRZERO) { /* too small; TODR was restarted */ ! 271: time = base; ! 272: clkset(); /* so fix it */ ! 273: } ! 274: else { ! 275: for (time = (todr-TODRZERO)/100; time < base-SECYR/2; time += SECYR) { ! 276: if (LEAPYEAR(year)) ! 277: time += SECDAY; ! 278: year++; ! 279: } ! 280: } ! 281: } ! 282: ! 283: /* ! 284: * once a day or so, set TOY clock to match system clock ! 285: */ ! 286: ! 287: static time_t clknext; ! 288: ! 289: clkcheck() ! 290: { ! 291: ! 292: if (clknext == 0) ! 293: clknext = time + SECDAY; ! 294: if (clknext > time) ! 295: return; ! 296: clknext = time + SECDAY; ! 297: clkset(); ! 298: } ! 299: ! 300: /* ! 301: * reset the TOY clock to match current unix time ! 302: */ ! 303: ! 304: clkset() ! 305: { ! 306: int year = YRREF; ! 307: unsigned secyr; ! 308: unsigned yrtime = time; ! 309: ! 310: for (;;) { ! 311: secyr = SECYR; ! 312: if (LEAPYEAR(year)) ! 313: secyr += SECDAY; ! 314: if (yrtime < secyr) ! 315: break; ! 316: yrtime -= secyr; ! 317: year++; ! 318: } ! 319: settodr(TODRZERO + yrtime*100); ! 320: } ! 321: ! 322: /* ! 323: * bias the clock to correct an error of `wrong' milliseconds ! 324: * -- just tick slightly slowly or quickly for a while ! 325: * MicroVAX has no NICR, but writing it is a no-op; ! 326: * let the clock interrupt code do the work ! 327: */ ! 328: ! 329: int clockbias; /* number of ticks */ ! 330: char clocksign; /* direction to correct */ ! 331: ! 332: biasclock() ! 333: { ! 334: register struct a { ! 335: int wrong; ! 336: } *uap; ! 337: register long nticks; ! 338: ! 339: uap = (struct a *)u.u_ap; ! 340: if (!suser()) ! 341: return; ! 342: nticks = (long)uap->wrong * 1000; /* microseconds */ ! 343: nticks /= CLKBIAS; /* number of ticks to bias */ ! 344: spl7(); ! 345: if (nticks < 0) { ! 346: mtpr(NICR, CLK60HZ-CLKBIAS); ! 347: clockbias = -nticks; ! 348: clocksign = -1; /* -1 => clock must run slower */ ! 349: } ! 350: else { ! 351: mtpr(NICR, CLK60HZ+CLKBIAS); ! 352: clockbias = nticks; ! 353: clocksign = 1; ! 354: } ! 355: spl0(); ! 356: } ! 357: ! 358: /* ! 359: * Return the difference (in microseconds) ! 360: * between the current time and a previous ! 361: * time as represented by the arguments. ! 362: * If there is a pending clock interrupt ! 363: * which has not been serviced due to high ! 364: * ipl, return error code. ! 365: */ ! 366: vmtime(otime, olbolt, oicr) ! 367: register int otime, olbolt, oicr; ! 368: { ! 369: ! 370: if (mfpr(ICCS)&ICCS_INT) ! 371: return(-1); ! 372: else ! 373: return(((time-otime)*60 + lbolt-olbolt)*16667 + mfpr(ICR)-oicr); ! 374: } ! 375: ! 376: /* ! 377: * Send an interrupt to process ! 378: * ! 379: * SHOULD CHANGE THIS TO PASS ONE MORE WORK SO THAT ALL INFORMATION ! 380: * PROVIDED BY HARDWARE IS AVAILABLE TO THE USER PROCESS. ! 381: */ ! 382: sendsig(p, n) ! 383: int (*p)(); ! 384: { ! 385: register int *usp, *regs; ! 386: ! 387: regs = u.u_ar0; ! 388: usp = (int *)regs[SP]; ! 389: usp -= 5; ! 390: if ((int)usp <= USRSTACK - ctob(u.u_ssize)) ! 391: (void) grow((unsigned)usp); ! 392: if (useracc((caddr_t)usp, 5*sizeof(int), B_WRITE) == 0) ! 393: goto bad; ! 394: *usp++ = n; ! 395: if (n == SIGILL || n == SIGFPE) { ! 396: *usp++ = u.u_code; ! 397: u.u_code = 0; ! 398: } else ! 399: *usp++ = 0; ! 400: *usp++ = (int)p; ! 401: *usp++ = regs[PC]; ! 402: *usp++ = regs[PS]; ! 403: regs[SP] = (int)(usp - 5); ! 404: regs[PS] &= ~(PSL_CM|PSL_FPD); ! 405: regs[PC] = (int)u.u_pcb.pcb_sigc; ! 406: return; ! 407: ! 408: bad: ! 409: /* ! 410: * Process has trashed its stack; give it an illegal ! 411: * instruction to halt it in its tracks. ! 412: */ ! 413: u.u_signal[SIGILL] = SIG_DFL; ! 414: P_SETDFL(u.u_procp, SIGMASK(SIGILL)); ! 415: psignal(u.u_procp, SIGILL); ! 416: } ! 417: ! 418: /* ! 419: * Invalidate single all pte's in a cluster ! 420: */ ! 421: tbiscl(v) ! 422: unsigned v; ! 423: { ! 424: register caddr_t addr; ! 425: register int i; ! 426: ! 427: addr = ptob(v); ! 428: for (i = 0; i < CLSIZE; i++) { ! 429: mtpr(TBIS, addr); ! 430: addr += NBPG; ! 431: } ! 432: } ! 433: ! 434: /* ! 435: * sys reboot ! 436: * can this please go away? ! 437: */ ! 438: ! 439: boot(howto) ! 440: int howto; ! 441: { ! 442: ! 443: if (howto&RB_HALT) ! 444: death(); ! 445: reboot(1); ! 446: } ! 447: ! 448: /* ! 449: * freeze. can't just halt because ! 450: * on some machines that would cause a boot ! 451: */ ! 452: ! 453: death() ! 454: { ! 455: splx(0x1f); ! 456: printf("death\n"); ! 457: for (;;) ! 458: ; ! 459: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.