summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaxon Haws <jaxon.haws@amd.com>2022-10-17 15:29:41 -0500
committerJaxon Haws <jaxon.haws@amd.com>2022-11-02 12:30:29 -0500
commitd462e89c81b9bb0986087abf30a8ea62dcc123a3 (patch)
tree77f9c655fab795e3a5c1f4271ed758ed57076efe
parent55704534e519d38ed4c2362925b2a68cf4c1e476 (diff)
downloadpciutils-d462e89c81b9bb0986087abf30a8ea62dcc123a3.tar.gz
lspci: Add support for CXL GPF Device DVSEC
Add Global Persistent Flush DVSEC decoding for CXL device according to DVSEC Revision ID 0. Decode GPF Phase 2 Duration and GPF Phase 2 Power. Signed-off-by: Jaxon Haws <jaxon.haws@amd.com>
-rw-r--r--lib/header.h13
-rw-r--r--ls-ecaps.c44
2 files changed, 56 insertions, 1 deletions
diff --git a/lib/header.h b/lib/header.h
index e74f6d8..36b7040 100644
--- a/lib/header.h
+++ b/lib/header.h
@@ -1129,6 +1129,19 @@
/* PCIe CXL 2.0 Designated Vendor-Specific Capabilities for Register Locator */
#define PCI_CXL_RL_BLOCK1_LO 0x0c
+/* PCIe CXL Designated Vendor-Specific Capabilities for Global Persistent Flush */
+#define PCI_CXL_GPF_DEV_LEN 0x10
+#define PCI_CXL_GPF_DEV_PHASE2_DUR 0x0a /* GPF Phase 2 Duration Register */
+#define PCI_CXL_GPF_DEV_PHASE2_POW 0x0c /* GPF Phase 2 Power Register */
+#define PCI_CXL_GPF_DEV_1US 0x0
+#define PCI_CXL_GPF_DEV_10US 0x1
+#define PCI_CXL_GPF_DEV_100US 0x2
+#define PCI_CXL_GPF_DEV_1MS 0x3
+#define PCI_CXL_GPF_DEV_10MS 0x4
+#define PCI_CXL_GPF_DEV_100MS 0x5
+#define PCI_CXL_GPF_DEV_1S 0x6
+#define PCI_CXL_GPF_DEV_10S 0x7
+
/* Access Control Services */
#define PCI_ACS_CAP 0x04 /* ACS Capability Register */
#define PCI_ACS_CAP_VALID 0x0001 /* ACS Source Validation */
diff --git a/ls-ecaps.c b/ls-ecaps.c
index b9a4512..af71c63 100644
--- a/ls-ecaps.c
+++ b/ls-ecaps.c
@@ -839,6 +839,48 @@ dvsec_cxl_register_locator(struct device *d, int where, int len)
}
static void
+dvsec_cxl_gpf_device(struct device *d, int where)
+{
+ u32 l;
+ u16 w, duration;
+ u8 time_base, time_scale;
+
+ w = get_conf_word(d, where + PCI_CXL_GPF_DEV_PHASE2_DUR);
+ time_base = BITS(w, 0, 4);
+ time_scale = BITS(w, 8, 4);
+
+ switch (time_scale)
+ {
+ case PCI_CXL_GPF_DEV_100US:
+ case PCI_CXL_GPF_DEV_100MS:
+ duration = time_base * 100;
+ break;
+ case PCI_CXL_GPF_DEV_10US:
+ case PCI_CXL_GPF_DEV_10MS:
+ case PCI_CXL_GPF_DEV_10S:
+ duration = time_base * 10;
+ break;
+ case PCI_CXL_GPF_DEV_1US:
+ case PCI_CXL_GPF_DEV_1MS:
+ case PCI_CXL_GPF_DEV_1S:
+ duration = time_base;
+ break;
+ default:
+ /* Reserved */
+ printf("\t\tReserved time scale encoding %x\n", time_scale);
+ duration = time_base;
+ }
+
+ printf("\t\tGPF Phase 2 Duration: %u%s\n", duration,
+ (time_scale < PCI_CXL_GPF_DEV_1MS) ? "us":
+ (time_scale < PCI_CXL_GPF_DEV_1S) ? "ms" :
+ (time_scale == PCI_CXL_GPF_DEV_1S) ? "s" : "<?>");
+
+ l = get_conf_long(d, where + PCI_CXL_GPF_DEV_PHASE2_POW);
+ printf("\t\tGPF Phase 2 Power: %umW\n", (unsigned int)l);
+}
+
+static void
cap_dvsec_cxl(struct device *d, int id, int rev, int where, int len)
{
printf(": CXL\n");
@@ -863,7 +905,7 @@ cap_dvsec_cxl(struct device *d, int id, int rev, int where, int len)
printf("\t\tGPF DVSEC for Port\n");
break;
case 5:
- printf("\t\tGPF DVSEC for Device\n");
+ dvsec_cxl_gpf_device(d, where);
break;
case 7:
printf("\t\tPCIe DVSEC Flex Bus Port\n");