Skip to content

Commit

Permalink
Kernel: Call ACPI reboot method first if possible
Browse files Browse the repository at this point in the history
Now we call ACPI reboot method first if possible, and if ACPI reboot is
not available, we attempt to reboot via the keyboard controller.
  • Loading branch information
supercomputer7 authored and awesomekling committed Mar 5, 2020
1 parent 87582d5 commit 1b8cd6d
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Kernel/ACPI/ACPIDynamicParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ namespace ACPI {
// FIXME: Implement AML Interpretation
ASSERT_NOT_REACHED();
}
void DynamicParser::do_acpi_shutdown()
void DynamicParser::try_acpi_shutdown()
{
// FIXME: Implement AML Interpretation to perform ACPI shutdown
ASSERT_NOT_REACHED();
Expand Down
5 changes: 3 additions & 2 deletions Kernel/ACPI/ACPIDynamicParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ class DynamicParser final : public IRQHandler
virtual void enable_aml_interpretation() override;
virtual void enable_aml_interpretation(File& dsdt_file) override;
virtual void enable_aml_interpretation(u8* physical_dsdt, u32 dsdt_payload_legnth) override;
virtual void disable_aml_interpretation() override;
virtual void do_acpi_shutdown() override;
virtual void disable_aml_interpretation() override;
virtual void try_acpi_shutdown() override;
virtual bool can_shutdown() override { return true; }

protected:
DynamicParser();
Expand Down
6 changes: 2 additions & 4 deletions Kernel/ACPI/ACPIParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,14 @@ namespace ACPI {
return {};
}

void Parser::do_acpi_reboot()
void Parser::try_acpi_reboot()
{
klog() << "ACPI: Cannot invoke reboot!";
ASSERT_NOT_REACHED();
}

void Parser::do_acpi_shutdown()
void Parser::try_acpi_shutdown()
{
klog() << "ACPI: Cannot invoke shutdown!";
ASSERT_NOT_REACHED();
}

void Parser::enable_aml_interpretation()
Expand Down
6 changes: 4 additions & 2 deletions Kernel/ACPI/ACPIParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ class Parser {
static void initialize_limited();
virtual PhysicalAddress find_table(const char* sig);

virtual void do_acpi_reboot();
virtual void do_acpi_shutdown();
virtual void try_acpi_reboot();
virtual bool can_reboot() { return false; }
virtual void try_acpi_shutdown();
virtual bool can_shutdown() { return false; }

virtual void enable_aml_interpretation();
virtual void enable_aml_interpretation(File&);
Expand Down
21 changes: 13 additions & 8 deletions Kernel/ACPI/ACPIStaticParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,28 +102,33 @@ namespace ACPI {
klog() << "ACPI: Fixed ACPI data, Revision " << sdt->revision << ", Length " << sdt->length << " bytes";
}

void StaticParser::do_acpi_reboot()
bool StaticParser::can_reboot()
{
// FIXME: Determine if we need to do MMIO/PCI/IO access to reboot, according to ACPI spec 6.2, Section 4.8.3.6
auto region = MM.allocate_kernel_region(m_fadt.page_base(), (PAGE_SIZE * 2), "ACPI Static Parser", Region::Access::Read);
auto* fadt = (const Structures::FADT*)region->vaddr().offset(m_fadt.offset_in_page().get()).as_ptr();
return fadt->h.revision >= 2;
}

void StaticParser::try_acpi_reboot()
{
// FIXME: Determine if we need to do MMIO/PCI/IO access to reboot, according to ACPI spec 6.2, Section 4.8.3.6
#ifdef ACPI_DEBUG
dbg() << "ACPI: Rebooting, Probing FADT (P @ " << m_fadt.ptr() << ")";
dbg() << "ACPI: Rebooting, Probing FADT (" << m_fadt << ")";
#endif

auto region = MM.allocate_kernel_region(m_fadt.page_base(), (PAGE_SIZE * 2), "ACPI Static Parser", Region::Access::Read);
auto* fadt = (const Structures::FADT*)region->vaddr().offset(m_fadt.offset_in_page().get()).as_ptr();
if (fadt->h.revision >= 2) {
klog() << "ACPI: Reboot, Sending value 0x" << String::format("%x", fadt->reset_value) << " to Port 0x" << String::format("%x", fadt->reset_reg.address);
IO::out8(fadt->reset_reg.address, fadt->reset_value);
} else {
klog() << "ACPI: Reboot, Not supported!";
}

ASSERT_NOT_REACHED(); /// If rebooting didn't work, halt.
klog() << "ACPI: Reboot, Not supported!";
}

void StaticParser::do_acpi_shutdown()
void StaticParser::try_acpi_shutdown()
{
klog() << "ACPI: Shutdown is not supported with the current configuration, Abort!";
ASSERT_NOT_REACHED();
}

size_t StaticParser::get_table_size(PhysicalAddress table_header)
Expand Down
6 changes: 4 additions & 2 deletions Kernel/ACPI/ACPIStaticParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ namespace ACPI {
static bool is_initialized();

virtual PhysicalAddress find_table(const char* sig) override;
virtual void do_acpi_reboot() override;
virtual void do_acpi_shutdown() override;
virtual void try_acpi_reboot() override;
virtual bool can_reboot() override;
virtual bool can_shutdown() override { return false; }
virtual void try_acpi_shutdown() override;
virtual bool is_operable() override { return m_operable; }

protected:
Expand Down
5 changes: 5 additions & 0 deletions Kernel/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <AK/StringBuilder.h>
#include <AK/Time.h>
#include <AK/Types.h>
#include <Kernel/ACPI/ACPIParser.h>
#include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Devices/BlockDevice.h>
#include <Kernel/Devices/KeyboardDevice.h>
Expand Down Expand Up @@ -3990,6 +3991,10 @@ int Process::sys$reboot()
FS::lock_all();
dbg() << "syncing mounted filesystems...";
FS::sync();
if (ACPI::Parser::the().can_reboot()) {
dbg() << "attempting reboot via ACPI";
ACPI::Parser::the().try_acpi_reboot();
}
dbg() << "attempting reboot via KB Controller...";
IO::out8(0x64, 0xFE);

Expand Down

0 comments on commit 1b8cd6d

Please sign in to comment.