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

📄 machdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department, The Mach Operating System project at * Carnegie-Mellon University, Ralph Campbell, Sony Corp. and Kazumasa * Utashiro of Software Research Associates, Inc. * * 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.3 (Berkeley) 1/12/94 *//* from: Utah $Hdr: machdep.c 1.63 91/04/24$ */#include <sys/param.h>#include <sys/systm.h>#include <sys/signalvar.h>#include <sys/kernel.h>#include <sys/map.h>#include <sys/proc.h>#include <sys/buf.h>#include <sys/reboot.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/msgbuf.h>#include <sys/user.h>#include <sys/exec.h>#include <sys/sysctl.h>#ifdef SYSVSHM#include <sys/shm.h>#endif#include <vm/vm_kern.h>#include <machine/cpu.h>#include <machine/reg.h>#include <machine/psl.h>#include <machine/pte.h>#include <machine/adrsmap.h>vm_map_t buffer_map;/* the following is used externally (sysctl_hw) */char	machine[] = "SONY";	/* cpu "architecture" */char	cpu_model[30];/* * 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	msgbufmapped = 0;	/* set when safe to use msgbuf */int	maxmem;			/* max memory per process */int	physmem;		/* max supported memory, changes to actual *//* * safepri is a safe priority for sleep to set for a spin-wait * during autoconfiguration or after a panic. */int	safepri = PSL_LOWIPL;struct	user *proc0paddr;struct	proc nullproc;		/* for use by switch_exit() *//* * Do all the stuff that locore normally does before calling main(). * Process arguments passed to us by the prom monitor. * Return the first page address following the system. */mach_init(x_boothowto, x_unkown, x_bootdev, x_maxmem)	int x_boothowto;	int x_unkown;	int x_bootdev;	int x_maxmem;{	register char *cp;	register int i;	register unsigned firstaddr;	register caddr_t v;	caddr_t start;	extern u_long bootdev;	extern char edata[], end[];	extern char MachUTLBMiss[], MachUTLBMissEnd[];	extern char MachException[], MachExceptionEnd[];	/*	 * Save parameters into kernel work area.	 */	*(int *)(MACH_CACHED_TO_UNCACHED(MACH_MAXMEMSIZE_ADDR)) = x_maxmem;	*(int *)(MACH_CACHED_TO_UNCACHED(MACH_BOOTDEV_ADDR)) = x_bootdev;	*(int *)(MACH_CACHED_TO_UNCACHED(MACH_BOOTSW_ADDR)) = x_boothowto;	/* clear the BSS segment */	v = (caddr_t)pmax_round_page(end);	bzero(edata, v - edata);	boothowto = x_boothowto;	bootdev = x_bootdev;	maxmem = physmem = pmax_btop(x_maxmem);	/*	 * Look at arguments passed to us and compute boothowto.	 */#ifdef GENERIC	boothowto |= RB_SINGLE | RB_ASKNAME;#endif#ifdef KADB	boothowto |= RB_KDB;#endif#ifdef MFS	/*	 * Check to see if a mini-root was loaded into memory. It resides	 * at the start of the next page just after the end of BSS.	 */	if (boothowto & RB_MINIROOT) {		boothowto |= RB_DFLTROOT;		v += mfs_initminiroot(v);	}#endif	/*	 * Init mapping for u page(s) for proc[0], pm_tlbpid 1.	 */	start = v;	curproc->p_addr = proc0paddr = (struct user *)v;	curproc->p_md.md_regs = proc0paddr->u_pcb.pcb_regs;	firstaddr = MACH_CACHED_TO_PHYS(v);	for (i = 0; i < UPAGES; i++) {		MachTLBWriteIndexed(i,			(UADDR + (i << PGSHIFT)) | (1 << VMMACH_TLB_PID_SHIFT),			curproc->p_md.md_upte[i] = firstaddr | PG_V | PG_M);		firstaddr += NBPG;	}	v += UPAGES * NBPG;	MachSetPID(1);	/*	 * init nullproc for switch_exit().	 * init mapping for u page(s), pm_tlbpid 0	 * This could be used for an idle process.	 */	nullproc.p_addr = (struct user *)v;	nullproc.p_md.md_regs = nullproc.p_addr->u_pcb.pcb_regs;	bcopy("nullproc", nullproc.p_comm, sizeof("nullproc"));	for (i = 0; i < UPAGES; i++) {		nullproc.p_md.md_upte[i] = firstaddr | PG_V | PG_M;		firstaddr += NBPG;	}	v += UPAGES * NBPG;	/* clear pages for u areas */	bzero(start, v - start);	/*	 * Copy down exception vector code.	 */	if (MachUTLBMissEnd - MachUTLBMiss > 0x80)		panic("startup: UTLB code too large");	bcopy(MachUTLBMiss, (char *)MACH_UTLB_MISS_EXC_VEC,		MachUTLBMissEnd - MachUTLBMiss);	bcopy(MachException, (char *)MACH_GEN_EXC_VEC,		MachExceptionEnd - MachException);	/*	 * Clear out the I and D caches.	 */	MachConfigCache();	MachFlushCache();	/*	 * Initialize error message buffer (at end of core).	 */	maxmem -= btoc(sizeof (struct msgbuf));	msgbufp = (struct msgbuf *)(MACH_PHYS_TO_CACHED(maxmem << PGSHIFT));	msgbufmapped = 1;	/*	 * Allocate space for system data structures.	 * The first available kernel virtual address is in "v".	 * As pages of kernel virtual memory are allocated, "v" is incremented.	 *	 * These data structures are allocated here instead of cpu_startup()	 * because physical memory is directly addressable. We don't have	 * to map these into virtual address space.	 */	start = v;#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)))	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.	 * We allocate more buffer space than the BSD standard of	 * using 10% of memory for the first 2 Meg, 5% of remaining.	 * We just allocate a flat 10%.  Insure a minimum of 16 buffers.	 * We allocate 1/2 as many swap buffer headers as file i/o buffers.	 */	if (bufpages == 0)		bufpages = physmem / 10 / 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);	/*	 * Clear allocated memory.	 */	bzero(start, v - start);	/*	 * Initialize the virtual memory system.	 */	pmap_bootstrap((vm_offset_t)v);}/* * Console initialization: called early on from main, * before vm init or startup.  Do enough configuration * to choose and initialize a console. * XXX need something better here. */#define	SCC_CONSOLE	0#define	SW_CONSOLE	0x07#define	SW_NWB512	0x04#define	SW_NWB225	0x01#define	SW_FBPOP	0x02#define	SW_FBPOP1	0x06#define	SW_FBPOP2	0x03#define	SW_AUTOSEL	0x07consinit(){	extern dev_t consdev;	extern struct tty *constty, *cn_tty, *rs_tty;	int dipsw = (int)*(volatile u_char *)DIP_SWITCH;#include "bm.h"#if NBM > 0#if defined(news3200) || defined(news3400)	/* KU:XXX */	fbbm_probe(dipsw|2);#else	fbbm_probe(dipsw);#endif	vt100_open();	setup_fnt();	setup_fnt24();#else	dipsw &= SW_CONSOLE;#endif	switch (dipsw & SW_CONSOLE) {	    case 0:		scc_open(SCC_CONSOLE);		consdev = makedev(1, 0);		constty = rs_tty;		break;	    default:#if NBM > 0		consdev = makedev(22, 0);		constty = cn_tty;#endif		break;	}	return(0);}/* * cpu_startup: allocate memory for variable-sized tables, * initialize cpu, and do autoconfiguration. */cpu_startup(){	register unsigned i;	register caddr_t v;	int base, residual;	vm_offset_t minaddr, maxaddr;	vm_size_t size;#ifdef DEBUG	extern int pmapdebug;	int opmapdebug = pmapdebug;	pmapdebug = 0;#endif	/*	 * Good {morning,afternoon,evening,night}.	 */	printf(version);	printf("real mem = %d\n", ctob(physmem));	/*	 * Allocate virtual address space for file I/O buffers.	 * Note they are different than the array of headers, 'buf',	 * and 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 submap for physio	 */	phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,				 VM_PHYS_SIZE, TRUE);	/*	 * 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 CPU-specific registers, cache, etc.	 */	initcpu();	/*	 * Set up buffers, so they can be used to read disk labels.	 */	bufinit();	/*	 * Configure the system.	 */	configure();}/* * Set registers on exec. * Clear all registers except sp, pc. */setregs(p, entry, retval)	register struct proc *p;	u_long entry;	int retval[2];{	int sp = p->p_md.md_regs[SP];	extern struct proc *machFPCurProcPtr;	bzero((caddr_t)p->p_md.md_regs, (FSR + 1) * sizeof(int));	p->p_md.md_regs[SP] = sp;	p->p_md.md_regs[PC] = entry & ~3;	p->p_md.md_regs[PS] = PSL_USERSET;	p->p_md.md_flags & ~MDP_FPUSED;	if (machFPCurProcPtr == p)		machFPCurProcPtr = (struct proc *)0;}/* * WARNING: code in locore.s assumes the layout shown for sf_signum * thru sf_handler so... don't screw with them! */struct sigframe {	int	sf_signum;		/* signo for handler */	int	sf_code;		/* additional info for handler */	struct	sigcontext *sf_scp;	/* context ptr for handler */	sig_t	sf_handler;		/* handler addr for u_sigc */	struct	sigcontext sf_sc;	/* actual context */};#ifdef DEBUGint sigdebug = 0;int sigpid = 0;#define SDB_FOLLOW	0x01#define SDB_KSTACK	0x02#define SDB_FPSTATE	0x04#endif/* * 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 sigframe *fp;	register int *regs;	register struct sigacts *psp = p->p_sigacts;	int oonstack, fsize;	struct sigcontext ksc;	extern char sigcode[], esigcode[];	regs = p->p_md.md_regs;	oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;	/*	 * Allocate and validate space for the signal handler	 * context. Note that if the stack is in data space, the

⌨️ 快捷键说明

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