1: /*
   2:  * Copyright (c) 1986 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:  *	@(#)machdep2.c	2.9 (2.11BSD) 1999/2/19
   7:  */
   8: 
   9: #include "param.h"
  10: #include "../machine/seg.h"
  11: #include "../machine/iopage.h"
  12: 
  13: #include "dir.h"
  14: #include "inode.h"
  15: #include "user.h"
  16: #include "proc.h"
  17: #include "fs.h"
  18: #include "map.h"
  19: #include "buf.h"
  20: #include "text.h"
  21: #include "file.h"
  22: #include "clist.h"
  23: #include "uba.h"
  24: #include "callout.h"
  25: #include "reboot.h"
  26: #include "systm.h"
  27: #include "ram.h"
  28: #include "msgbuf.h"
  29: #include "namei.h"
  30: #include "ra.h"
  31: #include "tms.h"
  32: #include "ingres.h"
  33: #include "disklabel.h"
  34: #include "mount.h"
  35: 
  36: #if NINGRES > 0
  37: #include <sys/ingreslock.h>
  38: #endif
  39: 
  40: #ifdef QUOTA
  41: #include "quota.h"
  42: #endif
  43: 
  44: size_t  physmem;    /* total amount of physical memory (for savecore) */
  45: #if NRAC > 0 || NTMSCP > 0
  46: memaddr _iostart, _iobase;
  47: ubadr_t _ioumr;
  48: u_short _iosize = ((NTMSCP * (ctob(btoc(1864)))) + (NRAC * (ctob(btoc(1096)))));
  49: #endif
  50: 
  51: #ifdef  SOFUB_MAP
  52: extern  size_t  sofub_addr, sofub_off;
  53: extern  memaddr sofub_base;
  54: extern  u_int   sofub_size;
  55: #endif
  56: 
  57: segm    seg5;       /* filled in by initialization */
  58: 
  59: /*
  60:  * Machine dependent startup code
  61:  */
  62: startup()
  63: {
  64: #ifdef UCB_CLIST
  65:     extern memaddr clststrt;
  66: #endif
  67:     extern ubadr_t  clstaddr;
  68:     extern int end;
  69:     register memaddr i, freebase, maxclick;
  70: #if NRAM > 0
  71:     size_t ramsize;
  72: #endif
  73: 
  74:     printf("\n%s\n", version);
  75: 
  76:     saveseg5(seg5);     /* must be done before clear() is called */
  77:     /*
  78: 	 * REMAP_AREA is the start of possibly-mapped area, for consistency
  79: 	 * check.  Only proc, text and file tables are after it, and it must
  80: 	 * lie at <= 0120000, or other kernel data will be mapped out.
  81: 	 */
  82:     if (REMAP_AREA > SEG5)
  83:         panic("remap > SEG5");
  84: 
  85:     /*
  86: 	 * Zero and free all of core:
  87: 	 *
  88: 	 * MAXCLICK is the maximum accessible physical memory, assuming an 8K
  89: 	 * I/O page.  On systems without a Unibus map the end of memory is
  90: 	 * heralded by the beginning of the I/O page (some people have dz's
  91: 	 * at 0160000).  On systems with a Unibus map, the last 256K of the
  92: 	 * 4M address space is off limits since 017000000 to 017777777 is the
  93: 	 * actual 18 bit Unibus address space.  61440 is btoc(4M - 256K),
  94: 	 * and 65408 is btoc(4M - 8K).
  95: 	 *
  96: 	 * Previous cautions about 18bit devices on a 22bit Qbus were misguided.
  97: 	 * Since the GENERIC kernel was built with Q22 defined the limiting
  98: 	 * effect on memory size was not achieved, thus an 18bit controller
  99: 	 * could not be used to load the distribution.  ALSO, the kernel
 100: 	 * plus associated data structures do not leave enough room in 248kb
 101: 	 * to run the programs necessary to do _anything_.
 102: 	 */
 103: #define MAXCLICK_22U    61440       /* 22 bit UNIBUS (UNIBUS mapping) */
 104: #define MAXCLICK_22 65408       /* 22 bit QBUS */
 105: 
 106:     maxclick = ubmap ? MAXCLICK_22U : MAXCLICK_22;
 107: 
 108:     i = freebase = *ka6 + USIZE;
 109:     UISD[0] = ((stoc(1) - 1) << 8) | RW;
 110:     for (;;) {
 111:         UISA[0] = i;
 112:         if (fuibyte((caddr_t)0) < 0)
 113:             break;
 114:         ++maxmem;
 115:         /* avoid testing locations past "real" memory. */
 116:         if (++i >= maxclick)
 117:             break;
 118:     }
 119:     clear(freebase,i - freebase);
 120:     mem_parity();           /* enable parity checking */
 121:     clear(freebase,i - freebase);   /* quick check for parities */
 122:     mfree(coremap,i - freebase,freebase);
 123:     physmem = i;
 124: 
 125:     procNPROC = proc + nproc;
 126:     textNTEXT = text + ntext;
 127:     inodeNINODE = inode + ninode;
 128:     fileNFILE = file + nfile;
 129: 
 130:     /*
 131: 	 * IMPORTANT! Mapped out clists should always be allocated first!
 132: 	 * This prevents needlessly having to restrict all memory use
 133: 	 * (maxclick) to 248K just because an 18-bit DH is present on a
 134: 	 * 22-bit Q-BUS machine.  The maximum possible location for mapped
 135: 	 * out clists this way is 232K (56K base + 15 * 8K overlays + 48K
 136: 	 * data space + 8K (maximum) user structure, which puts the maximum
 137: 	 * top of mapped out clists at 240K ...
 138: 	 */
 139: #ifdef UCB_CLIST
 140: #define C   (nclist * sizeof(struct cblock))
 141:     if ((clststrt = malloc(coremap, btoc(C))) == 0)
 142:         panic("clists");
 143:     clstaddr = ((ubadr_t)clststrt) << 6;
 144: #undef C
 145: #else
 146:     clstaddr = (ubadr_t)cfree;
 147: #endif
 148: 
 149: /*
 150:  * IMPORTANT.  The software Unibus/Qbus map is allocated now if support for
 151:  * 18 bit controllers in a 22 bit system has been selected.  This buffer must
 152:  * reside _entirely_ within the low 256kb of memory.  A 10kb buffer is
 153:  * allocated, this is sufficient to handle 'dump', 'restor' and the default
 154:  * blocking factor of 'tar' (20 sectors).
 155:  *
 156:  * NOTE:  There is only 1 software map.  Multiple 18 bit controllers will
 157:  * have their access to the 'bounce buffer' single threaded by the soft
 158:  * map allocation routine sofub_alloc() in machdep.c.
 159:  *
 160:  * For more details see machdep.c.
 161: */
 162: 
 163: #ifdef  SOFUB_MAP
 164: #define B   (10240+64)
 165: 
 166:     sofub_size = (unsigned) B;
 167: 
 168:     if  ((sofub_base = malloc(coremap, btoc(B))) == 0)
 169:         panic("sofmap");            /* Paranoia */
 170:     else if (((sofub_base + btoc(B)) >> 10) > 3)    /* > 256kb! */
 171:         {
 172:         printf("sofmap > 256kb\n");
 173:         mfree(coremap, btoc(B), sofub_base);    /* give it back */
 174:         sofub_base = 0;
 175:         }
 176:     else
 177:         {
 178:         sofub_addr = sofub_base;
 179:         sofub_off = (sofub_base>>10)&3;
 180:         }
 181: #undef  B
 182: #endif /* SOFUB_MAP */
 183: 
 184: #ifdef EXTERNALITIMES
 185: #define C (btoc(ninode * sizeof (struct icommon2)))
 186:     if ((xitimes = malloc(coremap, C)) == 0)
 187:         panic("xitimes");
 188:     xitdesc = ((C - 1) << 8) | RW;
 189: #undef C
 190: #endif
 191: 
 192: #ifdef QUOTA
 193: #define C   (btoc(8192))
 194:     if ((quotreg = malloc(coremap, C)) == 0)
 195:         panic("quotamem");
 196:     quotdesc = ((C - 1) << 8) | RW;
 197:     QUOini();
 198: #undef C
 199: #endif
 200: 
 201:     {
 202: register int B;
 203: 
 204:     nchsize = 8192 / sizeof(struct namecache);
 205:     if (nchsize > (ninode * 11 / 10))
 206:         nchsize = ninode * 11 / 10;
 207:     B = (btoc(nchsize * sizeof(struct namecache)));
 208:     if ((nmidesc.se_addr = malloc(coremap, B)) == 0)
 209:         panic("nmidesc");
 210:     nmidesc.se_desc = ((B - 1) << 8) | RW;
 211:     namecache = (struct namecache *)SEG5;
 212:     }
 213: 
 214: #if NRAC > 0 || NTMSCP > 0
 215:     if ((_iobase = malloc(coremap, btoc(_iosize))) == 0)
 216:         panic("_iobase");
 217: #endif
 218: 
 219: #define B   (size_t)(((long)nbuf * (MAXBSIZE)) / ctob(1))
 220:     if ((bpaddr = malloc(coremap, B)) == 0)
 221:         panic("buffers");
 222: #undef B
 223: 
 224: /*
 225:  * Now initialize the log driver (kernel logger, error logger and accounting)
 226: */
 227:     loginit();
 228: 
 229: #define C   (btoc(sizeof (struct xmount)))
 230:     for (i = 0; i < NMOUNT; i++)
 231:         mount[i].m_extern = (memaddr)malloc(coremap, C);
 232: #undef  C
 233: 
 234: #if NINGRES > 0
 235: #define C   (btoc(LOCKTABSIZE))
 236: 
 237:     if (Locktabseg.se_addr = malloc(coremap, C))
 238:         Locktabseg.se_desc = ((C - 1) << 8) | RW;
 239: #undef  C
 240: #endif
 241: 
 242: /*
 243:  * Allocate the initial disklabels.
 244: */
 245:     (void) initdisklabels();
 246: 
 247: #if NRAM > 0
 248:     ramsize = raminit();
 249: #endif
 250: 
 251:     /*
 252: 	 * Initialize callouts
 253: 	 */
 254:     callfree = callout;
 255:     for (i = 1; i < ncallout; i++)
 256:         callout[i-1].c_next = &callout[i];
 257: 
 258:     UISA[7] = ka6[1];           /* io segment */
 259:     UISD[7] = ((stoc(1) - 1) << 8) | RW;
 260: }
 261: 
 262: mem_parity()
 263: {
 264:     register int cnt;
 265: 
 266:     for (cnt = 0;cnt < 16;++cnt) {
 267:         if (fioword((caddr_t)(MEMSYSMCR+cnt)) == -1)
 268:             return;
 269:         *(MEMSYSMCR+cnt) = MEMMCR_EIE;  /* enable parity interrupts */
 270:     }
 271: }
 272: 
 273: #if defined(PROFILE) && !defined(ENABLE34)
 274: /*
 275:  * Allocate memory for system profiling.  Called once at boot time.
 276:  * Returns number of clicks used by profiling.
 277:  *
 278:  * The system profiler uses supervisor I space registers 2 and 3
 279:  * (virtual addresses 040000 through 0100000) to hold the profile.
 280:  */
 281: msprof()
 282: {
 283:     memaddr proloc;
 284:     int nproclicks;
 285: 
 286:     nproclicks = btoc(8192*2);
 287:     proloc = malloc(coremap, nproclicks);
 288:     if (proloc == 0)
 289:         panic("msprof");
 290: 
 291:     *SISA2 = proloc;
 292:     *SISA3 = proloc + btoc(8192);
 293:     *SISD2 = 077400|RW;
 294:     *SISD3 = 077400|RW;
 295:     *SISD0 = RW;
 296:     *SISD1 = RW;
 297: 
 298:     /*
 299: 	 * Enable system profiling.  Zero out the profile buffer
 300: 	 * and then turn the clock (KW11-P) on.
 301: 	 */
 302:     clear(proloc, nproclicks);
 303:     isprof();
 304:     printf("profiling on\n");
 305: 
 306:     return (nproclicks);
 307: }
 308: #endif
 309: 
 310: /*
 311:  * Re-initialize the Unibus map registers to statically map
 312:  * the clists and buffers.  Free the remaining registers for
 313:  * physical I/O.  At this time the [T]MSCP arena is also mapped.
 314:  */
 315: ubinit()
 316: {
 317:     register int i, ub_nreg;
 318:     long paddr;
 319:     register struct ubmap *ubp;
 320: 
 321:     if (!ubmap)
 322:         return;
 323:     /*
 324: 	 * Clists start at UNIBUS virtual address 0.  The size of
 325: 	 * the clist segment can be no larger than UBPAGE bytes.
 326: 	 * Clstaddt was the physical address of clists.
 327: 	 */
 328:     if (nclist * sizeof(struct cblock) > ctob(stoc(1)))
 329:         panic("clist > 8k");
 330:     setubregno(0, clstaddr);
 331:     clstaddr = (ubadr_t)0;
 332: 
 333:     /*
 334: 	 * Buffers start at UNIBUS virtual address BUF_UBADDR.
 335: 	 */
 336:     paddr = ((long)bpaddr) << 6;
 337:     ub_nreg = nubreg(nbuf, MAXBSIZE);
 338:     for (i = BUF_UBADDR/UBPAGE; i < ub_nreg + (BUF_UBADDR/UBPAGE); i++) {
 339:         setubregno(i, paddr);
 340:         paddr += (long)UBPAGE;
 341:     }
 342:     /*
 343: 	 * The 3Com ethernet board is hardwired to use UNIBUS registers 28, 29
 344: 	 * and 30 (counting from 0) and UNIBUS register 31 isn't usable.
 345: 	 */
 346: #include "ec.h"
 347: #if NEC > 0
 348:     mfree(ub_map, 28 - ub_nreg - 1, 1 + ub_nreg);   /* 3Com board */
 349: #else
 350:     mfree(ub_map, 31 - ub_nreg - 1, 1 + ub_nreg);
 351: #endif
 352: 
 353: /*
 354:  * this early in the system's life there had better be a UMR or two
 355:  * available!!  N.B. This was moved from where the [T]MSCP memory was
 356:  * allocated because at that point the UMR map was not initialized.
 357: */
 358: 
 359: #if NRAC > 0 || NTMSCP > 0
 360:     _iostart = _iobase;
 361:     i = (int)btoub(_iosize);
 362:     ub_nreg = malloc(ub_map, i);
 363:     _ioumr = (ubadr_t)ub_nreg << 13;
 364:     ubp = &UBMAP[ub_nreg];
 365:     paddr = ctob((ubadr_t)_iostart);
 366:     while (i--) {
 367:         ubp->ub_lo = loint(paddr);
 368:         ubp->ub_hi = hiint(paddr);
 369:         ubp++;
 370:         paddr += (ubadr_t)UBPAGE;
 371:     }
 372: #endif
 373: }
 374: 
 375: int waittime = -1;
 376: 
 377: boot(dev, howto)
 378:     register dev_t dev;
 379:     register int howto;
 380: {
 381:     register struct fs *fp;
 382: 
 383:     /*
 384: 	 * Force the root filesystem's superblock to be updated,
 385: 	 * so the date will be as current as possible after
 386: 	 * rebooting.
 387: 	 */
 388:     if (fp = getfs(rootdev))
 389:         fp->fs_fmod = 1;
 390:     if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) {
 391:         waittime = 0;
 392:         printf("syncing disks... ");
 393:         (void) _splnet();
 394:         /*
 395: 		 * Release inodes held by texts before update.
 396: 		 */
 397:         xumount(NODEV);
 398:         sync();
 399:         { register struct buf *bp;
 400:           int iter, nbusy;
 401: 
 402:           for (iter = 0; iter < 20; iter++) {
 403:             nbusy = 0;
 404:             for (bp = &buf[nbuf]; --bp >= buf; )
 405:                 if (bp->b_flags & B_BUSY)
 406:                     nbusy++;
 407:             if (nbusy == 0)
 408:                 break;
 409:             printf("%d ", nbusy);
 410:             delay(40000L * iter);
 411:           }
 412:         }
 413:         printf("done\n");
 414:     }
 415:     (void) _splhigh();
 416:     if (howto & RB_HALT) {
 417:         printf("halting\n");
 418:         halt();
 419:         /*NOTREACHED*/
 420:     }
 421:     else {
 422:         if (howto & RB_DUMP) {
 423:             /*
 424: 			 * save the registers in low core.
 425: 			 */
 426:             saveregs();
 427:             dumpsys();
 428:         }
 429:         doboot(dev, howto);
 430:         /*NOTREACHED*/
 431:     }
 432: }
 433: 
 434: /*
 435:  * Dumpsys takes a dump of memory by calling (*dump)(), which must
 436:  * correspond to dumpdev.  *(dump)() should dump from dumplo blocks
 437:  * to the end of memory or to the end of the logical device.
 438:  */
 439: dumpsys()
 440: {
 441:     extern int (*dump)();
 442:     register int error;
 443: 
 444:     if (dumpdev != NODEV) {
 445:         printf("\ndumping to dev %o off %D\ndump ",dumpdev,dumplo);
 446:         error = (*dump)(dumpdev);
 447:         switch(error) {
 448: 
 449:         case EFAULT:
 450:             printf("dev !ready:EFAULT\n");
 451:             break;
 452:         case EINVAL:
 453:             printf("args:EINVAL\n");
 454:             break;
 455:         case EIO:
 456:             printf("err:EIO\n");
 457:             break;
 458:         default:
 459:             printf("unknown err:%d\n",error);
 460:             break;
 461:         case 0:
 462:             printf("succeeded\n");
 463:             break;
 464:         }
 465:     }
 466: }
 467: 
 468: #if NRAC > 0 || NTMSCP > 0
 469: memaddr
 470: _ioget(size)
 471:     u_int size;
 472:     {
 473:     register memaddr base;
 474:     register u_int csize;
 475: 
 476:     csize = btoc(size);
 477:     size = ctob(csize);
 478:     if (size > _iosize)
 479:         return(0);
 480:     _iosize -= size;
 481:     base = _iobase;
 482:     _iobase += csize;
 483:     return(base);
 484:     }
 485: 
 486: ubadr_t
 487: _iomap(addr)
 488:     register memaddr addr;
 489:     {
 490:     return(((ubadr_t)(addr - _iostart) << 6) + _ioumr);
 491:     }
 492: #endif
 493: 
 494: #define NLABELS 6
 495: 
 496:     memaddr _dlabelbase;
 497:     int _dlabelnum = NLABELS;
 498: 
 499: void
 500: initdisklabels()
 501:     {
 502: #define C   (NLABELS * (btoc(sizeof (struct disklabel))))
 503: 
 504:     _dlabelbase = malloc(coremap, C);
 505:     }
 506: 
 507: memaddr
 508: disklabelalloc()
 509:     {
 510:     register memaddr base;
 511: 
 512:     if  (--_dlabelnum)
 513:         {
 514:         base = _dlabelbase;
 515:         _dlabelbase += btoc(sizeof (struct disklabel));
 516:         return(base);
 517:         }
 518:     base = malloc(coremap, btoc (sizeof (struct disklabel)));
 519:     return(base);
 520:     }

Defined functions

_ioget defined in line 469; used 2 times
boot defined in line 377; used 2 times
dumpsys defined in line 439; used 1 times
initdisklabels defined in line 499; used 1 times
mem_parity defined in line 262; used 1 times
msprof defined in line 281; never used
startup defined in line 62; used 1 times
ubinit defined in line 315; used 1 times

Defined variables

_dlabelbase defined in line 496; used 3 times
_dlabelnum defined in line 497; used 1 times
_iobase defined in line 46; used 4 times
_iosize defined in line 48; used 4 times
_iostart defined in line 46; used 3 times
_ioumr defined in line 47; used 2 times
physmem defined in line 44; used 4 times
seg5 defined in line 57; used 1 times
  • in line 76
waittime defined in line 375; used 2 times

Defined macros

B defined in line 219; used 11 times
C defined in line 502; used 14 times
MAXCLICK_22 defined in line 104; used 1 times
MAXCLICK_22U defined in line 103; used 1 times
NLABELS defined in line 494; used 2 times
Last modified: 1999-02-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4548
Valid CSS Valid XHTML 1.0 Strict