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

1992/0806/ss/faultsparc.c (diff list | history)

1992/0806/sys/src/9/ss/faultsparc.c:1,881992/0812/sys/src/9/ss/faultsparc.c:1,87 (short | long | prev | next)
1990/1223    
#include	"u.h" 
1992/0321    
#include	"../port/lib.h" 
1990/1223    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"ureg.h" 
1992/0111    
#include	"../port/error.h" 
1990/1223    
 
1992/0704    
enum 
{ 
	SE_WRITE	= 0x8000, 
	SE_INV		= 0x0080, 
	SE_PROT		= 0x0040, 
}; 
 
1990/1223    
void 
1990/1226    
faultsparc(Ureg *ur) 
1990/1223    
{ 
	ulong addr, badvaddr; 
1991/0717    
	char buf[ERRLEN]; 
1991/01151    
	int user, read; 
1992/0704    
	ulong tbr, ser; 
1990/1223    
 
1990/1227    
	tbr = (ur->tbr&0xFFF)>>4; 
1990/1226    
	addr = ur->pc;			/* assume instr. exception */ 
1990/1231    
	read = 1; 
	if(tbr == 9){			/* data access exception */ 
		/* 
		 * According to the book, this isn't good enough.  We'll see. 
		 */ 
1992/0806    
		addr = getsysspace(SEVAR); 
		ser = getsysspace(SER); 
1992/0704    
		if(ser&(SE_WRITE|SE_PROT)) 
1990/1231    
			read = 0; 
1990/1226    
	} 
	spllo(); 
1990/1223    
	if(u == 0){ 
		dumpregs(ur); 
1991/01151    
		panic("fault u==0 pc=%lux addr=%lux", ur->pc, addr); 
1990/1223    
	} 
1990/1226    
/*	addr &= VAMASK; /**/ 
1990/1223    
	badvaddr = addr; 
	addr &= ~(BY2PG-1); 
1990/1231    
	user = !(ur->psr&PSRPSUPER); 
1990/1223    
 
	if(fault(addr, read) < 0){ 
		if(user){ 
1991/1218    
			sprint(buf, "sys: trap: fault %s addr=0x%lux", 
				read? "read" : "write", badvaddr); 
1991/0717    
			postnote(u->p, 1, buf, NDebug); 
			return; 
1990/1223    
		} 
		dumpregs(ur); 
		panic("fault: 0x%lux", badvaddr); 
		exit(); 
	} 
1991/01151    
	splhi(); 
1991/0110    
} 
 
void 
faultasync(Ureg *ur) 
{ 
	int user; 
 
1992/0806    
	print("interrupt 15 ASER %lux ASEVAR %lux SER %lux\n", getsysspace(ASER), getsysspace(ASEVAR), getsysspace(SER)); 
1991/0110    
	dumpregs(ur); 
	/* 
	 * Clear interrupt by toggling low bit of interrupt register 
	 */ 
	*intrreg &= ~1; 
	*intrreg |= 1; 
	user = !(ur->psr&PSRPSUPER); 
	if(user) 
		pexit("Suicide", 0); 
	panic("interrupt 15"); 
1990/1226    
} 
 
/* 
 * called in sysfile.c 
 */ 
void 
evenaddr(ulong addr) 
{ 
	if(addr & 3){ 
		postnote(u->p, 1, "sys: odd address", NDebug); 
		error(Ebadarg); 
	} 
1990/1223    
} 


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