plan 9 kernel history: overview | file list | diff list

1991/0711/ss/trap.c (diff list | history)

1990/1223/sys/src/9/ss/trap.c:11,821990/1226/sys/src/9/ss/trap.c:11,54 (short | long)
1990/1223    
void	noted(Ureg**); 
void	rfnote(Ureg**); 
 
char *regname[]={ 
	"R0", 
	"R1", 
	"R2", 
	"R3", 
	"R4", 
	"R5", 
	"R6", 
	"R7", 
	"A0", 
	"A1", 
	"A2", 
	"A3", 
	"A4", 
	"A5", 
	"A6", 
	"A7", 
}; 
1990/1226    
extern	void traplink(void); 
extern	void syslink(void); 
1990/1223    
 
long	ticks; 
 
char *trapname[]={ 
	"reset isp", 
	"reset ipc", 
	"bus error", 
	"address error", 
1990/1226    
	"reset", 
	"instruction access exception", 
1990/1223    
	"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", 
1990/1226    
	"privileged instruction", 
	"fp disabled", 
	"window overflow", 
	"window underflow", 
	"unaligned address", 
	"fp exception", 
	"data access exception", 
	"tag overflow", 
1990/1223    
}; 
 
char* 
excname(unsigned vo) 
1990/1226    
excname(ulong tbr) 
1990/1223    
{ 
	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); 
1990/1226    
	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); 
1990/1223    
	return buf; 
} 
 
1990/1223/sys/src/9/ss/trap.c:86,1011990/1226/sys/src/9/ss/trap.c:58,77
1990/1223    
	int user; 
	char buf[64]; 
 
	user = !(ur->sr&SUPER); 
                 
	if(u) 
1990/1226    
	user = !(ur->psr&PSRPSUPER); 
 
/*	if(u) 
1990/1223    
		u->p->pc = ur->pc;		/* BUG */ 
	if(user){ 
		sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(ur->vo)); 
1990/1226    
		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)); 
1990/1223    
		postnote(u->p, 1, buf, NDebug); 
	}else{ 
		print("kernel trap vo=0x%ux pc=0x%lux\n", ur->vo, ur->pc); 
1990/1226    
		print("kernel trap: %s pc=0x%lux\n", excname(ur->tbr), ur->pc); 
1990/1223    
		dumpregs(ur); 
1990/1226    
for(;;); 
1990/1223    
		exit(); 
	} 
	if(user && u->nnote) 
1990/1223/sys/src/9/ss/trap.c:103,1081990/1226/sys/src/9/ss/trap.c:79,110
1990/1223    
} 
 
void 
1990/1226    
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 
1990/1223    
dumpstack(void) 
{ 
	ulong l, v; 
1990/1223/sys/src/9/ss/trap.c:126,1351990/1226/sys/src/9/ss/trap.c:128,137
1990/1223    
		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); 
1990/1226    
	print("PSR=%ux PC=%lux TBR=%lux\n", ur->psr, ur->pc, ur->tbr); 
1990/1223    
	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]); 
1990/1226    
	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]); 
1990/1223    
	dumpstack(); 
} 
 
1990/1223/sys/src/9/ss/trap.c:194,2001990/1226/sys/src/9/ss/trap.c:196,202
1990/1223    
} 
 
#undef	CHDIR	/* BUG */ 
#include "/sys/src/libc/680209sys/sys.h" 
1990/1226    
#include "/sys/src/libc/sparc9sys/sys.h" 
1990/1223    
 
typedef long Syscall(ulong*); 
Syscall	sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait; 
1990/1223/sys/src/9/ss/trap.c:241,2471990/1226/sys/src/9/ss/trap.c:243,249
1990/1223    
{ 
	long ret; 
	ulong sp; 
	ulong r0; 
1990/1226    
	ulong r7; 
1990/1223    
	Ureg *ur; 
	char *msg; 
 
1990/1223/sys/src/9/ss/trap.c:248,2611990/1226/sys/src/9/ss/trap.c:250,263
1990/1223    
	u->p->insyscall = 1; 
	ur = aur; 
	u->p->pc = ur->pc; 
	if(ur->sr & SUPER) 
1990/1226    
	if(ur->psr & PSRPSUPER) 
1990/1223    
		panic("recursive system call"); 
1990/1226    
#ifdef asdf 
1990/1223    
	/* 
	 * 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); 
1990/1223/sys/src/9/ss/trap.c:262,2761990/1226/sys/src/9/ss/trap.c:264,279
1990/1223    
		u->p->fpstate = FPinit; 
		m->fpstate = FPinit; 
	} 
1990/1226    
#endif 
1990/1223    
	spllo(); 
	r0 = ur->r0; 
1990/1226    
	r7 = ur->r7; 
1990/1223    
	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); 
1990/1226    
		if(r7 >= sizeof systab/BY2WD){ 
			pprint("bad sys call number %d pc %lux\n", r7, ((Ureg*)UREGADDR)->pc); 
1990/1223    
			msg = "sys: bad sys call"; 
	    Bad: 
			postnote(u->p, 1, msg, NDebug); 
1990/1223/sys/src/9/ss/trap.c:283,2991990/1226/sys/src/9/ss/trap.c:286,311
1990/1223    
		} 
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-5*BY2WD)) 
			validaddr(sp, 5*BY2WD, 0); 
		ret = (*systab[r0])((ulong*)(sp+BY2WD)); 
1990/1226    
		ret = (*systab[r7])((ulong*)(sp+2*BY2WD)); 
1990/1223    
	} 
1990/1226    
	ur->pc += 4; 
	ur->npc = ur->pc+4; 
1990/1223    
	u->nerrlab = 0; 
	u->p->insyscall = 0; 
	if(r0 == NOTED)	/* ugly hack */ 
1990/1226    
	if(r7 == NOTED)	/* ugly hack */ 
1990/1223    
		noted(&aur);	/* doesn't return */ 
	if(u->nnote){ 
		ur->r0 = ret; 
1990/1226    
		ur->r7 = ret; 
1990/1223    
		notify(ur); 
	} 
	return ret; 
1990/1226    
} 
 
