From 2272d932150f5858a8b80b1c5c35fdb8e953150a Mon Sep 17 00:00:00 2001 From: Liav A Date: Fri, 21 Jan 2022 17:06:39 +0200 Subject: [PATCH] Kernel/PCI: Unify disable checks under PCI::Access::is_disabled method To declare that we don't have a PCI bus in the system we do two things: 1. Probe IO ports before enabling access - In case we are using the QEMU ISA-PC machine type, IO probing results in floating bus condition (returning 0xFF values), thus, we know we don't have PCI bus on the system. 2. Allow the user to specify to not use the PCI bus at all in the kernel commandline. --- Kernel/Bus/PCI/Access.cpp | 6 ++++++ Kernel/Bus/PCI/Access.h | 1 + Kernel/Bus/PCI/Initializer.cpp | 10 ++++++++-- Kernel/Bus/PCI/Initializer.h | 3 +++ Kernel/init.cpp | 8 ++++---- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Kernel/Bus/PCI/Access.cpp b/Kernel/Bus/PCI/Access.cpp index bd4ee02a18..f33191106f 100644 --- a/Kernel/Bus/PCI/Access.cpp +++ b/Kernel/Bus/PCI/Access.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,11 @@ bool Access::is_initialized() return (s_access != nullptr); } +bool Access::is_disabled() +{ + return g_pci_access_is_disabled_from_commandline || g_pci_access_io_probe_failed; +} + UNMAP_AFTER_INIT bool Access::find_and_register_pci_host_bridges_from_acpi_mcfg_table(PhysicalAddress mcfg_table) { u32 length = 0; diff --git a/Kernel/Bus/PCI/Access.h b/Kernel/Bus/PCI/Access.h index f5c42c625c..8444b80c18 100644 --- a/Kernel/Bus/PCI/Access.h +++ b/Kernel/Bus/PCI/Access.h @@ -26,6 +26,7 @@ public: static Access& the(); static bool is_initialized(); + static bool is_disabled(); void write8_field(Address address, u32 field, u8 value); void write16_field(Address address, u32 field, u16 value); diff --git a/Kernel/Bus/PCI/Initializer.cpp b/Kernel/Bus/PCI/Initializer.cpp index 9d63ccc602..792e3fd8ad 100644 --- a/Kernel/Bus/PCI/Initializer.cpp +++ b/Kernel/Bus/PCI/Initializer.cpp @@ -17,6 +17,9 @@ namespace Kernel { namespace PCI { +READONLY_AFTER_INIT bool g_pci_access_io_probe_failed; +READONLY_AFTER_INIT bool g_pci_access_is_disabled_from_commandline; + static bool test_pci_io(); UNMAP_AFTER_INIT static PCIAccessLevel detect_optimal_access_type() @@ -28,7 +31,7 @@ UNMAP_AFTER_INIT static PCIAccessLevel detect_optimal_access_type() if (boot_determined != PCIAccessLevel::IOAddressing) return boot_determined; - if (test_pci_io()) + if (!g_pci_access_io_probe_failed) return PCIAccessLevel::IOAddressing; PANIC("No PCI bus access method detected!"); @@ -36,7 +39,10 @@ UNMAP_AFTER_INIT static PCIAccessLevel detect_optimal_access_type() UNMAP_AFTER_INIT void initialize() { - VERIFY(kernel_command_line().pci_access_level() != PCIAccessLevel::None); + g_pci_access_io_probe_failed = !test_pci_io(); + g_pci_access_is_disabled_from_commandline = kernel_command_line().is_pci_disabled(); + if (g_pci_access_is_disabled_from_commandline || g_pci_access_io_probe_failed) + return; switch (detect_optimal_access_type()) { case PCIAccessLevel::MemoryAddressing: { auto mcfg = ACPI::Parser::the()->find_table("MCFG"); diff --git a/Kernel/Bus/PCI/Initializer.h b/Kernel/Bus/PCI/Initializer.h index f9c01c4aad..6bf92efeb5 100644 --- a/Kernel/Bus/PCI/Initializer.h +++ b/Kernel/Bus/PCI/Initializer.h @@ -9,6 +9,9 @@ namespace Kernel { namespace PCI { +extern bool g_pci_access_io_probe_failed; +extern bool g_pci_access_is_disabled_from_commandline; + void initialize(); } diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 0bdc7e0b14..4c814cc9c2 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -299,8 +299,8 @@ void init_stage2(void*) } // Initialize the PCI Bus as early as possible, for early boot (PCI based) serial logging - if (!kernel_command_line().is_pci_disabled()) { - PCI::initialize(); + PCI::initialize(); + if (!PCI::Access::is_disabled()) { PCISerialDevice::detect(); } @@ -323,12 +323,12 @@ void init_stage2(void*) auto boot_profiling = kernel_command_line().is_boot_profiling_enabled(); - if (!kernel_command_line().is_pci_disabled()) { + if (!PCI::Access::is_disabled()) { USB::USBManagement::initialize(); } FirmwareSysFSDirectory::initialize(); - if (!kernel_command_line().is_pci_disabled()) { + if (!PCI::Access::is_disabled()) { VirtIO::detect(); }