⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 machdep.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
	 */	if (cpu == VAX_60) 		fccons_init();#endif MVAX || VAX3600 || VAX420 || VAX60	/*	 * Allocate space for system data structures.	 * The first available real memory address is in "firstaddr".	 * As pages of memory are allocated, "firstaddr" is incremented.	 * The first available kernel virtual address is in "v".	 * As pages of kernel virtual memory are allocated, "v" is incremented.	 * An index into the kernel page table corresponding to the	 * virtual memory address maintained in "v" is kept in "mapaddr".	 */	mapaddr = firstaddr;	v = (caddr_t) (0x80000000 | (firstaddr * NBPG));#define valloc(name, type, num) \		(name) = (type *)(v); (v) = (caddr_t)((name)+(num))#define valloclim(name, type, num, lim) \		(name) = (type *)(v); (v) = (caddr_t)((lim) = ((name)+(num)))	valloclim (gnode, struct gnode , ngnode, gnodeNGNODE);	valloclim (file, struct file   , nfile, fileNFILE);	valloclim (proc, struct proc   , nproc, procNPROC);	valloclim (text, struct text   , ntext, textNTEXT);	valloc (cfree, struct cblock   , nclist);	valloc (callout, struct callout, ncallout);	valloc (chrout, struct chrout, nchrout);	valloc (swapmap, struct map, nswapmap = nproc * 2);	valloc (kernelmap, struct map  , nproc+32);	valloc (nch, struct nch, nchsize); 	valloc (flox, struct filock, flckinfo.recs ); 	valloc (flinotab, struct flino, flckinfo.fils );	valloc (kmemmap, struct map, (ekmempt - kmempt) - km_wmapsize);	valloc (kmemwmap, struct map, km_wmapsize);	valloc (kmemusage, struct kmemusage, (ekmempt - kmempt) / CLSIZE);	/* allocate space for gateway screen freelist */	valloc(screen_storage, char, screen_space_needed());#ifdef QUOTA	valloclim (quota, struct quota , nquota, quotaNQUOTA);	valloclim (dquot, struct dquot , ndquot, dquotNDQUOT);#endif QUOTA	/*	 * Determine how many buffers to allocate, unless this has	 * already been patched into the kernel.	 *	 * Use bufcache% (a config'able option) of memory.	 * If bufpgs > (physmem - min mem reserved for system)	 * then set bufpgs to (physmem - min mem reserved for system).	 * Ensure that bufpages is at least 10% of memory.	 *	 * We allocate 1/2 as many swap buffer headers (nswbuf)	 * as file i/o buffers (nbuf), but never more than 256.	 */	if (bufpages == 0) {		/*		 * requestpages, maxbufpages, tenpercent are measured 		 * in NBPG byte units.		 *		 * requestpages is what was requested in the config file.		 * maxbufpages is the upper limit of what is allowed.		 * tenpercent is the lower limit of what is allowed.		 *		 * As silly as this sounds, the upper limit can be lower		 * than the lower limit (even negative on minimum		 * configuration machines), so make sure that the upper		 * limit is >= tenpercent		 *		 * Since we only have MINMEM_PGS to guide us, and		 * since this number is only meaningful for kernels		 * with relatively small system table sizes, scale		 * up the estimate of the demands that these tables		 * make on memory as a function of maxusers when		 * computing the upper limit.		 * Allow for the buffer headers as well.		 *		 */		requestpages = (physmem * ((float)bufcache/100));		maxbufpages = physmem			- MINMEM_PGS			- (maxusers/32) * 1024	/* .5 MB per 32 users */			- (sysptsize * sizeof(struct pte)) / NBPG			- 1;		/*		 * kperbuf is set to 4 for		 * uniprocessors, and 8 (no moving of physical		 * memory under a virtual address) for multi-processors.		 * Sanity test kperbuf on multiprocessors to		 * guarantee that buffer memory is not moved around.		 */		if (!kperbuf) /* hasn't been manually patched */			kperbuf = ((smp) ? 8 : 4);		if (smp && kperbuf != 8)			panic("buffer header allocation failure");		maxbufs = maxbufpages / CLSIZE / kperbuf;		maxbufpages -= (maxbufs * sizeof(struct buf)) / NBPG;		tenpercent = physmem / 10;		if (maxbufpages < tenpercent)			maxbufpages = tenpercent;if (bufdebug) {printf("startup: physmem %d bufcache %d requestpages %d\n",       physmem, bufcache, requestpages);printf("startup: kperbuf %d maxbufs %d maxbufpages %d tenpercent %d\n",       kperbuf, maxbufs, maxbufpages, tenpercent);}		if (requestpages > maxbufpages) {if (bufdebug) {printf("startup: bufcache request of %d bytes reduced to %d bytes\n",       requestpages*NBPG, maxbufpages*NBPG);}			requestpages = maxbufpages;		}		/* bufpages is measured in page cluster units */		bufpages = requestpages / CLSIZE;	}				if (nbuf == 0) {		/* nbuf is # of kperbuf-K objects that can fit in bufpages */		nbuf = bufpages / kperbuf;	}	if (nswbuf == 0) {		nswbuf = (nbuf / 2) &~ 1;	/* force even */		if (nswbuf > 256)			nswbuf = 256;		/* sanity */	}if (bufdebug) {printf("startup: bufpages %d nbuf %d nswbuf %d\n",	bufpages, nbuf, nswbuf);printf("startup: valloc swbuf v = 0x%x nswbuf %d\n", v, nswbuf);}	valloc(swbuf, struct buf, nswbuf);	/*	 * Now the amount of virtual memory remaining for buffers	 * can be calculated, estimating needs for the cmap.	 */	ncmap = (maxmem*NBPG - ((int)v &~ 0x80000000)) /		(CLBYTES + sizeof(struct cmap)) + 2;if (bufdebug) {printf("startup: maxmem %d NBPG %d v 0x%x CLBYTES %d sizeof(cmap) %d\n",       maxmem, NBPG, v, CLBYTES, sizeof(struct cmap));printf("startup: ncmap %d = (%d / %d) + 2\n",       ncmap, (maxmem*NBPG - ((int)v &~ 0x80000000)),       (CLBYTES + sizeof(struct cmap)) );}	maxbufs = ((sysptsize * NBPG) -	    ((int)(v + ncmap * sizeof(struct cmap)) - 0x80000000)) /		(MAXBSIZE + sizeof(struct buf));if (bufdebug) {printf("startup: sysptsize %d ncmap %d sizeof(cmap) %d\n",	sysptsize, ncmap, sizeof(struct cmap));printf("startup: ((0x%x + 0x%x) - 0x80000000) / 0x%x\n",	v, ncmap*sizeof(struct cmap), sizeof(struct buf));printf("startup: maxbufs %d\n", maxbufs);}	/*	 * If the system page table is too small for the available	 * physical memory (not enough room for nbufs after the core map)	 * then the size of physical memory (physmem) is artifically	 * reduced to MINMEM_PGS (the minimun amount supported).	 * This should allow booting generic kernels on systems with	 * large physical memory.	 */	if (maxbufs < 16) {		/* 		 * Let's not print this anymore. It scares the user and they		 * complain about it alot.  They will be told in a less		 * frightful way later, where 'real mem' is displayed.		 */if (bufdebug) {printf("startup: system page table too small, reducing physmem to %d meg\n",MINMEM_MB);}		if (++tries > 1)			panic ("sys pt too small");		physmem=MINMEM_PGS; /* # of 512 byte pages = MINMEM_MB */		maxusers=(maxusers > 8) ? 8 : maxusers;		nbuf=bufpages=nswbuf=0;		goto tryagain;	}	reducenbufs = 0;	if (nbuf > maxbufs) {if (bufdebug) {printf("startup: sysptsize limits number of buffers to %d\n", maxbufs);}		nbuf = maxbufs;		reducenbufs = 1;	}	if (bufpages > nbuf * (MAXBSIZE / CLBYTES)) {		bufpages = nbuf * (MAXBSIZE / CLBYTES);if (bufdebug) {printf("startup: bufpages > than needed, reduced to %d\n",       bufpages);}	}if (bufdebug) {printf("startup: valloc buf, nbuf %d(%d) bufpages %d v 0x%x\n",	nbuf, sizeof(struct buf), bufpages, v);}	valloc(buf, struct buf, nbuf);	/*	 * Allocate space for core map.	 * Allow space for all of phsical memory minus the amount 	 * dedicated to the system. The amount of physical memory	 * dedicated to the system is the total virtual memory of	 * the system thus far, plus core map, buffer pages,	 * and buffer headers not yet allocated.	 * Add 2: 1 because the 0th entry is unused, 1 for rounding.	 */	ncmap = (maxmem*NBPG - ((int)(v + bufpages*CLBYTES) &~ 0x80000000)) /		(CLBYTES + sizeof(struct cmap)) + 2;if (bufdebug) {printf("startup: maxmem %d bufpages %d v 0x%x\n",       maxmem, bufpages, v);printf("startup: ncmap %d = (%d / %d) + 2\n",       ncmap, (maxmem*NBPG - ((int)(v + bufpages*CLBYTES) &~ 0x80000000)),        (CLBYTES + sizeof(struct cmap)) );}	if (ncmap <= 0) {		if (++tries > 1)			panic ("no memory (A)");		printf("not enough memory after allocating buffer cache!\n");		if (bufcache > 10) {			bufcache = max(bufcache / 2, 10);			printf("bufcache reduced to %d percent\n", bufcache);		} else {			maxusers = max(maxusers / 2, 2);			printf("maxusers reduced to %d\n", maxusers);		}		printf("consider re-sizing kernel configuration parameters\n");		nbuf=bufpages=nswbuf=0;		goto tryagain;	}	valloclim(cmap, struct cmap, ncmap, ecmap);	/*	 * Clear space allocated thus far, and make r/w entries	 * for the space in the kernel map.	 */	unixsize = btoc((int)v &~ 0x80000000);	while (firstaddr < unixsize) {		*(int *)(&Sysmap[firstaddr]) = PG_V | PG_KW | firstaddr;		bzero(0x80000000 | (ctob(firstaddr)),NBPG);		firstaddr++;	}	/* Save PFN of last kernel page to dump for crashdump code */	lastkpage = firstaddr;	/*	 * Now allocate buffers proper.  They are different than the above	 * in that they usually occupy more virtual memory than physical.	 * Set endofmem to the last used kernel virtual address.	 */	v = (caddr_t) ((int)(v + PGOFSET) &~ PGOFSET);if (bufdebug) {printf("startup: valloc buffers, nbuf %d MAXBSIZE %d v 0x%x\n",	nbuf, MAXBSIZE, v);}	valloc(buffers, char, MAXBSIZE * nbuf);	endofmem = v;if (bufdebug) {printf("startup: endofmem = 0x%x\n", endofmem);}	base = bufpages / nbuf;	/* clusters of memory per buffer header */	residual = bufpages % nbuf;if (bufdebug) {printf("startup: base (K/buf) = %d, residual = %d\n", base, residual);}	mapaddr = firstaddr;	for (i = 0; i < residual; i++) {		for (j = 0; j < (base + 1) * CLSIZE; j++) {			*(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr;			bzero(0x80000000 | (ctob(mapaddr)),NBPG);			firstaddr++;		}		mapaddr += MAXBSIZE / NBPG;	}	for (i = residual; i < nbuf; i++) {		for (j = 0; j < base * CLSIZE; j++) {			*(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | firstaddr;			bzero(0x80000000 | (ctob(mapaddr)),NBPG);			firstaddr++;		}		mapaddr += MAXBSIZE / NBPG;	}if (bufdebug) {printf("startup: end(kernel real mem) %d, end(kernel virtual mem) %d\n",	firstaddr*NBPG, ((int)endofmem & ~ 0x80000000));printf("startup: sys virt pgs %d, sys real pgs %d\n",   	((int)(v + 1) & ~0x80000000) / NBPG, firstaddr*NBPG);printf("startup: # of sys ptes %d, # of sys ptes used %d\n",        sysptsize, mapaddr);}	if (firstaddr >= physmem - MINMEM_FREE)		panic ("no memory (B)");	mtpr (TBIA, 0); /*  * Initialize callouts  */	callfree = callout;	for (i = 1; i < ncallout; i++)		callout[i - 1].c_next = &callout[i]; /*  * Initialize interrupt queue  */	chrfree = chrcur = &chrout[0];	for (i = 1; i < nchrout; i++)		chrout[i - 1].c_next = &chrout[i];	chrout[nchrout - 1].c_next = &chrout[0]; /* circular llist */ /*  * Initialize gateway screen freelist  */	screen_init_freelist(screen_storage); /*  * Initialize memory allocator and swap  * and user page table maps.  *  * THE USER PAGE TABLE MAP IS CALLED ``kernelmap''  * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME.  */	meminit (firstaddr, maxmem);	maxmem = freemem;	kmeminit();		rminit (kernelmap, (long)usrptsize, (long) 1, "usrpt", nproc+32); /*    * Log startup printfs  */	appendflg = 1; 	/* tell error logger we're starting up */	printf (version);	printf ("real mem  = %d\n", ctob (Physmem));	if (tries  &&  Physmem != physmem) { /* we've reconfigured because of a small SPT */		printf("Memory configuration adjusted to run with small system page table\n");		printf ("real mem  = %d\n", ctob (physmem));	}	printf ("avail mem = %d\n", ctob (maxmem));	if (reducenbufs) { /* # of buffer headers was limited by sysptsize */		printf("Buffer configuration adjusted to run with small system page table\n");	}	printf ("using %d buffers containing %d bytes of memory\n",		nbuf, bufpages * CLBYTES);	/* allocate 1 pte for each proc structure to be used to 	   double map the PCB in the u_area */ 	nxv = (char *)get_sys_ptes(nproc, &pte);	/* put virtual address for double map in the proc structure */	for(i=0;i<nproc; i++) {		proc[i].p_pcb =(struct pcb *)((int)  nxv + (i*512));	} /*  * Clear restart inhibit flags.  */	switch(cpu) {#ifdef VAX9000		case VAX_9000:			ka9000_clear_coldstart();			ka9000_clear_warmstart();			break;#endif VAX9000#ifdef VAX8800		case VAX_8800:		case VAX_8820:			cons_putc (N_COMM|N_CLR_COLD);			cons_putc (N_COMM|N_CLR_WARM);			break;#endif VAX8800		default:			cons_putc (TXDB_CWSI);			cons_putc (TXDB_CCSI);			break;	}}/* * Enable Cache *  * The actual routines are entered through cpusw, and are located * in the appropiate cpu dependent routine kaXXX.c */cachenbl(){	if ((*cpup->cachenbl)() < 0 )		panic("No cachenbl routine configured\n");}#ifdef PGINPROF/* * Return the difference (in microseconds) * between the	current time and a previous * time as represented	by the arguments. * If there is a pending clock interrupt * which has not been serviced due to high * ipl, return error code. */vmtime (otime, olbolt, oicr)register int	otime, olbolt, oicr;{	if (mfpr (ICCS) & ICCS_INT)		return (-1);	else		return (((time.tv_sec - otime) * 60 + lbolt - olbolt) * 16667 + mfpr (ICR) - oicr);}#endif/* * Send an interrupt to process. * * Stack is set up to allow sigcode stored * in u. to call routine, followed by chmk * to sigcleanup routine below.  After sigcleanup * resets the signal mask and the stack, it * returns to user who then unwinds with the * rei at the bottom of sigcode. */sendsig (p, sig, mask)int	(*p) (), sig, mask;{	register struct sigcontext *scp;	/* know to be r11 */	register int   *regs;	register struct sigframe		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -