aboutsummaryrefslogtreecommitdiff
path: root/src/idt.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/idt.h')
-rw-r--r--src/idt.h61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/idt.h b/src/idt.h
new file mode 100644
index 0000000..3aa5a1e
--- /dev/null
+++ b/src/idt.h
@@ -0,0 +1,61 @@
+#pragma once
+
+#include <types.h>
+
+class IDT {
+public:
+ struct Pointer {
+ uint16_t limit;
+ uint32_t base;
+ } __attribute__((packed));
+
+ enum InterruptType : uint8_t {
+ Null = 0,
+ InterruptGate = 0b110, // hardware interrupts are disabled while the handler runs
+ TrapGate = 0b111, // hardware interrupts remain active while the handler runs
+ TaskGate = 0b101, // selector points to TSS rather than a code segment
+ };
+
+ class Entry {
+ public:
+ Entry(uint32_t offset = 0, uint16_t select = 0, InterruptType t = Null) {
+ offset_0_15 = offset & 0xffff;
+ offset_16_31 = (offset & 0xffff0000) >> 16;
+ selector = select;
+ type = t;
+ }
+
+ private:
+ uint16_t offset_0_15; // 0-15 offset in the segment
+ uint16_t selector; // 16-31 selector of the code segment
+ [[maybe_unused]] uint8_t null = 0; // 32-39 unused in protected mode
+ InterruptType type : 3; // 40-42 type
+ [[maybe_unused]] bool d : 1 = true; // 43 true: 32-bit, false: 16-bit segment
+ [[maybe_unused]] uint8_t u : 1 = 0; // 44 unused
+ uint8_t dpl : 2 = 0; // 45-46 descriptor privilege level
+ [[maybe_unused]] bool e : 1 = true; // 47 enable
+ uint16_t offset_16_31; // 48-63 offset high
+ } __attribute__((packed));
+
+ IDT();
+
+private:
+ Entry table[256];
+};
+
+struct interrupt_frame {
+ uword_t ip;
+ uword_t cs;
+ uword_t flags;
+ uword_t sp;
+ uword_t ss;
+};
+
+/* https://wiki.osdev.org/Interrupt_Service_Routines */
+template <uint8_t irq>
+__attribute__((interrupt)) void kirq(interrupt_frame* frame);
+
+template <>
+void kirq<0x0>(interrupt_frame* frame);
+template <>
+void kirq<0x1>(interrupt_frame* frame);