Lab 14, interrupts, part 3

Now we can study the C part of handling interrupts.
But before we start remember that we need to install stack pointers to appropriate modes:

void
trapinit(void)
{
	Vpage0 *vpage0;
	/* set up the exception vectors */
	vpage0 = (Vpage0*)HVECTORS;
	memmove(vpage0->vectors, vectors, sizeof(vpage0->vectors));
	memmove(vpage0->vtable,  vtable,  sizeof(vpage0->vtable));

	setr13(PsrMfiq, m->fiqstack+nelem(m->fiqstack));
	setr13(PsrMirq, m->irqstack+nelem(m->irqstack));
	setr13(PsrMabt, m->abtstack+nelem(m->abtstack));
	setr13(PsrMund, m->undstack+nelem(m->undstack));
}

TEXT setr13(SB), $-4
	MOVW	4(FP), R1
	MOVW	CPSR, R2
	BIC		$PsrMask, R2, R3
	ORR		R0, R3
	MOVW	R3, CPSR		/* switch to new mode */
	MOVW	SP, R0			/* return old sp */
	MOVW	R1, SP			/* install new one */
	MOVW	R2, CPSR		/* switch back to old mode */
	RET

Have a look at trap(Ureg *).
First worth to check that kernel stack is not overflow, otherwise we have no choice than “deat screen”:

	int rem, itype;

	if(up != nil)
		rem = ((char*)ureg)-up->kstack;
	else rem = ((char*)ureg)-(char*)m->stack;

	if(ureg->type != PsrMfiq && rem < 256) {
		panic("trap %d stack bytes remaining (%s), "\
			  "up=#%8.8lux ureg=#%8.8lux pc=#%8.8ux"
			  ,rem, up?up->text:"", up, ureg, ureg->pc);
		for(;;);
	}

(Later we can use delay() and reboot() in such case to prevent frozing)

Adjust ureg->pc

	itype = ureg->type;
	/*	All interrupts/exceptions should be resumed at ureg->pc-4,
		except for Data Abort which resumes at ureg->pc-8. */
	if(itype == PsrMabt+1)
		ureg->pc -= 8;
	else ureg->pc -= 4;

	if(up){
		up->pc = ureg->pc;
		up->dbgreg = ureg;
	}

Now we can have a switch of type. Break from switch will mean kernel panic:

	default:
faultpanic:
		setpanic();
		dumpregs(ureg);
		panic("exception %uX %s\n", ureg->type, trapname(ureg->type));
		break;
	}

All cases:

	switch(itype) {
	case PsrMirq:
		t = m->ticks;	/* CPU time per proc */
		up = nil;		/* no process at interrupt level */

		//todo:irq(ureg);

		up = m->proc;
		preemption(m->ticks - t);
		break;

	case PsrMund:
		panic("Undefined instruction");
		if(*(ulong*)ureg->pc == BREAK && breakhandler) {
			int s;
			Proc *p;

			p = up;
			s = breakhandler(ureg, p);
			if(s == BrkSched) {
				p->preempted = 0;
				sched();
			} else if(s == BrkNoSched) {
				/* stop it being preempted until next instruction */
				p->preempted = 1;
				if(up)
					up->dbgreg = 0;
				return;
			}
			break;
		}
		if(up == nil) goto faultpanic;
		spllo();
		if(waserror()) {
			if(waslo(ureg->psr) && up->type == Interp)
				disfault(ureg, up->env->errstr);
			setpanic();
			dumpregs(ureg);
			panic("%s", up->env->errstr);
		}
//		if(!fpiarm(ureg)) {
//			dumpregs(ureg);
//			sys_trap_error(ureg->type);
//		}
		poperror();
		break;

	case PsrMsvc: /* Jump through 0 or SWI */
		if(waslo(ureg->psr) && up && up->type == Interp) {
			spllo();
			dumpregs(ureg);
			sys_trap_error(ureg->type);
		}
		setpanic();
		dumpregs(ureg);
		panic("SVC/SWI exception");
		break;

	case PsrMabt: /* Prefetch abort */
		if(catchdbg && catchdbg(ureg, 0))
			break;
		/* FALL THROUGH */
	case PsrMabt+1: /* Data abort */
		if(waslo(ureg->psr) && up && up->type == Interp) {
			spllo();
			faultarm(ureg);
		}
		print("Data Abort\n");
		/* FALL THROUGH */

Check booting that nothing is broken:

## Starting application at 0x00008000 ...
Entered main() at 00009074 with SP=00002FE8
Clearing Mach:  00002000-00002060
Clearing edata: 00065708-0006C830
Conf: top=134217728, npage0=32659, ialloc=26750976, nproc=735

ARM 0 MHz id 410fb767
Inferno OS Fourth Edition (20121207) Vita Nuova
to inifinite loop

FILES:
fns.h
dat.h
intr.s
trap.c
dump.c
main.c
armv6.s

This entry was posted in Blog, Inferno OS, Raspberry Pi, Research. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Clef two-factor authentication