mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:47:44 +00:00
Kernel: Remove "non-operational" ACPI parser state
If we don't support ACPI, just don't instantiate an ACPI parser. This is way less confusing than having a special parser class whose only purpose is to do nothing. We now search for the RSDP in ACPI::initialize() instead of letting the parser constructor do it. This allows us to defer the decision to create a parser until we're sure we can make a useful one.
This commit is contained in:
parent
d95362d8cd
commit
4644217094
13 changed files with 46 additions and 111 deletions
|
@ -30,12 +30,6 @@
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
namespace ACPI {
|
namespace ACPI {
|
||||||
|
|
||||||
DynamicParser::DynamicParser()
|
|
||||||
: IRQHandler(9)
|
|
||||||
{
|
|
||||||
klog() << "ACPI: Dynamic Parsing Enabled, Can parse AML";
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicParser::DynamicParser(PhysicalAddress rsdp)
|
DynamicParser::DynamicParser(PhysicalAddress rsdp)
|
||||||
: IRQHandler(9)
|
: IRQHandler(9)
|
||||||
, StaticParser(rsdp)
|
, StaticParser(rsdp)
|
||||||
|
|
|
@ -51,8 +51,7 @@ public:
|
||||||
virtual const char* purpose() const override { return "ACPI Parser"; }
|
virtual const char* purpose() const override { return "ACPI Parser"; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DynamicParser();
|
explicit DynamicParser(PhysicalAddress rsdp);
|
||||||
explicit DynamicParser(PhysicalAddress);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void build_namespace();
|
void build_namespace();
|
||||||
|
|
|
@ -32,10 +32,9 @@ namespace ACPI {
|
||||||
|
|
||||||
static Parser* s_acpi_parser;
|
static Parser* s_acpi_parser;
|
||||||
|
|
||||||
Parser& Parser::the()
|
Parser* Parser::the()
|
||||||
{
|
{
|
||||||
ASSERT(s_acpi_parser);
|
return s_acpi_parser;
|
||||||
return *s_acpi_parser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::set_the(Parser& parser)
|
void Parser::set_the(Parser& parser)
|
||||||
|
@ -44,31 +43,6 @@ void Parser::set_the(Parser& parser)
|
||||||
s_acpi_parser = &parser;
|
s_acpi_parser = &parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::Parser(bool usable)
|
|
||||||
{
|
|
||||||
if (usable) {
|
|
||||||
klog() << "ACPI: Setting up a functional parser";
|
|
||||||
} else {
|
|
||||||
klog() << "ACPI: Limited Initialization. Vital functions are disabled by a request";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PhysicalAddress Parser::find_table(const char*)
|
|
||||||
{
|
|
||||||
klog() << "ACPI: Requested to search for a table, Abort!";
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Parser::try_acpi_reboot()
|
|
||||||
{
|
|
||||||
klog() << "ACPI: Cannot invoke reboot!";
|
|
||||||
}
|
|
||||||
|
|
||||||
void Parser::try_acpi_shutdown()
|
|
||||||
{
|
|
||||||
klog() << "ACPI: Cannot invoke shutdown!";
|
|
||||||
}
|
|
||||||
|
|
||||||
void Parser::enable_aml_interpretation()
|
void Parser::enable_aml_interpretation()
|
||||||
{
|
{
|
||||||
klog() << "ACPI: No AML Interpretation Allowed";
|
klog() << "ACPI: No AML Interpretation Allowed";
|
||||||
|
@ -99,9 +73,5 @@ const FADTFlags::x86_Specific_Flags& Parser::x86_specific_flags() const
|
||||||
klog() << "ACPI Limited: x86 specific features cannot be obtained";
|
klog() << "ACPI Limited: x86 specific features cannot be obtained";
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
bool Parser::is_operable()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <Kernel/ACPI/Definitions.h>
|
#include <Kernel/ACPI/Definitions.h>
|
||||||
|
#include <Kernel/ACPI/Initialize.h>
|
||||||
#include <Kernel/FileSystem/File.h>
|
#include <Kernel/FileSystem/File.h>
|
||||||
#include <Kernel/VM/Region.h>
|
#include <Kernel/VM/Region.h>
|
||||||
#include <LibBareMetal/Memory/PhysicalAddress.h>
|
#include <LibBareMetal/Memory/PhysicalAddress.h>
|
||||||
|
@ -38,33 +39,31 @@ namespace ACPI {
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
public:
|
public:
|
||||||
static Parser& the();
|
static Parser* the();
|
||||||
|
|
||||||
template<typename ParserType>
|
template<typename ParserType>
|
||||||
static void initialize()
|
static void initialize(PhysicalAddress rsdp)
|
||||||
{
|
{
|
||||||
set_the(*new ParserType);
|
set_the(*new ParserType(rsdp));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual PhysicalAddress find_table(const char* sig);
|
virtual PhysicalAddress find_table(const char* sig) = 0;
|
||||||
|
|
||||||
virtual void try_acpi_reboot();
|
virtual void try_acpi_reboot() = 0;
|
||||||
virtual bool can_reboot() { return false; }
|
virtual bool can_reboot() = 0;
|
||||||
virtual void try_acpi_shutdown();
|
virtual void try_acpi_shutdown() = 0;
|
||||||
virtual bool can_shutdown() { return false; }
|
virtual bool can_shutdown() = 0;
|
||||||
|
|
||||||
virtual const FADTFlags::HardwareFeatures& hardware_features() const;
|
virtual const FADTFlags::HardwareFeatures& hardware_features() const = 0;
|
||||||
virtual const FADTFlags::x86_Specific_Flags& x86_specific_flags() const;
|
virtual const FADTFlags::x86_Specific_Flags& x86_specific_flags() const = 0;
|
||||||
|
|
||||||
virtual void enable_aml_interpretation();
|
virtual void enable_aml_interpretation();
|
||||||
virtual void enable_aml_interpretation(File&);
|
virtual void enable_aml_interpretation(File&);
|
||||||
virtual void enable_aml_interpretation(u8*, u32);
|
virtual void enable_aml_interpretation(u8*, u32);
|
||||||
virtual void disable_aml_interpretation();
|
virtual void disable_aml_interpretation();
|
||||||
virtual bool is_operable();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit Parser(bool usable = false);
|
Parser() {}
|
||||||
bool m_operable;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void set_the(Parser&);
|
static void set_the(Parser&);
|
||||||
|
|
|
@ -324,26 +324,10 @@ void StaticParser::locate_main_system_description_table()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticParser::StaticParser()
|
|
||||||
: Parser(true)
|
|
||||||
, m_rsdp(StaticParsing::search_rsdp())
|
|
||||||
{
|
|
||||||
if (!m_rsdp.is_null()) {
|
|
||||||
klog() << "ACPI: Using RSDP @ " << m_rsdp;
|
|
||||||
m_operable = true;
|
|
||||||
locate_static_data();
|
|
||||||
} else {
|
|
||||||
m_operable = false;
|
|
||||||
klog() << "ACPI: Disabled, due to RSDP being absent";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StaticParser::StaticParser(PhysicalAddress rsdp)
|
StaticParser::StaticParser(PhysicalAddress rsdp)
|
||||||
: Parser(true)
|
: m_rsdp(rsdp)
|
||||||
, m_rsdp(rsdp)
|
|
||||||
{
|
{
|
||||||
klog() << "ACPI: Using RSDP @ " << rsdp;
|
klog() << "ACPI: Using RSDP @ " << rsdp;
|
||||||
m_operable = true;
|
|
||||||
locate_static_data();
|
locate_static_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,12 @@ public:
|
||||||
virtual bool can_reboot() override;
|
virtual bool can_reboot() override;
|
||||||
virtual bool can_shutdown() override { return false; }
|
virtual bool can_shutdown() override { return false; }
|
||||||
virtual void try_acpi_shutdown() override;
|
virtual void try_acpi_shutdown() override;
|
||||||
virtual bool is_operable() override { return m_operable; }
|
|
||||||
|
|
||||||
virtual const FADTFlags::HardwareFeatures& hardware_features() const override;
|
virtual const FADTFlags::HardwareFeatures& hardware_features() const override;
|
||||||
virtual const FADTFlags::x86_Specific_Flags& x86_specific_flags() const override;
|
virtual const FADTFlags::x86_Specific_Flags& x86_specific_flags() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StaticParser();
|
explicit StaticParser(PhysicalAddress rsdp);
|
||||||
explicit StaticParser(PhysicalAddress);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void locate_static_data();
|
void locate_static_data();
|
||||||
|
|
|
@ -49,17 +49,23 @@ static FeatureLevel determine_feature_level()
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
{
|
{
|
||||||
switch (determine_feature_level()) {
|
auto feature_level = determine_feature_level();
|
||||||
case FeatureLevel::Enabled:
|
if (feature_level == FeatureLevel::Disabled)
|
||||||
Parser::initialize<DynamicParser>();
|
return;
|
||||||
break;
|
|
||||||
case FeatureLevel::Limited:
|
auto rsdp = StaticParsing::search_rsdp();
|
||||||
Parser::initialize<StaticParser>();
|
if (rsdp.is_null())
|
||||||
break;
|
return;
|
||||||
case FeatureLevel::Disabled:
|
|
||||||
Parser::initialize<Parser>();
|
if (feature_level == FeatureLevel::Enabled)
|
||||||
break;
|
Parser::initialize<DynamicParser>(rsdp);
|
||||||
}
|
else
|
||||||
|
Parser::initialize<StaticParser>(rsdp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_enabled()
|
||||||
|
{
|
||||||
|
return Parser::the();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
namespace ACPI {
|
namespace ACPI {
|
||||||
|
|
||||||
|
bool is_enabled();
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,13 +36,11 @@
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
namespace PCI {
|
namespace PCI {
|
||||||
|
|
||||||
static bool test_acpi();
|
|
||||||
static bool test_pci_io();
|
static bool test_pci_io();
|
||||||
static bool test_pci_mmio();
|
|
||||||
|
|
||||||
static Access::Type detect_optimal_access_type(bool mmio_allowed)
|
static Access::Type detect_optimal_access_type(bool mmio_allowed)
|
||||||
{
|
{
|
||||||
if (mmio_allowed && test_acpi() && test_pci_mmio())
|
if (mmio_allowed && ACPI::is_enabled() && !ACPI::Parser::the()->find_table("MCFG").is_null())
|
||||||
return Access::Type::MMIO;
|
return Access::Type::MMIO;
|
||||||
|
|
||||||
if (test_pci_io())
|
if (test_pci_io())
|
||||||
|
@ -57,7 +55,7 @@ void initialize()
|
||||||
bool mmio_allowed = kernel_command_line().lookup("pci_mmio").value_or("off") == "on";
|
bool mmio_allowed = kernel_command_line().lookup("pci_mmio").value_or("off") == "on";
|
||||||
|
|
||||||
if (detect_optimal_access_type(mmio_allowed) == Access::Type::MMIO)
|
if (detect_optimal_access_type(mmio_allowed) == Access::Type::MMIO)
|
||||||
MMIOAccess::initialize(ACPI::Parser::the().find_table("MCFG"));
|
MMIOAccess::initialize(ACPI::Parser::the()->find_table("MCFG"));
|
||||||
else
|
else
|
||||||
IOAccess::initialize();
|
IOAccess::initialize();
|
||||||
|
|
||||||
|
@ -68,13 +66,6 @@ void initialize()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_acpi()
|
|
||||||
{
|
|
||||||
if ((kernel_command_line().contains("noacpi")) || !ACPI::Parser::the().is_operable())
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool test_pci_io()
|
bool test_pci_io()
|
||||||
{
|
{
|
||||||
klog() << "Testing PCI via manual probing... ";
|
klog() << "Testing PCI via manual probing... ";
|
||||||
|
@ -90,10 +81,5 @@ bool test_pci_io()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_pci_mmio()
|
|
||||||
{
|
|
||||||
return !ACPI::Parser::the().find_table("MCFG").is_null();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3993,7 +3993,8 @@ int Process::sys$reboot()
|
||||||
dbg() << "syncing mounted filesystems...";
|
dbg() << "syncing mounted filesystems...";
|
||||||
FS::sync();
|
FS::sync();
|
||||||
dbg() << "attempting reboot via ACPI";
|
dbg() << "attempting reboot via ACPI";
|
||||||
ACPI::Parser::the().try_acpi_reboot();
|
if (ACPI::is_enabled())
|
||||||
|
ACPI::Parser::the()->try_acpi_reboot();
|
||||||
dbg() << "attempting reboot via KB Controller...";
|
dbg() << "attempting reboot via KB Controller...";
|
||||||
IO::out8(0x64, 0xFE);
|
IO::out8(0x64, 0xFE);
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ bool HPET::test_and_initialize()
|
||||||
{
|
{
|
||||||
ASSERT(!HPET::initialized());
|
ASSERT(!HPET::initialized());
|
||||||
hpet_initialized = true;
|
hpet_initialized = true;
|
||||||
auto hpet = ACPI::Parser::the().find_table("HPET");
|
auto hpet = ACPI::Parser::the()->find_table("HPET");
|
||||||
if (hpet.is_null())
|
if (hpet.is_null())
|
||||||
return false;
|
return false;
|
||||||
klog() << "HPET @ " << hpet;
|
klog() << "HPET @ " << hpet;
|
||||||
|
@ -141,7 +141,7 @@ bool HPET::test_and_initialize()
|
||||||
|
|
||||||
bool HPET::check_for_exisiting_periodic_timers()
|
bool HPET::check_for_exisiting_periodic_timers()
|
||||||
{
|
{
|
||||||
auto hpet = ACPI::Parser::the().find_table("HPET");
|
auto hpet = ACPI::Parser::the()->find_table("HPET");
|
||||||
if (hpet.is_null())
|
if (hpet.is_null())
|
||||||
return false;
|
return false;
|
||||||
auto region = MM.allocate_kernel_region(hpet.page_base(), (PAGE_SIZE * 2), "HPET Initialization", Region::Access::Read);
|
auto region = MM.allocate_kernel_region(hpet.page_base(), (PAGE_SIZE * 2), "HPET Initialization", Region::Access::Read);
|
||||||
|
|
|
@ -92,8 +92,8 @@ void TimeManagement::stale_function(const RegisterState&)
|
||||||
|
|
||||||
TimeManagement::TimeManagement(bool probe_non_legacy_hardware_timers)
|
TimeManagement::TimeManagement(bool probe_non_legacy_hardware_timers)
|
||||||
{
|
{
|
||||||
if (ACPI::Parser::the().is_operable()) {
|
if (ACPI::is_enabled()) {
|
||||||
if (!ACPI::Parser::the().x86_specific_flags().cmos_rtc_not_present) {
|
if (!ACPI::Parser::the()->x86_specific_flags().cmos_rtc_not_present) {
|
||||||
RTC::initialize();
|
RTC::initialize();
|
||||||
m_epoch_time += boot_time();
|
m_epoch_time += boot_time();
|
||||||
} else {
|
} else {
|
||||||
|
@ -161,7 +161,7 @@ bool TimeManagement::is_hpet_periodic_mode_allowed()
|
||||||
|
|
||||||
bool TimeManagement::probe_and_set_non_legacy_hardware_timers()
|
bool TimeManagement::probe_and_set_non_legacy_hardware_timers()
|
||||||
{
|
{
|
||||||
if (!ACPI::Parser::the().is_operable())
|
if (!ACPI::is_enabled())
|
||||||
return false;
|
return false;
|
||||||
if (!HPET::test_and_initialize())
|
if (!HPET::test_and_initialize())
|
||||||
return false;
|
return false;
|
||||||
|
@ -211,8 +211,8 @@ bool TimeManagement::probe_and_set_non_legacy_hardware_timers()
|
||||||
|
|
||||||
bool TimeManagement::probe_and_set_legacy_hardware_timers()
|
bool TimeManagement::probe_and_set_legacy_hardware_timers()
|
||||||
{
|
{
|
||||||
if (ACPI::Parser::the().is_operable()) {
|
if (ACPI::is_enabled()) {
|
||||||
if (ACPI::Parser::the().x86_specific_flags().cmos_rtc_not_present) {
|
if (ACPI::Parser::the()->x86_specific_flags().cmos_rtc_not_present) {
|
||||||
dbg() << "ACPI: CMOS RTC Not Present";
|
dbg() << "ACPI: CMOS RTC Not Present";
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -167,9 +167,6 @@ void init_stage2()
|
||||||
SyncTask::spawn();
|
SyncTask::spawn();
|
||||||
FinalizerTask::spawn();
|
FinalizerTask::spawn();
|
||||||
|
|
||||||
// Sample test to see if the ACPI parser is working...
|
|
||||||
klog() << "ACPI: HPET table @ " << ACPI::Parser::the().find_table("HPET");
|
|
||||||
|
|
||||||
PCI::initialize();
|
PCI::initialize();
|
||||||
|
|
||||||
if (kernel_command_line().contains("text_debug")) {
|
if (kernel_command_line().contains("text_debug")) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue