Rev 565 | Rev 1007 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
490 | giacomo | 1 | #include <kernel/int_sem.h> |
2 | #include <stdlib.h> |
||
496 | giacomo | 3 | #include <kernel/func.h> |
4 | #include <ll/sys/ll/event.h> |
||
540 | giacomo | 5 | #include <ll/i386/pic.h> |
905 | mauro | 6 | #include <tracer.h> |
490 | giacomo | 7 | |
526 | giacomo | 8 | #include <linuxcomp.h> |
9 | |||
540 | giacomo | 10 | //#define DEBUG_SHARK_GLUE |
11 | |||
513 | giacomo | 12 | PID intr_server = NIL; |
13 | |||
14 | #define MAX_INT_LIST 50 |
||
15 | |||
514 | giacomo | 16 | /* 1-15 for IRQ and 16-63 for timers */ |
513 | giacomo | 17 | |
526 | giacomo | 18 | void *int_arg_table[MAX_INT_TABLE]; |
19 | void *int_func_table[MAX_INT_TABLE]; |
||
20 | int timer_table[MAX_INT_TABLE]; |
||
514 | giacomo | 21 | |
513 | giacomo | 22 | int int_list[MAX_INT_LIST]; |
23 | int next_free_int = 0; |
||
24 | int next_execute_int = 0; |
||
905 | mauro | 25 | int n_myact = 0, n_lost = 0; |
513 | giacomo | 26 | |
27 | /* FIFO add job */ |
||
28 | int add_interrupt_job(int no) |
||
29 | { |
||
30 | |||
521 | mauro | 31 | int old_free_int = next_free_int; |
32 | |||
905 | mauro | 33 | TRACER_LOGEVENT(FTrace_EVT_user_event_1, no, 0); |
34 | |||
513 | giacomo | 35 | int_list[next_free_int] = no; |
36 | next_free_int++; |
||
37 | |||
38 | if (next_free_int == MAX_INT_LIST) next_free_int = 0; |
||
39 | if (next_free_int == next_execute_int) { |
||
521 | mauro | 40 | next_free_int = old_free_int; |
905 | mauro | 41 | n_lost++; |
513 | giacomo | 42 | return -1; |
43 | } |
||
44 | |||
45 | return 0; |
||
46 | |||
47 | } |
||
48 | |||
49 | /* FIFO get job */ |
||
50 | int get_interrupt_job() |
||
51 | { |
||
52 | |||
53 | int res = -1; |
||
54 | |||
55 | if (next_free_int != next_execute_int) { |
||
56 | res = int_list[next_execute_int]; |
||
57 | next_execute_int++; |
||
58 | if (next_execute_int == MAX_INT_LIST) next_execute_int = 0; |
||
59 | } |
||
60 | |||
905 | mauro | 61 | TRACER_LOGEVENT(FTrace_EVT_user_event_2, res, 0); |
62 | |||
513 | giacomo | 63 | return res; |
64 | |||
65 | } |
||
66 | |||
559 | giacomo | 67 | static int current_timer = 16; |
68 | |||
514 | giacomo | 69 | int get_free_timer_slot() |
70 | { |
||
71 | |||
559 | giacomo | 72 | int i = current_timer, count = 0; |
514 | giacomo | 73 | |
559 | giacomo | 74 | while(timer_table[i] != -1) { |
75 | if (i < MAX_INT_TABLE) { |
||
76 | i++; |
||
77 | count++; |
||
78 | } else { |
||
79 | i = 16; |
||
80 | } |
||
81 | if (count > 2) return -1; |
||
82 | } |
||
83 | |||
84 | current_timer = i+1; |
||
85 | if (current_timer >= MAX_INT_TABLE) current_timer = 16; |
||
86 | |||
514 | giacomo | 87 | return i; |
88 | |||
89 | } |
||
90 | |||
513 | giacomo | 91 | extern void linux_intr(int no); |
514 | giacomo | 92 | extern void linux_timer(int no); |
513 | giacomo | 93 | |
514 | giacomo | 94 | |
95 | /* The Interrupt TASK is an aperiodic task designed for |
||
96 | the INTDRIVE module. */ |
||
97 | |||
513 | giacomo | 98 | TASK Interrupt_Server(void *arg) |
99 | { |
||
100 | |||
101 | int no; |
||
905 | mauro | 102 | |
513 | giacomo | 103 | while(1) { |
104 | |||
905 | mauro | 105 | n_myact++; |
106 | |||
513 | giacomo | 107 | no = get_interrupt_job(); |
108 | |||
540 | giacomo | 109 | if (no != -1 && no < 16) { |
514 | giacomo | 110 | linux_intr(no); |
540 | giacomo | 111 | irq_unmask(no); |
112 | } |
||
514 | giacomo | 113 | |
114 | if (no != -1 && no >= 16) { |
||
115 | linux_timer(no); |
||
116 | timer_table[no] = -1; |
||
117 | int_func_table[no] = NULL; |
||
118 | int_arg_table[no] = NULL; |
||
119 | } |
||
120 | |||
513 | giacomo | 121 | task_endcycle(); |
122 | |||
123 | } |
||
124 | |||
125 | } |
||
126 | |||
127 | int shark_interrupt_server() { |
||
128 | |||
129 | HARD_TASK_MODEL ht; |
||
130 | int i; |
||
131 | |||
526 | giacomo | 132 | for(i=0;i<MAX_INT_TABLE;i++) { |
513 | giacomo | 133 | int_arg_table[i] = NULL; |
134 | int_func_table[i] = NULL; |
||
514 | giacomo | 135 | timer_table[i] = -1; |
513 | giacomo | 136 | } |
137 | |||
514 | giacomo | 138 | |
513 | giacomo | 139 | hard_task_default_model(ht); |
140 | hard_task_def_wcet(ht,10000); |
||
141 | hard_task_def_interrupt(ht); |
||
565 | giacomo | 142 | hard_task_def_system(ht); |
143 | hard_task_def_nokill(ht); |
||
513 | giacomo | 144 | |
145 | intr_server = task_create("Interrupt Server",Interrupt_Server,&ht,NULL); |
||
514 | giacomo | 146 | if (intr_server == NIL) |
513 | giacomo | 147 | return -1; |
148 | |||
514 | giacomo | 149 | return 0; |
150 | |||
513 | giacomo | 151 | } |
152 | |||
490 | giacomo | 153 | void shark_internal_sem_create(void **sem, int init) { |
496 | giacomo | 154 | *sem = (void *)malloc(sizeof(internal_sem_t)); |
155 | internal_sem_init((internal_sem_t *)(*sem),init); |
||
490 | giacomo | 156 | } |
157 | |||
158 | void shark_internal_sem_wait(void *sem) { |
||
496 | giacomo | 159 | internal_sem_wait((internal_sem_t *)(sem)); |
160 | } |
||
490 | giacomo | 161 | |
496 | giacomo | 162 | void shark_internal_sem_post(void *sem) { |
163 | internal_sem_post((internal_sem_t *)(sem)); |
||
164 | } |
||
490 | giacomo | 165 | |
514 | giacomo | 166 | /* Timers */ |
167 | |||
168 | void fast_call_timer(void *arg) |
||
496 | giacomo | 169 | { |
514 | giacomo | 170 | |
171 | int no = (int)arg,res; |
||
172 | |||
540 | giacomo | 173 | #ifdef DEBUG_SHARK_GLUE |
174 | cprintf("(Timer Exe)"); |
||
175 | #endif |
||
176 | |||
525 | giacomo | 177 | timer_table[no] = -2; |
178 | |||
514 | giacomo | 179 | res = add_interrupt_job(no); |
180 | if (intr_server != NIL && res == 0) |
||
181 | task_activate(intr_server); |
||
182 | |||
490 | giacomo | 183 | } |
184 | |||
514 | giacomo | 185 | int shark_timer_set(const struct timespec *time, void *handler, void *arg) |
496 | giacomo | 186 | { |
514 | giacomo | 187 | SYS_FLAGS f; |
188 | int i; |
||
189 | |||
190 | f = kern_fsave(); |
||
191 | |||
540 | giacomo | 192 | #ifdef DEBUG_SHARK_GLUE |
193 | cprintf("(Timer Set)"); |
||
194 | #endif |
||
195 | |||
514 | giacomo | 196 | i = get_free_timer_slot(); |
197 | |||
198 | if (i == -1) { |
||
199 | kern_frestore(f); |
||
200 | return -1; |
||
201 | } |
||
202 | |||
203 | int_func_table[i] = handler; |
||
204 | int_arg_table[i] = arg; |
||
205 | |||
206 | timer_table[i] = kern_event_post(time,fast_call_timer,(void *)(i)); |
||
207 | |||
208 | if (timer_table[i] == -1) { |
||
209 | kern_frestore(f); |
||
210 | return -1; |
||
211 | } |
||
212 | |||
213 | kern_frestore(f); |
||
214 | |||
215 | return i; |
||
496 | giacomo | 216 | } |
490 | giacomo | 217 | |
514 | giacomo | 218 | int shark_timer_delete(int index) |
513 | giacomo | 219 | { |
220 | |||
514 | giacomo | 221 | SYS_FLAGS f; |
522 | mauro | 222 | |
514 | giacomo | 223 | f = kern_fsave(); |
224 | |||
526 | giacomo | 225 | if (index <= 0 || index >= MAX_INT_TABLE) { |
522 | mauro | 226 | kern_frestore(f); |
227 | return -1; |
||
228 | } |
||
229 | |||
540 | giacomo | 230 | #ifdef DEBUG_SHARK_GLUE |
231 | cprintf("(Timer Del)"); |
||
232 | #endif |
||
233 | |||
525 | giacomo | 234 | if (timer_table[index] != -1 && timer_table[index] != -2) { |
514 | giacomo | 235 | |
236 | int_func_table[index] = NULL; |
||
237 | int_arg_table[index] = NULL; |
||
525 | giacomo | 238 | |
514 | giacomo | 239 | kern_event_delete(timer_table[index]); |
240 | |||
241 | timer_table[index] = -1; |
||
242 | |||
243 | } |
||
244 | kern_frestore(f); |
||
245 | |||
246 | return 0; |
||
247 | |||
248 | } |
||
249 | |||
250 | /* Interrupt */ |
||
251 | |||
252 | void fast_call_intr(int no) |
||
253 | { |
||
513 | giacomo | 254 | int res; |
255 | |||
540 | giacomo | 256 | #ifdef DEBUG_SHARK_GLUE |
257 | cprintf("(Int Exe)"); |
||
258 | #endif |
||
259 | |||
260 | irq_mask(no); |
||
261 | |||
513 | giacomo | 262 | res = add_interrupt_job(no); |
263 | if (intr_server != NIL && res == 0) |
||
264 | task_activate(intr_server); |
||
265 | |||
496 | giacomo | 266 | } |
490 | giacomo | 267 | |
513 | giacomo | 268 | int shark_handler_set(int no, void *fast, void *arg){ |
269 | |||
514 | giacomo | 270 | if (no >= 1 && no < 16 && int_func_table[no] == NULL) { |
513 | giacomo | 271 | int_arg_table[no] = arg; |
272 | int_func_table[no] = fast; |
||
514 | giacomo | 273 | return handler_set(no, fast_call_intr, NIL, TRUE); |
513 | giacomo | 274 | } else { |
275 | return -1; |
||
276 | } |
||
277 | |||
278 | } |
||
279 | |||
496 | giacomo | 280 | int shark_handler_remove(int no){ |
514 | giacomo | 281 | |
282 | int_func_table[no] = NULL; |
||
283 | int_arg_table[no] = NULL; |
||
284 | handler_remove(no); |
||
285 | return 0; |
||
286 | |||
490 | giacomo | 287 | } |
496 | giacomo | 288 |