32V/usr/src/slowsys/sys/trap.c
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/proc.h"
#include "../h/reg.h"
#include "../h/seg.h"
#include "../h/trap.h"
#include "../h/psl.h"
#define USER 040 /* user-mode flag added to type */
struct sysent sysent[64];
/*
* Called from the trap handler when a processor trap occurs.
*/
trap(params, r0, r1, r2, r3, r4, r5 ,r6, r7, r8, r9, r10,
r11, r12, r13, sp, type, code, pc, psl)
caddr_t params;
{
register i, a;
register struct sysent *callp;
register caddr_t errorp;
register time_t syst;
register int *locr0;
locr0 = &r0;
syst = u.u_stime;
u.u_ar0 = locr0;
if (USERMODE(locr0[PS]))
type |= USER;
u.u_ar0 = locr0;
switch (type) {
/*
* Trap not expected.
* Usually a kernel mode bus error.
*/
default:
printf("user = %x\n", ctob(u.u_procp->p_addr + 1));
printf("ps = %x\n", locr0[PS]);
printf("pc = %x\n", locr0[PC]);
printf("trap type %x\n", type);
printf("code = %x\n", code);
panic("trap");
case PROTFLT + USER: /* protection fault */
i = SIGBUS;
break;
case PRIVINFLT + USER: /* privileged instruction fault */
case RESADFLT + USER: /* reserved addressing fault */
case RESOPFLT + USER: /* resereved operand fault */
i = SIGINS;
break;
case RESCHED + USER: /* Allow process switch */
goto out;
case SYSCALL + USER: /* sys call */
params += NBPW; /* skip word with param count */
u.u_error = 0;
callp = &sysent[code&077];
if (callp == sysent) { /* indirect */
a = fuword(params);
params += NBPW;
callp = &sysent[a&077];
}
for(i=0; i<callp->sy_narg; i++) {
u.u_arg[i] = fuword(params);
params += NBPW;
}
u.u_ap = u.u_arg;
locr0[PS] &= ~PSL_C;
u.u_dirp = (caddr_t)u.u_arg[0];
u.u_r.r_val1 = 0;
u.u_r.r_val2 = locr0[R1];
if(save(u.u_qsav)){
if(u.u_error==0)
u.u_error = EINTR;
} else {
(*(callp->sy_call))();
}
if(u.u_error) {
locr0[R0] = u.u_error;
locr0[PS] |= PSL_C; /* carry bit */
} else {
locr0[R0] = u.u_r.r_val1;
locr0[R1] = u.u_r.r_val2;
}
goto out;
case ARITHTRAP + USER:
i = SIGFPT;
break;
/*
* If the user SP is above the stack segment,
* grow the stack automatically.
*/
case SEGFLT + USER: /* segmentation exception */
if(grow(locr0[SP]) || grow(code))
goto out;
i = SIGSEG;
break;
case BPTFLT + USER: /* bpt instruction fault */
case TRCTRAP + USER: /* trace trap */
locr0[PS] &= ~PSL_T; /* turn off trace bit */
i = SIGTRC;
break;
case XFCFLT + USER: /* xfc instruction fault */
i = SIGEMT;
break;
}
psignal(u.u_procp, i);
out:
if(issig())
psig();
curpri = setpri(u.u_procp);
if (runrun)
qswtch();
if(u.u_prof.pr_scale)
addupc((caddr_t)locr0[PC], &u.u_prof, (int)(u.u_stime-syst));
return;
}
/*
* nonexistent system call-- set fatal error code.
*/
nosys()
{
u.u_error = 100;
}
/*
* Ignored system call
*/
nullsys()
{
}
random(dev, stat, ps, pc, ccb)
{
printf("Random interrupt, device %x\n", dev);
}