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

1998/0910/pc/trap.c (diff list | history)

1998/0825/sys/src/9/pc/trap.c:12,471998/0910/sys/src/9/pc/trap.c:12,69 (short | long | prev | next)
XXX big interrupt change
rsc Fri Mar 4 12:44:25 2005
1997/0327    
static void debugbpt(Ureg*, void*); 
static void fault386(Ureg*, void*); 
1991/0731    
 
1997/0327    
static Lock irqctllock; 
static Irqctl *irqctl[256]; 
1998/0910    
static Lock vctllock; 
static Vctl *vctl[256]; 
1991/0709    
 
1991/0703    
void 
1997/0327    
intrenable(int v, void (*f)(Ureg*, void*), void* a, int tbdf) 
1998/0910    
intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf) 
1991/0613    
{ 
1998/0806    
	Irq *irq; 
1997/0327    
	Irqctl *ctl; 
1998/0910    
	int vno; 
	Vctl *v; 
1991/0614    
 
1997/0327    
	lock(&irqctllock); 
1998/0806    
	if(irqctl[v] == 0) 
		irqctl[v] = xalloc(sizeof(Irqctl)); 
	ctl = irqctl[v]; 
1998/0910    
	v = xalloc(sizeof(Vctl)); 
	v->isintr = 1; 
	v->irq = irq; 
	v->tbdf = tbdf; 
	v->f = f; 
	v->a = a; 
1998/0806    
 
	if(v >= VectorINTR && arch->intrenable(v, tbdf, ctl) == -1){ 
		if(ctl->irq == nil){ 
			irqctl[v] = nil; 
1997/0327    
			xfree(ctl); 
		} 
1998/0806    
		unlock(&irqctllock); 
		print("intrenable: didn't find v %d, tbdf 0x%uX\n", v, tbdf); 
1998/0910    
	ilock(&vctllock); 
	vno = arch->intrenable(v); 
	//print("irq%d, vno %d\n", irq, vno); 
	if(vno == -1){ 
		iunlock(&vctllock); 
		print("intrenable: couldn't enable irq %d, tbdf 0x%uX\n", irq, tbdf); 
		xfree(v); 
1998/0806    
		return; 
1991/0709    
	} 
1998/0910    
	if(vctl[vno]){ 
		if(vctl[vno]->isr != v->isr || vctl[vno]->eoi != v->eoi) 
			panic("intrenable: irq handler botch: %luX %luX %luX %luX\n", 
				vctl[vno]->isr, v->isr, vctl[vno]->eoi, v->eoi); 
		v->next = vctl[vno]->next; 
	} 
	vctl[vno] = v; 
	iunlock(&vctllock); 
} 
1998/0806    
 
1997/0327    
	irq = xalloc(sizeof(Irq)); 
	irq->f = f; 
	irq->a = a; 
	irq->next = ctl->irq; 
	ctl->irq = irq; 
	unlock(&irqctllock); 
1998/0910    
void 
trapenable(int vno, void (*f)(Ureg*, void*), void* a) 
{ 
	Vctl *v; 
 
	if(vno < 0 || vno >= VectorPIC) 
		panic("trapenable: vno %d\n", vno); 
	v = xalloc(sizeof(Vctl)); 
	v->tbdf = BUSUNKNOWN; 
	v->f = f; 
	v->a = a; 
 
	lock(&vctllock); 
	if(vctl[vno]) 
		v->next = vctl[vno]->next; 
	vctl[vno] = v; 
	unlock(&vctllock); 
1991/0703    
} 
 
1997/0405    
static void 
1998/0825/sys/src/9/pc/trap.c:94,1251998/0910/sys/src/9/pc/trap.c:116,160
1997/1101    
	 * Special traps. 
	 * Syscall() is called directly without going through trap(). 
	 */ 
1997/0327    
	intrenable(VectorBPT, debugbpt, 0, BUSUNKNOWN); 
	intrenable(VectorPF, fault386, 0, BUSUNKNOWN); 
1998/0910    
	trapenable(VectorBPT, debugbpt, 0); 
	trapenable(VectorPF, fault386, 0); 
1997/0405    
 
	nmienable(); 
1991/0703    
} 
 
