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.
This commit is contained in:
Liav A 2022-01-21 17:06:39 +02:00 committed by Andreas Kling
parent f6e635938f
commit 2272d93215
Notes: sideshowbarker 2024-07-17 18:02:28 +09:00
5 changed files with 22 additions and 6 deletions

View file

@ -11,6 +11,7 @@
#include <Kernel/Bus/PCI/Access.h>
#include <Kernel/Bus/PCI/Controller/HostBridge.h>
#include <Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.h>
#include <Kernel/Bus/PCI/Initializer.h>
#include <Kernel/Debug.h>
#include <Kernel/Firmware/ACPI/Definitions.h>
#include <Kernel/Memory/MemoryManager.h>
@ -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;

View file

@ -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);

View file

@ -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");

View file

@ -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();
}

View file

@ -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();
}