diff --git a/cmake/kernel/interrupt/CMakeLists.txt b/cmake/kernel/interrupt/CMakeLists.txt index fc8300c..78f77e9 100644 --- a/cmake/kernel/interrupt/CMakeLists.txt +++ b/cmake/kernel/interrupt/CMakeLists.txt @@ -2,4 +2,5 @@ cmake_minimum_required(VERSION 3.14) target_sources(kernel PUBLIC ${CHURLOS_SRC_DIR}/kernel/interrupt/IntDispatcher.cc + ${CHURLOS_SRC_DIR}/kernel/interrupt/interrupt_asm.cpp ) diff --git a/src/kernel/interrupt/IntDispatcher.cc b/src/kernel/interrupt/IntDispatcher.cc index 5211030..20b0ddc 100755 --- a/src/kernel/interrupt/IntDispatcher.cc +++ b/src/kernel/interrupt/IntDispatcher.cc @@ -1,44 +1,18 @@ -/***************************************************************************** - * * - * I N T D I S P A T C H E R * - * * - *---------------------------------------------------------------------------* - * Beschreibung: Zentrale Unterbrechungsbehandlungsroutine des Systems. * - * Der Parameter gibt die Nummer des aufgetretenen * - * Interrupts an. Wenn eine Interrupt Service Routine * - * registriert ist, wird diese aufgerufen. * - * * - * Autor: Michael Schoettner, 31.8.2016 * - *****************************************************************************/ #include "IntDispatcher.h" #include "device/cpu/CPU.h" -#include "kernel/system/Globals.h" #include "kernel/exception/Bluescreen.h" #include "lib/util/System.h" namespace Kernel { -NamedLogger IntDispatcher::log = NamedLogger("IntDispatcher"); - -int IntDispatcher::assign(uint8_t vector, ISR &isr) { - - /* hier muss Code eingefuegt werden */ - +void IntDispatcher::assign(uint8_t vector, ISR &isr) { handlerMap[vector] = &isr; - log.info() << "Registered ISR for vector " << dec << vector << endl; // TODO: Numbers don't show up in log - - return 0; } -int IntDispatcher::dispatch(uint8_t vector) { - - /* hier muss Code eingefuegt werden */ - +void IntDispatcher::dispatch(uint8_t vector) { ISR *isr = handlerMap[vector]; if (isr == nullptr) { - log.error() << "No ISR registered for vector " << vector << endl; // TODO: Numbers don't show up in log - // TODO: Throw exception Util::System::out << "Panic: unexpected interrupt " << vector; @@ -47,8 +21,6 @@ int IntDispatcher::dispatch(uint8_t vector) { } isr->trigger(); - - return 0; } } diff --git a/src/kernel/interrupt/IntDispatcher.h b/src/kernel/interrupt/IntDispatcher.h index 8e3ad4f..5c16afe 100755 --- a/src/kernel/interrupt/IntDispatcher.h +++ b/src/kernel/interrupt/IntDispatcher.h @@ -13,9 +13,10 @@ #ifndef IntDispatcher_include__ #define IntDispatcher_include__ +#include #include "ISR.h" -#include "lib/container//Array.h" -#include "lib/stream/Logger.h" +#include "lib/container/Array.h" +#include "lib/util/RestrictedConstructors.h" namespace Kernel { @@ -23,7 +24,9 @@ class IntDispatcher { friend class InterruptService; public: - // Vektor-Nummern + /** + * Vector numbers (slots in the IDT) + */ enum Vector { TIMER = 32, KEYBOARD = 33, @@ -31,23 +34,19 @@ public: }; public: - IntDispatcher() = default; + MakeDefault(IntDispatcher) - IntDispatcher(const IntDispatcher ©) = delete; // Verhindere Kopieren + MakeUnmovable(IntDispatcher) - // TODO: Rest of constructors + MakeUncopyable(IntDispatcher) private: - // Registrierung einer ISR. (Rueckgabewert: 0 = Erfolg, -1 = Fehler) - int assign(uint8_t vector, ISR &isr); + void assign(uint8_t vector, ISR &isr); - // ISR fuer 'vector' ausfuehren - int dispatch(uint8_t vector); + void dispatch(uint8_t vector); private: Container::Array handlerMap = {nullptr}; - - static NamedLogger log; }; } diff --git a/src/kernel/interrupt/interrupt_asm.cpp b/src/kernel/interrupt/interrupt_asm.cpp new file mode 100644 index 0000000..da4a44f --- /dev/null +++ b/src/kernel/interrupt/interrupt_asm.cpp @@ -0,0 +1,11 @@ +#include "IntDispatcher.h" +#include "kernel/system/System.h" +#include "kernel/service/InterruptService.h" + +extern "C" void int_disp(uint8_t vector); + +void int_disp(uint8_t vector) { + auto &interruptService = Kernel::System::getService(); + interruptService.dispatchInterrupt(static_cast(vector)); +} + diff --git a/src/kernel/service/InterruptService.cpp b/src/kernel/service/InterruptService.cpp index d822a03..db1d4f4 100644 --- a/src/kernel/service/InterruptService.cpp +++ b/src/kernel/service/InterruptService.cpp @@ -1,39 +1,47 @@ #include "InterruptService.h" -#include "kernel/exception/Bluescreen.h" #include "device/cpu/CPU.h" -#include "kernel/system/System.h" +#include "kernel/exception/Bluescreen.h" -// TODO: Move to interrupt_interface or sth. -extern "C" void int_disp(uint8_t vector); +namespace Kernel { -void int_disp(uint8_t vector) { +NamedLogger InterruptService::log = NamedLogger("InterruptService"); - /* hier muss Code eingefuegt werden */ +void InterruptService::assignInterrupt(IntDispatcher::Vector vector, ISR &isr) { + intDispatcher.assign(vector, isr); + log.info() << "Assigned ISR for vector " << dec << vector << endl; +} - // Exception - if (vector < 32) { +void InterruptService::dispatchInterrupt(IntDispatcher::Vector vector) { + if (isException(vector)) { bs_dump(vector); Device::CPU::halt(); // TODO: Exception } - Kernel::System::getService() - .dispatchInterrupt(static_cast(vector)); -} + if (isSpurious(vector)) { + ++spuriousCounter; + log.info() << "Intercepted Spurious Interrupt" << endl; + return; + } -namespace Kernel { + sendEndOfInterrupt(); // TODO: Check when to send EOI with the PIC -void InterruptService::assignInterrupt(IntDispatcher::Vector vector, ISR &isr) { - intDispatcher.assign(vector, isr); -} - -void InterruptService::dispatchInterrupt(IntDispatcher::Vector vector) { intDispatcher.dispatch(vector); } +bool InterruptService::isException(IntDispatcher::Vector vector) { + return vector < IntDispatcher::TIMER; +} + +bool InterruptService::isSpurious(IntDispatcher::Vector vector) { + // TODO + return false; +} + void InterruptService::allowInterrupt(Device::PIC::Irq irq) { Device::PIC::allow(irq); + log.info() << "Allowed IRQ" << dec << irq << endl; } void InterruptService::forbidInterrupt(Device::PIC::Irq irq) { @@ -44,4 +52,8 @@ bool InterruptService::status(Device::PIC::Irq irq) { return Device::PIC::status(irq); } +void InterruptService::sendEndOfInterrupt() { + // TODO +} + } \ No newline at end of file diff --git a/src/kernel/service/InterruptService.h b/src/kernel/service/InterruptService.h index b528e9c..257d547 100644 --- a/src/kernel/service/InterruptService.h +++ b/src/kernel/service/InterruptService.h @@ -4,6 +4,7 @@ #include "Service.h" #include "kernel/interrupt/IntDispatcher.h" #include "device/interrupt/PIC.h" +#include "lib/stream/Logger.h" namespace Kernel { @@ -25,6 +26,8 @@ public: void dispatchInterrupt(IntDispatcher::Vector vector); + bool isException(IntDispatcher::Vector vector); + bool isSpurious(IntDispatcher::Vector vector); void allowInterrupt(Device::PIC::Irq irq); @@ -37,6 +40,10 @@ public: private: IntDispatcher intDispatcher; + + uint32_t spuriousCounter; + + static NamedLogger log; }; }