]> rtime.felk.cvut.cz Git - arc.git/blob - arch/ppc/mpc55xx/kernel/irq.c
Cleanup of makefiles. Cleanup of merge.
[arc.git] / arch / ppc / mpc55xx / kernel / irq.c
1 \r
2 /* -------------------------------- Arctic Core ------------------------------\r
3  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
4  *\r
5  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
6  *\r
7  * This source code is free software; you can redistribute it and/or modify it\r
8  * under the terms of the GNU General Public License version 2 as published by the\r
9  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
10  *\r
11  * This program is distributed in the hope that it will be useful, but\r
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
14  * for more details.\r
15  * -------------------------------- Arctic Core ------------------------------*/\r
16 \r
17 /* ----------------------------[includes]------------------------------------*/\r
18 /* ----------------------------[private define]------------------------------*/\r
19 /* ----------------------------[private macro]-------------------------------*/\r
20 /* ----------------------------[private typedef]-----------------------------*/\r
21 /* ----------------------------[private function prototypes]-----------------*/\r
22 /* ----------------------------[private variables]---------------------------*/\r
23 /* ----------------------------[private functions]---------------------------*/\r
24 /* ----------------------------[public functions]----------------------------*/\r
25 \r
26 \r
27 /* ----------------------------[includes]------------------------------------*/\r
28 \r
29 #include "internal.h"\r
30 #include "asm_book_e.h"\r
31 #include "irq_types.h"\r
32 #include "mpc55xx.h"\r
33 #include "pcb.h"\r
34 #include "sys.h"\r
35 #include "internal.h"\r
36 #include "task_i.h"\r
37 #include "hooks.h"\r
38 #include "debug.h"\r
39 #include "isr.h"\r
40 #include "irq_config.h"\r
41 #include <stdint.h>\r
42 \r
43 /* ----------------------------[private define]------------------------------*/\r
44 /* ----------------------------[private macro]-------------------------------*/\r
45 /* ----------------------------[private typedef]-----------------------------*/\r
46 typedef void (*f_t)( uint32_t *);\r
47 \r
48 /* ----------------------------[private function prototypes]-----------------*/\r
49 //extern uintptr_t Irq_VectorTable[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];\r
50 //extern uint8 Irq_IsrTypeTable[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];\r
51 //extern const OsIsrConstType *Irq_Map[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];\r
52 \r
53 static void dumpExceptionRegs( uint32_t *regs );\r
54 \r
55 /* ----------------------------[private variables]---------------------------*/\r
56 extern void exception_tbl(void);\r
57 \r
58 /* ----------------------------[private functions]---------------------------*/\r
59 /* ----------------------------[public functions]----------------------------*/\r
60 \r
61 // write 0 to pop INTC stack\r
62 void Irq_Init( void ) {\r
63           // Check alignment for the exception table\r
64           assert(((uint32)exception_tbl & 0xfff)==0);\r
65           set_spr(SPR_IVPR,(uint32)exception_tbl);\r
66 \r
67           ramlog_str("Test\n");\r
68           ramlog_hex(0x10);\r
69           ramlog_dec(20);\r
70 \r
71           // TODO: The 5516 simulator still thinks it's a 5554 so setup the rest\r
72 #if (defined(CFG_SIMULATOR) && defined(CFG_MPC5516)) || defined(CFG_MPC5567) || defined(CFG_MPC5554)\r
73             set_spr(SPR_IVOR0,((uint32_t)&exception_tbl+0x0) );\r
74             set_spr(SPR_IVOR1,((uint32_t)&exception_tbl+0x10) );\r
75             set_spr(SPR_IVOR2,((uint32_t)&exception_tbl+0x20) );\r
76             set_spr(SPR_IVOR3,((uint32_t)&exception_tbl+0x30) );\r
77             set_spr(SPR_IVOR4,((uint32_t)&exception_tbl+0x40) );\r
78             set_spr(SPR_IVOR5,((uint32_t)&exception_tbl+0x50) );\r
79             set_spr(SPR_IVOR6,((uint32_t)&exception_tbl+0x60) );\r
80             set_spr(SPR_IVOR7,((uint32_t)&exception_tbl+0x70) );\r
81             set_spr(SPR_IVOR8,((uint32_t)&exception_tbl+0x80) );\r
82             set_spr(SPR_IVOR9,((uint32_t)&exception_tbl+0x90) );\r
83             set_spr(SPR_IVOR10,((uint32_t)&exception_tbl+0xa0) );\r
84             set_spr(SPR_IVOR11,((uint32_t)&exception_tbl+0xb0) );\r
85             set_spr(SPR_IVOR12,((uint32_t)&exception_tbl+0xc0) );\r
86             set_spr(SPR_IVOR13,((uint32_t)&exception_tbl+0xd0) );\r
87             set_spr(SPR_IVOR14,((uint32_t)&exception_tbl+0xe0) );\r
88 #if defined(CFG_SPE)\r
89             // SPE exceptions...map to dummy\r
90             set_spr(SPR_IVOR32,((uint32_t)&exception_tbl+0xf0) );\r
91             set_spr(SPR_IVOR33,((uint32_t)&exception_tbl+0xf0) );\r
92             set_spr(SPR_IVOR34,((uint32_t)&exception_tbl+0xf0) );\r
93 #endif\r
94 #endif\r
95 \r
96           //\r
97           // Setup INTC\r
98           //\r
99           // according to manual\r
100           //\r
101           // 1. configure VTES_PRC0,VTES_PRC1,HVEN_PRC0 and HVEN_PRC1 in INTC_MCR\r
102           // 2. configure VTBA_PRCx in INTC_IACKR_PRCx\r
103           // 3. raise the PRIx fields and set the PRC_SELx fields to the desired processor in INTC_PSRx_x\r
104           // 4. set the enable bits or clear the mask bits for the peripheral interrupt requests\r
105           // 5. lower PRI in INTC_CPR_PRCx to zero\r
106           // 6. enable processor(s) recognition of interrupts\r
107 \r
108           // Z1 init\r
109 \r
110         #if defined(CFG_MPC5516)\r
111           INTC.MCR.B.HVEN_PRC0 = 0; // Soft vector mode\r
112           INTC.MCR.B.VTES_PRC0 = 0; // 4 byte offset between entries\r
113         #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
114           INTC.MCR.B.HVEN = 0; // Soft vector mode\r
115           INTC.MCR.B.VTES = 0; // 4 byte offset between entries\r
116         #endif\r
117 \r
118           // Pop the FIFO queue\r
119           for (int i = 0; i < 15; i++)\r
120           {\r
121         #if defined(CFG_MPC5516)\r
122             INTC.EOIR_PRC0.R = 0;\r
123         #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
124             INTC.EOIR.R = 0;\r
125         #endif\r
126           }\r
127 \r
128           // Accept interrupts\r
129         #if defined(CFG_MPC5516)\r
130           INTC.CPR_PRC0.B.PRI = 0;\r
131         #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)\r
132           INTC.CPR.B.PRI = 0;\r
133         #endif\r
134 }\r
135 \r
136 void Irq_EOI( void ) {\r
137 #if defined(CFG_MPC5516)\r
138         struct INTC_tag *intc = &INTC;\r
139         intc->EOIR_PRC0.R = 0;\r
140 #elif defined(CFG_MPC5554)||defined(CFG_MPC5567)\r
141         volatile struct INTC_tag *intc = &INTC;\r
142         intc->EOIR.R = 0;\r
143 #endif\r
144 }\r
145 \r
146 \r
147 /**\r
148  *\r
149  * @param stack_p Ptr to the current stack.\r
150  *\r
151  * The stack holds C, NVGPR, VGPR and the EXC frame.\r
152  *\r
153  */\r
154 void *Irq_Entry( void *stack_p )\r
155 {\r
156         uint32_t vector;\r
157         uint32_t *stack = (uint32_t *)stack_p;\r
158         uint32_t exc_vector = (EXC_OFF_FROM_BOTTOM+EXC_VECTOR_OFF)  / sizeof(uint32_t);\r
159         const OsIsrConstType *isr;\r
160 \r
161         // Check for exception\r
162         if( stack[exc_vector]>=CRITICAL_INPUT_EXCEPTION )\r
163         {\r
164                 vector = stack[exc_vector];\r
165         }\r
166         else\r
167         {\r
168 #if defined(CFG_MPC5516)\r
169                 struct INTC_tag *intc = &INTC;\r
170                 vector = (intc->IACKR_PRC0.B.INTVEC_PRC0);\r
171 #elif defined(CFG_MPC5554)||defined(CFG_MPC5567)\r
172                 volatile struct INTC_tag *intc = &INTC;\r
173                 vector = (intc->IACKR.B.INTVEC);\r
174 #endif\r
175                 // save the vector for later\r
176                 stack[exc_vector] = vector;\r
177 \r
178                 // Check for software interrupt\r
179                 if((uint32_t)vector<=INTC_SSCIR0_CLR7)\r
180                 {\r
181                         // Clear soft int\r
182                         intc->SSCIR[vector].B.CLR = 1;\r
183                         asm("mbar 0");\r
184                 }\r
185         }\r
186 \r
187         isr = Os_IsrGet(exc_vector);\r
188         if( isr->type == ISR_TYPE_1 ) {\r
189                 isr->entry();\r
190                 return stack;\r
191         } else {\r
192                 return Os_Isr(stack, vector);\r
193         }\r
194 }\r
195 \r
196 static inline int osPrioToCpuPio( uint8_t prio ) {\r
197         assert(prio<32);\r
198         return prio>>1;         // Os have 32 -> 16\r
199 }\r
200 \r
201 void Irq_SetPriority( Cpu_t cpu,  IrqType vector, uint8_t prio ) {\r
202 #if defined(CFG_MPC5516)\r
203         INTC.PSR[vector].B.PRC_SEL = cpu;\r
204 #endif\r
205         INTC.PSR[vector].B.PRI = prio;\r
206 }\r
207 \r
208 \r
209 \r
210 #if 0\r
211 /**\r
212  * Attach an ISR type 1 to the interrupt controller.\r
213  *\r
214  * @param entry\r
215  * @param int_ctrl\r
216  * @param vector\r
217  * @param prio\r
218  */\r
219 void Irq_AttachIsr1( void (*entry)(void), void *int_ctrl, uint32_t vector,uint8_t prio) {\r
220         Irq_VectorTable[vector] = (void *)entry;\r
221         Irq_SetIsrType(vector, ISR_TYPE_1);\r
222 \r
223         if (vector < INTC_NUMBER_OF_INTERRUPTS) {\r
224                 Irq_SetPriority(CPU_CORE0,vector + IRQ_INTERRUPT_OFFSET, osPrioToCpuPio(prio));\r
225         } else if ((vector >= CRITICAL_INPUT_EXCEPTION) && (vector\r
226                         <= DEBUG_EXCEPTION)) {\r
227         } else {\r
228                 /* Invalid vector! */\r
229                 assert(0);\r
230         }\r
231 \r
232 }\r
233 #endif\r
234 \r
235 \r
236 void Irq_EnableVector( int16_t vector, int priority, int core ) {\r
237 \r
238         if (vector < INTC_NUMBER_OF_INTERRUPTS) {\r
239                 Irq_SetPriority(core,vector + IRQ_INTERRUPT_OFFSET, osPrioToCpuPio(priority));\r
240         } else if ((vector >= CRITICAL_INPUT_EXCEPTION)\r
241                         && (vector<= DEBUG_EXCEPTION)) {\r
242         } else {\r
243                 /* Invalid vector! */\r
244                 assert(0);\r
245         }\r
246 }\r
247 \r
248 \r
249 \r
250 #if 0\r
251 \r
252 /**\r
253  *\r
254  * @param isrPtr\r
255  * @param type\r
256  * @param int_ctrl\r
257  */\r
258 ISRType Irq_Attach( int vector ) {\r
259 //      Os_Sys.isrCnt\r
260 //      uint32_t vector = isrPtr->vector;\r
261 \r
262         //Irq_VectorTable[vector] = (uintptr_t)isrPtr;\r
263 //      Irq_IsrTypeTable[vector] = type;\r
264 //      Irq_VectorTable[vector] = isrPtr;\r
265 \r
266 \r
267         if (vector < INTC_NUMBER_OF_INTERRUPTS) {\r
268                 Irq_SetPriority(Irq_Map[vector]->core ,vector + IRQ_INTERRUPT_OFFSET, osPrioToCpuPio(Irq_Map[vector]->priority));\r
269         } else if ((vector >= CRITICAL_INPUT_EXCEPTION)\r
270                         && (vector<= DEBUG_EXCEPTION)) {\r
271         } else {\r
272                 /* Invalid vector! */\r
273                 assert(0);\r
274         }\r
275 \r
276 \r
277         return;\r
278 }\r
279 #endif\r
280 \r
281 #if 0\r
282 /**\r
283  * Attach a ISR type 2 to the interrupt controller.\r
284  *\r
285  * @param tid\r
286  * @param int_ctrl\r
287  * @param vector\r
288  */\r
289 void Irq_AttachIsr2(TaskType tid,void *int_ctrl,IrqType vector ) {\r
290         OsTaskVarType *pcb;\r
291 \r
292         pcb = Os_TaskGet(tid);\r
293         Irq_VectorTable[vector] = (void *)pcb;\r
294         Irq_IsrTypeTable[vector] = PROC_ISR2;\r
295 \r
296         if (vector < INTC_NUMBER_OF_INTERRUPTS) {\r
297                 Irq_SetPriority(CPU_CORE0,vector + IRQ_INTERRUPT_OFFSET, osPrioToCpuPio(pcb->prio));\r
298         } else if ((vector >= CRITICAL_INPUT_EXCEPTION) && (vector\r
299                         <= DEBUG_EXCEPTION)) {\r
300         } else {\r
301                 /* Invalid vector! */\r
302                 assert(0);\r
303         }\r
304 }\r
305 #endif\r
306 \r
307 \r
308 /**\r
309  * Generates a soft interrupt\r
310  * @param vector\r
311  */\r
312 void Irq_GenerateSoftInt( IrqType vector ) {\r
313         if( vector > INTC_SSCIR0_CLR7 ) {\r
314                 assert(0);\r
315         }\r
316 \r
317         INTC.SSCIR[vector].B.SET = 1;\r
318 }\r
319 \r
320 /**\r
321  * Get the current priority from the interrupt controller.\r
322  * @param cpu\r
323  * @return\r
324  */\r
325 uint8_t Irq_GetCurrentPriority( Cpu_t cpu) {\r
326 \r
327         uint8_t prio = 0;\r
328 \r
329 #if defined(CFG_MPC5516)\r
330         if( cpu == CPU_Z1 ) {\r
331                 prio = INTC.CPR_PRC0.B.PRI;\r
332         } else if ( cpu == CPU_Z0 ) {\r
333                 prio = INTC.CPR_PRC1.B.PRI;\r
334         }\r
335 #elif defined(CFG_MPC5554)||defined(CFG_MPC5567)\r
336         prio = INTC.CPR.B.PRI;\r
337 #endif\r
338 \r
339         return prio;\r
340 }\r
341 \r
342 \r
343 \r
344 void dummy (void);\r
345 \r
346 // Critical Input Interrupt\r
347 void IVOR0Exception (uint32_t *regs)\r
348 {\r
349 //      srr0 = get_spr(SPR_SRR0);\r
350 //      srr1 = get_spr(SPR_SRR0);\r
351 //      ExceptionSave(srr0,srr1,esr,mcsr,dear;)\r
352         // CSRR0, CSSR1\r
353         // Nothing more\r
354         dumpExceptionRegs(regs);\r
355         while (1);\r
356 }\r
357 \r
358 // Machine check\r
359 void IVOR1Exception (uint32_t *regs)\r
360 {\r
361         // CSRR0, CSSR1\r
362         // MCSR - Source of machine check\r
363         dumpExceptionRegs(regs);\r
364    while (1);\r
365 }\r
366 // Data Storage Interrupt\r
367 void IVOR2Exception (uint32_t *regs)\r
368 {\r
369         // SRR0, SRR1\r
370         // ESR - lots of stuff\r
371         dumpExceptionRegs(regs);\r
372    while (1);\r
373 }\r
374 \r
375 // Instruction Storage Interrupt\r
376 void IVOR3Exception (uint32_t *regs)\r
377 {\r
378         // SRR0, SRR1\r
379         // ESR - lots of stuff\r
380         dumpExceptionRegs(regs);\r
381    while (1);\r
382 }\r
383 \r
384 // Alignment Interrupt\r
385 void IVOR5Exception (uint32_t *regs)\r
386 {\r
387         // SRR0, SRR1\r
388         // ESR - lots of stuff\r
389         // DEAR - Address of load store that caused the exception\r
390         dumpExceptionRegs(regs);\r
391    while (1);\r
392 }\r
393 \r
394 // Program Interrupt\r
395 void IVOR6Exception (uint32_t *regs)\r
396 {\r
397         // SRR0, SRR1\r
398         // ESR - lots of stuff\r
399         dumpExceptionRegs(regs);\r
400         while (1);\r
401 }\r
402 \r
403 // Floating point unavailable\r
404 void IVOR7Exception (uint32_t *regs)\r
405 {\r
406         // SRR0, SRR1\r
407         dumpExceptionRegs(regs);\r
408    while (1);\r
409 }\r
410 \r
411 // System call\r
412 void IVOR8Exception (uint32_t *regs)\r
413 {\r
414         // SRR0, SRR1\r
415         // ESR\r
416         dumpExceptionRegs(regs);\r
417         while (1);\r
418 }\r
419 \r
420 // Aux processor Unavailable\r
421 void IVOR9Exception (uint32_t *regs)\r
422 {\r
423         // Does not happen on e200\r
424         dumpExceptionRegs(regs);\r
425         while (1);\r
426 }\r
427 #if 0\r
428 // Decrementer\r
429 void IVOR10Exception (uint32_t *regs)\r
430 {\r
431         // SRR0, SRR1\r
432         while (1);\r
433 }\r
434 #endif\r
435 \r
436 // FIT\r
437 void IVOR11Exception (uint32_t *regs)\r
438 {\r
439         // SRR0, SRR1\r
440         dumpExceptionRegs(regs);\r
441         while (1);\r
442 }\r
443 \r
444 // Watchdog Timer\r
445 void IVOR12Exception (uint32_t *regs)\r
446 {\r
447         // SRR0, SRR1\r
448         dumpExceptionRegs(regs);\r
449         while (1);\r
450 }\r
451 \r
452 // Data TLB Error Interrupt\r
453 void IVOR13Exception (uint32_t *regs)\r
454 {\r
455 \r
456         // SRR0, SRR1\r
457         // ESR - lots\r
458         // DEAR -\r
459         while (1);\r
460 }\r
461 \r
462 // Instruction TLB Error Interupt\r
463 void IVOR14Exception (uint32_t *regs)\r
464 {\r
465         // SRR0, SRR1\r
466         // ESR - MIF set, All others cleared\r
467         dumpExceptionRegs(regs);\r
468         while (1);\r
469 }\r
470 \r
471 void IVOR15Exception (uint32_t *regs)\r
472 {\r
473         // Debug\r
474         dumpExceptionRegs(regs);\r
475         while (1);\r
476 }\r
477 \r
478 #if defined(CFG_CONSOLE_T32) || defined(CFG_CONSOLE_WINIDEA)\r
479 \r
480 typedef struct {\r
481         uint32_t sp;\r
482         uint32_t bc;  // backchain\r
483         uint32_t pad;\r
484         uint32_t srr0;\r
485         uint32_t srr1;\r
486         uint32_t lr;\r
487         uint32_t ctr;\r
488         uint32_t xer;\r
489         uint32_t cr;\r
490         uint32_t esr;\r
491         uint32_t mcsr;\r
492         uint32_t dear;\r
493         uint32_t vector;\r
494         uint32_t r3;\r
495         uint32_t r4;\r
496 } exc_stack_t;\r
497 \r
498 \r
499 \r
500 static void dumpExceptionRegs( uint32_t *regs ) {\r
501         exc_stack_t *r = (exc_stack_t *)regs;\r
502 \r
503         LDEBUG_PRINTF("sp   %08x  srr0 %08x  srr1 %08x\n",r->sp,r->srr0,r->srr1);\r
504         LDEBUG_PRINTF("lr   %08x  ctr  %08x  xer  %08x\n",r->lr,r->ctr,r->xer);\r
505         LDEBUG_PRINTF("cr   %08x  esr  %08x  mcsr %08x\n",r->cr,r->esr,r->mcsr);\r
506         LDEBUG_PRINTF("dear %08x  vec  %08x  r3   %08x\n",r->dear,r->vector,r->r3);\r
507         LDEBUG_PRINTF("r4   %08x\n",r->r4);\r
508 }\r
509 \r
510 #else\r
511 static void dumpExceptionRegs( uint32_t *regs ) {\r
512 }\r
513 #endif\r
514 \r