summaryrefslogtreecommitdiff
path: root/kernel/src/arch/i686/pic.c
diff options
context:
space:
mode:
authorTyler Murphy <=>2023-07-17 19:34:52 -0400
committerTyler Murphy <=>2023-07-17 19:34:52 -0400
commit7a912d1b668ab86ffe088eca3ac7e6f78a04a0c5 (patch)
tree4e86ff20e73171285156631db043e12aaf63bf04 /kernel/src/arch/i686/pic.c
parentpaging (diff)
downloadfinix-7a912d1b668ab86ffe088eca3ac7e6f78a04a0c5.tar.gz
finix-7a912d1b668ab86ffe088eca3ac7e6f78a04a0c5.tar.bz2
finix-7a912d1b668ab86ffe088eca3ac7e6f78a04a0c5.zip
refactoring
Diffstat (limited to 'kernel/src/arch/i686/pic.c')
-rw-r--r--kernel/src/arch/i686/pic.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/kernel/src/arch/i686/pic.c b/kernel/src/arch/i686/pic.c
new file mode 100644
index 0000000..f5d0f94
--- /dev/null
+++ b/kernel/src/arch/i686/pic.c
@@ -0,0 +1,80 @@
+#include <sys.h>
+#include <print.h>
+#include <arch/i686/pic.h>
+#include <arch/i686/asm.h>
+
+#define PIC1_COMMAND_PORT 0x20
+#define PIC1_DATA_PORT 0x21
+#define PIC2_COMMAND_PORT 0xA0
+#define PIC2_DATA_PORT 0xA1
+
+void pic_remap(void) {
+ char a1 = inb(PIC1_DATA_PORT);
+ char a2 = inb(PIC2_DATA_PORT);
+ // control word 1
+ // 0x11: initialize, enable ICW4
+ outb(PIC1_COMMAND_PORT, 0x11);
+ io_wait();
+ outb(PIC2_COMMAND_PORT, 0x11);
+ io_wait();
+ // control word 2
+ // interrupt offset
+ outb(PIC1_DATA_PORT, PIC_REMAP_OFFSET);
+ io_wait();
+ outb(PIC2_DATA_PORT, PIC_REMAP_OFFSET + 8);
+ io_wait();
+ // control word 3
+ // primary pic: set which pin secondary is connected to
+ // (pin 2)
+ outb(PIC1_DATA_PORT, 0x04);
+ io_wait();
+ outb(PIC2_DATA_PORT, 2);
+ io_wait();
+ // control word 3
+ // 0x01: enable 8086 mode
+ outb(PIC1_DATA_PORT, 0x01);
+ io_wait();
+ outb(PIC2_DATA_PORT, 0x01);
+ io_wait();
+ // clear data registers
+ outb(PIC1_DATA_PORT, a1);
+ outb(PIC2_DATA_PORT, a2);
+}
+
+void pic_mask(int irq) {
+ uint8_t port;
+ if(irq < 8) {
+ port = PIC1_DATA_PORT;
+ } else {
+ irq -= 8;
+ port = PIC2_DATA_PORT;
+ }
+ uint8_t mask = inb(port);
+ outb(port, mask | (1 << irq));
+}
+
+void pic_unmask(int irq) {
+ uint8_t port;
+ if(irq < 8) {
+ port = PIC1_DATA_PORT;
+ } else {
+ irq -= 8;
+ port = PIC2_DATA_PORT;
+ }
+ uint8_t mask = inb(port);
+ outb(port, mask & ~(1 << irq));
+}
+
+void pic_disable(void) {
+ outb(PIC1_DATA_PORT, 0xff);
+ io_wait();
+ outb(PIC2_DATA_PORT, 0xff);
+ io_wait();
+}
+
+void pic_eoi(int irq) {
+ if(irq >= 8) {
+ outb(PIC2_COMMAND_PORT, 0x20);
+ }
+ outb(PIC1_COMMAND_PORT, 0x20);
+}