From 9b8b8c0e04c811be6df4550ce1463a1935eb4e94 Mon Sep 17 00:00:00 2001 From: Liav A Date: Fri, 9 Jun 2023 22:13:04 +0300 Subject: [PATCH] Kernel: Simplify reboot & poweroff code flow a bit Instead of using ifdefs to use the correct platform-specific methods, we can just use the same pattern we use for the microseconds_delay function which has specific implementations for each Arch CPU subdirectory. When linking a kernel image, the actual correct and platform-specific power-state changing methods will be called in Firmware/PowerState.cpp file. --- Kernel/Arch/PowerState.h | 16 ++++++ Kernel/Arch/aarch64/PowerState.cpp | 21 +++++++ Kernel/Arch/x86_64/PowerState.cpp | 24 ++++++++ Kernel/CMakeLists.txt | 3 + .../Subsystems/Kernel/PowerStateSwitch.cpp | 53 +----------------- .../Subsystems/Kernel/PowerStateSwitch.h | 3 - Kernel/Firmware/PowerState.cpp | 55 +++++++++++++++++++ Kernel/Firmware/PowerState.h | 16 ++++++ 8 files changed, 138 insertions(+), 53 deletions(-) create mode 100644 Kernel/Arch/PowerState.h create mode 100644 Kernel/Arch/aarch64/PowerState.cpp create mode 100644 Kernel/Arch/x86_64/PowerState.cpp create mode 100644 Kernel/Firmware/PowerState.cpp create mode 100644 Kernel/Firmware/PowerState.h diff --git a/Kernel/Arch/PowerState.h b/Kernel/Arch/PowerState.h new file mode 100644 index 0000000000..a853931340 --- /dev/null +++ b/Kernel/Arch/PowerState.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Kernel { + +void arch_specific_reboot(); +void arch_specific_poweroff(); + +} diff --git a/Kernel/Arch/aarch64/PowerState.cpp b/Kernel/Arch/aarch64/PowerState.cpp new file mode 100644 index 0000000000..2cc333d413 --- /dev/null +++ b/Kernel/Arch/aarch64/PowerState.cpp @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Kernel { + +void arch_specific_reboot() +{ +} + +void arch_specific_poweroff() +{ + RPi::Watchdog::the().system_shutdown(); +} + +} diff --git a/Kernel/Arch/x86_64/PowerState.cpp b/Kernel/Arch/x86_64/PowerState.cpp new file mode 100644 index 0000000000..dc08aa2ebf --- /dev/null +++ b/Kernel/Arch/x86_64/PowerState.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +void arch_specific_reboot() +{ + i8042_reboot(); +} + +void arch_specific_poweroff() +{ + qemu_shutdown(); + virtualbox_shutdown(); +} + +} diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index ea03907088..7c508ab334 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -209,6 +209,7 @@ set(KERNEL_SOURCES Firmware/ACPI/Initialize.cpp Firmware/ACPI/Parser.cpp Firmware/ACPI/StaticParsing.cpp + Firmware/PowerState.cpp Interrupts/GenericInterruptHandler.cpp Interrupts/IRQHandler.cpp Interrupts/PCIIRQHandler.cpp @@ -402,6 +403,7 @@ if ("${SERENITY_ARCH}" STREQUAL "x86_64") Arch/x86_64/VGA/IOArbiter.cpp + Arch/x86_64/PowerState.cpp Arch/x86_64/RTC.cpp Arch/x86_64/Shutdown.cpp Arch/x86_64/SmapDisabler.cpp @@ -477,6 +479,7 @@ elseif("${SERENITY_ARCH}" STREQUAL "aarch64") Arch/aarch64/PageDirectory.cpp Arch/aarch64/Panic.cpp Arch/aarch64/Processor.cpp + Arch/aarch64/PowerState.cpp Arch/aarch64/SafeMem.cpp Arch/aarch64/SmapDisabler.cpp Arch/aarch64/TrapFrame.cpp diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.cpp index 639b9954ec..9996ea5cfe 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.cpp @@ -6,15 +6,10 @@ */ #include -#if ARCH(X86_64) -# include -# include -#elif ARCH(AARCH64) -# include -#endif #include #include #include +#include #include #include #include @@ -60,55 +55,13 @@ ErrorOr SysFSPowerStateSwitchNode::write_bytes(off_t offset, size_t coun TRY(data.read(buf, 1)); switch (buf[0]) { case '1': - reboot(); + Firmware::reboot(); VERIFY_NOT_REACHED(); case '2': - poweroff(); + Firmware::poweroff(); VERIFY_NOT_REACHED(); default: return Error::from_errno(EINVAL); } } - -void SysFSPowerStateSwitchNode::reboot() -{ - MutexLocker locker(Process::current().big_lock()); - - dbgln("acquiring FS locks..."); - FileSystem::lock_all(); - dbgln("syncing mounted filesystems..."); - FileSystem::sync(); - dbgln("attempting reboot via ACPI"); - if (ACPI::is_enabled()) - ACPI::Parser::the()->try_acpi_reboot(); -#if ARCH(X86_64) - i8042_reboot(); -#endif - dbgln("reboot attempts failed, applications will stop responding."); - dmesgln("Reboot can't be completed. It's safe to turn off the computer!"); - Processor::halt(); -} - -void SysFSPowerStateSwitchNode::poweroff() -{ - MutexLocker locker(Process::current().big_lock()); - - ConsoleManagement::the().switch_to_debug(); - - dbgln("acquiring FS locks..."); - FileSystem::lock_all(); - dbgln("syncing mounted filesystems..."); - FileSystem::sync(); - dbgln("attempting system shutdown..."); -#if ARCH(X86_64) - qemu_shutdown(); - virtualbox_shutdown(); -#elif ARCH(AARCH64) - RPi::Watchdog::the().system_shutdown(); -#endif - dbgln("shutdown attempts failed, applications will stop responding."); - dmesgln("Shutdown can't be completed. It's safe to turn off the computer!"); - Processor::halt(); -} - } diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.h index 8e3d7bef21..47ee58f1c5 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.h +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.h @@ -29,9 +29,6 @@ public: private: explicit SysFSPowerStateSwitchNode(SysFSDirectory const&); - - void reboot(); - void poweroff(); }; } diff --git a/Kernel/Firmware/PowerState.cpp b/Kernel/Firmware/PowerState.cpp new file mode 100644 index 0000000000..50bde73c62 --- /dev/null +++ b/Kernel/Firmware/PowerState.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace Kernel::Firmware { + +void reboot() +{ + MutexLocker locker(Process::current().big_lock()); + + dbgln("acquiring FS locks..."); + FileSystem::lock_all(); + dbgln("syncing mounted filesystems..."); + FileSystem::sync(); + dbgln("attempting reboot via ACPI"); + if (ACPI::is_enabled()) + ACPI::Parser::the()->try_acpi_reboot(); + + arch_specific_reboot(); + + dbgln("reboot attempts failed, applications will stop responding."); + dmesgln("Reboot can't be completed. It's safe to turn off the computer!"); + Processor::halt(); +} + +void poweroff() +{ + MutexLocker locker(Process::current().big_lock()); + + ConsoleManagement::the().switch_to_debug(); + + dbgln("acquiring FS locks..."); + FileSystem::lock_all(); + dbgln("syncing mounted filesystems..."); + FileSystem::sync(); + + dbgln("attempting system shutdown..."); + arch_specific_poweroff(); + + dbgln("shutdown attempts failed, applications will stop responding."); + dmesgln("Shutdown can't be completed. It's safe to turn off the computer!"); + Processor::halt(); +} + +} diff --git a/Kernel/Firmware/PowerState.h b/Kernel/Firmware/PowerState.h new file mode 100644 index 0000000000..439dbbc6f0 --- /dev/null +++ b/Kernel/Firmware/PowerState.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Kernel::Firmware { + +void reboot(); +void poweroff(); + +}