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

1991/0614/gnot/trap.c (diff list | history)

gnot/trap.c on 1990/03091
1990/03091    
#include	"u.h" 
#include	"lib.h" 
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"ureg.h" 
#include	"io.h" 
1990/0513    
#include	"errno.h" 
1990/03091    
 
void	notify(Ureg*); 
1991/0503    
void	noted(Ureg*); 
void	rfnote(Ureg*); 
1990/03091    
 
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){ 
1990/1127    
		sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(ur->vo)); 
1990/03091    
		postnote(u->p, 1, buf, NDebug); 
	}else{ 
1990/1127    
		print("kernel trap vo=0x%ux pc=0x%lux\n", ur->vo, ur->pc); 
1990/03091    
		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; 
1991/0503    
		u->svvo = ur->vo; 
		u->svsr = ur->sr; 
1990/0816    
		sp = ur->usp; 
1990/03091    
		sp -= sizeof(Ureg); 
		u->ureg = (void*)sp; 
1991/0318    
		memmove((Ureg*)sp, ur, sizeof(Ureg)); 
1990/03091    
		sp -= ERRLEN; 
1991/0318    
		memmove((char*)sp, u->note[0].msg, ERRLEN); 
1990/03091    
		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 */ 
1990/0816    
		ur->usp = sp; 
1990/03091    
		ur->pc = (ulong)u->notify; 
		u->notified = 1; 
		u->nnote--; 
1991/0318    
		memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note)); 
1990/03091    
	} 
	unlock(&u->p->debug); 
} 
 
/* 
 * Return user to state before notify() 
 */ 
void 
1991/0503    
noted(Ureg *ur) 
1990/03091    
{ 
1991/0503    
	Ureg *nur; 
 
	nur = u->ureg; 
	validaddr(nur->pc, 1, 0); 
	validaddr(nur->usp, BY2WD, 0); 
	if(nur->sr!=u->svsr || nur->vo!=u->svvo){ 
		pprint("bad noted ureg sr %ux vo %ux\n", nur->sr, nur->vo); 
		pexit("Suicide", 0); 
	} 
1990/03091    
	lock(&u->p->debug); 
1990/0619    
	if(!u->notified){ 
		unlock(&u->p->debug); 
		return; 
	} 
1990/03091    
	u->notified = 0; 
1991/0503    
	memmove(ur, u->ureg, sizeof(Ureg)); 
1990/03091    
	unlock(&u->p->debug); 
	splhi(); 
1991/0503    
	rfnote(ur); 
1990/03091    
} 
 
#undef	CHDIR	/* BUG */ 
#include "/sys/src/libc/680209sys/sys.h" 
 
typedef long Syscall(ulong*); 
1990/11211    
Syscall	sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait; 
1990/03091    
Syscall	sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat; 
1990/11211    
Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate; 
1991/0513    
Syscall	sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm; 
1990/03091    
 
Syscall *systab[]={ 
	sysr1, 
1990/11211    
	syserrstr, 
1990/03091    
	sysbind, 
	syschdir, 
	sysclose, 
	sysdup, 
1991/0513    
	sysalarm, 
1990/03091    
	sysexec, 
	sysexits, 
	sysfork, 
	sysforkpgrp, 
	sysfstat, 
1990/11211    
	sysdeath, 
1990/03091    
	sysmount, 
	sysopen, 
	sysread, 
	sysseek, 
	syssleep, 
	sysstat, 
	syswait, 
	syswrite, 
	syspipe, 
	syscreate, 
1990/11211    
	sysdeath, 
1990/03091    
	sysbrk_, 
	sysremove, 
	syswstat, 
	sysfwstat, 
1990/08141    
	sysnotify, 
	sysnoted, 
1990/11211    
	sysdeath,	/* sysfilsys */ 
1990/03091    
}; 
 
long 
syscall(Ureg *aur) 
{ 
1991/0614    
	int i; 
1990/03091    
	long ret; 
	ulong sp; 
	ulong r0; 
	Ureg *ur; 
1990/0513    
	char *msg; 
1990/03091    
 
	u->p->insyscall = 1; 
	ur = aur; 
1990/0312    
	u->p->pc = ur->pc; 
1990/03091    
	if(ur->sr & SUPER) 
		panic("recursive system call"); 
	/* 
	 * since the system call interface does not 
1990/08163    
	 * guarantee anything about registers, but the fpcr is more than 
	 * just a register...  BUG 
1990/03091    
	 */ 
1990/08163    
	splhi(); 
	fpsave(&u->fpsave); 
	if(u->p->fpstate==FPactive || u->fpsave.type){ 
1990/0905    
		fprestore(&initfp); 
1990/08163    
		u->p->fpstate = FPinit; 
		m->fpstate = FPinit; 
1990/03091    
	} 
1990/08163    
	spllo(); 
1990/03091    
	r0 = ur->r0; 
	sp = ur->usp; 
 
	u->nerrlab = 0; 
	ret = -1; 
1990/0511    
	if(!waserror()){ 
1990/0513    
		if(r0 >= sizeof systab/BY2WD){ 
			pprint("bad sys call number %d pc %lux\n", r0, ((Ureg*)UREGADDR)->pc); 
1990/1110    
			msg = "sys: bad sys call"; 
1990/0511    
	    Bad: 
			postnote(u->p, 1, msg, NDebug); 
1990/11211    
			error(Ebadarg); 
1990/0511    
		} 
		if(sp & (BY2WD-1)){ 
			pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); 
1990/1110    
			msg = "sys: odd stack"; 
1990/0511    
			goto Bad; 
		} 
1991/0614    
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD)) 
			validaddr(sp, (1+MAXSYSARG)*BY2WD, 0); 
1990/0515    
		ret = (*systab[r0])((ulong*)(sp+BY2WD)); 
1991/0614    
		poperror(); 
1990/0511    
	} 
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/03091    
	u->p->insyscall = 0; 
	if(r0 == NOTED)	/* ugly hack */ 
1991/0503    
		noted(aur);	/* doesn't return */ 
1990/03091    
	if(u->nnote){ 
		ur->r0 = ret; 
		notify(ur); 
	} 
	return ret; 
} 
 
1990/1226    
void 
execpc(ulong entry) 
{ 
	((Ureg*)UREGADDR)->pc = entry; 
} 
 
1990/11211    
#include "errstr.h" 
 
1990/03091    
void 
1990/11211    
error(int code) 
1990/03091    
{ 
1991/0115    
	strncpy(u->error, errstrtab[code], ERRLEN); 
1990/03091    
	nexterror(); 
} 
1990/11211    
 
void 
errors(char *err) 
{ 
1991/0322    
	strncpy(u->error, err, ERRLEN); 
1990/11211    
	nexterror(); 
} 
 
1990/03091    
 
void 
nexterror(void) 
{ 
	gotolabel(&u->errlab[--u->nerrlab]); 
} 


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