diff options
author | Alexis Gryta <alexis.gryta@liquid-markets.com> | 2023-06-05 15:06:08 +0900 |
---|---|---|
committer | Alexis Gryta <alexis.gryta@liquid-markets.com> | 2023-06-06 16:32:15 +0900 |
commit | 23b1ee0cef6856d540916e05cc80fab99eaefaa0 (patch) | |
tree | b823376c2a0403dd4d4502239f3ed165476dd799 | |
parent | 0766bfa0f557430a6dd3256d45a5b756499f9f7b (diff) | |
download | pciutils-23b1ee0cef6856d540916e05cc80fab99eaefaa0.tar.gz |
CXL: Fix Flex Bus DVSEC cap
-rw-r--r-- | lib/header.h | 1 | ||||
-rw-r--r-- | ls-ecaps.c | 60 |
2 files changed, 50 insertions, 11 deletions
diff --git a/lib/header.h b/lib/header.h index 63ee03c..1a04a78 100644 --- a/lib/header.h +++ b/lib/header.h @@ -1192,6 +1192,7 @@ #define PCI_CXL_FB_PORT_CTRL2 0x18 /* CXL Flex Bus Port Control2 Register */ #define PCI_CXL_FB_CTRL2_NOP_HINT 0x01 /* NOP Hint Enable */ #define PCI_CXL_FB_PORT_STATUS2 0x1c /* CXL Flex Bus Port Status2 Register */ +#define PCI_CXL_FB_NEXT_UNSUPPORTED 0x20 /* PCIe CXL Designated Vendor-Specific Capabilities for Multi-Logical Device */ #define PCI_CXL_MLD_LEN 0x10 @@ -950,17 +950,33 @@ dvsec_cxl_gpf_port(struct device *d, int where) } static void -dvsec_cxl_flex_bus(struct device *d, int where, int rev) +dvsec_cxl_flex_bus(struct device *d, int where, int rev, int len) { u16 w; u32 l, data; - if (rev < 1) - { - printf("\t\tRevision %d not supported\n", rev); - return; + // Sanity check: Does the length correspond to its revision? + switch (rev) { + case 0: + if (len != PCI_CXL_FB_MOD_TS_DATA) { + printf("\t\t<Wrong length for Revision %d>\n", rev); + } + break; + case 1: + if (len != PCI_CXL_FB_PORT_CAP2) { + printf("\t\t<Wrong length for Revision %d>\n", rev); + } + break; + case 2: + if (len != PCI_CXL_FB_NEXT_UNSUPPORTED) { + printf("\t\t<Wrong length for Revision %d>\n", rev); + } + break; + default: + break; } + // From Rev 0 w = get_conf_word(d, where + PCI_CXL_FB_PORT_CAP); printf("\t\tFBCap:\tCache%c IO%c Mem%c 68BFlit%c MltLogDev%c", FLAG(w, PCI_CXL_FB_CAP_CACHE), FLAG(w, PCI_CXL_FB_CAP_IO), @@ -993,12 +1009,18 @@ dvsec_cxl_flex_bus(struct device *d, int where, int rev) if (rev > 1) printf(" 256BFlit%c PBRFlit%c", FLAG(w, PCI_CXL_FB_STAT_256B_FLIT), FLAG(w, PCI_CXL_FB_STAT_PBR_FLIT)); + printf("\n"); - l = get_conf_long(d, where + PCI_CXL_FB_MOD_TS_DATA); - data = BITS(l, 0, 24); - printf("\n\t\tFBModTS:\tReceived FB Data: %06x\n", (unsigned int)data); + // From Rev 1 + if (rev >= 1) + { + l = get_conf_long(d, where + PCI_CXL_FB_MOD_TS_DATA); + data = BITS(l, 0, 24); + printf("\t\tFBModTS:\tReceived FB Data: %06x\n", (unsigned int)data); + } - if (rev > 1) + // From Rev 2 + if (rev >= 2) { u8 nop; @@ -1011,7 +1033,12 @@ dvsec_cxl_flex_bus(struct device *d, int where, int rev) l = get_conf_long(d, where + PCI_CXL_FB_PORT_STATUS2); nop = BITS(l, 0, 2); printf("\t\tFBSta2:\tNOPHintInfo: %x\n", nop); - } + } + + // Unparsed data + if (len > PCI_CXL_FB_LEN) { + printf("\t\t<?>\n"); + } } static void @@ -1068,29 +1095,40 @@ cap_dvsec_cxl(struct device *d, int id, int rev, int where, int len) switch (id) { case 0: + printf("\t\tPCIe DVSEC for CXL Devices\n"); dvsec_cxl_device(d, rev, where, len); break; case 2: + printf("\t\tNon-CXL Function Map DVSEC\n"); dvsec_cxl_function_map(d, where); break; case 3: + printf("\t\tCXL Extensions DVSEC for Ports\n"); dvsec_cxl_port(d, where, len); break; case 4: + printf("\t\tGPF DVSEC for CXL Ports\n"); dvsec_cxl_gpf_port(d, where); break; case 5: + printf("\t\tGPF DVSEC for CXL Devices\n"); dvsec_cxl_gpf_device(d, where); break; case 7: - dvsec_cxl_flex_bus(d, where, rev); + printf("\t\tPCIe DVSEC for Flex Bus Port\n"); + dvsec_cxl_flex_bus(d, where, rev, len); break; case 8: + printf("\t\tRegister Locator DVSEC\n"); dvsec_cxl_register_locator(d, where, len); break; case 9: + printf("\t\tMLD DVSEC\n"); dvsec_cxl_mld(d, where); break; + case 0xa: + printf("\t\tPCIe DVSEC for Test Capability <?>\n"); + break; default: printf("\t\tUnknown ID %04x\n", id); } |