void 
execpc(ulong entry) 
{ 
	((Ureg*)UREGADDR)->pc = entry - 4;		/* syscall advances it */ 
	((Ureg*)UREGADDR)->npc = entry; 
1990/1223    
} 
 
#include "errstr.h" 
1990/1226/sys/src/9/ss/trap.c:35,421990/1227/sys/src/9/ss/trap.c:35,40 (short | long)
1990/1223    
{ 
	static char buf[32];	/* BUG: not reentrant! */ 
 
1990/1226    
	tbr &= 0xFFF; 
	tbr >>= 4; 
	if(tbr < sizeof trapname/sizeof(char*)) 
		return trapname[tbr]; 
	if(tbr == 36) 
1990/1226/sys/src/9/ss/trap.c:57,751990/1227/sys/src/9/ss/trap.c:55,80
1990/1223    
{ 
	int user; 
	char buf[64]; 
1990/1227    
	ulong tbr; 
1990/1223    
 
1990/1227    
	tbr = (ur->tbr&0xFFF)>>4; 
	if(tbr == 30){				/* interrupt 14: counter 1 */ 
		clock(ur); 
		return; 
	} 
 
1990/1226    
	user = !(ur->psr&PSRPSUPER); 
 
/*	if(u) 
1990/1223    
		u->p->pc = ur->pc;		/* BUG */ 
	if(user){ 
1990/1226    
		print("user trap: %s pc=0x%lux\n", excname(ur->tbr), ur->pc); 
1990/1227    
		print("user trap: %s pc=0x%lux\n", excname(tbr), ur->pc); 
1990/1226    
dumpregs(ur); 
for(;;); 
		sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(ur->tbr)); 
1990/1227    
		sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(tbr)); 
1990/1223    
		postnote(u->p, 1, buf, NDebug); 
	}else{ 
1990/1226    
		print("kernel trap: %s pc=0x%lux\n", excname(ur->tbr), ur->pc); 
1990/1227    
		print("kernel trap: %s pc=0x%lux\n", excname(tbr), ur->pc); 
1990/1223    
		dumpregs(ur); 
1990/1226    
for(;;); 
1990/1223    
		exit(); 
1990/1227/sys/src/9/ss/trap.c:58,651990/1231/sys/src/9/ss/trap.c:58,73 (short | long)
1990/1227    
	ulong tbr; 
1990/1223    
 
1990/1227    
	tbr = (ur->tbr&0xFFF)>>4; 
	if(tbr == 30){				/* interrupt 14: counter 1 */ 
1990/1231    
	if(tbr == 16+14){			/* interrupt 14: counter 1 */ 
1990/1227    
		clock(ur); 
1990/1231    
		return; 
	} 
	if(tbr == 16+12){			/* interrupt 12: keyboard and mouse */ 
		duartintr(); 
		return; 
	} 
	if(tbr == 16+5){			/* interrupt 5: lance */ 
		lanceintr(); 
1990/1227    
		return; 
	} 
 
1990/1231/sys/src/9/ss/trap.c:78,861991/0109/sys/src/9/ss/trap.c:78,87 (short | long)
1990/1223    
	if(user){ 
1990/1227    
		print("user trap: %s pc=0x%lux\n", excname(tbr), ur->pc); 
1990/1226    
dumpregs(ur); 
for(;;); 
1990/1227    
		sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(tbr)); 
1991/0109    
print("call postnote\n"); 
1990/1223    
		postnote(u->p, 1, buf, NDebug); 
1991/0109    
print("return from postnote\n"); 
1990/1223    
	}else{ 
1990/1227    
		print("kernel trap: %s pc=0x%lux\n", excname(tbr), ur->pc); 
1990/1223    
		dumpregs(ur); 
1990/1231/sys/src/9/ss/trap.c:87,941991/0109/sys/src/9/ss/trap.c:88,98
1990/1226    
for(;;); 
1990/1223    
		exit(); 
	} 
	if(user && u->nnote) 
1991/0109    
	if(user && u->nnote){ 
		print("notify %d\n", u->p->pid); 
1990/1223    
		notify(ur); 
1991/0109    
		print("notifyed %d\n", u->p->pid); 
	} 
1990/1223    
} 
 
