Basic framework for getting interrupts to go, but alas nothing yet...

This commit is contained in:
Eryn Wells 2016-03-13 13:17:08 -04:00
parent c9c64b154a
commit 46d18b97d5
3 changed files with 143 additions and 0 deletions

View file

@ -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");
}

View file

@ -15,6 +15,7 @@ files = [
'Interrupts.cc',
'PIC.cc',
'cxa.cc',
'isr.S',
]
toolchain_bin = Dir(os.environ['POLKA_TOOLCHAIN']).Dir('bin')

69
src/isr.S Normal file
View file

@ -0,0 +1,69 @@
# isr.s
# Eryn Wells <eryn@erynwells.me>
# 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