BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / b33d632d85a31b49ca4a764fe3b644a60459387b / kernel / idt.c

// Related

Nucleus

Barry Interrupt handlers b33d632 (3 years, 3 months ago)
diff --git a/kernel/idt.c b/kernel/idt.c
new file mode 100644
index 0000000..4c594bb
--- /dev/null
+++ b/kernel/idt.c
@@ -0,0 +1,352 @@
+/*
+ * This file deals with the Interrupt Descriptor Table.  It creates a simple
+ * IDT, with hard-coded handler functions.  It is these handler functions that
+ * can run custom handlers, registered at runtime.  This file does not deal with
+ * dispatching messages/signals to processes on an interrupt.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <nucleus/panic.h>
+#include <nucleus/memory.h>
+#include <io.h>
+#include "idt.h"
+
+/* Structure for an IDT Entry */
+static struct IDTEntry {
+	uint16_t offsetLower, selector;
+	uint8_t zero, typeAttr;
+	uint16_t offsetHigher;
+} __attribute__((packed)) *IDT;
+
+void (**exceptions)(struct InterruptFrame *, uint32_t);
+void (**interrupts)(struct InterruptFrame *);
+
+/* Install an IDT Entry */
+static void
+install_idt_entry(uint8_t num, void *addr)
+{
+	IDT[num].offsetLower = (uintptr_t) addr & 0xFFFF;
+	IDT[num].selector = 0x08;
+	IDT[num].zero = 0;
+	IDT[num].typeAttr = 0x8E | 0x60; /* Allowed from ring 3 */
+	IDT[num].offsetHigher = (uintptr_t) addr >> 16;
+}
+
+/* First level generic exception handler */
+static void
+exc_handler(int num, struct InterruptFrame *frame, uint32_t err)
+{
+	ASSERT(exceptions[num]);
+	exceptions[num](frame, err);
+
+	/* TODO: Send APIC EOI */
+}
+
+/* First level generic interrupt handler */
+static void
+int_handler(int num, struct InterruptFrame *frame)
+{
+	if (interrupts[num - 32])
+		interrupts[num - 32](frame);
+
+	/* Send EOI */
+	if (num >= 8)
+		outb(0xA0, 0x20);
+	outb(0x20, 0x20);
+	/* TODO: Send APIC EOI*/
+}
+
+/* Exceptions */
+__attribute__((interrupt))
+static void
+exc0(struct InterruptFrame *frame)
+{
+	exc_handler(0, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc1(struct InterruptFrame *frame)
+{
+	exc_handler(1, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc2(struct InterruptFrame *frame)
+{
+	exc_handler(2, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc3(struct InterruptFrame *frame)
+{
+	exc_handler(3, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc4(struct InterruptFrame *frame)
+{
+	exc_handler(4, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc5(struct InterruptFrame *frame)
+{
+	exc_handler(5, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc6(struct InterruptFrame *frame)
+{
+	exc_handler(6, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc7(struct InterruptFrame *frame)
+{
+	exc_handler(7, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc8(struct InterruptFrame *frame, uint32_t err)
+{
+	exc_handler(8, frame, err);
+}
+__attribute__((interrupt))
+static void
+exc9(struct InterruptFrame *frame)
+{
+	exc_handler(9, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc10(struct InterruptFrame *frame, uint32_t err)
+{
+	exc_handler(10, frame, err);
+}
+__attribute__((interrupt))
+static void
+exc11(struct InterruptFrame *frame, uint32_t err)
+{
+	exc_handler(11, frame, err);
+}
+__attribute__((interrupt))
+static void
+exc12(struct InterruptFrame *frame, uint32_t err)
+{
+	exc_handler(12, frame, err);
+}
+__attribute__((interrupt))
+static void
+exc13(struct InterruptFrame *frame, uint32_t err)
+{
+	exc_handler(13, frame, err);
+}
+__attribute__((interrupt))
+static void
+exc14(struct InterruptFrame *frame, uint32_t err)
+{
+	exc_handler(14, frame, err);
+}
+__attribute__((interrupt))
+static void
+exc15(struct InterruptFrame *frame)
+{
+	exc_handler(15, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc16(struct InterruptFrame *frame)
+{
+	exc_handler(16, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc17(struct InterruptFrame *frame, uint32_t err)
+{
+	exc_handler(17, frame, err);
+}
+__attribute__((interrupt))
+static void
+exc18(struct InterruptFrame *frame)
+{
+	exc_handler(18, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc19(struct InterruptFrame *frame)
+{
+	exc_handler(19, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc20(struct InterruptFrame *frame)
+{
+	exc_handler(20, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc30(struct InterruptFrame *frame)
+{
+	exc_handler(30, frame, 0);
+}
+__attribute__((interrupt))
+static void
+exc128(struct InterruptFrame *frame)
+{
+	exc_handler(128, frame, 0);
+}
+
+/* Interrupts */
+__attribute__((interrupt))
+static void
+int0(struct InterruptFrame *frame)
+{
+	int_handler(32, frame);
+}
+__attribute__((interrupt))
+static void
+int1(struct InterruptFrame *frame)
+{
+	int_handler(33, frame);
+}
+__attribute__((interrupt))
+static void
+int2(struct InterruptFrame *frame)
+{
+	int_handler(34, frame);
+}
+__attribute__((interrupt))
+static void
+int3(struct InterruptFrame *frame)
+{
+	int_handler(35, frame);
+}
+__attribute__((interrupt))
+static void
+int4(struct InterruptFrame *frame)
+{
+	int_handler(36, frame);
+}
+__attribute__((interrupt))
+static void
+int5(struct InterruptFrame *frame)
+{
+	int_handler(37, frame);
+}
+__attribute__((interrupt))
+static void
+int6(struct InterruptFrame *frame)
+{
+	int_handler(38, frame);
+}
+__attribute__((interrupt))
+static void
+int7(struct InterruptFrame *frame)
+{
+	int_handler(39, frame);
+}
+__attribute__((interrupt))
+static void
+int8(struct InterruptFrame *frame)
+{
+	int_handler(40, frame);
+}
+__attribute__((interrupt))
+static void
+int9(struct InterruptFrame *frame)
+{
+	int_handler(41, frame);
+}
+__attribute__((interrupt))
+static void
+int10(struct InterruptFrame *frame)
+{
+	int_handler(42, frame);
+}
+__attribute__((interrupt))
+static void
+int11(struct InterruptFrame *frame)
+{
+	int_handler(43, frame);
+}
+__attribute__((interrupt))
+static void
+int12(struct InterruptFrame *frame)
+{
+	int_handler(44, frame);
+}
+__attribute__((interrupt))
+static void
+int13(struct InterruptFrame *frame)
+{
+	int_handler(45, frame);
+}
+__attribute__((interrupt))
+static void
+int14(struct InterruptFrame *frame)
+{
+	int_handler(46, frame);
+}
+__attribute__((interrupt))
+static void
+int15(struct InterruptFrame *frame)
+{
+	int_handler(47, frame);
+}
+
+/* Initialise the IDT */
+void
+init_idt(void)
+{
+	IDT = (void *) alloc_frame();
+
+	/* Install exceptions */
+	install_idt_entry(0, exc0);
+	install_idt_entry(1, exc1);
+	install_idt_entry(2, exc2);
+	install_idt_entry(3, exc3);
+	install_idt_entry(4, exc4);
+	install_idt_entry(5, exc5);
+	install_idt_entry(6, exc6);
+	install_idt_entry(7, exc7);
+	install_idt_entry(8, exc8);
+	install_idt_entry(9, exc9);
+	install_idt_entry(10, exc10);
+	install_idt_entry(11, exc11);
+	install_idt_entry(12, exc12);
+	install_idt_entry(13, exc13);
+	install_idt_entry(14, exc14);
+	install_idt_entry(15, exc15);
+	install_idt_entry(16, exc16);
+	install_idt_entry(17, exc17);
+	install_idt_entry(18, exc18);
+	install_idt_entry(19, exc19);
+	install_idt_entry(20, exc20);
+	install_idt_entry(30, exc30);
+
+	/* Install interrupts */
+	install_idt_entry(32, int0);
+	install_idt_entry(33, int1);
+	install_idt_entry(34, int2);
+	install_idt_entry(35, int3);
+	install_idt_entry(36, int4);
+	install_idt_entry(37, int5);
+	install_idt_entry(38, int6);
+	install_idt_entry(39, int7);
+	install_idt_entry(40, int8);
+	install_idt_entry(41, int9);
+	install_idt_entry(42, int10);
+	install_idt_entry(43, int11);
+	install_idt_entry(44, int12);
+	install_idt_entry(45, int13);
+	install_idt_entry(46, int14);
+	install_idt_entry(47, int15);
+
+	/* Install system call handler */
+	install_idt_entry(128, exc128);
+
+	exceptions = (void *) (IDT + 256);
+	interrupts = (void *) (exceptions + 32);
+	memset(exceptions, 0, 1024);
+}