void 
1990/1231/sys/src/9/ss/trap.c:157,1631991/0109/sys/src/9/ss/trap.c:161,167
1990/1223    
	ulong sp; 
 
	lock(&u->p->debug); 
	if(u->nnote==0){ 
1991/0109    
	if(u->nnote == 0){ 
1990/1223    
		unlock(&u->p->debug); 
		return; 
	} 
1990/1231/sys/src/9/ss/trap.c:165,1701991/0109/sys/src/9/ss/trap.c:169,175
1990/1223    
		if(u->note[0].flag == NDebug) 
			pprint("suicide: %s\n", u->note[0].msg); 
    Die: 
1991/0109    
print("suicide: %s\n", u->note[0].msg); 
1990/1223    
		unlock(&u->p->debug); 
		pexit(u->note[0].msg, u->note[0].flag!=NDebug); 
	} 
1991/0109/sys/src/9/ss/trap.c:58,631991/0110/sys/src/9/ss/trap.c:58,67 (short | long)
1990/1227    
	ulong tbr; 
1990/1223    
 
1990/1227    
	tbr = (ur->tbr&0xFFF)>>4; 
1991/0110    
	if(tbr == 16+15){			/* interrupt 14: counter 1 */ 
		faultasync(ur); 
		return; 
	} 
1990/1231    
	if(tbr == 16+14){			/* interrupt 14: counter 1 */ 
1990/1227    
		clock(ur); 
1990/1231    
		return; 
1991/0109/sys/src/9/ss/trap.c:77,871991/0110/sys/src/9/ss/trap.c:81,88
1990/1223    
		u->p->pc = ur->pc;		/* BUG */ 
	if(user){ 
1990/1227    
		print("user trap: %s pc=0x%lux\n", excname(tbr), ur->pc); 
1990/1226    
dumpregs(ur); 
1990/1227    
		sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(tbr)); 
1991/0109    
print("call postnote\n"); 
1990/1223    
		postnote(u->p, 1, buf, NDebug); 
1991/0109    
print("return from postnote\n"); 
1990/1223    
	}else{ 
1990/1227    
		print("kernel trap: %s pc=0x%lux\n", excname(tbr), ur->pc); 
1990/1223    
		dumpregs(ur); 
1991/0109/sys/src/9/ss/trap.c:169,1751991/0110/sys/src/9/ss/trap.c:170,175
1990/1223    
		if(u->note[0].flag == NDebug) 
			pprint("suicide: %s\n", u->note[0].msg); 
    Die: 
1991/0109    
print("suicide: %s\n", u->note[0].msg); 
1990/1223    
		unlock(&u->p->debug); 
		pexit(u->note[0].msg, u->note[0].flag!=NDebug); 
	} 
1991/0110/sys/src/9/ss/trap.c:80,861991/0112/sys/src/9/ss/trap.c:80,85 (short | long)
1990/1226    
/*	if(u) 
1990/1223    
		u->p->pc = ur->pc;		/* BUG */ 
	if(user){ 
1990/1227    
		print("user trap: %s pc=0x%lux\n", excname(tbr), ur->pc); 
		sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(tbr)); 
1990/1223    
		postnote(u->p, 1, buf, NDebug); 
	}else{ 
1991/0110/sys/src/9/ss/trap.c:89,991991/0112/sys/src/9/ss/trap.c:88,95
1990/1226    
for(;;); 
1990/1223    
		exit(); 
	} 
1991/0109    
	if(user && u->nnote){ 
		print("notify %d\n", u->p->pid); 
1991/0112    
	if(user && u->nnote) 
1990/1223    
		notify(ur); 
1991/0109    
		print("notifyed %d\n", u->p->pid); 
	} 
1990/1223    
} 
 
void 
1991/0110/sys/src/9/ss/trap.c:162,1681991/0112/sys/src/9/ss/trap.c:158,164
1990/1223    
	ulong sp; 
 
	lock(&u->p->debug); 
1991/0109    
	if(u->nnote == 0){ 
1991/0112    
	if(u->nnote==0){ 
1990/1223    
		unlock(&u->p->debug); 
		return; 
	} 
1991/0110/sys/src/9/ss/trap.c:188,1931991/0112/sys/src/9/ss/trap.c:184,190
1990/1223    
		*(ulong*)(sp+0*BY2WD) = 0;		/* arg 0 is pc */ 
		ur->usp = sp; 
		ur->pc = (ulong)u->notify; 
1991/0112    
		ur->npc = (ulong)u->notify+4; 
1990/1223    
		u->notified = 1; 
		u->nnote--; 
		memcpy(&u->note[0], &u->note[1], u->nnote*sizeof(Note)); 
1991/0110/sys/src/9/ss/trap.c:208,2131991/0112/sys/src/9/ss/trap.c:205,211
1990/1223    
	} 
	u->notified = 0; 
	memcpy(*urp, u->ureg, sizeof(Ureg)); 
