I know this topic springs up from time to time, but I failed to find an answer to the question I'm about to ask.
So I want to implement a proper PCI enumeration. In the topic PCI Configuration Registers Brendan gave an excellent reply on how to get size of a BAR (of the area it represents, to be exact). However, it's unclear to me what flags are there in a BAR and what they stand for.
Let me quote some of his code:
Code: Select all
// IO space
...
BAR = PCI_read_32(bus, device, function, BAR_offset);
BAR = BAR & 0xFFFFFFFC; // Clear flags
...
Let's see further...
Code: Select all
if ( (BAR & 1) == 0) {
// Memory
type = (BAR >> 1) & 0x03;
if( (type & 2) == 0) {
// 32 bit Memory
...
} else {
// 64 bit Memory
....
...
I'll be very thankful if you make this stuff clear for me.
Please excuse me for asking more than 1 question, but I'm afraid there's something else I'd want to ask.
So I'd love to know more about the "Header type" field in the config space. In the topic of pci enumeration I could read:
Quite a valuable piece. But doesn't (headertype & 0x7F) == 1) mean that headertype=1? Besides, in Linux sources there's following:Pype.Clicker wrote:Some devices can have multiple functions, which you can identify because their HeaderType byte has the 7th bit set (0x80). For those devices, you have to poll every function.
Some devices can be pci-to-pci bridge (they'll have a (headertype & 0x7F) == 1) In the case of such a bridge, there's a place in the header where you can read the amount of "subordinate" busses (and thus the highest bus to be scanned).
Code: Select all
PCI_HEADER_TYPE_NORMAL EQU 0
PCI_HEADER_TYPE_BRIDGE EQU 1
PCI_HEADER_TYPE_CARDBUS EQU 2
Once again, sorry for boring questions. I'll appreciate any information on that. Good links are more than welcome. CmpXchg