:: commit b9be2e70c1b0268c82c6dd4e6afa65c9b5ca4ff3

mintsuki <mintsuki@protonmail.com> — 2020-09-02 00:32

parents: 1a267656f9

Change PIC IRQ flushing method

diff --git a/limine.bin b/limine.bin
index 6b707945..5276f5f4 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/src/drivers/pic.c b/src/drivers/pic.c
new file mode 100644
index 00000000..7c2d7cd3
--- /dev/null
+++ b/src/drivers/pic.c
@@ -0,0 +1,43 @@
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <drivers/pic.h>
+#include <lib/cio.h>
+
+void pic_eoi(int irq) {
+    if (irq >= 8) {
+        port_out_b(0xa0, 0x20);
+    }
+
+    port_out_b(0x20, 0x20);
+}
+
+// Flush all potentially pending IRQs
+void pic_flush(void) {
+    for (int i = 0; i < 16; i++)
+        pic_eoi(i);
+}
+
+void pic_set_mask(int line, bool status) {
+    uint16_t port;
+    uint8_t value;
+
+    if (line < 8) {
+        port = 0x21;
+    } else {
+        port = 0xa1;
+        line -= 8;
+    }
+
+    if (!status)
+        value = port_in_b(port) & ~((uint8_t)1 << line);
+    else
+        value = port_in_b(port) | ((uint8_t)1 << line);
+
+    port_out_b(port, value);
+}
+
+void pic_mask_all(void) {
+    port_out_b(0xa1, 0xff);
+    port_out_b(0x21, 0xff);
+}
diff --git a/src/drivers/pic.h b/src/drivers/pic.h
new file mode 100644
index 00000000..e4962bb6
--- /dev/null
+++ b/src/drivers/pic.h
@@ -0,0 +1,11 @@
+#ifndef __DRIVERS__PIT_H__
+#define __DRIVERS__PIT_H__
+
+#include <stdbool.h>
+
+void pic_eoi(int irq);
+void pic_flush(void);
+void pic_set_mask(int line, bool status);
+void pic_mask_all(void);
+
+#endif
diff --git a/src/lib/real.c b/src/lib/real.c
index 18270366..5e6cfe75 100644
--- a/src/lib/real.c
+++ b/src/lib/real.c
@@ -2,88 +2,6 @@
 #include <lib/real.h>
 #include <lib/asm.h>
 
-__attribute__((naked))
-void rm_flush_irqs(void) {
-    ASM_BASIC(
-        // Mask PICs
-        "mov al, 0xff\n\t"
-        "out 0x21, al\n\t"
-        "out 0xa1, al\n\t"
-
-        // Save GDT in case BIOS overwrites it
-        "sgdt [8f]\n\t"
-
-        // Save non-scratch GPRs
-        "push ebx\n\t"
-        "push esi\n\t"
-        "push edi\n\t"
-        "push ebp\n\t"
-
-        // Jump to real mode
-        FARJMP32("0x08", "1f")
-        "1: .code16\n\t"
-        "mov ax, 0x10\n\t"
-        "mov ds, ax\n\t"
-        "mov es, ax\n\t"
-        "mov fs, ax\n\t"
-        "mov gs, ax\n\t"
-        "mov ss, ax\n\t"
-        "mov eax, cr0\n\t"
-        "and al, 0xfe\n\t"
-        "mov cr0, eax\n\t"
-        FARJMP16("0", "1f")
-        "1:\n\t"
-        "mov ax, 0\n\t"
-        "mov ds, ax\n\t"
-        "mov es, ax\n\t"
-        "mov fs, ax\n\t"
-        "mov gs, ax\n\t"
-        "mov ss, ax\n\t"
-
-        "sti\n\t"
-        "call 2f\n\t"   // call await
-        "cli\n\t"
-
-        // Restore GDT
-        "lgdt [8f]\n\t"
-
-        // Jump back to pmode
-        "mov eax, cr0\n\t"
-        "or al, 1\n\t"
-        "mov cr0, eax\n\t"
-        FARJMP16("0x18", "1f")
-        "1: .code32\n\t"
-        "mov ax, 0x20\n\t"
-        "mov ds, ax\n\t"
-        "mov es, ax\n\t"
-        "mov fs, ax\n\t"
-        "mov gs, ax\n\t"
-        "mov ss, ax\n\t"
-
-        // Restore non-scratch GPRs
-        "pop ebp\n\t"
-        "pop edi\n\t"
-        "pop esi\n\t"
-        "pop ebx\n\t"
-
-        // Exit
-        "ret\n\t"
-
-        // gdt
-        "1: .long 0\n\t"
-        "   .long 0\n\t"
-
-        // Await
-        ".code16\n\t"
-        "2: xor al, al\n\t"
-        "mov cx, 0x1000\n\t"
-        "3: out 0x80, al\n\t"
-        "loop 3b\n\t"
-        "ret\n\t"
-        ".code32\n\t"
-    );
-}
-
 __attribute__((naked))
 void rm_int(uint8_t int_no, struct rm_regs *out_regs, struct rm_regs *in_regs) {
     ASM_BASIC(
diff --git a/src/lib/real.h b/src/lib/real.h
index b04eb146..545cbded 100644
--- a/src/lib/real.h
+++ b/src/lib/real.h
@@ -24,6 +24,4 @@ struct rm_regs {
 
 void rm_int(uint8_t int_no, struct rm_regs *out_regs, struct rm_regs *in_regs);
 
-void rm_flush_irqs(void);
-
 #endif
diff --git a/src/protos/stivale.c b/src/protos/stivale.c
index d3efab14..305191be 100644
--- a/src/protos/stivale.c
+++ b/src/protos/stivale.c
@@ -13,6 +13,7 @@
 #include <lib/real.h>
 #include <drivers/vbe.h>
 #include <drivers/vga_textmode.h>
+#include <drivers/pic.h>
 #include <fs/file.h>
 #include <lib/asm.h>
 
@@ -248,7 +249,8 @@ void stivale_load(char *cmdline, int boot_drive) {
         rm_int(0x15, &r, &r);
     }
 
-    rm_flush_irqs();
+    pic_mask_all();
+    pic_flush();
 
     if (bits == 64) {
         void *pagemap_ptr;
diff --git a/src/protos/stivale2.c b/src/protos/stivale2.c
index a5bef8ec..5f812872 100644
--- a/src/protos/stivale2.c
+++ b/src/protos/stivale2.c
@@ -15,6 +15,7 @@
 #include <lib/libc.h>
 #include <drivers/vbe.h>
 #include <drivers/vga_textmode.h>
+#include <drivers/pic.h>
 #include <fs/file.h>
 #include <lib/asm.h>
 
@@ -414,7 +415,8 @@ void stivale2_load(char *cmdline, int boot_drive) {
         rm_int(0x15, &r, &r);
     }
 
-    rm_flush_irqs();
+    pic_mask_all();
+    pic_flush();
 
     if (bits == 64) {
         void *pagemap_ptr;
tab: 248 wrap: offon