device/pciexp: add pcie_find_dsn()
Add pcie_find_dsn() to detect and match PCIe device serial number. In addition, vendor ID is matched when provided. Change-Id: I54b6dc42c8da47cd7b4447ab23a6a21562c7618 Signed-off-by: Jonathan Zhang <jonzhang@meta.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/54510 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Marc Jones <marc@marcjonesconsulting.com>
This commit is contained in:
parent
3dcafa8774
commit
1864f12fda
|
@ -93,6 +93,57 @@ unsigned int pciexp_find_ext_vendor_cap(const struct device *dev, unsigned int c
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a PCIe device with a given serial number, and a given VID if applicable
|
||||
*
|
||||
* @param serial The serial number of the device.
|
||||
* @param vid Vendor ID of the device, may be 0 if not applicable.
|
||||
* @param from Pointer to the device structure, used as a starting point in
|
||||
* the linked list of all_devices, which can be 0 to start at the
|
||||
* head of the list (i.e. all_devices).
|
||||
* @return Pointer to the device struct.
|
||||
*/
|
||||
struct device *pcie_find_dsn(const uint64_t serial, const uint16_t vid,
|
||||
struct device *from)
|
||||
{
|
||||
union dsn {
|
||||
struct {
|
||||
uint32_t dsn_low;
|
||||
uint32_t dsn_high;
|
||||
};
|
||||
uint64_t dsn;
|
||||
} dsn;
|
||||
unsigned int cap;
|
||||
uint16_t vendor_id;
|
||||
|
||||
if (!from)
|
||||
from = all_devices;
|
||||
else
|
||||
from = from->next;
|
||||
|
||||
while (from) {
|
||||
if (from->path.type == DEVICE_PATH_PCI) {
|
||||
cap = pciexp_find_extended_cap(from, PCI_EXT_CAP_ID_DSN, 0);
|
||||
/*
|
||||
* For PCIe device, find extended capability for serial number.
|
||||
* The capability header is 4 bytes, followed by lower 4 bytes
|
||||
* of serial number, then higher 4 byes of serial number.
|
||||
*/
|
||||
if (cap != 0) {
|
||||
dsn.dsn_low = pci_read_config32(from, cap + 4);
|
||||
dsn.dsn_high = pci_read_config32(from, cap + 8);
|
||||
vendor_id = pci_read_config16(from, PCI_VENDOR_ID);
|
||||
if ((dsn.dsn == serial) && (vid == 0 || vendor_id == vid))
|
||||
return from;
|
||||
}
|
||||
}
|
||||
|
||||
from = from->next;
|
||||
}
|
||||
|
||||
return from;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-train a PCIe link
|
||||
*/
|
||||
|
|
|
@ -44,6 +44,9 @@ static inline bool pciexp_is_downstream_port(int type)
|
|||
type == PCI_EXP_TYPE_PCIE_BRIDGE;
|
||||
}
|
||||
|
||||
struct device *pcie_find_dsn(const uint64_t serial, const uint16_t vid,
|
||||
struct device *from);
|
||||
|
||||
bool pciexp_get_ltr_max_latencies(struct device *dev, u16 *max_snoop, u16 *max_nosnoop);
|
||||
|
||||
#endif /* DEVICE_PCIEXP_H */
|
||||
|
|
Loading…
Reference in New Issue