2 /* -------------------------------- Arctic Core ------------------------------
\r
3 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
5 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\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
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
15 * -------------------------------- Arctic Core ------------------------------*/
\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
27 /* ----------------------------[includes]------------------------------------*/
\r
29 #include "internal.h"
\r
30 #include "asm_book_e.h"
\r
31 #include "irq_types.h"
\r
32 #include "mpc55xx.h"
\r
35 #include "internal.h"
\r
40 #include "irq_config.h"
\r
43 /* ----------------------------[private define]------------------------------*/
\r
44 /* ----------------------------[private macro]-------------------------------*/
\r
45 /* ----------------------------[private typedef]-----------------------------*/
\r
46 typedef void (*f_t)( uint32_t *);
\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
53 static void dumpExceptionRegs( uint32_t *regs );
\r
55 /* ----------------------------[private variables]---------------------------*/
\r
56 extern void exception_tbl(void);
\r
58 /* ----------------------------[private functions]---------------------------*/
\r
59 /* ----------------------------[public functions]----------------------------*/
\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
67 ramlog_str("Test\n");
\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
99 // according to manual
\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
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
118 // Pop the FIFO queue
\r
119 for (int i = 0; i < 15; i++)
\r
121 #if defined(CFG_MPC5516)
\r
122 INTC.EOIR_PRC0.R = 0;
\r
123 #elif defined(CFG_MPC5554) || defined(CFG_MPC5567)
\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
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
149 * @param stack_p Ptr to the current stack.
\r
151 * The stack holds C, NVGPR, VGPR and the EXC frame.
\r
154 void *Irq_Entry( void *stack_p )
\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
161 // Check for exception
\r
162 if( stack[exc_vector]>=CRITICAL_INPUT_EXCEPTION )
\r
164 vector = stack[exc_vector];
\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
175 // save the vector for later
\r
176 stack[exc_vector] = vector;
\r
178 // Check for software interrupt
\r
179 if((uint32_t)vector<=INTC_SSCIR0_CLR7)
\r
182 intc->SSCIR[vector].B.CLR = 1;
\r
187 isr = Os_IsrGet(exc_vector);
\r
188 if( isr->type == ISR_TYPE_1 ) {
\r
192 return Os_Isr(stack, vector);
\r
196 static inline int osPrioToCpuPio( uint8_t prio ) {
\r
198 return prio>>1; // Os have 32 -> 16
\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
205 INTC.PSR[vector].B.PRI = prio;
\r
212 * Attach an ISR type 1 to the interrupt controller.
\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
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
228 /* Invalid vector! */
\r
236 void Irq_EnableVector( int16_t vector, int priority, int core ) {
\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
243 /* Invalid vector! */
\r
258 ISRType Irq_Attach( int vector ) {
\r
260 // uint32_t vector = isrPtr->vector;
\r
262 //Irq_VectorTable[vector] = (uintptr_t)isrPtr;
\r
263 // Irq_IsrTypeTable[vector] = type;
\r
264 // Irq_VectorTable[vector] = isrPtr;
\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
272 /* Invalid vector! */
\r
283 * Attach a ISR type 2 to the interrupt controller.
\r
289 void Irq_AttachIsr2(TaskType tid,void *int_ctrl,IrqType vector ) {
\r
290 OsTaskVarType *pcb;
\r
292 pcb = Os_TaskGet(tid);
\r
293 Irq_VectorTable[vector] = (void *)pcb;
\r
294 Irq_IsrTypeTable[vector] = PROC_ISR2;
\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
301 /* Invalid vector! */
\r
309 * Generates a soft interrupt
\r
312 void Irq_GenerateSoftInt( IrqType vector ) {
\r
313 if( vector > INTC_SSCIR0_CLR7 ) {
\r
317 INTC.SSCIR[vector].B.SET = 1;
\r
321 * Get the current priority from the interrupt controller.
\r
325 uint8_t Irq_GetCurrentPriority( Cpu_t cpu) {
\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
335 #elif defined(CFG_MPC5554)||defined(CFG_MPC5567)
\r
336 prio = INTC.CPR.B.PRI;
\r
346 // Critical Input Interrupt
\r
347 void IVOR0Exception (uint32_t *regs)
\r
349 // srr0 = get_spr(SPR_SRR0);
\r
350 // srr1 = get_spr(SPR_SRR0);
\r
351 // ExceptionSave(srr0,srr1,esr,mcsr,dear;)
\r
354 dumpExceptionRegs(regs);
\r
359 void IVOR1Exception (uint32_t *regs)
\r
362 // MCSR - Source of machine check
\r
363 dumpExceptionRegs(regs);
\r
366 // Data Storage Interrupt
\r
367 void IVOR2Exception (uint32_t *regs)
\r
370 // ESR - lots of stuff
\r
371 dumpExceptionRegs(regs);
\r
375 // Instruction Storage Interrupt
\r
376 void IVOR3Exception (uint32_t *regs)
\r
379 // ESR - lots of stuff
\r
380 dumpExceptionRegs(regs);
\r
384 // Alignment Interrupt
\r
385 void IVOR5Exception (uint32_t *regs)
\r
388 // ESR - lots of stuff
\r
389 // DEAR - Address of load store that caused the exception
\r
390 dumpExceptionRegs(regs);
\r
394 // Program Interrupt
\r
395 void IVOR6Exception (uint32_t *regs)
\r
398 // ESR - lots of stuff
\r
399 dumpExceptionRegs(regs);
\r
403 // Floating point unavailable
\r
404 void IVOR7Exception (uint32_t *regs)
\r
407 dumpExceptionRegs(regs);
\r
412 void IVOR8Exception (uint32_t *regs)
\r
416 dumpExceptionRegs(regs);
\r
420 // Aux processor Unavailable
\r
421 void IVOR9Exception (uint32_t *regs)
\r
423 // Does not happen on e200
\r
424 dumpExceptionRegs(regs);
\r
429 void IVOR10Exception (uint32_t *regs)
\r
437 void IVOR11Exception (uint32_t *regs)
\r
440 dumpExceptionRegs(regs);
\r
445 void IVOR12Exception (uint32_t *regs)
\r
448 dumpExceptionRegs(regs);
\r
452 // Data TLB Error Interrupt
\r
453 void IVOR13Exception (uint32_t *regs)
\r
462 // Instruction TLB Error Interupt
\r
463 void IVOR14Exception (uint32_t *regs)
\r
466 // ESR - MIF set, All others cleared
\r
467 dumpExceptionRegs(regs);
\r
471 void IVOR15Exception (uint32_t *regs)
\r
474 dumpExceptionRegs(regs);
\r
478 #if defined(CFG_CONSOLE_T32) || defined(CFG_CONSOLE_WINIDEA)
\r
482 uint32_t bc; // backchain
\r
500 static void dumpExceptionRegs( uint32_t *regs ) {
\r
501 exc_stack_t *r = (exc_stack_t *)regs;
\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
511 static void dumpExceptionRegs( uint32_t *regs ) {
\r