Master the fundamental concepts of device drivers & interrupts through this focused micro-challenge.
PCI devices expose 256 bytes (or 4 KB extended) of configuration registers per function. Access via I/O ports 0xCF8 (address) and 0xCFC (data) with enable bit set. For example, to read vendor/device ID of bus 0 dev 0 fn 0, write 0x80000000 to 0xCF8 and read 0xCFC.
nasmLoading…
After reading vendor/device IDs, read command register bit 1 and 2 to see if I/O and memory space are enabled. BAR0 low bits encode whether the region is I/O or memory and whether it is 32- or 64-bit. QEMU exposes host bridges on bus 0; plug-in devices appear on higher slot numbers. Config reads return 0xFFFFFFFF for nonexistent functions; mask with size probe writes to discover BAR lengths.
You will scan PCI buses and print vendor/device IDs using config port I/O. This exercise requires building the 0xCF8 address dword and interpreting the first config dword as vendor plus device identifiers.
Implement PCI configuration space access in C.
Requirements:
Test:
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
All starter code and reference implementations are available for your local setup.
View on Github