PCI: Difference between revisions

Jump to navigation Jump to search
108 bytes added ,  29 days ago
m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
m (Bot: Replace deprecated source tag with syntaxhighlight)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
Line 41:
The following code segment illustrates the use of configuration mechanism #1 to read 16-bit fields from configuration space. Note that this segment, the outl(port, value) and inl(port) functions refer to the OUTL and INL Pentium assembly language instructions.
 
<sourcesyntaxhighlight lang="c">
uint16_t pciConfigReadWord(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) {
uint32_t address;
Line 60:
return tmp;
}
</syntaxhighlight>
</source>
 
When a configuration access attempts to select a device that does not exist, the host bridge will complete the access without error, dropping all data on writes and returning all ones on reads. The following code segment illustrates the read of a non-existent device.
Line 1,018:
For all 3 methods, you need to be able to check if a specific device on a specific bus is present and if it is multi-function or not. Pseudo-code might look like this:
 
<sourcesyntaxhighlight lang="c">
void checkDevice(uint8_t bus, uint8_t device) {
uint8_t function = 0;
Line 1,038:
void checkFunction(uint8_t bus, uint8_t device, uint8_t function) {
}
</syntaxhighlight>
</source>
 
Please note that if you don't check bit 7 of the header type and scan all functions, then some single-function devices will report details for "function 0" for every function.
Line 1,046:
For the brute force method, the remaining code is relatively simple. Pseudo-code might look like this:
 
<sourcesyntaxhighlight lang="c">
void checkAllBuses(void) {
uint16_t bus;
Line 1,057:
}
}
</syntaxhighlight>
</source>
 
For this method, there are 32 devices per bus and 256 buses, so you call "checkDevice()" 8192 times.
Line 1,065:
The first step for the recursive scan is to implement a function that scans one bus. Pseudo-code might look like this:
 
<sourcesyntaxhighlight lang="c">
void checkBus(uint8_t bus) {
uint8_t device;
Line 1,073:
}
}
</syntaxhighlight>
</source>
 
The next step is to add code in "checkFunction()" that detects if the function is a PCI to PCI bridge. If the device is a PCI to PCI bridge then you want to extract the "secondary bus number" from the bridge's configuration space and call "checkBus()" with the number of the bus on the other side of the bridge.
Line 1,098:
Pseudo-code might look like this:
 
<sourcesyntaxhighlight lang="c">
void checkAllBuses(void) {
uint8_t function;
Line 1,116:
}
}
</syntaxhighlight>
</source>
 
=== Recursive Scan With Bus Configuration ===
Line 1,206:
 
The message address/data is architecture specific. On x86(-64), it is as follows:
<sourcesyntaxhighlight lang="c">
uint64_t arch_msi_address(uint64_t *data, size_t vector, uint32_t processor, uint8_t edgetrigger, uint8_t deassert) {
*data = (vector & 0xFF) | (edgetrigger == 1 ? 0 : (1 << 15)) | (deassert == 1 ? 0 : (1 << 14));
return (0xFEE00000 | (processor << 12));
}
</syntaxhighlight>
</source>
MSI interrupts seem to be invariably edge triggered high.
 
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Navigation menu