2020-05-03 23:10:49 +02:00
|
|
|
#include <kernel/drivers/vbr.h>
|
2020-03-15 00:56:31 +01:00
|
|
|
#include <kernel/devices/earlyterm.h>
|
2020-05-03 23:10:49 +02:00
|
|
|
#include <kernel/util/atomic.h>
|
2019-12-16 16:25:13 +01:00
|
|
|
|
2020-05-03 23:10:49 +02:00
|
|
|
// TODO: update me
|
2019-12-16 16:25:13 +01:00
|
|
|
void interrupt_handler(void)
|
|
|
|
{
|
2020-05-03 23:10:49 +02:00
|
|
|
extern void (*int_handler[VBR_INTERRUPT_NB])(void);
|
2019-12-16 16:25:13 +01:00
|
|
|
uint32_t intevt = *(uint32_t*)0xff000028;
|
2020-05-03 23:10:49 +02:00
|
|
|
int id;
|
2019-12-16 16:25:13 +01:00
|
|
|
|
2020-05-03 23:10:49 +02:00
|
|
|
// Get the interrupt ID
|
|
|
|
VBR_GET_INTERRUPT_CODE(id, intevt);
|
2019-12-16 16:25:13 +01:00
|
|
|
|
2020-05-03 23:10:49 +02:00
|
|
|
// Check id validity and handler error
|
|
|
|
if (id < 0 || id >= VBR_INTERRUPT_NB || int_handler[id] == NULL)
|
2019-12-16 16:25:13 +01:00
|
|
|
{
|
2020-05-03 23:10:49 +02:00
|
|
|
earlyterm_write(
|
|
|
|
"Ho crap ! Interrupt error !\n"
|
|
|
|
"Interrupt ID (%#x)\n"
|
|
|
|
"Error: handler not foud !\n",
|
|
|
|
intevt
|
|
|
|
);
|
|
|
|
while (1);
|
2019-12-16 16:25:13 +01:00
|
|
|
}
|
|
|
|
|
2020-05-03 23:10:49 +02:00
|
|
|
// Call handler and exit
|
|
|
|
(*int_handler[id])();
|
|
|
|
}
|
|
|
|
|
|
|
|
void *vbr_interrupt_set(int intcode, void (*handler)(void))
|
|
|
|
{
|
|
|
|
extern void (*int_handler[VBR_INTERRUPT_NB])(void);
|
|
|
|
void *old;
|
|
|
|
int id;
|
|
|
|
|
|
|
|
// Get the interrupt ID
|
|
|
|
VBR_GET_INTERRUPT_CODE(id, intcode);
|
|
|
|
|
|
|
|
// Check id validity
|
|
|
|
if (id < 0 || id >= VBR_INTERRUPT_NB)
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
// Start atomic operations
|
|
|
|
atomic_start();
|
|
|
|
|
|
|
|
// Switch interupt handler
|
|
|
|
old = int_handler[id];
|
|
|
|
int_handler[id] = handler;
|
|
|
|
|
|
|
|
// Stop atomic operations
|
|
|
|
atomic_stop();
|
|
|
|
|
|
|
|
// Return old interrupt handler
|
|
|
|
return (old);
|
2019-12-16 16:25:13 +01:00
|
|
|
}
|