diff --git a/drivers/pcie/host/pcie.c b/drivers/pcie/host/pcie.c index 735541cb644..3bb576a40eb 100644 --- a/drivers/pcie/host/pcie.c +++ b/drivers/pcie/host/pcie.c @@ -229,3 +229,28 @@ void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq) #endif irq_enable(irq); } + +pcie_bdf_t pcie_bdf_lookup(pcie_id_t id) +{ + int bus, dev, func; + + for (bus = 0; bus <= PCIE_MAX_BUS; bus++) { + for (dev = 0; dev <= PCIE_MAX_DEV; dev++) { + for (func = 0; func <= PCIE_MAX_FUNC; func++) { + pcie_bdf_t bdf = PCIE_BDF(bus, dev, func); + uint32_t data; + + data = pcie_conf_read(bdf, PCIE_CONF_ID); + if (data == PCIE_ID_NONE) { + continue; + } + + if (data == id) { + return bdf; + } + } + } + } + + return PCIE_BDF_NONE; +} diff --git a/include/drivers/pcie/pcie.h b/include/drivers/pcie/pcie.h index dca897e6546..12b6cafe269 100644 --- a/include/drivers/pcie/pcie.h +++ b/include/drivers/pcie/pcie.h @@ -45,6 +45,17 @@ struct pcie_mbar { * These functions are arch-, board-, or SoC-specific. */ +/** + * @brief 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. + * + * @param id PCI(e) vendor & device ID encoded using PCIE_ID() + * @return The BDF for the device, or PCIE_BDF_NONE if it was not found + */ +extern pcie_bdf_t pcie_bdf_lookup(pcie_id_t id); + /** * @brief Read a 32-bit word from an endpoint's configuration space. * diff --git a/include/dt-bindings/pcie/pcie.h b/include/dt-bindings/pcie/pcie.h index 323da9e505a..2cf6698be53 100644 --- a/include/dt-bindings/pcie/pcie.h +++ b/include/dt-bindings/pcie/pcie.h @@ -35,6 +35,8 @@ #define PCIE_ID_NONE PCIE_ID(0xFFFF, 0xFFFF) +#define PCIE_BDF_NONE 0xFFFFFFFFU + /* * Since our internal representation of bus/device/function is arbitrary, * we choose the same format employed in the x86 Configuration Address Port: