V5/usr/sys/ken/trap.c
#
/*
* Copyright 1973 Bell Telephone Laboratories Inc
*/
#include "../param.h"
#include "../systm.h"
#include "../user.h"
#include "../proc.h"
#include "../reg.h"
#include "../seg.h"
#define EBIT 1
#define UMODE 0170000
#define SETD 0170011
struct sysent {
int count;
int (*call)();
} sysent[64];
char regloc[8]
{
R0, R1, R2, R3, R4, R5, R6, R7
};
trap(dev, sp, r1, nps, r0, pc, ps)
char *sp;
{
register i, a;
register struct sysent *callp;
savfp();
u.u_ar0 = &r0;
if(dev == 8) {
psignal(u.u_procp, SIGFPT);
if((ps&UMODE) == UMODE)
goto err;
return;
}
if(dev==1 && fuword(pc-2)==SETD && u.u_signal[SIGINS]==0)
return;
if((ps&UMODE) != UMODE)
goto bad;
u.u_error = 0;
if(dev==9 && sp < -u.u_ssize*64) {
if(backup(&r0) == 0)
if(!estabur(u.u_tsize, u.u_dsize, u.u_ssize+SINCR)) {
expand(u.u_procp->p_size+SINCR);
a = u.u_procp->p_addr + u.u_procp->p_size;
for(i=u.u_ssize; i; i--) {
a--;
copyseg(a-SINCR, a);
}
for(i=SINCR; i; i--)
clearseg(--a);
u.u_ssize =+ SINCR;
goto err;
}
}
switch(dev) {
case 0:
i = SIGBUS;
goto def;
case 1:
i = SIGINS;
goto def;
case 2:
i = SIGTRC;
goto def;
case 3:
i = SIGIOT;
goto def;
case 5:
i = SIGEMT;
goto def;
case 9:
i = SIGSEG;
goto def;
def:
psignal(u.u_procp, i);
default:
u.u_error = dev+100;
case 6:;
}
if(u.u_error)
goto err;
ps =& ~EBIT;
callp = &sysent[fuword(pc-2)&077];
if (callp == sysent) { /* indirect */
a = fuword(pc);
pc =+ 2;
callp = &sysent[fuword(a)&077];
a =+ 2;
} else {
a = pc;
pc =+ callp->count*2;
}
for(i=0; i < callp->count; i++) {
u.u_arg[i] = fuword(a);
a =+ 2;
}
u.u_dirp = u.u_arg[0];
trap1(callp->call);
if(u.u_error >= 100)
psignal(u.u_procp, SIGSYS);
err:
if(issig())
psig();
if(u.u_error != 0) {
ps =| EBIT;
r0 = u.u_error;
}
u.u_procp->p_pri = PUSER + u.u_nice;
if(u.u_dsleep++ > 15) {
u.u_dsleep = 0;
u.u_procp->p_pri++;
swtch();
}
return;
bad:
printf("ka6 = %o\n", *ka6);
printf("aps = %o\n", &ps);
panic("trap");
}
trap1(f)
int (*f)();
{
savu(u.u_qsav);
(*f)();
}
nosys()
{
u.u_error = 100;
}
nullsys()
{
}