BarryServer : Git

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

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)
diff --git a/proc/irqs.c b/proc/irqs.c
new file mode 100644
index 0000000..f9a523c
--- /dev/null
+++ b/proc/irqs.c
@@ -0,0 +1,80 @@
+/*
+ * This file contains the abstraction for exceptions and interrupts.  It
+ * presents a system of registrable exception/interrupt handlers.  It also
+ * contains the generic handlers, which pass control to the appropriate
+ * registered handler.  This file does not deal with dispatching
+ * messages/signals to processes on an interrupt.
+ */
+
+#include <stdint.h>
+#include "proc.h"
+#include "../proc/proc.h"
+#include "../task/task.h"
+#include "../io.h"
+#include "../screen.h"
+
+void (**exceptions)(InterruptFrame *);
+void (**interrupts)(InterruptFrame *);
+
+/* Register an exception handler */
+void
+register_exception(int num, void (*addr)(InterruptFrame *))
+{
+	if (num >= 0 && num < 32)
+		exceptions[num] = addr;
+}
+
+/* Register an interrupt handler */
+void
+register_interrupt(int num, void (*addr)(InterruptFrame *))
+{
+	if (num >= 0 && num < 224)
+		interrupts[num] = addr;
+}
+
+/* Call the appropriate exception handler */
+uintptr_t
+exc_handler(InterruptFrame frame)
+{
+	uint8_t num = frame.intNo & 0xFF;
+
+	/* System Call */
+	if (num == 0x80)
+		syscall_handler(&frame);
+	/* Other exception */
+	else if (exceptions[num])
+		exceptions[num](&frame);
+	else
+		panic("Unhandled exception %d (%#x) @ %#.8x [CPU#%d]\n"
+		      "EFLAGS: %#.8x",
+		      num, frame.errCode, frame.eip, CPUID, frame.eflags);
+
+	/* Send EOI */
+	LAPIC(0xB0) = 0;
+
+	if (current)
+		if (current->tls)
+			return current->tls->start + 4;
+	return 0;
+}
+
+/* Call the appropriate interrupt handler */
+uintptr_t
+irq_handler(InterruptFrame frame)
+{
+	uint8_t num = (frame.intNo & 0xFF) - 32;
+
+	if (interrupts[num])
+		interrupts[num](&frame);
+
+	/* Send EOI */
+	outb(0x20, 0x20);
+	if (num >= 8)
+		outb(0xA0, 0x20);
+	LAPIC(0xB0) = 0;
+
+	if (current)
+		if (current->tls)
+			return current->tls->start + 4;
+	return 0;
+}