1991/0112    
	(*urp)->r7 = -1;	/* return error from the interrupted call */ 
1990/1223    
	unlock(&u->p->debug); 
	splhi(); 
	rfnote(urp); 
1991/0110/sys/src/9/ss/trap.c:323,3291991/0112/sys/src/9/ss/trap.c:321,326
1990/1226    
execpc(ulong entry) 
{ 
	((Ureg*)UREGADDR)->pc = entry - 4;		/* syscall advances it */ 
	((Ureg*)UREGADDR)->npc = entry; 
1990/1223    
} 
 
#include "errstr.h" 
1991/0112/sys/src/9/ss/trap.c:74,791991/0115/sys/src/9/ss/trap.c:74,81 (short | long)
1990/1231    
		lanceintr(); 
1990/1227    
		return; 
	} 
1991/0115    
	if(tbr == 8)				/* floating point exception */ 
		clearfpintr(); 
1990/1227    
 
1990/1226    
	user = !(ur->psr&PSRPSUPER); 
 
1991/0112/sys/src/9/ss/trap.c:81,861991/0115/sys/src/9/ss/trap.c:83,90
1990/1223    
		u->p->pc = ur->pc;		/* BUG */ 
	if(user){ 
1990/1227    
		sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(tbr)); 
1991/0115    
		if(tbr == 8) 
			sprint(buf+strlen(buf), " FSR %lux", getfsr()); 
1990/1223    
		postnote(u->p, 1, buf, NDebug); 
	}else{ 
1990/1227    
		print("kernel trap: %s pc=0x%lux\n", excname(tbr), ur->pc); 
1991/0112/sys/src/9/ss/trap.c:328,3341991/0115/sys/src/9/ss/trap.c:332,338
1990/1223    
void 
error(int code) 
{ 
	strncpy(u->error, errstrtab[code], NAMELEN); 
1991/0115    
	strncpy(u->error, errstrtab[code], ERRLEN); 
1990/1223    
	nexterror(); 
} 
 
1991/0115/sys/src/9/ss/trap.c:53,991991/01151/sys/src/9/ss/trap.c:53,147 (short | long)
1990/1223    
void 
trap(Ureg *ur) 
{ 
	int user; 
1991/01151    
	int user, x; 
1990/1223    
	char buf[64]; 
1990/1227    
	ulong tbr; 
1990/1223    
 
1990/1227    
	tbr = (ur->tbr&0xFFF)>>4; 
1991/0110    
	if(tbr == 16+15){			/* interrupt 14: counter 1 */ 
		faultasync(ur); 
		return; 
	} 
1990/1231    
	if(tbr == 16+14){			/* interrupt 14: counter 1 */ 
1990/1227    
		clock(ur); 
1990/1231    
		return; 
	} 
	if(tbr == 16+12){			/* interrupt 12: keyboard and mouse */ 
		duartintr(); 
		return; 
	} 
	if(tbr == 16+5){			/* interrupt 5: lance */ 
		lanceintr(); 
1990/1227    
		return; 
	} 
1991/0115    
	if(tbr == 8)				/* floating point exception */ 
		clearfpintr(); 
1990/1227    
                 
1990/1226    
	user = !(ur->psr&PSRPSUPER); 
                 
/*	if(u) 
1991/01151    
	if(u) 
1990/1223    
		u->p->pc = ur->pc;		/* BUG */ 
	if(user){ 
1990/1227    
		sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(tbr)); 
1991/0115    
		if(tbr == 8) 
			sprint(buf+strlen(buf), " FSR %lux", getfsr()); 
1990/1223    
		postnote(u->p, 1, buf, NDebug); 
1991/01151    
	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; 
		} 
1990/1223    
	}else{ 
1990/1227    
		print("kernel trap: %s pc=0x%lux\n", excname(tbr), ur->pc); 
1990/1223    
		dumpregs(ur); 
1990/1226    
for(;;); 
1990/1223    
		exit(); 
1991/01151    
		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); 
1990/1223    
	} 
1991/0112    
	if(user && u->nnote) 
1990/1223    
		notify(ur); 
1991/01151    
    Return: 
	if(user && u && u->p->fpstate == FPinactive) { 
		restfpregs(&u->fpsave); 
		u->p->fpstate = FPactive; 
		ur->psr |= PSREF; 
	} 
1990/1223    
} 
 
void 
1991/0115/sys/src/9/ss/trap.c:272,2901991/01151/sys/src/9/ss/trap.c:320,335
1990/1223    
	u->p->pc = ur->pc; 
