diff options
-rw-r--r-- | Kernel/ACPI/ACPIDynamicParser.cpp | 2 | ||||
-rw-r--r-- | Kernel/ACPI/ACPIDynamicParser.h | 4 | ||||
-rw-r--r-- | Kernel/ACPI/ACPIParser.cpp | 402 | ||||
-rw-r--r-- | Kernel/ACPI/ACPIParser.h | 38 | ||||
-rw-r--r-- | Kernel/ACPI/ACPIStaticParser.cpp | 432 | ||||
-rw-r--r-- | Kernel/ACPI/ACPIStaticParser.h | 75 | ||||
-rw-r--r-- | Kernel/ACPI/Initialize.cpp | 2 | ||||
-rw-r--r-- | Kernel/Makefile | 1 | ||||
-rw-r--r-- | Kernel/init.cpp | 1 |
9 files changed, 424 insertions, 533 deletions
diff --git a/Kernel/ACPI/ACPIDynamicParser.cpp b/Kernel/ACPI/ACPIDynamicParser.cpp index 30b5cf94ff..7e9de14898 100644 --- a/Kernel/ACPI/ACPIDynamicParser.cpp +++ b/Kernel/ACPI/ACPIDynamicParser.cpp @@ -32,7 +32,7 @@ namespace ACPI { DynamicParser::DynamicParser(PhysicalAddress rsdp) : IRQHandler(9) - , StaticParser(rsdp) + , Parser(rsdp) { klog() << "ACPI: Dynamic Parsing Enabled, Can parse AML"; } diff --git a/Kernel/ACPI/ACPIDynamicParser.h b/Kernel/ACPI/ACPIDynamicParser.h index f7b80f4953..1e75930c36 100644 --- a/Kernel/ACPI/ACPIDynamicParser.h +++ b/Kernel/ACPI/ACPIDynamicParser.h @@ -27,7 +27,7 @@ #pragma once #include <AK/RefPtr.h> -#include <Kernel/ACPI/ACPIStaticParser.h> +#include <Kernel/ACPI/ACPIParser.h> #include <Kernel/Interrupts/IRQHandler.h> #include <Kernel/Lock.h> #include <Kernel/VM/PhysicalPage.h> @@ -38,7 +38,7 @@ namespace ACPI { class DynamicParser final : public IRQHandler - , public StaticParser { + , public Parser { friend class Parser; public: diff --git a/Kernel/ACPI/ACPIParser.cpp b/Kernel/ACPI/ACPIParser.cpp index 3ea46756ba..4eebc86f04 100644 --- a/Kernel/ACPI/ACPIParser.cpp +++ b/Kernel/ACPI/ACPIParser.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il> + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,6 +27,11 @@ #include <AK/StringView.h> #include <Kernel/ACPI/ACPIParser.h> +#include <Kernel/PCI/Access.h> +#include <Kernel/VM/MemoryManager.h> +#include <Kernel/VM/TypedMapping.h> +#include <LibBareMetal/IO.h> +#include <LibBareMetal/StdLib.h> namespace Kernel { namespace ACPI { @@ -43,35 +49,407 @@ void Parser::set_the(Parser& parser) s_acpi_parser = &parser; } -void Parser::enable_aml_interpretation() +static bool match_table_signature(PhysicalAddress table_header, const StringView& signature); +static PhysicalAddress search_table_in_xsdt(PhysicalAddress xsdt, const StringView& signature); +static PhysicalAddress search_table_in_rsdt(PhysicalAddress rsdt, const StringView& signature); +static bool validate_table(const Structures::SDTHeader&, size_t length); + +void Parser::locate_static_data() +{ + locate_main_system_description_table(); + initialize_main_system_description_table(); + init_fadt(); + init_facs(); +} + +PhysicalAddress Parser::find_table(const StringView& signature) +{ +#ifdef ACPI_DEBUG + dbg() << "ACPI: Calling Find Table method!"; +#endif + for (auto p_sdt : m_sdt_pointers) { + auto sdt = map_typed<Structures::SDTHeader>(p_sdt); +#ifdef ACPI_DEBUG + dbg() << "ACPI: Examining Table @ P " << p_sdt; +#endif + if (!strncmp(sdt->sig, signature.characters_without_null_termination(), 4)) { +#ifdef ACPI_DEBUG + dbg() << "ACPI: Found Table @ P " << p_sdt; +#endif + return p_sdt; + } + } + return {}; +} + +void Parser::init_facs() +{ + m_facs = find_table("FACS"); +} + +void Parser::init_fadt() { - klog() << "ACPI: No AML Interpretation Allowed"; + klog() << "ACPI: Initializing Fixed ACPI data"; + klog() << "ACPI: Searching for the Fixed ACPI Data Table"; + + m_fadt = find_table("FACP"); + ASSERT(!m_fadt.is_null()); + + auto sdt = map_typed<Structures::FADT>(m_fadt); + +#ifdef ACPI_DEBUG + dbg() << "ACPI: FADT @ V " << sdt << ", P " << (void*)m_fadt.as_ptr(); +#endif + klog() << "ACPI: Fixed ACPI data, Revision " << sdt->h.revision << ", Length " << sdt->h.length << " bytes"; + klog() << "ACPI: DSDT " << PhysicalAddress(sdt->dsdt_ptr); + m_x86_specific_flags.cmos_rtc_not_present = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::CMOS_RTC_Not_Present); + m_x86_specific_flags.keyboard_8042 = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::PS2_8042); + m_x86_specific_flags.legacy_devices = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::Legacy_Devices); + m_x86_specific_flags.msi_not_supported = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::MSI_Not_Supported); + m_x86_specific_flags.vga_not_present = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::VGA_Not_Present); + + m_hardware_flags.cpu_software_sleep = (sdt->flags & (u32)FADTFlags::FeatureFlags::CPU_SW_SLP); + m_hardware_flags.docking_capability = (sdt->flags & (u32)FADTFlags::FeatureFlags::DCK_CAP); + m_hardware_flags.fix_rtc = (sdt->flags & (u32)FADTFlags::FeatureFlags::FIX_RTC); + m_hardware_flags.force_apic_cluster_model = (sdt->flags & (u32)FADTFlags::FeatureFlags::FORCE_APIC_CLUSTER_MODEL); + m_hardware_flags.force_apic_physical_destination_mode = (sdt->flags & (u32)FADTFlags::FeatureFlags::FORCE_APIC_PHYSICAL_DESTINATION_MODE); + m_hardware_flags.hardware_reduced_acpi = (sdt->flags & (u32)FADTFlags::FeatureFlags::HW_REDUCED_ACPI); + m_hardware_flags.headless = (sdt->flags & (u32)FADTFlags::FeatureFlags::HEADLESS); + m_hardware_flags.low_power_s0_idle_capable = (sdt->flags & (u32)FADTFlags::FeatureFlags::LOW_POWER_S0_IDLE_CAPABLE); + m_hardware_flags.multiprocessor_c2 = (sdt->flags & (u32)FADTFlags::FeatureFlags::P_LVL2_UP); + m_hardware_flags.pci_express_wake = (sdt->flags & (u32)FADTFlags::FeatureFlags::PCI_EXP_WAK); + m_hardware_flags.power_button = (sdt->flags & (u32)FADTFlags::FeatureFlags::PWR_BUTTON); + m_hardware_flags.processor_c1 = (sdt->flags & (u32)FADTFlags::FeatureFlags::PROC_C1); + m_hardware_flags.remote_power_on_capable = (sdt->flags & (u32)FADTFlags::FeatureFlags::REMOTE_POWER_ON_CAPABLE); + m_hardware_flags.reset_register_supported = (sdt->flags & (u32)FADTFlags::FeatureFlags::RESET_REG_SUPPORTED); + m_hardware_flags.rtc_s4 = (sdt->flags & (u32)FADTFlags::FeatureFlags::RTC_s4); + m_hardware_flags.s4_rtc_status_valid = (sdt->flags & (u32)FADTFlags::FeatureFlags::S4_RTC_STS_VALID); + m_hardware_flags.sealed_case = (sdt->flags & (u32)FADTFlags::FeatureFlags::SEALED_CASE); + m_hardware_flags.sleep_button = (sdt->flags & (u32)FADTFlags::FeatureFlags::SLP_BUTTON); + m_hardware_flags.timer_value_extension = (sdt->flags & (u32)FADTFlags::FeatureFlags::TMR_VAL_EXT); + m_hardware_flags.use_platform_clock = (sdt->flags & (u32)FADTFlags::FeatureFlags::USE_PLATFORM_CLOCK); + m_hardware_flags.wbinvd = (sdt->flags & (u32)FADTFlags::FeatureFlags::WBINVD); + m_hardware_flags.wbinvd_flush = (sdt->flags & (u32)FADTFlags::FeatureFlags::WBINVD_FLUSH); +} + +bool Parser::can_reboot() +{ + auto fadt = map_typed<Structures::FADT>(m_fadt); + if (fadt->h.revision < 2) + return false; + return m_hardware_flags.reset_register_supported; +} + +void Parser::access_generic_address(const Structures::GenericAddressStructure& structure, u32 value) +{ + switch ((GenericAddressStructure::AddressSpace)structure.address_space) { + case GenericAddressStructure::AddressSpace::SystemIO: { + IOAddress address(structure.address); + dbg() << "ACPI: Sending value 0x" << String::format("%x", value) << " to " << address; + switch (structure.access_size) { + case (u8)GenericAddressStructure::AccessSize::QWord: { + dbg() << "Trying to send QWord to IO port"; + ASSERT_NOT_REACHED(); + break; + } + case (u8)GenericAddressStructure::AccessSize::Undefined: { + dbg() << "ACPI Warning: Unknown access size " << structure.access_size; + ASSERT(structure.bit_width != (u8)GenericAddressStructure::BitWidth::QWord); + ASSERT(structure.bit_width != (u8)GenericAddressStructure::BitWidth::Undefined); + dbg() << "ACPI: Bit Width - " << structure.bit_width << " bits"; + address.out(value, structure.bit_width); + break; + } + default: + address.out(value, (8 << (structure.access_size - 1))); + break; + } + return; + } + case GenericAddressStructure::AddressSpace::SystemMemory: { + dbg() << "ACPI: Sending value 0x" << String::format("%x", value) << " to " << PhysicalAddress(structure.address); + switch ((GenericAddressStructure::AccessSize)structure.access_size) { + case GenericAddressStructure::AccessSize::Byte: + *map_typed<u8>(PhysicalAddress(structure.address)) = value; + break; + case GenericAddressStructure::AccessSize::Word: + *map_typed<u16>(PhysicalAddress(structure.address)) = value; + break; + case GenericAddressStructure::AccessSize::DWord: + *map_typed<u32>(PhysicalAddress(structure.address)) = value; + break; + case GenericAddressStructure::AccessSize::QWord: { + *map_typed<u64>(PhysicalAddress(structure.address)) = value; + break; + } + default: + ASSERT_NOT_REACHED(); + } + return; + } + case GenericAddressStructure::AddressSpace::PCIConfigurationSpace: { + // According to the ACPI specification 6.2, page 168, PCI addresses must be confined to devices on Segment group 0, bus 0. + auto pci_address = PCI::Address(0, 0, ((structure.address >> 24) & 0xFF), ((structure.address >> 16) & 0xFF)); + dbg() << "ACPI: Sending value 0x" << String::format("%x", value) << " to " << pci_address; + u32 offset_in_pci_address = structure.address & 0xFFFF; + if (structure.access_size == (u8)GenericAddressStructure::AccessSize::QWord) { + dbg() << "Trying to send QWord to PCI configuration space"; + ASSERT_NOT_REACHED(); + } + ASSERT(structure.access_size != (u8)GenericAddressStructure::AccessSize::Undefined); + PCI::raw_access(pci_address, offset_in_pci_address, (1 << (structure.access_size - 1)), value); + return; + } + default: + ASSERT_NOT_REACHED(); + } ASSERT_NOT_REACHED(); } -void Parser::enable_aml_interpretation(File&) + +bool Parser::validate_reset_register() { - klog() << "ACPI: No AML Interpretation Allowed"; + // According to the ACPI spec 6.2, page 152, The reset register can only be located in I/O bus, PCI bus or memory-mapped. + auto fadt = map_typed<Structures::FADT>(m_fadt); + return (fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::PCIConfigurationSpace || fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::SystemMemory || fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::SystemIO); +} + +void Parser::try_acpi_reboot() +{ + InterruptDisabler disabler; + if (!can_reboot()) { + klog() << "ACPI: Reboot, Not supported!"; + return; + } +#ifdef ACPI_DEBUG + dbg() << "ACPI: Rebooting, Probing FADT (" << m_fadt << ")"; +#endif + + auto fadt = map_typed<Structures::FADT>(m_fadt); + ASSERT(validate_reset_register()); + access_generic_address(fadt->reset_reg, fadt->reset_value); + hang(); +} + +void Parser::try_acpi_shutdown() +{ + klog() << "ACPI: Shutdown is not supported with the current configuration, Abort!"; +} + +size_t Parser::get_table_size(PhysicalAddress table_header) +{ + InterruptDisabler disabler; +#ifdef ACPI_DEBUG + dbg() << "ACPI: Checking SDT Length"; +#endif + return map_typed<Structures::SDTHeader>(table_header)->length; +} + +u8 Parser::get_table_revision(PhysicalAddress table_header) +{ + InterruptDisabler disabler; +#ifdef ACPI_DEBUG + dbg() << "ACPI: Checking SDT Revision"; +#endif + return map_typed<Structures::SDTHeader>(table_header)->revision; +} + +void Parser::initialize_main_system_description_table() +{ +#ifdef ACPI_DEBUG + dbg() << "ACPI: Checking Main SDT Length to choose the correct mapping size"; +#endif + ASSERT(!m_main_system_description_table.is_null()); + auto length = get_table_size(m_main_system_description_table); + auto revision = get_table_revision(m_main_system_description_table); + + auto sdt = map_typed<Structures::SDTHeader>(m_main_system_description_table, length); + + klog() << "ACPI: Main Description Table valid? " << validate_table(*sdt, length); + + if (m_xsdt_supported) { + auto& xsdt = (const Structures::XSDT&)*sdt; + klog() << "ACPI: Using XSDT, Enumerating tables @ " << m_main_system_description_table; + klog() << "ACPI: XSDT Revision " << revision << ", Total length - " << length; +#ifdef ACPI_DEBUG + dbg() << "ACPI: XSDT pointer @ V " << xsdt; +#endif + for (u32 i = 0; i < ((length - sizeof(Structures::SDTHeader)) / sizeof(u64)); i++) { +#ifdef ACPI_DEBUG + dbg() << "ACPI: Found new table [" << i << "], @ V 0x" << String::format("%x", &xsdt.table_ptrs[i]) << " - P 0x" << String::format("%x", xsdt.table_ptrs[i]); +#endif + m_sdt_pointers.append(PhysicalAddress(xsdt.table_ptrs[i])); + } + } else { + auto& rsdt = (const Structures::RSDT&)*sdt; + klog() << "ACPI: Using RSDT, Enumerating tables @ " << m_main_system_description_table; + klog() << "ACPI: RSDT Revision " << revision << ", Total length - " << length; +#ifdef ACPI_DEBUG + dbg() << "ACPI: RSDT pointer @ V " << rsdt; +#endif + for (u32 i = 0; i < ((length - sizeof(Structures::SDTHeader)) / sizeof(u32)); i++) { +#ifdef ACPI_DEBUG + dbg() << "ACPI: Found new table [" << i << "], @ V 0x" << String::format("%x", &rsdt.table_ptrs[i]) << " - P 0x" << String::format("%x", rsdt.table_ptrs[i]); +#endif + m_sdt_pointers.append(PhysicalAddress(rsdt.table_ptrs[i])); + } + } +} + +void Parser::locate_main_system_description_table() +{ + auto rsdp = map_typed<Structures::RSDPDescriptor20>(m_rsdp); + if (rsdp->base.revision == 0) { + m_xsdt_supported = false; + } else if (rsdp->base.revision >= 2) { + if (rsdp->xsdt_ptr != (u64) nullptr) { + m_xsdt_supported = true; + } else { + m_xsdt_supported = false; + } + } + if (!m_xsdt_supported) { + m_main_system_description_table = PhysicalAddress(rsdp->base.rsdt_ptr); + } else { + m_main_system_description_table = PhysicalAddress(rsdp->xsdt_ptr); + } +} + +Parser::Parser(PhysicalAddress rsdp) + : m_rsdp(rsdp) +{ + klog() << "ACPI: Using RSDP @ " << rsdp; + locate_static_data(); +} + +static PhysicalAddress find_rsdp_in_ebda(u16 ebda_segment) +{ + auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)(ebda_segment << 4))), PAGE_ROUND_UP(1024), "ACPI Static Parser RSDP Finding #1", Region::Access::Read, false, true); + char* p_rsdp_str = (char*)(PhysicalAddress(ebda_segment << 4).as_ptr()); + for (char* rsdp_str = (char*)rsdp_region->vaddr().offset(offset_in_page((u32)(ebda_segment << 4))).as_ptr(); rsdp_str < (char*)(rsdp_region->vaddr().offset(offset_in_page((u32)(ebda_segment << 4))).get() + 1024); rsdp_str += 16) { +#ifdef ACPI_DEBUG + dbg() << "ACPI: Looking for RSDP in EBDA @ V " << (void*)rsdp_str << ", P " << (void*)p_rsdp_str; +#endif + if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR "))) + return PhysicalAddress((FlatPtr)p_rsdp_str); + p_rsdp_str += 16; + } + return {}; +} + +static PhysicalAddress find_rsdp_in_bios_area() +{ + auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(0xE0000), PAGE_ROUND_UP(0xFFFFF - 0xE0000), "ACPI Static Parser RSDP Finding #2", Region::Access::Read, false, true); + char* p_rsdp_str = (char*)(PhysicalAddress(0xE0000).as_ptr()); + for (char* rsdp_str = (char*)rsdp_region->vaddr().offset(offset_in_page((u32)(0xE0000))).as_ptr(); rsdp_str < (char*)(rsdp_region->vaddr().offset(offset_in_page((u32)(0xE0000))).get() + (0xFFFFF - 0xE0000)); rsdp_str += 16) { +#ifdef ACPI_DEBUG + dbg() << "ACPI: Looking for RSDP in BIOS ROM area @ V " << (void*)rsdp_str << ", P " << (void*)p_rsdp_str; +#endif + if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR "))) + return PhysicalAddress((FlatPtr)p_rsdp_str); + p_rsdp_str += 16; + } + return {}; +} + +static bool validate_table(const Structures::SDTHeader& v_header, size_t length) +{ + u8 checksum = 0; + auto* sdt = (const u8*)&v_header; + for (size_t i = 0; i < length; i++) + checksum += sdt[i]; + if (checksum == 0) + return true; + return false; +} + +PhysicalAddress StaticParsing::find_rsdp() +{ + auto ebda_seg_ptr = map_typed<u16>(PhysicalAddress(0x40e)); + klog() << "ACPI: Probing EBDA, Segment 0x" << String::format("%x", *ebda_seg_ptr); + auto rsdp = find_rsdp_in_ebda(*ebda_seg_ptr); + if (!rsdp.is_null()) + return rsdp; + return find_rsdp_in_bios_area(); +} + +PhysicalAddress StaticParsing::find_table(PhysicalAddress rsdp_address, const StringView& signature) +{ + // FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables. + // FIXME: Don't blindly use PAGE_SIZE here, but probe the actual length. + ASSERT(signature.length() == 4); + + auto rsdp = map_typed<Structures::RSDPDescriptor20>(rsdp_address); + + if (rsdp->base.revision == 0) + return search_table_in_rsdt(PhysicalAddress(rsdp->base.rsdt_ptr), signature); + + if (rsdp->base.revision >= 2) { + if (rsdp->xsdt_ptr) + return search_table_in_xsdt(PhysicalAddress(rsdp->xsdt_ptr), signature); + return search_table_in_rsdt(PhysicalAddress(rsdp->base.rsdt_ptr), signature); + } ASSERT_NOT_REACHED(); } -void Parser::enable_aml_interpretation(u8*, u32) + +static PhysicalAddress search_table_in_xsdt(PhysicalAddress xsdt_address, const StringView& signature) +{ + // FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables. + // FIXME: Don't blindly use PAGE_SIZE here, but probe the actual length. + ASSERT(signature.length() == 4); + + auto xsdt = map_typed<Structures::XSDT>(xsdt_address); + + for (size_t i = 0; i < ((xsdt->h.length - sizeof(Structures::SDTHeader)) / sizeof(u64)); ++i) { + if (match_table_signature(PhysicalAddress((FlatPtr)xsdt->table_ptrs[i]), signature)) + return PhysicalAddress((FlatPtr)xsdt->table_ptrs[i]); + } + return {}; +} + +static bool match_table_signature(PhysicalAddress table_header, const StringView& signature) +{ + // FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables. + // FIXME: Don't blindly use PAGE_SIZE here, but probe the actual length. + ASSERT(signature.length() == 4); + + auto table = map_typed<Structures::RSDT>(table_header); + return !strncmp(table->h.sig, signature.characters_without_null_termination(), 4); +} + +static PhysicalAddress search_table_in_rsdt(PhysicalAddress rsdt_address, const StringView& signature) +{ + // FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables. + // FIXME: Don't blindly use PAGE_SIZE here, but probe the actual length. + ASSERT(signature.length() == 4); + + auto rsdt = map_typed<Structures::RSDT>(rsdt_address); + + for (u32 i = 0; i < ((rsdt->h.length - sizeof(Structures::SDTHeader)) / sizeof(u32)); i++) { + if (match_table_signature(PhysicalAddress((FlatPtr)rsdt->table_ptrs[i]), signature)) + return PhysicalAddress((FlatPtr)rsdt->table_ptrs[i]); + } + return {}; +} + +void Parser::enable_aml_interpretation() { - klog() << "ACPI: No AML Interpretation Allowed"; ASSERT_NOT_REACHED(); } -void Parser::disable_aml_interpretation() + +void Parser::enable_aml_interpretation(File&) { - klog() << "ACPI Limited: No AML Interpretation Allowed"; ASSERT_NOT_REACHED(); } -const FADTFlags::HardwareFeatures& Parser::hardware_features() const + +void Parser::enable_aml_interpretation(u8*, u32) { - klog() << "ACPI Limited: Hardware features cannot be obtained"; ASSERT_NOT_REACHED(); } -const FADTFlags::x86_Specific_Flags& Parser::x86_specific_flags() const + +void Parser::disable_aml_interpretation() { - klog() << "ACPI Limited: x86 specific features cannot be obtained"; ASSERT_NOT_REACHED(); } + } } diff --git a/Kernel/ACPI/ACPIParser.h b/Kernel/ACPI/ACPIParser.h index 8a69682b5c..18b1de19aa 100644 --- a/Kernel/ACPI/ACPIParser.h +++ b/Kernel/ACPI/ACPIParser.h @@ -47,15 +47,15 @@ public: set_the(*new ParserType(rsdp)); } - virtual PhysicalAddress find_table(const StringView& signature) = 0; + virtual PhysicalAddress find_table(const StringView& signature); - virtual void try_acpi_reboot() = 0; - virtual bool can_reboot() = 0; - virtual void try_acpi_shutdown() = 0; - virtual bool can_shutdown() = 0; + virtual void try_acpi_reboot(); + virtual bool can_reboot(); + virtual void try_acpi_shutdown(); + virtual bool can_shutdown() { return false; } - virtual const FADTFlags::HardwareFeatures& hardware_features() const = 0; - virtual const FADTFlags::x86_Specific_Flags& x86_specific_flags() const = 0; + const FADTFlags::HardwareFeatures& hardware_features() const { return m_hardware_flags; } + const FADTFlags::x86_Specific_Flags& x86_specific_flags() const { return m_x86_specific_flags; } virtual void enable_aml_interpretation(); virtual void enable_aml_interpretation(File&); @@ -63,10 +63,32 @@ public: virtual void disable_aml_interpretation(); protected: - Parser() {} + explicit Parser(PhysicalAddress rsdp); private: static void set_the(Parser&); + + void locate_static_data(); + void locate_main_system_description_table(); + void initialize_main_system_description_table(); + size_t get_table_size(PhysicalAddress); + u8 get_table_revision(PhysicalAddress); + void init_fadt(); + void init_facs(); + + bool validate_reset_register(); + void access_generic_address(const Structures::GenericAddressStructure&, u32 value); + + PhysicalAddress m_rsdp; + PhysicalAddress m_main_system_description_table; + + Vector<PhysicalAddress> m_sdt_pointers; + PhysicalAddress m_fadt; + PhysicalAddress m_facs; + + bool m_xsdt_supported { false }; + FADTFlags::HardwareFeatures m_hardware_flags; + FADTFlags::x86_Specific_Flags m_x86_specific_flags; }; } diff --git a/Kernel/ACPI/ACPIStaticParser.cpp b/Kernel/ACPI/ACPIStaticParser.cpp deleted file mode 100644 index 292f71f17a..0000000000 --- a/Kernel/ACPI/ACPIStaticParser.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <AK/StringView.h> -#include <Kernel/ACPI/ACPIStaticParser.h> -#include <Kernel/PCI/Access.h> -#include <Kernel/VM/MemoryManager.h> -#include <Kernel/VM/TypedMapping.h> -#include <LibBareMetal/IO.h> -#include <LibBareMetal/StdLib.h> - -//#define ACPI_DEBUG - -namespace Kernel { -namespace ACPI { - -static bool match_table_signature(PhysicalAddress table_header, const StringView& signature); -static PhysicalAddress search_table_in_xsdt(PhysicalAddress xsdt, const StringView& signature); -static PhysicalAddress search_table_in_rsdt(PhysicalAddress rsdt, const StringView& signature); -static bool validate_table(const Structures::SDTHeader&, size_t length); - -void StaticParser::locate_static_data() -{ - locate_main_system_description_table(); - initialize_main_system_description_table(); - init_fadt(); - init_facs(); -} - -PhysicalAddress StaticParser::find_table(const StringView& signature) -{ -#ifdef ACPI_DEBUG - dbg() << "ACPI: Calling Find Table method!"; -#endif - for (auto p_sdt : m_sdt_pointers) { - auto sdt = map_typed<Structures::SDTHeader>(p_sdt); -#ifdef ACPI_DEBUG - dbg() << "ACPI: Examining Table @ P " << p_sdt; -#endif - if (!strncmp(sdt->sig, signature.characters_without_null_termination(), 4)) { -#ifdef ACPI_DEBUG - dbg() << "ACPI: Found Table @ P " << p_sdt; -#endif - return p_sdt; - } - } - return {}; -} - -void StaticParser::init_facs() -{ - m_facs = find_table("FACS"); -} - -const FADTFlags::HardwareFeatures& StaticParser::hardware_features() const -{ - return m_hardware_flags; -} -const FADTFlags::x86_Specific_Flags& StaticParser::x86_specific_flags() const -{ - return m_x86_specific_flags; -} - -void StaticParser::init_fadt() -{ - klog() << "ACPI: Initializing Fixed ACPI data"; - klog() << "ACPI: Searching for the Fixed ACPI Data Table"; - - m_fadt = find_table("FACP"); - ASSERT(!m_fadt.is_null()); - - auto sdt = map_typed<Structures::FADT>(m_fadt); - -#ifdef ACPI_DEBUG - dbg() << "ACPI: FADT @ V " << sdt << ", P " << (void*)m_fadt.as_ptr(); -#endif - klog() << "ACPI: Fixed ACPI data, Revision " << sdt->h.revision << ", Length " << sdt->h.length << " bytes"; - klog() << "ACPI: DSDT " << PhysicalAddress(sdt->dsdt_ptr); - m_x86_specific_flags.cmos_rtc_not_present = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::CMOS_RTC_Not_Present); - m_x86_specific_flags.keyboard_8042 = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::PS2_8042); - m_x86_specific_flags.legacy_devices = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::Legacy_Devices); - m_x86_specific_flags.msi_not_supported = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::MSI_Not_Supported); - m_x86_specific_flags.vga_not_present = (sdt->ia_pc_boot_arch_flags & (u8)FADTFlags::IA_PC_Flags::VGA_Not_Present); - - m_hardware_flags.cpu_software_sleep = (sdt->flags & (u32)FADTFlags::FeatureFlags::CPU_SW_SLP); - m_hardware_flags.docking_capability = (sdt->flags & (u32)FADTFlags::FeatureFlags::DCK_CAP); - m_hardware_flags.fix_rtc = (sdt->flags & (u32)FADTFlags::FeatureFlags::FIX_RTC); - m_hardware_flags.force_apic_cluster_model = (sdt->flags & (u32)FADTFlags::FeatureFlags::FORCE_APIC_CLUSTER_MODEL); - m_hardware_flags.force_apic_physical_destination_mode = (sdt->flags & (u32)FADTFlags::FeatureFlags::FORCE_APIC_PHYSICAL_DESTINATION_MODE); - m_hardware_flags.hardware_reduced_acpi = (sdt->flags & (u32)FADTFlags::FeatureFlags::HW_REDUCED_ACPI); - m_hardware_flags.headless = (sdt->flags & (u32)FADTFlags::FeatureFlags::HEADLESS); - m_hardware_flags.low_power_s0_idle_capable = (sdt->flags & (u32)FADTFlags::FeatureFlags::LOW_POWER_S0_IDLE_CAPABLE); - m_hardware_flags.multiprocessor_c2 = (sdt->flags & (u32)FADTFlags::FeatureFlags::P_LVL2_UP); - m_hardware_flags.pci_express_wake = (sdt->flags & (u32)FADTFlags::FeatureFlags::PCI_EXP_WAK); - m_hardware_flags.power_button = (sdt->flags & (u32)FADTFlags::FeatureFlags::PWR_BUTTON); - m_hardware_flags.processor_c1 = (sdt->flags & (u32)FADTFlags::FeatureFlags::PROC_C1); - m_hardware_flags.remote_power_on_capable = (sdt->flags & (u32)FADTFlags::FeatureFlags::REMOTE_POWER_ON_CAPABLE); - m_hardware_flags.reset_register_supported = (sdt->flags & (u32)FADTFlags::FeatureFlags::RESET_REG_SUPPORTED); - m_hardware_flags.rtc_s4 = (sdt->flags & (u32)FADTFlags::FeatureFlags::RTC_s4); - m_hardware_flags.s4_rtc_status_valid = (sdt->flags & (u32)FADTFlags::FeatureFlags::S4_RTC_STS_VALID); - m_hardware_flags.sealed_case = (sdt->flags & (u32)FADTFlags::FeatureFlags::SEALED_CASE); - m_hardware_flags.sleep_button = (sdt->flags & (u32)FADTFlags::FeatureFlags::SLP_BUTTON); - m_hardware_flags.timer_value_extension = (sdt->flags & (u32)FADTFlags::FeatureFlags::TMR_VAL_EXT); - m_hardware_flags.use_platform_clock = (sdt->flags & (u32)FADTFlags::FeatureFlags::USE_PLATFORM_CLOCK); - m_hardware_flags.wbinvd = (sdt->flags & (u32)FADTFlags::FeatureFlags::WBINVD); - m_hardware_flags.wbinvd_flush = (sdt->flags & (u32)FADTFlags::FeatureFlags::WBINVD_FLUSH); -} - -bool StaticParser::can_reboot() -{ - auto fadt = map_typed<Structures::FADT>(m_fadt); - if (fadt->h.revision < 2) - return false; - return m_hardware_flags.reset_register_supported; -} - -void StaticParser::access_generic_address(const Structures::GenericAddressStructure& structure, u32 value) -{ - switch ((GenericAddressStructure::AddressSpace)structure.address_space) { - case GenericAddressStructure::AddressSpace::SystemIO: { - IOAddress address(structure.address); - dbg() << "ACPI: Sending value 0x" << String::format("%x", value) << " to " << address; - switch (structure.access_size) { - case (u8)GenericAddressStructure::AccessSize::QWord: { - dbg() << "Trying to send QWord to IO port"; - ASSERT_NOT_REACHED(); - break; - } - case (u8)GenericAddressStructure::AccessSize::Undefined: { - dbg() << "ACPI Warning: Unknown access size " << structure.access_size; - ASSERT(structure.bit_width != (u8)GenericAddressStructure::BitWidth::QWord); - ASSERT(structure.bit_width != (u8)GenericAddressStructure::BitWidth::Undefined); - dbg() << "ACPI: Bit Width - " << structure.bit_width << " bits"; - address.out(value, structure.bit_width); - break; - } - default: - address.out(value, (8 << (structure.access_size - 1))); - break; - } - return; - } - case GenericAddressStructure::AddressSpace::SystemMemory: { - dbg() << "ACPI: Sending value 0x" << String::format("%x", value) << " to " << PhysicalAddress(structure.address); - switch ((GenericAddressStructure::AccessSize)structure.access_size) { - case GenericAddressStructure::AccessSize::Byte: - *map_typed<u8>(PhysicalAddress(structure.address)) = value; - break; - case GenericAddressStructure::AccessSize::Word: - *map_typed<u16>(PhysicalAddress(structure.address)) = value; - break; - case GenericAddressStructure::AccessSize::DWord: - *map_typed<u32>(PhysicalAddress(structure.address)) = value; - break; - case GenericAddressStructure::AccessSize::QWord: { - *map_typed<u64>(PhysicalAddress(structure.address)) = value; - break; - } - default: - ASSERT_NOT_REACHED(); - } - return; - } - case GenericAddressStructure::AddressSpace::PCIConfigurationSpace: { - // According to the ACPI specification 6.2, page 168, PCI addresses must be confined to devices on Segment group 0, bus 0. - auto pci_address = PCI::Address(0, 0, ((structure.address >> 24) & 0xFF), ((structure.address >> 16) & 0xFF)); - dbg() << "ACPI: Sending value 0x" << String::format("%x", value) << " to " << pci_address; - u32 offset_in_pci_address = structure.address & 0xFFFF; - if (structure.access_size == (u8)GenericAddressStructure::AccessSize::QWord) { - dbg() << "Trying to send QWord to PCI configuration space"; - ASSERT_NOT_REACHED(); - } - ASSERT(structure.access_size != (u8)GenericAddressStructure::AccessSize::Undefined); - PCI::raw_access(pci_address, offset_in_pci_address, (1 << (structure.access_size - 1)), value); - return; - } - default: - ASSERT_NOT_REACHED(); - } - ASSERT_NOT_REACHED(); -} - -bool StaticParser::validate_reset_register() -{ - // According to the ACPI spec 6.2, page 152, The reset register can only be located in I/O bus, PCI bus or memory-mapped. - auto fadt = map_typed<Structures::FADT>(m_fadt); - return (fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::PCIConfigurationSpace || fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::SystemMemory || fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::SystemIO); -} - -void StaticParser::try_acpi_reboot() -{ - InterruptDisabler disabler; - if (!can_reboot()) { - klog() << "ACPI: Reboot, Not supported!"; - return; - } -#ifdef ACPI_DEBUG - dbg() << "ACPI: Rebooting, Probing FADT (" << m_fadt << ")"; -#endif - - auto fadt = map_typed<Structures::FADT>(m_fadt); - ASSERT(validate_reset_register()); - access_generic_address(fadt->reset_reg, fadt->reset_value); - hang(); -} - -void StaticParser::try_acpi_shutdown() -{ - klog() << "ACPI: Shutdown is not supported with the current configuration, Abort!"; -} - -size_t StaticParser::get_table_size(PhysicalAddress table_header) -{ - InterruptDisabler disabler; -#ifdef ACPI_DEBUG - dbg() << "ACPI: Checking SDT Length"; -#endif - return map_typed<Structures::SDTHeader>(table_header)->length; -} - -u8 StaticParser::get_table_revision(PhysicalAddress table_header) -{ - InterruptDisabler disabler; -#ifdef ACPI_DEBUG - dbg() << "ACPI: Checking SDT Revision"; -#endif - return map_typed<Structures::SDTHeader>(table_header)->revision; -} - -void StaticParser::initialize_main_system_description_table() -{ -#ifdef ACPI_DEBUG - dbg() << "ACPI: Checking Main SDT Length to choose the correct mapping size"; -#endif - ASSERT(!m_main_system_description_table.is_null()); - auto length = get_table_size(m_main_system_description_table); - auto revision = get_table_revision(m_main_system_description_table); - - auto sdt = map_typed<Structures::SDTHeader>(m_main_system_description_table, length); - - klog() << "ACPI: Main Description Table valid? " << validate_table(*sdt, length); - - if (m_xsdt_supported) { - auto& xsdt = (const Structures::XSDT&)*sdt; - klog() << "ACPI: Using XSDT, Enumerating tables @ " << m_main_system_description_table; - klog() << "ACPI: XSDT Revision " << revision << ", Total length - " << length; -#ifdef ACPI_DEBUG - dbg() << "ACPI: XSDT pointer @ V " << xsdt; -#endif - for (u32 i = 0; i < ((length - sizeof(Structures::SDTHeader)) / sizeof(u64)); i++) { -#ifdef ACPI_DEBUG - dbg() << "ACPI: Found new table [" << i << "], @ V 0x" << String::format("%x", &xsdt.table_ptrs[i]) << " - P 0x" << String::format("%x", xsdt.table_ptrs[i]); -#endif - m_sdt_pointers.append(PhysicalAddress(xsdt.table_ptrs[i])); - } - } else { - auto& rsdt = (const Structures::RSDT&)*sdt; - klog() << "ACPI: Using RSDT, Enumerating tables @ " << m_main_system_description_table; - klog() << "ACPI: RSDT Revision " << revision << ", Total length - " << length; -#ifdef ACPI_DEBUG - dbg() << "ACPI: RSDT pointer @ V " << rsdt; -#endif - for (u32 i = 0; i < ((length - sizeof(Structures::SDTHeader)) / sizeof(u32)); i++) { -#ifdef ACPI_DEBUG - dbg() << "ACPI: Found new table [" << i << "], @ V 0x" << String::format("%x", &rsdt.table_ptrs[i]) << " - P 0x" << String::format("%x", rsdt.table_ptrs[i]); -#endif - m_sdt_pointers.append(PhysicalAddress(rsdt.table_ptrs[i])); - } - } -} - -void StaticParser::locate_main_system_description_table() -{ - auto rsdp = map_typed<Structures::RSDPDescriptor20>(m_rsdp); - if (rsdp->base.revision == 0) { - m_xsdt_supported = false; - } else if (rsdp->base.revision >= 2) { - if (rsdp->xsdt_ptr != (u64) nullptr) { - m_xsdt_supported = true; - } else { - m_xsdt_supported = false; - } - } - if (!m_xsdt_supported) { - m_main_system_description_table = PhysicalAddress(rsdp->base.rsdt_ptr); - } else { - m_main_system_description_table = PhysicalAddress(rsdp->xsdt_ptr); - } -} - -StaticParser::StaticParser(PhysicalAddress rsdp) - : m_rsdp(rsdp) -{ - klog() << "ACPI: Using RSDP @ " << rsdp; - locate_static_data(); -} - -static PhysicalAddress find_rsdp_in_ebda(u16 ebda_segment) -{ - auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)(ebda_segment << 4))), PAGE_ROUND_UP(1024), "ACPI Static Parser RSDP Finding #1", Region::Access::Read, false, true); - char* p_rsdp_str = (char*)(PhysicalAddress(ebda_segment << 4).as_ptr()); - for (char* rsdp_str = (char*)rsdp_region->vaddr().offset(offset_in_page((u32)(ebda_segment << 4))).as_ptr(); rsdp_str < (char*)(rsdp_region->vaddr().offset(offset_in_page((u32)(ebda_segment << 4))).get() + 1024); rsdp_str += 16) { -#ifdef ACPI_DEBUG - dbg() << "ACPI: Looking for RSDP in EBDA @ V " << (void*)rsdp_str << ", P " << (void*)p_rsdp_str; -#endif - if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR "))) - return PhysicalAddress((FlatPtr)p_rsdp_str); - p_rsdp_str += 16; - } - return {}; -} - -static PhysicalAddress find_rsdp_in_bios_area() -{ - auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(0xE0000), PAGE_ROUND_UP(0xFFFFF - 0xE0000), "ACPI Static Parser RSDP Finding #2", Region::Access::Read, false, true); - char* p_rsdp_str = (char*)(PhysicalAddress(0xE0000).as_ptr()); - for (char* rsdp_str = (char*)rsdp_region->vaddr().offset(offset_in_page((u32)(0xE0000))).as_ptr(); rsdp_str < (char*)(rsdp_region->vaddr().offset(offset_in_page((u32)(0xE0000))).get() + (0xFFFFF - 0xE0000)); rsdp_str += 16) { -#ifdef ACPI_DEBUG - dbg() << "ACPI: Looking for RSDP in BIOS ROM area @ V " << (void*)rsdp_str << ", P " << (void*)p_rsdp_str; -#endif - if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR "))) - return PhysicalAddress((FlatPtr)p_rsdp_str); - p_rsdp_str += 16; - } - return {}; -} - -static bool validate_table(const Structures::SDTHeader& v_header, size_t length) -{ - u8 checksum = 0; - auto* sdt = (const u8*)&v_header; - for (size_t i = 0; i < length; i++) - checksum += sdt[i]; - if (checksum == 0) - return true; - return false; -} - -PhysicalAddress StaticParsing::find_rsdp() -{ - auto ebda_seg_ptr = map_typed<u16>(PhysicalAddress(0x40e)); - klog() << "ACPI: Probing EBDA, Segment 0x" << String::format("%x", *ebda_seg_ptr); - auto rsdp = find_rsdp_in_ebda(*ebda_seg_ptr); - if (!rsdp.is_null()) - return rsdp; - return find_rsdp_in_bios_area(); -} - -PhysicalAddress StaticParsing::find_table(PhysicalAddress rsdp_address, const StringView& signature) -{ - // FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables. - // FIXME: Don't blindly use PAGE_SIZE here, but probe the actual length. - ASSERT(signature.length() == 4); - - auto rsdp = map_typed<Structures::RSDPDescriptor20>(rsdp_address); - - if (rsdp->base.revision == 0) - return search_table_in_rsdt(PhysicalAddress(rsdp->base.rsdt_ptr), signature); - - if (rsdp->base.revision >= 2) { - if (rsdp->xsdt_ptr) - return search_table_in_xsdt(PhysicalAddress(rsdp->xsdt_ptr), signature); - return search_table_in_rsdt(PhysicalAddress(rsdp->base.rsdt_ptr), signature); - } - ASSERT_NOT_REACHED(); -} - -static PhysicalAddress search_table_in_xsdt(PhysicalAddress xsdt_address, const StringView& signature) -{ - // FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables. - // FIXME: Don't blindly use PAGE_SIZE here, but probe the actual length. - ASSERT(signature.length() == 4); - - auto xsdt = map_typed<Structures::XSDT>(xsdt_address); - - for (size_t i = 0; i < ((xsdt->h.length - sizeof(Structures::SDTHeader)) / sizeof(u64)); ++i) { - if (match_table_signature(PhysicalAddress((FlatPtr)xsdt->table_ptrs[i]), signature)) - return PhysicalAddress((FlatPtr)xsdt->table_ptrs[i]); - } - return {}; -} - -static bool match_table_signature(PhysicalAddress table_header, const StringView& signature) -{ - // FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables. - // FIXME: Don't blindly use PAGE_SIZE here, but probe the actual length. - ASSERT(signature.length() == 4); - - auto table = map_typed<Structures::RSDT>(table_header); - return !strncmp(table->h.sig, signature.characters_without_null_termination(), 4); -} - -static PhysicalAddress search_table_in_rsdt(PhysicalAddress rsdt_address, const StringView& signature) -{ - // FIXME: There's no validation of ACPI tables here. Use the checksum to validate the tables. - // FIXME: Don't blindly use PAGE_SIZE here, but probe the actual length. - ASSERT(signature.length() == 4); - - auto rsdt = map_typed<Structures::RSDT>(rsdt_address); - - for (u32 i = 0; i < ((rsdt->h.length - sizeof(Structures::SDTHeader)) / sizeof(u32)); i++) { - if (match_table_signature(PhysicalAddress((FlatPtr)rsdt->table_ptrs[i]), signature)) - return PhysicalAddress((FlatPtr)rsdt->table_ptrs[i]); - } - return {}; -} - -} -} diff --git a/Kernel/ACPI/ACPIStaticParser.h b/Kernel/ACPI/ACPIStaticParser.h deleted file mode 100644 index 506b16de0e..0000000000 --- a/Kernel/ACPI/ACPIStaticParser.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include <AK/OwnPtr.h> -#include <Kernel/ACPI/ACPIParser.h> - -namespace Kernel { -namespace ACPI { - -class StaticParser : public Parser { - friend class Parser; - -public: - virtual PhysicalAddress find_table(const StringView& signature) 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 const FADTFlags::HardwareFeatures& hardware_features() const override; - virtual const FADTFlags::x86_Specific_Flags& x86_specific_flags() const override; - -protected: - explicit StaticParser(PhysicalAddress rsdp); - -private: - void locate_static_data(); - void locate_main_system_description_table(); - void initialize_main_system_description_table(); - size_t get_table_size(PhysicalAddress); - u8 get_table_revision(PhysicalAddress); - void init_fadt(); - void init_facs(); - - bool validate_reset_register(); - void access_generic_address(const Structures::GenericAddressStructure&, u32 value); - - PhysicalAddress m_rsdp; - PhysicalAddress m_main_system_description_table; - - Vector<PhysicalAddress> m_sdt_pointers; - PhysicalAddress m_fadt; - PhysicalAddress m_facs; - - bool m_xsdt_supported; - FADTFlags::HardwareFeatures m_hardware_flags; - FADTFlags::x86_Specific_Flags m_x86_specific_flags; -}; -} -} diff --git a/Kernel/ACPI/Initialize.cpp b/Kernel/ACPI/Initialize.cpp index 5678aa83a7..7ebeb39074 100644 --- a/Kernel/ACPI/Initialize.cpp +++ b/Kernel/ACPI/Initialize.cpp @@ -60,7 +60,7 @@ void initialize() if (feature_level == FeatureLevel::Enabled) Parser::initialize<DynamicParser>(rsdp); else - Parser::initialize<StaticParser>(rsdp); + Parser::initialize<Parser>(rsdp); } bool is_enabled() diff --git a/Kernel/Makefile b/Kernel/Makefile index 110b35d006..eec367de39 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -122,7 +122,6 @@ OBJS = \ VM/SharedInodeVMObject.o \ VM/VMObject.o \ ACPI/ACPIParser.o \ - ACPI/ACPIStaticParser.o \ ACPI/ACPIDynamicParser.o \ ACPI/DMIDecoder.o \ ACPI/Initialize.o \ diff --git a/Kernel/init.cpp b/Kernel/init.cpp index ac9fd0a156..1b16dae215 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -26,7 +26,6 @@ #include <AK/Types.h> #include <Kernel/ACPI/ACPIDynamicParser.h> -#include <Kernel/ACPI/ACPIStaticParser.h> #include <Kernel/ACPI/DMIDecoder.h> #include <Kernel/ACPI/Initialize.h> #include <Kernel/ACPI/MultiProcessorParser.h> |