1998/0320    
static char *excname[] = { 
1994/0722    
	[0]	"divide error", 
	[1]	"debug exception", 
1997/0327    
	[2]	"nonmaskable interrupt", 
1994/0722    
	[3]	"breakpoint", 
	[4]	"overflow", 
	[5]	"bounds check", 
	[6]	"invalid opcode", 
	[7]	"coprocessor not available", 
	[8]	"double fault", 
1997/0327    
	[9]	"coprocessor segment overrun", 
1994/0722    
	[10]	"invalid TSS", 
	[11]	"segment not present", 
	[12]	"stack exception", 
	[13]	"general protection violation", 
	[14]	"page fault", 
	[15]	"15 (reserved)", 
	[16]	"coprocessor error", 
1994/1029    
	[17]	"alignment check", 
1997/0327    
	[18]	"machine check", 
1998/0910    
static char* excname[32] = { 
	"divide error", 
	"debug exception", 
	"nonmaskable interrupt", 
	"breakpoint", 
	"overflow", 
	"bounds check", 
	"invalid opcode", 
	"coprocessor not available", 
	"double fault", 
	"coprocessor segment overrun", 
	"invalid TSS", 
	"segment not present", 
	"stack exception", 
	"general protection violation", 
	"page fault", 
	"15 (reserved)", 
	"coprocessor error", 
	"alignment check", 
	"machine check", 
	"19 (reserved)", 
	"20 (reserved)", 
	"21 (reserved)", 
	"22 (reserved)", 
	"23 (reserved)", 
	"24 (reserved)", 
	"25 (reserved)", 
	"26 (reserved)", 
	"27 (reserved)", 
	"28 (reserved)", 
	"29 (reserved)", 
	"30 (reserved)", 
	"31 (reserved)", 
1991/1113    
}; 
 
1991/0614    
/* 
1998/0825/sys/src/9/pc/trap.c:131,1401998/0910/sys/src/9/pc/trap.c:166,174
1991/0710    
void 
1997/0327    
trap(Ureg* ureg) 
1991/0614    
{ 
1998/0115    
	int i, v, user; 
1998/0910    
	int i, vno, user; 
1991/1113    
	char buf[ERRLEN]; 
1997/0327    
	Irqctl *ctl; 
	Irq *irq; 
1998/0910    
	Vctl *ctl, *v; 
1998/0115    
	Mach *mach; 
1991/0703    
 
1997/1101    
	user = 0; 
1998/0825/sys/src/9/pc/trap.c:143,1631998/0910/sys/src/9/pc/trap.c:177,198
1997/0327    
		up->dbgreg = ureg; 
1997/1101    
	} 
1991/1112    
 
1997/0327    
	v = ureg->trap; 
	if(ctl = irqctl[v]){ 
1998/0910    
	vno = ureg->trap; 
	if(ctl = vctl[vno]){ 
1997/1101    
		if(ctl->isintr){ 
1997/0327    
			m->intr++; 
1997/1101    
			if(ctl->isr) 
				ctl->isr(v); 
1998/0115    
			if(v >= VectorPIC && v <= MaxVectorPIC) 
				m->lastintr = v-VectorPIC; 
1998/0910    
			if(vno >= VectorPIC && vno != VectorSYSCALL) 
				m->lastintr = ctl->irq; 
1997/1101    
		} 
1991/1113    
 
1997/0327    
		for(irq = ctl->irq; irq; irq = irq->next) 
			irq->f(ureg, irq->a); 
1993/0224    
                 
1998/0910    
		if(ctl->isr) 
			ctl->isr(vno); 
		for(v = ctl; v != nil; v = v->next){ 
			if(v->f) 
				v->f(ureg, v->a); 
		} 
1997/0327    
		if(ctl->eoi) 
			ctl->eoi(v); 
1998/0910    
			ctl->eoi(vno); 
1998/0401    
 
1998/0516    
		/*  
		 *  preemptive scheduling.  to limit stack depth, 
1998/0825/sys/src/9/pc/trap.c:165,1711998/0910/sys/src/9/pc/trap.c:200,206
1998/0516    
		 *  the current interrupt before being preempted a 
		 *  second time. 
		 */ 
1998/0401    
		if(ctl->isintr && v != VectorTIMER && v != VectorCLOCK) 
1998/0910    
		if(ctl->isintr && ctl->irq != IrqTIMER && ctl->irq != IrqCLOCK) 
1998/0512    
		if(up && up->state == Running) 
		if(anyhigher()) 
1998/0516    
		if(up->preempted == 0) 
1998/0825/sys/src/9/pc/trap.c:177,1881998/0910/sys/src/9/pc/trap.c:212,223
1998/0605    
			return; 
1998/0516    
		} 