1990/1226    
	if(ur->psr & PSRPSUPER) 
1990/1223    
		panic("recursive system call"); 
1990/1226    
#ifdef asdf 
1991/01151    
 
1990/1223    
	/* 
	 * since the system call interface does not 
	 * guarantee anything about registers, but the fpcr is more than 
	 * just a register...  BUG 
1991/01151    
	 * guarantee anything about registers, 
1990/1223    
	 */ 
	fpsave(&u->fpsave); 
	if(u->p->fpstate==FPactive || u->fpsave.type){ 
		fprestore(&initfp); 
1991/01151    
	if(u->p->fpstate == FPactive) { 
1990/1223    
		u->p->fpstate = FPinit; 
		m->fpstate = FPinit; 
1991/01151    
		ur->psr &= ~PSREF; 
1990/1223    
	} 
1990/1226    
#endif 
1991/01151    
 
1990/1223    
	spllo(); 
1990/1226    
	r7 = ur->r7; 
1990/1223    
	sp = ur->usp; 
1991/01151/sys/src/9/ss/trap.c:227,2351991/0318/sys/src/9/ss/trap.c:227,235 (short | long)
1990/1223    
		sp = ur->usp; 
		sp -= sizeof(Ureg); 
		u->ureg = (void*)sp; 
		memcpy((Ureg*)sp, ur, sizeof(Ureg)); 
1991/0318    
		memmove((Ureg*)sp, ur, sizeof(Ureg)); 
1990/1223    
		sp -= ERRLEN; 
		memcpy((char*)sp, u->note[0].msg, ERRLEN); 
1991/0318    
		memmove((char*)sp, u->note[0].msg, ERRLEN); 
1990/1223    
		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* */ 
1991/01151/sys/src/9/ss/trap.c:239,2451991/0318/sys/src/9/ss/trap.c:239,245
1991/0112    
		ur->npc = (ulong)u->notify+4; 
1990/1223    
		u->notified = 1; 
		u->nnote--; 
		memcpy(&u->note[0], &u->note[1], u->nnote*sizeof(Note)); 
1991/0318    
		memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note)); 
1990/1223    
	} 
	unlock(&u->p->debug); 
} 
1991/01151/sys/src/9/ss/trap.c:256,2621991/0318/sys/src/9/ss/trap.c:256,262
1990/1223    
		return; 
	} 
	u->notified = 0; 
	memcpy(*urp, u->ureg, sizeof(Ureg)); 
1991/0318    
	memmove(*urp, u->ureg, sizeof(Ureg)); 
1991/0112    
	(*urp)->r7 = -1;	/* return error from the interrupted call */ 
1990/1223    
	unlock(&u->p->debug); 
	splhi(); 
1991/0318/sys/src/9/ss/trap.c:384,3901991/0322/sys/src/9/ss/trap.c:384,390 (short | long)
1990/1223    
void 
errors(char *err) 
{ 
	strncpy(u->error, err, NAMELEN); 
1991/0322    
	strncpy(u->error, err, ERRLEN); 
1990/1223    
	nexterror(); 
} 
 
1991/0322/sys/src/9/ss/trap.c:214,2191991/0503/sys/src/9/ss/trap.c:214,220 (short | long)
1990/1223    
		unlock(&u->p->debug); 
		return; 
	} 
1991/0503    
print("suicide: %s\n", u->note[0].msg); 
1990/1223    
	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); 
1991/0322/sys/src/9/ss/trap.c:336,3411991/0503/sys/src/9/ss/trap.c:337,343
1990/1223    
 
	u->nerrlab = 0; 
	ret = -1; 
1991/0503    
print("syscall %s %d %d\n", u->p->text, u->p->pid, r7); 
1990/1223    
	if(!waserror()){ 
1990/1226    
		if(r7 >= sizeof systab/BY2WD){ 
			pprint("bad sys call number %d pc %lux\n", r7, ((Ureg*)UREGADDR)->pc); 
1991/0503/sys/src/9/ss/trap.c:214,2201991/0504/sys/src/9/ss/trap.c:214,219 (short | long)
1990/1223    
		unlock(&u->p->debug); 
		return; 
	} 
1991/0503    
print("suicide: %s\n", u->note[0].msg); 
1990/1223    
	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); 
1991/0503/sys/src/9/ss/trap.c:337,3431991/0504/sys/src/9/ss/trap.c:336,341
1990/1223    
 
	u->nerrlab = 0; 
	ret = -1; 
