39,9 → 39,16 |
#include <arch/cp0.h> |
#include <time/clock.h> |
#include <arch/drivers/arc.h> |
|
#include <ipc/sysipc.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
|
#define IRQ_COUNT 8 |
#define TIMER_IRQ 7 |
|
function timer_fnc = NULL; |
static irq_t timer_irq; |
|
/** Disable interrupts. |
* |
* @return Old interrupt priority level. |
91,8 → 98,13 |
cp0_compare_write(nextcount); |
} |
|
static void timer_exception(int n, istate_t *istate) |
static irq_ownership_t timer_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
|
static void timer_irq_handler(irq_t *irq, void *arg, ...) |
{ |
unsigned long drift; |
|
drift = cp0_count_read() - nextcount; |
103,42 → 115,25 |
nextcount = cp0_count_read() + cp0_compare_value - drift; |
cp0_compare_write(nextcount); |
clock(); |
} |
|
static void swint0(int n, istate_t *istate) |
{ |
cp0_cause_write(cp0_cause_read() & ~(1 << 8)); /* clear SW0 interrupt */ |
ipc_irq_send_notif(0); |
if (timer_fnc != NULL) |
timer_fnc(); |
} |
|
static void swint1(int n, istate_t *istate) |
{ |
cp0_cause_write(cp0_cause_read() & ~(1 << 9)); /* clear SW1 interrupt */ |
ipc_irq_send_notif(1); |
} |
|
/* Initialize basic tables for exception dispatching */ |
void interrupt_init(void) |
{ |
int_register(TIMER_IRQ, "timer", timer_exception); |
int_register(0, "swint0", swint0); |
int_register(1, "swint1", swint1); |
timer_start(); |
} |
irq_init(IRQ_COUNT, IRQ_COUNT); |
|
static void ipc_int(int n, istate_t *istate) |
{ |
ipc_irq_send_notif(n-INT_OFFSET); |
} |
irq_initialize(&timer_irq); |
timer_irq.devno = device_assign_devno(); |
timer_irq.inr = TIMER_IRQ; |
timer_irq.claim = timer_claim; |
timer_irq.handler = timer_irq_handler; |
irq_register(&timer_irq); |
|
/* Reregister irq to be IPC-ready */ |
void irq_ipc_bind_arch(unative_t irq) |
{ |
/* Do not allow to redefine timer */ |
/* Swint0, Swint1 are already handled */ |
if (irq == TIMER_IRQ || irq < 2) |
return; |
int_register(irq, "ipc_int", ipc_int); |
timer_start(); |
cp0_unmask_int(TIMER_IRQ); |
} |
|
/** @} |