/shark/trunk/drivers/linuxc26/shark_linuxc26.c |
---|
24,6 → 24,7 |
extern int buses_init(void); |
extern int classes_init(void); |
extern int linuxcomp_init(void); |
extern int shark_interrupt_server(void); |
unsigned long read_time(void) { |
40,6 → 41,8 |
/* Init the Emulation Library */ |
int LINUXC26_register_module() { |
int res; |
printk("LINUXC26_register_module\n"); |
linuxcomp_init(); |
47,6 → 50,12 |
buses_init(); |
classes_init(); |
res = shark_interrupt_server(); |
if (res != 0) { |
printk("ERROR: CANNOT REGISTER LINUX COMPATIBILITY LAYER\n"); |
sys_end(); |
} |
return 0; |
} |
/shark/trunk/drivers/linuxc26/include/linuxcomp.h |
---|
59,7 → 59,7 |
int shark_event_delete(int index); |
/* Interrupt handler installation and removal */ |
int shark_handler_set(int no, void (*fast)(int), int pi, BYTE lock); |
int shark_handler_set(int no, void *fast, void *arg); |
int shark_handler_remove(int no); |
#endif |
/shark/trunk/drivers/linuxc26/shark_glue.c |
---|
3,6 → 3,92 |
#include <kernel/func.h> |
#include <ll/sys/ll/event.h> |
PID intr_server = NIL; |
#define MAX_INT_LIST 50 |
void *int_arg_table[16]; |
void *int_func_table[16]; |
int int_list[MAX_INT_LIST]; |
int next_free_int = 0; |
int next_execute_int = 0; |
/* FIFO add job */ |
int add_interrupt_job(int no) |
{ |
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--; |
return -1; |
} |
return 0; |
} |
/* 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; |
} |
return res; |
} |
extern void linux_intr(int no); |
TASK Interrupt_Server(void *arg) |
{ |
int no; |
while(1) { |
no = get_interrupt_job(); |
if (no != -1) |
linux_intr(no); |
task_endcycle(); |
} |
} |
int shark_interrupt_server() { |
HARD_TASK_MODEL ht; |
int i; |
for(i=0;i<16;i++) { |
int_arg_table[i] = NULL; |
int_func_table[i] = NULL; |
} |
hard_task_default_model(ht); |
hard_task_def_wcet(ht,10000); |
hard_task_def_interrupt(ht); |
intr_server = task_create("Interrupt Server",Interrupt_Server,&ht,NULL); |
if (intr_server != NIL) |
return 0; |
else |
return -1; |
} |
void shark_internal_sem_create(void **sem, int init) { |
*sem = (void *)malloc(sizeof(internal_sem_t)); |
internal_sem_init((internal_sem_t *)(*sem),init); |
26,10 → 112,29 |
return event_delete(index); |
} |
int shark_handler_set(int no, void (*fast)(int), int pi, BYTE lock){ |
return handler_set(no, fast, (PID)pi, lock); |
void fast_call(int no) |
{ |
int res; |
res = add_interrupt_job(no); |
if (intr_server != NIL && res == 0) |
task_activate(intr_server); |
} |
int shark_handler_set(int no, void *fast, void *arg){ |
if (no >= 1 && no < 16) { |
int_arg_table[no] = arg; |
int_func_table[no] = fast; |
return handler_set(no, fast_call, NIL, TRUE); |
} else { |
return -1; |
} |
} |
int shark_handler_remove(int no){ |
return handler_remove(no); |
} |
/shark/trunk/drivers/linuxc26/int.c |
---|
4,28 → 4,21 |
#include <asm-generic/errno-base.h> |
#include <linux/kernel.h> |
#define NIL -1 |
extern void *int_arg_table[16]; |
extern void *int_func_table[16]; |
int intr_count = 0; |
static struct { |
void (*func)(int, void *dev_id, struct pt_regs *); |
void *data; |
int flags; |
} handlers[16]; |
unsigned long intr_count = 0; |
/* |
* Generic Linux interrupt handler. |
*/ |
static void linux_intr(int irq) |
void linux_intr(int irq) |
{ |
struct pt_regs regs; |
//printk("linux_intr %d\n", irq); |
intr_count++; |
(*handlers[irq].func)(irq, handlers[irq].data, ®s); |
if (int_func_table[irq] != NULL) |
(* (void (*)(int, void *dev_id, struct pt_regs *))int_func_table[irq])(irq, int_arg_table[irq], ®s); |
intr_count--; |
36,17 → 29,7 |
*/ |
int request_irq(unsigned int irq, void (*handler)(int, void *dev_id, struct pt_regs *), unsigned long flags, const char *device, void *dev_id) |
{ |
if (handlers[irq].func) { |
return (-EBUSY); |
} |
handlers[irq].func = handler; |
handlers[irq].flags = flags; |
handlers[irq].data = dev_id; |
shark_handler_set(irq, linux_intr, NIL, TRUE); |
shark_handler_set(irq, (void *)(handler), dev_id); |
return 0; |
} |
55,6 → 38,7 |
*/ |
void free_irq(unsigned int irq, void *a) |
{ |
shark_handler_remove(irq); |
handlers[irq].func = 0; |
} |