pci enumeration
pci enumeration
Hey, can somebody show me some resource on how pci enumeration is done? Thanx in advance.
This might be a silly question, if so, this does not mean Im silly, but I am young...
This might be a silly question, if so, this does not mean Im silly, but I am young...
Re:pci enumeration
for each bus (bios32 installation check b101), loop for 255 times (5 bits device, 3 bits function).
read the configuration space for each (bios32 funcion b108).
if the first two bytes come back as 0xff, 0xff, no device/function exists at that place...
read the configuration space for each (bios32 funcion b108).
if the first two bytes come back as 0xff, 0xff, no device/function exists at that place...
-- Stu --
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:pci enumeration
there are a few information about PCI enum on the FAQ (search for "pci" )
The enumeration is performed by polling each possible device on each possible bus. You poll one device by reading it's VENDOR and PRODUCT ids. nonexistent devices will not respond and you'll get a "floating" bus state (0xffff).
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).
Note that devices are not assigned contiguous ids, so if you have no device #2 on bus #0, that doesn't mean you can't have a device #4 or #15 !
The enumeration is performed by polling each possible device on each possible bus. You poll one device by reading it's VENDOR and PRODUCT ids. nonexistent devices will not respond and you'll get a "floating" bus state (0xffff).
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).
Note that devices are not assigned contiguous ids, so if you have no device #2 on bus #0, that doesn't mean you can't have a device #4 or #15 !
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:pci enumeration
You can also wish to check whyme's pci enumerator module for the latest Clicker 0.8.20
Re:pci enumeration
for devices, ok, what about "bus"es?Note that devices are not assigned contiguous ids, so if you have no device #2 on bus #0, that doesn't mean you can't have a device #4 or #15 !
i enumerated my pci hardware and i have only 2 buses, bus 0 is the pci bus and it has all my pci devices ( pci2pci pci2isa bridges, usb and several cards etc ) but bus 1 has only one device and it is my graphics card, so i decided this is AGP bus. there exists no further cards on any further buses.
( i hope you know or at least understand what i mean and that, "bus" and "device" are different )
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:pci enumeration
this is quite typical from a PC. I got the same here, and if i get a look at
Bus 0, device 1, function 0:
PCI bridge: VIA Technologies, Inc. VT82C598/694x [Apollo MVP3/Pro133x AGP] (rev 0).
Master Capable. No bursts. Min Gnt=8.
hexdump -C /proc/bus/pci/00/01.0
00000000 06 11 98 85 07 00 30 22 00 00 04 06 00 00 HT:01 00
00000010 00 00 00 00 00 00 00 00 PPB:00 PSB:01 SUB:01 00 e0 d0 00 00
00000020 00 f7 e0 f8 f0 f9 f0 fb 00 00 00 00 00 00 00 00
00000030 00 00 00 00 80 00 00 00 00 00 00 00 00 00 08 00
We can see that the header type is '01', so we have a PCI-to-PCI bridge header. In that case, we have other registers defined:So we can tell that the bridge is connecting primary=0 to secondary=1 and that the highest bus behind the bridge is bus 1.* Header type 1 (PCI-to-PCI bridges) */
#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
Since this is the only bridge on bus 0, only busses 0 and 1 needs to be scanned on my system
Re:pci enumeration
For example code on pci enumeration I highly recommend
Chis Gieses PCI - detection utility, PCI-32
Chris Giese <[email protected]>, http://www.execpc.com/~geezer
The code in this uses two types of enumeration and shows how to walk the bus, as well as having a couple of utility functions that can be expanded for your own use. At the moment PCI-32 only prints up device, vendor, class and subclass numbers. Of course once you've detected a PCI card, you need to know the register layout to program it.
I'll be posting an expanded version of this utility that supplies info on PCI card 'capabilities' ie power management, vendor info, AGP capabilities by the weekend in another thread (the AGP one running around here somewhere).
Keep safe.
Chis Gieses PCI - detection utility, PCI-32
Chris Giese <[email protected]>, http://www.execpc.com/~geezer
The code in this uses two types of enumeration and shows how to walk the bus, as well as having a couple of utility functions that can be expanded for your own use. At the moment PCI-32 only prints up device, vendor, class and subclass numbers. Of course once you've detected a PCI card, you need to know the register layout to program it.
I'll be posting an expanded version of this utility that supplies info on PCI card 'capabilities' ie power management, vendor info, AGP capabilities by the weekend in another thread (the AGP one running around here somewhere).
Keep safe.
Re:pci enumeration
I still think this is the best for dumping pci info ive found sofar
http://members.datafast.net.au/dft0802/downloads.htm
plus ive known merlin for years and hung out on his BBS in the pre internet days.
http://members.datafast.net.au/dft0802/downloads.htm
plus ive known merlin for years and hung out on his BBS in the pre internet days.
-- Stu --
Re:pci enumeration
Hey, I hope it makes sense to ask this question here. Suppose I can do pci enumeration but how can I be sure that there is no device attached to some other bus like isa bus? Is there a way to detect devices on isa bus too?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:pci enumeration
If these are PnP cards, you may try to ask the PnP BIOS or the SMBios. Otherwise, you need to rely on the user's knowledge of his (her) PC. E.g. if a legacy Sound Blaster Pro card is installed, the only way to check is there is to apply the card reset sequence on the base port (and you can know by the docs that possible base ports are 0x200, 0x220, 0x240, 0x260) and then check if the status gives something consistent.Ozgunh82 wrote: Hey, I hope it makes sense to ask this question here. Suppose I can do pci enumeration but how can I be sure that there is no device attached to some other bus like isa bus? Is there a way to detect devices on isa bus too?
Re:pci enumeration
Ok, thanks for the replies Pype and other guys... Now another thing Ive noticed, windows says that my nvidia graphics card on pci bus is assigned irq 16, does windows do that or pnp compatible bios set this on boot time? Also how can it get an irq number bigger than 15?
Re:pci enumeration
I'm no expert but IIRC to get IRQs higher than 15 the APIC has to be enabled (and the legacy 8259 mode disabled).
The BIOS starts up the computer in legacy mode. The operating system always reprograms the APIC from legacy 8259 mode to "native" mode (IIRC).
The BIOS starts up the computer in legacy mode. The operating system always reprograms the APIC from legacy 8259 mode to "native" mode (IIRC).
Re:pci enumeration
PCI 2.2+ supports Message Signalled Interrupts. This allows you to set up a block of interrupts for a video card. You can request up to 128 interrupts per card. Cards using MSI don't need an interrupt pin. These don't go through the usual interrupt hardware (APIC or otherwise).
Basically how it works is that when you receive an interrupt, the data from the I/O device might not be ready yet. So when you receive an interrupt, you have to do an I/O read from the device to force the host to update main memory with everything. If you start reading immediatley, you could have stinky data.
With an MSI card, you provide a memory location in an MSI table, instead of an interrupt being generated, the card writes something to the memory location. I'd expect this to be a 1 for interrupt, 0 for no interrupt, but MSI is implementation dependant.
Anyway, PCI writes have to be done in order, so when the memory address changes, you can be sure your data is OK.
More info in PCI spec 2.2+. I've never found any use for more than 16 hardware interrupts by the way.
Basically how it works is that when you receive an interrupt, the data from the I/O device might not be ready yet. So when you receive an interrupt, you have to do an I/O read from the device to force the host to update main memory with everything. If you start reading immediatley, you could have stinky data.
With an MSI card, you provide a memory location in an MSI table, instead of an interrupt being generated, the card writes something to the memory location. I'd expect this to be a 1 for interrupt, 0 for no interrupt, but MSI is implementation dependant.
Anyway, PCI writes have to be done in order, so when the memory address changes, you can be sure your data is OK.
More info in PCI spec 2.2+. I've never found any use for more than 16 hardware interrupts by the way.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:pci enumeration
well, i haven't heard of MSI so far ... that's neat to have a '1' written in main memory (which doesn't mean it's in cache either at the CPU, right ?)
but still if i'm waiting for a vertical retrace or for a packet to arrive, i think being interrupted is still what i need -- not having to poll a memory location.
Or is there a "generic pci interrupt" that will still arrive and i should check the various MSI locations to know what event occured ?
but still if i'm waiting for a vertical retrace or for a packet to arrive, i think being interrupted is still what i need -- not having to poll a memory location.
Or is there a "generic pci interrupt" that will still arrive and i should check the various MSI locations to know what event occured ?
Re:pci enumeration
Yup, no caching according to the spec - everything sent to or from the device is guaranteed to have arrived.
At the moment all PCI cards still require a hardwired interrupt line, so that's probably as generic as you can get, but I suppose that a card could provide a single MSI interrupt which would mean the same thing :"Oi! Attention Please!"
I thought that retracing etc. always had to be through software polling. I've seen very few video cards that support actual hardware interrupts for vertical or (even rarer) horizontal retracing. (Reg 3DAH, bit 3 if I remember my CGA regs. remember)
It's a pity IBM screwed up so badly when adding the second interrupt controller, guess graphics weren't important.
MSI was 'supposed' to be the cure for hardware interrupts since it wasn't PC/AT based. My thought was some time ago I could just set up a block of memory for all devices and then scan the block and jump to the installed handler. The IDT would simply exist for processor exceptions and nothing else.
With the lack of MSI cards and support via Intel chipsets though, the cost of coding and maintaining two separate interrupt subsystems isn't worth it at the moment.
The new PCI-X standard makes MSI mandatory (different slots etc - no hardware interrupt pins) It is after all a serial bus. Now all we need is a few PCI-X computers to play with.
At the moment all PCI cards still require a hardwired interrupt line, so that's probably as generic as you can get, but I suppose that a card could provide a single MSI interrupt which would mean the same thing :"Oi! Attention Please!"
I thought that retracing etc. always had to be through software polling. I've seen very few video cards that support actual hardware interrupts for vertical or (even rarer) horizontal retracing. (Reg 3DAH, bit 3 if I remember my CGA regs. remember)
It's a pity IBM screwed up so badly when adding the second interrupt controller, guess graphics weren't important.
MSI was 'supposed' to be the cure for hardware interrupts since it wasn't PC/AT based. My thought was some time ago I could just set up a block of memory for all devices and then scan the block and jump to the installed handler. The IDT would simply exist for processor exceptions and nothing else.
With the lack of MSI cards and support via Intel chipsets though, the cost of coding and maintaining two separate interrupt subsystems isn't worth it at the moment.
The new PCI-X standard makes MSI mandatory (different slots etc - no hardware interrupt pins) It is after all a serial bus. Now all we need is a few PCI-X computers to play with.