diff --git a/src/Interrupts.cc b/src/Interrupts.cc index 908a140..9b7fa35 100644 --- a/src/Interrupts.cc +++ b/src/Interrupts.cc @@ -9,6 +9,18 @@ #include "Interrupts.hh" #include "Console.hh" +extern "C" { + void dispatchExceptionHandler(size_t vector); + + // Assembly functions. See isr.S. + void unhandledInterrupt(); + void handleDEException(); + void handleDFException(); + void handleGPException(); + void handleHardwareInterrupt0(); + void handleHardwareInterrupt1(); +} + namespace x86 { /* @@ -37,11 +49,18 @@ InterruptHandler::initialize() { auto& console = kernel::Console::systemConsole(); + for (size_t i = 0; i < IDT::Size; i++) { + mIDT.setDescriptor(i, IDT::DescriptorSpec::exceptionHandler(1, &unhandledInterrupt)); + } mIDT.load(); console.writeString("Interrupt table loaded\n"); mPIC.initialize(0x20, 0x28); // Map hardware IRQs to interrupt vectors 32 through 48. console.writeString("Hardware interrupts initialized\n"); + + // Enable the keyboard interrupt. + mPIC.enableInterrupt(1, true); + console.writeString("Enabling keyboard interrupt\n"); } @@ -61,3 +80,57 @@ InterruptHandler::disableInterrupts() } } /* namespace x86 */ + + +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"); +} diff --git a/src/SConscript b/src/SConscript index b974fa5..7d703d1 100644 --- a/src/SConscript +++ b/src/SConscript @@ -15,6 +15,7 @@ files = [ 'Interrupts.cc', 'PIC.cc', 'cxa.cc', + 'isr.S', ] toolchain_bin = Dir(os.environ['POLKA_TOOLCHAIN']).Dir('bin') diff --git a/src/isr.S b/src/isr.S new file mode 100644 index 0000000..4010c7d --- /dev/null +++ b/src/isr.S @@ -0,0 +1,69 @@ +# isr.s +# Eryn Wells + +# Interrupt service routine. See also: Interrupts.cc. + +.section .text +.global unhandledInterrupt +.global handleDEException, handleGPException +.global handleHardwareInterrupt0, handleHardwareInterrupt1 + +#define SaveContext \ + pushal; \ + cld; + +#define RestoreContext \ + popal; \ + iret + +#define RestoreContextAndHalt \ + popal; \ + cli; \ + hlt + +// Generic handler +unhandledInterrupt: + SaveContext + call doUnhandledInterrupt + RestoreContextAndHalt + +// Divide error +handleDEException: + SaveContext + pushl $0 + call dispatchExceptionHandler + add $4, %esp + RestoreContextAndHalt + +// Double fault +handleDFException: + SaveContext + pushl $0x08 + call dispatchExceptionHandler + add $4, %esp + RestoreContextAndHalt + +// General Protection fault +handleGPException: + SaveContext + pushl $0x0D + call dispatchExceptionHandler + add $4, %esp + RestoreContextAndHalt + +/* + * Hardware Interrupts + */ + +handleHardwareInterrupt0: + SaveContext + call handleTimerInterrupt + RestoreContext + +handleHardwareInterrupt1: + SaveContext + call handleKeyboardInterrupt + RestoreContext + +#undef RestoreContext +#undef SaveContext