7,179 → 7,92 |
|
#include <linuxcomp.h> |
|
//#define DEBUG_SHARK_GLUE |
extern int add_interrupt_job(int no); |
extern void set_noint_handler(void * new_handler); |
|
PID intr_server = NIL; |
extern int intr_count; |
|
#define MAX_INT_LIST 50 |
//#define DEBUG_SHARK_GLUE |
|
/* 1-15 for IRQ and 16-63 for timers */ |
void *timer_arg_table[MAX_TIMER_TABLE]; |
void *timer_func_table[MAX_TIMER_TABLE]; |
int timer_table[MAX_TIMER_TABLE]; |
int intr_table[NR_IRQS]; |
|
void *int_arg_table[MAX_INT_TABLE]; |
void *int_func_table[MAX_INT_TABLE]; |
int timer_table[MAX_INT_TABLE]; |
int use_intdrive = 0; |
static int current_timer = 0; |
|
int int_list[MAX_INT_LIST]; |
int next_free_int = 0; |
int next_execute_int = 0; |
int n_myact = 0, n_lost = 0; |
void shark_internal_sem_create(void **sem, int init) { |
*sem = (void *)malloc(sizeof(internal_sem_t)); |
internal_sem_init((internal_sem_t *)(*sem),init); |
} |
|
/* FIFO add job */ |
int add_interrupt_job(int no) |
{ |
|
int old_free_int = next_free_int; |
|
TRACER_LOGEVENT(FTrace_EVT_user_event_1, no, 0); |
|
int_list[next_free_int] = no; |
next_free_int++; |
|
if (next_free_int == MAX_INT_LIST) next_free_int = 0; |
if (next_free_int == next_execute_int) { |
next_free_int = old_free_int; |
n_lost++; |
return -1; |
} |
|
return 0; |
|
void shark_internal_sem_wait(void *sem) { |
internal_sem_wait((internal_sem_t *)(sem)); |
} |
|
/* FIFO get job */ |
int get_interrupt_job() |
{ |
|
int res = -1; |
|
if (next_free_int != next_execute_int) { |
res = int_list[next_execute_int]; |
next_execute_int++; |
if (next_execute_int == MAX_INT_LIST) next_execute_int = 0; |
} |
|
TRACER_LOGEVENT(FTrace_EVT_user_event_2, res, 0); |
|
return res; |
|
void shark_internal_sem_post(void *sem) { |
internal_sem_post((internal_sem_t *)(sem)); |
} |
|
static int current_timer = 16; |
/* Timers */ |
|
int get_free_timer_slot() |
{ |
int i = current_timer; |
|
int i = current_timer, count = 0; |
|
while(timer_table[i] != -1) { |
if (i < MAX_INT_TABLE) { |
if (i < MAX_TIMER_TABLE) { |
i++; |
count++; |
} else { |
i = 16; |
i = 0; |
} |
if (count > 2) return -1; |
if (i == current_timer) return -1; |
} |
|
current_timer = i+1; |
if (current_timer >= MAX_INT_TABLE) current_timer = 16; |
if (current_timer >= MAX_TIMER_TABLE) current_timer = 0; |
|
return i; |
|
} |
|
extern void linux_intr(int no); |
extern void linux_timer(int no); |
|
|
/* The Interrupt TASK is an aperiodic task designed for |
the INTDRIVE module. */ |
|
TASK Interrupt_Server(void *arg) |
void shark_timer_exec(int n) |
{ |
int no = n - 16; |
void(*tmp_func)(void*) = timer_func_table[no]; |
|
int no; |
|
while(1) { |
#ifdef DEBUG_SHARK_GLUE |
cprintf("(Timer EXEC %d)", no); |
#endif |
|
n_myact++; |
|
no = get_interrupt_job(); |
|
if (no != -1 && no < 16) { |
linux_intr(no); |
irq_unmask(no); |
} |
|
if (no != -1 && no >= 16) { |
linux_timer(no); |
timer_table[no] = -1; |
int_func_table[no] = NULL; |
int_arg_table[no] = NULL; |
} |
|
task_endcycle(); |
|
if (tmp_func != NULL){ |
intr_count++; |
(tmp_func)(timer_arg_table[no]); |
intr_count--; |
} |
|
timer_table[no] = -1; |
timer_func_table[no] = NULL; |
timer_arg_table[no] = NULL; |
} |
|
int shark_interrupt_server() { |
|
HARD_TASK_MODEL ht; |
int i; |
|
for(i=0;i<MAX_INT_TABLE;i++) { |
int_arg_table[i] = NULL; |
int_func_table[i] = NULL; |
timer_table[i] = -1; |
} |
|
|
hard_task_default_model(ht); |
hard_task_def_wcet(ht,10000); |
hard_task_def_interrupt(ht); |
hard_task_def_system(ht); |
hard_task_def_nokill(ht); |
|
intr_server = task_create("Interrupt Server",Interrupt_Server,&ht,NULL); |
if (intr_server == NIL) |
return -1; |
|
return 0; |
|
} |
|
void shark_internal_sem_create(void **sem, int init) { |
*sem = (void *)malloc(sizeof(internal_sem_t)); |
internal_sem_init((internal_sem_t *)(*sem),init); |
} |
|
void shark_internal_sem_wait(void *sem) { |
internal_sem_wait((internal_sem_t *)(sem)); |
} |
|
void shark_internal_sem_post(void *sem) { |
internal_sem_post((internal_sem_t *)(sem)); |
} |
|
/* Timers */ |
|
void fast_call_timer(void *arg) |
{ |
int no = (int)arg; |
int res; |
|
int no = (int)arg,res; |
#ifdef DEBUG_SHARK_GLUE |
cprintf("(Timer fast %d)", no); |
#endif |
|
#ifdef DEBUG_SHARK_GLUE |
cprintf("(Timer Exe)"); |
#endif |
|
timer_table[no] = -2; |
|
res = add_interrupt_job(no); |
if (intr_server != NIL && res == 0) |
task_activate(intr_server); |
|
if (use_intdrive == TRUE) { |
res = add_interrupt_job(no+16); |
} else { |
shark_timer_exec(no+16); |
} |
} |
|
int shark_timer_set(const struct timespec *time, void *handler, void *arg) |
189,9 → 102,9 |
|
f = kern_fsave(); |
|
#ifdef DEBUG_SHARK_GLUE |
cprintf("(Timer Set)"); |
#endif |
#ifdef DEBUG_SHARK_GLUE |
cprintf("(Timer Set %d)", no); |
#endif |
|
i = get_free_timer_slot(); |
|
200,15 → 113,15 |
return -1; |
} |
|
int_func_table[i] = handler; |
int_arg_table[i] = arg; |
timer_func_table[i] = handler; |
timer_arg_table[i] = arg; |
|
timer_table[i] = kern_event_post(time,fast_call_timer,(void *)(i)); |
timer_table[i] = kern_event_post(time, fast_call_timer, (void *)(i)); |
|
if (timer_table[i] == -1) { |
kern_frestore(f); |
return -1; |
} |
return -1; |
} |
|
kern_frestore(f); |
|
217,72 → 130,88 |
|
int shark_timer_delete(int index) |
{ |
|
SYS_FLAGS f; |
|
f = kern_fsave(); |
f = kern_fsave(); |
|
if (index <= 0 || index >= MAX_INT_TABLE) { |
if (index <= 0 || index >= MAX_TIMER_TABLE) { |
kern_frestore(f); |
return -1; |
} |
|
#ifdef DEBUG_SHARK_GLUE |
cprintf("(Timer Del)"); |
#endif |
#ifdef DEBUG_SHARK_GLUE |
cprintf("(Timer Del %d)", no); |
#endif |
|
if (timer_table[index] != -1 && timer_table[index] != -2) { |
|
int_func_table[index] = NULL; |
int_arg_table[index] = NULL; |
timer_func_table[index] = NULL; |
timer_arg_table[index] = NULL; |
|
kern_event_delete(timer_table[index]); |
|
timer_table[index] = -1; |
|
} |
kern_frestore(f); |
kern_frestore(f); |
|
return 0; |
|
} |
|
/* Interrupt */ |
int shark_handler_set(int no, void *fast){ |
|
void fast_call_intr(int no) |
{ |
int res; |
|
#ifdef DEBUG_SHARK_GLUE |
cprintf("(Int Exe)"); |
#endif |
|
irq_mask(no); |
|
res = add_interrupt_job(no); |
if (intr_server != NIL && res == 0) |
task_activate(intr_server); |
|
if ((no >= 1) && (no < 16) && (intr_table[no] <= 0)) { |
if (use_intdrive == TRUE) { |
intr_table[no] = handler_set(no, NULL, TRUE, NIL, fast); |
#ifdef DEBUG_SHARK_GLUE |
cprintf("(shark_handler_set - INT: %d - %d)", no, intr_table[no]); |
#endif |
} else { |
intr_table[no] = handler_set(no, fast, TRUE, NIL, NULL); |
#ifdef DEBUG_SHARK_GLUE |
cprintf("(Shark_Handler_Set - NOINT: %d - %d)", no, intr_table[no]); |
#endif |
} |
return intr_table[no]; |
} else { |
#ifdef DEBUG_SHARK_GLUE |
cprintf("(shark_handler_set - ERR: %d - %d)", no, intr_table[no]); |
#endif |
return -1; |
} |
} |
|
int shark_handler_set(int no, void *fast, void *arg){ |
int shark_handler_remove(int no){ |
|
if (no >= 1 && no < 16 && int_func_table[no] == NULL) { |
int_arg_table[no] = arg; |
int_func_table[no] = fast; |
return handler_set(no, fast_call_intr, NIL, TRUE); |
} else { |
return -1; |
if (intr_table[no] == 1) { |
handler_remove(no); |
#ifdef DEBUG_SHARK_GLUE |
cprintf("(shark_handler_remove: %d)", no); |
#endif |
intr_table[no] = 0; |
} |
|
return 0; |
} |
|
/* Boot function */ |
int shark_interrupt_server(int use_intdrv) { |
int i; |
|
int shark_handler_remove(int no){ |
for(i=0; i<MAX_TIMER_TABLE; i++) { |
timer_arg_table[i] = NULL; |
timer_func_table[i] = NULL; |
timer_table[i] = -1; |
} |
for(i=0; i<NR_IRQS; i++) { |
intr_table[i] = 0; |
} |
|
use_intdrive = use_intdrv; |
#ifdef DEBUG_SHARK_GLUE |
cprintf("(Use_intdrive: %d)", use_intdrive); |
#endif |
if (use_intdrive == TRUE) |
set_noint_handler(shark_timer_exec); |
|
int_func_table[no] = NULL; |
int_arg_table[no] = NULL; |
handler_remove(no); |
return 0; |
|
} |
|