]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/isr.c
Added T32 simulator support for cortex r4
[arc.git] / system / kernel / isr.c
1 /* -------------------------------- Arctic Core ------------------------------
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com
3  *
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
5  *
6  * This source code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by the
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  * -------------------------------- Arctic Core ------------------------------*/
15
16 #include <sys/types.h>
17 #include <stdint.h>
18 #include <string.h>
19 #include "internal.h"
20 #include "irq.h"
21 #if 0
22
23
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include <assert.h>
27 #include <sys/queue.h>
28 #include <string.h>
29 #include "internal.h"
30
31 #endif
32
33
34 // TODO: remove. Make soft links or whatever
35 #if defined(CFG_ARM_CM3)
36 #include "irq_types.h"
37 //#include "stm32f10x.h"
38 //#include "stm32f10x_arc.h"
39 #endif
40
41 extern caddr_t *sbrk(int);
42
43 #define os_alloc(_x)    sbrk(_x)
44
45 OsPcbType * os_alloc_new_pcb( void ) {
46         void *h = os_alloc(sizeof(OsPcbType));
47         memset(h,0,sizeof(OsPcbType));
48         assert(h!=NULL);
49         return h;
50 }
51
52 #if 0
53 typedef void (*Os_IsrEntryType)(void);
54
55
56 typedef Os_IsrInfo_s {
57         Os_IsrEntryType entry;
58         uint32_t vector;
59         uint8_t priority;
60 } Os_IsrInfoType;
61 #endif
62
63
64 extern TaskType Os_AddTask( OsPcbType *pcb );
65
66 static uint8 stackTop = 0x42;
67
68 /**
69  * Creates an ISR dynamically
70  * @param entry
71  * @param prio
72  * @param name
73  *
74  * @return The PID of the ISR created
75  */
76 TaskType Os_Arc_CreateIsr( void (*entry)(void ), uint8_t prio, const char *name )
77 {
78         OsPcbType *pcb = os_alloc_new_pcb();
79         strncpy(pcb->name,name,TASK_NAME_SIZE);
80         pcb->vector = -1;
81         pcb->prio = prio;
82         /* TODO: map to interrupt controller priority */
83         assert(prio<=OS_TASK_PRIORITY_MAX);
84         pcb->proc_type  = PROC_ISR2;
85         pcb->state = ST_SUSPENDED;
86         pcb->entry = entry;
87         pcb->stack.top = &stackTop;
88
89         return Os_AddTask(pcb);
90 }
91
92
93 #if defined(CFG_ARM_CM3)
94 extern void Irq_EOI2( void );
95 #endif
96
97
98 /**
99  * Handle ISR type 2 interrupts from interrupt controller.
100  *
101  * @param stack Ptr to the current stack
102  * @param vector The vector that took the interrupt
103  */
104 void *Os_Isr( void *stack, void *pcb_p ) {
105         struct OsPcb *pcb;
106         struct OsPcb *preempted_pcb;
107
108         os_sys.int_nest_cnt++;
109
110         // Save info for preempted pcb
111         preempted_pcb = get_curr_pcb();
112         preempted_pcb->stack.curr = stack;
113         preempted_pcb->state = ST_READY;
114         OS_DEBUG(D_TASK,"Preempted %s\n",preempted_pcb->name);
115
116         Os_StackPerformCheck(preempted_pcb);
117
118         POSTTASKHOOK();
119
120         pcb = (struct OsPcb *)pcb_p;
121         pcb->state = ST_RUNNING;
122         set_curr_pcb(pcb);
123
124         PRETASKHOOK();
125
126         // We should not get here if we're NON
127         if( pcb->scheduling == NON) {
128                 // TODO:
129                 // assert(0);
130                 while(1);
131         }
132
133         Irq_SOI();
134
135 #ifndef CFG_HCS12D
136         Irq_Enable();
137         pcb->entry();
138         Irq_Disable();
139 #else
140         pcb->entry();
141 #endif
142
143         /** @req OS368 */
144         if( Os_IrqAnyDisabled() ) {
145                 Os_IrqClearAll();
146                 ERRORHOOK(E_OS_DISABLEDINT);
147         }
148
149         /** @req OS369 */
150         Os_ResourceCheckAndRelease(pcb);
151
152         pcb->state = ST_SUSPENDED;
153         POSTTASKHOOK();
154
155         Irq_EOI();
156
157         --os_sys.int_nest_cnt;
158
159         // TODO: Check stack check marker....
160         // We have preempted a task
161         if( (os_sys.int_nest_cnt == 0) && (os_sys.scheduler_lock==0) ) { //&& is_idle_task() ) {
162                 /* If we get here:
163                  * - the preempted task is saved with large context.
164                  * - We are on interrupt stack..( this function )
165                  *
166                  * if we find a new task:
167                  * - just switch in the new context( don't save the old because
168                  *   its already saved )
169                  */
170                 OsPcbType *new_pcb;
171                 new_pcb = Os_TaskGetTop();
172
173                 Os_StackPerformCheck(new_pcb);
174
175                 if( new_pcb != preempted_pcb ) {
176                         OS_DEBUG(D_TASK,"Found candidate %s\n",new_pcb->name);
177 //#warning Os_TaskSwapContextTo should call the pretaskswaphook
178 // TODO: This shuould go away!!!!
179 #if defined(CFG_ARM_CM3)
180                         Irq_EOI2();
181 #endif
182                         Os_TaskSwapContextTo(NULL,new_pcb);
183                 } else {
184                         if( new_pcb == NULL ) {
185                                 assert(0);
186                         }
187                         preempted_pcb->state = ST_RUNNING;
188                         set_curr_pcb(preempted_pcb);
189                 }
190         } else {
191                 set_curr_pcb(preempted_pcb);
192                 PRETASKHOOK();
193         }
194
195         return stack;
196 }