aboutsummaryrefslogtreecommitdiff
path: root/devices
diff options
context:
space:
mode:
Diffstat (limited to 'devices')
-rw-r--r--devices/meson.build2
-rw-r--r--devices/pic.h4
-rw-r--r--devices/pic_8259.c39
3 files changed, 44 insertions, 1 deletions
diff --git a/devices/meson.build b/devices/meson.build
index c52c389..de0230d 100644
--- a/devices/meson.build
+++ b/devices/meson.build
@@ -1,5 +1,5 @@
devices = declare_dependency(
- sources: ['vga.c', 'uart_16550.c'],
+ sources: ['vga.c', 'uart_16550.c', 'pic_8259.c'],
include_directories: '.'
)
diff --git a/devices/pic.h b/devices/pic.h
new file mode 100644
index 0000000..685a85b
--- /dev/null
+++ b/devices/pic.h
@@ -0,0 +1,4 @@
+#pragma once
+
+void pic_init();
+void pic_clear(unsigned char irq);
diff --git a/devices/pic_8259.c b/devices/pic_8259.c
new file mode 100644
index 0000000..43b090f
--- /dev/null
+++ b/devices/pic_8259.c
@@ -0,0 +1,39 @@
+#include "pic.h"
+#include <sys/io.h>
+
+#define PIC1 0x20
+#define PIC2 0xa0
+#define DATA 1
+
+// initialization
+#define ICW1_INIT 0x10
+// TODO
+#define ICW1_ICW4 0x01
+// 8086/88 mode
+#define ICW4_8086 0x01
+
+void
+pic_init()
+{
+ outb(ICW1_INIT | ICW1_ICW4, PIC1);
+ outb(ICW1_INIT | ICW1_ICW4, PIC2);
+
+ outb(0x20, PIC1 + DATA); // offset 0x20
+ outb(0x28, PIC2 + DATA); // offset 0x28
+
+ outb(0x04, PIC1 + DATA); // tell master pic there is a slave pic
+ outb(0x02, PIC2 + DATA); // tell slave pic its cascade identity
+
+ outb(ICW4_8086, PIC1 + DATA);
+ outb(ICW4_8086, PIC2 + DATA);
+
+ // PIC masks
+ outb(0xff, PIC1 + DATA);
+ outb(0xff, PIC2 + DATA);
+}
+
+void
+pic_clear(unsigned char irq)
+{
+ outb(0x20, PIC1);
+}