feat: add support for shutdown/reboot via UEFI Runtime Services

This commit is contained in:
daniel committed 2026-02-26 18:08:05 +01:00
1 parent 33c5d6037a
commit b01789a1f4
11 files changed
+208 -20

No files matched your search

+20 -10
View File
@@ -6,23 +6,33 @@
#pragma once
#include <cstdint>
#include <Efi/UEFI.hpp>
#include <Memory/Paging.hpp>
namespace Zenith {
static void Sys_Reset() {
/*
Triple fault for now; TODO: implement UEFI runtime function for clean reboot.
if (Efi::g_ResetSystem) {
/* Switch to kernel PML4 which has identity-mapped UEFI runtime regions */
Memory::VMM::LoadCR3(Memory::VMM::g_paging->PML4);
Efi::g_ResetSystem(Efi::EfiResetCold, 0, 0, nullptr);
}
We implement the triple fault by loading a null IDT into the IDT register,
and then immediately triggering an interrupt.
This technique should pretty much work across the board but it's of course
better to use the UEFI runtime API as it has a method for this purpose,
along with shutdown.
*/
/* Fallback: triple fault via null IDT */
struct [[gnu::packed]] { uint16_t limit; uint64_t base; } nullIdt = {0, 0};
asm volatile("lidt %0; int $0x03" :: "m"(nullIdt));
__builtin_unreachable();
}
static void Sys_Shutdown() {
if (Efi::g_ResetSystem) {
/* Switch to kernel PML4 which has identity-mapped UEFI runtime regions */
Memory::VMM::LoadCR3(Memory::VMM::g_paging->PML4);
Efi::g_ResetSystem(Efi::EfiResetShutdown, 0, 0, nullptr);
}
/* No fallback for shutdown; halt the CPU */
asm volatile("cli; hlt");
__builtin_unreachable();
}
};
+2 -2
View File
@@ -109,8 +109,8 @@ namespace Zenith {
Sys_Reset();
return 0;
case SYS_SHUTDOWN:
/* Unimplemented */
return -1;
Sys_Shutdown();
return 0;
case SYS_GETTIME:
Sys_GetTime((DateTime*)frame->arg1);
return 0;