From 9ab9e548f4510697d79ac3e3abb6c5465085570a Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 22 Dec 2020 04:03:20 +0000 Subject: [PATCH] Kernel/PCI: Create device configuration space mapping before creating a physical ID When enumerating the hardware using MMIO mode, it would attempt to create a physical ID first. To create a physical ID, it needs to retrieve the capabilities of the device. When enumerating the first device, there would be no device configuration space mappings. Access::get_capabilities_pointer calls PCI::read16, which in turn goes to MMIOAccess::read16_field. MMIOAccess::read16_field attempts to get a device configuration space and fully expects to get one. However, since this is the first device, there are none and it crashes with an m_has_value assertion failure. This fixes this by creating the device configuration space mapping before creating the physical ID. Testing with VMware Player 16.1.0. --- Kernel/PCI/MMIOAccess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kernel/PCI/MMIOAccess.cpp b/Kernel/PCI/MMIOAccess.cpp index 03b5b39dd9..fbb692eb00 100644 --- a/Kernel/PCI/MMIOAccess.cpp +++ b/Kernel/PCI/MMIOAccess.cpp @@ -122,8 +122,8 @@ MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg) InterruptDisabler disabler; enumerate_hardware([&](const Address& address, ID id) { - m_physical_ids.append({ address, id, get_capabilities(address) }); m_mapped_device_regions.append(make(address, m_segments.get(address.seg()).value())); + m_physical_ids.append({ address, id, get_capabilities(address) }); #ifdef PCI_DEBUG dbg() << "PCI: Mapping device @ pci (" << String::format("%w", address.seg()) << ":" << String::format("%b", address.bus()) << ":" << String::format("%b", address.slot()) << "." << String::format("%b", address.function()) << ")" << " " << m_mapped_device_regions.last().vaddr() << " " << m_mapped_device_regions.last().paddr();