xref: /inferno-os/os/boot/puma/trap.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "boot.h"
2*74a4d8c2SCharles.Forsyth 
3*74a4d8c2SCharles.Forsyth typedef struct IrqEntry {
4*74a4d8c2SCharles.Forsyth 		void	(*r)(Ureg*, void*);
5*74a4d8c2SCharles.Forsyth 		void 	*a;
6*74a4d8c2SCharles.Forsyth } IrqEntry;
7*74a4d8c2SCharles.Forsyth 
8*74a4d8c2SCharles.Forsyth IrqEntry Irq[V_MAXNUM+1];
9*74a4d8c2SCharles.Forsyth 
10*74a4d8c2SCharles.Forsyth static void dumpstk(ulong *);
11*74a4d8c2SCharles.Forsyth void dumpregs(Ureg* ureg);
12*74a4d8c2SCharles.Forsyth 
13*74a4d8c2SCharles.Forsyth void
setvec(int v,void (* f)(Ureg *,void *),void * a)14*74a4d8c2SCharles.Forsyth setvec(int v, void (*f)(Ureg*, void*), void* a)
15*74a4d8c2SCharles.Forsyth {
16*74a4d8c2SCharles.Forsyth 	if(v < 0 || v >= V_MAXNUM)
17*74a4d8c2SCharles.Forsyth 		panic("setvec: interrupt source %d out of range\n", v);
18*74a4d8c2SCharles.Forsyth 	Irq[v].r = f;
19*74a4d8c2SCharles.Forsyth 	Irq[v].a = a;
20*74a4d8c2SCharles.Forsyth }
21*74a4d8c2SCharles.Forsyth 
22*74a4d8c2SCharles.Forsyth ulong irqstack[64];
23*74a4d8c2SCharles.Forsyth ulong fiqstack[64];
24*74a4d8c2SCharles.Forsyth ulong abtstack[64];
25*74a4d8c2SCharles.Forsyth ulong undstack[64];
26*74a4d8c2SCharles.Forsyth 
27*74a4d8c2SCharles.Forsyth static void
safeintr(Ureg *,void * a)28*74a4d8c2SCharles.Forsyth safeintr(Ureg*, void *a)
29*74a4d8c2SCharles.Forsyth {
30*74a4d8c2SCharles.Forsyth 	int v = (int)a;
31*74a4d8c2SCharles.Forsyth //	print("spurious interrupt %d\n", v);
32*74a4d8c2SCharles.Forsyth 	USED(v);
33*74a4d8c2SCharles.Forsyth }
34*74a4d8c2SCharles.Forsyth 
35*74a4d8c2SCharles.Forsyth void
trapinit(void)36*74a4d8c2SCharles.Forsyth trapinit(void)
37*74a4d8c2SCharles.Forsyth {
38*74a4d8c2SCharles.Forsyth 	int offset;
39*74a4d8c2SCharles.Forsyth 	ulong op;
40*74a4d8c2SCharles.Forsyth 	int v;
41*74a4d8c2SCharles.Forsyth 	int s;
42*74a4d8c2SCharles.Forsyth 
43*74a4d8c2SCharles.Forsyth 	s = splhi();
44*74a4d8c2SCharles.Forsyth 
45*74a4d8c2SCharles.Forsyth 	/* set up stacks for various exceptions */
46*74a4d8c2SCharles.Forsyth 	setr13(PsrMirq, irqstack+nelem(irqstack)-1);
47*74a4d8c2SCharles.Forsyth 	setr13(PsrMfiq, fiqstack+nelem(fiqstack)-1);
48*74a4d8c2SCharles.Forsyth 	setr13(PsrMabt, abtstack+nelem(abtstack)-1);
49*74a4d8c2SCharles.Forsyth 	setr13(PsrMund, undstack+nelem(undstack)-1);
50*74a4d8c2SCharles.Forsyth 
51*74a4d8c2SCharles.Forsyth 	for(v = 0; v <= V_MAXNUM; v++) {
52*74a4d8c2SCharles.Forsyth 		Irq[v].r = safeintr;
53*74a4d8c2SCharles.Forsyth 		Irq[v].a = (void *)v;
54*74a4d8c2SCharles.Forsyth 	}
55*74a4d8c2SCharles.Forsyth 
56*74a4d8c2SCharles.Forsyth 	/* Reset Exception */
57*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _vsvccall) - 0x0)-8) >> 2;
58*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
59*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x0) = op;
60*74a4d8c2SCharles.Forsyth 
61*74a4d8c2SCharles.Forsyth 	/* Undefined Instruction Exception */
62*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _vundcall) - 0x4)-8) >> 2;
63*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
64*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x4) = op;
65*74a4d8c2SCharles.Forsyth 
66*74a4d8c2SCharles.Forsyth 	/* SWI Exception */
67*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _vsvccall) - 0x8)-8) >> 2;
68*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
69*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x8) = op;
70*74a4d8c2SCharles.Forsyth 
71*74a4d8c2SCharles.Forsyth 	/* Prefetch Abort Exception */
72*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _vpabcall) - 0xc)-8) >> 2;
73*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
74*74a4d8c2SCharles.Forsyth 	*((ulong *) 0xc) = op;
75*74a4d8c2SCharles.Forsyth 
76*74a4d8c2SCharles.Forsyth 	/* Data Abort Exception */
77*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _vdabcall) - 0x10)-8) >> 2;
78*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
79*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x10) = op;
80*74a4d8c2SCharles.Forsyth 
81*74a4d8c2SCharles.Forsyth 	/* IRQ Exception */
82*74a4d8c2SCharles.Forsyth  	offset = ((((ulong) _virqcall) - 0x18)-8) >> 2;
83*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
84*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x18) = op;
85*74a4d8c2SCharles.Forsyth 
86*74a4d8c2SCharles.Forsyth 	/* FIQ Exception */
87*74a4d8c2SCharles.Forsyth  	offset = ((((ulong) _vfiqcall) - 0x1c)-8) >> 2;
88*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
89*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x1c) = op;
90*74a4d8c2SCharles.Forsyth 
91*74a4d8c2SCharles.Forsyth 
92*74a4d8c2SCharles.Forsyth 	flushIcache();
93*74a4d8c2SCharles.Forsyth 	writeBackDC();
94*74a4d8c2SCharles.Forsyth 	flushDcache();
95*74a4d8c2SCharles.Forsyth 	flushIcache();
96*74a4d8c2SCharles.Forsyth 	drainWBuffer();
97*74a4d8c2SCharles.Forsyth 
98*74a4d8c2SCharles.Forsyth 	splx(s);
99*74a4d8c2SCharles.Forsyth }
100*74a4d8c2SCharles.Forsyth 
101*74a4d8c2SCharles.Forsyth /*
102*74a4d8c2SCharles.Forsyth  *  trap is called splhi().
103*74a4d8c2SCharles.Forsyth  */
104*74a4d8c2SCharles.Forsyth 
105*74a4d8c2SCharles.Forsyth void
trap(Ureg * ureg)106*74a4d8c2SCharles.Forsyth trap(Ureg* ureg)
107*74a4d8c2SCharles.Forsyth {
108*74a4d8c2SCharles.Forsyth 	ushort mask;
109*74a4d8c2SCharles.Forsyth 	IrqEntry *ip;
110*74a4d8c2SCharles.Forsyth 
111*74a4d8c2SCharles.Forsyth 	/*
112*74a4d8c2SCharles.Forsyth 	 * All interrupts/exceptions should be resumed at ureg->pc-4,
113*74a4d8c2SCharles.Forsyth 	 * except for Data Abort which resumes at ureg->pc-8.
114*74a4d8c2SCharles.Forsyth 	 */
115*74a4d8c2SCharles.Forsyth 	ureg->pc -= 4;
116*74a4d8c2SCharles.Forsyth 
117*74a4d8c2SCharles.Forsyth 	switch(ureg->type) {
118*74a4d8c2SCharles.Forsyth 	case PsrMirq:				/* Interrupt Request */
119*74a4d8c2SCharles.Forsyth 		mask = *(uchar*)HARI1 | ((*(uchar*)HARI2) << 8);
120*74a4d8c2SCharles.Forsyth 		ip = Irq;
121*74a4d8c2SCharles.Forsyth 		while (mask != 0) {
122*74a4d8c2SCharles.Forsyth 			if(mask&1)
123*74a4d8c2SCharles.Forsyth 				ip->r(ureg, ip->a);
124*74a4d8c2SCharles.Forsyth 			ip++;
125*74a4d8c2SCharles.Forsyth 			mask >>= 1;
126*74a4d8c2SCharles.Forsyth 		}
127*74a4d8c2SCharles.Forsyth 		break;
128*74a4d8c2SCharles.Forsyth 
129*74a4d8c2SCharles.Forsyth 	case PsrMfiq:					/* FIQ */
130*74a4d8c2SCharles.Forsyth 		mask = *(uchar*)HARI1 & HARI1_FIQ_MASK;
131*74a4d8c2SCharles.Forsyth 		ip = Irq;
132*74a4d8c2SCharles.Forsyth 		while (mask != 0) {
133*74a4d8c2SCharles.Forsyth 			if(mask&1)
134*74a4d8c2SCharles.Forsyth 				ip->r(ureg, ip->a);
135*74a4d8c2SCharles.Forsyth 			ip++;
136*74a4d8c2SCharles.Forsyth 			mask >>= 1;
137*74a4d8c2SCharles.Forsyth 		}
138*74a4d8c2SCharles.Forsyth 		break;
139*74a4d8c2SCharles.Forsyth 
140*74a4d8c2SCharles.Forsyth 	case PsrMund:			/* Undefined instruction */
141*74a4d8c2SCharles.Forsyth 		dumpregs(ureg);
142*74a4d8c2SCharles.Forsyth 		panic("Undefined Instruction Exception\n");
143*74a4d8c2SCharles.Forsyth 		break;
144*74a4d8c2SCharles.Forsyth 
145*74a4d8c2SCharles.Forsyth 	case PsrMsvc:				/* Jump through 0 or SWI  */
146*74a4d8c2SCharles.Forsyth 		dumpregs(ureg);
147*74a4d8c2SCharles.Forsyth 		panic("SVC/SWI Exception\n");
148*74a4d8c2SCharles.Forsyth 		break;
149*74a4d8c2SCharles.Forsyth 
150*74a4d8c2SCharles.Forsyth 	case PsrMabt:					/* Prefetch abort */
151*74a4d8c2SCharles.Forsyth 		ureg->pc -= 4;
152*74a4d8c2SCharles.Forsyth 		/* FALLTHROUGH */
153*74a4d8c2SCharles.Forsyth 
154*74a4d8c2SCharles.Forsyth 	case PsrMabt+1:	{				/* Data abort */
155*74a4d8c2SCharles.Forsyth 		uint far =0;
156*74a4d8c2SCharles.Forsyth 		uint fsr =0;
157*74a4d8c2SCharles.Forsyth 
158*74a4d8c2SCharles.Forsyth 		USED(far,fsr);
159*74a4d8c2SCharles.Forsyth 		fsr = 0;	/*mmuregr(CpFSR);*/
160*74a4d8c2SCharles.Forsyth 		far = 0;	/*mmuregr(CpFAR);	*/
161*74a4d8c2SCharles.Forsyth 		if (ureg->type == PsrMabt)
162*74a4d8c2SCharles.Forsyth 			print("Prefetch Abort/");
163*74a4d8c2SCharles.Forsyth 		print("Data Abort\n");
164*74a4d8c2SCharles.Forsyth 
165*74a4d8c2SCharles.Forsyth 		print("Data Abort: FSR %8.8uX FAR %8.8uX\n", fsr, far);
166*74a4d8c2SCharles.Forsyth 		/* FALLTHROUGH */
167*74a4d8c2SCharles.Forsyth 	}
168*74a4d8c2SCharles.Forsyth 	default:
169*74a4d8c2SCharles.Forsyth 		dumpregs(ureg);
170*74a4d8c2SCharles.Forsyth 		panic("exception %uX\n", ureg->type);
171*74a4d8c2SCharles.Forsyth 		break;
172*74a4d8c2SCharles.Forsyth 	}
173*74a4d8c2SCharles.Forsyth 
174*74a4d8c2SCharles.Forsyth 	splhi();
175*74a4d8c2SCharles.Forsyth }
176*74a4d8c2SCharles.Forsyth 
177*74a4d8c2SCharles.Forsyth void
dumpregs(Ureg * ureg)178*74a4d8c2SCharles.Forsyth dumpregs(Ureg* ureg)
179*74a4d8c2SCharles.Forsyth {
180*74a4d8c2SCharles.Forsyth 	print("PSR %8.8uX type %2.2uX PC %8.8uX LINK %8.8uX\n",
181*74a4d8c2SCharles.Forsyth 		ureg->psr, ureg->type, ureg->pc, ureg->link);
182*74a4d8c2SCharles.Forsyth 	print("R14 %8.8uX R13 %8.8uX R12 %8.8uX R11 %8.8uX R10 %8.8uX\n",
183*74a4d8c2SCharles.Forsyth 		ureg->r14, ureg->r13, ureg->r12, ureg->r11, ureg->r10);
184*74a4d8c2SCharles.Forsyth 	print("R9  %8.8uX R8  %8.8uX R7  %8.8uX R6  %8.8uX R5  %8.8uX\n",
185*74a4d8c2SCharles.Forsyth 		ureg->r9, ureg->r8, ureg->r7, ureg->r6, ureg->r5);
186*74a4d8c2SCharles.Forsyth 	print("R4  %8.8uX R3  %8.8uX R2  %8.8uX R1  %8.8uX R0  %8.8uX\n",
187*74a4d8c2SCharles.Forsyth 		ureg->r4, ureg->r3, ureg->r2, ureg->r1, ureg->r0);
188*74a4d8c2SCharles.Forsyth 	print("Stack is at: %8.8uX\n", ureg);
189*74a4d8c2SCharles.Forsyth /*	print("CPSR %8.8uX SPSR %8.8uX\n", cpsrr(), spsrr());*/
190*74a4d8c2SCharles.Forsyth }
191