Discussion:
accessing PCI configuration space
(too old to reply)
Maxim
2008-06-17 15:22:07 UTC
Permalink
Is there a way to access PCI(E) config space from user mode in Windows 2003+?
I.e., an equivalent of lspci command? Alternatively, does that information
get cached
somewhere (e.g. in the registry) by the OS?

I know a driver can read that information out, but the idea is to get access
to the
information without having to load a driver for a device.

The basic problem I am trying to solve is to determine the width of PCIE link
in the slot that my device is plugged into. The only information I can find
in the registry
is vendor/product PCI IDs and a few other things, but nothing close to a
full dump of
PCI config space.
Maxim
2008-06-17 15:29:10 UTC
Permalink
Btw, I'll also take an answer in a form of an existing freeware application
that does not install a driver :)
Doron Holan [MSFT]
2008-06-17 22:27:02 UTC
Permalink
starting in vista (and subsequent OS's) the current link speed is exposed
through a DEVPKEY (DEVPKEY_PciDevice_CurrentLinkSpeed in pciprop.h). before
that, you need to figure this out for yourself...


d
--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.
Post by Maxim
Btw, I'll also take an answer in a form of an existing freeware application
that does not install a driver :)
Maxim
2008-06-18 04:09:00 UTC
Permalink
bummer. oh well, thanks anyhow
Post by Doron Holan [MSFT]
starting in vista (and subsequent OS's) the current link speed is exposed
through a DEVPKEY (DEVPKEY_PciDevice_CurrentLinkSpeed in pciprop.h). before
that, you need to figure this out for yourself...
DaveH
2008-06-18 17:10:01 UTC
Permalink
Maxim, I'm not sure what Doron has suggested is what you're after as the link
speed (as defined by PCI Express spec) currently can only ever be 2.5Gb/s no
matter what the width of the link is.

If you really want to figure out the link width from user mode, you have to
query the Link Status Register (offset 12h of PCI Express Capability
Structure in PCI Config Space) which tells you the negotiated width of the
link (1x, 2x, etc.). To access PCI Config Space you have to use PCI host
bridge I/O ports namely CF8h and CFCh in a way described in PCI spec. In
kernel mode, you can use the deprecated HalGetBusDataByOffset (recommended
method is to create and send an IRP to PCI driver). In user mode, you could
use _inpd, _outpd on above ports in a similar way to HalGetBusDataByOffset
(check
http://www.reactos.org/generated/doxygen/d7/d7c/hal_2halx86_2generic_2pci_8c.html#a4 to know how).

That said, I don't think this would be a good approach as accesses to above
registers are not atomic and you might end up with some nasty side effects.

DaveH.
Post by Doron Holan [MSFT]
starting in vista (and subsequent OS's) the current link speed is exposed
through a DEVPKEY (DEVPKEY_PciDevice_CurrentLinkSpeed in pciprop.h). before
that, you need to figure this out for yourself...
d
--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.
Post by Maxim
Btw, I'll also take an answer in a form of an existing freeware application
that does not install a driver :)
luchnikov
2008-06-20 16:57:27 UTC
Permalink
This is Maxim, under a diff name... Do __inpb/__outpb really work in
user mode? I'd imagine that Windows does not allow user-level access
to hardware resources...
Post by DaveH
Maxim, I'm not sure what Doron has suggested is what you're after as the link
speed (as defined by PCI Express spec) currently can only ever be 2.5Gb/s no
matter what the width of the link is.
If you really want to figure out the link width from user mode, you have to
query the Link Status Register (offset 12h of PCI Express Capability
Structure in PCI Config Space) which tells you the negotiated width of the
link (1x, 2x, etc.). To access PCI Config Space you have to use PCI host
bridge I/O ports namely CF8h and CFCh in a way described in PCI spec. In
kernel mode, you can use the deprecated HalGetBusDataByOffset (recommended
method is to create and send an IRP to PCI driver). In user mode, you could
use _inpd, _outpd on above ports in a similar way to HalGetBusDataByOffset
(checkhttp://www.reactos.org/generated/doxygen/d7/d7c/hal_2halx86_2generic_...to know how).
That said, I don't think this would be a good approach as accesses to above
registers are not atomic and you might end up with some nasty side effects.
DaveH.
Don Burn
2008-06-20 17:08:05 UTC
Permalink
Using __inpb/__outpb is not allowed from user space in Windows. And to go
further a great way to create subtle bugs is to access the PCI Config Space
registers I know a firm being sued for doing this.
--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply
Post by luchnikov
This is Maxim, under a diff name... Do __inpb/__outpb really work in
user mode? I'd imagine that Windows does not allow user-level access
to hardware resources...
Post by DaveH
Maxim, I'm not sure what Doron has suggested is what you're after as the link
speed (as defined by PCI Express spec) currently can only ever be 2.5Gb/s no
matter what the width of the link is.
If you really want to figure out the link width from user mode, you have to
query the Link Status Register (offset 12h of PCI Express Capability
Structure in PCI Config Space) which tells you the negotiated width of the
link (1x, 2x, etc.). To access PCI Config Space you have to use PCI host
bridge I/O ports namely CF8h and CFCh in a way described in PCI spec. In
kernel mode, you can use the deprecated HalGetBusDataByOffset
(recommended
method is to create and send an IRP to PCI driver). In user mode, you could
use _inpd, _outpd on above ports in a similar way to
HalGetBusDataByOffset
(checkhttp://www.reactos.org/generated/doxygen/d7/d7c/hal_2halx86_2generic_...to
know how).
That said, I don't think this would be a good approach as accesses to above
registers are not atomic and you might end up with some nasty side effects.
DaveH.
luchnikov
2008-06-20 17:29:51 UTC
Permalink
By merely reading the space? I imagine they are writing it...

Anyway, looks like w/o a filter driver I am SOL. See my other post -
I tried getting PCI config data in STORPORT miniport driver via
StorPortGetBusData, without much luck.

Too bad there isn't some IOCTL you can send to the PCI bus driver to
get this data in Win2K3
Post by Don Burn
Using __inpb/__outpb is not allowed from user space in Windows. And to go
further a great way to create subtle bugs is to access the PCI Config Space
registers I know a firm being sued for doing this.
Don Burn
2008-06-20 17:51:56 UTC
Permalink
To read a specific location in PCI config space you have to write the
address to one register, then read from the other register. Since you have
no access to the lock doing this, you can get subtle bugs of the form:

System writes address reg
User writes address reg
Systems reads "data"
User reads "data"

Of course the system is not reading what it expects!
--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply
Post by luchnikov
By merely reading the space? I imagine they are writing it...
Anyway, looks like w/o a filter driver I am SOL. See my other post -
I tried getting PCI config data in STORPORT miniport driver via
StorPortGetBusData, without much luck.
Too bad there isn't some IOCTL you can send to the PCI bus driver to
get this data in Win2K3
Post by Don Burn
Using __inpb/__outpb is not allowed from user space in Windows. And to go
further a great way to create subtle bugs is to access the PCI Config Space
registers I know a firm being sued for doing this.
Calvin Guan
2008-06-17 23:33:57 UTC
Permalink
!pcitree
You don't need a driver, it's free. does that count?
Post by Maxim
Btw, I'll also take an answer in a form of an existing freeware application
that does not install a driver :)
Maxim
2008-06-18 13:52:00 UTC
Permalink
i don't think it does, because it does not provide a dump of PCIE config
space - only prints a few fields that are visible by other means (registry,
device property details, devcon find pci\*, etc). same goes for !devext xxx
PCI
Post by Calvin Guan
!pcitree
You don't need a driver, it's free. does that count?
Post by Maxim
Btw, I'll also take an answer in a form of an existing freeware application
that does not install a driver :)
Loading...