Cleanup Interrupt
This commit is contained in:
@ -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
|
||||
)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,9 +13,10 @@
|
||||
#ifndef IntDispatcher_include__
|
||||
#define IntDispatcher_include__
|
||||
|
||||
#include <cstdint>
|
||||
#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<ISR *, 256> handlerMap = {nullptr};
|
||||
|
||||
static NamedLogger log;
|
||||
};
|
||||
|
||||
}
|
||||
|
11
src/kernel/interrupt/interrupt_asm.cpp
Normal file
11
src/kernel/interrupt/interrupt_asm.cpp
Normal file
@ -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<Kernel::InterruptService>();
|
||||
interruptService.dispatchInterrupt(static_cast<Kernel::IntDispatcher::Vector>(vector));
|
||||
}
|
||||
|
@ -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<Kernel::InterruptService>()
|
||||
.dispatchInterrupt(static_cast<Kernel::IntDispatcher::Vector>(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
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user