Missing PCI devices when enumerating
Posted: Sun Dec 22, 2024 2:45 am
I'm learning about PCI, starting with PCI enumeration. I have implemented a linux kernel module for this task, using the IO port approach:
The module log using dmesg:
But when I list all pci devices using lspci, I found out that my NVIDIA MX450 (bus 1) and Realtek PCIe Card Reader (bus 2) are missing in the kernel module log:
What am I missing here? Does linux have some kind of architecture specific code for PCI detection? Thanks in advance.
Code: Select all
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#define PCI_CONFIG_ADDRESS 0xCF8
#define PCI_CONFIG_DATA 0xCFC
#define MAX_BUS 256
#define MAX_DEVICE 32
#define MAX_FUNCTION 8
// Function to read a 32-bit value from the PCI configuration space using I/O ports
static u32 pci_config_read_u32(u8 bus, u8 device, u8 function, u8 offset) {
u32 address = (1 << 31) | (bus << 16) | (device << 11) | (function << 8) | (offset & ~3);
outl(address, PCI_CONFIG_ADDRESS); // Write address to 0xCF8
return inl(PCI_CONFIG_DATA); // Read data from 0xCFC
}
// Function to enumerate PCI devices using I/O ports
static void enumerate_pci_devices(void) {
int bus, device, function;
u32 vendor_device_id;
for (bus = 0; bus < MAX_BUS; bus++) {
for (device = 0; device < MAX_DEVICE; device++) {
for (function = 0; function < MAX_FUNCTION; function++) {
// Read the first 4 bytes of the PCI configuration space (Vendor ID + Device ID)
vendor_device_id = pci_config_read_u32(bus, device, function, 0);
// Extract Vendor ID and Device ID
u16 vendor_id = vendor_device_id & 0xFFFF;
u16 device_id = (vendor_device_id >> 16) & 0xFFFF;
// Check if a device is present (Vendor ID must not be 0xFFFF)
if (vendor_id == 0xFFFF)
continue;
pr_info("PCI Device Found: Bus %02x Device %02x Function %x Vendor ID: %04x Device ID: %04x\n",
bus, device, function, vendor_id, device_id);
}
}
}
}
static int __init pci_io_driver_init(void) {
pr_info("Initializing PCI I/O Port Driver\n");
// Enumerate all PCI devices using I/O ports
enumerate_pci_devices();
return 0;
}
static void __exit pci_io_driver_exit(void) {
pr_info("PCI I/O Port Driver Unloaded\n");
}
module_init(pci_io_driver_init);
module_exit(pci_io_driver_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PCI Enumeration Driver using I/O Ports");
MODULE_AUTHOR("Linux User");
Code: Select all
# dmesg
[ 5602.968050] Initializing PCI I/O Port Driver
[ 5602.968054] PCI Device Found: Bus 00 Device 00 Function 0 Vendor ID: 8086 Device ID: 9a14
[ 5602.968056] PCI Device Found: Bus 00 Device 00 Function 1 Vendor ID: 0002 Device ID: 0401
[ 5602.968068] PCI Device Found: Bus 00 Device 00 Function 3 Vendor ID: 0000 Device ID: 0000
[ 5602.968070] PCI Device Found: Bus 00 Device 00 Function 4 Vendor ID: 0000 Device ID: 0000
[ 5602.968073] PCI Device Found: Bus 00 Device 00 Function 5 Vendor ID: 0010 Device ID: 0000
[ 5602.968109] PCI Device Found: Bus 00 Device 02 Function 0 Vendor ID: 8086 Device ID: 9a49
[ 5602.968140] PCI Device Found: Bus 00 Device 04 Function 0 Vendor ID: 8086 Device ID: 9a03
[ 5602.968196] PCI Device Found: Bus 00 Device 06 Function 0 Vendor ID: 8086 Device ID: 9a09
[ 5602.968289] PCI Device Found: Bus 00 Device 0a Function 0 Vendor ID: 8086 Device ID: 9a0d
[ 5602.968363] PCI Device Found: Bus 00 Device 0d Function 0 Vendor ID: 8086 Device ID: 9a13
[ 5602.968411] PCI Device Found: Bus 00 Device 0e Function 0 Vendor ID: 8086 Device ID: 9a0b
[ 5602.968557] PCI Device Found: Bus 00 Device 14 Function 0 Vendor ID: 8086 Device ID: a0ed
[ 5602.968570] PCI Device Found: Bus 00 Device 14 Function 2 Vendor ID: 8086 Device ID: a0ef
[ 5602.968640] PCI Device Found: Bus 00 Device 14 Function 3 Vendor ID: 8086 Device ID: a0f0
[ 5602.968702] PCI Device Found: Bus 00 Device 15 Function 0 Vendor ID: 8086 Device ID: a0e8
[ 5602.968738] PCI Device Found: Bus 00 Device 16 Function 0 Vendor ID: 8086 Device ID: a0e0
[ 5602.968884] PCI Device Found: Bus 00 Device 1c Function 0 Vendor ID: 8086 Device ID: a0bd
[ 5602.968909] PCI Device Found: Bus 00 Device 1c Function 7 Vendor ID: 8086 Device ID: a0bf
[ 5602.968912] PCI Device Found: Bus 00 Device 1d Function 0 Vendor ID: 8086 Device ID: a0b0
[ 5602.968958] PCI Device Found: Bus 00 Device 1f Function 0 Vendor ID: 8086 Device ID: a082
[ 5602.968982] PCI Device Found: Bus 00 Device 1f Function 3 Vendor ID: 8086 Device ID: a0c8
[ 5602.968987] PCI Device Found: Bus 00 Device 1f Function 4 Vendor ID: 8086 Device ID: a0a3
[ 5602.968990] PCI Device Found: Bus 00 Device 1f Function 5 Vendor ID: 8086 Device ID: a0a4
[ 5602.970453] PCI Device Found: Bus 03 Device 00 Function 0 Vendor ID: 10ec Device ID: 8168
[ 5602.970687] PCI Device Found: Bus 04 Device 00 Function 0 Vendor ID: 1e0f Device ID: 0001
Code: Select all
# lspci -tv
-[0000:00]-+-00.0 Intel Corporation 11th Gen Core Processor Host Bridge/DRAM Registers
+-02.0 Intel Corporation TigerLake-LP GT2 [Iris Xe Graphics]
+-04.0 Intel Corporation TigerLake-LP Dynamic Tuning Processor Participant
+-06.0-[01]----00.0 NVIDIA Corporation TU117M [GeForce MX450]
+-0a.0 Intel Corporation Tigerlake Telemetry Aggregator Driver
+-0d.0 Intel Corporation Tiger Lake-LP Thunderbolt 4 USB Controller
+-0e.0 Intel Corporation Volume Management Device NVMe RAID Controller
+-14.0 Intel Corporation Tiger Lake-LP USB 3.2 Gen 2x1 xHCI Host Controller
+-14.2 Intel Corporation Tiger Lake-LP Shared SRAM
+-14.3 Intel Corporation Wi-Fi 6 AX201
+-15.0 Intel Corporation Tiger Lake-LP Serial IO I2C Controller #0
+-16.0 Intel Corporation Tiger Lake-LP Management Engine Interface
+-1c.0-[02]----00.0 Realtek Semiconductor Co., Ltd. RTS522A PCI Express Card Reader
+-1c.7-[03]----00.0 Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
+-1d.0-[04]----00.0 KIOXIA Corporation Device 0001
+-1f.0 Intel Corporation Tiger Lake-LP LPC Controller
+-1f.3 Intel Corporation Tiger Lake-LP Smart Sound Technology Audio Controller
+-1f.4 Intel Corporation Tiger Lake-LP SMBus Controller
\-1f.5 Intel Corporation Tiger Lake-LP SPI Controller