xref: /inferno-os/os/boot/puma/ebsit.trap.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "../port/lib.h"
3*74a4d8c2SCharles.Forsyth #include "mem.h"
4*74a4d8c2SCharles.Forsyth #include "ebsit.h"
5*74a4d8c2SCharles.Forsyth #include "dat.h"
6*74a4d8c2SCharles.Forsyth #include "fns.h"
7*74a4d8c2SCharles.Forsyth 
8*74a4d8c2SCharles.Forsyth #include "ureg.h"
9*74a4d8c2SCharles.Forsyth 
10*74a4d8c2SCharles.Forsyth int inpanic;
11*74a4d8c2SCharles.Forsyth 
12*74a4d8c2SCharles.Forsyth #define CSR ((ushort *) 0x2000000)
13*74a4d8c2SCharles.Forsyth 
14*74a4d8c2SCharles.Forsyth 
15*74a4d8c2SCharles.Forsyth typedef struct Irqctlr {
16*74a4d8c2SCharles.Forsyth 	uint	addr;
17*74a4d8c2SCharles.Forsyth   	uint	enabled;
18*74a4d8c2SCharles.Forsyth 	struct {
19*74a4d8c2SCharles.Forsyth 		void	(*r)(Ureg*, void*);
20*74a4d8c2SCharles.Forsyth 		void 	*a;
21*74a4d8c2SCharles.Forsyth 	} h[16];
22*74a4d8c2SCharles.Forsyth } Irqctlr;
23*74a4d8c2SCharles.Forsyth 
24*74a4d8c2SCharles.Forsyth static Irqctlr irqctlr;
25*74a4d8c2SCharles.Forsyth 
26*74a4d8c2SCharles.Forsyth void
csrset(int bit)27*74a4d8c2SCharles.Forsyth csrset( int bit )
28*74a4d8c2SCharles.Forsyth {
29*74a4d8c2SCharles.Forsyth static ushort *csr_val = 0x8c;
30*74a4d8c2SCharles.Forsyth 
31*74a4d8c2SCharles.Forsyth 	*csr_val ^= (1 << bit);
32*74a4d8c2SCharles.Forsyth 	putcsr(*csr_val);
33*74a4d8c2SCharles.Forsyth }
34*74a4d8c2SCharles.Forsyth 
35*74a4d8c2SCharles.Forsyth void
intrinit(void)36*74a4d8c2SCharles.Forsyth intrinit( void )
37*74a4d8c2SCharles.Forsyth {
38*74a4d8c2SCharles.Forsyth int offset;
39*74a4d8c2SCharles.Forsyth ulong op;
40*74a4d8c2SCharles.Forsyth 
41*74a4d8c2SCharles.Forsyth 
42*74a4d8c2SCharles.Forsyth 	irqctlr.addr = 1;
43*74a4d8c2SCharles.Forsyth 	irqctlr.enabled = 0;
44*74a4d8c2SCharles.Forsyth 
45*74a4d8c2SCharles.Forsyth 	/* Reset Exception */
46*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _vsvccall) - 0x0)-8) >> 2;
47*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
48*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x0) = op;
49*74a4d8c2SCharles.Forsyth 
50*74a4d8c2SCharles.Forsyth 	/* Undefined Instruction Exception */
51*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _vundcall) - 0x4)-8) >> 2;
52*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
53*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x4) = op;
54*74a4d8c2SCharles.Forsyth 
55*74a4d8c2SCharles.Forsyth 	/* SWI Exception */
56*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _vsvccall) - 0x8)-8) >> 2;
57*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
58*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x8) = op;
59*74a4d8c2SCharles.Forsyth 
60*74a4d8c2SCharles.Forsyth 	/* Prefetch Abort Exception */
61*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _vpabcall) - 0xc)-8) >> 2;
62*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
63*74a4d8c2SCharles.Forsyth 	*((ulong *) 0xc) = op;
64*74a4d8c2SCharles.Forsyth 
65*74a4d8c2SCharles.Forsyth 	/* Data Abort Exception */
66*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _vdabcall) - 0x10)-8) >> 2;
67*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
68*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x10) = op;
69*74a4d8c2SCharles.Forsyth 
70*74a4d8c2SCharles.Forsyth 	/* IRQ Exception */
71*74a4d8c2SCharles.Forsyth 	offset = ((((ulong) _virqcall) - 0x18)-8) >> 2;
72*74a4d8c2SCharles.Forsyth 	op = ( 0xea << 24 ) | offset;
73*74a4d8c2SCharles.Forsyth 	*((ulong *) 0x18) = op;
74*74a4d8c2SCharles.Forsyth 
75*74a4d8c2SCharles.Forsyth 
76*74a4d8c2SCharles.Forsyth }
77*74a4d8c2SCharles.Forsyth 
78*74a4d8c2SCharles.Forsyth void
intrenable(uint addr,int bit,void (* r)(Ureg *,void *),void * a)79*74a4d8c2SCharles.Forsyth intrenable(uint addr, int bit, void (*r)(Ureg*, void*), void* a)
80*74a4d8c2SCharles.Forsyth {
81*74a4d8c2SCharles.Forsyth 	int i;
82*74a4d8c2SCharles.Forsyth 	USED(addr);
83*74a4d8c2SCharles.Forsyth 	for(i = 0; i < 16; i++)
84*74a4d8c2SCharles.Forsyth 		{
85*74a4d8c2SCharles.Forsyth 		if((bit & (1<<i)) == 0)
86*74a4d8c2SCharles.Forsyth 			continue;
87*74a4d8c2SCharles.Forsyth 		irqctlr.h[i].r = r;
88*74a4d8c2SCharles.Forsyth 		irqctlr.h[i].a = a;
89*74a4d8c2SCharles.Forsyth 		irqctlr.enabled |= (1<<i);
90*74a4d8c2SCharles.Forsyth 		if (i < 7)
91*74a4d8c2SCharles.Forsyth 			csrset(i);
92*74a4d8c2SCharles.Forsyth 		}
93*74a4d8c2SCharles.Forsyth 	return;
94*74a4d8c2SCharles.Forsyth }
95*74a4d8c2SCharles.Forsyth 
96*74a4d8c2SCharles.Forsyth int lucifer;					/* Global to store the last CSR (eric) */
97*74a4d8c2SCharles.Forsyth 
98*74a4d8c2SCharles.Forsyth static void
interrupt(Ureg * ureg)99*74a4d8c2SCharles.Forsyth interrupt(Ureg* ureg)
100*74a4d8c2SCharles.Forsyth {
101*74a4d8c2SCharles.Forsyth 	int i, mask;
102*74a4d8c2SCharles.Forsyth 
103*74a4d8c2SCharles.Forsyth  		mask = *CSR;
104*74a4d8c2SCharles.Forsyth 		lucifer = mask;			/* eric */
105*74a4d8c2SCharles.Forsyth 		if(irqctlr.enabled == 0){
106*74a4d8c2SCharles.Forsyth 
107*74a4d8c2SCharles.Forsyth 			return;
108*74a4d8c2SCharles.Forsyth  			}
109*74a4d8c2SCharles.Forsyth 		for(i = 0; i < 16; i++)
110*74a4d8c2SCharles.Forsyth 			{
111*74a4d8c2SCharles.Forsyth 
112*74a4d8c2SCharles.Forsyth 			if((irqctlr.enabled & (1<<i)) == 0)
113*74a4d8c2SCharles.Forsyth 				continue;
114*74a4d8c2SCharles.Forsyth 			if(( mask & (1 << i)) == 0)
115*74a4d8c2SCharles.Forsyth 				continue;
116*74a4d8c2SCharles.Forsyth 			if (!irqctlr.h[i].r)
117*74a4d8c2SCharles.Forsyth 				continue;
118*74a4d8c2SCharles.Forsyth 			(irqctlr.h[i].r)(ureg, irqctlr.h[i].a);
119*74a4d8c2SCharles.Forsyth 			mask &= ~(1 << i);
120*74a4d8c2SCharles.Forsyth 			}
121*74a4d8c2SCharles.Forsyth 
122*74a4d8c2SCharles.Forsyth 		if ((mask) && (mask < 0x90))		/* ignore non-maskable interrupts */
123*74a4d8c2SCharles.Forsyth 			{
124*74a4d8c2SCharles.Forsyth 			print("unknown or unhandled interrupt\n");
125*74a4d8c2SCharles.Forsyth 			panic("unknown or unhandled interrupt: mask=%ux",mask);
126*74a4d8c2SCharles.Forsyth 			}
127*74a4d8c2SCharles.Forsyth 
128*74a4d8c2SCharles.Forsyth }
129*74a4d8c2SCharles.Forsyth 
130*74a4d8c2SCharles.Forsyth static void
dumpregs(Ureg * ureg)131*74a4d8c2SCharles.Forsyth dumpregs(Ureg* ureg)
132*74a4d8c2SCharles.Forsyth {
133*74a4d8c2SCharles.Forsyth 	print("PSR %8.8uX type %2.2uX PC %8.8uX LINK %8.8uX\n",
134*74a4d8c2SCharles.Forsyth 		ureg->psr, ureg->type, ureg->pc, ureg->link);
135*74a4d8c2SCharles.Forsyth 	print("R14 %8.8uX R13 %8.8uX R12 %8.8uX R11 %8.8uX R10 %8.8uX\n",
136*74a4d8c2SCharles.Forsyth 		ureg->r14, ureg->r13, ureg->r12, ureg->r11, ureg->r10);
137*74a4d8c2SCharles.Forsyth 	print("R9  %8.8uX R8  %8.8uX R7  %8.8uX R6  %8.8uX R5  %8.8uX\n",
138*74a4d8c2SCharles.Forsyth 		ureg->r9, ureg->r8, ureg->r7, ureg->r6, ureg->r5);
139*74a4d8c2SCharles.Forsyth 	print("R4  %8.8uX R3  %8.8uX R2  %8.8uX R1  %8.8uX R0  %8.8uX\n",
140*74a4d8c2SCharles.Forsyth 		ureg->r4, ureg->r3, ureg->r2, ureg->r1, ureg->r0);
141*74a4d8c2SCharles.Forsyth 	print("Last Interrupt's CSR: %8.8uX\n",lucifer);
142*74a4d8c2SCharles.Forsyth 	print("CPSR %8.8uX SPSR %8.8uX\n", cpsrr(), spsrr());
143*74a4d8c2SCharles.Forsyth }
144*74a4d8c2SCharles.Forsyth 
145*74a4d8c2SCharles.Forsyth void
dumpstack(void)146*74a4d8c2SCharles.Forsyth dumpstack(void)
147*74a4d8c2SCharles.Forsyth {
148*74a4d8c2SCharles.Forsyth }
149*74a4d8c2SCharles.Forsyth 
150*74a4d8c2SCharles.Forsyth void
exception(Ureg * ureg)151*74a4d8c2SCharles.Forsyth exception(Ureg* ureg)
152*74a4d8c2SCharles.Forsyth {
153*74a4d8c2SCharles.Forsyth 	static Ureg old_ureg;
154*74a4d8c2SCharles.Forsyth 	uint far =0;
155*74a4d8c2SCharles.Forsyth 	uint fsr =0;
156*74a4d8c2SCharles.Forsyth 
157*74a4d8c2SCharles.Forsyth 	static lasttype = 0;
158*74a4d8c2SCharles.Forsyth 
159*74a4d8c2SCharles.Forsyth 	LOWBAT;
160*74a4d8c2SCharles.Forsyth 
161*74a4d8c2SCharles.Forsyth 	USED(far, fsr);
162*74a4d8c2SCharles.Forsyth 
163*74a4d8c2SCharles.Forsyth 	lasttype = ureg->type;
164*74a4d8c2SCharles.Forsyth 
165*74a4d8c2SCharles.Forsyth 	/*
166*74a4d8c2SCharles.Forsyth 	 * All interrupts/exceptions should be resumed at ureg->pc-4,
167*74a4d8c2SCharles.Forsyth 	 * except for Data Abort which resumes at ureg->pc-8.
168*74a4d8c2SCharles.Forsyth 	 */
169*74a4d8c2SCharles.Forsyth 
170*74a4d8c2SCharles.Forsyth 	if(ureg->type == (PsrMabt+1))
171*74a4d8c2SCharles.Forsyth 		ureg->pc -= 8;
172*74a4d8c2SCharles.Forsyth 	else
173*74a4d8c2SCharles.Forsyth 		ureg->pc -= 4;
174*74a4d8c2SCharles.Forsyth 
175*74a4d8c2SCharles.Forsyth 	switch(ureg->type){
176*74a4d8c2SCharles.Forsyth 
177*74a4d8c2SCharles.Forsyth 	case PsrMfiq:				/* (Fast) */
178*74a4d8c2SCharles.Forsyth 		print("Fast\n");
179*74a4d8c2SCharles.Forsyth 		print("We should never be here\n");
180*74a4d8c2SCharles.Forsyth 		while(1);
181*74a4d8c2SCharles.Forsyth 
182*74a4d8c2SCharles.Forsyth 	case PsrMirq:				/* Interrupt Request */
183*74a4d8c2SCharles.Forsyth 		interrupt(ureg);
184*74a4d8c2SCharles.Forsyth 		break;
185*74a4d8c2SCharles.Forsyth 
186*74a4d8c2SCharles.Forsyth 	case PsrMund:				/* Undefined instruction */
187*74a4d8c2SCharles.Forsyth 		print("Undefined instruction\n");
188*74a4d8c2SCharles.Forsyth 	case PsrMsvc:				/* Jump through 0, SWI or reserved trap */
189*74a4d8c2SCharles.Forsyth 		print("SWI/SVC trap\n");
190*74a4d8c2SCharles.Forsyth 	case PsrMabt:				/* Prefetch abort */
191*74a4d8c2SCharles.Forsyth 		print("Prefetch Abort\n");
192*74a4d8c2SCharles.Forsyth 	case PsrMabt+1:				/* Data abort */
193*74a4d8c2SCharles.Forsyth 		print("Data Abort\n");
194*74a4d8c2SCharles.Forsyth 
195*74a4d8c2SCharles.Forsyth 
196*74a4d8c2SCharles.Forsyth 	default:
197*74a4d8c2SCharles.Forsyth 		dumpregs(ureg);
198*74a4d8c2SCharles.Forsyth 		/* panic("exception %uX\n", ureg->type); */
199*74a4d8c2SCharles.Forsyth 		break;
200*74a4d8c2SCharles.Forsyth 	}
201*74a4d8c2SCharles.Forsyth 
202*74a4d8c2SCharles.Forsyth 	LOWBAT;				/* Low bat off after interrupt */
203*74a4d8c2SCharles.Forsyth 
204*74a4d8c2SCharles.Forsyth 	splhi();
205*74a4d8c2SCharles.Forsyth 
206*74a4d8c2SCharles.Forsyth }
207