Message ID | 20231230124239.310927-3-aik@amd.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Bjorn Helgaas |
Headers | show |
Series | lspci: Adding TDISP, IDE | expand |
On 30/12/23 23:42, Alexey Kardashevskiy wrote: > IDE (Integrity & Data Encryption) Extended Capability defined in [1] > implements control of the PCI link encryption. > > The example output is: > > Capabilities: [830 v1] IDE > IDECap: Lnk=1 Sel=1 FlowThru- PartHdr- Aggr- PCPC- IDE_KM+ > IDECtl: IntEn- > LinkIDE#0 Ctl: En- NPR- PR- CPL- PCRC- HdrEnc=no Alg='AES-GCM 256 key size, 96b MAC' TC0 ID0 > LinkIDE#0 Sta: Status=secure RecvChkFail- > SelectiveIDE#0 Ctl: En- NPR- PR- CPL- PCRC- HdrEnc=no Alg='AES-GCM 256 key size, 96b MAC' TC0 ID0 > SelectiveIDE#0 Sta: insecure RecvChkFail- > SelectiveIDE#0 RID: Valid- Base=0 Limit=0 SegBase=0 Ping? Suspiciously quiet :) This is also missing: --- a/setpci.c +++ b/setpci.c @@ -396,6 +396,7 @@ static const struct reg_name pci_reg_names[] = { { 0x20027, 0, 0, 0x0, "ECAP_LMR" }, { 0x20028, 0, 0, 0x0, "ECAP_HIER_ID" }, { 0x20029, 0, 0, 0x0, "ECAP_NPEM" }, + { 0x20030, 0, 0, 0x0, "ECAP_IDE" }, Which reminded me - one thing I want to do with setpci is changing the "En-"s above to "En+". At the moment setpci.c seems only allowing offsets into a ecapability which is tricky to use as offsets of "LinkIDE#NN Ctl" and "SelectiveIDE#NN Ctl" are not fixed - these are variable length arrays. So, I could 1) teach setpci do parsing (repeat what s-ecaps.c does) to allow register names, like "setpci CAP_IDE+LinkIDE#4Ctl", something like this. 2) dump offsets as ([24] in this example and use offsets with setpci which it can do now): LinkIDE#0 Ctl [24]: En- NPR- PR- CPL- PCRC- HdrEnc=no Alg='AES-GCM 256 key size, 96b MAC' TC0 ID0 3) leave lspci/setpci alone and do it elsewhere. Any advice? Thanks, > > [1] PCIe r6.0.1, sections 6.33, 7.9.26 > > Signed-off-by: Alexey Kardashevskiy <aik@amd.com> > --- > lib/header.h | 61 ++++++++ > ls-ecaps.c | 162 ++++++++++++++++++++ > 2 files changed, 223 insertions(+) > > diff --git a/lib/header.h b/lib/header.h > index 47ee8a6..5df2f57 100644 > --- a/lib/header.h > +++ b/lib/header.h > @@ -256,6 +256,7 @@ > #define PCI_EXT_CAP_ID_NPEM 0x29 /* Native PCIe Enclosure Management */ > #define PCI_EXT_CAP_ID_32GT 0x2a /* Physical Layer 32.0 GT/s */ > #define PCI_EXT_CAP_ID_DOE 0x2e /* Data Object Exchange */ > +#define PCI_EXT_CAP_ID_IDE 0x30 /* IDE */ > > /*** Definitions of capabilities ***/ > > @@ -1416,6 +1417,66 @@ > #define PCI_DOE_STS_ERROR 0x4 /* DOE Error */ > #define PCI_DOE_STS_OBJECT_READY 0x80000000 /* Data Object Ready */ > > +/* IDE Extended Capability */ > +#define PCI_IDE_CAP 0x4 > +#define PCI_IDE_CAP_LINK_IDE_SUPP 0x1 /* Link IDE Stream Supported */ > +#define PCI_IDE_CAP_SELECTIVE_IDE_SUPP 0x2 /* Selective IDE Streams Supported */ > +#define PCI_IDE_CAP_FLOWTHROUGH_IDE_SUPP 0x4 /* Flow-Through IDE Stream Supported */ > +#define PCI_IDE_CAP_PARTIAL_HEADER_ENC_SUPP 0x8 /* Partial Header Encryption Supported */ > +#define PCI_IDE_CAP_AGGREGATION_SUPP 0x10 /* Aggregation Supported */ > +#define PCI_IDE_CAP_PCRC_SUPP 0x20 /* PCRC Supported */ > +#define PCI_IDE_CAP_IDE_KM_SUPP 0x40 /* IDE_KM Protocol Supported */ > +#define PCI_IDE_CAP_ALG(x) (((x) >> 8) & 0x1f) /* Supported Algorithms */ > +#define PCI_IDE_CAP_ALG_AES_GCM_256 0 /* AES-GCM 256 key size, 96b MAC */ > +#define PCI_IDE_CAP_LINK_TC_NUM(x) (((x) >> 13) & 0x7) /* Number of TCs Supported for Link IDE */ > +#define PCI_IDE_CAP_SELECTIVE_STREAMS_NUM(x) (((x) >> 16) & 0xff) /* Number of Selective IDE Streams Supported */ > +#define PCI_IDE_CTL 0x8 > +#define PCI_IDE_CTL_FLOWTHROUGH_IDE 0x4 /* Flow-Through IDE Stream Enabled */ > +#define PCI_IDE_LINK_STREAM 0xC > +/* Link IDE Stream block, up to PCI_IDE_CAP_LINK_TC_NUM */ > +/* Link IDE Stream Control Register */ > +#define PCI_IDE_LINK_CTL_EN 0x1 /* Link IDE Stream Enable */ > +#define PCI_IDE_LINK_CTL_TX_AGGR_NPR(x)(((x) >> 2) & 0x3) /* Tx Aggregation Mode NPR */ > +#define PCI_IDE_LINK_CTL_TX_AGGR_PR(x) (((x) >> 4) & 0x3) /* Tx Aggregation Mode PR */ > +#define PCI_IDE_LINK_CTL_TX_AGGR_CPL(x)(((x) >> 6) & 0x3) /* Tx Aggregation Mode CPL */ > +#define PCI_IDE_LINK_CTL_PCRC_EN 0x100 /* PCRC Enable */ > +#define PCI_IDE_LINK_CTL_PART_ENC(x) (((x) >> 10) & 0xf) /* Partial Header Encryption Mode */ > +#define PCI_IDE_LINK_CTL_ALG(x) (((x) >> 14) & 0x1f) /* Selected Algorithm */ > +#define PCI_IDE_LINK_CTL_TC(x) (((x) >> 19) & 0x7) /* Traffic Class */ > +#define PCI_IDE_LINK_CTL_ID(x) (((x) >> 24) & 0xff) /* Stream ID */ > +/* Link IDE Stream Status Register */ > +#define PCI_IDE_LINK_STS_STATUS(x) ((x) & 0xf) /* Link IDE Stream State */ > +#define PCI_IDE_LINK_STS_RECVD_INTEGRITY_CHECK 0x80000000 /* Received Integrity Check Fail Message */ > +/* Selective IDE Stream block, up to PCI_IDE_CAP_SELECTIVE_STREAMS_NUM */ > +/* Selective IDE Stream Capability Register */ > +#define PCI_IDE_SEL_CAP_BLOCKS_NUM(x) ((x) & 0xf) /* Number of Address Association Register Blocks */ > +/* Selective IDE Stream Control Register */ > +#define PCI_IDE_SEL_CTL_EN 0x1 /* Selective IDE Stream Enable */ > +#define PCI_IDE_SEL_CTL_TX_AGGR_NPR(x) (((x) >> 2) & 0x3) /* Tx Aggregation Mode NPR */ > +#define PCI_IDE_SEL_CTL_TX_AGGR_PR(x) (((x) >> 4) & 0x3) /* Tx Aggregation Mode PR */ > +#define PCI_IDE_SEL_CTL_TX_AGGR_CPL(x) (((x) >> 6) & 0x3) /* Tx Aggregation Mode CPL */ > +#define PCI_IDE_SEL_CTL_PCRC_EN 0x100 /* PCRC Enable */ > +#define PCI_IDE_SEL_CTL_PART_ENC(x) (((x) >> 10) & 0xf) /* Partial Header Encryption Mode */ > +#define PCI_IDE_SEL_CTL_ALG(x) (((x) >> 14) & 0x1f) /* Selected Algorithm */ > +#define PCI_IDE_SEL_CTL_TC(x) (((x) >> 19) & 0x7) /* Traffic Class */ > +#define PCI_IDE_SEL_CTL_DEFAULT 0x400000 /* Default Stream */ > +#define PCI_IDE_SEL_CTL_ID(x) (((x) >> 24) & 0xff) /* Stream ID */ > +/* Selective IDE Stream Status Register */ > +#define PCI_IDE_SEL_STS_STATUS(x) ((x) & 0xf) /* Selective IDE Stream State */ > +#define PCI_IDE_SEL_STS_RECVD_INTEGRITY_CHECK 0x80000000 /* Received Integrity Check Fail Message */ > +/* IDE RID Association Register 1 */ > +#define PCI_IDE_SEL_RID_1_LIMIT(x) (((x) >> 8) & 0xffff) /* RID Limit */ > +/* IDE RID Association Register 2 */ > +#define PCI_IDE_SEL_RID_2_VALID 0x1 /* Valid */ > +#define PCI_IDE_SEL_RID_2_BASE(x) (((x) >> 8) & 0xffff) /* RID Base */ > +#define PCI_IDE_SEL_RID_2_SEG_BASE(x) (((x) >> 24) & 0xff) /* Segmeng Base */ > +/* Selective IDE Address Association Register Block, up to PCI_IDE_SEL_CAP_BLOCKS_NUM */ > +#define PCI_IDE_SEL_ADDR_1_VALID 0x1 /* Valid */ > +#define PCI_IDE_SEL_ADDR_1_BASE_LOW(x) (((x) >> 8) & 0xfff) /* Memory Base Lower */ > +#define PCI_IDE_SEL_ADDR_1_LIMIT_LOW(x)(((x) >> 20) & 0xfff) /* Memory Limit Lower */ > +/* IDE Address Association Register 2 is "Memory Limit Upper" */ > +/* IDE Address Association Register 3 is "Memory Base Upper" */ > + > /* > * The PCI interface treats multi-function devices as independent > * devices. The slot/function address of each device is encoded > diff --git a/ls-ecaps.c b/ls-ecaps.c > index 2d7d827..9f6c3f8 100644 > --- a/ls-ecaps.c > +++ b/ls-ecaps.c > @@ -1468,6 +1468,165 @@ cap_doe(struct device *d, int where) > FLAG(l, PCI_DOE_STS_OBJECT_READY)); > } > > +static void > +cap_ide(struct device *d, int where) > +{ > + const char *hdr_enc_mode[] = { "no", "17:2", "25:2", "33:2", "41:2" }; > + const char *algo[] = { "AES-GCM 256 key size, 96b MAC" }; > + const char *stream_state[] = { "insecure", "secure" }; > + const char *aggr[] = { "-", "=2", "=4", "=8" }; > + u32 l, l2, linknum = 0, selnum = 0, addrnum, off, i, j; > + char buf1[16], buf2[16]; > + > + printf("IDE\n"); > + > + if (verbose < 2) > + return; > + > + if (!config_fetch(d, where + PCI_IDE_CAP, 8)) > + { > + printf("\t\t<unreadable>\n"); > + return; > + } > + > + l = get_conf_long(d, where + PCI_IDE_CAP); > + if (l & PCI_IDE_CAP_LINK_IDE_SUPP) > + linknum = PCI_IDE_CAP_LINK_TC_NUM(l) + 1; > + if (l & PCI_IDE_CAP_SELECTIVE_IDE_SUPP) > + selnum = PCI_IDE_CAP_SELECTIVE_STREAMS_NUM(l) + 1; > + > + printf("\t\tIDECap: Lnk=%d Sel=%d FlowThru%c PartHdr%c Aggr%c PCPC%c IDE_KM%c\n", > + linknum, > + selnum, > + FLAG(l, PCI_IDE_CAP_FLOWTHROUGH_IDE_SUPP), > + FLAG(l, PCI_IDE_CAP_PARTIAL_HEADER_ENC_SUPP), > + FLAG(l, PCI_IDE_CAP_AGGREGATION_SUPP), > + FLAG(l, PCI_IDE_CAP_PCRC_SUPP), > + FLAG(l, PCI_IDE_CAP_IDE_KM_SUPP)); > + > + l = get_conf_long(d, where + PCI_IDE_CTL); > + printf("\t\tIDECtl: IntEn%c\n", > + FLAG(l, PCI_IDE_CTL_FLOWTHROUGH_IDE)); > + > + // The rest of the capability is variable length arrays > + off = where + PCI_IDE_CAP + PCI_IDE_LINK_STREAM; > + > + // Link IDE Register Block repeated 0 to 8 times > + if (linknum) > + { > + if (!config_fetch(d, off, 8 * linknum)) > + { > + printf("\t\t<unreadable>\n"); > + return; > + } > + for (i = 0; i < linknum; ++i) > + { > + // Link IDE Stream Control Register > + l = get_conf_long(d, off); > + off += 4; > + printf("\t\tLinkIDE#%d Ctl: En%c NPR%s PR%s CPL%s PCRC%c HdrEnc=%s Alg='%s' TC%d ID%d\n", > + i, > + FLAG(l, PCI_IDE_LINK_CTL_EN), > + aggr[PCI_IDE_LINK_CTL_TX_AGGR_NPR(l)], > + aggr[PCI_IDE_LINK_CTL_TX_AGGR_PR(l)], > + aggr[PCI_IDE_LINK_CTL_TX_AGGR_CPL(l)], > + FLAG(l, PCI_IDE_LINK_CTL_EN), > + TABLE(hdr_enc_mode, PCI_IDE_LINK_CTL_PART_ENC(l), buf1), > + TABLE(algo, PCI_IDE_LINK_CTL_ALG(l), buf2), > + PCI_IDE_LINK_CTL_TC(l), > + PCI_IDE_LINK_CTL_ID(l) > + ); > + > + /* Link IDE Stream Status Register */ > + l = get_conf_long(d, off); > + off += 4; > + printf("\t\tLinkIDE#%d Sta: Status=%s RecvChkFail%c\n", > + i, > + TABLE(stream_state, PCI_IDE_LINK_STS_STATUS(l), buf1), > + FLAG(l, PCI_IDE_LINK_STS_RECVD_INTEGRITY_CHECK)); > + } > + } > + > + for (i = 0; i < linknum; ++i) > + { > + // Fetching Selective IDE Stream Capability/Control/Status/RID1/RID2 > + if (!config_fetch(d, off, 20)) > + { > + printf("\t\t<unreadable>\n"); > + return; > + } > + > + // Selective IDE Stream Capability Register > + l = get_conf_long(d, off); > + off += 4; > + addrnum = PCI_IDE_SEL_CAP_BLOCKS_NUM(l); > + > + // Selective IDE Stream Control Register > + l = get_conf_long(d, off); > + off += 4; > + > + printf("\t\tSelectiveIDE#%d Ctl: En%c NPR%s PR%s CPL%s PCRC%c HdrEnc=%s Alg='%s' TC%d ID%d%s\n", > + i, > + FLAG(l, PCI_IDE_SEL_CTL_EN), > + aggr[PCI_IDE_SEL_CTL_TX_AGGR_NPR(l)], > + aggr[PCI_IDE_SEL_CTL_TX_AGGR_PR(l)], > + aggr[PCI_IDE_SEL_CTL_TX_AGGR_CPL(l)], > + FLAG(l, PCI_IDE_SEL_CTL_PCRC_EN), > + TABLE(hdr_enc_mode, PCI_IDE_SEL_CTL_PART_ENC(l), buf1), > + TABLE(algo, PCI_IDE_SEL_CTL_ALG(l), buf2), > + PCI_IDE_SEL_CTL_TC(l), > + PCI_IDE_SEL_CTL_ID(l), > + (l & PCI_IDE_SEL_CTL_DEFAULT) ? " Default" : "" > + ); > + > + // Selective IDE Stream Status Register > + l = get_conf_long(d, off); > + off += 4; > + > + printf("\t\tSelectiveIDE#%d Sta: %s RecvChkFail%c\n", > + i, > + TABLE(stream_state, PCI_IDE_SEL_STS_STATUS(l), buf1), > + FLAG(l, PCI_IDE_SEL_STS_RECVD_INTEGRITY_CHECK)); > + > + // IDE RID Association Registers > + l = get_conf_long(d, off); > + off += 4; > + l2 = get_conf_long(d, off); > + off += 4; > + > + printf("\t\tSelectiveIDE#%d RID: Valid%c Base=%x Limit=%x SegBase=%x\n", > + i, > + FLAG(l2, PCI_IDE_SEL_RID_2_VALID), > + PCI_IDE_SEL_RID_2_BASE(l2), > + PCI_IDE_SEL_RID_1_LIMIT(l), > + PCI_IDE_SEL_RID_2_SEG_BASE(l2)); > + > + if (!config_fetch(d, off, addrnum * 12)) > + { > + printf("\t\t<unreadable>\n"); > + return; > + } > + > + // IDE Address Association Registers > + for (j = 0; j < addrnum; ++j) > + { > + u64 limit, base; > + > + l = get_conf_long(d, off); > + off += 4; > + limit = get_conf_long(d, off); > + off += 4; > + base = get_conf_long(d, off); > + off += 4; > + printf("\t\tSelectiveIDE#%d RID: Valid%c Base=%lx Limit=%lx\n", > + i, > + FLAG(l, PCI_IDE_SEL_ADDR_1_VALID), > + (base << 32) | PCI_IDE_SEL_ADDR_1_BASE_LOW(l), > + (limit << 32) | PCI_IDE_SEL_ADDR_1_LIMIT_LOW(l)); > + } > + } > +} > + > void > show_ext_caps(struct device *d, int type) > { > @@ -1621,6 +1780,9 @@ show_ext_caps(struct device *d, int type) > case PCI_EXT_CAP_ID_DOE: > cap_doe(d, where); > break; > + case PCI_EXT_CAP_ID_IDE: > + cap_ide(d, where); > + break; > default: > printf("Extended Capability ID %#02x\n", id); > break;
On Sat, Dec 30, 2023 at 11:42:39PM +1100, Alexey Kardashevskiy wrote: > IDE (Integrity & Data Encryption) Extended Capability defined in [1] > implements control of the PCI link encryption. > > The example output is: > > Capabilities: [830 v1] IDE Possibly expand "IDE"? Many other Capabilities are spelled out: Capabilities: [c0] Express Downstream Port (Slot+), MSI 00 Capabilities: [100] Device Serial Number 5f-2f-9d-40-30-f1-0c-00 Capabilities: [200] Advanced Error Reporting Capabilities: [300] Virtual Channel Capabilities: [400] Power Budgeting <?> Capabilities: [500] Vendor Specific Information: ID=1234 Rev=1 Len=0d8 <?> Capabilities: [700] Secondary PCI Express
Hello! > > Capabilities: [830 v1] IDE > > Possibly expand "IDE"? [...] Yes, please. Also, could you please provide some test data (a dump of config space which contains this capability)? See also the dumps in the "tests" directory. Have a nice fortnight
diff --git a/lib/header.h b/lib/header.h index 47ee8a6..5df2f57 100644 --- a/lib/header.h +++ b/lib/header.h @@ -256,6 +256,7 @@ #define PCI_EXT_CAP_ID_NPEM 0x29 /* Native PCIe Enclosure Management */ #define PCI_EXT_CAP_ID_32GT 0x2a /* Physical Layer 32.0 GT/s */ #define PCI_EXT_CAP_ID_DOE 0x2e /* Data Object Exchange */ +#define PCI_EXT_CAP_ID_IDE 0x30 /* IDE */ /*** Definitions of capabilities ***/ @@ -1416,6 +1417,66 @@ #define PCI_DOE_STS_ERROR 0x4 /* DOE Error */ #define PCI_DOE_STS_OBJECT_READY 0x80000000 /* Data Object Ready */ +/* IDE Extended Capability */ +#define PCI_IDE_CAP 0x4 +#define PCI_IDE_CAP_LINK_IDE_SUPP 0x1 /* Link IDE Stream Supported */ +#define PCI_IDE_CAP_SELECTIVE_IDE_SUPP 0x2 /* Selective IDE Streams Supported */ +#define PCI_IDE_CAP_FLOWTHROUGH_IDE_SUPP 0x4 /* Flow-Through IDE Stream Supported */ +#define PCI_IDE_CAP_PARTIAL_HEADER_ENC_SUPP 0x8 /* Partial Header Encryption Supported */ +#define PCI_IDE_CAP_AGGREGATION_SUPP 0x10 /* Aggregation Supported */ +#define PCI_IDE_CAP_PCRC_SUPP 0x20 /* PCRC Supported */ +#define PCI_IDE_CAP_IDE_KM_SUPP 0x40 /* IDE_KM Protocol Supported */ +#define PCI_IDE_CAP_ALG(x) (((x) >> 8) & 0x1f) /* Supported Algorithms */ +#define PCI_IDE_CAP_ALG_AES_GCM_256 0 /* AES-GCM 256 key size, 96b MAC */ +#define PCI_IDE_CAP_LINK_TC_NUM(x) (((x) >> 13) & 0x7) /* Number of TCs Supported for Link IDE */ +#define PCI_IDE_CAP_SELECTIVE_STREAMS_NUM(x) (((x) >> 16) & 0xff) /* Number of Selective IDE Streams Supported */ +#define PCI_IDE_CTL 0x8 +#define PCI_IDE_CTL_FLOWTHROUGH_IDE 0x4 /* Flow-Through IDE Stream Enabled */ +#define PCI_IDE_LINK_STREAM 0xC +/* Link IDE Stream block, up to PCI_IDE_CAP_LINK_TC_NUM */ +/* Link IDE Stream Control Register */ +#define PCI_IDE_LINK_CTL_EN 0x1 /* Link IDE Stream Enable */ +#define PCI_IDE_LINK_CTL_TX_AGGR_NPR(x)(((x) >> 2) & 0x3) /* Tx Aggregation Mode NPR */ +#define PCI_IDE_LINK_CTL_TX_AGGR_PR(x) (((x) >> 4) & 0x3) /* Tx Aggregation Mode PR */ +#define PCI_IDE_LINK_CTL_TX_AGGR_CPL(x)(((x) >> 6) & 0x3) /* Tx Aggregation Mode CPL */ +#define PCI_IDE_LINK_CTL_PCRC_EN 0x100 /* PCRC Enable */ +#define PCI_IDE_LINK_CTL_PART_ENC(x) (((x) >> 10) & 0xf) /* Partial Header Encryption Mode */ +#define PCI_IDE_LINK_CTL_ALG(x) (((x) >> 14) & 0x1f) /* Selected Algorithm */ +#define PCI_IDE_LINK_CTL_TC(x) (((x) >> 19) & 0x7) /* Traffic Class */ +#define PCI_IDE_LINK_CTL_ID(x) (((x) >> 24) & 0xff) /* Stream ID */ +/* Link IDE Stream Status Register */ +#define PCI_IDE_LINK_STS_STATUS(x) ((x) & 0xf) /* Link IDE Stream State */ +#define PCI_IDE_LINK_STS_RECVD_INTEGRITY_CHECK 0x80000000 /* Received Integrity Check Fail Message */ +/* Selective IDE Stream block, up to PCI_IDE_CAP_SELECTIVE_STREAMS_NUM */ +/* Selective IDE Stream Capability Register */ +#define PCI_IDE_SEL_CAP_BLOCKS_NUM(x) ((x) & 0xf) /* Number of Address Association Register Blocks */ +/* Selective IDE Stream Control Register */ +#define PCI_IDE_SEL_CTL_EN 0x1 /* Selective IDE Stream Enable */ +#define PCI_IDE_SEL_CTL_TX_AGGR_NPR(x) (((x) >> 2) & 0x3) /* Tx Aggregation Mode NPR */ +#define PCI_IDE_SEL_CTL_TX_AGGR_PR(x) (((x) >> 4) & 0x3) /* Tx Aggregation Mode PR */ +#define PCI_IDE_SEL_CTL_TX_AGGR_CPL(x) (((x) >> 6) & 0x3) /* Tx Aggregation Mode CPL */ +#define PCI_IDE_SEL_CTL_PCRC_EN 0x100 /* PCRC Enable */ +#define PCI_IDE_SEL_CTL_PART_ENC(x) (((x) >> 10) & 0xf) /* Partial Header Encryption Mode */ +#define PCI_IDE_SEL_CTL_ALG(x) (((x) >> 14) & 0x1f) /* Selected Algorithm */ +#define PCI_IDE_SEL_CTL_TC(x) (((x) >> 19) & 0x7) /* Traffic Class */ +#define PCI_IDE_SEL_CTL_DEFAULT 0x400000 /* Default Stream */ +#define PCI_IDE_SEL_CTL_ID(x) (((x) >> 24) & 0xff) /* Stream ID */ +/* Selective IDE Stream Status Register */ +#define PCI_IDE_SEL_STS_STATUS(x) ((x) & 0xf) /* Selective IDE Stream State */ +#define PCI_IDE_SEL_STS_RECVD_INTEGRITY_CHECK 0x80000000 /* Received Integrity Check Fail Message */ +/* IDE RID Association Register 1 */ +#define PCI_IDE_SEL_RID_1_LIMIT(x) (((x) >> 8) & 0xffff) /* RID Limit */ +/* IDE RID Association Register 2 */ +#define PCI_IDE_SEL_RID_2_VALID 0x1 /* Valid */ +#define PCI_IDE_SEL_RID_2_BASE(x) (((x) >> 8) & 0xffff) /* RID Base */ +#define PCI_IDE_SEL_RID_2_SEG_BASE(x) (((x) >> 24) & 0xff) /* Segmeng Base */ +/* Selective IDE Address Association Register Block, up to PCI_IDE_SEL_CAP_BLOCKS_NUM */ +#define PCI_IDE_SEL_ADDR_1_VALID 0x1 /* Valid */ +#define PCI_IDE_SEL_ADDR_1_BASE_LOW(x) (((x) >> 8) & 0xfff) /* Memory Base Lower */ +#define PCI_IDE_SEL_ADDR_1_LIMIT_LOW(x)(((x) >> 20) & 0xfff) /* Memory Limit Lower */ +/* IDE Address Association Register 2 is "Memory Limit Upper" */ +/* IDE Address Association Register 3 is "Memory Base Upper" */ + /* * The PCI interface treats multi-function devices as independent * devices. The slot/function address of each device is encoded diff --git a/ls-ecaps.c b/ls-ecaps.c index 2d7d827..9f6c3f8 100644 --- a/ls-ecaps.c +++ b/ls-ecaps.c @@ -1468,6 +1468,165 @@ cap_doe(struct device *d, int where) FLAG(l, PCI_DOE_STS_OBJECT_READY)); } +static void +cap_ide(struct device *d, int where) +{ + const char *hdr_enc_mode[] = { "no", "17:2", "25:2", "33:2", "41:2" }; + const char *algo[] = { "AES-GCM 256 key size, 96b MAC" }; + const char *stream_state[] = { "insecure", "secure" }; + const char *aggr[] = { "-", "=2", "=4", "=8" }; + u32 l, l2, linknum = 0, selnum = 0, addrnum, off, i, j; + char buf1[16], buf2[16]; + + printf("IDE\n"); + + if (verbose < 2) + return; + + if (!config_fetch(d, where + PCI_IDE_CAP, 8)) + { + printf("\t\t<unreadable>\n"); + return; + } + + l = get_conf_long(d, where + PCI_IDE_CAP); + if (l & PCI_IDE_CAP_LINK_IDE_SUPP) + linknum = PCI_IDE_CAP_LINK_TC_NUM(l) + 1; + if (l & PCI_IDE_CAP_SELECTIVE_IDE_SUPP) + selnum = PCI_IDE_CAP_SELECTIVE_STREAMS_NUM(l) + 1; + + printf("\t\tIDECap: Lnk=%d Sel=%d FlowThru%c PartHdr%c Aggr%c PCPC%c IDE_KM%c\n", + linknum, + selnum, + FLAG(l, PCI_IDE_CAP_FLOWTHROUGH_IDE_SUPP), + FLAG(l, PCI_IDE_CAP_PARTIAL_HEADER_ENC_SUPP), + FLAG(l, PCI_IDE_CAP_AGGREGATION_SUPP), + FLAG(l, PCI_IDE_CAP_PCRC_SUPP), + FLAG(l, PCI_IDE_CAP_IDE_KM_SUPP)); + + l = get_conf_long(d, where + PCI_IDE_CTL); + printf("\t\tIDECtl: IntEn%c\n", + FLAG(l, PCI_IDE_CTL_FLOWTHROUGH_IDE)); + + // The rest of the capability is variable length arrays + off = where + PCI_IDE_CAP + PCI_IDE_LINK_STREAM; + + // Link IDE Register Block repeated 0 to 8 times + if (linknum) + { + if (!config_fetch(d, off, 8 * linknum)) + { + printf("\t\t<unreadable>\n"); + return; + } + for (i = 0; i < linknum; ++i) + { + // Link IDE Stream Control Register + l = get_conf_long(d, off); + off += 4; + printf("\t\tLinkIDE#%d Ctl: En%c NPR%s PR%s CPL%s PCRC%c HdrEnc=%s Alg='%s' TC%d ID%d\n", + i, + FLAG(l, PCI_IDE_LINK_CTL_EN), + aggr[PCI_IDE_LINK_CTL_TX_AGGR_NPR(l)], + aggr[PCI_IDE_LINK_CTL_TX_AGGR_PR(l)], + aggr[PCI_IDE_LINK_CTL_TX_AGGR_CPL(l)], + FLAG(l, PCI_IDE_LINK_CTL_EN), + TABLE(hdr_enc_mode, PCI_IDE_LINK_CTL_PART_ENC(l), buf1), + TABLE(algo, PCI_IDE_LINK_CTL_ALG(l), buf2), + PCI_IDE_LINK_CTL_TC(l), + PCI_IDE_LINK_CTL_ID(l) + ); + + /* Link IDE Stream Status Register */ + l = get_conf_long(d, off); + off += 4; + printf("\t\tLinkIDE#%d Sta: Status=%s RecvChkFail%c\n", + i, + TABLE(stream_state, PCI_IDE_LINK_STS_STATUS(l), buf1), + FLAG(l, PCI_IDE_LINK_STS_RECVD_INTEGRITY_CHECK)); + } + } + + for (i = 0; i < linknum; ++i) + { + // Fetching Selective IDE Stream Capability/Control/Status/RID1/RID2 + if (!config_fetch(d, off, 20)) + { + printf("\t\t<unreadable>\n"); + return; + } + + // Selective IDE Stream Capability Register + l = get_conf_long(d, off); + off += 4; + addrnum = PCI_IDE_SEL_CAP_BLOCKS_NUM(l); + + // Selective IDE Stream Control Register + l = get_conf_long(d, off); + off += 4; + + printf("\t\tSelectiveIDE#%d Ctl: En%c NPR%s PR%s CPL%s PCRC%c HdrEnc=%s Alg='%s' TC%d ID%d%s\n", + i, + FLAG(l, PCI_IDE_SEL_CTL_EN), + aggr[PCI_IDE_SEL_CTL_TX_AGGR_NPR(l)], + aggr[PCI_IDE_SEL_CTL_TX_AGGR_PR(l)], + aggr[PCI_IDE_SEL_CTL_TX_AGGR_CPL(l)], + FLAG(l, PCI_IDE_SEL_CTL_PCRC_EN), + TABLE(hdr_enc_mode, PCI_IDE_SEL_CTL_PART_ENC(l), buf1), + TABLE(algo, PCI_IDE_SEL_CTL_ALG(l), buf2), + PCI_IDE_SEL_CTL_TC(l), + PCI_IDE_SEL_CTL_ID(l), + (l & PCI_IDE_SEL_CTL_DEFAULT) ? " Default" : "" + ); + + // Selective IDE Stream Status Register + l = get_conf_long(d, off); + off += 4; + + printf("\t\tSelectiveIDE#%d Sta: %s RecvChkFail%c\n", + i, + TABLE(stream_state, PCI_IDE_SEL_STS_STATUS(l), buf1), + FLAG(l, PCI_IDE_SEL_STS_RECVD_INTEGRITY_CHECK)); + + // IDE RID Association Registers + l = get_conf_long(d, off); + off += 4; + l2 = get_conf_long(d, off); + off += 4; + + printf("\t\tSelectiveIDE#%d RID: Valid%c Base=%x Limit=%x SegBase=%x\n", + i, + FLAG(l2, PCI_IDE_SEL_RID_2_VALID), + PCI_IDE_SEL_RID_2_BASE(l2), + PCI_IDE_SEL_RID_1_LIMIT(l), + PCI_IDE_SEL_RID_2_SEG_BASE(l2)); + + if (!config_fetch(d, off, addrnum * 12)) + { + printf("\t\t<unreadable>\n"); + return; + } + + // IDE Address Association Registers + for (j = 0; j < addrnum; ++j) + { + u64 limit, base; + + l = get_conf_long(d, off); + off += 4; + limit = get_conf_long(d, off); + off += 4; + base = get_conf_long(d, off); + off += 4; + printf("\t\tSelectiveIDE#%d RID: Valid%c Base=%lx Limit=%lx\n", + i, + FLAG(l, PCI_IDE_SEL_ADDR_1_VALID), + (base << 32) | PCI_IDE_SEL_ADDR_1_BASE_LOW(l), + (limit << 32) | PCI_IDE_SEL_ADDR_1_LIMIT_LOW(l)); + } + } +} + void show_ext_caps(struct device *d, int type) { @@ -1621,6 +1780,9 @@ show_ext_caps(struct device *d, int type) case PCI_EXT_CAP_ID_DOE: cap_doe(d, where); break; + case PCI_EXT_CAP_ID_IDE: + cap_ide(d, where); + break; default: printf("Extended Capability ID %#02x\n", id); break;
IDE (Integrity & Data Encryption) Extended Capability defined in [1] implements control of the PCI link encryption. The example output is: Capabilities: [830 v1] IDE IDECap: Lnk=1 Sel=1 FlowThru- PartHdr- Aggr- PCPC- IDE_KM+ IDECtl: IntEn- LinkIDE#0 Ctl: En- NPR- PR- CPL- PCRC- HdrEnc=no Alg='AES-GCM 256 key size, 96b MAC' TC0 ID0 LinkIDE#0 Sta: Status=secure RecvChkFail- SelectiveIDE#0 Ctl: En- NPR- PR- CPL- PCRC- HdrEnc=no Alg='AES-GCM 256 key size, 96b MAC' TC0 ID0 SelectiveIDE#0 Sta: insecure RecvChkFail- SelectiveIDE#0 RID: Valid- Base=0 Limit=0 SegBase=0 [1] PCIe r6.0.1, sections 6.33, 7.9.26 Signed-off-by: Alexey Kardashevskiy <aik@amd.com> --- lib/header.h | 61 ++++++++ ls-ecaps.c | 162 ++++++++++++++++++++ 2 files changed, 223 insertions(+)