Subversion Repositories shark

Rev

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