RE: How is PCI Configuration space mapped??

xxxxx@yahoo.com said:

I have another query . … where is the PCI configuration address
actually present . . i mean in the PCI slot/card/device or is it the
system memory which is used . . .

The PCI configuration space of a device from the perspective of a device
is not in *any* address space. There is a special signal, IDSEL, that
goes to each device and acts as an enable. The pin number (in a slot) of
IDSEL is the same for every card, but each slot gets a different IDSEL.

How the IDSEL for a slot is activated (in other words, how a “configuration
cycle is initiated”) varies based on the system board chip set, but almost
certainly the configuration spaces are *not* memory mapped or I/O mapped.
Instead, access to the configuration space typically goes through some other
magical (yet physically real) device for which the O/S has a driver.

Steve Williams “The woods are lovely, dark and deep.
xxxxx@icarus.com But I have promises to keep,
xxxxx@picturel.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep.”

*This message was transferred with a trial version of CommuniGate™ Pro*
Hello Stephen,

SW> xxxxx@yahoo.com said:

> I have another query . … where is the PCI configuration address
> actually present . . i mean in the PCI slot/card/device or is it the
> system memory which is used . . .

SW> How the IDSEL for a slot is activated (in other words, how a “configuration
SW> cycle is initiated”) varies based on the system board chip set, but almost
SW> certainly the configuration spaces are *not* memory mapped or I/O mapped.
SW> Instead, access to the configuration space typically goes through some other
SW> magical (yet physically real) device for which the O/S has a driver.

Yea, it’s true. But for IA32 there are two standart 32-bit ports in I/O space (0xCF8
and 0xCFC) through which perform reading/setting PCI device’s config space.

You should define type of your config space and find relative
addresses of intrested params, build config DWORD for 0xCF8 and
set/get data in 0xCFC

0xCF8 - command for config space
0xCFC - data from/to this param.

Example for finding device by its DevID and VendorID

ConfAdd = 0xCF8;
ConfData = 0xCFC;

for (i = 0; i < 0x1F; i++)
{
data = 0x80000000 + (i << 0xB) ; //formatting data for 0xCFC
//if need I can describe how

outprt(ConfAdd, data);
result = inprt(ConfData); //get data from DevID&VenID
//area of conf space

if (((result & 0x0000FFFF) == VendID) && ((result >> 16) == DevID))
{
printf(“Device %X was found %X\n”, DevID, i);
break;
}
}

Best regards,
Michael

Software Engineer mailto:xxxxx@set.vrn.ru
Scan Engineering Telecom www.xilinx.ru\set.htm
tel. (0732)512-199
fax (0732)727-101

>Yea, it’s true. But for IA32 there are two standart 32-bit ports in I/O

space (0xCF8
and 0xCFC) through which perform reading/setting PCI device’s config space.

You should define type of your config space and find relative
addresses of intrested params, build config DWORD for 0xCF8 and
set/get data in 0xCFC

It’s REALLY not that simple. There is no easy way for you to synchronize
YOUR access to these ports with the OS. When you stuff your desired config
space address into the address port, and then read/write on the data port,
the OS may have also simultaneously (on a different processor for example)
stuffed it’s desired address into the address port. The result is any
write’s you do MAY be going to some incorrect address on the incorrect
device, possible causing the device to malfunction. Any reads may be
totally wrong data from some other device.

The two major strategies I’ve heard for preventing this are:

  1. have your code hunt through the OS to find the address of the PCI config
    port spinlock

  2. assure that ALL processors are locked at a high IRQL running your code
    (via system threads and setting affinity)

The best strategy is to use the HAL functions for accessing PCI config
space (as the HAL function knows where the spinlock is). Under NT though,
these functions unfortunately have code to stop them from working on PCI
bridge devices (and maybe others).

There was a discussion about this on this list last year

  • Jan.

> I have another query . … where is the PCI configuration address actually

present . . i mean in the PCI slot/card/device or is it the system memory
which is used . . .

On the card, but accessed via standard ports of the onboard PCI controller.

Max

> 0xCF8 - command for config space

0xCFC - data from/to this param.

Example for finding device by its DevID and VendorID

ConfAdd = 0xCF8;
ConfData = 0xCFC;

for (i = 0; i < 0x1F; i++)
{
data = 0x80000000 + (i << 0xB) ; //formatting data for 0xCFC
//if need I can describe how

outprt(ConfAdd, data);
result = inprt(ConfData); //get data from DevID&VenID
//area of conf space

if (((result & 0x0000FFFF) == VendID) && ((result >> 16) == DevID))
{
printf(“Device %X was found %X\n”, DevID, i);
break;
}
}

Never use this in NT. Use HalGetBusData instead.
The PCI config space IO ports belongs to the HAL and it is a bad idea to
access them bypassing the HAL.

Max