From 37361821dd6409bc26fb892d3dde28edeacc9316 Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 29 Jun 2021 23:29:42 +0100 Subject: [PATCH] Kernel/PCI: Keep track of the currently mapped bus in MMIO mode There is a check in map_bus_region to make sure we don't pointlessly remap the bus region if the previous mapping was for the same bus. This is tracked with `m_mapped_bus`. However, nothing was actually updating `m_mapped_bus`, and it is initialised to 0. This means that if we start with a device on bus 0, the read in data will be valid. If we map say bus 1 then bus 0 again, the map for bus 0 will now be ignored and invalid data will be read in. Fixed by updating `m_mapped_bus` with the currently mapped bus. --- Kernel/PCI/MMIOAccess.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Kernel/PCI/MMIOAccess.cpp b/Kernel/PCI/MMIOAccess.cpp index 7474b06d89..55bd097d2a 100644 --- a/Kernel/PCI/MMIOAccess.cpp +++ b/Kernel/PCI/MMIOAccess.cpp @@ -88,8 +88,10 @@ UNMAP_AFTER_INIT MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg) // Note: we need to map this region before enumerating the hardware and adding // PCI::PhysicalID objects to the vector, because get_capabilities calls // PCI::read16 which will need this region to be mapped. - m_mapped_region = MM.allocate_kernel_region(determine_memory_mapped_bus_region(0, m_segments.get(0).value().get_start_bus()), MEMORY_RANGE_PER_BUS, "PCI ECAM", Region::Access::Read | Region::Access::Write); - dbgln("PCI ECAM Mapped region @ {}", m_mapped_region->vaddr()); + u8 start_bus = m_segments.get(0).value().get_start_bus(); + m_mapped_region = MM.allocate_kernel_region(determine_memory_mapped_bus_region(0, start_bus), MEMORY_RANGE_PER_BUS, "PCI ECAM", Region::Access::Read | Region::Access::Write); + m_mapped_bus = start_bus; + dbgln_if(PCI_DEBUG, "PCI: First PCI ECAM Mapped region for starting bus {} @ {} {}", start_bus, m_mapped_region->vaddr(), m_mapped_region->physical_page(0)->paddr()); enumerate_hardware([&](const Address& address, ID id) { m_physical_ids.append({ address, id, get_capabilities(address) }); @@ -101,6 +103,8 @@ void MMIOAccess::map_bus_region(u32 segment, u8 bus) if (m_mapped_bus == bus) return; m_mapped_region = MM.allocate_kernel_region(determine_memory_mapped_bus_region(segment, bus), MEMORY_RANGE_PER_BUS, "PCI ECAM", Region::Access::Read | Region::Access::Write); + m_mapped_bus = bus; + dbgln_if(PCI_DEBUG, "PCI: New PCI ECAM Mapped region for bus {} @ {} {}", bus, m_mapped_region->vaddr(), m_mapped_region->physical_page(0)->paddr()); } VirtualAddress MMIOAccess::get_device_configuration_space(Address address)