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:

 1void
 2trapinit(void)
 3{
 4	Vpage0 *vpage0;
 5	/* set up the exception vectors */
 6	vpage0 = (Vpage0*)HVECTORS;
 7	memmove(vpage0->vectors, vectors, sizeof(vpage0->vectors));
 8	memmove(vpage0->vtable,  vtable,  sizeof(vpage0->vtable));
 9
10	setr13(PsrMfiq, m->fiqstack+nelem(m->fiqstack));
11	setr13(PsrMirq, m->irqstack+nelem(m->irqstack));
12	setr13(PsrMabt, m->abtstack+nelem(m->abtstack));
13	setr13(PsrMund, m->undstack+nelem(m->undstack));
14}
 1TEXT setr13(SB), $-4
 2	MOVW	4(FP), R1
 3	MOVW	CPSR, R2
 4	BIC		$PsrMask, R2, R3
 5	ORR		R0, R3
 6	MOVW	R3, CPSR		/* switch to new mode */
 7	MOVW	SP, R0			/* return old sp */
 8	MOVW	R1, SP			/* install new one */
 9	MOVW	R2, CPSR		/* switch back to old mode */
10	RET

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

 1int rem, itype;
 2
 3if(up != nil)
 4	rem = ((char*)ureg)-up->kstack;
 5else rem = ((char*)ureg)-(char*)m->stack;
 6
 7if(ureg->type != PsrMfiq && rem < 256) {
 8	panic("trap %d stack bytes remaining (%s), "\
 9		  "up=#%8.8lux ureg=#%8.8lux pc=#%8.8ux"
10		  ,rem, up?up->text:"", up, ureg, ureg->pc);
11	for(;;);
12}

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

Adjust ureg->pc

 1itype = ureg->type;
 2/*	All interrupts/exceptions should be resumed at ureg->pc-4,
 3	except for Data Abort which resumes at ureg->pc-8. */
 4if(itype == PsrMabt+1)
 5	ureg->pc -= 8;
 6else ureg->pc -= 4;
 7
 8if(up){
 9	up->pc = ureg->pc;
10	up->dbgreg = ureg;
11}

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

1	default:
2faultpanic:
3		setpanic();
4		dumpregs(ureg);
5		panic("exception %uX %s\n", ureg->type, trapname(ureg->type));
6		break;
7	}

All cases:

 1	switch(itype) {
 2	case PsrMirq:
 3		t = m->ticks;	/* CPU time per proc */
 4		up = nil;		/* no process at interrupt level */
 5
 6		//todo:irq(ureg);
 7
 8		up = m->proc;
 9		preemption(m->ticks - t);
10		break;
11
12	case PsrMund:
13		panic("Undefined instruction");
14		if(*(ulong*)ureg->pc == BREAK && breakhandler) {
15			int s;
16			Proc *p;
17
18			p = up;
19			s = breakhandler(ureg, p);
20			if(s == BrkSched) {
21				p->preempted = 0;
22				sched();
23			} else if(s == BrkNoSched) {
24				/* stop it being preempted until next instruction */
25				p->preempted = 1;
26				if(up)
27					up->dbgreg = 0;
28				return;
29			}
30			break;
31		}
32		if(up == nil) goto faultpanic;
33		spllo();
34		if(waserror()) {
35			if(waslo(ureg->psr) && up->type == Interp)
36				disfault(ureg, up->env->errstr);
37			setpanic();
38			dumpregs(ureg);
39			panic("%s", up->env->errstr);
40		}
41//		if(!fpiarm(ureg)) {
42//			dumpregs(ureg);
43//			sys_trap_error(ureg->type);
44//		}
45		poperror();
46		break;
47
48	case PsrMsvc: /* Jump through 0 or SWI */
49		if(waslo(ureg->psr) && up && up->type == Interp) {
50			spllo();
51			dumpregs(ureg);
52			sys_trap_error(ureg->type);
53		}
54		setpanic();
55		dumpregs(ureg);
56		panic("SVC/SWI exception");
57		break;
58
59	case PsrMabt: /* Prefetch abort */
60		if(catchdbg && catchdbg(ureg, 0))
61			break;
62		/* FALL THROUGH */
63	case PsrMabt+1: /* Data abort */
64		if(waslo(ureg->psr) && up && up->type == Interp) {
65			spllo();
66			faultarm(ureg);
67		}
68		print("Data Abort\n");
69		/* 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: