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

1990/1226/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 | prev | next)
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" 


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