/* * Power.hpp * SYS_RESET, SYS_SHUTDOWN, SYS_SUSPEND syscalls * Copyright (c) 2026 Daniel Hammer */ #pragma once #include #include #include #include #include #include #include #include #include #include "Syscall.hpp" namespace montauk::abi { // Pending graceful power-off request, set by the desktop and consumed by // login.elf. Kernel-global IPC channel (one outstanding request system-wide). // `inline` so the single definition is shared across translation units. inline int g_pendingPowerAction = POWER_REQ_QUERY; // SYS_POWER_REQUEST. action == POWER_REQ_QUERY reads and clears the pending // action; any other value records it as the pending action. Returns the // pending action for queries, or 0 when recording one. static int64_t Sys_PowerRequest(int action) { if (action == POWER_REQ_QUERY) { int pending = g_pendingPowerAction; g_pendingPowerAction = POWER_REQ_QUERY; return (int64_t)pending; } g_pendingPowerAction = action; return 0; } static void Sys_Reset() { 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); } /* 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() { /* Primary: ACPI S5 shutdown via PM1 control registers */ if (Hal::AcpiShutdown::IsAvailable()) { Hal::AcpiShutdown::Shutdown(); } /* Fallback: EFI ResetSystem */ if (Efi::g_ResetSystem) { Memory::VMM::LoadCR3(Memory::VMM::g_paging->PML4); Efi::g_ResetSystem(Efi::EfiResetShutdown, 0, 0, nullptr); } /* Last resort: halt the CPU */ asm volatile("cli; hlt"); __builtin_unreachable(); } static int64_t Sys_Suspend() { if (!Hal::AcpiSleep::IsS3Available()) { return -1; // S3 not supported } return (int64_t)Hal::AcpiSleep::Suspend(); } // SYS_POWERINFO. Fills a CPU power/thermal snapshot. Returns -1 when the // CPU exposes no power management features (e.g. under QEMU). static int64_t Sys_PowerInfo(PowerInfo* out) { Hal::CpuPower::Snapshot s{}; if (!Hal::CpuPower::GetSnapshot(s)) { return -1; } out->hwpActive = s.HwpActive ? 1 : 0; out->throttling = s.Throttling ? 1 : 0; out->tempC = s.TempC; out->tjMaxC = s.TjMaxC; out->highestPerf = s.HighestPerf; out->lowestPerf = s.LowestPerf; out->curMaxPerf = s.CurMaxPerf; out->epp = s.Epp; out->baseMHz = s.BaseMHz; out->maxMHz = s.MaxMHz; out->effMHz = s.EffMHz; out->apIdleHint = Hal::CpuIdle::GetApIdleHint(); return 0; } };