1
Fork 0
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:
Andreas Kling 2020-04-09 14:31:47 +02:00
parent d95362d8cd
commit 4644217094
13 changed files with 46 additions and 111 deletions

View file

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

View file

@ -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();

View file

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

View file

@ -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&);

View file

@ -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();
} }

View file

@ -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();

View file

@ -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();
} }
} }

View file

@ -29,6 +29,7 @@
namespace Kernel { namespace Kernel {
namespace ACPI { namespace ACPI {
bool is_enabled();
void initialize(); void initialize();
} }

View file

@ -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();
}
} }
} }

View file

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

View file

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

View file

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

View file

@ -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")) {