PCI Over Again
Posted: Sat Jun 07, 2008 11:17 am
Hi!
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:
So the operation BAR = BAR & 0xFFFFFFFC zeroes out two lowest bits of BAR. Hex "C" stands for "1100", right? So there are 2 flags. Ok, I know the LSB indicates if it's a memory region or I/O space area, but what does the other flag stand for?
Let's see further...
So, 64-bit Memory? How come? It can exist only on x86-64 platform, right? I must admit this piece of code is a little difficult for me to understand, so please tell me what do the bits stand for, without shift and multiple AND operations.
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:
which makes me sure Bridges have a 1 in Headertype. So my question is: how exactly should one interpret Headertype? Are these the only possible values for Headertype? What should I do if come across a CARDBUS?
Once again, sorry for boring questions. I'll appreciate any information on that. Good links are more than welcome. CmpXchg
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