PCI Bus Config

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
johnsa
Member
Member
Posts: 296
Joined: Mon Oct 15, 2007 3:04 pm

PCI Bus Config

Post 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
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: PCI Bus Config

Post 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
johnsa
Member
Member
Posts: 296
Joined: Mon Oct 15, 2007 3:04 pm

Re: PCI Bus Config

Post 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..
johnsa
Member
Member
Posts: 296
Joined: Mon Oct 15, 2007 3:04 pm

Re: PCI Bus Config

Post by johnsa »

"PCI Express System Architecture" and other mindshare books look like they could come in handy...
johnsa
Member
Member
Posts: 296
Joined: Mon Oct 15, 2007 3:04 pm

Re: PCI Bus Config

Post 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?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: PCI Bus Config

Post 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
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.
johnsa
Member
Member
Posts: 296
Joined: Mon Oct 15, 2007 3:04 pm

Re: PCI Bus Config

Post 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 ? :)
Hyperdrive
Member
Member
Posts: 93
Joined: Mon Nov 24, 2008 9:13 am

Re: PCI Bus Config

Post 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
johnsa
Member
Member
Posts: 296
Joined: Mon Oct 15, 2007 3:04 pm

Re: PCI Bus Config

Post 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;};
Post Reply