From 547eabb403cf2f587b44548d567031ffd00d4499 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 28 Sep 2023 12:48:52 +0300 Subject: [PATCH] Kernel: Reboot will now always succeed If acpi reset fails, we forcefully trigger a triple fault to restart the system. --- kernel/arch/x86_64/IDT.cpp | 10 ++++++++++ kernel/include/kernel/IDT.h | 1 + kernel/kernel/Process.cpp | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/kernel/arch/x86_64/IDT.cpp b/kernel/arch/x86_64/IDT.cpp index 23f739c0..b7392734 100644 --- a/kernel/arch/x86_64/IDT.cpp +++ b/kernel/arch/x86_64/IDT.cpp @@ -424,4 +424,14 @@ namespace IDT flush_idt(); } + [[noreturn]] void force_triple_fault() + { + // load 0 sized IDT and trigger an interrupt to force triple fault + asm volatile("cli"); + s_idtr.size = 0; + flush_idt(); + asm volatile("int $0x00"); + ASSERT_NOT_REACHED(); + } + } \ No newline at end of file diff --git a/kernel/include/kernel/IDT.h b/kernel/include/kernel/IDT.h index f69fb91a..679442e4 100644 --- a/kernel/include/kernel/IDT.h +++ b/kernel/include/kernel/IDT.h @@ -9,5 +9,6 @@ namespace IDT void initialize(); void register_irq_handler(uint8_t irq, void(*f)()); + [[noreturn]] void force_triple_fault(); } \ No newline at end of file diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 1c196819..509ccdc0 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -776,6 +777,18 @@ namespace Kernel return 0; } + [[noreturn]] static void reset_system() + { + lai_acpi_reset(); + + // acpi reset did not work + + dwarnln("Could not reset with ACPI, crashing the cpu"); + + // reset through triple fault + IDT::force_triple_fault(); + } + BAN::ErrorOr Process::sys_poweroff(int command) { if (command != POWEROFF_REBOOT && command != POWEROFF_SHUTDOWN) @@ -789,7 +802,7 @@ namespace Kernel switch (command) { case POWEROFF_REBOOT: - error = lai_acpi_reset(); + reset_system(); break; case POWEROFF_SHUTDOWN: error = lai_enter_sleep(5);