Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion kernel/include/pci/pci_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions kernel/include/pci/pci_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
13 changes: 7 additions & 6 deletions kernel/src/pci/pci_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
#include <serial/serial.h>

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();
}
Expand Down Expand Up @@ -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;
Expand Down
30 changes: 20 additions & 10 deletions kernel/src/pci/pci_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
}
}

Expand Down Expand Up @@ -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);

Expand All @@ -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<pci_function_desc*>(function_virtual_base);
Expand All @@ -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<pci_device>(function_address, desc);
auto dev = kstl::make_shared<pci_device>(
bus, device, function,
function_address, desc);
m_devices.push_back(dev);
}

Expand Down