X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ls-ecaps.c;h=634db21dd1b239ae0c408727bc5136ef0240b66e;hb=d9b1b8e350adbaf97713ce50b044f1c63d6a98cf;hp=e02c1be8e08f2b36543e4151aec6ba611c1840e5;hpb=de91b6f262456ffc62afe5cff2b4f54ec4b38598;p=pciutils.git diff --git a/ls-ecaps.c b/ls-ecaps.c index e02c1be..634db21 100644 --- a/ls-ecaps.c +++ b/ls-ecaps.c @@ -90,15 +90,16 @@ cap_dsn(struct device *d, int where) } static void -cap_aer(struct device *d, int where) +cap_aer(struct device *d, int where, int type) { - u32 l; + u32 l, l0, l1, l2, l3; + u16 w; printf("Advanced Error Reporting\n"); if (verbose < 2) return; - if (!config_fetch(d, where + PCI_ERR_UNCOR_STATUS, 24)) + if (!config_fetch(d, where + PCI_ERR_UNCOR_STATUS, 40)) return; l = get_conf_long(d, where + PCI_ERR_UNCOR_STATUS); @@ -131,10 +132,48 @@ cap_aer(struct device *d, int where) FLAG(l, PCI_ERR_COR_RCVR), FLAG(l, PCI_ERR_COR_BAD_TLP), FLAG(l, PCI_ERR_COR_BAD_DLLP), FLAG(l, PCI_ERR_COR_REP_ROLL), FLAG(l, PCI_ERR_COR_REP_TIMER), FLAG(l, PCI_ERR_COR_REP_ANFE)); l = get_conf_long(d, where + PCI_ERR_CAP); - printf("\t\tAERCap:\tFirst Error Pointer: %02x, GenCap%c CGenEn%c ChkCap%c ChkEn%c\n", + printf("\t\tAERCap:\tFirst Error Pointer: %02x, ECRCGenCap%c ECRCGenEn%c ECRCChkCap%c ECRCChkEn%c\n" + "\t\t\tMultHdrRecCap%c MultHdrRecEn%c TLPPfxPres%c HdrLogCap%c\n", PCI_ERR_CAP_FEP(l), FLAG(l, PCI_ERR_CAP_ECRC_GENC), FLAG(l, PCI_ERR_CAP_ECRC_GENE), - FLAG(l, PCI_ERR_CAP_ECRC_CHKC), FLAG(l, PCI_ERR_CAP_ECRC_CHKE)); + FLAG(l, PCI_ERR_CAP_ECRC_CHKC), FLAG(l, PCI_ERR_CAP_ECRC_CHKE), + FLAG(l, PCI_ERR_CAP_MULT_HDRC), FLAG(l, PCI_ERR_CAP_MULT_HDRE), + FLAG(l, PCI_ERR_CAP_TLP_PFX), FLAG(l, PCI_ERR_CAP_HDR_LOG)); + l0 = get_conf_long(d, where + PCI_ERR_HEADER_LOG); + l1 = get_conf_long(d, where + PCI_ERR_HEADER_LOG + 4); + l2 = get_conf_long(d, where + PCI_ERR_HEADER_LOG + 8); + l3 = get_conf_long(d, where + PCI_ERR_HEADER_LOG + 12); + printf("\t\tHeaderLog: %08x %08x %08x %08x\n", l0, l1, l2, l3); + + if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_ROOT_EC) + { + if (!config_fetch(d, where + PCI_ERR_ROOT_COMMAND, 12)) + return; + + l = get_conf_long(d, where + PCI_ERR_ROOT_COMMAND); + printf("\t\tRootCmd: CERptEn%c NFERptEn%c FERptEn%c\n", + FLAG(l, PCI_ERR_ROOT_CMD_COR_EN), + FLAG(l, PCI_ERR_ROOT_CMD_NONFATAL_EN), + FLAG(l, PCI_ERR_ROOT_CMD_FATAL_EN)); + + l = get_conf_long(d, where + PCI_ERR_ROOT_STATUS); + printf("\t\tRootSta: CERcvd%c MultCERcvd%c UERcvd%c MultUERcvd%c\n" + "\t\t\t FirstFatal%c NonFatalMsg%c FatalMsg%c IntMsg %d\n", + FLAG(l, PCI_ERR_ROOT_COR_RCV), + FLAG(l, PCI_ERR_ROOT_MULTI_COR_RCV), + FLAG(l, PCI_ERR_ROOT_UNCOR_RCV), + FLAG(l, PCI_ERR_ROOT_MULTI_UNCOR_RCV), + FLAG(l, PCI_ERR_ROOT_FIRST_FATAL), + FLAG(l, PCI_ERR_ROOT_NONFATAL_RCV), + FLAG(l, PCI_ERR_ROOT_FATAL_RCV), + PCI_ERR_MSG_NUM(l)); + + w = get_conf_word(d, where + PCI_ERR_ROOT_COR_SRC); + printf("\t\tErrorSrc: ERR_COR: %04x ", w); + + w = get_conf_word(d, where + PCI_ERR_ROOT_SRC); + printf("ERR_FATAL/NONFATAL: %04x\n", w); + } } static void cap_dpc(struct device *d, int where) @@ -527,60 +566,150 @@ cap_evendor(struct device *d, int where) BITS(hdr, 20, 12)); } +static int l1pm_calc_pwron(int scale, int value) +{ + switch (scale) + { + case 0: + return 2 * value; + case 1: + return 10 * value; + case 2: + return 100 * value; + } + return -1; +} + static void cap_l1pm(struct device *d, int where) { - u32 l1_cap; - int power_on_scale; + u32 l1_cap, val, scale; + int time; printf("L1 PM Substates\n"); if (verbose < 2) return; - if (!config_fetch(d, where + 4, 4)) + if (!config_fetch(d, where + PCI_L1PM_SUBSTAT_CAP, 12)) { printf("\t\t\n"); return; } - l1_cap = get_conf_long(d, where + 4); + l1_cap = get_conf_long(d, where + PCI_L1PM_SUBSTAT_CAP); printf("\t\tL1SubCap: "); printf("PCI-PM_L1.2%c PCI-PM_L1.1%c ASPM_L1.2%c ASPM_L1.1%c L1_PM_Substates%c\n", - FLAG(l1_cap, 1), - FLAG(l1_cap, 2), - FLAG(l1_cap, 4), - FLAG(l1_cap, 8), - FLAG(l1_cap, 16)); + FLAG(l1_cap, PCI_L1PM_SUBSTAT_CAP_PM_L12), + FLAG(l1_cap, PCI_L1PM_SUBSTAT_CAP_PM_L11), + FLAG(l1_cap, PCI_L1PM_SUBSTAT_CAP_ASPM_L12), + FLAG(l1_cap, PCI_L1PM_SUBSTAT_CAP_ASPM_L11), + FLAG(l1_cap, PCI_L1PM_SUBSTAT_CAP_L1PM_SUPP)); - if (BITS(l1_cap, 0, 1) || BITS(l1_cap, 2, 1)) + if (l1_cap & PCI_L1PM_SUBSTAT_CAP_PM_L12 || l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12) { - printf("\t\t\t PortCommonModeRestoreTime=%dus ", - BITS(l1_cap, 8,8)); + printf("\t\t\t PortCommonModeRestoreTime=%dus ", BITS(l1_cap, 8, 8)); + time = l1pm_calc_pwron(BITS(l1_cap, 16, 2), BITS(l1_cap, 19, 5)); + if (time != -1) + printf("PortTPowerOnTime=%dus\n", time); + else + printf("PortTPowerOnTime=\n"); + } - power_on_scale = BITS(l1_cap, 16, 2); + val = get_conf_long(d, where + PCI_L1PM_SUBSTAT_CTL1); + printf("\t\tL1SubCtl1: PCI-PM_L1.2%c PCI-PM_L1.1%c ASPM_L1.2%c ASPM_L1.1%c\n", + FLAG(val, PCI_L1PM_SUBSTAT_CTL1_PM_L12), + FLAG(val, PCI_L1PM_SUBSTAT_CTL1_PM_L11), + FLAG(val, PCI_L1PM_SUBSTAT_CTL1_ASPM_L12), + FLAG(val, PCI_L1PM_SUBSTAT_CTL1_ASPM_L11)); - printf("PortTPowerOnTime="); - switch (power_on_scale) - { - case 0: - printf("%dus\n", BITS(l1_cap, 19, 5) * 2); - break; - case 1: - printf("%dus\n", BITS(l1_cap, 19, 5) * 10); - break; - case 2: - printf("%dus\n", BITS(l1_cap, 19, 5) * 100); - break; - default: - printf("\n"); - break; - } + if (l1_cap & PCI_L1PM_SUBSTAT_CAP_PM_L12 || l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12) + printf("\t\t\t T_CommonMode=%dus", BITS(val, 8, 8)); + + if (l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12) + { + scale = BITS(val, 29, 3); + if (scale > 5) + printf(" LTR1.2_Threshold="); + else + printf(" LTR1.2_Threshold=%lldns", BITS(val, 16, 10) * (unsigned long long) cap_ltr_scale(scale)); + } + printf("\n"); + + val = get_conf_long(d, where + PCI_L1PM_SUBSTAT_CTL2); + printf("\t\tL1SubCtl2:"); + if (l1_cap & PCI_L1PM_SUBSTAT_CAP_PM_L12 || l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12) + { + time = l1pm_calc_pwron(BITS(val, 0, 2), BITS(val, 3, 5)); + if (time != -1) + printf(" T_PwrOn=%dus", time); + else + printf(" T_PwrOn="); + } + printf("\n"); +} + +static void +cap_ptm(struct device *d, int where) +{ + u32 buff; + u16 clock; + + printf("Precision Time Measurement\n"); + + if (verbose < 2) + return; + + if (!config_fetch(d, where + 4, 8)) + { + printf("\t\t\n"); + return; + } + + buff = get_conf_long(d, where + 4); + printf("\t\tPTMCap: "); + printf("Requester:%c Responder:%c Root:%c\n", + FLAG(buff, 0x1), + FLAG(buff, 0x2), + FLAG(buff, 0x4)); + + clock = BITS(buff, 8, 8); + printf("\t\tPTMClockGranularity: "); + switch (clock) + { + case 0x00: + printf("Unimplemented\n"); + break; + case 0xff: + printf("Greater than 254ns\n"); + break; + default: + printf("%huns\n", clock); + } + + buff = get_conf_long(d, where + 8); + printf("\t\tPTMControl: "); + printf("Enabled:%c RootSelected:%c\n", + FLAG(buff, 0x1), + FLAG(buff, 0x2)); + + clock = BITS(buff, 8, 8); + printf("\t\tPTMEffectiveGranularity: "); + switch (clock) + { + case 0x00: + printf("Unknown\n"); + break; + case 0xff: + printf("Greater than 254ns\n"); + break; + default: + printf("%huns\n", clock); } } void -show_ext_caps(struct device *d) +show_ext_caps(struct device *d, int type) { int where = 0x100; char been_there[0x1000]; @@ -609,7 +738,7 @@ show_ext_caps(struct device *d) switch (id) { case PCI_EXT_CAP_ID_AER: - cap_aer(d, where); + cap_aer(d, where, type); break; case PCI_EXT_CAP_ID_DPC: cap_dpc(d, where); @@ -669,6 +798,9 @@ show_ext_caps(struct device *d) case PCI_EXT_CAP_ID_L1PM: cap_l1pm(d, where); break; + case PCI_EXT_CAP_ID_PTM: + cap_ptm(d, where); + break; default: printf("#%02x\n", id); break;