From 9252a892bb7f7fe3719a57143497726784138bd3 Mon Sep 17 00:00:00 2001 From: Liav A Date: Fri, 2 Sep 2022 10:17:55 +0300 Subject: [PATCH] Kernel: Abstracts x86 reboot and shutdown specific methods We move QEMU and VirtualBox shutdown sequences to a separate file, as well as moving the i8042 reboot code sequence too to another file. This allows us to abstract specific methods from the power state node code of the SysFS filesystem, to allow other architectures to put their methods there too in the future. --- Kernel/Arch/x86/common/I8042Reboot.cpp | 19 +++++++++++++++++ .../common/{QEMUShutdown.h => I8042Reboot.h} | 2 +- .../common/{QEMUShutdown.cpp => Shutdown.cpp} | 7 ++++++- Kernel/Arch/x86/common/Shutdown.h | 14 +++++++++++++ Kernel/CMakeLists.txt | 3 ++- .../Subsystems/Firmware/PowerStateSwitch.cpp | 21 +++++++++++-------- Kernel/Panic.cpp | 3 ++- 7 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 Kernel/Arch/x86/common/I8042Reboot.cpp rename Kernel/Arch/x86/common/{QEMUShutdown.h => I8042Reboot.h} (86%) rename Kernel/Arch/x86/common/{QEMUShutdown.cpp => Shutdown.cpp} (80%) create mode 100644 Kernel/Arch/x86/common/Shutdown.h diff --git a/Kernel/Arch/x86/common/I8042Reboot.cpp b/Kernel/Arch/x86/common/I8042Reboot.cpp new file mode 100644 index 00000000000..2eaf0a0df73 --- /dev/null +++ b/Kernel/Arch/x86/common/I8042Reboot.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +void i8042_reboot() +{ + dbgln("attempting reboot via KB Controller..."); + IO::out8(0x64, 0xFE); +} + +} diff --git a/Kernel/Arch/x86/common/QEMUShutdown.h b/Kernel/Arch/x86/common/I8042Reboot.h similarity index 86% rename from Kernel/Arch/x86/common/QEMUShutdown.h rename to Kernel/Arch/x86/common/I8042Reboot.h index 18634ff6222..9c457a0f1ad 100644 --- a/Kernel/Arch/x86/common/QEMUShutdown.h +++ b/Kernel/Arch/x86/common/I8042Reboot.h @@ -8,6 +8,6 @@ namespace Kernel { -void qemu_shutdown(); +void i8042_reboot(); } diff --git a/Kernel/Arch/x86/common/QEMUShutdown.cpp b/Kernel/Arch/x86/common/Shutdown.cpp similarity index 80% rename from Kernel/Arch/x86/common/QEMUShutdown.cpp rename to Kernel/Arch/x86/common/Shutdown.cpp index 0c3149dff54..948f7209816 100644 --- a/Kernel/Arch/x86/common/QEMUShutdown.cpp +++ b/Kernel/Arch/x86/common/Shutdown.cpp @@ -5,7 +5,7 @@ */ #include -#include +#include namespace Kernel { @@ -18,4 +18,9 @@ void qemu_shutdown() IO::out16(0xb004, 0x2000); } +void virtualbox_shutdown() +{ + IO::out16(0x4004, 0x3400); +} + } diff --git a/Kernel/Arch/x86/common/Shutdown.h b/Kernel/Arch/x86/common/Shutdown.h new file mode 100644 index 00000000000..90a742176e2 --- /dev/null +++ b/Kernel/Arch/x86/common/Shutdown.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace Kernel { + +void qemu_shutdown(); +void virtualbox_shutdown(); + +} diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index d13ae0b1e58..20b53634a94 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -333,9 +333,10 @@ if ("${SERENITY_ARCH}" STREQUAL "i686" OR "${SERENITY_ARCH}" STREQUAL "x86_64") ${KERNEL_SOURCES} Arch/Processor.cpp + Arch/x86/common/I8042Reboot.cpp Arch/x86/common/ScopedCritical.cpp Arch/x86/common/SmapDisabler.cpp - Arch/x86/common/QEMUShutdown.cpp + Arch/x86/common/Shutdown.cpp ) set(KERNEL_SOURCES diff --git a/Kernel/FileSystem/SysFS/Subsystems/Firmware/PowerStateSwitch.cpp b/Kernel/FileSystem/SysFS/Subsystems/Firmware/PowerStateSwitch.cpp index 51beb59dee5..b9d225ffafc 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Firmware/PowerStateSwitch.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Firmware/PowerStateSwitch.cpp @@ -5,7 +5,11 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include +#if ARCH(I386) || ARCH(X86_64) +# include +# include +#endif #include #include #include @@ -76,8 +80,9 @@ void PowerStateSwitchNode::reboot() dbgln("attempting reboot via ACPI"); if (ACPI::is_enabled()) ACPI::Parser::the()->try_acpi_reboot(); - dbgln("attempting reboot via KB Controller..."); - IO::out8(0x64, 0xFE); +#if ARCH(I386) || 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(); @@ -94,12 +99,10 @@ void PowerStateSwitchNode::poweroff() dbgln("syncing mounted filesystems..."); FileSystem::sync(); dbgln("attempting system shutdown..."); - // QEMU Shutdown - IO::out16(0x604, 0x2000); - // If we're here, the shutdown failed. Try VirtualBox shutdown. - IO::out16(0x4004, 0x3400); - // VirtualBox shutdown failed. Try Bochs/Old QEMU shutdown. - IO::out16(0xb004, 0x2000); +#if ARCH(I386) || ARCH(X86_64) + qemu_shutdown(); + virtualbox_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/Panic.cpp b/Kernel/Panic.cpp index ca360751510..deba3bfaf39 100644 --- a/Kernel/Panic.cpp +++ b/Kernel/Panic.cpp @@ -7,7 +7,7 @@ #include #include #if ARCH(I386) || ARCH(X86_64) -# include +# include #endif #include #include @@ -20,6 +20,7 @@ namespace Kernel { { #if ARCH(I386) || ARCH(X86_64) qemu_shutdown(); + virtualbox_shutdown(); #endif // Note: If we failed to invoke platform shutdown, we need to halt afterwards // to ensure no further execution on any CPU still happens.