From 767978ef01b27508193dd917b6ba0d6ea644b9d6 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Thu, 13 Jul 2023 17:31:07 +1000 Subject: [PATCH] lspci: Add support for the DOE Discovery options The PCIe 6 specification added support for the Data Object Exchange (DOE). When DOE is supported the Discovery Data Object Protocol must be implemented. The protocol allows a requester to obtain information about the other DOE protocols supported by the device. This patch adds support for querying the list of DOE Discovery Data Object Protocols supported by the device. This unfortunatley does require writing to the device, as we can't query the information without sending data objects to the device. Signed-off-by: Alistair Francis --- lib/header.h | 6 +++++ ls-ecaps.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/lib/header.h b/lib/header.h index e146a56b..32638d51 100644 --- a/lib/header.h +++ b/lib/header.h @@ -1393,6 +1393,12 @@ #define PCI_DOE_STS_INT 0x2 /* DOE Interrupt Status */ #define PCI_DOE_STS_ERROR 0x3 /* DOE Error */ #define PCI_DOE_STS_OBJECT_READY 0x80000000 /* Data Object Ready */ +#define PCI_DOE_WRITE_MAILBOX 0x10 /* DOE Write Data Mailbox Register */ +#define PCI_DOE_READ_MAILBOX 0x14 /* DOE Read Data Mailbox Register */ + +#define PCI_DOE_DISCOVERY_RESPONSE_VENDOR_ID 0xFFFF +#define PCI_DOE_DISCOVERY_RESPONSE_OBJ_PROTOCOL 0xFF0000 +#define PCI_DOE_DISCOVERY_RESPONSE_NEXT_INDX 0xFF000000 /* * The PCI interface treats multi-function devices as independent diff --git a/ls-ecaps.c b/ls-ecaps.c index 1bd1bf7b..f4493a5e 100644 --- a/ls-ecaps.c +++ b/ls-ecaps.c @@ -10,6 +10,7 @@ #include #include +#include #include "lspci.h" @@ -1374,6 +1375,77 @@ cap_rebar(struct device *d, int where, int virtual) } } +static void +doe_discovery(struct device *d, int where) +{ + u32 l, index = 0, dop; + + while (true) { + // header1 + // VendorID = 0x01 + // Data Object Type = 0x00 + pci_write_long(d->dev, where + PCI_DOE_WRITE_MAILBOX, 0x00000001); + + // header2 + // Length = 0x03 + pci_write_long(d->dev, where + PCI_DOE_WRITE_MAILBOX, 0x00000003); + + // dword0 + // DWORD = index + pci_write_long(d->dev, where + PCI_DOE_WRITE_MAILBOX, index); + + pci_write_long(d->dev, where + PCI_DOE_CTL, PCI_DOE_CTL_GO); + + while (pci_read_long(d->dev, where + PCI_DOE_STS) & PCI_DOE_STS_OBJECT_READY != 0x00) { + if ((pci_read_long(d->dev, where + PCI_DOE_STS) & PCI_DOE_STS_ERROR) == PCI_DOE_STS_ERROR) { + return; + } + } + + l = pci_read_long(d->dev, where + PCI_DOE_READ_MAILBOX); + pci_write_long(d->dev, where + PCI_DOE_READ_MAILBOX, 0xDEADBEEF); + if (l != 0x01) { + break; + } + + l = pci_read_long(d->dev, where + PCI_DOE_READ_MAILBOX); + pci_write_long(d->dev, where + PCI_DOE_READ_MAILBOX, 0xDEADBEEF); + if (l != 0x03) { + break; + } + + // DOE discovery response data object + l = pci_read_long(d->dev, where + PCI_DOE_READ_MAILBOX); + pci_write_long(d->dev, where + PCI_DOE_READ_MAILBOX, 0xDEADBEEF); + + if ((l & PCI_DOE_DISCOVERY_RESPONSE_VENDOR_ID) != 0x01) { + break; + } + + dop = (l & PCI_DOE_DISCOVERY_RESPONSE_OBJ_PROTOCOL) >> 16; + + switch (dop) { + case 0x00: + printf("\t\tDOE Protocol:\tDOE Discovery\n"); + break; + case 0x01: + printf("\t\tDOE Protocol:\tCMA/SPDM\n"); + break; + case 0x02: + printf("\t\tDOE Protocol:\tSecured CMA/SPDM\n"); + break; + default: + printf("\t\tDOE Protocol:\t0x%x\n", dop); + } + + if ((l & PCI_DOE_DISCOVERY_RESPONSE_NEXT_INDX) == 0x00) { + break; + } + + index = (l & PCI_DOE_DISCOVERY_RESPONSE_NEXT_INDX) >> 24; + } +} + static void cap_doe(struct device *d, int where) { @@ -1407,6 +1479,8 @@ cap_doe(struct device *d, int where) FLAG(l, PCI_DOE_STS_INT), FLAG(l, PCI_DOE_STS_ERROR), FLAG(l, PCI_DOE_STS_OBJECT_READY)); + + doe_discovery(d, where); } void