BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 232d0f9e7dd31316a9b91cbdfec0174afce40c7e / kernel / pic.c

// Related

Nucleus

Barry ACPI + APIC 232d0f9 (3 years, 3 months ago)
diff --git a/kernel/pic.c b/kernel/pic.c
new file mode 100644
index 0000000..566abb2
--- /dev/null
+++ b/kernel/pic.c
@@ -0,0 +1,42 @@
+/*
+ * This file deals with the Programmable Interrupt Controller.  It is usually
+ * disabled and replaced by the Advanced Programmable Interrupt Controller.  It
+ * is required to be enabled for the APIC to initialise, and can be used as a
+ * fallback if there is no APIC in the system.
+ */
+
+#include <stdint.h>
+#include <io.h>
+
+/* Initialise the PIT to a specified frequency */
+static void
+init_pit(uint32_t freq)
+{
+	uint32_t div = 1193182 / freq;
+	outb(0x43, 0x36);
+	outb(0x40, div & 0xFF);
+	outb(0x40, (div >> 8) & 0xFF);
+}
+
+/* Initialise the PIC */
+void
+init_pic(void)
+{
+	/*
+	 * By default interrupts and exceptions both start at IRQ#0.  To avoid
+	 * collision interrupts are mapped to start at IRQ#32.  Since lower
+	 * numbered IRQ lines are higher priority, exceptions have priority.
+	 */
+	outb(0x20, 0x11); io_wait();
+	outb(0xA0, 0x11); io_wait();
+	outb(0x21, 0x20); io_wait();
+	outb(0xA1, 0x28); io_wait();
+	outb(0x21, 0x04); io_wait();
+	outb(0xA1, 0x02); io_wait();
+	outb(0x21, 0x01); io_wait();
+	outb(0xA1, 0x01); io_wait();
+	outb(0x21, 0x00); io_wait();
+	outb(0xA1, 0x00); io_wait();
+
+	init_pit(1000);
+}