]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/isr.c
Merge with hcs12_mcal
[arc.git] / system / kernel / isr.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 <sys/types.h>\r
17 #include <stdint.h>\r
18 #include <string.h>\r
19 #include "internal.h"\r
20 #include "irq.h"\r
21 #if 0\r
22 \r
23 \r
24 #include <stdint.h>\r
25 #include <stdlib.h>\r
26 #include <assert.h>\r
27 #include <sys/queue.h>\r
28 #include <string.h>\r
29 #include "internal.h"\r
30 \r
31 #endif\r
32 \r
33 \r
34 // TODO: remove. Make soft links or whatever\r
35 #if defined(CFG_ARM_CM3)\r
36 #include "irq_types.h"\r
37 //#include "stm32f10x.h"\r
38 //#include "stm32f10x_arc.h"\r
39 #endif\r
40 \r
41 extern caddr_t *sbrk(int);\r
42 \r
43 #define os_alloc(_x)    sbrk(_x)\r
44 \r
45 OsPcbType * os_alloc_new_pcb( void ) {\r
46         void *h = os_alloc(sizeof(OsPcbType));\r
47         memset(h,0,sizeof(OsPcbType));\r
48         assert(h!=NULL);\r
49         return h;\r
50 }\r
51 \r
52 #if 0\r
53 typedef void (*Os_IsrEntryType)(void);\r
54 \r
55 \r
56 typedef Os_IsrInfo_s {\r
57         Os_IsrEntryType entry;\r
58         uint32_t vector;\r
59         uint8_t priority;\r
60 } Os_IsrInfoType;\r
61 #endif\r
62 \r
63 \r
64 extern TaskType Os_AddTask( OsPcbType *pcb );\r
65 \r
66 static uint8 stackTop = 0x42;\r
67 \r
68 TaskType Os_Arc_CreateIsr( void (*entry)(void ), uint8_t prio, const char *name )\r
69 {\r
70         OsPcbType *pcb = os_alloc_new_pcb();\r
71         strncpy(pcb->name,name,TASK_NAME_SIZE);\r
72         pcb->vector = -1;\r
73         pcb->prio = prio;\r
74         /* TODO: map to interrupt controller priority */\r
75         assert(prio<=OS_TASK_PRIORITY_MAX);\r
76         pcb->proc_type  = PROC_ISR2;\r
77         pcb->state = ST_SUSPENDED;\r
78         pcb->entry = entry;\r
79         pcb->stack.top = &stackTop;\r
80 \r
81         return Os_AddTask(pcb);\r
82 }\r
83 \r
84 \r
85 #if defined(CFG_ARM_CM3)\r
86 extern void Irq_EOI2(void *pc);\r
87 #endif\r
88 \r
89 \r
90 /**\r
91  * Handle ISR type 2 interrupts from interrupt controller.\r
92  *\r
93  * @param stack Ptr to the current stack\r
94  * @param vector The vector that took the interrupt\r
95  */\r
96 void *Os_Isr( void *stack, void *pcb_p ) {\r
97         struct OsPcb *pcb;\r
98         struct OsPcb *preempted_pcb;\r
99 \r
100         os_sys.int_nest_cnt++;\r
101 \r
102         // Save info for preempted pcb\r
103         preempted_pcb = get_curr_pcb();\r
104         preempted_pcb->stack.curr = stack;\r
105         preempted_pcb->state = ST_READY;\r
106         OS_DEBUG(D_TASK,"Preempted %s\n",preempted_pcb->name);\r
107 \r
108         POSTTASKHOOK();\r
109 \r
110         pcb = (struct OsPcb *)pcb_p;\r
111         pcb->state = ST_RUNNING;\r
112         set_curr_pcb(pcb);\r
113 \r
114         PRETASKHOOK();\r
115 \r
116         // We should not get here if we're NON\r
117         if( pcb->scheduling == NON) {\r
118                 // TODO:\r
119                 // assert(0);\r
120                 while(1);\r
121         }\r
122 \r
123 #ifndef CFG_HCS12D\r
124         Irq_Enable();\r
125         pcb->entry();\r
126         Irq_Disable();\r
127 #else\r
128         pcb->entry();\r
129 #endif\r
130 \r
131         /** @req OS368 */\r
132         if( Os_IrqAnyDisabled() ) {\r
133                 Os_IrqClearAll();\r
134                 ERRORHOOK(E_OS_DISABLEDINT);\r
135         }\r
136 \r
137         /** @req OS369 */\r
138         Os_ResourceCheckAndRelease(pcb);\r
139 \r
140         pcb->state = ST_SUSPENDED;\r
141         POSTTASKHOOK();\r
142 \r
143         Irq_EOI();\r
144 \r
145         --os_sys.int_nest_cnt;\r
146 \r
147         // TODO: Check stack check marker....\r
148         // We have preempted a task\r
149         if( (os_sys.int_nest_cnt == 0) && (os_sys.scheduler_lock==0) ) { //&& is_idle_task() ) {\r
150                 /* If we get here:\r
151                  * - the preempted task is saved with large context.\r
152                  * - We are on interrupt stack..( this function )\r
153                  *\r
154                  * if we find a new task:\r
155                  * - just switch in the new context( don't save the old because\r
156                  *   its already saved )\r
157                  */\r
158                 OsPcbType *new_pcb;\r
159                 new_pcb = Os_TaskGetTop();\r
160                 if( new_pcb != preempted_pcb ) {\r
161                         OS_DEBUG(D_TASK,"Found candidate %s\n",new_pcb->name);\r
162 //#warning Os_TaskSwapContextTo should call the pretaskswaphook\r
163 // TODO: This shuould go away!!!!\r
164 #if defined(CFG_ARM_CM3)\r
165                         void *p;\r
166                         p = &&really_ugly;\r
167                         Irq_EOI2(p);\r
168 really_ugly:\r
169 #endif\r
170                         Os_TaskSwapContextTo(NULL,new_pcb);\r
171                 } else {\r
172                         if( new_pcb == NULL ) {\r
173                                 assert(0);\r
174                         }\r
175                         preempted_pcb->state = ST_RUNNING;\r
176                         set_curr_pcb(preempted_pcb);\r
177                 }\r
178         } else {\r
179                 set_curr_pcb(preempted_pcb);\r
180                 PRETASKHOOK();\r
181         }\r
182 \r
183         return stack;\r
184 }\r