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.
This commit is contained in:
Liav A 2022-09-02 10:17:55 +03:00 committed by Linus Groh
parent 0a220a413f
commit 9252a892bb
Notes: sideshowbarker 2024-07-17 06:51:48 +09:00
7 changed files with 56 additions and 13 deletions

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Format.h>
#include <Kernel/Arch/x86/IO.h>
#include <Kernel/Arch/x86/common/I8042Reboot.h>
namespace Kernel {
void i8042_reboot()
{
dbgln("attempting reboot via KB Controller...");
IO::out8(0x64, 0xFE);
}
}

View File

@ -8,6 +8,6 @@
namespace Kernel {
void qemu_shutdown();
void i8042_reboot();
}

View File

@ -5,7 +5,7 @@
*/
#include <Kernel/Arch/x86/IO.h>
#include <Kernel/Arch/x86/common/QEMUShutdown.h>
#include <Kernel/Arch/x86/common/Shutdown.h>
namespace Kernel {
@ -18,4 +18,9 @@ void qemu_shutdown()
IO::out16(0xb004, 0x2000);
}
void virtualbox_shutdown()
{
IO::out16(0x4004, 0x3400);
}
}

View File

@ -0,0 +1,14 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
namespace Kernel {
void qemu_shutdown();
void virtualbox_shutdown();
}

View File

@ -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

View File

@ -5,7 +5,11 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/Arch/x86/IO.h>
#include <AK/Platform.h>
#if ARCH(I386) || ARCH(X86_64)
# include <Kernel/Arch/x86/common/I8042Reboot.h>
# include <Kernel/Arch/x86/common/Shutdown.h>
#endif
#include <Kernel/FileSystem/FileSystem.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Firmware/PowerStateSwitch.h>
#include <Kernel/Firmware/ACPI/Parser.h>
@ -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();

View File

@ -7,7 +7,7 @@
#include <AK/Format.h>
#include <Kernel/Arch/Processor.h>
#if ARCH(I386) || ARCH(X86_64)
# include <Kernel/Arch/x86/common/QEMUShutdown.h>
# include <Kernel/Arch/x86/common/Shutdown.h>
#endif
#include <Kernel/CommandLine.h>
#include <Kernel/KSyms.h>
@ -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.