summaryrefslogtreecommitdiff
path: root/src/kernel/arch/i386/interrupts
diff options
context:
space:
mode:
authordzwdz2022-03-26 21:06:07 +0100
committerdzwdz2022-03-26 21:06:07 +0100
commit38d1712e31e60de9f2afe85873b2174e002e3e99 (patch)
tree19c402747631d6df2dbd7c9222d7871b941e94ee /src/kernel/arch/i386/interrupts
parent96f021e783f1e99a1ce7d34c0dfeaef524abc2d1 (diff)
kernel: IRQs; PS/2 keyboard support
Diffstat (limited to 'src/kernel/arch/i386/interrupts')
-rw-r--r--src/kernel/arch/i386/interrupts/irq.c41
-rw-r--r--src/kernel/arch/i386/interrupts/irq.h8
-rw-r--r--src/kernel/arch/i386/interrupts/isr.c8
3 files changed, 57 insertions, 0 deletions
diff --git a/src/kernel/arch/i386/interrupts/irq.c b/src/kernel/arch/i386/interrupts/irq.c
new file mode 100644
index 0000000..cb33bc8
--- /dev/null
+++ b/src/kernel/arch/i386/interrupts/irq.c
@@ -0,0 +1,41 @@
+#include <kernel/arch/i386/interrupts/irq.h>
+#include <kernel/arch/i386/port_io.h>
+#include <stdint.h>
+
+static const int PIC1 = 0x20;
+static const int PIC2 = 0xA0;
+
+static void irq_unmask(uint8_t line) {
+ uint16_t pic = line < 8 ? PIC1 : PIC2;
+ line &= 7;
+
+ port_out8(pic+1, port_in8(pic+1) & ~(1 << line));
+}
+
+void irq_init(void) {
+ port_out8(PIC1, 0x11); /* start init sequence */
+ port_out8(PIC2, 0x11);
+
+ port_out8(PIC1+1, 0x20); /* interrupt offsets */
+ port_out8(PIC2+1, 0x30);
+
+ port_out8(PIC1+1, 0x4); /* just look at the osdev wiki lol */
+ port_out8(PIC2+1, 0x2);
+
+ port_out8(PIC1+1, 0x1); /* 8086 mode */
+ port_out8(PIC2+1, 0x1);
+
+ port_out8(PIC1+1, 0xfd); /* mask */
+ port_out8(PIC2+1, 0xff);
+}
+
+void irq_eoi(uint8_t line) {
+ port_out8(PIC1, 0x20);
+ if (line >= 8)
+ port_out8(PIC2, 0x20);
+}
+
+void irq_interrupt_flag(bool flag) {
+ if (flag) asm("sti" : : : "memory");
+ else asm("cli" : : : "memory");
+}
diff --git a/src/kernel/arch/i386/interrupts/irq.h b/src/kernel/arch/i386/interrupts/irq.h
new file mode 100644
index 0000000..73d4af2
--- /dev/null
+++ b/src/kernel/arch/i386/interrupts/irq.h
@@ -0,0 +1,8 @@
+#pragma once
+#include <stdbool.h>
+#include <stdint.h>
+
+void irq_init(void);
+void irq_eoi(uint8_t line);
+
+void irq_interrupt_flag(bool flag);
diff --git a/src/kernel/arch/i386/interrupts/isr.c b/src/kernel/arch/i386/interrupts/isr.c
index 9d8bb6c..1448f44 100644
--- a/src/kernel/arch/i386/interrupts/isr.c
+++ b/src/kernel/arch/i386/interrupts/isr.c
@@ -1,4 +1,7 @@
+#include <kernel/arch/i386/interrupts/irq.h>
#include <kernel/arch/i386/interrupts/isr.h>
+#include <kernel/arch/i386/port_io.h>
+#include <kernel/arch/i386/tty/keyboard.h>
#include <kernel/arch/io.h>
#include <kernel/panic.h>
#include <kernel/proc.h>
@@ -16,6 +19,11 @@ void isr_stage3(int interrupt) {
isr_test_interrupt_called = true;
return;
+ case 0x21:; // keyboard irq
+ keyboard_recv(port_in8(0x60));
+ irq_eoi(1);
+ return;
+
default:
// TODO check if the exception was in the kernel
process_kill(process_current, interrupt);