Peripheral Component Interconnect express Bus (PCIe)
Overview
API Reference
- group pcie_host_interface
PCIe Host Interface.
Defines
-
PCIE_ID_IS_VALID(id)
-
PCIE_DT_ID(node_id)
Get the PCIe Vendor and Device ID for a node.
- Parameters:
node_id – DTS node identifier
- Returns:
The VID/DID combination as pcie_id_t
-
PCIE_DT_INST_ID(inst)
Get the PCIe Vendor and Device ID for a node.
This is equivalent to
PCIE_DT_ID(DT_DRV_INST(inst))
- Parameters:
inst – Devicetree instance number
- Returns:
The VID/DID combination as pcie_id_t
-
DEVICE_PCIE_DECLARE(node_id)
Declare a PCIe context variable for a DTS node.
Declares a PCIe context for a DTS node. This must be done before using the DEVICE_PCIE_INIT() macro for the same node.
- Parameters:
node_id – DTS node identifier
-
DEVICE_PCIE_INST_DECLARE(inst)
Declare a PCIe context variable for a DTS node.
This is equivalent to
DEVICE_PCIE_DECLARE(DT_DRV_INST(inst))
- Parameters:
inst – Devicetree instance number
-
DEVICE_PCIE_INIT(node_id, name)
Initialize a named struct member to point at a PCIe context.
Initialize PCIe-related information within a specific instance of a device config struct, using information from DTS. Using the macro requires having first created PCIe context struct using the DEVICE_PCIE_DECLARE() macro.
Example for an instance of a driver belonging to the “foo” subsystem
struct foo_config { struct pcie_dev *pcie; … };
DEVICE_PCIE_ID_DECLARE(DT_DRV_INST(…)); struct foo_config my_config = { DEVICE_PCIE_INIT(pcie, DT_DRV_INST(…)), … };
- Parameters:
node_id – DTS node identifier
name – Member name within config for the MMIO region
-
DEVICE_PCIE_INST_INIT(inst, name)
Initialize a named struct member to point at a PCIe context.
This is equivalent to
DEVICE_PCIE_INIT(DT_DRV_INST(inst), name)
- Parameters:
inst – Devicetree instance number
name – Name of the struct member (of type struct pcie_dev *)
-
PCIE_HOST_CONTROLLER(n)
Get the BDF for a given PCI host controller.
This macro is useful when the PCI host controller behind PCIE_BDF(0, 0, 0) indicates a multifunction device. In such a case each function of this endpoint is a potential host controller itself.
- Parameters:
n – Bus number
- Returns:
BDF value of the given host controller
-
PCIE_CONF_CAPPTR
-
PCIE_CONF_CAPPTR_FIRST(w)
-
PCIE_CONF_CAP_ID(w)
-
PCIE_CONF_CAP_NEXT(w)
-
PCIE_CONF_EXT_CAPPTR
-
PCIE_CONF_EXT_CAP_ID(w)
-
PCIE_CONF_EXT_CAP_VER(w)
-
PCIE_CONF_EXT_CAP_NEXT(w)
-
PCIE_CONF_ID
-
PCIE_CONF_CMDSTAT
-
PCIE_CONF_CMDSTAT_IO
-
PCIE_CONF_CMDSTAT_MEM
-
PCIE_CONF_CMDSTAT_MASTER
-
PCIE_CONF_CMDSTAT_INTERRUPT
-
PCIE_CONF_CMDSTAT_CAPS
-
PCIE_CONF_CLASSREV
-
PCIE_CONF_CLASSREV_CLASS(w)
-
PCIE_CONF_CLASSREV_SUBCLASS(w)
-
PCIE_CONF_CLASSREV_PROGIF(w)
-
PCIE_CONF_CLASSREV_REV(w)
-
PCIE_CONF_TYPE
-
PCIE_CONF_MULTIFUNCTION(w)
-
PCIE_CONF_TYPE_BRIDGE(w)
-
PCIE_CONF_TYPE_GET(w)
-
PCIE_CONF_TYPE_STANDARD
-
PCIE_CONF_TYPE_PCI_BRIDGE
-
PCIE_CONF_TYPE_CARDBUS_BRIDGE
-
PCIE_CONF_BAR0
-
PCIE_CONF_BAR1
-
PCIE_CONF_BAR2
-
PCIE_CONF_BAR3
-
PCIE_CONF_BAR4
-
PCIE_CONF_BAR5
-
PCIE_CONF_BAR_IO(w)
-
PCIE_CONF_BAR_MEM(w)
-
PCIE_CONF_BAR_64(w)
-
PCIE_CONF_BAR_ADDR(w)
-
PCIE_CONF_BAR_IO_ADDR(w)
-
PCIE_CONF_BAR_FLAGS(w)
-
PCIE_CONF_BAR_NONE
-
PCIE_CONF_BAR_INVAL
-
PCIE_CONF_BAR_INVAL64
-
PCIE_CONF_BAR_INVAL_FLAGS(w)
-
PCIE_BUS_NUMBER
-
PCIE_BUS_PRIMARY_NUMBER(w)
-
PCIE_BUS_SECONDARY_NUMBER(w)
-
PCIE_BUS_SUBORDINATE_NUMBER(w)
-
PCIE_SECONDARY_LATENCY_TIMER(w)
-
PCIE_BUS_NUMBER_VAL(prim, sec, sub, lat)
-
PCIE_IO_SEC_STATUS
-
PCIE_IO_BASE(w)
-
PCIE_IO_LIMIT(w)
-
PCIE_SEC_STATUS(w)
-
PCIE_IO_SEC_STATUS_VAL(iob, iol, sec_status)
-
PCIE_MEM_BASE_LIMIT
-
PCIE_MEM_BASE(w)
-
PCIE_MEM_LIMIT(w)
-
PCIE_MEM_BASE_LIMIT_VAL(memb, meml)
-
PCIE_PREFETCH_BASE_LIMIT
-
PCIE_PREFETCH_BASE(w)
-
PCIE_PREFETCH_LIMIT(w)
-
PCIE_PREFETCH_BASE_LIMIT_VAL(pmemb, pmeml)
-
PCIE_PREFETCH_BASE_UPPER
-
PCIE_PREFETCH_LIMIT_UPPER
-
PCIE_IO_BASE_LIMIT_UPPER
-
PCIE_IO_BASE_UPPER(w)
-
PCIE_IO_LIMIT_UPPER(w)
-
PCIE_IO_BASE_LIMIT_UPPER_VAL(iobu, iolu)
-
PCIE_CONF_INTR
-
PCIE_CONF_INTR_IRQ(w)
-
PCIE_CONF_INTR_IRQ_NONE
-
PCIE_MAX_BUS
-
PCIE_MAX_DEV
-
PCIE_MAX_FUNC
-
PCIE_IRQ_CONNECT(bdf_p, irq_p, priority_p, isr_p, isr_param_p, flags_p)
Initialize an interrupt handler for a PCIe endpoint IRQ.
This routine is only meant to be used by drivers using PCIe bus and having fixed or MSI based IRQ (so no runtime detection of the IRQ). In case of runtime detection see pcie_connect_dynamic_irq()
- Parameters:
bdf_p – PCIe endpoint BDF
irq_p – IRQ line number.
priority_p – Interrupt priority.
isr_p – Address of interrupt service routine.
isr_param_p – Parameter passed to interrupt service routine.
flags_p – Architecture-specific IRQ configuration flags..
Typedefs
-
typedef uint32_t pcie_bdf_t
A unique PCI(e) endpoint (bus, device, function).
A PCI(e) endpoint is uniquely identified topologically using a (bus, device, function) tuple. The internal structure is documented in include/dt-bindings/pcie/pcie.h: see PCIE_BDF() and friends, since these tuples are referenced from devicetree.
-
typedef uint32_t pcie_id_t
A unique PCI(e) identifier (vendor ID, device ID).
The PCIE_CONF_ID register for each endpoint is a (vendor ID, device ID) pair, which is meant to tell the system what the PCI(e) endpoint is. Again, look to PCIE_ID_* macros in include/dt-bindings/pcie/pcie.h for more.
-
typedef bool (*pcie_scan_cb_t)(pcie_bdf_t bdf, pcie_id_t id, void *cb_data)
Callback type used for scanning for PCI endpoints.
- Param bdf:
BDF value for a found endpoint.
- Param id:
Vendor & Device ID for the found endpoint.
- Param cb_data:
Custom, use case specific data.
- Return:
true to continue scanning, false to stop scanning.
Enums
Functions
-
pcie_bdf_t pcie_bdf_lookup(pcie_id_t id)
Look up the BDF based on PCI(e) vendor & device ID.
This function is used to look up the BDF for a device given its vendor and device ID.
- Deprecated:
See also
- Parameters:
id – PCI(e) vendor & device ID encoded using PCIE_ID()
- Returns:
The BDF for the device, or PCIE_BDF_NONE if it was not found
-
uint32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg)
Read a 32-bit word from an endpoint’s configuration space.
This function is exported by the arch/SoC/board code.
- Parameters:
bdf – PCI(e) endpoint
reg – the configuration word index (not address)
- Returns:
the word read (0xFFFFFFFFU if nonexistent endpoint or word)
-
void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, uint32_t data)
Write a 32-bit word to an endpoint’s configuration space.
This function is exported by the arch/SoC/board code.
- Parameters:
bdf – PCI(e) endpoint
reg – the configuration word index (not address)
data – the value to write
-
int pcie_scan(const struct pcie_scan_opt *opt)
Scan for PCIe devices.
Scan the PCI bus (or busses) for available endpoints.
- Parameters:
opt – Options determining how to perform the scan.
- Returns:
0 on success, negative POSIX error number on failure.
-
bool pcie_probe(pcie_bdf_t bdf, pcie_id_t id)
Probe for the presence of a PCI(e) endpoint.
- Deprecated:
See also
- Parameters:
bdf – the endpoint to probe
id – the endpoint ID to expect, or PCIE_ID_NONE for “any device”
- Returns:
true if the device is present, false otherwise
-
bool pcie_get_mbar(pcie_bdf_t bdf, unsigned int bar_index, struct pcie_bar *mbar)
Get the MBAR at a specific BAR index.
- Parameters:
bdf – the PCI(e) endpoint
bar_index – 0-based BAR index
mbar – Pointer to struct pcie_bar
- Returns:
true if the mbar was found and is valid, false otherwise
-
bool pcie_probe_mbar(pcie_bdf_t bdf, unsigned int index, struct pcie_bar *mbar)
Probe the nth MMIO address assigned to an endpoint.
A PCI(e) endpoint has 0 or more memory-mapped regions. This function allows the caller to enumerate them by calling with index=0..n. Value of n has to be below 6, as there is a maximum of 6 BARs. The indices are order-preserving with respect to the endpoint BARs: e.g., index 0 will return the lowest-numbered memory BAR on the endpoint.
- Parameters:
bdf – the PCI(e) endpoint
index – (0-based) index
mbar – Pointer to struct pcie_bar
- Returns:
true if the mbar was found and is valid, false otherwise
-
bool pcie_get_iobar(pcie_bdf_t bdf, unsigned int bar_index, struct pcie_bar *iobar)
Get the I/O BAR at a specific BAR index.
- Parameters:
bdf – the PCI(e) endpoint
bar_index – 0-based BAR index
iobar – Pointer to struct pcie_bar
- Returns:
true if the I/O BAR was found and is valid, false otherwise
-
bool pcie_probe_iobar(pcie_bdf_t bdf, unsigned int index, struct pcie_bar *iobar)
Probe the nth I/O BAR address assigned to an endpoint.
A PCI(e) endpoint has 0 or more I/O regions. This function allows the caller to enumerate them by calling with index=0..n. Value of n has to be below 6, as there is a maximum of 6 BARs. The indices are order-preserving with respect to the endpoint BARs: e.g., index 0 will return the lowest-numbered I/O BAR on the endpoint.
- Parameters:
bdf – the PCI(e) endpoint
index – (0-based) index
iobar – Pointer to struct pcie_bar
- Returns:
true if the I/O BAR was found and is valid, false otherwise
-
void pcie_set_cmd(pcie_bdf_t bdf, uint32_t bits, bool on)
Set or reset bits in the endpoint command/status register.
- Parameters:
bdf – the PCI(e) endpoint
bits – the powerset of bits of interest
on – use true to set bits, false to reset them
-
unsigned int pcie_alloc_irq(pcie_bdf_t bdf)
Allocate an IRQ for an endpoint.
This function first checks the IRQ register and if it contains a valid value this is returned. If the register does not contain a valid value allocation of a new one is attempted. Such function is only exposed if CONFIG_PCIE_CONTROLLER is unset. It is thus available where architecture tied dynamic IRQ allocation for PCIe device makes sense.
- Parameters:
bdf – the PCI(e) endpoint
- Returns:
the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if allocation failed.
-
unsigned int pcie_get_irq(pcie_bdf_t bdf)
Return the IRQ assigned by the firmware/board to an endpoint.
- Parameters:
bdf – the PCI(e) endpoint
- Returns:
the IRQ number, or PCIE_CONF_INTR_IRQ_NONE if unknown.
-
void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq)
Enable the PCI(e) endpoint to generate the specified IRQ.
If MSI is enabled and the endpoint supports it, the endpoint will be configured to generate the specified IRQ via MSI. Otherwise, it is assumed that the IRQ has been routed by the boot firmware to the specified IRQ, and the IRQ is enabled (at the I/O APIC, or wherever appropriate).
- Parameters:
bdf – the PCI(e) endpoint
irq – the IRQ to generate
-
uint32_t pcie_get_cap(pcie_bdf_t bdf, uint32_t cap_id)
Find a PCI(e) capability in an endpoint’s configuration space.
- Parameters:
bdf – the PCI endpoint to examine
cap_id – the capability ID of interest
- Returns:
the index of the configuration word, or 0 if no capability.
-
uint32_t pcie_get_ext_cap(pcie_bdf_t bdf, uint32_t cap_id)
Find an Extended PCI(e) capability in an endpoint’s configuration space.
- Parameters:
bdf – the PCI endpoint to examine
cap_id – the capability ID of interest
- Returns:
the index of the configuration word, or 0 if no capability.
-
bool pcie_connect_dynamic_irq(pcie_bdf_t bdf, unsigned int irq, unsigned int priority, void (*routine)(const void *parameter), const void *parameter, uint32_t flags)
Dynamically connect a PCIe endpoint IRQ to an ISR handler.
- Parameters:
bdf – the PCI endpoint to examine
irq – the IRQ to connect (see pcie_alloc_irq())
priority – priority of the IRQ
routine – the ISR handler to connect to the IRQ
parameter – the parameter to provide to the handler
flags – IRQ connection flags
- Returns:
true if connected, false otherwise
-
struct pcie_dev
- #include <pcie.h>
-
struct pcie_bar
- #include <pcie.h>
-
PCIE_ID_IS_VALID(id)