1991/0503    
print("syscall %s %d %d\n", u->p->text, u->p->pid, r7); 
1990/1223    
	if(!waserror()){ 
1990/1226    
		if(r7 >= sizeof systab/BY2WD){ 
			pprint("bad sys call number %d pc %lux\n", r7, ((Ureg*)UREGADDR)->pc); 
1991/0504/sys/src/9/ss/trap.c:270,2761991/0513/sys/src/9/ss/trap.c:270,276 (short | long)
1990/1223    
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; 
1991/0513    
Syscall	sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm; 
1990/1223    
 
Syscall *systab[]={ 
	sysr1, 
1991/0504/sys/src/9/ss/trap.c:279,2851991/0513/sys/src/9/ss/trap.c:279,285
1990/1223    
	syschdir, 
	sysclose, 
	sysdup, 
	sysdeath, 
1991/0513    
	sysalarm, 
1990/1223    
	sysexec, 
	sysexits, 
	sysfork, 
1991/0513/sys/src/9/ss/trap.c:77,831991/0604/sys/src/9/ss/trap.c:77,83 (short | long)
1991/01151    
			clock(ur); 
			break; 
		case 12:			/* keyboard and mouse */ 
			duartintr(); 
1991/0604    
			sccintr(); 
1991/01151    
			break; 
		case 5:				/* lance */ 
			lanceintr(); 
1991/0604/sys/src/9/ss/trap.c:309,3141991/0614/sys/src/9/ss/trap.c:309,315 (short | long)
1990/1223    
long 
syscall(Ureg *aur) 
{ 
1991/0614    
	int i; 
1990/1223    
	long ret; 
	ulong sp; 
1990/1226    
	ulong r7; 
1991/0604/sys/src/9/ss/trap.c:349,3611991/0614/sys/src/9/ss/trap.c:350,368
1990/1223    
			msg = "sys: odd stack"; 
			goto Bad; 
		} 
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-5*BY2WD)) 
			validaddr(sp, 5*BY2WD, 0); 
1991/0614    
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(2+MAXSYSARG)*BY2WD)) 
			validaddr(sp, ((2+MAXSYSARG)*BY2WD), 0); 
1990/1226    
		ret = (*systab[r7])((ulong*)(sp+2*BY2WD)); 
1991/0614    
		poperror(); 
1990/1223    
	} 
1990/1226    
	ur->pc += 4; 
	ur->npc = ur->pc+4; 
1990/1223    
	u->nerrlab = 0; 
1991/0614    
	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"); 
	} 
1990/1223    
	u->p->insyscall = 0; 
1990/1226    
	if(r7 == NOTED)	/* ugly hack */ 
1990/1223    
		noted(&aur);	/* doesn't return */ 
1991/0614/sys/src/9/ss/trap.c:358,3671991/0709/sys/src/9/ss/trap.c:358,367 (short | long)
1990/1226    
	ur->pc += 4; 
	ur->npc = ur->pc+4; 
1991/0614    
	if(u->nerrlab){ 
		print("unbalanced error stack: %d extra\n", u->nerrlab); 
1991/0709    
		print("bad error stack [%d]: %d extra\n", r7, u->nerrlab); 
1991/0614    
		for(i = 0; i < NERR; i++) 
			print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc); 
		panic("bad rob"); 
1991/0709    
		panic("error stack"); 
1991/0614    
	} 
1990/1223    
	u->p->insyscall = 0; 
1990/1226    
	if(r7 == NOTED)	/* ugly hack */ 
1991/0709/sys/src/9/ss/trap.c:264,2701991/0710/sys/src/9/ss/trap.c:264,270 (short | long)
1990/1223    
} 
 
#undef	CHDIR	/* BUG */ 
1990/1226    
#include "/sys/src/libc/sparc9sys/sys.h" 
1991/0710    
#include "/sys/src/libc/9syscall/sys.h" 
1990/1223    
 
typedef long Syscall(ulong*); 
Syscall	sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait; 
1991/0709/sys/src/9/ss/trap.c:377,4031991/0710/sys/src/9/ss/trap.c:377,380
1990/1226    
execpc(ulong entry) 
{ 
	((Ureg*)UREGADDR)->pc = entry - 4;		/* syscall advances it */ 
1990/1223    
} 
                 
#include "errstr.h" 
                 
void 
error(int code) 
{ 
1991/0115    
	strncpy(u->error, errstrtab[code], ERRLEN); 
1990/1223    
	nexterror(); 
} 
                 
void 
errors(char *err) 
{ 
1991/0322    
	strncpy(u->error, err, ERRLEN); 
1990/1223    
	nexterror(); 
} 
                 
                 
void 
nexterror(void) 
{ 
	gotolabel(&u->errlab[--u->nerrlab]); 
} 
1991/0710/sys/src/9/ss/trap.c:174,1871991/0711/sys/src/9/ss/trap.c:174,195 (short | long)
1990/1223    
dumpstack(void) 
{ 
	ulong l, v; 
1991/0711    
	int i; 
1990/1223    
	extern ulong etext; 
1991/0711    
print("no dumpstack\n"); 
return; 
1990/1223    
 
	if(u) 
1991/0711    
	if(u){ 
		i = 0; 
1990/1223    
		for(l=(ulong)&l; l<USERADDR+BY2PG; l+=4){ 
			v = *(ulong*)l; 
			if(KTZERO < v && v < (ulong)&etext) 
				print("%lux=%lux\n", l, v); 
1991/0711    
				print("%lux=%lux  ", l, v); 
			++i; 
			if((i&7) == 0) 
				print("\n"); 
1990/1223    
		} 
1991/0711    
	} 
1990/1223    
} 
 
