Subject: Re: PCI-Express question: standard offsets for PCI-e registers in PCI
To: None <>
From: Matthias Drochner <>
List: tech-kern
Date: 11/15/2005 13:18:20 said:
> a PCI config-space register, at offset 0xD8. bgereg.h currently uses
> symbolic name BGE_PCI_UNKNOWN1

PCI config addresses between 0x40 and 0x100 are usually used for
the linked list of capability structures. These are register
blocks marked by tags.
The general mechanism exists since PCI 2.2 (if the comment in
dev/pci/pcireg.h is correct); tag values are allocated as
new functionalities get into the standard.
See the PCI_CAP* definitions in pcireg.h, and the pci_get_capability()
function (which looks up a capability block by ID) in pci.c.

> the OpenSolaris header file bge_hw.h gives the names
> PCI_CONF_DEV_CTRL and PCI_CONF_DEV_STUS to config-space offsets 0xD8
> and 0xDA, respectively

This looks a lot like part of the "PCI Express Capability Structure",
chapter 7.8 in the spec. Its ID is 0x10 (PCI_CAP_PCIEXPRESS in pcireg.h).
At offset 8 there is a control/status register, much like the one in
the standard PCI header.

What the bge driver does:
	/* XXX: Magic Numbers */
	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_UNKNOWN1, 0xf5000)
-write ones into the lower 4 bits of the status register. This clears
 some sticky error bits.
-write "5" into the "max read request size" field of the control
 register, means 4096.

The BGE_PCI_UNKNOWN0 can probably be explained too. A complete
config space dump would help to find out which capability block
this address belongs to.

> these registers are now required for all PCI-e devices, and so we
> should either add them to sys/dev/pci/pcireg.h

The addresses are not fixed (just constant for a given hardware
appearently). If setting the "max read request size" is needed
by more than one driver, it might make sense to write a common
helper function which does this in a device independant way.
(like eg pci_powerstate() and pci_vpd* in pci.c)

best regards