Page 1 of 1

PCI Bus Config

Posted: Fri Mar 06, 2009 7:29 am
by johnsa
Hey,

I've gone through the wiki and some other references i could find on PCI and have a few questions on it.

#1) Am I correct in assuming that there is no function that will return the full topology of the PCI devices in the system and that you basically have to probe it by starting at bus 0 - 255 and every slot/device (0-31) to see if a device is present there and if so what it's vendor and device id is. Then using that you'd know what driver/code to load for it.

#2) Is it correct to ignore BIOS32 and the PCI bios functions and just use the two i/o ports (config address and data)? - I didn't see any other BIOS32 functions that were particularly useful. Or is there other stuff in BIOS32 that is an absolute must have?

#3) The wiki article mentions how to read the config space registers, is the process the same to write to them, would one be able to write to them? (IE: command register).

#4) I presume PCI express is basically identical but there would be something additional in the config space to determine the speed? like x16 etc? Is there any additional work for PCIe ?

Thanks for any info!
John

Re: PCI Bus Config

Posted: Fri Mar 06, 2009 8:04 am
by JamesM
Hi,
johnsa wrote:Hey,

I've gone through the wiki and some other references i could find on PCI and have a few questions on it.

#1) Am I correct in assuming that there is no function that will return the full topology of the PCI devices in the system and that you basically have to probe it by starting at bus 0 - 255 and every slot/device (0-31) to see if a device is present there and if so what it's vendor and device id is. Then using that you'd know what driver/code to load for it.
Yes.
#2) Is it correct to ignore BIOS32 and the PCI bios functions and just use the two i/o ports (config address and data)? - I didn't see any other BIOS32 functions that were particularly useful. Or is there other stuff in BIOS32 that is an absolute must have?
No, those two registers are all you need.
#3) The wiki article mentions how to read the config space registers, is the process the same to write to them, would one be able to write to them? (IE: command register).
Yes. Some are read-only, most are read-write.
#4) I presume PCI express is basically identical but there would be something additional in the config space to determine the speed? like x16 etc? Is there any additional work for PCIe ?
Not certain about this - someone else will probably provide more info.

Thanks for any info!
John

Cheers,

James

Re: PCI Bus Config

