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

📄 machdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * All advertising materials mentioning features or use of this software * must display the following acknowledgement: *	This product includes software developed by the University of *	California, Lawrence Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)machdep.c	8.6 (Berkeley) 1/14/94 * * from: $Header: machdep.c,v 1.44 93/10/31 05:28:36 torek Exp $ */#include <sys/param.h>#include <sys/proc.h>#include <sys/user.h>#include <sys/map.h>#include <sys/buf.h>#include <sys/device.h>#include <sys/reboot.h>#include <sys/systm.h>#include <sys/conf.h>#include <sys/file.h>#include <sys/clist.h>#include <sys/callout.h>#include <sys/malloc.h>#include <sys/mbuf.h>#include <sys/mount.h>#include <sys/msgbuf.h>#ifdef SYSVSHM#include <sys/shm.h>#endif#include <sys/exec.h>#include <sys/sysctl.h>#include <machine/autoconf.h>#include <machine/frame.h>#include <machine/cpu.h>#include <vm/vm_kern.h>#include <vm/vm_page.h>#include <sparc/sparc/asm.h>#include <sparc/sparc/cache.h>#include <sparc/sparc/vaddrs.h>vm_map_t buffer_map;extern vm_offset_t avail_end;/* * Declare these as initialized data so we can patch them. */int	nswbuf = 0;#ifdef	NBUFint	nbuf = NBUF;#elseint	nbuf = 0;#endif#ifdef	BUFPAGESint	bufpages = BUFPAGES;#elseint	bufpages = 0;#endifint	physmem;extern struct msgbuf msgbuf;struct	msgbuf *msgbufp = &msgbuf;int	msgbufmapped = 1;	/* message buffer is always mapped *//* * safepri is a safe priority for sleep to set for a spin-wait * during autoconfiguration or after a panic. */int   safepri = 0;caddr_t allocsys();/* * Machine-dependent startup code */cpu_startup(){	register unsigned i;	register caddr_t v;	register int sz;	int base, residual;#ifdef DEBUG	extern int pmapdebug;	int opmapdebug = pmapdebug;#endif	vm_offset_t minaddr, maxaddr;	vm_size_t size;#ifdef DEBUG	pmapdebug = 0;#endif	/*	 * Good {morning,afternoon,evening,night}.	 */	printf(version);	/*identifycpu();*/	physmem = btoc(avail_end);	printf("real mem = %d\n", avail_end);	/*	 * Find out how much space we need, allocate it,	 * and then give everything true virtual addresses.	 */	sz = (int)allocsys((caddr_t)0);	if ((v = (caddr_t)kmem_alloc(kernel_map, round_page(sz))) == 0)		panic("startup: no room for tables");	if (allocsys(v) - v != sz)		panic("startup: table size inconsistency");	/*	 * Now allocate buffers proper.  They are different than the above	 * in that they usually occupy more virtual memory than physical.	 */	size = MAXBSIZE * nbuf;	buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers,	    &maxaddr, size, TRUE);	minaddr = (vm_offset_t)buffers;	if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,			&minaddr, size, FALSE) != KERN_SUCCESS)		panic("startup: cannot allocate buffers");	base = bufpages / nbuf;	residual = bufpages % nbuf;	for (i = 0; i < nbuf; i++) {		vm_size_t curbufsize;		vm_offset_t curbuf;		/*		 * First <residual> buffers get (base+1) physical pages		 * allocated for them.  The rest get (base) physical pages.		 *		 * The rest of each buffer occupies virtual space,		 * but has no physical memory allocated for it.		 */		curbuf = (vm_offset_t)buffers + i * MAXBSIZE;		curbufsize = CLBYTES * (i < residual ? base+1 : base);		vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);		vm_map_simplify(buffer_map, curbuf);	}	/*	 * Allocate a submap for exec arguments.  This map effectively	 * limits the number of processes exec'ing at any time.	 */	exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,	    16*NCARGS, TRUE);	/*	 * Allocate a map for physio.  Others use a submap of the kernel	 * map, but we want one completely separate, even though it uses	 * the same pmap.	 */	phys_map = vm_map_create(kernel_pmap, DVMA_BASE, DVMA_END, 1);	if (phys_map == NULL)		panic("unable to create DVMA map");	/*	 * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size	 * we use the more space efficient malloc in place of kmem_alloc.	 */	mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,				   M_MBUF, M_NOWAIT);	bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);	mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr,			       VM_MBUF_SIZE, FALSE);	/*	 * Initialize callouts	 */	callfree = callout;	for (i = 1; i < ncallout; i++)		callout[i-1].c_next = &callout[i];	callout[i-1].c_next = NULL;#ifdef DEBUG	pmapdebug = opmapdebug;#endif	printf("avail mem = %d\n", ptoa(cnt.v_free_count));	printf("using %d buffers containing %d bytes of memory\n",		nbuf, bufpages * CLBYTES);	/*	 * Set up buffers, so they can be used to read disk labels.	 */	bufinit();	/*	 * Configure the system, then turn on the cache.  Should be able	 * to do this earlier, but then esp.c fails on SS1+ boxes (??).	 */	configure();	cache_enable();}/* * Allocate space for system data structures.  We are given * a starting virtual address and we return a final virtual * address; along the way we set each data structure pointer. * * You call allocsys() with 0 to find out how much space we want, * allocate that much and fill it with zeroes, and then call * allocsys() again with the correct base virtual address. */caddr_tallocsys(v)	register caddr_t v;{#define	valloc(name, type, num) \	    v = (caddr_t)(((name) = (type *)v) + (num))	valloc(cfree, struct cblock, nclist);	valloc(callout, struct callout, ncallout);	valloc(swapmap, struct map, nswapmap = maxproc * 2);#ifdef SYSVSHM	valloc(shmsegs, struct shmid_ds, shminfo.shmmni);#endif		/*	 * Determine how many buffers to allocate (enough to	 * hold 5% of total physical memory, but at least 16).	 * Allocate 1/2 as many swap buffer headers as file i/o buffers.	 */	if (bufpages == 0)		bufpages = (physmem / 20) / CLSIZE;	if (nbuf == 0) {		nbuf = bufpages;		if (nbuf < 16)			nbuf = 16;	}	if (nswbuf == 0) {		nswbuf = (nbuf / 2) &~ 1;	/* force even */		if (nswbuf > 256)			nswbuf = 256;		/* sanity */	}	valloc(swbuf, struct buf, nswbuf);	valloc(buf, struct buf, nbuf);	return (v);}/* * Set up registers on exec. * * XXX this entire mess must be fixed *//* ARGSUSED */setregs(p, entry, retval)	register struct proc *p;	u_long entry;	int retval[2];{	register struct trapframe *tf = p->p_md.md_tf;	register struct fpstate *fs;	register int psr, sp;	/*	 * The syscall will ``return'' to npc or %g7 or %g2; set them all.	 * Set the rest of the registers to 0 except for %o6 (stack pointer,	 * built in exec()) and psr (retain CWP and PSR_S bits).	 */	psr = tf->tf_psr & (PSR_S | PSR_CWP);	sp = tf->tf_out[6];	if ((fs = p->p_md.md_fpstate) != NULL) {		/*		 * We hold an FPU state.  If we own *the* FPU chip state		 * we must get rid of it, and the only way to do that is		 * to save it.  In any case, get rid of our FPU state.		 */		if (p == fpproc) {			savefpstate(fs);			fpproc = NULL;		}		free((void *)fs, M_SUBPROC);		p->p_md.md_fpstate = NULL;	}	bzero((caddr_t)tf, sizeof *tf);	tf->tf_psr = psr;	tf->tf_global[2] = tf->tf_global[7] = tf->tf_npc = entry & ~3;	tf->tf_out[6] = sp;	retval[1] = 0;}#ifdef DEBUGint sigdebug = 0;int sigpid = 0;#define SDB_FOLLOW	0x01#define SDB_KSTACK	0x02#define SDB_FPSTATE	0x04#endifstruct sigframe {	int	sf_signo;		/* signal number */	int	sf_code;		/* code */#ifdef COMPAT_SUNOS	struct	sigcontext *sf_scp;	/* points to user addr of sigcontext */#else	int	sf_xxx;			/* placeholder */#endif	int	sf_addr;		/* SunOS compat, always 0 for now */	struct	sigcontext sf_sc;	/* actual sigcontext */};/* * machine dependent system variables. */cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)	int *name;	u_int namelen;	void *oldp;	size_t *oldlenp;	void *newp;	size_t newlen;	struct proc *p;{	/* all sysctl names are this level are terminal */	if (namelen != 1)		return (ENOTDIR);	/* overloaded */	switch (name[0]) {	default:		return (EOPNOTSUPP);	}	/* NOTREACHED */}/* * Send an interrupt to process. */voidsendsig(catcher, sig, mask, code)	sig_t catcher;	int sig, mask;	unsigned code;{	register struct proc *p = curproc;	register struct sigacts *psp = p->p_sigacts;	register struct sigframe *fp;	register struct trapframe *tf;	register int addr, oonstack, oldsp, newsp;	struct sigframe sf;	extern char sigcode[], esigcode[];#define	szsigcode	(esigcode - sigcode)	tf = p->p_md.md_tf;	oldsp = tf->tf_out[6];	oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;	/*	 * Compute new user stack addresses, subtract off	 * one signal frame, and align.	 */	if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&	    (psp->ps_sigonstack & sigmask(sig))) {		fp = (struct sigframe *)(psp->ps_sigstk.ss_base +					 psp->ps_sigstk.ss_size);		psp->ps_sigstk.ss_flags |= SA_ONSTACK;	} else		fp = (struct sigframe *)oldsp;	fp = (struct sigframe *)((int)(fp - 1) & ~7);#ifdef DEBUG	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)		printf("sendsig: %s[%d] sig %d newusp %x scp %x\n",		    p->p_comm, p->p_pid, sig, fp, &fp->sf_sc);#endif	/* 	 * Now set up the signal frame.  We build it in kernel space	 * and then copy it out.  We probably ought to just build it	 * directly in user space....	 */	sf.sf_signo = sig;	sf.sf_code = code;#ifdef COMPAT_SUNOS	sf.sf_scp = &fp->sf_sc;#endif	sf.sf_addr = 0;			/* XXX */	/*	 * Build the signal context to be used by sigreturn.	 */	sf.sf_sc.sc_onstack = oonstack;	sf.sf_sc.sc_mask = mask;	sf.sf_sc.sc_sp = oldsp;	sf.sf_sc.sc_pc = tf->tf_pc;	sf.sf_sc.sc_npc = tf->tf_npc;	sf.sf_sc.sc_psr = tf->tf_psr;	sf.sf_sc.sc_g1 = tf->tf_global[1];	sf.sf_sc.sc_o0 = tf->tf_out[0];	/*	 * Put the stack in a consistent state before we whack away	 * at it.  Note that write_user_windows may just dump the	 * registers into the pcb; we need them in the process's memory.	 * We also need to make sure that when we start the signal handler,	 * its %i6 (%fp), which is loaded from the newly allocated stack area,	 * joins seamlessly with the frame it was in when the signal occurred,	 * so that the debugger and _longjmp code can back up through it.	 */	newsp = (int)fp - sizeof(struct rwindow);	write_user_windows();

⌨️ 快捷键说明

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