Subversion Repositories shark

Rev

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