panic: Go back to real mode instead of hanging with interrupts disabled so BIOS can handle events like ctrl-alt-delete
diff --git a/limine-pxe.bin b/limine-pxe.bin
index c710cd03..9dbe8e5d 100644
Binary files a/limine-pxe.bin and b/limine-pxe.bin differ
diff --git a/limine.bin b/limine.bin
index 2e5a0cc9..a9526f86 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2.map b/stage2.map
index ae2c2678..cb6678ae 100644
Binary files a/stage2.map and b/stage2.map differ
diff --git a/stage2/lib/blib.c b/stage2/lib/blib.c
index b608c4fc..fde7dd39 100644
--- a/stage2/lib/blib.c
+++ b/stage2/lib/blib.c
@@ -5,6 +5,7 @@
#include <lib/blib.h>
#include <lib/print.h>
#include <lib/trace.h>
+#include <lib/real.h>
uint8_t boot_drive;
int boot_partition = -1;
@@ -78,9 +79,7 @@ __attribute__((noreturn)) void panic(const char *fmt, ...) {
print("\n");
print_stacktrace(NULL);
- for (;;) {
- asm volatile ("hlt" ::: "memory");
- }
+ rm_hcf();
}
int digit_to_int(char c) {
diff --git a/stage2/lib/real.asm b/stage2/lib/real.asm
index ee98ced2..911c3101 100644
--- a/stage2/lib/real.asm
+++ b/stage2/lib/real.asm
@@ -1,5 +1,35 @@
section .realmode
+global rm_hcf
+rm_hcf:
+ ; Jump to real mode
+ jmp 0x08:.bits16
+ .bits16:
+ bits 16
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ mov eax, cr0
+ btr ax, 0
+ mov cr0, eax
+ jmp 0x00:.cszero
+ .cszero:
+ xor ax, ax
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ sti
+ .hang:
+ hlt
+ jmp .hang
+ bits 32
+
global rm_int
rm_int:
; Self-modifying code: int $int_no
diff --git a/stage2/lib/real.h b/stage2/lib/real.h
index e2c6843f..94a150a5 100644
--- a/stage2/lib/real.h
+++ b/stage2/lib/real.h
@@ -28,4 +28,6 @@ struct rm_regs {
void rm_int(uint8_t int_no, struct rm_regs *out_regs, struct rm_regs *in_regs);
+__attribute__((noreturn)) void rm_hcf(void);
+
#endif
