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