Rev 540 | Rev 565 | 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); |
||
133 | |||
134 | intr_server = task_create("Interrupt Server",Interrupt_Server,&ht,NULL); |
||
514 | giacomo | 135 | if (intr_server == NIL) |
513 | giacomo | 136 | return -1; |
137 | |||
514 | giacomo | 138 | return 0; |
139 | |||
513 | giacomo | 140 | } |
141 | |||
490 | giacomo | 142 | void shark_internal_sem_create(void **sem, int init) { |
496 | giacomo | 143 | *sem = (void *)malloc(sizeof(internal_sem_t)); |
144 | internal_sem_init((internal_sem_t *)(*sem),init); |
||
490 | giacomo | 145 | } |
146 | |||
147 | void shark_internal_sem_wait(void *sem) { |
||
496 | giacomo | 148 | internal_sem_wait((internal_sem_t *)(sem)); |
149 | } |
||
490 | giacomo | 150 | |
496 | giacomo | 151 | void shark_internal_sem_post(void *sem) { |
152 | internal_sem_post((internal_sem_t *)(sem)); |
||
153 | } |
||
490 | giacomo | 154 | |
514 | giacomo | 155 | /* Timers */ |
156 | |||
157 | void fast_call_timer(void *arg) |
||
496 | giacomo | 158 | { |
514 | giacomo | 159 | |
160 | int no = (int)arg,res; |
||
161 | |||
540 | giacomo | 162 | #ifdef DEBUG_SHARK_GLUE |
163 | cprintf("(Timer Exe)"); |
||
164 | #endif |
||
165 | |||
525 | giacomo | 166 | timer_table[no] = -2; |
167 | |||
514 | giacomo | 168 | res = add_interrupt_job(no); |
169 | if (intr_server != NIL && res == 0) |
||
170 | task_activate(intr_server); |
||
171 | |||
490 | giacomo | 172 | } |
173 | |||
514 | giacomo | 174 | int shark_timer_set(const struct timespec *time, void *handler, void *arg) |
496 | giacomo | 175 | { |
514 | giacomo | 176 | SYS_FLAGS f; |
177 | int i; |
||
178 | |||
179 | f = kern_fsave(); |
||
180 | |||
540 | giacomo | 181 | #ifdef DEBUG_SHARK_GLUE |
182 | cprintf("(Timer Set)"); |
||
183 | #endif |
||
184 | |||
514 | giacomo | 185 | i = get_free_timer_slot(); |
186 | |||
187 | if (i == -1) { |
||
188 | kern_frestore(f); |
||
189 | return -1; |
||
190 | } |
||
191 | |||
192 | int_func_table[i] = handler; |
||
193 | int_arg_table[i] = arg; |
||
194 | |||
195 | timer_table[i] = kern_event_post(time,fast_call_timer,(void *)(i)); |
||
196 | |||
197 | if (timer_table[i] == -1) { |
||
198 | kern_frestore(f); |
||
199 | return -1; |
||
200 | } |
||
201 | |||
202 | kern_frestore(f); |
||
203 | |||
204 | return i; |
||
496 | giacomo | 205 | } |
490 | giacomo | 206 | |
514 | giacomo | 207 | int shark_timer_delete(int index) |
513 | giacomo | 208 | { |
209 | |||
514 | giacomo | 210 | SYS_FLAGS f; |
522 | mauro | 211 | |
514 | giacomo | 212 | f = kern_fsave(); |
213 | |||
526 | giacomo | 214 | if (index <= 0 || index >= MAX_INT_TABLE) { |
522 | mauro | 215 | kern_frestore(f); |
216 | return -1; |
||
217 | } |
||
218 | |||
540 | giacomo | 219 | #ifdef DEBUG_SHARK_GLUE |
220 | cprintf("(Timer Del)"); |
||
221 | #endif |
||
222 | |||
525 | giacomo | 223 | if (timer_table[index] != -1 && timer_table[index] != -2) { |
514 | giacomo | 224 | |
225 | int_func_table[index] = NULL; |
||
226 | int_arg_table[index] = NULL; |
||
525 | giacomo | 227 | |
514 | giacomo | 228 | kern_event_delete(timer_table[index]); |
229 | |||
230 | timer_table[index] = -1; |
||
231 | |||
232 | } |
||
233 | kern_frestore(f); |
||
234 | |||
235 | return 0; |
||
236 | |||
237 | } |
||
238 | |||
239 | /* Interrupt */ |
||
240 | |||
241 | void fast_call_intr(int no) |
||
242 | { |
||
513 | giacomo | 243 | int res; |
244 | |||
540 | giacomo | 245 | #ifdef DEBUG_SHARK_GLUE |
246 | cprintf("(Int Exe)"); |
||
247 | #endif |
||
248 | |||
249 | irq_mask(no); |
||
250 | |||
513 | giacomo | 251 | res = add_interrupt_job(no); |
252 | if (intr_server != NIL && res == 0) |
||
253 | task_activate(intr_server); |
||
254 | |||
496 | giacomo | 255 | } |
490 | giacomo | 256 | |
513 | giacomo | 257 | int shark_handler_set(int no, void *fast, void *arg){ |
258 | |||
514 | giacomo | 259 | if (no >= 1 && no < 16 && int_func_table[no] == NULL) { |
513 | giacomo | 260 | int_arg_table[no] = arg; |
261 | int_func_table[no] = fast; |
||
514 | giacomo | 262 | return handler_set(no, fast_call_intr, NIL, TRUE); |
513 | giacomo | 263 | } else { |
264 | return -1; |
||
265 | } |
||
266 | |||
267 | } |
||
268 | |||
496 | giacomo | 269 | int shark_handler_remove(int no){ |
514 | giacomo | 270 | |
271 | int_func_table[no] = NULL; |
||
272 | int_arg_table[no] = NULL; |
||
273 | handler_remove(no); |
||
274 | return 0; |
||
275 | |||
490 | giacomo | 276 | } |
496 | giacomo | 277 |