BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / commit / d41a53cbc7d055b1c00cf0a339dbed6925f4f02c / proc / idt.c

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)
diff --git a/proc/idt.c b/proc/idt.c
new file mode 100644
index 0000000..a1552c2
--- /dev/null
+++ b/proc/idt.c
@@ -0,0 +1,148 @@
+/*
+ * 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 "proc.h"
+#include "../mem/heap.h"
+#include "../mem/frame.h"
+#include "../screen.h"
+
+/* Structure for IDT entry */
+static struct IDTEntry {
+	uint16_t offsetLower, selector;
+	uint8_t zero, typeAttr;
+	uint16_t offsetHigher;
+} __attribute__((packed)) *IDT;
+
+void load_idt(uint32_t ptr[2]);
+/* Exceptions */
+void exc0(void);
+void exc1(void);
+void exc2(void);
+void exc3(void);
+void exc4(void);
+void exc5(void);
+void exc6(void);
+void exc7(void);
+void exc8(void);
+void exc9(void);
+void exc10(void);
+void exc11(void);
+void exc12(void);
+void exc13(void);
+void exc14(void);
+void exc15(void);
+void exc16(void);
+void exc17(void);
+void exc18(void);
+void exc19(void);
+void exc20(void);
+void exc30(void);
+void exc128(void); /* syscall */
+/* Interrutps */
+void irq0(void);
+void irq1(void);
+void irq2(void);
+void irq3(void);
+void irq4(void);
+void irq5(void);
+void irq6(void);
+void irq7(void);
+void irq8(void);
+void irq9(void);
+void irq10(void);
+void irq11(void);
+void irq12(void);
+void irq13(void);
+void irq14(void);
+void irq15(void);
+
+extern void (**exceptions)(InterruptFrame *);
+extern void (**interrupts)(InterruptFrame *);
+
+/* Install an IDT entry */
+static void
+install_idt_entry(uint8_t num, uint32_t addr)
+{
+	IDT[num].offsetLower = addr & 0xFFFF;
+	IDT[num].selector = 0x08;
+	IDT[num].zero = 0;
+	IDT[num].typeAttr = 0x8E | 0x60; /* Allowed from ring 3 */
+	IDT[num].offsetHigher = addr >> 16;
+}
+
+/* Initialise the IDT */
+void
+init_idt(void)
+{
+	IDT = (void *) alloc_frames(1);
+
+	/* Install exceptions */
+	install_idt_entry(0, (uint32_t) exc0);
+	install_idt_entry(1, (uint32_t) exc1);
+	install_idt_entry(2, (uint32_t) exc2);
+	install_idt_entry(3, (uint32_t) exc3);
+	install_idt_entry(4, (uint32_t) exc4);
+	install_idt_entry(5, (uint32_t) exc5);
+	install_idt_entry(6, (uint32_t) exc6);
+	install_idt_entry(7, (uint32_t) exc7);
+	install_idt_entry(8, (uint32_t) exc8);
+	install_idt_entry(9, (uint32_t) exc9);
+	install_idt_entry(10, (uint32_t) exc10);
+	install_idt_entry(11, (uint32_t) exc11);
+	install_idt_entry(12, (uint32_t) exc12);
+	install_idt_entry(13, (uint32_t) exc13);
+	install_idt_entry(14, (uint32_t) exc14);
+	install_idt_entry(15, (uint32_t) exc15);
+	install_idt_entry(16, (uint32_t) exc16);
+	install_idt_entry(17, (uint32_t) exc17);
+	install_idt_entry(18, (uint32_t) exc18);
+	install_idt_entry(19, (uint32_t) exc19);
+	install_idt_entry(20, (uint32_t) exc20);
+	install_idt_entry(30, (uint32_t) exc30);
+
+	/* Install interrutps */
+	install_idt_entry(32, (uint32_t) irq0);
+	install_idt_entry(33, (uint32_t) irq1);
+	install_idt_entry(34, (uint32_t) irq2);
+	install_idt_entry(35, (uint32_t) irq3);
+	install_idt_entry(36, (uint32_t) irq4);
+	install_idt_entry(37, (uint32_t) irq5);
+	install_idt_entry(38, (uint32_t) irq6);
+	install_idt_entry(39, (uint32_t) irq7);
+	install_idt_entry(40, (uint32_t) irq8);
+	install_idt_entry(41, (uint32_t) irq9);
+	install_idt_entry(42, (uint32_t) irq10);
+	install_idt_entry(43, (uint32_t) irq11);
+	install_idt_entry(44, (uint32_t) irq12);
+	install_idt_entry(45, (uint32_t) irq13);
+	install_idt_entry(46, (uint32_t) irq14);
+	install_idt_entry(47, (uint32_t) irq15);
+
+	/* Install syscall handler */
+	install_idt_entry(128, (uint32_t) exc128);
+
+	exceptions = (void (**)(InterruptFrame *)) (IDT + 256);
+	interrupts = (void (**)(InterruptFrame *)) (exceptions + 32);
+	memset(exceptions, 0, 1024);
+
+	kprintf("Loaded IDT @ %#.8x, Exceptions @ %#.8x, Interrupts @ %#.8x",
+	        IDT, exceptions, interrupts);
+}
+
+/* Load the IDT */
+void
+cpu_load_idt(void)
+{
+	uint32_t idtAddr, idtPtr[2];
+	idtAddr = (uint32_t) IDT;
+	idtPtr[0] = sizeof(struct IDTEntry) * 256;
+	idtPtr[0] += (idtAddr & 0xFFFF) << 16;
+	idtPtr[1] = idtAddr >> 16;
+	load_idt(idtPtr);
+}