Posted: Fri Mar 06, 2009 2:12 pm
by johnsa
Ok, been doing some looking up (wikipedia and http://www.pcisig.com/home)..
PCIe is available up to v2 currently and v3 is slated for release in 2010 at 16gig/sec transfer rate!
In any event from what i've found sofar there are 2 major differences. The PCIe config space is no longer 256 bytes but 4kb. You also cannot assume access via IO (ports as used for PCI).
You need to use MMIO and obtain the info about that from ACPI tables... still need to try and obtain more detail..

Re: PCI Bus Config

Posted: Fri Mar 06, 2009 2:39 pm
by johnsa
"PCI Express System Architecture" and other mindshare books look like they could come in handy...

Re: PCI Bus Config

Posted: Sat Mar 07, 2009 1:23 pm
by johnsa
Example Enhanced Configuration Access
Refer to Figure 20-9 on page 737. The following x86 code sample will cause the Root Complex to perform a read from Bus 4, Device 0, Function 0's Vendor ID configuration register. The example assumes that the 256MB-aligned base address of the Enhanced Configuration memory-mapped IO range is 50000000h:

mov ax,[50400000];memory-mapped IO read

Address bits 63:28 indicates the upper 36 bits of the 256MB-aligned base address of the overall Enhanced Configuration address range (in this case, 000000005h).

Address bits 27:20 select the target bus (in this case, 4).

Address bits 19:15 select the target device (in this case, 0) on the bus.

Address bits 14:12 select the target function (in this case, 0) within the device.

Address bits 11:2 selects the target dword (in this case, 0) within the selected function's configuration space.

Address bits 1:0 define the start byte location within the selected dword (in this case, 0).

The processor initiates a 2-byte memory read from memory locations 50400000h and 50400001h on its FSB. The request is latched by the Host/PCI bridge in the Root Complex. It decodes the address and determines that it is a configuration read request for the first two bytes in dword 0, function 0, device 0, bus 4. The remainder of the operation is the same as that described in the previous section.

... how to access the additional PCI express 4kb config space.
I guess the 256Mb aligned value part is what needs to be read from ACPI tables... anyone know where in the table/mem to scan for this address?

Re: PCI Bus Config

Posted: Sat Mar 07, 2009 11:27 pm
by Brendan
Hi,

For older systems there's actually 2 different PCI configuration space mechanisms (the normal mechanism and an obsolete mechanism), and if your OS supports older computers (80486, Pentium and Pentium Pro?) then you'll need to support the obsolete PCI configuration space mechanism. See an old version of the PCI specification (e.g. Section 3.7.4.2 in "PCI Local Bus Specification, Revision 2.1") for details on "Configuration Mechanism #2".
johnsa wrote:I guess the 256Mb aligned value part is what needs to be read from ACPI tables... anyone know where in the table/mem to scan for this address?
According to ACPI 3.0, there's a table with the signature "MCFG” that tells you the base address for each 256 MiB aligned area (there may be more than one PCI Express host controller, and therefore more than one area for memory mapped configuration space). This "MCFG” table is defined in "PCI Firmware Specification, Revision 3.0", which is unfortunately only available free of charge to members at http://pcisig.com.


Cheers,

Brendan

Re: PCI Bus Config

Posted: Sun Mar 08, 2009 7:04 am
by johnsa
Isn't that lovely... as usual... does anyone happen to know the format of the MCFG table and how to find it / interpret it? an would be willing to share this info without $3000 p/a subscription ? :)

Re: PCI Bus Config

Posted: Sun Mar 08, 2009 8:56 am
by Hyperdrive
johnsa wrote:Isn't that lovely... as usual... does anyone happen to know the format of the MCFG table and how to find it / interpret it? an would be willing to share this info without $3000 p/a subscription ? :)
You can look into the Linux sources and learn from it (note: I didn't say copy...).

For MCFG struct: include/acpi/actbl1.h -- or use ACPICA (as Linux does)
How to use the information: arch/x86/pci/[mmconfig_shared.c , mmconfig_32.c , mmconfig_64.c]

That helped me a lot and worked for me.

--TS

Re: PCI Bus Config

Posted: Sun Mar 08, 2009 9:25 am
by johnsa
Ahh.. many thanks for the pointer ;)

I found the table structures you mentioned.. I'll try to avoid seeing how they're used, I just wanted the format part that would've cost an insane amount of money to buy :) I'll refer to the ACPI spec doc and PCI System Architecture book to see if that deals with the usage in a thorough fashion.

For info:


ACPI_NAME_SIZE = 4
ACPI_OEM_ID_SIZE = 6
ACPI_OEM_TABLE_ID_SIZE = 8

;struct acpi_table_header {
; char signature[ACPI_NAME_SIZE]; /* ASCII table signature */
; u32 length; /* Length of table in bytes, including this header */
; u8 revision; /* ACPI Specification minor version # */
; u8 checksum; /* To make sum of entire table == 0 */
; char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */
;char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
;u32 oem_revision; /* OEM revision number */
;char asl_compiler_id[ACPI_NAME_SIZE]; /* ASCII ASL compiler vendor ID */
;u32 asl_compiler_revision; /* ASL compiler version */

;struct acpi_table_mcfg {
; struct acpi_table_header header; /* Common ACPI table header */
; u8 reserved[8];};
;
;/* Subtable */
;struct acpi_mcfg_allocation {
; u64 address; /* Base address, processor-relative */
; u16 pci_segment; /* PCI segment group number */
; u8 start_bus_number; /* Starting PCI Bus number */
; u8 end_bus_number; /* Final PCI Bus number */
;u32 reserved;};