📄 kern_misc.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 + -