Make sure to mask and flush IRQs for stivale protocol
diff --git a/STIVALE.md b/STIVALE.md
index fd501657..54448c59 100644
--- a/STIVALE.md
+++ b/STIVALE.md
@@ -67,6 +67,8 @@ If stivale header flag bit 1 is set, then, if available, 5-level paging is enabl
The A20 gate is enabled.
+PIC/APIC IRQs are all masked.
+
`rsp` is set to the requested stack as per stivale header.
`rdi` will point to the stivale structure (described below).
@@ -91,6 +93,8 @@ PE is enabled (`cr0`).
The A20 gate is enabled.
+PIC/APIC IRQs are all masked.
+
`esp` is set to the requested stack as per stivale header.
A pointer to the stivale structure (described below) is pushed onto this stack
diff --git a/qloader2.bin b/qloader2.bin
index 4c7ebf33..c7675879 100644
Binary files a/qloader2.bin and b/qloader2.bin differ
diff --git a/src/lib/real.c b/src/lib/real.c
index b1d57389..9000d05a 100644
--- a/src/lib/real.c
+++ b/src/lib/real.c
@@ -1,6 +1,88 @@
#include <stdint.h>
#include <lib/real.h>
+__attribute__((naked))
+void rm_flush_irqs(void) {
+ asm (
+ // 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
+ "jmp 0x08:1f\n\t"
+ "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"
+ "jmp 0:2f\n\t"
+ "2:\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"
+ "jmp 0x18:4f\n\t"
+ "4: .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 (
diff --git a/src/lib/real.h b/src/lib/real.h
index 545cbded..b04eb146 100644
--- a/src/lib/real.h
+++ b/src/lib/real.h
@@ -24,4 +24,6 @@ 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 0b641175..59a0c4e2 100644
--- a/src/protos/stivale.c
+++ b/src/protos/stivale.c
@@ -10,6 +10,7 @@
#include <lib/time.h>
#include <lib/print.h>
#include <lib/random.h>
+#include <lib/real.h>
#include <drivers/vbe.h>
#include <drivers/vga_textmode.h>
#include <fs/file.h>
@@ -226,6 +227,8 @@ void stivale_load(char *cmdline, int boot_drive) {
deinit_vga_textmode();
}
+ rm_flush_irqs();
+
if (bits == 64) {
void *pagemap_ptr;
if (level5pg && (stivale_hdr.flags & (1 << 1))) {
