summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/ACPI/Definitions.h6
-rw-r--r--Kernel/ACPI/Initialize.cpp6
-rw-r--r--Kernel/ACPI/MultiProcessorParser.cpp64
-rw-r--r--Kernel/ACPI/MultiProcessorParser.h14
-rw-r--r--Kernel/ACPI/Parser.cpp33
-rw-r--r--Kernel/Interrupts/InterruptManagement.cpp15
-rw-r--r--Kernel/Interrupts/InterruptManagement.h1
-rw-r--r--Kernel/VM/MappedROM.h9
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()); }
};