2017-11-03 01:10:07 -04:00
|
|
|
#include "hwint.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"
|
|
|
|
|
|
|
|
struct IsrRegisters {
|
|
|
|
unsigned int ds; // Data segment selector
|
|
|
|
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
|
|
|
|
unsigned int int_no, err_code; // Interrupt number and error code (if applicable)
|
|
|
|
unsigned int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *const messages[] = {
|
2017-11-02 22:57:19 -04:00
|
|
|
"Unhandled hardware interrupt: 0",
|
|
|
|
"Unhandled hardware interrupt: 1",
|
|
|
|
"Unhandled hardware interrupt: 2",
|
|
|
|
"Unhandled hardware interrupt: 3",
|
|
|
|
"Unhandled hardware interrupt: 4",
|
|
|
|
"Unhandled hardware interrupt: 5",
|
|
|
|
"Unhandled hardware interrupt: 6",
|
|
|
|
"Unhandled hardware interrupt: 7",
|
|
|
|
"Unhandled hardware interrupt: 8",
|
|
|
|
"Unhandled hardware interrupt: 9",
|
|
|
|
"Unhandled hardware interrupt: 10",
|
|
|
|
"Unhandled hardware interrupt: 11",
|
|
|
|
"Unhandled hardware interrupt: 12",
|
|
|
|
"Unhandled hardware interrupt: 13",
|
|
|
|
"Unhandled hardware interrupt: 14",
|
|
|
|
"Unhandled hardware interrupt: 15",
|
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-02 23:14:46 -04:00
|
|
|
if (
|
|
|
|
!(regs.int_no >= INT_HWINT_FIRST &&
|
|
|
|
regs.int_no <= INT_HWINT_LAST)
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-11-02 23:25:01 -04:00
|
|
|
// Send an EOI (end of interrupt) signal to the PICs
|
|
|
|
|
|
|
|
if (regs.int_no >= 40) { // TODO: hardcoded
|
|
|
|
// Send reset signal to slave
|
2017-11-03 00:04:14 -04:00
|
|
|
outportb(0xA0, 0x20); // TODO: hardcoded
|
2017-11-02 23:25:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Send reset signal to master
|
2017-11-03 00:04:14 -04:00
|
|
|
outportb(0x20, 0x20); // TODO: hardcoded
|
2017-11-02 23:25:01 -04:00
|
|
|
|
2017-11-02 23:14:46 -04:00
|
|
|
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) {
|
|
|
|
logger_warn(messages[hwint_no]);
|
|
|
|
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-02 22:51:24 -04:00
|
|
|
}
|