2016-03-09 01:17:13 -05:00
|
|
|
/* Interrupts.cc
|
|
|
|
* vim: set tw=80:
|
|
|
|
* Eryn Wells <eryn@erynwells.me>
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* Implementation of interrupt handers and things.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Interrupts.hh"
|
2016-03-09 01:23:06 -05:00
|
|
|
#include "Console.hh"
|
2016-03-09 01:17:13 -05:00
|
|
|
|
2016-03-13 13:17:08 -04:00
|
|
|
extern "C" {
|
|
|
|
void dispatchExceptionHandler(size_t vector);
|
|
|
|
|
|
|
|
// Assembly functions. See isr.S.
|
|
|
|
void unhandledInterrupt();
|
|
|
|
void handleDEException();
|
|
|
|
void handleDFException();
|
|
|
|
void handleGPException();
|
|
|
|
void handleHardwareInterrupt0();
|
|
|
|
void handleHardwareInterrupt1();
|
|
|
|
}
|
|
|
|
|
2016-03-09 01:17:13 -05:00
|
|
|
namespace x86 {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Static
|
|
|
|
*/
|
|
|
|
|
|
|
|
InterruptHandler&
|
|
|
|
InterruptHandler::systemInterruptHandler()
|
|
|
|
{
|
|
|
|
static InterruptHandler sInterruptHandler;
|
|
|
|
return sInterruptHandler;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Public
|
|
|
|
*/
|
|
|
|
|
|
|
|
InterruptHandler::InterruptHandler()
|
|
|
|
: mPIC(),
|
|
|
|
mIDT()
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
InterruptHandler::initialize()
|
|
|
|
{
|
2016-03-12 19:14:36 -05:00
|
|
|
auto& console = kernel::Console::systemConsole();
|
2016-03-09 01:23:06 -05:00
|
|
|
|
2016-03-13 13:17:08 -04:00
|
|
|
for (size_t i = 0; i < IDT::Size; i++) {
|
|
|
|
mIDT.setDescriptor(i, IDT::DescriptorSpec::exceptionHandler(1, &unhandledInterrupt));
|
|
|
|
}
|
2016-03-09 01:17:13 -05:00
|
|
|
mIDT.load();
|
2016-03-09 01:23:06 -05:00
|
|
|
console.writeString("Interrupt table loaded\n");
|
2016-03-13 12:53:28 -04:00
|
|
|
|
|
|
|
mPIC.initialize(0x20, 0x28); // Map hardware IRQs to interrupt vectors 32 through 48.
|
2016-03-09 01:23:06 -05:00
|
|
|
console.writeString("Hardware interrupts initialized\n");
|
2016-03-13 13:17:08 -04:00
|
|
|
|
|
|
|
// Enable the keyboard interrupt.
|
|
|
|
mPIC.enableInterrupt(1, true);
|
|
|
|
console.writeString("Enabling keyboard interrupt\n");
|
2016-03-09 01:17:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
InterruptHandler::enableInterrupts()
|
|
|
|
const
|
|
|
|
{
|
|
|
|
asm("sti");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
InterruptHandler::disableInterrupts()
|
|
|
|
const
|
|
|
|
{
|
|
|
|
asm("cli");
|
|
|
|
}
|
|
|
|
|
|
|
|
} /* namespace x86 */
|
2016-03-13 13:17:08 -04:00
|
|
|
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
void
|
|
|
|
doUnhandledInterrupt()
|
|
|
|
{
|
|
|
|
auto& console = kernel::Console::systemConsole();
|
|
|
|
console.writeString("Received unhandled interrupt.\nAbort. :(");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
void
|
|
|
|
dispatchExceptionHandler(size_t vector)
|
|
|
|
{
|
|
|
|
using x86::Interrupt;
|
|
|
|
|
|
|
|
auto& console = kernel::Console::systemConsole();
|
|
|
|
console.writeString("Received exception ");
|
|
|
|
switch (Interrupt(vector)) {
|
|
|
|
case Interrupt::DE:
|
|
|
|
console.writeString("#DE");
|
|
|
|
break;
|
|
|
|
case Interrupt::NMI:
|
|
|
|
console.writeString("NMI");
|
|
|
|
break;
|
|
|
|
case Interrupt::DF:
|
|
|
|
console.writeString("#DF");
|
|
|
|
break;
|
|
|
|
case Interrupt::GP:
|
|
|
|
console.writeString("#GP");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
console.writeString("SOME OTHER THING");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
console.writeString("\nAbort. :(");
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
void
|
|
|
|
handleTimerInterrupt()
|
|
|
|
{
|
|
|
|
auto& console = kernel::Console::systemConsole();
|
|
|
|
console.writeString("Thyme!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
void
|
|
|
|
handleKeyboardInterrupt()
|
|
|
|
{
|
|
|
|
auto& console = kernel::Console::systemConsole();
|
|
|
|
console.writeString("Key!\n");
|
|
|
|
}
|