summaryrefslogtreecommitdiffhomepage
path: root/src/loader/pic.c
diff options
context:
space:
mode:
authorMarvin Borner2021-07-05 18:28:40 +0200
committerMarvin Borner2021-07-05 18:28:40 +0200
commitd1476974cd612412eefc40c6dc72ba66191136fd (patch)
tree74fa7b96337bed895aff5fa268131fc9e3961f97 /src/loader/pic.c
parent4e5b18fb3284705904a2f15f790b8c15b5767fd0 (diff)
Added interrupt handling
Diffstat (limited to 'src/loader/pic.c')
-rw-r--r--src/loader/pic.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/loader/pic.c b/src/loader/pic.c
new file mode 100644
index 0000000..18b248c
--- /dev/null
+++ b/src/loader/pic.c
@@ -0,0 +1,64 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#include <cpu.h>
+#include <pic.h>
+
+#define PIC1 0x20
+#define PIC1_COMMAND PIC1
+#define PIC1_OFFSET 0x20
+#define PIC1_DATA (PIC1 + 1)
+
+#define PIC2 0xa0
+#define PIC2_COMMAND PIC2
+#define PIC2_OFFSET 0x28
+#define PIC2_DATA (PIC2 + 1)
+
+#define ICW1_ICW4 0x01
+#define ICW1_INIT 0x10
+
+static void pic_wait(void)
+{
+ __asm__ volatile("jmp 1f\n\t"
+ "1:\n\t"
+ " jmp 2f\n\t"
+ "2:");
+}
+
+void pic_install(void)
+{
+ // Initialize
+ outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);
+ pic_wait();
+ outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
+ pic_wait();
+
+ // Remap
+ outb(PIC1_DATA, PIC1_OFFSET);
+ pic_wait();
+ outb(PIC2_DATA, PIC2_OFFSET);
+ pic_wait();
+
+ outb(PIC1_DATA, 0x04);
+ pic_wait();
+ outb(PIC2_DATA, 0x02);
+ pic_wait();
+
+ // Set 8086 mode
+ outb(PIC1_DATA, 0x01);
+ pic_wait();
+ outb(PIC2_DATA, 0x01);
+ pic_wait();
+
+ outb(PIC1_DATA, 0x00);
+ pic_wait();
+ outb(PIC2_DATA, 0x00);
+ pic_wait();
+}
+
+void pic_ack(u32 int_no)
+{
+ if (int_no >= 40)
+ outb(PIC2, 0x20);
+
+ outb(PIC1, 0x20);
+}