/* * Copyright 1993,1994,1995 Emin Gun Sirer * MIPSI - Mips Instruction Set Simulator. */ #include #define __mips 1 #include "config.h" #include "main.h" #include "mem.h" #include "MIPS/signal.h" #include extern struct sigvec sighandler[]; extern int prog_sigmask; extern jmp_buf inrun; mem_addr sigtramp = 0; #define asm(x) /* Turn on integer overflow, underflow and floating point exceptions */ extern void setfsr(int val) { #ifdef __mips__ asm("cfc1 $5,$31"); asm("or $5,$5,$4"); asm("ctc1 $5,$31"); #endif } extern void setupsignalstack(int sig, int code, struct sigcontext *scp) { #if 0 int i; mem_addr locsc; struct sigcontext *sc; locsc = (int) ((struct sigcontext *)STACK_ALIGN(R[29]) - 1); sc = (struct sigcontext *) mem_address(locsc); *sc = *scp; /* * we have to check if we are to put this on a signal stack or not * scp->sc_onstack = ??; */ sc->sc_mask = prog_sigmask; sc->sc_pc = pc; /* we save only that which is not saved by trampoline code */ sc->sc_regs[REG_V0] = R[REG_V0]; sc->sc_regs[REG_A0] = R[REG_A0]; sc->sc_regs[REG_A1] = R[REG_A1]; sc->sc_regs[REG_A2] = R[REG_A2]; sc->sc_regs[REG_A3] = R[REG_A3]; sc->sc_regs[REG_SP] = R[REG_SP]; sc->sc_mdlo = LO; /* mul/div low */ sc->sc_mdhi = HI; sc->sc_ownedfp = ownedfp; if(ownedfp) { for(i=0; i < 32; ++i) /* FPU registers */ sc->sc_fpregs[i] = FGR[i]; /* * these are in the kernel code - I have no idea what to do with them * sc->sc_fpc_eir = u.u_pcb.pcb_fpc_eir; */ sc->sc_fpc_csr = CCR[1][31]; } sc->sc_cause = Cause; /* cp0 cause register */ sc->sc_badvaddr = BadVAddr; /* cp0 bad virtual address */ R[29] = STACK_ALIGN(locsc); R[REG_A0] = sig; R[REG_A1] = code; R[REG_A2] = locsc; R[REG_A3] = (int) sighandler[R[REG_A0]].sv_handler; #endif } extern void dosigreturn(void) { #if 0 int i; struct sigcontext *sc; sc = (struct sigcontext *) mem_address(R[REG_A0]); prog_sigmask = sc->sc_mask; npc = sc->sc_pc; /* * This has to check for the branch delay bit (and someone has to set it) */ nnpc = npc + 4; for(i=0; i < 32; ++i) R[i] = sc->sc_regs[i]; LO = sc->sc_mdlo; HI = sc->sc_mdhi; if(sc->sc_ownedfp) { for(i=0; i < 32; ++i) /* FPU registers */ FGR[i] = sc->sc_fpregs[i]; CCR[1][31] = sc->sc_fpc_csr; } Cause = 0; BadVAddr = 0; #endif } extern void sighandle(int sig, int code, struct sigcontext *scp) { #if 0 /* * check to see who incurred the signal * * this is a great idea, but doesn't work with asynchronous signals, * such as clock interrupts if((scp->sc_pc < (int) run) || (scp->sc_pc > (int) endofrun)) error(Fatal, "internal mipsi error\n"); */ /* * See if the process is blocking the signal * or if the CCR is set up to receive overflow/underflow/divbyzero * BUG BUG BUG I pulled these numbers out from nowhere - where are they * defined ? where is ccr[1] described ? Why is signal.h so bad ?? */ if((prog_sigmask & (1 << R[REG_A0])) == 1) return; #if 0 || ((sig == SIGFPE) && (((code == 0x20) && (!(CCR[1][31] & 0x200))) || ((code == 0x30) && (!(CCR[1][31] & 0x400))) || ((code == 0x40) && (!(CCR[1][31] & 0x800)))))) #endif if((int) sighandler[sig].sv_handler == 0) { /* * Since the process is not trapping or blocking the signal, * print a diagnostic and go interactive. */ switch(sig) { case SIGINT: error(Benign, "mipsi: Interrupt\n"); break; case SIGSEGV:error(Benign, "mipsi: Segmentation Fault\n"); break; case SIGBUS: error(Benign, "mipsi: Bus Error\n"); break; case SIGSYS: error(Benign, "mipsi: Bad arg to system call\n"); break; case SIGFPE: error(Benign, "mipsi: Floating Point exception\n"); break; default: error(Benign, "mipsi: signal not caught\n"); break; } print(pc, 1); dumpregs(GENREGS | FPREGS); error(TopLevel, "Exception occurred at PC=0x%08x - no handler\n", pc); } setupsignalstack(sig, code, scp); if(sigtramp == 0) error(Fatal, "No sigvec call preceded the trapped signal ??\n"); sigsetmask(sighandler[sig].sv_mask); longjmp(inrun, 1); #endif }