diff options
author | Andreas Kling <kling@serenityos.org> | 2020-05-22 13:34:53 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-22 13:36:57 +0200 |
commit | 4b847810bf4eb2308d13e1e99eb11090ce8622b6 (patch) | |
tree | 7f6fb9ac3ec62bf3958a4dbfebd9ce520e470a50 | |
parent | 84b7bc5e14bcdaef0721143f8d99b40fde7e7c5e (diff) | |
download | serenity-4b847810bf4eb2308d13e1e99eb11090ce8622b6.zip |
Kernel: Simplify scanning BIOS/EBDA and MP parser initialization
Add a MappedROM::find_chunk_starting_with() helper since that's a very
common usage pattern in clients of this code.
Also convert MultiProcessorParser from a persistent singleton object
to a temporary object constructed via a failable factory function.
-rw-r--r-- | Kernel/ACPI/Definitions.h | 6 | ||||
-rw-r--r-- | Kernel/ACPI/Initialize.cpp | 6 | ||||
-rw-r--r-- | Kernel/ACPI/MultiProcessorParser.cpp | 64 | ||||
-rw-r--r-- | Kernel/ACPI/MultiProcessorParser.h | 14 | ||||
-rw-r--r-- | Kernel/ACPI/Parser.cpp | 33 | ||||
-rw-r--r-- | Kernel/Interrupts/InterruptManagement.cpp | 15 | ||||
-rw-r--r-- | Kernel/Interrupts/InterruptManagement.h | 1 | ||||
-rw-r--r-- | Kernel/VM/MappedROM.h | 9 |
8 files changed, 47 insertions, 101 deletions
diff --git a/Kernel/ACPI/Definitions.h b/Kernel/ACPI/Definitions.h index c269f19d22..f386dc48b5 100644 --- a/Kernel/ACPI/Definitions.h +++ b/Kernel/ACPI/Definitions.h @@ -336,8 +336,10 @@ class DynamicParser; class Parser; namespace StaticParsing { -PhysicalAddress find_rsdp(); +Optional<PhysicalAddress> find_rsdp(); PhysicalAddress find_table(PhysicalAddress rsdp, const StringView& signature); -}; } + +} + } diff --git a/Kernel/ACPI/Initialize.cpp b/Kernel/ACPI/Initialize.cpp index 0ef293a166..177c0e1f5c 100644 --- a/Kernel/ACPI/Initialize.cpp +++ b/Kernel/ACPI/Initialize.cpp @@ -54,13 +54,13 @@ void initialize() return; auto rsdp = StaticParsing::find_rsdp(); - if (rsdp.is_null()) + if (!rsdp.has_value()) return; if (feature_level == FeatureLevel::Enabled) - Parser::initialize<DynamicParser>(rsdp); + Parser::initialize<DynamicParser>(rsdp.value()); else - Parser::initialize<Parser>(rsdp); + Parser::initialize<Parser>(rsdp.value()); } bool is_enabled() diff --git a/Kernel/ACPI/MultiProcessorParser.cpp b/Kernel/ACPI/MultiProcessorParser.cpp index 2191d1194d..a292e8be60 100644 --- a/Kernel/ACPI/MultiProcessorParser.cpp +++ b/Kernel/ACPI/MultiProcessorParser.cpp @@ -37,29 +37,20 @@ namespace Kernel { -static MultiProcessorParser* s_parser; - -bool MultiProcessorParser::is_initialized() -{ - return s_parser != nullptr; -} - -void MultiProcessorParser::initialize() +OwnPtr<MultiProcessorParser> MultiProcessorParser::autodetect() { - ASSERT(!is_initialized()); - s_parser = new MultiProcessorParser; + auto floating_pointer = find_floating_pointer(); + if (!floating_pointer.has_value()) + return nullptr; + return adopt_own(*new MultiProcessorParser(floating_pointer.value())); } -MultiProcessorParser::MultiProcessorParser() - : m_floating_pointer(search_floating_pointer()) +MultiProcessorParser::MultiProcessorParser(PhysicalAddress floating_pointer) + : m_floating_pointer(floating_pointer) { - if (!m_floating_pointer.is_null()) { - klog() << "MultiProcessor: Floating Pointer Structure @ " << PhysicalAddress(m_floating_pointer); - parse_floating_pointer_data(); - parse_configuration_table(); - } else { - klog() << "MultiProcessor: Can't Locate Floating Pointer Structure, disabled."; - } + klog() << "MultiProcessor: Floating Pointer Structure @ " << m_floating_pointer; + parse_floating_pointer_data(); + parse_configuration_table(); } void MultiProcessorParser::parse_floating_pointer_data() @@ -114,32 +105,13 @@ void MultiProcessorParser::parse_configuration_table() } } -PhysicalAddress MultiProcessorParser::search_floating_pointer() +Optional<PhysicalAddress> MultiProcessorParser::find_floating_pointer() { - auto mp_floating_pointer = search_floating_pointer_in_ebda(); - if (!mp_floating_pointer.is_null()) + StringView signature("_MP_"); + auto mp_floating_pointer = map_ebda().find_chunk_starting_with(signature, 16); + if (mp_floating_pointer.has_value()) return mp_floating_pointer; - return search_floating_pointer_in_bios_area(); -} - -PhysicalAddress MultiProcessorParser::search_floating_pointer_in_ebda() -{ - klog() << "MultiProcessor: Probing EBDA"; - auto ebda = map_ebda(); - for (auto* floating_pointer_str = ebda.base(); floating_pointer_str < ebda.end(); floating_pointer_str += 16) { - if (!strncmp("_MP_", (const char*)floating_pointer_str, strlen("_MP_"))) - return ebda.paddr_of(floating_pointer_str); - } - return {}; -} -PhysicalAddress MultiProcessorParser::search_floating_pointer_in_bios_area() -{ - auto bios = map_bios(); - for (auto* floating_pointer_str = bios.base(); floating_pointer_str < bios.end(); floating_pointer_str += 16) { - if (!strncmp("_MP_", (const char*)floating_pointer_str, strlen("_MP_"))) - return bios.paddr_of(floating_pointer_str); - } - return {}; + return map_bios().find_chunk_starting_with(signature, 16); } Vector<u8> MultiProcessorParser::get_pci_bus_ids() const @@ -152,12 +124,6 @@ Vector<u8> MultiProcessorParser::get_pci_bus_ids() const return pci_bus_ids; } -MultiProcessorParser& MultiProcessorParser::the() -{ - ASSERT(is_initialized()); - return *s_parser; -} - Vector<PCIInterruptOverrideMetadata> MultiProcessorParser::get_pci_interrupt_redirections() { dbg() << "MultiProcessor: Get PCI IOAPIC redirections"; diff --git a/Kernel/ACPI/MultiProcessorParser.h b/Kernel/ACPI/MultiProcessorParser.h index 7aca917d0f..9f3a05b385 100644 --- a/Kernel/ACPI/MultiProcessorParser.h +++ b/Kernel/ACPI/MultiProcessorParser.h @@ -189,25 +189,21 @@ struct [[gnu::packed]] CompatibilityBusAddressSpaceModifierEntry class PCIInterruptOverrideMetadata; -class MultiProcessorParser { +class MultiProcessorParser final { public: - static MultiProcessorParser& the(); + static OwnPtr<MultiProcessorParser> autodetect(); - static bool is_initialized(); - static void initialize(); Vector<PCIInterruptOverrideMetadata> get_pci_interrupt_redirections(); -protected: - MultiProcessorParser(); +private: + explicit MultiProcessorParser(PhysicalAddress floating_pointer); void parse_configuration_table(); void parse_floating_pointer_data(); Vector<u8> get_pci_bus_ids() const; - PhysicalAddress search_floating_pointer(); - PhysicalAddress search_floating_pointer_in_ebda(); - PhysicalAddress search_floating_pointer_in_bios_area(); + static Optional<PhysicalAddress> find_floating_pointer(); PhysicalAddress m_floating_pointer; PhysicalAddress m_configuration_table; diff --git a/Kernel/ACPI/Parser.cpp b/Kernel/ACPI/Parser.cpp index 54ece1a94d..dae7504f5c 100644 --- a/Kernel/ACPI/Parser.cpp +++ b/Kernel/ACPI/Parser.cpp @@ -322,29 +322,6 @@ Parser::Parser(PhysicalAddress rsdp) locate_static_data(); } -static PhysicalAddress find_rsdp_in_ebda() -{ - auto ebda = map_ebda(); - for (auto* rsdp_str = ebda.base(); rsdp_str < ebda.end(); 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 ", (const char*)rsdp_str, strlen("RSD PTR "))) - return ebda.paddr_of(rsdp_str); - } - return {}; -} - -static PhysicalAddress find_rsdp_in_bios_area() -{ - auto bios = map_bios(); - for (auto* rsdp_str = bios.base(); rsdp_str < bios.end(); rsdp_str += 16) { - if (!strncmp("RSD PTR ", (const char*)rsdp_str, strlen("RSD PTR "))) - return bios.paddr_of(rsdp_str); - } - return {}; -} - static bool validate_table(const Structures::SDTHeader& v_header, size_t length) { u8 checksum = 0; @@ -356,13 +333,13 @@ static bool validate_table(const Structures::SDTHeader& v_header, size_t length) return false; } -PhysicalAddress StaticParsing::find_rsdp() +Optional<PhysicalAddress> StaticParsing::find_rsdp() { - klog() << "ACPI: Probing EBDA"; - auto rsdp = find_rsdp_in_ebda(); - if (!rsdp.is_null()) + StringView signature("RSD PTR "); + auto rsdp = map_ebda().find_chunk_starting_with(signature, 16); + if (rsdp.has_value()) return rsdp; - return find_rsdp_in_bios_area(); + return map_bios().find_chunk_starting_with(signature, 16); } PhysicalAddress StaticParsing::find_table(PhysicalAddress rsdp_address, const StringView& signature) diff --git a/Kernel/Interrupts/InterruptManagement.cpp b/Kernel/Interrupts/InterruptManagement.cpp index 445791a7d7..b5e4284fd0 100644 --- a/Kernel/Interrupts/InterruptManagement.cpp +++ b/Kernel/Interrupts/InterruptManagement.cpp @@ -129,9 +129,9 @@ PhysicalAddress InterruptManagement::search_for_madt() { dbg() << "Early access to ACPI tables for interrupt setup"; auto rsdp = ACPI::StaticParsing::find_rsdp(); - if (rsdp.is_null()) + if (!rsdp.has_value()) return {}; - return ACPI::StaticParsing::find_table(rsdp, "APIC"); + return ACPI::StaticParsing::find_table(rsdp.value(), "APIC"); } InterruptManagement::InterruptManagement() @@ -189,8 +189,10 @@ void InterruptManagement::switch_to_ioapic_mode() } APIC::init(); APIC::enable_bsp(); - MultiProcessorParser::initialize(); - locate_pci_interrupt_overrides(); + + if (auto mp_parser = MultiProcessorParser::autodetect()) { + m_pci_interrupt_overrides = mp_parser->get_pci_interrupt_redirections(); + } } void InterruptManagement::locate_apic_data() @@ -231,9 +233,4 @@ void InterruptManagement::locate_apic_data() } } -void InterruptManagement::locate_pci_interrupt_overrides() -{ - m_pci_interrupt_overrides = MultiProcessorParser::the().get_pci_interrupt_redirections(); -} - } diff --git a/Kernel/Interrupts/InterruptManagement.h b/Kernel/Interrupts/InterruptManagement.h index 71526e66e8..eb5edd2de6 100644 --- a/Kernel/Interrupts/InterruptManagement.h +++ b/Kernel/Interrupts/InterruptManagement.h @@ -88,7 +88,6 @@ private: InterruptManagement(); PhysicalAddress search_for_madt(); void locate_apic_data(); - void locate_pci_interrupt_overrides(); bool m_smp_enabled { false }; FixedArray<RefPtr<IRQController>> m_interrupt_controllers { 1 }; Vector<ISAInterruptOverrideMetadata> m_isa_interrupt_overrides; diff --git a/Kernel/VM/MappedROM.h b/Kernel/VM/MappedROM.h index 5eb37f57ce..9be57c2f45 100644 --- a/Kernel/VM/MappedROM.h +++ b/Kernel/VM/MappedROM.h @@ -39,6 +39,15 @@ struct MappedROM { size_t offset { 0 }; PhysicalAddress paddr; + Optional<PhysicalAddress> find_chunk_starting_with(StringView prefix, size_t chunk_size) const + { + for (auto* candidate = base(); candidate < end(); candidate += chunk_size) { + if (!__builtin_memcmp(prefix.characters_without_null_termination(), candidate, prefix.length())) + return paddr_of(candidate); + } + return {}; + } + PhysicalAddress paddr_of(const u8* ptr) const { return paddr.offset(ptr - this->base()); } }; |