reading PCI bars.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

reading PCI bars.

Post by naiksidd_85 »

hi,

firstly appologies as i am opening similar thread after long time (I should have tracked my previous thread).

I am able to enumerate the PCI bus by writing the address on port 0xcf8 and reading back from 0xcfc (took reference from osdev wiki ).
but I am not very sure as to how should I read the bars of the devices. I tried to read the bars but for all of the devices the bars read 0x0 can any one please throw some light on the issue and suggest me some way.
i have read about writing 0xffff on the bars and then reading back but am confused should i write to the address or some port.
Learning a lot these days THANKS to OSdev users
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: reading PCI bars.

Post by pcmattman »

i have read about writing 0xffff on the bars and then reading back but am confused should i write to the address or some port.
Try writing to the address and see what happens? If you're working in an emulator trial and error isn't going to hurt anything.
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

Re: reading PCI bars.

Post by naiksidd_85 »

I have tried it ,
it then returns 0xffffffff
Learning a lot these days THANKS to OSdev users
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: reading PCI bars.

Post by Brendan »

Hi,
naiksidd_85 wrote:I have tried it ,
it then returns 0xffffffff
If you are writing to the BAR in PCI configuration space, then bit 0 is meant to be hardwired (and won't change from 0 to 1), and 0xFFFFFFFF is an impossible combination (at least one of the lowest 3 bits must be clear, otherwise a reserved bit was set).

Unfortunately, my copy of the PCI specification doesn't say what a PCI device is meant to do if a BAR isn't used by the device. I'd assume the BAR would always return 0x00000000 or 0xFFFFFFFF regardless of what you write to it; but when the specifications don't say what should happen it's possible that device manufacturers do what-ever they feel like (including allowing all bits in the BAR to be written to).

In any case, check that you:
  • Make sure the "header type" field at offset 0x0E in PCI configuration space is 0. If the header type is 1 then it's a PCI to PCI bridge and only has 2 BARs (or one 64-bit BAR) and the rest of the data in PCI configuration space (after the BARs) is entirely different to a normal device. If the header type is 2 or more then there's no way to guess what the format of the device's PCI configuration space could be and you shouldn't touch it (although I'd be tempted to disable the device completely, by writing zero to the command register at offset 0x04 in PCI configuration space and display some sort of "WTF" error message).
  • Check if the device is in some sort of legacy mode. For example, for IDE/ATA controllers the "programming interface" field (the lowest 8-bits of the "class code" field at offset 0x09 in PCI configuration space) determines if the device supports "fixed mode" (where legacy I/O ports and IRQs are assumed and BARs are ignored) and/or "native mode" (where BARs and PCI IRQs are used and legacy stuff isn't); and if the device is currently using fixed mode or native mode. I'm not sure if there's any other types of PCI devices that have some sort of compatibility mode (I'd assume video cards do, and I know there's special crud in bridges to forward legacy VGA I/O port space and address space accesses to a video card, but I'm not sure of the details).
  • Disable I/O space and address space decoding in the command register (clear the lowest 2 bits in the command register at offset 0x04 in PCI configuration space) before you write to the BAR.
  • Write 0xFFFFFFFF to all BARs at the same time, because that makes it easier to handle 64-bit BARs (which are implemented as a pair of 32-bit BARs).
Also note that at least some of the devices in Bochs behave like ISA devices even though they may pretend to be on the PCI bus and have "pseudo PCI configuration spaces". IMHO this is mostly due to historical reasons (once upon a time Bochs was "ISA only"). An example of this is the PCI VGA card (which IIRC behaves like a PCI device without any expansion ROM, where a suitable VGA ROM appears by magic at 0x000C0000).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

Re: reading PCI bars.

Post by naiksidd_85 »

Sorry :oops: for the incomplete reply what i mean is, if I write 0xffffffff directly on the address I read 0xffffffff (which is but obvious).
but thanks for the reply its covering a lot of my future doubts i might have asked.
:D
Learning a lot these days THANKS to OSdev users
whiteOS
Member
Member
Posts: 29
Joined: Mon Oct 06, 2008 12:38 am

Re: reading PCI bars.

Post by whiteOS »

You haven't provided enough information to be helped. The PCI Controller is standard to a point but the device it describes is not, so just because you think there is a bar their it may not be so. What device are you reading and how do you know you have the one you want? What offset are you you addressing and how are you doing this? If you posted some code it might be easier to see where you went wrong.
Post Reply