From 6d87e26e0b547a2b1ff6172ce850ce4871cfbc30 Mon Sep 17 00:00:00 2001 From: msokalski Date: Thu, 30 Oct 2025 18:50:19 +0100 Subject: [PATCH] Fix bus/device/function --- kernel/include/pci/pci_device.h | 3 ++- kernel/include/pci/pci_manager.h | 4 ++-- kernel/src/pci/pci_device.cpp | 13 +++++++------ kernel/src/pci/pci_manager.cpp | 30 ++++++++++++++++++++---------- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/kernel/include/pci/pci_device.h b/kernel/include/pci/pci_device.h index 6a75d0bf..86bcc985 100644 --- a/kernel/include/pci/pci_device.h +++ b/kernel/include/pci/pci_device.h @@ -20,7 +20,8 @@ class pci_device { * * Initializes the PCI device with its configuration and address details. */ - pci_device(uint64_t function_address, pci_function_desc* desc); + pci_device(uint8_t bus, uint8_t device, uint8_t function, + uint64_t function_address, pci_function_desc* desc); /** * @brief Retrieves the vendor ID of the PCI device. diff --git a/kernel/include/pci/pci_manager.h b/kernel/include/pci/pci_manager.h index 195dfef6..52588989 100644 --- a/kernel/include/pci/pci_manager.h +++ b/kernel/include/pci/pci_manager.h @@ -133,14 +133,14 @@ class pci_manager { * @param bus_addr Address of the PCI bus containing the device. * @param device Device number to enumerate. */ - void _enumerate_device(uint64_t bus_addr, uint8_t device); + void _enumerate_device(uint64_t segment_base_addr, uint8_t bus, uint8_t device); /** * @brief Enumerates a specific PCI function on a device. * @param device_addr Address of the PCI device containing the function. * @param function Function number to enumerate. */ - void _enumerate_function(uint64_t device_addr, uint8_t function); + void _enumerate_function(uint64_t segment_base_addr, uint8_t bus, uint8_t device, uint8_t function); }; } // namespace pci diff --git a/kernel/src/pci/pci_device.cpp b/kernel/src/pci/pci_device.cpp index 081a7d23..26541529 100644 --- a/kernel/src/pci/pci_device.cpp +++ b/kernel/src/pci/pci_device.cpp @@ -6,13 +6,14 @@ #include namespace pci { -pci_device::pci_device(uint64_t function_address, pci_function_desc* desc) +pci_device::pci_device(uint8_t bus, uint8_t device, uint8_t function, + uint64_t function_address, pci_function_desc* desc) : m_function_address(function_address), m_desc(desc), m_bars() { - m_bus = (uint8_t)((m_function_address >> 20) & 0xFF); - m_device = (uint8_t)((m_function_address >> 15) & 0x1F); - m_function = (uint8_t)((m_function_address >> 12) & 0x07); - + m_bus = bus; + m_device = device; + m_function = function; + _parse_bars(); _parse_capabilities(); } @@ -241,7 +242,7 @@ bool pci_device::setup_msi(uint8_t cpu, uint8_t vector, uint8_t edgetrigger, uin // Enable MSI in the message control field // This sets 'enable_bit' to 1 msi.enable_bit = 1; - + // Potentially set multiple_message_enable if you want multiple vectors // For now only support single vector. msi.multiple_message_enable = 0; diff --git a/kernel/src/pci/pci_manager.cpp b/kernel/src/pci/pci_manager.cpp index 50a6c670..df4076d2 100644 --- a/kernel/src/pci/pci_manager.cpp +++ b/kernel/src/pci/pci_manager.cpp @@ -9,8 +9,13 @@ pci_manager& pci_manager::get() { void pci_manager::init(acpi::acpi_sdt_header* mcfg_ptr) { _parse_mcfg(mcfg_ptr); - for (uint8_t bus = m_mcfg_segment->start_bus; bus < m_mcfg_segment->end_bus; bus++) { + uint8_t bus = m_mcfg_segment->start_bus; + while (1) + { _enumerate_bus(m_mcfg_segment->base_address, bus); + if (bus == m_mcfg_segment->end_bus) + break; + bus++; } } @@ -38,13 +43,14 @@ void pci_manager::_enumerate_bus(uint64_t segment_base_addr, uint8_t bus) { } for (uint64_t device = 0; device < 32; device++){ - _enumerate_device(bus_address, device); + _enumerate_device(segment_base_addr, bus, device); } } -void pci_manager::_enumerate_device(uint64_t bus_addr, uint8_t device) { - uint64_t device_offset = device << 15; - uint64_t device_address = bus_addr + device_offset; +void pci_manager::_enumerate_device(uint64_t segment_base_addr, uint8_t bus, uint8_t device) { + uint64_t bus_offset = (uint64_t)bus << 20; + uint64_t device_offset = (uint64_t)device << 15; + uint64_t device_address = segment_base_addr + bus_offset + device_offset; void* device_virtual_base = vmm::map_physical_page(device_address, DEFAULT_PRIV_PAGE_FLAGS); @@ -56,14 +62,16 @@ void pci_manager::_enumerate_device(uint64_t bus_addr, uint8_t device) { } for (uint64_t function = 0; function < 8; function++){ - _enumerate_function(device_address, function); + _enumerate_function(segment_base_addr, bus, device, function); } } -void pci_manager::_enumerate_function(uint64_t device_addr, uint8_t function) { - uint64_t function_offset = function << 12; +void pci_manager::_enumerate_function(uint64_t segment_base_addr, uint8_t bus, uint8_t device, uint8_t function) { + uint64_t bus_offset = (uint64_t)bus << 20; + uint64_t device_offset = (uint64_t)device << 15; + uint64_t function_offset = (uint64_t)function << 12; + uint64_t function_address = segment_base_addr + bus_offset + device_offset + function_offset; - uint64_t function_address = device_addr + function_offset; void* function_virtual_base = vmm::map_physical_page(function_address, DEFAULT_PRIV_PAGE_FLAGS); pci_function_desc* desc = reinterpret_cast(function_virtual_base); @@ -74,7 +82,9 @@ void pci_manager::_enumerate_function(uint64_t device_addr, uint8_t function) { } // Register and store the PCI device class instance - auto dev = kstl::make_shared(function_address, desc); + auto dev = kstl::make_shared( + bus, device, function, + function_address, desc); m_devices.push_back(dev); }