Rev 526 | Rev 559 | 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 | |||
514 | giacomo | 60 | int get_free_timer_slot() |
61 | { |
||
62 | |||
63 | int i = 16; |
||
64 | |||
65 | while(timer_table[i] != -1) |
||
526 | giacomo | 66 | if (i < MAX_INT_TABLE) i++; else return -1; |
514 | giacomo | 67 | |
68 | return i; |
||
69 | |||
70 | } |
||
71 | |||
513 | giacomo | 72 | extern void linux_intr(int no); |
514 | giacomo | 73 | extern void linux_timer(int no); |
513 | giacomo | 74 | |
514 | giacomo | 75 | |
76 | /* The Interrupt TASK is an aperiodic task designed for |
||
77 | the INTDRIVE module. */ |
||
78 | |||
513 | giacomo | 79 | TASK Interrupt_Server(void *arg) |
80 | { |
||
81 | |||
82 | int no; |
||
83 | |||
84 | while(1) { |
||
85 | |||
86 | no = get_interrupt_job(); |
||
87 | |||
540 | giacomo | 88 | if (no != -1 && no < 16) { |
514 | giacomo | 89 | linux_intr(no); |
540 | giacomo | 90 | irq_unmask(no); |
91 | } |
||
514 | giacomo | 92 | |
93 | if (no != -1 && no >= 16) { |
||
94 | linux_timer(no); |
||
95 | timer_table[no] = -1; |
||
96 | int_func_table[no] = NULL; |
||
97 | int_arg_table[no] = NULL; |
||
98 | } |
||
99 | |||
513 | giacomo | 100 | task_endcycle(); |
101 | |||
102 | } |
||
103 | |||
104 | } |
||
105 | |||
106 | int shark_interrupt_server() { |
||
107 | |||
108 | HARD_TASK_MODEL ht; |
||
109 | int i; |
||
110 | |||
526 | giacomo | 111 | for(i=0;i<MAX_INT_TABLE;i++) { |
513 | giacomo | 112 | int_arg_table[i] = NULL; |
113 | int_func_table[i] = NULL; |
||
514 | giacomo | 114 | timer_table[i] = -1; |
513 | giacomo | 115 | } |
116 | |||
514 | giacomo | 117 | |
513 | giacomo | 118 | hard_task_default_model(ht); |
119 | hard_task_def_wcet(ht,10000); |
||
120 | hard_task_def_interrupt(ht); |
||
121 | |||
122 | intr_server = task_create("Interrupt Server",Interrupt_Server,&ht,NULL); |
||
514 | giacomo | 123 | if (intr_server == NIL) |
513 | giacomo | 124 | return -1; |
125 | |||
514 | giacomo | 126 | return 0; |
127 | |||
513 | giacomo | 128 | } |
129 | |||
490 | giacomo | 130 | void shark_internal_sem_create(void **sem, int init) { |
496 | giacomo | 131 | *sem = (void *)malloc(sizeof(internal_sem_t)); |
132 | internal_sem_init((internal_sem_t *)(*sem),init); |
||
490 | giacomo | 133 | } |
134 | |||
135 | void shark_internal_sem_wait(void *sem) { |
||
496 | giacomo | 136 | internal_sem_wait((internal_sem_t *)(sem)); |
137 | } |
||
490 | giacomo | 138 | |
496 | giacomo | 139 | void shark_internal_sem_post(void *sem) { |
140 | internal_sem_post((internal_sem_t *)(sem)); |
||
141 | } |
||
490 | giacomo | 142 | |
514 | giacomo | 143 | /* Timers */ |
144 | |||
145 | void fast_call_timer(void *arg) |
||
496 | giacomo | 146 | { |
514 | giacomo | 147 | |
148 | int no = (int)arg,res; |
||
149 | |||
540 | giacomo | 150 | #ifdef DEBUG_SHARK_GLUE |
151 | cprintf("(Timer Exe)"); |
||
152 | #endif |
||
153 | |||
525 | giacomo | 154 | timer_table[no] = -2; |
155 | |||
514 | giacomo | 156 | res = add_interrupt_job(no); |
157 | if (intr_server != NIL && res == 0) |
||
158 | task_activate(intr_server); |
||
159 | |||
490 | giacomo | 160 | } |
161 | |||
514 | giacomo | 162 | int shark_timer_set(const struct timespec *time, void *handler, void *arg) |
496 | giacomo | 163 | { |
514 | giacomo | 164 | SYS_FLAGS f; |
165 | int i; |
||
166 | |||
167 | f = kern_fsave(); |
||
168 | |||
540 | giacomo | 169 | #ifdef DEBUG_SHARK_GLUE |
170 | cprintf("(Timer Set)"); |
||
171 | #endif |
||
172 | |||
514 | giacomo | 173 | i = get_free_timer_slot(); |
174 | |||
175 | if (i == -1) { |
||
176 | kern_frestore(f); |
||
177 | return -1; |
||
178 | } |
||
179 | |||
180 | int_func_table[i] = handler; |
||
181 | int_arg_table[i] = arg; |
||
182 | |||
183 | timer_table[i] = kern_event_post(time,fast_call_timer,(void *)(i)); |
||
184 | |||
185 | if (timer_table[i] == -1) { |
||
186 | kern_frestore(f); |
||
187 | return -1; |
||
188 | } |
||
189 | |||
190 | kern_frestore(f); |
||
191 | |||
192 | return i; |
||
496 | giacomo | 193 | } |
490 | giacomo | 194 | |
514 | giacomo | 195 | int shark_timer_delete(int index) |
513 | giacomo | 196 | { |
197 | |||
514 | giacomo | 198 | SYS_FLAGS f; |
522 | mauro | 199 | |
514 | giacomo | 200 | f = kern_fsave(); |
201 | |||
526 | giacomo | 202 | if (index <= 0 || index >= MAX_INT_TABLE) { |
522 | mauro | 203 | kern_frestore(f); |
204 | return -1; |
||
205 | } |
||
206 | |||
540 | giacomo | 207 | #ifdef DEBUG_SHARK_GLUE |
208 | cprintf("(Timer Del)"); |
||
209 | #endif |
||
210 | |||
525 | giacomo | 211 | if (timer_table[index] != -1 && timer_table[index] != -2) { |
514 | giacomo | 212 | |
213 | int_func_table[index] = NULL; |
||
214 | int_arg_table[index] = NULL; |
||
525 | giacomo | 215 | |
514 | giacomo | 216 | kern_event_delete(timer_table[index]); |
217 | |||
218 | timer_table[index] = -1; |
||
219 | |||
220 | } |
||
221 | kern_frestore(f); |
||
222 | |||
223 | return 0; |
||
224 | |||
225 | } |
||
226 | |||
227 | /* Interrupt */ |
||
228 | |||
229 | void fast_call_intr(int no) |
||
230 | { |
||
513 | giacomo | 231 | int res; |
232 | |||
540 | giacomo | 233 | #ifdef DEBUG_SHARK_GLUE |
234 | cprintf("(Int Exe)"); |
||
235 | #endif |
||
236 | |||
237 | irq_mask(no); |
||
238 | |||
513 | giacomo | 239 | res = add_interrupt_job(no); |
240 | if (intr_server != NIL && res == 0) |
||
241 | task_activate(intr_server); |
||
242 | |||
496 | giacomo | 243 | } |
490 | giacomo | 244 | |
513 | giacomo | 245 | int shark_handler_set(int no, void *fast, void *arg){ |
246 | |||
514 | giacomo | 247 | if (no >= 1 && no < 16 && int_func_table[no] == NULL) { |
513 | giacomo | 248 | int_arg_table[no] = arg; |
249 | int_func_table[no] = fast; |
||
514 | giacomo | 250 | return handler_set(no, fast_call_intr, NIL, TRUE); |
513 | giacomo | 251 | } else { |
252 | return -1; |
||
253 | } |
||
254 | |||
255 | } |
||
256 | |||
496 | giacomo | 257 | int shark_handler_remove(int no){ |
514 | giacomo | 258 | |
259 | int_func_table[no] = NULL; |
||
260 | int_arg_table[no] = NULL; |
||
261 | handler_remove(no); |
||
262 | return 0; |
||
263 | |||
490 | giacomo | 264 | } |
496 | giacomo | 265 |