summaryrefslogtreecommitdiff
path: root/arch/i386/boot/pic.c
diff options
context:
space:
mode:
authorDanny Holman <dholman@gymli.xyz>2021-09-28 09:04:01 -0500
committerDanny Holman <dholman@gymli.xyz>2021-09-28 09:04:38 -0500
commit0ad50c878838640ce53c202ab028d7b2c5810fe6 (patch)
tree77f189f1369a31b1941dfc5cacb8da71fe343aca /arch/i386/boot/pic.c
parent7bf2c634fdb55d67affe74a2ed0a157610308942 (diff)
arch: i386: add support for 8259 PIC
Add support for the 8259 programmable interrupt controller. Signed-off-by: Danny Holman <dholman@gymli.xyz>
Diffstat (limited to 'arch/i386/boot/pic.c')
-rw-r--r--arch/i386/boot/pic.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/arch/i386/boot/pic.c b/arch/i386/boot/pic.c
new file mode 100644
index 0000000..f103b92
--- /dev/null
+++ b/arch/i386/boot/pic.c
@@ -0,0 +1,53 @@
+#include <kernel/pic.h>
+
+void pic_eoi(unsigned char irq) {
+ if (irq >= 8)
+ outb(PIC2_COMMAND, 0x20);
+ outb(PIC1_COMMAND, 0x20);
+}
+
+void pic_remap(void) {
+ unsigned char a1 = inb(PIC1_DATA);
+ unsigned char a2 = inb(PIC2_DATA);
+
+ outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);
+ outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
+ outb(PIC1_DATA, PIC1);
+ outb(PIC2_DATA, PIC2);
+ outb(PIC1_DATA, 4);
+ outb(PIC2_DATA, 2);
+ outb(PIC1_DATA, ICW4_8086);
+ outb(PIC2_DATA, ICW4_8086);
+ outb(PIC1_DATA, a1);
+ outb(PIC2_DATA, a2);
+}
+
+void irq_set_mask(uint8_t irq) {
+ uint16_t port;
+ uint8_t data;
+
+ if (irq < 8) {
+ port = PIC1_DATA;
+ } else {
+ port = PIC2_DATA;
+ irq -= 8;
+ }
+
+ data = inb(port) | (1 << irq);
+ outb(port, data);
+}
+
+void irq_clear_mask(unsigned char irq) {
+ uint16_t port;
+ uint8_t data;
+
+ if (irq < 8) {
+ port = PIC1_DATA;
+ } else {
+ port = PIC2_DATA;
+ irq -= 8;
+ }
+
+ data = inb(port) & ~(1 << irq);
+ outb(port, data);
+}