1991/0731    
	} 
1997/0327    
	else if(v <= 16 && user){ 
1998/0910    
	else if(vno <= nelem(excname) && user){ 
1997/0327    
		spllo(); 
		sprint(buf, "sys: trap: %s", excname[v]); 
1998/0910    
		sprint(buf, "sys: trap: %s", excname[vno]); 
1997/0327    
		postnote(up, 1, buf, NDebug); 
	} 
	else if(v >= VectorPIC && v <= MaxVectorPIC){ 
1998/0910    
	else if(vno >= VectorPIC && vno != VectorSYSCALL){ 
1997/0327    
		/* 
		 * An unknown interrupt. 
		 * Check for a default IRQ7. This can happen when 
1998/0825/sys/src/9/pc/trap.c:192,1981998/0910/sys/src/9/pc/trap.c:227,233
1997/0327    
		 * In fact, just ignore all such interrupts. 
		 */ 
1998/0115    
		print("cpu%d: spurious interrupt %d, last %d", 
			m->machno, v-VectorPIC, m->lastintr); 
1998/0910    
			m->machno, vno, m->lastintr); 
1998/0115    
		for(i = 0; i < 32; i++){ 
			if(!(active.machs & (1<<i))) 
				continue; 
1998/0825/sys/src/9/pc/trap.c:206,2121998/0910/sys/src/9/pc/trap.c:241,247
1997/0327    
		return; 
	} 
	else{ 
1998/0320    
		if(v == VectorNMI){ 
1998/0910    
		if(vno == VectorNMI){ 
1998/0401    
			nmienable(); 
			if(m->machno != 0){ 
1998/0825    
				print("cpu%d: PC %8.8luX\n", m->machno, ureg->pc); 
1998/0825/sys/src/9/pc/trap.c:214,2221998/0910/sys/src/9/pc/trap.c:249,257
1998/0401    
			} 
1997/0405    
		} 
1997/0327    
		dumpregs(ureg); 
		if(v < nelem(excname)) 
			panic("%s", excname[v]); 
		panic("unknown trap/intr: %d\n", v); 
1998/0910    
		if(vno < nelem(excname)) 
			panic("%s", excname[vno]); 
		panic("unknown trap/intr: %d\n", vno); 
1997/0327    
	} 
1991/0801    
 
1997/1101    
	if(user && (up->procctl || up->nnote)){ 
1998/0825/sys/src/9/pc/trap.c:335,3481998/0910/sys/src/9/pc/trap.c:370,382
1997/0327    
	spllo(); 
	n = fault(addr, read); 
	if(n < 0){ 
		if(user){ 
			sprint(buf, "sys: trap: fault %s addr=0x%lux", 
				read? "read" : "write", addr); 
			postnote(up, 1, buf, NDebug); 
			return; 
1998/0910    
		if(!user){ 
			dumpregs(ureg); 
			panic("fault: 0x%lux\n", addr); 
1997/0327    
		} 
1998/0731    
		dumpregs(ureg); 
		panic("fault: 0x%lux\n", addr); 
1998/0910    
		sprint(buf, "sys: trap: fault %s addr=0x%lux", 
			read? "read" : "write", addr); 
		postnote(up, 1, buf, NDebug); 
1997/0327    
	} 
	up->insyscall = insyscall; 
} 


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