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

📄 kern_misc.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
字号:
/*	$Id: kern_misc.c,v 1.6 2003/08/10 11:24:51 pefo Exp $ *//* * Copyright (c) 2000 Opsycon AB  (www.opsycon.se) * Copyright (c) 2000 Rtmx, Inc   (www.rtmx.com) *  * 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 for Rtmx, Inc by *	Opsycon Open System Consulting AB, Sweden. * 4. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. * *//* *  Miscelaneous code requiered by the kernel code. */#include <sys/param.h>#include <sys/syslog.h>#include <sys/queue.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/socketvar.h>#include <sys/systm.h>#include <sys/malloc.h>#include <sys/sysctl.h>#include <sys/buf.h>#include <net/if.h>#include <net/if_types.h>#include <net/netisr.h>#include <machine/stdarg.h>#include <machine/intr.h>#include <pmon.h>int hz = 100;int securelevel = -1;int cmask = 0777;vm_size_t page_mask = (NBPG-1);struct timeval boottime;static u_char *kmem;vm_offset_t kmem_offs;static void ifpoll __P((void));intcopyin (src, dest, cnt)	const void *src;	void *dest;	size_t cnt;{	memcpy (dest, src, cnt);	return 0;}intcopyout(src, dest, size)	const void *src;	void *dest;	size_t size;{	memcpy(dest, src, size);	return(0);}intuiomove(cp, n, uio)	caddr_t cp;	int n;	struct uio *uio;{	struct iovec *iov;	u_int cnt;	while (n > 0 && uio->uio_resid) {		iov = uio->uio_iov;		cnt = iov->iov_len;		if (cnt == 0) {			uio->uio_iov++;			uio->uio_iovcnt--;			continue;		}		if (cnt > n) {			cnt = n;		}		if (uio->uio_rw == UIO_READ) {			memcpy (iov->iov_base, cp, cnt);		}		else {			memcpy (cp, iov->iov_base, cnt);		}		iov->iov_base += cnt;		iov->iov_len -= cnt;		uio->uio_resid -= cnt;		uio->uio_offset += cnt;		cp += cnt;		n -= cnt;	}	return 0;}voidpanic(msg)	const char *msg;{	printf("PMON PANIC '%s'\n", msg);	md_do_stacktrace(NULL, -1, -1, 0);	tgt_reboot();	while(1);}extern int sysloglevel;static const char *const priname[] = {	"\nEMERG",	"\nALERT",	"\nCRIT",	"\nERROR",	"\nWARNING",	"\nNOTICE",	"INFO",	"DEBUG",};voidlog (int kind, const char *fmt, ...){	va_list arg;	int pri = kind & LOG_PRIMASK;	if (pri > sysloglevel)		return;	printf ("%s: ", priname[pri]);	va_start(arg, fmt);	vprintf (fmt, arg);	va_end(arg);}voidtablefull (name)	const char *name;{	log (LOG_ERR, "%s table is full\n", name);}intmin (a, b){	return a < b ? a : b;}intimin (a, b){	return a < b ? a : b;}intmax (a, b){	return a > b ? a : b;}intimax (a, b){	return a > b ? a : b;}u_int32_tarc4random(){	return(0);}/* * General routine to allocate a hash table. */void *hashinit(elements, type, flags, hashmask)        int elements, type, flags;        u_long *hashmask;{        long hashsize;        LIST_HEAD(generic, generic) *hashtbl;        int i;        if (elements <= 0)                panic("hashinit: bad cnt");        for (hashsize = 1; hashsize <= elements; hashsize <<= 1)                continue;        hashsize >>= 1;        hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, flags);        for (i = 0; i < hashsize; i++)                LIST_INIT(&hashtbl[i]);        *hashmask = hashsize - 1;        return (hashtbl);}/* * Validate parameters and get old / set new parameters * for a structure oriented sysctl function. */intsysctl_struct(oldp, oldlenp, newp, newlen, sp, len)        void *oldp;        size_t *oldlenp;        void *newp;        size_t newlen;        void *sp;        int len;{        int error = 0;        if (oldp && *oldlenp < len)                return (ENOMEM);        if (newp && newlen > len)                return (EINVAL);        if (oldp) {                *oldlenp = len;                error = copyout(sp, oldp, len);        }        if (error == 0 && newp)                error = copyin(newp, sp, len);        return (error);}/* * Validate parameters and get old / set new parameters * for an integer-valued sysctl function. */intsysctl_int(oldp, oldlenp, newp, newlen, valp)        void *oldp;        size_t *oldlenp;        void *newp;        size_t newlen;        int *valp;{        int error = 0;        if (oldp && *oldlenp < sizeof(int))                return (ENOMEM);        if (newp && newlen != sizeof(int))                return (EINVAL);        *oldlenp = sizeof(int);        if (oldp)                error = copyout(valp, oldp, sizeof(int));        if (error == 0 && newp)                error = copyin(newp, valp, sizeof(int));        return (error);}/* * As above, but read-only. */int   sysctl_rdint(oldp, oldlenp, newp, val)   void *oldp;size_t *oldlenp;void *newp;int val;{   int error = 0;   if (oldp && *oldlenp < sizeof(int))      return (ENOMEM);   if (newp)      return (EPERM);   *oldlenp = sizeof(int);   if (oldp)      error = copyout((caddr_t)&val, oldp, sizeof(int));   return (error);}void vminit __P((void));voidvminit (){	if (!kmem) {		/* grab a chunk at the top of memory */		if (totalmemsize < VM_KMEM_SIZE * 2) {			panic ("not enough memory for network");		}		kmem = (u_char *)(((int)kmemtop - VM_KMEM_SIZE) & ~PGOFSET);#ifdef __mips__		if ((u_int32_t)&kmem < (u_int32_t)UNCACHED_MEMORY_ADDR) {			/* if linked for data in kseg0, keep kmem there too */			kmem = (u_char *) PHYS_TO_CACHED (kmem);		}		else {			kmem = (u_char *) PHYS_TO_UNCACHED (kmem);		}#endif		memtop = kmem;	}}vm_offset_tkmem_malloc (map, size, canwait)	vm_map_t map;	vm_size_t size;{	vm_offset_t p;	if(!kmem) {	/* In case we call this before vminit() */		vminit();	}	size = (size + PGOFSET) & ~PGOFSET;	if (kmem_offs + size > VM_KMEM_SIZE) {		log (LOG_DEBUG, "kmem_malloc: request for %d bytes fails\n", size);		return 0;	}	p = (vm_offset_t) &kmem[kmem_offs];	kmem_offs += size;	return p;}vm_offset_tkmem_alloc (map, size)	vm_map_t map;	vm_size_t size;{	return kmem_malloc (map, size, 0);}vm_map_tkmem_suballoc (map, base, lim, size, canwait)	vm_map_t map;	vm_offset_t *base, *lim;	vm_size_t size;{	if (size > VM_KMEM_SIZE)		panic ("kmem_suballoc");	*base = (vm_offset_t) kmem;	*lim = (vm_offset_t)  kmem + VM_KMEM_SIZE;	return map;}voidkmem_free (map, addr, size)	vm_map_t map;	vm_offset_t addr;	vm_size_t size;{	panic ("kmem_free");}/*XXX*//* *  Shutdown hooks are currently nops. Later we should add something *  that shutdown activites like ethernet etc (eg does the hook calls) *  so interfearence with loaded and run programs will not occur. */void *shutdownhook_establish(callee, sc)	void (*callee) __P((void *));	void *sc;{	return((void *)1);	/* Return non-zero for now */}static voidifpoll(){	struct ifnet *ifp;static int here = 0;	if(here) {		/* Don't recurse */		splhigh();		printf("ifpoll recursed!\n");		md_do_stacktrace(0, -1, 0, 0);		while(1);	}	here = 1;	for(ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) {		if (ifp->if_ioctl) {			(*ifp->if_ioctl)(ifp, SIOCPOLL, 0);		}	}	here = 0;}/* *  XXX The entire SPL code is wrong in the sense that the 'levels' *  XXX are not levels but events that should be masked. Note that *  XXX some 'levels' masks more than one event anyhow. This should *  XXX really be rewritten in the future and especially if we start *  XXX using real interrupts. */volatile int spl;	/* Current SPL mask */intsplhigh(){	int old = spl;	spl = 7;	return(old);}intsplclock(){	int old = spl;	spl = 7;	return(old);}intspltty(){	int old = spl;	if(old < 5) {		spl = 5;	}	return(old);}intsplbio(){	int old = spl;	if(old < 4) {		spl = 4;	}	return(old);}intsplimp(){	int old = spl;	if(old < 7) {		spl = 7;	}	return(old);}intsplnet(){	int old = spl;	if(old < 3) {		spl = 3;	}	return(old);}intsplsoftclock(){	int old = spl;	if(old < 1) {		spl = 1;	}	return(old);}intsplsoftnet(){	int old = spl;	if(old < 1) {		spl = 1;	}	return(old);}intspl0(){	int s = spl;	splx(0);	return(s);} voidsplx(newspl){extern void softnet __P((void));	/* If new means lowering then check pending jobs */	if (newspl < spl) {		if (newspl < 7) {			spl = 7;			tgt_clkpoll ();		}		if (newspl < 3) {	/* NET + IMP */			spl = 3;			ifpoll ();		}		if (newspl < 1 && netisr != 0) {			spl = 1;			softnet ();		}	}	spl = newspl;	if (spl == 0) {		tgt_poll();	}}voidsetsoftnet (){	/* nothing to do, checked by spl0() */}voidsetsoftclock (){	/* simulated soft clock */	schednetisr(NETISR_SCLK);}voidminphys(bp)	struct buf *bp;{	if (bp->b_bcount > MAXPHYS)		bp->b_bcount = MAXPHYS;}

⌨️ 快捷键说明

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