]> rtime.felk.cvut.cz Git - arc.git/blob - arch/hc1x/hcs12d/kernel/irq.c
Fixes to make the os kernel test framework pass.
[arc.git] / arch / hc1x / hcs12d / kernel / irq.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 #include "internal.h"\r
17 #include "irq.h"\r
18 #include "irq_types.h"\r
19 #include "regs.h"\r
20 \r
21 extern void * Irq_VectorTable[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];\r
22 extern uint8 Irq_IsrTypeTable[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];\r
23 \r
24 extern void _start (void);\r
25 \r
26 \r
27 void Irq_Init( void ) {\r
28 \r
29 }\r
30 \r
31 void Irq_EOI( void ) {\r
32 \r
33 }\r
34 \r
35 // IRQ debug information\r
36 // Stores irq nr on erroneous interrupt\r
37 volatile sint16 bad_irq_nr = -1;\r
38 \r
39 // Stores context info on erroneous interrupt\r
40 volatile uint8 bad_irq_context_bank = 0;\r
41 volatile void* bad_irq_context_address = 0;\r
42 \r
43 void bad_irq(uint8_t irq_nr, void **stack) {\r
44 \r
45         // Save number of caught interrupt\r
46         bad_irq_nr = irq_nr;\r
47 \r
48         // Fetch address and page of where we were interrupted, from context\r
49         uint16 bank_and_ccr = (uint16)(*(stack + 4));\r
50         bad_irq_context_bank = (bank_and_ccr & 0xFF00) >> 8;\r
51         bad_irq_context_address = *(stack + 8);\r
52 \r
53         for (;;);\r
54 }\r
55 \r
56 void *Irq_Entry( uint8_t irq_nr, void *stack )\r
57 {\r
58         void* vector = (void *)Irq_VectorTable[irq_nr];\r
59 \r
60         // trap uninitialized interrupts\r
61         if (vector == NULL) {\r
62                 bad_irq(irq_nr, stack);\r
63         }\r
64 \r
65         if( Irq_GetIsrType(irq_nr) == ISR_TYPE_1 ) {\r
66                 // It's a function, just call it.\r
67                 ((func_t)vector)();\r
68                 return stack;\r
69 \r
70         } else {\r
71                 // It's a PCB\r
72                 // Let the kernel handle the rest,\r
73                 return Os_Isr(stack, vector);\r
74         }\r
75 }\r
76 \r
77 /**\r
78  * Attach an ISR type 1 to the interrupt controller.\r
79  *\r
80  * @param entry\r
81  * @param int_ctrl\r
82  * @param vector\r
83  * @param prio\r
84  */\r
85 void Irq_AttachIsr1( void (*entry)(void), void *int_ctrl, uint32_t vector, uint8_t prio) {\r
86         Irq_VectorTable[vector] = (void *)entry;\r
87         Irq_SetIsrType(vector, ISR_TYPE_1);\r
88 }\r
89 \r
90 \r
91 /**\r
92  * Attach a ISR type 2 to the interrupt controller.\r
93  *\r
94  * @param tid\r
95  * @param int_ctrl\r
96  * @param vector\r
97  */\r
98 void Irq_AttachIsr2(TaskType tid,void *int_ctrl,IrqType vector ) {\r
99         OsPcbType *pcb;\r
100 \r
101         pcb = os_find_task(tid);\r
102         Irq_VectorTable[vector] = (void *)pcb;\r
103         Irq_IsrTypeTable[vector] = PROC_ISR2;\r
104 \r
105 }\r
106 \r
107 \r
108 /**\r
109  * Generates a soft interrupt, ie sets pending bit.\r
110  * This could also be implemented using ISPR regs.\r
111  *\r
112  * @param vector\r
113  */\r
114 void Irq_GenerateSoftInt( IrqType vector ) {\r
115         if (vector == IRQ_TYPE_SWI)\r
116         {\r
117             asm("swi");\r
118         }\r
119 \r
120         if (vector == IRQ_TYPE_ILLEGAL)\r
121         {\r
122             asm(".short 0x1830"); // Trap instruction\r
123         }\r
124 }\r
125 \r
126 /**\r
127  * Get the current priority from the interrupt controller.\r
128  * @param cpu\r
129  * @return\r
130  */\r
131 uint8_t Irq_GetCurrentPriority( Cpu_t cpu) {\r
132 \r
133         uint8_t prio = 0;\r
134 \r
135         // SCB_ICSR contains the active vector\r
136         return prio;\r
137 }\r
138 \r
139 \r
140 // #####################  INTERRUPT TRANSLATE TABLE #######################\r
141 #define IRQ_MAP(x) irq_##x\r
142 \r
143 const struct interrupt_vectors __attribute__((section(".vectors"))) vectors =\r
144     {\r
145           pwm_shutdown_handler:\r
146                   IRQ_MAP(pwm_shutdown),\r
147           ptpif_handler:\r
148                   IRQ_MAP(ptpif),\r
149           can4_tx_handler:\r
150                   IRQ_MAP(can4_tx),\r
151           can4_rx_handler:\r
152                   IRQ_MAP(can4_rx),\r
153           can4_err_handler:\r
154                   IRQ_MAP(can4_err),\r
155           can4_wake_handler:\r
156                   IRQ_MAP(can4_wake),\r
157           can3_tx_handler:\r
158                   IRQ_MAP(can3_tx),\r
159           can3_rx_handler:\r
160                   IRQ_MAP(can3_rx),\r
161           can3_err_handler:\r
162                   IRQ_MAP(can3_err),\r
163           can3_wake_handler:\r
164                   IRQ_MAP(can3_wake),\r
165           can2_tx_handler:\r
166                   IRQ_MAP(can2_tx),\r
167           can2_rx_handler:\r
168                   IRQ_MAP(can2_rx),\r
169           can2_err_handler:\r
170                   IRQ_MAP(can2_err),\r
171           can2_wake_handler:\r
172                   IRQ_MAP(can2_wake),\r
173           can1_tx_handler:\r
174                   IRQ_MAP(can1_tx),\r
175           can1_rx_handler:\r
176                   IRQ_MAP(can1_rx),\r
177           can1_err_handler:\r
178                   IRQ_MAP(can1_err),\r
179           can1_wake_handler:\r
180                   IRQ_MAP(can1_wake),\r
181           can0_tx_handler:\r
182                   IRQ_MAP(can0_tx),\r
183           can0_rx_handler:\r
184                   IRQ_MAP(can0_rx),\r
185           can0_err_handler:\r
186                   IRQ_MAP(can0_err),\r
187           can0_wake_handler:\r
188                   IRQ_MAP(can0_wake),\r
189           flash_handler:\r
190                   IRQ_MAP(flash),\r
191           eeprom_handler:\r
192                   IRQ_MAP(eeprom),\r
193           spi2_handler:\r
194                   IRQ_MAP(spi2),\r
195           spi1_handler:\r
196                   IRQ_MAP(spi1),\r
197           iic_handler:\r
198                   IRQ_MAP(iic),\r
199           bdlc_handler:\r
200                   IRQ_MAP(bdlc),\r
201           selfclk_mode_handler:\r
202                   IRQ_MAP(selfclk_mode),\r
203           pll_lock_handler:\r
204                   IRQ_MAP(pll_lock),\r
205           accb_overflow_handler:\r
206                   IRQ_MAP(accb_overflow),\r
207           mccnt_underflow_handler:\r
208                   IRQ_MAP(mccnt_underflow),\r
209           pthif_handler:\r
210                   IRQ_MAP(pthif),\r
211           ptjif_handler:\r
212                   IRQ_MAP(ptjif),\r
213           atd1_handler:\r
214                   IRQ_MAP(atd1),\r
215           atd0_handler:\r
216                   IRQ_MAP(atd0),\r
217           sci1_handler:\r
218                   IRQ_MAP(sci1),\r
219           sci0_handler:\r
220                   IRQ_MAP(sci0),\r
221           spi0_handler:\r
222                   IRQ_MAP(spi0),\r
223 \r
224                   // Timer and Accumulator\r
225           acca_input_handler:\r
226                   IRQ_MAP(acca_input),\r
227           acca_overflow_handler:\r
228                   IRQ_MAP(acca_overflow),\r
229           timer_overflow_handler:\r
230                   IRQ_MAP(timer_overflow),\r
231 \r
232                   // InputCapture/OutputCompare Timers\r
233           tc7_handler:\r
234                   IRQ_MAP(tc7),\r
235           tc6_handler:\r
236                   IRQ_MAP(tc6),\r
237           tc5_handler:\r
238                   IRQ_MAP(tc5),\r
239           tc4_handler:\r
240                   IRQ_MAP(tc4),\r
241           tc3_handler:\r
242                   IRQ_MAP(tc3),\r
243           tc2_handler:\r
244                   IRQ_MAP(tc2),\r
245           tc1_handler:\r
246                   IRQ_MAP(tc1),\r
247           tc0_handler:\r
248                   IRQ_MAP(tc0),\r
249 \r
250                   // External Interrupts\r
251           rtii_handler:\r
252                   IRQ_MAP(rtii),\r
253           irq_handler:\r
254                   IRQ_MAP(irq),\r
255           xirq_handler:\r
256                   IRQ_MAP(xirq),\r
257 \r
258           // Vectors in use\r
259           swi_handler:\r
260                   IRQ_MAP(swi),\r
261 \r
262           illegal_handler:\r
263                   IRQ_MAP(illegal),\r
264           cop_fail_handler:\r
265                   _start,\r
266           cop_clock_handler:\r
267                   IRQ_MAP(cop_clock),\r
268 \r
269   reset_handler:\r
270       _start,\r
271     };\r