aboutsummaryrefslogtreecommitdiff
path: root/src/idt.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/idt.cc')
-rw-r--r--src/idt.cc30
1 files changed, 21 insertions, 9 deletions
diff --git a/src/idt.cc b/src/idt.cc
index 68ae260..363afcd 100644
--- a/src/idt.cc
+++ b/src/idt.cc
@@ -1,22 +1,24 @@
#include "idt.h"
#include <stdlib.h>
#include "cpu/irq.h"
+#include "cpu/registers.h"
#include "ports.h"
static_assert(sizeof(IDT::Pointer) == 6);
+constexpr uint8_t irq_base = 0x20;
static InterruptHandler* handlers[256] = {nullptr};
bool IDT::install(uint8_t irq, InterruptHandler* h) {
- if (h != nullptr && handlers[irq] == nullptr) {
- handlers[irq] = h;
+ if (h != nullptr && handlers[irq + irq_base] == nullptr) {
+ handlers[irq + irq_base] = h;
return true;
}
return false;
}
bool IDT::uninstall(uint8_t irq, InterruptHandler* h) {
- if (handlers[irq] == h) {
- handlers[irq] = nullptr;
+ if (handlers[irq + irq_base] == h) {
+ handlers[irq + irq_base] = nullptr;
return true;
}
return false;
@@ -37,18 +39,28 @@ bool IDT::uninstall(uint8_t irq, InterruptHandler* h) {
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
-extern "C" uint32_t handle_interrupt(uint8_t irq, uint32_t esp) {
- if (handlers[irq] != nullptr) {
- handlers[irq]->trigger();
+extern "C" void print_exception(cpu_state_t* r) {
+ printk("exception ", uhex{r->irq}, " error ", uhex{r->error}, '\n');
+ asm volatile("cli");
+ while (true) asm volatile("hlt");
+ __builtin_unreachable();
+};
+
+extern "C" uint32_t handle_interrupt(cpu_state_t* r) {
+ if (r->irq < irq_base) print_exception(r);
+
+ if (handlers[r->irq] != nullptr) {
+ handlers[r->irq]->trigger();
}
pic1_t pic1;
pic1.write(0x20);
- if (irq > 7) {
+ if (r->irq > 7 + irq_base) {
pic2_t pic2;
pic2.write(0x20);
}
- return esp;
+
+ return reinterpret_cast<uint32_t>(r);
};
IDT::IDT(const uint16_t selector) {