1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 15:47:42 +00:00

Kernel: Allow switching to IOAPIC mode even without enabling SMP

This small change allows to use the IOAPIC by default without to enable
SMP mode, which emulates Uni-Processor setup with IOAPIC instead of
using the PIC.

This opens the opportunity to utilize other types of interrupts like MSI
and MSI-X interrupts.
This commit is contained in:
Liav A 2021-11-28 17:38:10 +02:00 committed by Andreas Kling
parent f57900a41b
commit ac7953f945
5 changed files with 41 additions and 29 deletions

View file

@ -111,6 +111,16 @@ UNMAP_AFTER_INIT bool CommandLine::is_smp_enabled() const
return lookup("smp"sv).value_or("off"sv) == "on"sv; 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 UNMAP_AFTER_INIT bool CommandLine::is_vmmouse_enabled() const
{ {
return lookup("vmmouse"sv).value_or("on"sv) == "on"sv; return lookup("vmmouse"sv).value_or("on"sv) == "on"sv;

View file

@ -59,6 +59,7 @@ public:
[[nodiscard]] bool is_boot_profiling_enabled() const; [[nodiscard]] bool is_boot_profiling_enabled() const;
[[nodiscard]] bool is_ide_enabled() const; [[nodiscard]] bool is_ide_enabled() const;
[[nodiscard]] bool is_ioapic_enabled() const;
[[nodiscard]] bool is_smp_enabled() const; [[nodiscard]] bool is_smp_enabled() const;
[[nodiscard]] bool is_physical_networking_disabled() const; [[nodiscard]] bool is_physical_networking_disabled() const;
[[nodiscard]] bool is_vmmouse_enabled() const; [[nodiscard]] bool is_vmmouse_enabled() const;

View file

@ -270,6 +270,7 @@ UNMAP_AFTER_INIT bool APIC::init_bsp()
return false; return false;
} }
if (kernel_command_line().is_smp_enabled()) {
auto madt = Memory::map_typed<ACPI::Structures::MADT>(madt_address.value()); auto madt = Memory::map_typed<ACPI::Structures::MADT>(madt_address.value());
size_t entry_index = 0; size_t entry_index = 0;
size_t entries_length = madt->h.length - sizeof(ACPI::Structures::MADT); size_t entries_length = madt->h.length - sizeof(ACPI::Structures::MADT);
@ -294,14 +295,14 @@ UNMAP_AFTER_INIT bool APIC::init_bsp()
entries_length -= entry_length; entries_length -= entry_length;
entry_index++; entry_index++;
} }
dbgln("APIC processors found: {}, enabled: {}", m_processor_cnt, m_processor_enabled_cnt);
}
if (m_processor_enabled_cnt < 1) if (m_processor_enabled_cnt < 1)
m_processor_enabled_cnt = 1; m_processor_enabled_cnt = 1;
if (m_processor_cnt < 1) if (m_processor_cnt < 1)
m_processor_cnt = 1; m_processor_cnt = 1;
dbgln("APIC processors found: {}, enabled: {}", m_processor_cnt, m_processor_enabled_cnt);
enable(0); enable(0);
return true; return true;
} }

View file

@ -41,10 +41,10 @@ UNMAP_AFTER_INIT void InterruptManagement::initialize()
VERIFY(!InterruptManagement::initialized()); VERIFY(!InterruptManagement::initialized());
s_interrupt_management = new InterruptManagement(); s_interrupt_management = new InterruptManagement();
if (kernel_command_line().is_smp_enabled()) if (!kernel_command_line().is_ioapic_enabled() && !kernel_command_line().is_smp_enabled())
InterruptManagement::the().switch_to_ioapic_mode();
else
InterruptManagement::the().switch_to_pic_mode(); InterruptManagement::the().switch_to_pic_mode();
else
InterruptManagement::the().switch_to_ioapic_mode();
} }
void InterruptManagement::enumerate_interrupt_handlers(Function<void(GenericInterruptHandler&)> callback) void InterruptManagement::enumerate_interrupt_handlers(Function<void(GenericInterruptHandler&)> callback)
@ -220,7 +220,7 @@ UNMAP_AFTER_INIT void InterruptManagement::locate_apic_data()
dbgln("Interrupts: Overriding INT {:#x} with GSI {}, for bus {:#x}", dbgln("Interrupts: Overriding INT {:#x} with GSI {}, for bus {:#x}",
interrupt_override_entry->source, interrupt_override_entry->source,
global_system_interrupt, global_system_interrupt,
flags); interrupt_override_entry->bus);
} }
madt_entry = (ACPI::Structures::MADTEntryHeader*)(VirtualAddress(madt_entry).offset(entry_length).get()); madt_entry = (ACPI::Structures::MADTEntryHeader*)(VirtualAddress(madt_entry).offset(entry_length).get());
entries_length -= entry_length; entries_length -= entry_length;

View file

@ -271,7 +271,7 @@ void init_stage2(void*)
WorkQueue::initialize(); 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 can't start the APs until we have a scheduler up and running.
// We need to be able to process ICI messages, otherwise another // We need to be able to process ICI messages, otherwise another
// core may send too many and end up deadlocking once the pool is // core may send too many and end up deadlocking once the pool is