Module Name: src
Committed By: msaitoh
Date: Sun Apr 21 23:54:44 UTC 2013
Modified Files:
src/sys/dev/pci: pci_subr.c
Log Message:
- Print PCIe 2.0 or higher capability registers.
- Print Link related registers only if the device is PCI Express Endpoint,
Legacy PCI Express Endpoint or Root Port of PCI Express Root Complex.
- Don't print Root related registers if the device is Root Complex
Integrated Endpoint and print if the device is Root Complex Event Collector.
- Not Gb/s but GT/s.
To generate a diff of this commit:
cvs rdiff -u -r1.104 -r1.105 src/sys/dev/pci/pci_subr.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/pci_subr.c
diff -u src/sys/dev/pci/pci_subr.c:1.104 src/sys/dev/pci/pci_subr.c:1.105
--- src/sys/dev/pci/pci_subr.c:1.104 Sun Apr 21 23:46:06 2013
+++ src/sys/dev/pci/pci_subr.c Sun Apr 21 23:54:44 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_subr.c,v 1.104 2013/04/21 23:46:06 msaitoh Exp $ */
+/* $NetBSD: pci_subr.c,v 1.105 2013/04/21 23:54:44 msaitoh Exp $ */
/*
* Copyright (c) 1997 Zubin D. Dittia. All rights reserved.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.104 2013/04/21 23:46:06 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.105 2013/04/21 23:54:44 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_pci.h"
@@ -857,32 +857,64 @@ pci_print_pcie_L1_latency(uint32_t val)
}
static void
+pci_print_pcie_compl_timeout(uint32_t val)
+{
+
+ switch (val) {
+ case 0x0:
+ printf("50us to 50ms\n");
+ break;
+ case 0x5:
+ printf("16ms to 55ms\n");
+ break;
+ case 0x6:
+ printf("65ms to 210ms\n");
+ break;
+ case 0x9:
+ printf("260ms to 900ms\n");
+ break;
+ case 0xa:
+ printf("1s to 3.5s\n");
+ break;
+ default:
+ printf("unknown %u value\n", val);
+ break;
+ }
+}
+
+static void
pci_conf_print_pcie_cap(const pcireg_t *regs, int capoff)
{
pcireg_t reg; /* for each register */
pcireg_t val; /* for each bitfield */
+ bool check_link = false;
bool check_slot = false;
bool check_rootport = false;
+ unsigned int pciever;
static const char * const linkspeeds[] = {"2.5", "5.0", "8.0"};
+ int i;
printf("\n PCI Express Capabilities Register\n");
/* Capability Register */
reg = regs[o2i(capoff)];
printf(" Capability register: %04x\n", reg >> 16);
- printf(" Capability version: %x\n",
- (unsigned int)((reg & 0x000f0000) >> 16));
+ pciever = (unsigned int)((reg & 0x000f0000) >> 16);
+ printf(" Capability version: %u\n", pciever);
printf(" Device type: ");
switch ((reg & 0x00f00000) >> 20) {
case 0x0:
printf("PCI Express Endpoint device\n");
+ check_link = true;
break;
case 0x1:
printf("Legacy PCI Express Endpoint device\n");
+ check_link = true;
break;
case 0x4:
printf("Root Port of PCI Express Root Complex\n");
+ check_link = true;
check_slot = true;
- check_rootport = true; /* XXX right? */
+ check_rootport = true;
break;
case 0x5:
printf("Upstream Port of PCI Express Switch\n");
@@ -890,7 +922,7 @@ pci_conf_print_pcie_cap(const pcireg_t *
case 0x6:
printf("Downstream Port of PCI Express Switch\n");
check_slot = true;
- check_rootport = true; /* XXX right? */
+ check_rootport = true;
break;
case 0x7:
printf("PCI Express to PCI/PCI-X Bridge\n");
@@ -900,9 +932,9 @@ pci_conf_print_pcie_cap(const pcireg_t *
break;
case 0x9:
printf("Root Complex Integrated Endpoint\n");
- check_rootport = true; /* XXX right? */
break;
case 0xa:
+ check_rootport = true;
printf("Root Complex Event Collector\n");
break;
default:
@@ -997,103 +1029,104 @@ pci_conf_print_pcie_cap(const pcireg_t *
printf(" Transaction Pending: %s\n",
(reg & PCIE_DCSR_TRANSACTION_PND) != 0 ? "on" : "off");
- /* Link Capability Register */
- reg = regs[o2i(capoff + PCIE_LCAP)];
- printf(" Link Capabilities Register: 0x%08x\n", reg);
- printf(" Maximum Link Speed: ");
- val = reg & PCIE_LCAP_MAX_SPEED;
- if (val < 1 || val > 3) {
- printf("unknown %u value\n", val);
- } else {
- printf("%sGb/s\n", linkspeeds[val - 1]);
- }
- printf(" Maximum Link Width: x%u lanes\n",
- (unsigned int)(reg & PCIE_LCAP_MAX_WIDTH) >> 4);
- printf(" Active State PM Support: ");
- val = (reg & PCIE_LCAP_ASPM) >> 10;
- switch (val) {
- case 0x1:
- printf("L0s Entry supported\n");
- break;
- case 0x3:
- printf("L0s and L1 supported\n");
- break;
- default:
- printf("Reserved value\n");
- break;
- }
- printf(" L0 Exit Latency: ");
- pci_print_pcie_L0s_latency((reg & PCIE_LCAP_L0S_EXIT) >> 12);
- printf(" L1 Exit Latency: ");
- pci_print_pcie_L1_latency((reg & PCIE_LCAP_L1_EXIT) >> 15);
- printf(" Port Number: %u\n", reg >> 24);
-
- /* Link Control Register */
- reg = regs[o2i(capoff + PCIE_LCSR)];
- printf(" Link Control Register: 0x%04x\n", reg & 0xffff);
- printf(" Active State PM Control: ");
- val = reg & (PCIE_LCSR_ASPM_L1 | PCIE_LCSR_ASPM_L0S);
- switch (val) {
- case 0:
- printf("disabled\n");
- break;
- case 1:
- printf("L0s Entry Enabled\n");
- break;
- case 2:
- printf("L1 Entry Enabled\n");
- break;
- case 3:
- printf("L0s and L1 Entry Enabled\n");
- break;
- }
- printf(" Read Completion Boundary Control: %dbyte\n",
- (reg & PCIE_LCSR_RCB) != 0 ? 128 : 64);
- printf(" Link Disable: %s\n",
- (reg & PCIE_LCSR_LINK_DIS) != 0 ? "on" : "off");
- printf(" Retrain Link: %s\n",
- (reg & PCIE_LCSR_RETRAIN) != 0 ? "on" : "off");
- printf(" Common Clock Configuration: %s\n",
- (reg & PCIE_LCSR_COMCLKCFG) != 0 ? "on" : "off");
- printf(" Extended Synch: %s\n",
- (reg & PCIE_LCSR_EXTNDSYNC) != 0 ? "on" : "off");
- printf(" Enable Clock Power Management: %s\n",
- (reg & PCIE_LCSR_ENCLKPM) != 0 ? "on" : "off");
- printf(" Hardware Autonomous Width Disable: %s\n",
- (reg & PCIE_LCSR_HAWD) != 0 ? "on" : "off");
- printf(" Link Bandwidth Management Interrupt Enable: %s\n",
- (reg & PCIE_LCSR_LBMIE) != 0 ? "on" : "off");
- printf(" Link Autonomous Bandwidth Interrupt Enable: %s\n",
- (reg & PCIE_LCSR_LABIE) != 0 ? "on" : "off");
-
- /* Link Status Register */
- reg = regs[o2i(capoff + PCIE_LCSR)];
- printf(" Link Status Register: 0x%04x\n", reg >> 16);
- printf(" Negotiated Link Speed: ");
- if (((reg >> 16) & 0x000f) < 1 ||
- ((reg >> 16) & 0x000f) > 3) {
- printf("unknown %u value\n",
- (unsigned int)(reg & PCIE_LCSR_LINKSPEED) >> 16);
- } else {
- printf("%sGb/s\n",
- linkspeeds[((reg & PCIE_LCSR_LINKSPEED) >> 16) - 1]);
+ if (check_link) {
+ /* Link Capability Register */
+ reg = regs[o2i(capoff + PCIE_LCAP)];
+ printf(" Link Capabilities Register: 0x%08x\n", reg);
+ printf(" Maximum Link Speed: ");
+ val = reg & PCIE_LCAP_MAX_SPEED;
+ if (val < 1 || val > 3) {
+ printf("unknown %u value\n", val);
+ } else {
+ printf("%sGT/s\n", linkspeeds[val - 1]);
+ }
+ printf(" Maximum Link Width: x%u lanes\n",
+ (unsigned int)(reg & PCIE_LCAP_MAX_WIDTH) >> 4);
+ printf(" Active State PM Support: ");
+ val = (reg & PCIE_LCAP_ASPM) >> 10;
+ switch (val) {
+ case 0x1:
+ printf("L0s Entry supported\n");
+ break;
+ case 0x3:
+ printf("L0s and L1 supported\n");
+ break;
+ default:
+ printf("Reserved value\n");
+ break;
+ }
+ printf(" L0 Exit Latency: ");
+ pci_print_pcie_L0s_latency((reg & PCIE_LCAP_L0S_EXIT) >> 12);
+ printf(" L1 Exit Latency: ");
+ pci_print_pcie_L1_latency((reg & PCIE_LCAP_L1_EXIT) >> 15);
+ printf(" Port Number: %u\n", reg >> 24);
+
+ /* Link Control Register */
+ reg = regs[o2i(capoff + PCIE_LCSR)];
+ printf(" Link Control Register: 0x%04x\n", reg & 0xffff);
+ printf(" Active State PM Control: ");
+ val = reg & (PCIE_LCSR_ASPM_L1 | PCIE_LCSR_ASPM_L0S);
+ switch (val) {
+ case 0:
+ printf("disabled\n");
+ break;
+ case 1:
+ printf("L0s Entry Enabled\n");
+ break;
+ case 2:
+ printf("L1 Entry Enabled\n");
+ break;
+ case 3:
+ printf("L0s and L1 Entry Enabled\n");
+ break;
+ }
+ printf(" Read Completion Boundary Control: %dbyte\n",
+ (reg & PCIE_LCSR_RCB) != 0 ? 128 : 64);
+ printf(" Link Disable: %s\n",
+ (reg & PCIE_LCSR_LINK_DIS) != 0 ? "on" : "off");
+ printf(" Retrain Link: %s\n",
+ (reg & PCIE_LCSR_RETRAIN) != 0 ? "on" : "off");
+ printf(" Common Clock Configuration: %s\n",
+ (reg & PCIE_LCSR_COMCLKCFG) != 0 ? "on" : "off");
+ printf(" Extended Synch: %s\n",
+ (reg & PCIE_LCSR_EXTNDSYNC) != 0 ? "on" : "off");
+ printf(" Enable Clock Power Management: %s\n",
+ (reg & PCIE_LCSR_ENCLKPM) != 0 ? "on" : "off");
+ printf(" Hardware Autonomous Width Disable: %s\n",
+ (reg & PCIE_LCSR_HAWD) != 0 ? "on" : "off");
+ printf(" Link Bandwidth Management Interrupt Enable: %s\n",
+ (reg & PCIE_LCSR_LBMIE) != 0 ? "on" : "off");
+ printf(" Link Autonomous Bandwidth Interrupt Enable: %s\n",
+ (reg & PCIE_LCSR_LABIE) != 0 ? "on" : "off");
+
+ /* Link Status Register */
+ reg = regs[o2i(capoff + PCIE_LCSR)];
+ printf(" Link Status Register: 0x%04x\n", reg >> 16);
+ printf(" Negotiated Link Speed: ");
+ if (((reg >> 16) & 0x000f) < 1 ||
+ ((reg >> 16) & 0x000f) > 3) {
+ printf("unknown %u value\n",
+ (unsigned int)(reg & PCIE_LCSR_LINKSPEED) >> 16);
+ } else {
+ printf("%sGb/s\n",
+ linkspeeds[((reg & PCIE_LCSR_LINKSPEED) >> 16) - 1]);
+ }
+ printf(" Negotiated Link Width: x%u lanes\n",
+ (reg >> 20) & 0x003f);
+ printf(" Training Error: %s\n",
+ (reg & PCIE_LCSR_LINKTRAIN_ERR) != 0 ? "on" : "off");
+ printf(" Link Training: %s\n",
+ (reg & PCIE_LCSR_LINKTRAIN) != 0 ? "on" : "off");
+ printf(" Slot Clock Configuration: %s\n",
+ (reg & PCIE_LCSR_SLOTCLKCFG) != 0 ? "on" : "off");
+ printf(" Data Link Layer Link Active: %s\n",
+ (reg & PCIE_LCSR_DLACTIVE) != 0 ? "on" : "off");
+ printf(" Link Bandwidth Management Status: %s\n",
+ (reg & PCIE_LCSR_LINK_BW_MGMT) != 0 ? "on" : "off");
+ printf(" Link Autonomous Bandwidth Status: %s\n",
+ (reg & PCIE_LCSR_LINK_AUTO_BW) != 0 ? "on" : "off");
}
- printf(" Negotiated Link Width: x%u lanes\n",
- (reg >> 20) & 0x003f);
- printf(" Training Error: %s\n",
- (reg & PCIE_LCSR_LINKTRAIN_ERR) != 0 ? "on" : "off");
- printf(" Link Training: %s\n",
- (reg & PCIE_LCSR_LINKTRAIN) != 0 ? "on" : "off");
- printf(" Slot Clock Configuration: %s\n",
- (reg & PCIE_LCSR_SLOTCLKCFG) != 0 ? "on" : "off");
- printf(" Data Link Layer Link Active: %s\n",
- (reg & PCIE_LCSR_DLACTIVE) != 0 ? "on" : "off");
- printf(" Link Bandwidth Management Status: %s\n",
- (reg & PCIE_LCSR_LINK_BW_MGMT) != 0 ? "on" : "off");
- printf(" Link Autonomous Bandwidth Status: %s\n",
- (reg & PCIE_LCSR_LINK_AUTO_BW) != 0 ? "on" : "off");
- /* XXX Is this check right? */
if (check_slot == true) {
/* Slot Capability Register */
reg = regs[o2i(capoff + PCIE_SLCAP)];
@@ -1200,7 +1233,6 @@ pci_conf_print_pcie_cap(const pcireg_t *
printf(" Data Link Layer State Changed\n");
}
- /* XXX Is this check right? */
if (check_rootport == true) {
/* Root Control Register */
reg = regs[o2i(capoff + PCIE_RCR)];
@@ -1228,6 +1260,148 @@ pci_conf_print_pcie_cap(const pcireg_t *
if ((reg & PCIE_RSR_PME_PEND) != 0)
printf(" another PME is pending\n");
}
+
+ /* PCIe DW9 to DW14 is for PCIe 2.0 and newer */
+ if (pciever < 2)
+ return;
+
+ /* Device Capabilities 2 */
+ reg = regs[o2i(capoff + PCIE_DCAP2)];
+ printf(" Device Capabilities 2: 0x%08x\n", reg);
+ printf(" Completion Timeout Ranges Supported: %u \n",
+ (unsigned int)(reg & PCIE_DCAP2_COMPT_RANGE));
+ printf(" Completion Timeout Disable Supported: %s\n",
+ (reg & PCIE_DCAP2_COMPT_DIS) != 0 ? "yes" : "no");
+ printf(" ARI Forwarding Supported: %s\n",
+ (reg & PCIE_DCAP2_ARI_FWD) != 0 ? "yes" : "no");
+ printf(" AtomicOp Routing Supported: %s\n",
+ (reg & PCIE_DCAP2_ATOM_ROUT) != 0 ? "yes" : "no");
+ printf(" 32bit AtomicOp Completer Supported: %s\n",
+ (reg & PCIE_DCAP2_32ATOM) != 0 ? "yes" : "no");
+ printf(" 64bit AtomicOp Completer Supported: %s\n",
+ (reg & PCIE_DCAP2_64ATOM) != 0 ? "yes" : "no");
+ printf(" 128-bit CAS Completer Supported: %s\n",
+ (reg & PCIE_DCAP2_128CAS) != 0 ? "yes" : "no");
+ printf(" No RO-enabled PR-PR passing: %s\n",
+ (reg & PCIE_DCAP2_NO_ROPR_PASS) != 0 ? "yes" : "no");
+ printf(" LTR Mechanism Supported: %s\n",
+ (reg & PCIE_DCAP2_LTR_MEC) != 0 ? "yes" : "no");
+ printf(" TPH Completer Supported: %u\n",
+ (unsigned int)(reg & PCIE_DCAP2_TPH_COMP) >> 12);
+ printf(" OBFF Supported: ");
+ switch ((reg & PCIE_DCAP2_OBFF) >> 18) {
+ case 0x0:
+ printf("Not supported\n");
+ break;
+ case 0x1:
+ printf("Message only\n");
+ break;
+ case 0x2:
+ printf("WAKE# only\n");
+ break;
+ case 0x3:
+ printf("Both\n");
+ break;
+ }
+ printf(" Extended Fmt Field Supported: %s\n",
+ (reg & PCIE_DCAP2_EXTFMT_FLD) != 0 ? "yes" : "no");
+ printf(" End-End TLP Prefix Supported: %s\n",
+ (reg & PCIE_DCAP2_EETLP_PREF) != 0 ? "yes" : "no");
+ printf(" Max End-End TLP Prefixes: %u\n",
+ (unsigned int)(reg & PCIE_DCAP2_MAX_EETLP) >> 22);
+
+ /* Device Control 2 */
+ reg = regs[o2i(capoff + PCIE_DCSR2)];
+ printf(" Device Control 2: 0x%04x\n", reg & 0xffff);
+ printf(" Completion Timeout Value: ");
+ pci_print_pcie_compl_timeout(reg & PCIE_DCSR2_COMPT_VAL);
+ if ((reg & PCIE_DCSR2_COMPT_DIS) != 0)
+ printf(" Completion Timeout Disabled\n");
+ if ((reg & PCIE_DCSR2_ARI_FWD) != 0)
+ printf(" ARI Forwarding Enabled\n");
+ if ((reg & PCIE_DCSR2_ATOM_REQ) != 0)
+ printf(" AtomicOp Rquester Enabled\n");
+ if ((reg & PCIE_DCSR2_ATOM_EBLK) != 0)
+ printf(" AtomicOp Egress Blocking on\n");
+ if ((reg & PCIE_DCSR2_IDO_REQ) != 0)
+ printf(" IDO Request Enabled\n");
+ if ((reg & PCIE_DCSR2_IDO_COMP) != 0)
+ printf(" IDO Completion Enabled\n");
+ if ((reg & PCIE_DCSR2_LTR_MEC) != 0)
+ printf(" LTR Mechanism Enabled\n");
+ printf(" OBFF: ");
+ switch ((reg & PCIE_DCSR2_OBFF_EN) >> 13) {
+ case 0x0:
+ printf("Disabled\n");
+ break;
+ case 0x1:
+ printf("Enabled with Message Signaling Variation A\n");
+ break;
+ case 0x2:
+ printf("Enabled with Message Signaling Variation B\n");
+ break;
+ case 0x3:
+ printf("Enabled using WAKE# signaling\n");
+ break;
+ }
+ if ((reg & PCIE_DCSR2_EETLP) != 0)
+ printf(" End-End TLP Prefix Blocking on\n");
+
+ if (check_link) {
+ /* Link Capability 2 */
+ reg = regs[o2i(capoff + PCIE_LCAP2)];
+ printf(" Link Capabilities 2: 0x%08x\n", reg);
+ val = (reg & PCIE_LCAP2_SUP_LNKSV) >> 1;
+ printf(" Supported Link Speed Vector:");
+ for (i = 0; i <= 2; i++) {
+ if (((val >> i) & 0x01) != 0)
+ printf(" %sGT/s", linkspeeds[i]);
+ }
+ printf("\n");
+
+ /* Link Control 2 */
+ reg = regs[o2i(capoff + PCIE_LCSR2)];
+ printf(" Link Control 2: 0x%04x\n", reg & 0xffff);
+ printf(" Target Link Speed: ");
+ val = reg & PCIE_LCSR2_TGT_LSPEED;
+ if (val < 1 || val > 3) {
+ printf("unknown %u value\n", val);
+ } else {
+ printf("%sGT/s\n", linkspeeds[val - 1]);
+ }
+ if ((reg & PCIE_LCSR2_ENT_COMPL) != 0)
+ printf(" Enter Compliance Enabled\n");
+ if ((reg & PCIE_LCSR2_HW_AS_DIS) != 0)
+ printf(" HW Autonomous Speed Disabled\n");
+ if ((reg & PCIE_LCSR2_SEL_DEEMP) != 0)
+ printf(" Selectable De-emphasis\n");
+ printf(" Transmit Margin: %u\n",
+ (unsigned int)(reg & PCIE_LCSR2_TX_MARGIN) >> 7);
+ if ((reg & PCIE_LCSR2_EN_MCOMP) != 0)
+ printf(" Enter Modified Compliance\n");
+ if ((reg & PCIE_LCSR2_COMP_SOS) != 0)
+ printf(" Compliance SOS\n");
+ printf(" Compliance Present/De-emphasis: %u\n",
+ (unsigned int)(reg & PCIE_LCSR2_COMP_DEEMP) >> 12);
+
+ /* Link Status 2 */
+ if ((reg & PCIE_LCSR2_DEEMP_LVL) != 0)
+ printf(" Current De-emphasis Level\n");
+ if ((reg & PCIE_LCSR2_EQ_COMPL) != 0)
+ printf(" Equalization Complete\n");
+ if ((reg & PCIE_LCSR2_EQP1_SUC) != 0)
+ printf(" Equalization Phase 1 Successful\n");
+ if ((reg & PCIE_LCSR2_EQP2_SUC) != 0)
+ printf(" Equalization Phase 2 Successful\n");
+ if ((reg & PCIE_LCSR2_EQP3_SUC) != 0)
+ printf(" Equalization Phase 3 Successful\n");
+ if ((reg & PCIE_LCSR2_LNKEQ_REQ) != 0)
+ printf(" Link Equalization Request\n");
+ }
+
+ /* Slot Capability 2 */
+ /* Slot Control 2 */
+ /* Slot Status 2 */
}
static const char *