diff --git a/Kernel/CommandLine.cpp b/Kernel/CommandLine.cpp index 6f8b88e74b..77eace91d4 100644 --- a/Kernel/CommandLine.cpp +++ b/Kernel/CommandLine.cpp @@ -111,6 +111,16 @@ UNMAP_AFTER_INIT bool CommandLine::is_smp_enabled() const return lookup("smp"sv).value_or("off"sv) == "on"sv; } +UNMAP_AFTER_INIT bool CommandLine::is_ioapic_enabled() const +{ + auto value = lookup("enable_ioapic"sv).value_or("on"sv); + if (value == "on"sv) + return true; + if (value == "off"sv) + return false; + PANIC("Unknown enable_ioapic setting: {}", value); +} + UNMAP_AFTER_INIT bool CommandLine::is_vmmouse_enabled() const { return lookup("vmmouse"sv).value_or("on"sv) == "on"sv; diff --git a/Kernel/CommandLine.h b/Kernel/CommandLine.h index 6006958fee..5b4f2c37b6 100644 --- a/Kernel/CommandLine.h +++ b/Kernel/CommandLine.h @@ -59,6 +59,7 @@ public: [[nodiscard]] bool is_boot_profiling_enabled() const; [[nodiscard]] bool is_ide_enabled() const; + [[nodiscard]] bool is_ioapic_enabled() const; [[nodiscard]] bool is_smp_enabled() const; [[nodiscard]] bool is_physical_networking_disabled() const; [[nodiscard]] bool is_vmmouse_enabled() const; diff --git a/Kernel/Interrupts/APIC.cpp b/Kernel/Interrupts/APIC.cpp index b7ad320c24..ca1a4dcd72 100644 --- a/Kernel/Interrupts/APIC.cpp +++ b/Kernel/Interrupts/APIC.cpp @@ -270,29 +270,32 @@ UNMAP_AFTER_INIT bool APIC::init_bsp() return false; } - auto madt = Memory::map_typed(madt_address.value()); - size_t entry_index = 0; - size_t entries_length = madt->h.length - sizeof(ACPI::Structures::MADT); - auto* madt_entry = madt->entries; - while (entries_length > 0) { - size_t entry_length = madt_entry->length; - if (madt_entry->type == (u8)ACPI::Structures::MADTEntryType::LocalAPIC) { - auto* plapic_entry = (const ACPI::Structures::MADTEntries::ProcessorLocalAPIC*)madt_entry; - dbgln_if(APIC_DEBUG, "APIC: AP found @ MADT entry {}, processor ID: {}, xAPIC ID: {}, flags: {:#08x}", entry_index, plapic_entry->acpi_processor_id, plapic_entry->apic_id, plapic_entry->flags); - m_processor_cnt++; - if ((plapic_entry->flags & 0x1) != 0) - m_processor_enabled_cnt++; - } else if (madt_entry->type == (u8)ACPI::Structures::MADTEntryType::Local_x2APIC) { - // Only used for APID IDs >= 255 - auto* plx2apic_entry = (const ACPI::Structures::MADTEntries::ProcessorLocalX2APIC*)madt_entry; - dbgln_if(APIC_DEBUG, "APIC: AP found @ MADT entry {}, processor ID: {}, x2APIC ID: {}, flags: {:#08x}", entry_index, plx2apic_entry->acpi_processor_id, plx2apic_entry->apic_id, plx2apic_entry->flags); - m_processor_cnt++; - if ((plx2apic_entry->flags & 0x1) != 0) - m_processor_enabled_cnt++; + if (kernel_command_line().is_smp_enabled()) { + auto madt = Memory::map_typed(madt_address.value()); + size_t entry_index = 0; + size_t entries_length = madt->h.length - sizeof(ACPI::Structures::MADT); + auto* madt_entry = madt->entries; + while (entries_length > 0) { + size_t entry_length = madt_entry->length; + if (madt_entry->type == (u8)ACPI::Structures::MADTEntryType::LocalAPIC) { + auto* plapic_entry = (const ACPI::Structures::MADTEntries::ProcessorLocalAPIC*)madt_entry; + dbgln_if(APIC_DEBUG, "APIC: AP found @ MADT entry {}, processor ID: {}, xAPIC ID: {}, flags: {:#08x}", entry_index, plapic_entry->acpi_processor_id, plapic_entry->apic_id, plapic_entry->flags); + m_processor_cnt++; + if ((plapic_entry->flags & 0x1) != 0) + m_processor_enabled_cnt++; + } else if (madt_entry->type == (u8)ACPI::Structures::MADTEntryType::Local_x2APIC) { + // Only used for APID IDs >= 255 + auto* plx2apic_entry = (const ACPI::Structures::MADTEntries::ProcessorLocalX2APIC*)madt_entry; + dbgln_if(APIC_DEBUG, "APIC: AP found @ MADT entry {}, processor ID: {}, x2APIC ID: {}, flags: {:#08x}", entry_index, plx2apic_entry->acpi_processor_id, plx2apic_entry->apic_id, plx2apic_entry->flags); + m_processor_cnt++; + if ((plx2apic_entry->flags & 0x1) != 0) + m_processor_enabled_cnt++; + } + madt_entry = (ACPI::Structures::MADTEntryHeader*)(VirtualAddress(madt_entry).offset(entry_length).get()); + entries_length -= entry_length; + entry_index++; } - madt_entry = (ACPI::Structures::MADTEntryHeader*)(VirtualAddress(madt_entry).offset(entry_length).get()); - entries_length -= entry_length; - entry_index++; + dbgln("APIC processors found: {}, enabled: {}", m_processor_cnt, m_processor_enabled_cnt); } if (m_processor_enabled_cnt < 1) @@ -300,8 +303,6 @@ UNMAP_AFTER_INIT bool APIC::init_bsp() if (m_processor_cnt < 1) m_processor_cnt = 1; - dbgln("APIC processors found: {}, enabled: {}", m_processor_cnt, m_processor_enabled_cnt); - enable(0); return true; } diff --git a/Kernel/Interrupts/InterruptManagement.cpp b/Kernel/Interrupts/InterruptManagement.cpp index 6120479ac2..c0f57531a8 100644 --- a/Kernel/Interrupts/InterruptManagement.cpp +++ b/Kernel/Interrupts/InterruptManagement.cpp @@ -41,10 +41,10 @@ UNMAP_AFTER_INIT void InterruptManagement::initialize() VERIFY(!InterruptManagement::initialized()); s_interrupt_management = new InterruptManagement(); - if (kernel_command_line().is_smp_enabled()) - InterruptManagement::the().switch_to_ioapic_mode(); - else + if (!kernel_command_line().is_ioapic_enabled() && !kernel_command_line().is_smp_enabled()) InterruptManagement::the().switch_to_pic_mode(); + else + InterruptManagement::the().switch_to_ioapic_mode(); } void InterruptManagement::enumerate_interrupt_handlers(Function callback) @@ -220,7 +220,7 @@ UNMAP_AFTER_INIT void InterruptManagement::locate_apic_data() dbgln("Interrupts: Overriding INT {:#x} with GSI {}, for bus {:#x}", interrupt_override_entry->source, global_system_interrupt, - flags); + interrupt_override_entry->bus); } madt_entry = (ACPI::Structures::MADTEntryHeader*)(VirtualAddress(madt_entry).offset(entry_length).get()); entries_length -= entry_length; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 953af7cd28..dbbb067054 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -271,7 +271,7 @@ void init_stage2(void*) WorkQueue::initialize(); - if (APIC::initialized() && APIC::the().enabled_processor_count() > 1) { + if (kernel_command_line().is_smp_enabled() && APIC::initialized() && APIC::the().enabled_processor_count() > 1) { // We can't start the APs until we have a scheduler up and running. // We need to be able to process ICI messages, otherwise another // core may send too many and end up deadlocking once the pool is