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