## diffname ss/trap.c 1990/1223
## diff -e /dev/null /n/bootesdump/1990/1223/sys/src/9/sparc/trap.c
0a
#include "u.h"
#include "lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "ureg.h"
#include "io.h"
#include "errno.h"
void notify(Ureg*);
void noted(Ureg**);
void rfnote(Ureg**);
char *regname[]={
"R0",
"R1",
"R2",
"R3",
"R4",
"R5",
"R6",
"R7",
"A0",
"A1",
"A2",
"A3",
"A4",
"A5",
"A6",
"A7",
};
long ticks;
char *trapname[]={
"reset isp",
"reset ipc",
"bus error",
"address error",
"illegal instruction",
"zero divide",
"chk, chk2 instruction",
"cptrapcc, trapcc, trapv instruction",
"privilege violation",
"trace",
"line 1010 emulator",
"line 1111 emulator",
"reserved",
"coprocessor protocol violation",
"format error",
"uninitialized interrupt",
"unassigned 0x40",
"unassigned 0x44",
"unassigned 0x48",
"unassigned 0x4C",
"unassigned 0x50",
"unassigned 0x54",
"unassigned 0x58",
"unassigned 0x5C",
"spurious interrupt",
"level 1 autovector (tac)",
"level 2 autovector (port)",
"level 3 autovector (incon)",
"level 4 autovector (mouse)",
"level 5 autovector (uart)",
"level 6 autovector (sync)",
"level 7 autovector",
};
char*
excname(unsigned vo)
{
static char buf[32]; /* BUG: not reentrant! */
vo &= 0x0FFF;
vo >>= 2;
if(vo < sizeof trapname/sizeof(char*))
return trapname[vo];
sprint(buf, "offset 0x%ux", vo<<2);
return buf;
}
void
trap(Ureg *ur)
{
int user;
char buf[64];
user = !(ur->sr&SUPER);
if(u)
u->p->pc = ur->pc; /* BUG */
if(user){
sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(ur->vo));
postnote(u->p, 1, buf, NDebug);
}else{
print("kernel trap vo=0x%ux pc=0x%lux\n", ur->vo, ur->pc);
dumpregs(ur);
exit();
}
if(user && u->nnote)
notify(ur);
}
void
dumpstack(void)
{
ulong l, v;
extern ulong etext;
if(u)
for(l=(ulong)&l; l<USERADDR+BY2PG; l+=4){
v = *(ulong*)l;
if(KTZERO < v && v < (ulong)&etext)
print("%lux=%lux\n", l, v);
}
}
void
dumpregs(Ureg *ur)
{
int i;
ulong *l;
if(u)
print("registers for %s %d\n", u->p->text, u->p->pid);
else
print("registers for kernel\n");
print("SR=%ux PC=%lux VO=%lux, USP=%lux\n", ur->sr, ur->pc, ur->vo, ur->usp);
l = &ur->r0;
for(i=0; i<sizeof regname/sizeof(char*); i+=2, l+=2)
print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
dumpstack();
}
/*
* Call user, if necessary, with note
*/
void
notify(Ureg *ur)
{
ulong sp;
lock(&u->p->debug);
if(u->nnote==0){
unlock(&u->p->debug);
return;
}
if(u->note[0].flag!=NUser && (u->notified || u->notify==0)){
if(u->note[0].flag == NDebug)
pprint("suicide: %s\n", u->note[0].msg);
Die:
unlock(&u->p->debug);
pexit(u->note[0].msg, u->note[0].flag!=NDebug);
}
if(!u->notified){
if(!u->notify)
goto Die;
sp = ur->usp;
sp -= sizeof(Ureg);
u->ureg = (void*)sp;
memcpy((Ureg*)sp, ur, sizeof(Ureg));
sp -= ERRLEN;
memcpy((char*)sp, u->note[0].msg, ERRLEN);
sp -= 3*BY2WD;
*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */
*(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 is ureg* */
*(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */
ur->usp = sp;
ur->pc = (ulong)u->notify;
u->notified = 1;
u->nnote--;
memcpy(&u->note[0], &u->note[1], u->nnote*sizeof(Note));
}
unlock(&u->p->debug);
}
/*
* Return user to state before notify()
*/
void
noted(Ureg **urp)
{
lock(&u->p->debug);
if(!u->notified){
unlock(&u->p->debug);
return;
}
u->notified = 0;
memcpy(*urp, u->ureg, sizeof(Ureg));
unlock(&u->p->debug);
splhi();
rfnote(urp);
}
#undef CHDIR /* BUG */
#include "/sys/src/libc/680209sys/sys.h"
typedef long Syscall(ulong*);
Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait;
Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate;
Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted;
Syscall *systab[]={
sysr1,
syserrstr,
sysbind,
syschdir,
sysclose,
sysdup,
sysdeath,
sysexec,
sysexits,
sysfork,
sysforkpgrp,
sysfstat,
sysdeath,
sysmount,
sysopen,
sysread,
sysseek,
syssleep,
sysstat,
syswait,
syswrite,
syspipe,
syscreate,
sysdeath,
sysbrk_,
sysremove,
syswstat,
sysfwstat,
sysnotify,
sysnoted,
sysdeath, /* sysfilsys */
};
long
syscall(Ureg *aur)
{
long ret;
ulong sp;
ulong r0;
Ureg *ur;
char *msg;
u->p->insyscall = 1;
ur = aur;
u->p->pc = ur->pc;
if(ur->sr & SUPER)
panic("recursive system call");
/*
* since the system call interface does not
* guarantee anything about registers, but the fpcr is more than
* just a register... BUG
*/
splhi();
fpsave(&u->fpsave);
if(u->p->fpstate==FPactive || u->fpsave.type){
fprestore(&initfp);
u->p->fpstate = FPinit;
m->fpstate = FPinit;
}
spllo();
r0 = ur->r0;
sp = ur->usp;
u->nerrlab = 0;
ret = -1;
if(!waserror()){
if(r0 >= sizeof systab/BY2WD){
pprint("bad sys call number %d pc %lux\n", r0, ((Ureg*)UREGADDR)->pc);
msg = "sys: bad sys call";
Bad:
postnote(u->p, 1, msg, NDebug);
error(Ebadarg);
}
if(sp & (BY2WD-1)){
pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
msg = "sys: odd stack";
goto Bad;
}
if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-5*BY2WD))
validaddr(sp, 5*BY2WD, 0);
ret = (*systab[r0])((ulong*)(sp+BY2WD));
}
u->nerrlab = 0;
u->p->insyscall = 0;
if(r0 == NOTED) /* ugly hack */
noted(&aur); /* doesn't return */
if(u->nnote){
ur->r0 = ret;
notify(ur);
}
return ret;
}
#include "errstr.h"
void
error(int code)
{
strncpy(u->error, errstrtab[code], NAMELEN);
nexterror();
}
void
errors(char *err)
{
strncpy(u->error, err, NAMELEN);
nexterror();
}
void
nexterror(void)
{
gotolabel(&u->errlab[--u->nerrlab]);
}
.
## diffname ss/trap.c 1990/1226
## diff -e /n/bootesdump/1990/1223/sys/src/9/sparc/trap.c /n/bootesdump/1990/1226/sys/src/9/sparc/trap.c
296a
}
void
execpc(ulong entry)
{
((Ureg*)UREGADDR)->pc = entry - 4; /* syscall advances it */
((Ureg*)UREGADDR)->npc = entry;
.
293c
ur->r7 = ret;
.
290c
if(r7 == NOTED) /* ugly hack */
.
287a
ur->pc += 4;
ur->npc = ur->pc+4;
.
286c
ret = (*systab[r7])((ulong*)(sp+2*BY2WD));
.
272,273c
if(r7 >= sizeof systab/BY2WD){
pprint("bad sys call number %d pc %lux\n", r7, ((Ureg*)UREGADDR)->pc);
.
266c
r7 = ur->r7;
.
264a
#endif
.
258d
252a
#ifdef asdf
.
251c
if(ur->psr & PSRPSUPER)
.
244c
ulong r7;
.
197c
#include "/sys/src/libc/sparc9sys/sys.h"
.
131,132c
for(i=0; i<32; i+=2, l+=2)
print("R%d\t%.8lux\tR%d\t%.8lux\n", i, l[0], i+1, l[1]);
.
129c
print("PSR=%ux PC=%lux TBR=%lux\n", ur->psr, ur->pc, ur->tbr);
.
105a
trapinit(void)
{
int i;
long t, a;
a = ((ulong)traplink-TRAPS)>>2;
a += 0x40000000; /* CALL traplink(SB) */
t = TRAPS;
for(i=0; i<256; i++){
*(ulong*)t = a; /* CALL traplink(SB) */
*(ulong*)(t+4) = 0xa7480000; /* MOVW PSR, R19 */
a -= 16/4;
t += 16;
}
/*
* Vector 128 goes directly to syslink
*/
t = TRAPS+128*16;
a = ((ulong)syslink-t)>>2;
a += 0x40000000;
*(ulong*)t = a; /* CALL syscall(SB) */
*(ulong*)(t+4) = 0xa7480000; /* MOVW PSR, R19 */
puttbr(TRAPS);
}
void
.
98a
for(;;);
.
97c
print("kernel trap: %s pc=0x%lux\n", excname(ur->tbr), ur->pc);
.
94c
print("user trap: %s pc=0x%lux\n", excname(ur->tbr), ur->pc);
dumpregs(ur);
for(;;);
sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(ur->tbr));
.
89,91c
user = !(ur->psr&PSRPSUPER);
/* if(u)
.
75,79c
tbr &= 0xFFF;
tbr >>= 4;
if(tbr < sizeof trapname/sizeof(char*))
return trapname[tbr];
if(tbr == 36)
return "cp disabled";
if(tbr == 40)
return "cp exception";
if(tbr >= 128)
sprint(buf, "trap instruction %d", tbr-128);
else if(17<=tbr && tbr<=31)
sprint(buf, "interrupt level %d", tbr-16);
else
sprint(buf, "unknown trap %d", tbr);
.
71c
excname(ulong tbr)
.
41,67c
"privileged instruction",
"fp disabled",
"window overflow",
"window underflow",
"unaligned address",
"fp exception",
"data access exception",
"tag overflow",
.
36,39c
"reset",
"instruction access exception",
.
14,31c
extern void traplink(void);
extern void syslink(void);
.
## diffname ss/trap.c 1990/1227
## diff -e /n/bootesdump/1990/1226/sys/src/9/sparc/trap.c /n/bootesdump/1990/1227/sys/src/9/sparc/trap.c
72c
print("kernel trap: %s pc=0x%lux\n", excname(tbr), ur->pc);
.
69c
sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(tbr));
.
66c
print("user trap: %s pc=0x%lux\n", excname(tbr), ur->pc);
.
60a
tbr = (ur->tbr&0xFFF)>>4;
if(tbr == 30){ /* interrupt 14: counter 1 */
clock(ur);
return;
}
.
59a
ulong tbr;
.
38,39d
## diffname ss/trap.c 1990/1231
## diff -e /n/bootesdump/1990/1227/sys/src/9/sparc/trap.c /n/bootesdump/1990/1231/sys/src/9/sparc/trap.c
62a
return;
}
if(tbr == 16+12){ /* interrupt 12: keyboard and mouse */
duartintr();
return;
}
if(tbr == 16+5){ /* interrupt 5: lance */
lanceintr();
.
61c
if(tbr == 16+14){ /* interrupt 14: counter 1 */
.
## diffname ss/trap.c 1991/0109
## diff -e /n/bootesdump/1990/1231/sys/src/9/sparc/trap.c /n/bootesdump/1991/0109/sys/src/9/sparc/trap.c
167a
print("suicide: %s\n", u->note[0].msg);
.
160c
if(u->nnote == 0){
.
91a
print("notifyed %d\n", u->p->pid);
}
.
90c
if(user && u->nnote){
print("notify %d\n", u->p->pid);
.
83a
print("return from postnote\n");
.
82a
print("call postnote\n");
.
81d
## diffname ss/trap.c 1991/0110
## diff -e /n/bootesdump/1991/0109/sys/src/9/sparc/trap.c /n/bootesdump/1991/0110/sys/src/9/sparc/trap.c
172d
84d
82d
80d
60a
if(tbr == 16+15){ /* interrupt 14: counter 1 */
faultasync(ur);
return;
}
.
## diffname ss/trap.c 1991/0112
## diff -e /n/bootesdump/1991/0110/sys/src/9/sparc/trap.c /n/bootesdump/1991/0112/sys/src/9/sparc/trap.c
326d
210a
(*urp)->r7 = -1; /* return error from the interrupted call */
.
190a
ur->npc = (ulong)u->notify+4;
.
165c
if(u->nnote==0){
.
95,96d
92,93c
if(user && u->nnote)
.
83d
## diffname ss/trap.c 1991/0115
## diff -e /n/bootesdump/1991/0112/sys/src/9/sparc/trap.c /n/bootesdump/1991/0115/sys/src/9/sparc/trap.c
331c
strncpy(u->error, errstrtab[code], ERRLEN);
.
83a
if(tbr == 8)
sprint(buf+strlen(buf), " FSR %lux", getfsr());
.
76a
if(tbr == 8) /* floating point exception */
clearfpintr();
.
## diffname ss/trap.c 1991/01151
## diff -e /n/bootesdump/1991/0115/sys/src/9/sparc/trap.c /n/bootesdump/1991/01151/sys/src/9/sparc/trap.c
287c
.
285c
ur->psr &= ~PSREF;
.
281,283c
if(u->p->fpstate == FPactive) {
.
278,279c
* guarantee anything about registers,
.
275c
.
95,96c
Return:
if(user && u && u->p->fpstate == FPinactive) {
restfpregs(&u->fpsave);
u->p->fpstate = FPactive;
ur->psr |= PSREF;
}
.
90,93c
switch(tbr){
case 1: /* instr. access */
case 9: /* data access */
if(u && u->p->fpstate==FPactive) {
savefpregs(&u->fpsave);
u->p->fpstate = FPinactive;
ur->psr &= ~PSREF;
}
if(u){
x = u->p->insyscall;
u->p->insyscall = 1;
faultsparc(ur);
u->p->insyscall = x;
}else
faultsparc(ur);
goto Return;
case 4: /* floating point disabled */
if(u && u->p){
if(u->p->fpstate == FPinit)
restfpregs(&initfp);
else if(u->p->fpstate == FPinactive)
restfpregs(&u->fpsave);
else
break;
u->p->fpstate = FPactive;
ur->psr |= PSREF;
return;
}
break;
case 8: /* floating point exception */
clearfpintr();
break;
default:
break;
}
if(user){
spllo();
sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(tbr));
if(tbr == 8)
sprint(buf+strlen(buf), " FSR %lux", u->fpsave.fsr);
postnote(u->p, 1, buf, NDebug);
}else{
Error:
print("kernel trap: %s pc=0x%lux\n", excname(tbr), ur->pc);
dumpregs(ur);
for(;;);
}
if(user && u->nnote)
notify(ur);
.
84,88c
user = !(ur->psr&PSRPSUPER);
tbr = (ur->tbr&0xFFF)>>4;
if(tbr > 16){ /* interrupt */
if(u && u->p->state==Running){
if(u->p->fpstate == FPactive) {
savefpregs(&u->fpsave);
u->p->fpstate = FPinactive;
ur->psr &= ~PSREF;
}
}
switch(tbr-16){
case 15: /* asynch mem err */
faultasync(ur);
break;
case 14: /* counter 1 */
clock(ur);
break;
case 12: /* keyboard and mouse */
duartintr();
break;
case 5: /* lance */
lanceintr();
break;
default:
goto Error;
}
.
60,82c
if(u)
.
56c
int user, x;
.
## diffname ss/trap.c 1991/0318
## diff -e /n/bootesdump/1991/0201/sys/src/9/sparc/trap.c /n/bootesdump/1991/0318/sys/src/9/slc/trap.c
259c
memmove(*urp, u->ureg, sizeof(Ureg));
.
242c
memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note));
.
232c
memmove((char*)sp, u->note[0].msg, ERRLEN);
.
230c
memmove((Ureg*)sp, ur, sizeof(Ureg));
.
## diffname ss/trap.c 1991/0322
## diff -e /n/bootesdump/1991/0318/sys/src/9/slc/trap.c /n/bootesdump/1991/0322/sys/src/9/slc/trap.c
387c
strncpy(u->error, err, ERRLEN);
.
## diffname ss/trap.c 1991/0503
## diff -e /n/bootesdump/1991/0322/sys/src/9/slc/trap.c /n/bootesdump/1991/0503/sys/src/9/slc/trap.c
338a
print("syscall %s %d %d\n", u->p->text, u->p->pid, r7);
.
216a
print("suicide: %s\n", u->note[0].msg);
.
## diffname ss/trap.c 1991/0504
## diff -e /n/bootesdump/1991/0503/sys/src/9/slc/trap.c /n/bootesdump/1991/0504/sys/src/9/slc/trap.c
340d
217d
## diffname ss/trap.c 1991/0513
## diff -e /n/bootesdump/1991/0504/sys/src/9/slc/trap.c /n/bootesdump/1991/0513/sys/src/9/slc/trap.c
282c
sysalarm,
.
273c
Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm;
.
## diffname ss/trap.c 1991/0604
## diff -e /n/bootesdump/1991/0513/sys/src/9/slc/trap.c /n/bootesdump/1991/0604/sys/src/9/slc/trap.c
80c
sccintr();
.
## diffname ss/trap.c 1991/0614
## diff -e /n/bootesdump/1991/0604/sys/src/9/slc/trap.c /n/bootesdump/1991/0614/sys/src/9/slc/trap.c
358c
if(u->nerrlab){
print("unbalanced error stack: %d extra\n", u->nerrlab);
for(i = 0; i < NERR; i++)
print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc);
panic("bad rob");
}
.
354a
poperror();
.
352,353c
if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(2+MAXSYSARG)*BY2WD))
validaddr(sp, ((2+MAXSYSARG)*BY2WD), 0);
.
311a
int i;
.
## diffname ss/trap.c 1991/0709
## diff -e /n/bootesdump/1991/0614/sys/src/9/slc/trap.c /n/bootesdump/1991/0709/sys/src/9/slc/trap.c
364c
panic("error stack");
.
361c
print("bad error stack [%d]: %d extra\n", r7, u->nerrlab);
.
## diffname ss/trap.c 1991/0710
## diff -e /n/bootesdump/1991/0709/sys/src/9/slc/trap.c /n/bootesdump/1991/0710/sys/src/9/slc/trap.c
380,402d
267c
#include "/sys/src/libc/9syscall/sys.h"
.
## diffname ss/trap.c 1991/0711
## diff -e /n/bootesdump/1991/0710/sys/src/9/slc/trap.c /n/bootesdump/1991/0711/sys/src/9/slc/trap.c
351a
}
if(((ulong*)ur->pc)[-2] != 0x82206004){ /* new calling convention: look for ADD $-4, SP */
pprint("new system call linkage\n");
sp -= BY2WD;
.
334a
print("got low in syscall\n");
.
333c
print("syscall %d\n", ur->r7);
.
323a
}
u->p->insyscall = 1;
u->p->pc = ur->pc;
.
321,322c
if(ur->psr & PSRPSUPER){
dumpregs(ur);
.
319d
184a
}
.
183c
print("%lux=%lux ", l, v);
++i;
if((i&7) == 0)
print("\n");
.
179c
if(u){
i = 0;
.
177a
print("no dumpstack\n");
return;
.
176a
int i;
.
## diffname ss/trap.c 1991/0712
## diff -e /n/bootesdump/1991/0711/sys/src/9/slc/trap.c /n/bootesdump/1991/0712/sys/src/9/slc/trap.c
345d
343d
331d
328,329c
if(ur->psr & PSRPSUPER)
.
## diffname ss/trap.c 1991/0713
## diff -e /n/bootesdump/1991/0712/sys/src/9/slc/trap.c /n/bootesdump/1991/0713/sys/src/9/slc/trap.c
364,366c
if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD))
validaddr(sp, ((1+MAXSYSARG)*BY2WD), 0);
ret = (*systab[r7])((ulong*)(sp+1*BY2WD));
.
360,362c
if(((ulong*)ur->pc)[-2] == 0x82206004){ /* new calling convention: look for ADD $-4, SP */
pprint("old system call linkage\n");
sp += BY2WD;
.
## diffname ss/trap.c 1991/0717
## diff -e /n/bootesdump/1991/0713/sys/src/9/slc/trap.c /n/bootesdump/1991/0717/sys/src/9/slc/trap.c
379c
noted(&aur, *(ulong*)(sp+1*BY2WD)); /* doesn't return */
.
269,271c
switch(arg0){
case NCONT:
splhi();
unlock(&u->p->debug);
rfnote(urp);
break;
/* never returns */
default:
pprint("unknown noted arg 0x%lux\n", arg0);
u->lastnote.flag = NDebug;
/* fall through */
case NTERM:
if(u->lastnote.flag == NDebug)
pprint("suicide: %s\n", u->lastnote.msg);
unlock(&u->p->debug);
pexit(u->lastnote.msg, u->lastnote.flag!=NDebug);
}
.
260a
Ureg *nur;
nur = u->ureg;
validaddr(nur->pc, 1, 0);
validaddr(nur->usp, BY2WD, 0);
if(nur->psr!=u->svpsr){
pprint("bad noted ureg psr %lux\n", nur->psr);
pexit("Suicide", 0);
}
.
259c
noted(Ureg **urp, ulong arg0)
.
249a
memmove(&u->lastnote, &u->note[0], sizeof(Note));
.
234a
u->svpsr = ur->psr;
.
11c
void noted(Ureg**, ulong);
.
## diffname ss/trap.c 1991/0718
## diff -e /n/bootesdump/1991/0717/sys/src/9/slc/trap.c /n/bootesdump/1991/0718/sys/src/9/slc/trap.c
293c
case NDFLT:
.
## diffname ss/trap.c 1991/0722
## diff -e /n/bootesdump/1991/0718/sys/src/9/slc/trap.c /n/bootesdump/1991/0722/sys/src/9/slc/trap.c
237a
if(waserror()){
pprint("suicide: trap in notify\n");
unlock(&u->p->debug);
pexit("Suicide", 0);
}
validaddr((ulong)u->notify, 1, 0);
validaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0);
poperror();
.
## diffname ss/trap.c 1991/0724
## diff -e /n/bootesdump/1991/0722/sys/src/9/slc/trap.c /n/bootesdump/1991/0724/sys/src/9/slc/trap.c
415c
if(u->nnote && r7!=FORK){
.
287d
## diffname ss/trap.c 1991/0727
## diff -e /n/bootesdump/1991/0724/sys/src/9/slc/trap.c /n/bootesdump/1991/0727/sys/src/9/slc/trap.c
220a
u->p->notepending = 0;
.
## diffname ss/trap.c 1991/0731
## diff -e /n/bootesdump/1991/0727/sys/src/9/slc/trap.c /n/bootesdump/1991/0731/sys/src/9/slc/trap.c
309,350c
#include "../port/systab.h"
.
## diffname ss/trap.c 1991/0814
## diff -e /n/bootesdump/1991/0731/sys/src/9/slc/trap.c /n/bootesdump/1991/0814/sys/src/9/slc/trap.c
289a
if(waserror()){
pprint("suicide: trap in noted\n");
unlock(&u->p->debug);
goto Die;
}
validaddr(nur->pc, 1, 0);
validaddr(nur->usp, BY2WD, 0);
poperror();
.
284c
pprint("call to noted() when not notified\n");
goto Die;
.
278a
Die:
.
275,276d
## diffname ss/trap.c 1991/0926
## diff -e /n/bootesdump/1991/0814/sys/src/9/slc/trap.c /n/bootesdump/1991/0926/sys/src/9/slc/trap.c
379a
u->p->psstate = 0;
.
367a
u->p->psstate = sysctab[r7];
.
## diffname ss/trap.c 1991/1105
## diff -e /n/bootesdump/1991/0926/sys/src/9/slc/trap.c /n/bootesdump/1991/1105/sys/src/9/slc/trap.c
361,364d
253c
*(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 is ureg* (compat) */
ur->r7 = (ulong)u->ureg; /* arg 1 is ureg* */
.
## diffname ss/trap.c 1991/1108
## diff -e /n/bootesdump/1991/1105/sys/src/9/slc/trap.c /n/bootesdump/1991/1108/sys/src/9/slc/trap.c
371,376c
u->nerrlab = 0;
if(u->p->procctl)
procctl(u->p);
.
344a
if(u->p->procctl)
procctl(u->p);
.
179,180d
140,143c
if(user) {
if(u->p->procctl)
procctl(u->p);
if(u->nnote)
notify(ur);
if(u->p->fpstate == FPinactive) {
restfpregs(&u->fpsave);
u->p->fpstate = FPactive;
ur->psr |= PSREF;
}
.
136,137d
## diffname ss/trap.c 1991/1111
## diff -e /n/bootesdump/1991/1108/sys/src/9/slc/trap.c /n/bootesdump/1991/1111/sys/src/9/slc/trap.c
395a
}
/* This routine must save the values of registers the user is not permitted
* to write from devproc and restore them before returning
*/
void
setregisters(Ureg *xp, char *pureg, char *uva, int n)
{
print("setregisters: no idea\n");
.
385c
if(u->p->procctl || (u->nnote && r7!=FORK)){
.
348,350d
221a
if(u->p->procctl)
procctl(u->p);
if(u->nnote == 0)
return;
.
139,142c
notify(ur);
.
131d
123a
Error:
.
## diffname ss/trap.c 1991/1113
## diff -e /n/bootesdump/1991/1111/sys/src/9/slc/trap.c /n/bootesdump/1991/1113/sys/src/9/slc/trap.c
222a
.
170a
.
127c
sprint(buf, "sys: %s pc=0x%lux", excname(tbr), ur->pc);
.
61a
u->dbgreg = ur;
}
.
60c
if(u) {
.
49a
}
Return:
.
48c
else switch(tbr){
case 36:
return "cp disabled";
case 40:
return "cp exception";
case 128:
return "syscall";
case 129:
return "breakpoint";
default:
.
40,44c
if(tbr >= 130)
.
36c
static char buf[64]; /* BUG: not reentrant! */
.
## diffname ss/trap.c 1991/1114
## diff -e /n/bootesdump/1991/1113/sys/src/9/slc/trap.c /n/bootesdump/1991/1114/sys/src/9/slc/trap.c
414c
ulong psr;
status = xp->psr;
memmove(pureg, uva, n);
xp->psr = psr;
.
408,409c
/* This routine must save the values of registers the user is not permitted to write
* from devproc and the restore the saved values before returning
.
395c
splhi();
if(r7!=FORK && (u->p->procctl || u->nnote)){
.
279a
splx(s);
.
234a
s = spllo(); /* need to go low as may fault */
.
228c
ulong s, sp;
.
222,224d
## diffname ss/trap.c 1991/1115
## diff -e /n/bootesdump/1991/1114/sys/src/9/slc/trap.c /n/bootesdump/1991/1115/sys/src/9/slc/trap.c
417c
psr = xp->psr;
.
## diffname ss/trap.c 1991/1214
## diff -e /n/bootesdump/1991/1115/sys/src/9/slc/trap.c /n/bootesdump/1991/1214/sys/src/9/slc/trap.c
406c
ulong *sp;
sp = (ulong*)(USTKTOP - ssize);
*--sp = nargs;
((Ureg*)UREGADDR)->usp = (ulong)sp;
((Ureg*)UREGADDR)->pc = entry - 4; /* syscall advances it */
return USTKTOP-BY2WD; /* address of user-level clock */
.
403,404c
long
execregs(ulong entry, ulong ssize, ulong nargs)
.
## diffname ss/trap.c 1991/1216
## diff -e /n/bootesdump/1991/1214/sys/src/9/slc/trap.c /n/bootesdump/1991/1216/sys/src/9/slc/trap.c
327c
qunlock(&u->p->debug);
.
314c
qunlock(&u->p->debug);
.
307c
qunlock(&u->p->debug);
.
297c
qunlock(&u->p->debug);
.
295c
qlock(&u->p->debug);
.
277c
qunlock(&u->p->debug);
.
254c
qunlock(&u->p->debug);
.
243c
qunlock(&u->p->debug);
.
236c
qunlock(&u->p->debug);
.
233c
qlock(&u->p->debug);
.
## diffname ss/trap.c 1991/12171
## diff -e /n/bootesdump/1991/1216/sys/src/9/slc/trap.c /n/bootesdump/1991/12171/sys/src/9/slc/trap.c
28c
"fp: exception",
.
24c
"fp: disabled",
.
## diffname ss/trap.c 1991/1218
## diff -e /n/bootesdump/1991/12171/sys/src/9/slc/trap.c /n/bootesdump/1991/1218/sys/src/9/slc/trap.c
244c
pexit(n->msg, n->flag!=NDebug);
.
241c
pprint("suicide: %s\n", n->msg);
.
239c
if(n->flag!=NUser && (u->notified || u->notify==0)){
.
235,237c
n = &u->note[0];
if(strncmp(n->msg, "sys:", 4) == 0){
l = strlen(n->msg);
if(l > ERRLEN-15) /* " pc=0x12345678\0" */
l = ERRLEN-15;
sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
.
232c
s = spllo();
.
229c
if(u->nnote==0)
.
225a
Note *n;
.
224a
int l;
.
137c
sprint(buf, "sys: %s", excname(tbr));
.
56c
if(tbr < sizeof trapname/sizeof(char*))
t = trapname[tbr];
else{
if(tbr >= 130)
sprint(xx, "trap instruction %d", tbr-128);
else if(17<=tbr && tbr<=31)
sprint(xx, "interrupt level %d", tbr-16);
else
sprint(xx, "unknown trap %d", tbr);
t = xx;
}
if(strncmp(t, "fp: ", 4) == 0)
strcpy(buf, t);
else
sprint(buf, "trap: %s", t);
.
53,54d
48c
return "trap: cp exception";
.
38,46c
switch(tbr){
return "trap: cp disabled";
.
36a
char xx[64];
char *t;
.
## diffname ss/trap.c 1992/0102
## diff -e /n/bootesdump/1991/1218/sys/src/9/slc/trap.c /n/bootesdump/1992/0102/sys/src/9/slc/trap.c
410a
return ur->r7;
.
409c
u->svr7 = ret;
.
314a
(*urp)->r7 = u->svr7;
.
## diffname ss/trap.c 1992/0108
## diff -e /n/bootesdump/1992/0102/sys/src/9/slc/trap.c /n/bootesdump/1992/0108/sys/src/9/slc/trap.c
411,412c
if(notify(ur))
return ur->r7;
.
290a
return 1;
.
238,239c
if(u->nnote == 0)
return 0;
.
229c
int
.
10d
## diffname ss/trap.c 1992/0111
## diff -e /n/bootesdump/1992/0108/sys/src/9/slc/trap.c /n/bootesdump/1992/0111/sys/src/9/slc/trap.c
8c
#include "../port/error.h"
.
## diffname ss/trap.c 1992/0120
## diff -e /n/bootesdump/1992/0111/sys/src/9/slc/trap.c /n/bootesdump/1992/0120/sys/src/9/slc/trap.c
428a
ulong
userpc(void)
{
return ((Ureg*)UREGADDR)->pc;
}
.
## diffname ss/trap.c 1992/0124
## diff -e /n/bootesdump/1992/0120/sys/src/9/slc/trap.c /n/bootesdump/1992/0124/sys/src/9/slc/trap.c
290c
return sent;
.
259a
sent = 1;
.
256a
sent = 0;
.
231c
int l, sent;
.
## diffname ss/trap.c 1992/0209
## diff -e /n/bootesdump/1992/0124/sys/src/9/slc/trap.c /n/bootesdump/1992/0209/sys/src/9/slc/trap.c
197c
print("no dumpstack\n");
return;
.
## diffname ss/trap.c 1992/0321
## diff -e /n/bootesdump/1992/0209/sys/src/9/slc/trap.c /n/bootesdump/1992/0321/sys/src/9/slc/trap.c
2c
#include "../port/lib.h"
.
## diffname ss/trap.c 1992/0409
## diff -e /n/bootesdump/1992/0321/sys/src/9/slc/trap.c /n/bootesdump/1992/0409/sys/src/9/slc/trap.c
413c
ur->r7 = ret; /* load up for noted() */
.
280a
u->svr7 = ur->r7; /* save away r7 */
.
## diffname ss/trap.c 1992/0430
## diff -e /n/bootesdump/1992/0409/sys/src/9/slc/trap.c /n/bootesdump/1992/0430/sys/src/9/slc/trap.c
413c
if(r7!=RFORK && (u->p->procctl || u->nnote)){
.
## diffname ss/trap.c 1992/0616
## diff -e /n/bootesdump/1992/0430/sys/src/9/slc/trap.c /n/bootesdump/1992/0616/sys/src/9/slc/trap.c
327,329d
322c
if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){
.
271,273d
266,267c
if(!okaddr((ulong)u->notify, 1, 0)
|| !okaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0)){
pprint("suicide: bad address in notify\n");
.
## diffname ss/trap.c 1992/0620
## diff -e /n/bootesdump/1992/0616/sys/src/9/slc/trap.c /n/bootesdump/1992/0620/sys/src/9/slc/trap.c
395a
.
388c
postnote(u->p, 1, msg, NDebug);
error(Ebadarg);
.
386c
pprint("odd sp in sys call pc %lux sp %lux\n", ur->pc, ur->sp);
.
381d
379c
pprint("bad sys call number %d pc %lux\n", r7, ur->pc);
.
## diffname ss/trap.c 1992/0625
## diff -e /n/bootesdump/1992/0620/sys/src/9/slc/trap.c /n/bootesdump/1992/0625/sys/src/9/slc/trap.c
393c
ret = (*systab[r7])(u->s.args);
.
390,391c
if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)))
validaddr(sp, sizeof(Sargs), 0);
u->s = *((Sargs*)(sp+1*BY2WD));
.
386,387c
postnote(u->p, 1, "sys: odd stack", NDebug);
.
383a
.
380,381c
postnote(u->p, 1, "sys: bad sys call", NDebug);
.
354d
## diffname ss/trap.c 1992/06271
## diff -e /n/bootesdump/1992/0625/sys/src/9/slc/trap.c /n/bootesdump/1992/06271/sys/src/9/slc/trap.c
411c
if(u->scallnr!=RFORK && (u->p->procctl || u->nnote)){
.
407c
if(u->scallnr == NOTED) /* ugly hack */
.
395c
ret = (*systab[u->scallnr])(u->s.args);
.
393c
u->p->psstate = sysctab[u->scallnr];
.
377,378c
if(u->scallnr >= sizeof systab/BY2WD){
pprint("bad sys call number %d pc %lux\n", u->scallnr, ur->pc);
.
371c
u->scallnr = ur->r7;
.
352d
## diffname ss/trap.c 1992/0714
## diff -e /n/bootesdump/1992/06271/sys/src/9/slc/trap.c /n/bootesdump/1992/0714/sys/src/9/slc/trap.c
252c
if(n->flag == NDebug)
.
## diffname ss/trap.c 1992/0720
## diff -e /n/bootesdump/1992/0714/sys/src/9/slc/trap.c /n/bootesdump/1992/0720/sys/src/9/slc/trap.c
349d
## diffname ss/trap.c 1992/0721
## diff -e /n/bootesdump/1992/0720/sys/src/9/slc/trap.c /n/bootesdump/1992/0721/sys/src/9/slc/trap.c
188a
}
void
mulu(ulong u1, ulong u2, ulong *lop, ulong *hip)
{
ulong lo1, lo2, hi1, hi2, lo, hi, t1, t2, t;
lo1 = u1 & 0xffff;
lo2 = u2 & 0xffff;
hi1 = u1 >> 16;
hi2 = u2 >> 16;
lo = lo1 * lo2;
t1 = lo1 * hi2;
t2 = lo2 * hi1;
hi = hi1 * hi2;
t = lo;
lo += t1 << 16;
if(lo < t)
hi++;
t = lo;
lo += t2 << 16;
if(lo < t)
hi++;
hi += (t1 >> 16) + (t2 >> 16);
*lop = lo;
*hip = hi;
}
void
muls(long l1, long l2, long *lop, long *hip)
{
ulong t, lo, hi;
ulong mlo, mhi;
int sign;
sign = 0;
if(l1 < 0){
sign ^= 1;
l1 = -l1;
}
if(l2 < 0){
sign ^= 1;
l2 = -l2;
}
mulu(l1, l2, &mlo, &mhi);
lo = mlo;
hi = mhi;
if(sign){
t = lo = ~lo;
hi = ~hi;
lo++;
if(lo < t)
hi++;
}
*lop = lo;
*hip = hi;
}
int
domuldiv(ulong iw, Ureg *ur)
{
long op1, op2;
long *regp;
long *regs;
regs = (long*)ur;
if(iw & (1<<13)){ /* signed immediate */
op2 = iw & 0x1FFF;
if(op2 & 0x1000)
op2 |= ~0x1FFF;
}else
op2 = regs[iw&0x1F];
op1 = regs[(iw>>14)&0x1F];
regp = ®s[(iw>>25)&0x1F];
if(iw & (4<<19)){ /* divide */
if(ur->y!=0 && ur->y!=~0){
unimp:
ur->tbr = 37; /* "unimplemented instruction" */
return 0; /* complex Y is too hard */
}
if(op2 == 0){
ur->tbr = 42; /* "zero divide" */
return 0;
}
if(iw & (1<<19)){
if(ur->y && (op1&(1<<31))==0)
goto unimp; /* Y not sign extension */
*regp = op1 / op2;
}else{
if(ur->y)
goto unimp;
*regp = (ulong)op1 / (ulong)op2;
}
}else{
if(iw & (1<<19))
muls(op1, op2, regp, (long*)&ur->y);
else
mulu(op1, op2, (ulong*)regp, &ur->y);
}
if(iw & (16<<19)){ /* set CC */
ur->psr &= ~(0xF << 20);
if(*regp & (1<<31))
ur->psr |= 8 << 20; /* N */
if(*regp == 0)
ur->psr |= 4 << 20; /* Z */
/* BUG: don't get overflow right on divide */
}
ur->pc += 4;
ur->npc = ur->pc+4;
return 1;
.
120a
case 2: /* illegal instr, maybe mul */
iw = *(ulong*)ur->pc;
if((iw&0xC1500000) == 0x80500000){
if(domuldiv(iw, ur))
goto Return;
tbr = ur->tbr;
}
break;
.
71c
ulong tbr, iw;
.
50c
if(t == 0){
.
47a
t = 0;
.
42a
case 42:
return "trap: divide by zero";
.
40a
case 37:
return "trap: unimplemented instruction";
.
39a
case 36:
.
29a
"watchpoint detected",
.
11a
int domuldiv(ulong, Ureg*);
.
## diffname ss/trap.c 1992/0726
## diff -e /n/bootesdump/1992/0721/sys/src/9/slc/trap.c /n/bootesdump/1992/0726/sys/src/9/slc/trap.c
160,161d
151c
if(fptrap()){
/* do NOT talk to the FPU: see fptrap.c */
return;
}
.
70,71c
sprint(excbuf, "trap: %s", t);
return excbuf;
.
68c
strcpy(excbuf, t);
.
41a
case 8:
if(u == 0){
fsr = getfsr();
sprint(excbuf, "fp: %s FSR %lux",
fptrapname[(fsr>>14)&7], fsr);
}else{
fsr = u->fpsave.fsr;
sprint(excbuf, "fp: %s FQpc=0x%lux",
fptrapname[(fsr>>14)&7],
u->fpsave.q[0].a, fsr);
}
return excbuf;
.
39a
ulong fsr;
.
37d
33a
char *fptrapname[]={
"none",
"IEEE 754 exception",
"unfinished FP op",
"unimplemented FP op",
"sequence error",
"hardware error",
"invalid FP register",
"reserved",
};
.
17c
long ticks;
static char excbuf[64]; /* BUG: not reentrant! */
.
## diffname ss/trap.c 1992/0727
## diff -e /n/bootesdump/1992/0726/sys/src/9/slc/trap.c /n/bootesdump/1992/0727/sys/src/9/slc/trap.c
516a
fpquiet();
.
164c
restfpregs(initfpp);
.
140a
fpquiet();
.
114c
if(u->p->fpstate == FPactive){
fpquiet();
.
98a
fpquiet(void)
{
int i;
ulong fsr;
i = 0;
fsr = getfsr();
while(fsr & (1<<13)){
if(fsr & 0x1F){
print("trap in fpquiet\n");
break;
}
if(++i > 1000){
print("fp not quiescent\n");
break;
}
}
}
void
.
97a
/*
* This routine is frightening. See comment in fptrap.c
*/
.
## diffname ss/trap.c 1992/0801
## diff -e /n/bootesdump/1992/0727/sys/src/9/slc/trap.c /n/bootesdump/1992/0801/sys/src/9/slc/trap.c
535a
/* SS2 bug: flush cache line holding trap entry in table */
if(conf.ss2)
putw2(CACHETAGS+((TRAPS+16*128)&(VACSIZE-1)), 0);
.
253d
240c
/* ss2: must flush cache line for table */
*(ulong*)(t+0) = a; /* CALL traplink(SB) */
.
134a
/* SS2 bug: flush cache line holding trap entry in table */
if(conf.ss2)
putw2(CACHETAGS+((TRAPS+16*tbr)&(VACSIZE-1)), 0);
.
## diffname ss/trap.c 1992/0802
## diff -e /n/bootesdump/1992/0801/sys/src/9/slc/trap.c /n/bootesdump/1992/0802/sys/src/9/slc/trap.c
446c
sp -= sizeof(Ureg)+ERRLEN+3*BY2WD;
sp &= ~7; /* SP must be 8-byte aligned */
sp += ERRLEN+3*BY2WD;
.
223c
/*
* Handled the interrupt; now it's safe to look at the FPQ
*/
if(fpunsafe)
fpquiet();
if(user){
.
216,220c
}else
panic("kernel trap: %s pc=0x%lux\n", excname(tbr), ur->pc);
.
206a
if(fptrap())
goto Return; /* handled the problem */
.
203,204c
/* if unsafe, trap happened shutting down FPU; just return */
if(m->fpunsafe){
m->fptrap = (fptrap()==0);
.
171d
168,169c
fpunsafe = 1;
m->fpunsafe = 1;
.
144d
141,142c
fpunsafe = 1;
m->fpunsafe = 1;
.
139a
/* if active, FPop at head of Q is probably an excep */
.
132a
fpunsafe = 0;
.
124c
int user, x, fpunsafe;
.
102,121d
98,100d
55,59c
if(u == 0)
panic("fptrap in kernel\n");
else{
if(m->fpunsafe==0 && u->p->fpstate!=FPactive)
panic("fptrap not active\n");
.
## diffname ss/trap.c 1992/0803
## diff -e /n/bootesdump/1992/0802/sys/src/9/slc/trap.c /n/bootesdump/1992/0803/sys/src/9/slc/trap.c
570,572d
538a
if(u->p->procctl)
procctl(u->p);
.
## diffname ss/trap.c 1992/0804
## diff -e /n/bootesdump/1992/0803/sys/src/9/slc/trap.c /n/bootesdump/1992/0804/sys/src/9/slc/trap.c
572a
if(u->p->procctl)
procctl(u->p);
.
539,541d
534a
u->fpsave.fsr = getfsr();
.
528,531d
208c
restfpregs(&u->fpsave, u->fpsave.fsr);
.
171c
restfpregs(&u->fpsave, u->fpsave.fsr);
.
169c
restfpregs(initfpp, initfpp->fsr);
.
## diffname ss/trap.c 1992/0805
## diff -e /n/bootesdump/1992/0804/sys/src/9/slc/trap.c /n/bootesdump/1992/0805/sys/src/9/slc/trap.c
592a
u->fpsave.fsr = initfpp->fsr;
.
169c
restfpregs(initfpp, u->fpsave.fsr);
.
108d
105,106c
if(u)
.
## diffname ss/trap.c 1992/0806
## diff -e /n/bootesdump/1992/0805/sys/src/9/slc/trap.c /n/bootesdump/1992/0806/sys/src/9/slc/trap.c
524c
putsysspace(CACHETAGS+((TRAPS+16*128)&(VACSIZE-1)), 0);
.
410c
sprint(n->msg+l, " pc=0x%lux", ur->pc);
.
113c
putsysspace(CACHETAGS+((TRAPS+16*tbr)&(VACSIZE-1)), 0);
.
61c
sprint(excbuf, "fp: %s fppc=0x%lux",
.
## diffname ss/trap.c 1992/0807
## diff -e /n/bootesdump/1992/0807/sys/src/9/slc/trap.c /n/bootesdump/1992/0807/sys/src/9/ss/trap.c
524c
putsysspace(CACHETAGS+((TRAPS+16*128)&(conf.vacsize-1)), 0);
.
135a
case 3: /* lance */
scsiintr();
break;
.
112,113c
if(conf.ss2cachebug)
putsysspace(CACHETAGS+((TRAPS+16*tbr)&(conf.vacsize-1)), 0);
.
## diffname ss/trap.c 1992/0810
## diff -e /n/bootesdump/1992/0807/sys/src/9/ss/trap.c /n/bootesdump/1992/0810/sys/src/9/ss/trap.c
110d
104a
tbr = (ur->tbr&0xFFF)>>4;
/*
* Hack to catch bootstrap fault during probe
*/
if(catch.pc)
longjmp(&catch, 1);
.
13a
extern Label catch;
.
## diffname ss/trap.c 1992/0811
## diff -e /n/bootesdump/1992/0810/sys/src/9/ss/trap.c /n/bootesdump/1992/0811/sys/src/9/ss/trap.c
247a
setpsr(getpsr()|PSRET|SPL(15)); /* enable traps, not interrupts */
.
111c
gotolabel(&catch);
.
## diffname ss/trap.c 1992/0914
## diff -e /n/bootesdump/1992/0811/sys/src/9/ss/trap.c /n/bootesdump/1992/0914/sys/src/9/ss/trap.c
381a
print("\n");
.
377,379c
++i;
if((i&3) == 0)
print("\n");
}
.
375c
if(KTZERO < v && v < (ulong)&etext){
.
369,370c
static int dumping;
if(dumping == 1){
print("no dumpstack\n");
return;
}
dumping = 1;
.
208,212d
154,155c
fpquiet();
savefpregs(&u->fpsave);
.
125,126c
fpquiet();
savefpregs(&u->fpsave);
.
116d
102c
int user, x;
.
## diffname ss/trap.c 1993/0225
## diff -e /n/bootesdump/1992/0914/sys/src/9/ss/trap.c /n/bootesdump/1993/0225/sys/src/9/ss/trap.c
456a
*(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 0(FP) is ureg* */
.
## diffname ss/trap.c 1993/0501 # deleted
## diff -e /n/bootesdump/1993/0225/sys/src/9/ss/trap.c /n/fornaxdump/1993/0501/sys/src/brazil/ss/trap.c
1,626d
|