2017-11-03 01:10:07 -04:00
|
|
|
#include "hwint.h"
|
|
|
|
|
2017-11-05 07:44:57 -05:00
|
|
|
#include "interrupt.h"
|
2017-11-02 23:14:46 -04:00
|
|
|
#include "config.h"
|
2017-11-02 23:25:01 -04:00
|
|
|
#include "asm.h"
|
2017-11-02 22:51:24 -04:00
|
|
|
#include "logger.h"
|
2017-11-06 05:57:55 -05:00
|
|
|
#include "pic.h"
|
2017-11-02 22:51:24 -04:00
|
|
|
|
2017-11-03 01:10:07 -04:00
|
|
|
static hwint_handler_t handlers[INT_HWINT_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
|
|
|
2017-11-02 22:51:24 -04:00
|
|
|
void hwint_handler(struct IsrRegisters regs)
|
|
|
|
{
|
2017-11-06 05:59:52 -05:00
|
|
|
if (!pic_end_of_interrupt(regs.int_no)) {
|
2017-11-02 23:14:46 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const unsigned char hwint_no = regs.int_no - INT_HWINT_FIRST;
|
|
|
|
|
2017-11-03 01:10:07 -04:00
|
|
|
const hwint_handler_t handler = handlers[hwint_no];
|
|
|
|
|
|
|
|
if (!handler) {
|
2017-11-06 07:19:11 -05:00
|
|
|
logger_warn_from("hwint", "Unhandled hardware interrupt: %u", hwint_no);
|
2017-11-03 01:10:07 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
handler();
|
|
|
|
}
|
|
|
|
|
|
|
|
void hwint_register_handler(unsigned int int_no, hwint_handler_t handler)
|
|
|
|
{
|
|
|
|
if (int_no >= INT_HWINT_COUNT) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
handlers[int_no] = handler;
|
2017-11-06 06:49:53 -05:00
|
|
|
pic_enable(int_no);
|
2017-11-02 22:51:24 -04:00
|
|
|
}
|
2017-11-06 07:06:28 -05:00
|
|
|
|
|
|
|
void hwint_unregister_handler(unsigned int int_no)
|
|
|
|
{
|
|
|
|
if (int_no >= INT_HWINT_COUNT) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_disable(int_no);
|
|
|
|
handlers[int_no] = 0;
|
|
|
|
}
|