📄 machdep.c
字号:
#ifndef lintstatic char *sccsid = "@(#)machdep.c 4.12 ULTRIX 3/6/91";#endif lint/************************************************************************ * * * Copyright (c) 1990 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* ------------------------------------------------------------------ *//* | Copyright Unpublished, MIPS Computer Systems, Inc. All Rights | *//* | Reserved. This software contains proprietary and confidential | *//* | information of MIPS and its suppliers. Use, disclosure or | *//* | reproduction is prohibited without the prior express written | *//* | consent of MIPS. | *//* ------------------------------------------------------------------ *//************************************************************************ * * Modification History: machdep.c * * 06-Mar-91 jaw * 3min ipl opt... * * 06-Nov-90 Joe Szczypek * Created char array which where bootpath will be saved. This * will be used by the network dump code during crashdumping. * Also added check for tftp to getbootctlr(). * * 13-Sep-90 Joe Szczypek * Added support for 3max/3min TURBOchannel console callbacks. Use * rex_rex() to reboot, restart, and autoboot. Use argv to get * bootdev if new console ROMs are present, and modified code getting * "lnx" and "fzax" to use slot number instead of controller number to * fetch appropriate entry from tc_slot structure. Also added * routine which will load up bootctlr for getsysinfo. * * 04-Sep-90 sekhar * changes for memory mapped devices: * modified useracc to disallow access to virtual addresses which * map I/O space. * * 31-Aug-90 Jim Paradis * On sigreturn(), only restore the fp context if it had been * previously saved by sendsig(). * * 04-Aug-90 Randall Brown * Added getspl() and whatspl() routines that call the system specific * routines through the cpu switch. Added the spl_init() routine that * loads the spl pointers with values from the cpu switch . * * 18-June-90 Fred L. Templin * Added FZA for DS_5000. Code is running in compatibility mode. * * 15-June-90 Mark A. Parenti * Moved stray() and passive_release here from vec_intr.c because * vec_intr.c now gets built as Notbinary and we don't want to ship * these sources. * * 6-June-90 Fred L. Templin * Fixed "netbootchk()" for all LANCE and SGEC platforms * * 2-May-90 chc * Added the "ne" device for supporting the network boot * * 24-Aprl-90 robin * fixed a bug in the R3000 that causes the cache isolate to fail if the * write buffers are full is worked around via wbflush. The fix is in the * clear_cache routines; we need to make sure the write buffers are NOT * full when we TRY to isolate the cache. If the write buffer is * full the cache REALY is NOT isolated and every word get a zero low * order byte.... not good. * * * 29-Mar-90 gmm * Changed some splhigh() to splextreme() since splhigh() now same * as splclock() * * 06-Mar-90 gmm * Added the routine alert_cpu() to update whichqs to ALLCPU under * lk_rq. * * 03-Mar-90 jaw * primitive change to optimize mips. * * 14-Feb-90 -- gmm * Avoid a race condition when starting more than one secondary * processor by switching affinity of the idle_proc to boot cpu. * * 05-Feb-90 -- dws * Fixed handling of SIGCONT in sigreturn() for POSIX mode. * * 08-Dec-89 -- gmm * Change the parent of the secondary's idle process to proc 0. When the * idle process comes up on the secondary, it goes and removes itself * from the current parent's child queue and puts itself on proc 0's * child queue. * * 14-Nov-89 -- gmm * Changes to secondary_startup(), new routine init_idleproc() to start * the idle process for the secondary, etc. Stop_secondary_cpu() now * dumps the tlbs in core for debugging purposes. * * 09-Nov-89 -- jaw * change references to maxcpu to smp. * * 26-Oct-89 -- afd * for network boot, pick up network device unit number if its not 0. * * 19-Oct-89 -- jmartin * Use PROT_{URKR|UW} instead of PG_{URKR|UW} as they are no longer * the same thing. * * 13-Oct 89 -- gmm * All MIPS specific smp changes. Changes to release_uarea_noreturn(), * stop_secondary_cpu(), sig_parent_swtch(), new rotutines like intrcpu(), * cpuident(), is_cpu(), secondary_startup() etc. * * 03-Oct-89 -- Joe Szczypek * Changed set_lock, clear_lock, set_bit_atomic, and clear_bit_atomic * to use interlocked operations if system is MP. * * 25 Jul 89 -- chet * Change unmount and cache flushing code in boot() * * 24-July-89 -- Alan Frechette * Moved all the crashdump code to a new file. The new file * containing the crashdump code is "/sys/sys/crashdump.c". * * 18-July-89 kong * Rewrote the routine useracc. The original routine was * located in usercopy.s and checks user access by reading * and writing the page. If the cache is incoherent at the * time, or if DMA is going on, the contents of the buffer * being probed gets corrupted. The original routine also * has the side-effect of causing paging in of pages. * The new routine simply checks the protection field of the * PTE to determine if access is allowed. This is similar * to the implementation on a VAX which uses the PROBEr/w instruction * to check access. * * 10-July-89 burns * Added emulation for Vax crc instruction (from pmk). * Added cpu switch routines for mips specific cache routines to * clean_icache, clean_dcache, page_iflush and page_dflush. * * 21-Jul-89 -- Fred Canter * Conditionally include devio.h (errlog.h includes devio.h). * * 19-Jun-89 -- condylis * Tightened up unmounting of file systems in boot(). * * 15-Jun-1989 afd * Added cpu_initialize routine to call system specific initialization * routine (for splm, intr vectors, hz, etc). * * 15-June-1989 kong * Changed code in boot to work around (not fix) a panic hang, * see the comments in "boot". * * 12-Jun-1989 -- gg * In dumpsys() added a check for the presence dumpdev. * * 09-Jun-1989 gmm * Call switch_to_idle_stack() in release_uarea_noreturn() before * releasing the process's memory resources. * * 06-June-1989 robin * Changed gendump to dump to the device specified in the config * file as the bump device. This applies to devices on non-boot * controllers. I also put in a routine to convert an integer to * an ascii string (didn't know where to put it; its used here so * here it lives?). * * 20-Apr-1989 afd * In dumpsys(), if console is a graphics device, force printf messages * directly to screen. This is needed here for the case when we * manually start the dump routine from console mode. * * 07-Apr-1989 afd * Call wbflush, flush_cache, microdelay, & clock routines thru * cpu switch. * * 06-Apr-89 -- prs * Added SMP accounting lock in boot(). * * 28-Feb-1989 Kong * Added routine "startrtclock", "ackrtclock", and "stopclocks". * These routines are machine dependent and should eventually * go through the cpu switch table. * * 24-Feb-1989 Kong * Added variable "Physmem" to keep track of the size of * physical memory actually in the system. This variable * is used by "sizer" to generate the proper config file. * * 20-Feb-1989 Kong * Added routine "badaddr". As in VAXen, "badaddr" needs to * be machine dependent because of the differences in I/O buses * used. * * 13-Jan-1989 Kong * Add the use of a system switch table. From the variable "cpu" * index into the system switch table to determine what system * specific routine to call. * * 29-Dec-1988 afd * In dumpsys(), set dumpsize BEFORE calling netdump(). * Otherwise, dumpsize is zero and savecore saves zero bytes. * *************************************************************************/#include "../machine/pte.h"#include "../machine/entrypt.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/kernel.h"#include "../h/map.h"#include "../h/vm.h"#include "../h/proc.h"#include "../h/buf.h"#include "../h/reboot.h"#include "../h/conf.h"#include "../h/gnode.h"#include "../h/file.h"#include "../h/text.h"#include "../h/clist.h"#include "../h/callout.h"#include "../h/cmap.h"#include "../h/mbuf.h"#include "../h/mount.h"#include "../h/errlog.h"#ifdef QUOTA#include "../h/quota.h"#endif QUOTA#include "../h/exec.h"#include "../h/signal.h"#include "../h/fs_types.h"#include "../h/dump.h"#include "../io/uba/ubavar.h"#include "../io/tc/tc.h"#include "../machine/cpu.h"#include "../machine/fpu.h"#include "../machine/reg.h"#include "../../machine/common/cpuconf.h"#include "../net/net/netisr.h"#include "../h/ioctl.h"#ifndef DEVIO_INCLUDE#include "../h/devio.h"#endif DEVIO_INCLUDE#include "../fs/ufs/fs.h"#include "../sas/mop.h"#include "../h/cpudata.h"#include "../h/ipc.h"#include "../h/shm.h"extern int cpu; /* System type, value defined in system.h */extern struct cpusw *cpup; /* Pointer to cpusw entry for this machine*/extern int console_magic; /* magic number of console */char netdevice[80];#ifdef PGINPROF/* NOT ported to MIPS yet! *//* * 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/* * Clear registers on exec */setregs(entry) long entry;{ register int i; register struct proc *p = u.u_procp; register int *rp; for (rp = &u.u_ar0[EF_AT]; rp < &u.u_ar0[EF_GP];) *rp++ = 0; u.u_ar0[EF_S8] = 0; u.u_ar0[EF_RA] = 0; u.u_ar0[EF_MDLO] = 0; u.u_ar0[EF_MDHI] = 0; u.u_ar0[EF_EPC] = (int)entry; for (rp = u.u_pcb.pcb_fpregs; rp < &u.u_pcb.pcb_fpregs[32];) *rp++ = 0; u.u_pcb.pcb_fpc_csr = 0; u.u_pcb.pcb_fpc_eir = 0; u.u_pcb.pcb_ownedfp = 0; u.u_pcb.pcb_sstep = 0; u.u_pcb.pcb_ssi.ssi_cnt = 0;}#define R_ZERO 0#define R_AT 1#define R_V0 2#define R_A0 4#define R_A1 5#define R_A2 6#define R_A3 7#define R_SP 29/* * Send an interrupt to process. * * Stack is set up to allow sigcode in libc * to call user signal handling routine, followed by syscall * to sigreturn routine below. After sigreturn * restores critcal registers, resets the signal mask and the * stack, it returns to user mode. */#define STACK_ALIGN(x) ((unsigned)(x) &~ ((4*sizeof(int))-1))sendsig(p, sig, signalmask)int (*p)(), sig, signalmask;{ register struct sigcontext *scp; register int *srp; register u_int *urp; register int *frp; int oonstack; XPRINTF(XPR_SIGNAL,"enter sendsig %d, 0x%x",sig,signalmask,0,0); oonstack = u.u_onstack; /* * decide which stack signal is to be taken on, and make * sure its aligned and accessable. */ if (!u.u_onstack && (u.u_sigonstack & sigmask(sig))) { scp = (struct sigcontext *)STACK_ALIGN(u.u_sigsp) - 1; u.u_onstack = 1; } else scp = (struct sigcontext *)STACK_ALIGN(USER_REG(EF_SP)) - 1; if (!u.u_onstack && (int)scp <= USRSTACK - ctob(u.u_ssize)) grow((unsigned)scp); if (!useracc((caddr_t)scp, sizeof (struct sigcontext), B_WRITE)) goto bad; /* * Save into the sigcontext the signal state and that portion * of process state that we trash in order to transfer control * to the signal trampoline code. * The remainder of the process state is preserved by * signal trampoline code that runs in user mode. */ scp->sc_onstack = oonstack; scp->sc_mask = signalmask; scp->sc_pc = USER_REG(EF_EPC); scp->sc_regs[R_V0] = USER_REG(EF_V0); scp->sc_regs[R_A0] = USER_REG(EF_A0); scp->sc_regs[R_A1] = USER_REG(EF_A1); scp->sc_regs[R_A2] = USER_REG(EF_A2); scp->sc_regs[R_A3] = USER_REG(EF_A3); scp->sc_regs[R_SP] = USER_REG(EF_SP); /* * if this process has ever used the fp coprocessor, save * its state into the sigcontext */ scp->sc_ownedfp = u.u_pcb.pcb_ownedfp; if (u.u_pcb.pcb_ownedfp) { checkfp(u.u_procp, 0); /* dump fp to pcb */ for (srp = &scp->sc_fpregs[0], frp = u.u_pcb.pcb_fpregs; frp < &u.u_pcb.pcb_fpregs[32]; srp++, frp++) *srp = *frp; scp->sc_fpc_csr = u.u_pcb.pcb_fpc_csr; scp->sc_fpc_eir = u.u_pcb.pcb_fpc_eir; u.u_pcb.pcb_fpc_csr &= ~FPCSR_EXCEPTIONS; } scp->sc_cause = USER_REG(EF_CAUSE); scp->sc_badvaddr = USER_REG(EF_BADVADDR); /* * setup registers to enter signal handler * when resuming user process */ USER_REG(EF_A0) = sig; if (sig == SIGFPE || sig == SIGSEGV || sig == SIGILL || sig == SIGBUS || sig == SIGTRAP) { USER_REG(EF_A1) = u.u_code; u.u_code = 0; } else USER_REG(EF_A1) = 0; USER_REG(EF_A2) = (unsigned)scp; USER_REG(EF_A3) = (unsigned)p; USER_REG(EF_SP) = STACK_ALIGN(scp); USER_REG(EF_EPC) = (unsigned)u.u_sigtramp; XPRINTF(XPR_SIGNAL,"exit sendsig %d, 0x%x",sig,signalmask,0,0); return;bad: uprintf("sendsig: can't grow stack, pid %d, proc %s\n", u.u_procp->p_pid, u.u_comm); /* * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ u.u_signal[SIGILL] = SIG_DFL; sig = sigmask(SIGILL); u.u_procp->p_sigignore &= ~sig; u.u_procp->p_sigcatch &= ~sig; u.u_procp->p_sigmask &= ~sig; psignal(u.u_procp, SIGILL);}/* * Routine to cleanup state after a signal * has been taken. Reset signal mask and * stack state from context left by sendsig (above). */sigreturn(){ register int *srp; register u_int *urp; register int *frp; struct a { struct sigcontext *sigcontextp; } *uap = (struct a *)u.u_ap; register struct sigcontext *scp; scp = uap->sigcontextp; if (!useracc((caddr_t)scp, sizeof (*scp), B_READ)) return; u.u_eosys = FULLRESTORE; u.u_onstack = scp->sc_onstack & 01; if (u.u_procp->p_progenv == A_POSIX) u.u_procp->p_sigmask = scp->sc_mask &~ (sigmask(SIGKILL)|sigmask(SIGSTOP)); else u.u_procp->p_sigmask = scp->sc_mask &~ (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP)); /* * copy entire user process state from sigcontext into * exception frame, a special exit from syscall insures * that the entire exception frame gets restored */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -