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

1990/1212/gnot/fault68020.c (diff list | history)

gnot/fault68020.c on 1990/1212
1990/1212    
#include	"u.h" 
#include	"lib.h" 
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"ureg.h" 
#include	"errno.h" 
 
#define	FORMAT(ur)	((((ur)->vo)>>12)&0xF) 
#define	OFFSET(ur)	(((ur)->vo)&0xFFF) 
 
 
struct FFrame 
{ 
	ushort	ireg0;			/* internal register */ 
	ushort	ssw;			/* special status word */ 
	ushort	ipsc;			/* instr. pipe stage c */ 
	ushort	ipsb;			/* instr. pipe stage b */ 
	ulong	addr;			/* data cycle fault address */ 
	ushort	ireg1;			/* internal register */ 
	ushort	ireg2;			/* internal register */ 
	ulong	dob;			/* data output buffer */ 
	ushort	ireg3[4];		/* more stuff */ 
	ulong	baddr;			/* stage b address */ 
	ushort	ireg4[26];		/* more more stuff */ 
}; 
 
/* 
 * SSW bits 
 */ 
#define	RW	0x0040		/* read/write for data cycle */ 
#define	FC	0x8000		/* fault on stage C of instruction pipe */ 
#define	FB	0x4000		/* fault on stage B of instruction pipe */ 
#define	RC	0x2000		/* rerun flag for stage C of instruction pipe */ 
#define	RB	0x1000		/* rerun flag for stage B of instruction pipe */ 
#define	DF	0x0100		/* fault/rerun flag for data cycle */ 
#define	RM	0x0080		/* read-modify-write on data cycle */ 
#define	READ	0x0040 
#define	WRITE	0x0000 
#define	SIZ	0x0030		/* size code for data cycle */ 
#define	FC2	0x0004		/* address space for data cycle */ 
#define	FC1	0x0002 
#define	FC0	0x0001 
 
void 
fault68020(Ureg *ur, FFrame *f) 
{ 
	ulong addr, mmuvirt, mmuphys, n, badvaddr; 
	Seg *s; 
	PTE *opte, *pte, *npte; 
	Orig *o; 
	char *l; 
	Page *pg; 
	KMap *k, *k1; 
	int zeroed = 0, head = 1; 
	int i, user, read, insyscall; 
 
	if(u == 0){ 
		dumpregs(ur); 
		panic("fault u==0 pc=%lux", ur->pc); 
	} 
	insyscall = u->p->insyscall; 
	u->p->insyscall = 1; 
	addr = 0;	/* set */ 
	if(f->ssw & DF) 
		addr = f->addr; 
	else if(FORMAT(ur) == 0xA){ 
		if(f->ssw & FC) 
			addr = ur->pc+2; 
		else if(f->ssw & FB) 
			addr = ur->pc+4; 
		else 
			panic("prefetch pagefault"); 
	}else if(FORMAT(ur) == 0xB){ 
		if(f->ssw & FC) 
			addr = f->baddr-2; 
		else if(f->ssw & FB) 
			addr = f->baddr; 
		else 
			panic("prefetch pagefault"); 
	}else 
		panic("prefetch format"); 
	addr &= VAMASK; 
	badvaddr = addr; 
	addr &= ~(BY2PG-1); 
	user = !(ur->sr&SUPER); 
	if(f->ssw & DF) 
		read = (f->ssw&READ) && !(f->ssw&RM); 
	else 
		read = f->ssw&(FB|FC); 
/* print("fault pc=%lux addr=%lux read %d\n", ur->pc, badvaddr, read); /**/ 
 
	if(fault(addr, read) < 0){ 
		if(user){ 
			pprint("user %s error addr=0x%lux\n", read? "read" : "write", badvaddr); 
			pprint("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->sr, ur->pc, ur->sp); 
			pexit("Suicide", 0); 
		} 
		u->p->state = MMUing; 
		dumpregs(ur); 
		panic("fault: 0x%lux", badvaddr); 
		exit(); 
	} 
	u->p->insyscall = insyscall; 
} 


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