void 
1991/0710/sys/src/9/ss/trap.c:316,3261991/0711/sys/src/9/ss/trap.c:324,336
1990/1223    
	Ureg *ur; 
	char *msg; 
 
	u->p->insyscall = 1; 
	ur = aur; 
	u->p->pc = ur->pc; 
1990/1226    
	if(ur->psr & PSRPSUPER) 
1991/0711    
	if(ur->psr & PSRPSUPER){ 
		dumpregs(ur); 
1990/1223    
		panic("recursive system call"); 
1991/0711    
	} 
	u->p->insyscall = 1; 
	u->p->pc = ur->pc; 
1991/01151    
 
1990/1223    
	/* 
	 * since the system call interface does not 
1991/0710/sys/src/9/ss/trap.c:330,3371991/0711/sys/src/9/ss/trap.c:340,348
1990/1223    
		u->p->fpstate = FPinit; 
1991/01151    
		ur->psr &= ~PSREF; 
1990/1223    
	} 
1991/01151    
                 
1991/0711    
print("syscall %d\n", ur->r7); 
1990/1223    
	spllo(); 
1991/0711    
print("got low in syscall\n"); 
1990/1226    
	r7 = ur->r7; 
1990/1223    
	sp = ur->usp; 
 
1991/0710/sys/src/9/ss/trap.c:349,3541991/0711/sys/src/9/ss/trap.c:360,369
1990/1223    
			pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); 
			msg = "sys: odd stack"; 
			goto Bad; 
1991/0711    
		} 
		if(((ulong*)ur->pc)[-2] != 0x82206004){	/* new calling convention: look for ADD $-4, SP */ 
			pprint("new system call linkage\n"); 
			sp -= BY2WD; 
1990/1223    
		} 
1991/0614    
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(2+MAXSYSARG)*BY2WD)) 
			validaddr(sp, ((2+MAXSYSARG)*BY2WD), 0); 
1991/0711/sys/src/9/ss/trap.c:325,3341991/0712/sys/src/9/ss/trap.c:325,332 (short | long)
1990/1223    
	char *msg; 
 
	ur = aur; 
1991/0711    
	if(ur->psr & PSRPSUPER){ 
		dumpregs(ur); 
1991/0712    
	if(ur->psr & PSRPSUPER) 
1990/1223    
		panic("recursive system call"); 
1991/0711    
	} 
	u->p->insyscall = 1; 
	u->p->pc = ur->pc; 
1991/01151    
 
1991/0711/sys/src/9/ss/trap.c:340,3481991/0712/sys/src/9/ss/trap.c:338,344
1990/1223    
		u->p->fpstate = FPinit; 
1991/01151    
		ur->psr &= ~PSREF; 
1990/1223    
	} 
1991/0711    
print("syscall %d\n", ur->r7); 
1990/1223    
	spllo(); 
1991/0711    
print("got low in syscall\n"); 
1990/1226    
	r7 = ur->r7; 
1990/1223    
	sp = ur->usp; 
 
1991/0712/sys/src/9/ss/trap.c:357,3691991/0713/sys/src/9/ss/trap.c:357,369 (short | long)
1990/1223    
			msg = "sys: odd stack"; 
			goto Bad; 
1991/0711    
		} 
		if(((ulong*)ur->pc)[-2] != 0x82206004){	/* new calling convention: look for ADD $-4, SP */ 
			pprint("new system call linkage\n"); 
			sp -= BY2WD; 
1991/0713    
		if(((ulong*)ur->pc)[-2] == 0x82206004){	/* new calling convention: look for ADD $-4, SP */ 
			pprint("old system call linkage\n"); 
			sp += BY2WD; 
1990/1223    
		} 
1991/0614    
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(2+MAXSYSARG)*BY2WD)) 
			validaddr(sp, ((2+MAXSYSARG)*BY2WD), 0); 
1990/1226    
		ret = (*systab[r7])((ulong*)(sp+2*BY2WD)); 
1991/0713    
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD)) 
			validaddr(sp, ((1+MAXSYSARG)*BY2WD), 0); 
		ret = (*systab[r7])((ulong*)(sp+1*BY2WD)); 
1991/0614    
		poperror(); 
1990/1223    
	} 
1990/1226    
	ur->pc += 4; 
1991/0713/sys/src/9/ss/trap.c:8,141991/0717/sys/src/9/ss/trap.c:8,14 (short | long)
1990/1223    
#include	"errno.h" 
 
void	notify(Ureg*); 
void	noted(Ureg**); 
1991/0717    
void	noted(Ureg**, ulong); 
1990/1223    
void	rfnote(Ureg**); 
 
1990/1226    
extern	void traplink(void); 
1991/0713/sys/src/9/ss/trap.c:232,2371991/0717/sys/src/9/ss/trap.c:232,238
1990/1223    
	if(!u->notified){ 
		if(!u->notify) 
			goto Die; 
1991/0717    
		u->svpsr = ur->psr; 
1990/1223    
		sp = ur->usp; 
		sp -= sizeof(Ureg); 
		u->ureg = (void*)sp; 
1991/0713/sys/src/9/ss/trap.c:247,2521991/0717/sys/src/9/ss/trap.c:248,254
1991/0112    
		ur->npc = (ulong)u->notify+4; 
1990/1223    
		u->notified = 1; 
		u->nnote--; 
1991/0717    
		memmove(&u->lastnote, &u->note[0], sizeof(Note)); 
1991/0318    
		memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note)); 
1990/1223    
	} 
	unlock(&u->p->debug); 
1991/0713/sys/src/9/ss/trap.c:256,2631991/0717/sys/src/9/ss/trap.c:258,274
1990/1223    
 * Return user to state before notify() 
 */ 
void 
noted(Ureg **urp) 
1991/0717    
noted(Ureg **urp, ulong arg0) 
1990/1223    
{ 
1991/0717    
	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); 
	} 
1990/1223    
	lock(&u->p->debug); 
	if(!u->notified){ 
		unlock(&u->p->debug); 
1991/0713/sys/src/9/ss/trap.c:266,2741991/0717/sys/src/9/ss/trap.c:277,301
1990/1223    
	u->notified = 0; 
1991/0318    
	memmove(*urp, u->ureg, sizeof(Ureg)); 
1991/0112    
	(*urp)->r7 = -1;	/* return error from the interrupted call */ 
1990/1223    
	unlock(&u->p->debug); 
	splhi(); 
	rfnote(urp); 
1991/0717    
	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); 
	} 
1990/1223    
} 
 
#undef	CHDIR	/* BUG */ 
1991/0713/sys/src/9/ss/trap.c:376,3821991/0717/sys/src/9/ss/trap.c:403,409
1991/0614    
	} 
1990/1223    
	u->p->insyscall = 0; 
1990/1226    
	if(r7 == NOTED)	/* ugly hack */ 
1990/1223    
		noted(&aur);	/* doesn't return */ 
1991/0717    
		noted(&aur, *(ulong*)(sp+1*BY2WD));	/* doesn't return */ 
1990/1223    
	if(u->nnote){ 
1990/1226    
		ur->r7 = ret; 
1990/1223    
		notify(ur); 
1991/0717/sys/src/9/ss/trap.c:290,2961991/0718/sys/src/9/ss/trap.c:290,296 (short | long)
1991/0717    
		u->lastnote.flag = NDebug; 
		/* fall through */ 
		 
	case NTERM: 
1991/0718    
	case NDFLT: 
1991/0717    
		if(u->lastnote.flag == NDebug) 
			pprint("suicide: %s\n", u->lastnote.msg); 
		unlock(&u->p->debug); 
1991/0718/sys/src/9/ss/trap.c:235,2401991/0722/sys/src/9/ss/trap.c:235,248 (short | long)
1991/0717    
		u->svpsr = ur->psr; 
1990/1223    
		sp = ur->usp; 
		sp -= sizeof(Ureg); 
1991/0722    
		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(); 
1990/1223    
		u->ureg = (void*)sp; 
1991/0318    
		memmove((Ureg*)sp, ur, sizeof(Ureg)); 
1990/1223    
		sp -= ERRLEN; 
1991/0722/sys/src/9/ss/trap.c:284,2901991/0724/sys/src/9/ss/trap.c:284,289 (short | long)
1990/1223    
	} 
	u->notified = 0; 
1991/0318    
	memmove(*urp, u->ureg, sizeof(Ureg)); 
1991/0112    
	(*urp)->r7 = -1;	/* return error from the interrupted call */ 
1991/0717    
	switch(arg0){ 
	case NCONT: 
		splhi(); 
1991/0722/sys/src/9/ss/trap.c:412,4181991/0724/sys/src/9/ss/trap.c:411,417
1990/1223    
	u->p->insyscall = 0; 
1990/1226    
	if(r7 == NOTED)	/* ugly hack */ 
1991/0717    
		noted(&aur, *(ulong*)(sp+1*BY2WD));	/* doesn't return */ 
1990/1223    
	if(u->nnote){ 
1991/0724    
	if(u->nnote && r7!=FORK){ 
1990/1226    
		ur->r7 = ret; 
1990/1223    
		notify(ur); 
	} 
1991/0724/sys/src/9/ss/trap.c:218,2231991/0727/sys/src/9/ss/trap.c:218,224 (short | long)
1990/1223    
	ulong sp; 
 
	lock(&u->p->debug); 
1991/0727    
	u->p->notepending = 0; 
1991/0112    
	if(u->nnote==0){ 
1990/1223    
		unlock(&u->p->debug); 
		return; 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)