diff mbox

phb4: Add link training trace mode

Message ID 20170724003727.17077-1-mikey@neuling.org
State Accepted
Headers show

Commit Message

Michael Neuling July 24, 2017, 12:37 a.m. UTC
Add a mode to PHB4 to trace training process closely. This activates
as soon as PERST is deasserted and produces human readable output of
the process.

This may increase training times since it duplicates some of the
training code.  This code has it's own simple checks for fence and
timeout but will fall through to the default training code once done.

Output produced, looks like the "TRACE:" lines below:

  [    3.410799664,7] PHB#0001[0:1]: FRESET: Starts
  [    3.410802000,7] PHB#0001[0:1]: FRESET: Prepare for link down
  [    3.410806624,7] PHB#0001[0:1]: FRESET: Assert skipped
  [    3.410808848,7] PHB#0001[0:1]: FRESET: Deassert
  [    3.410812176,3] PHB#0001[0:1]: TRACE: 0x0000000101000000  0ms
  [    3.417170176,3] PHB#0001[0:1]: TRACE: 0x0000100101000000 12ms presence
  [    3.436289104,3] PHB#0001[0:1]: TRACE: 0x0000180101000000 49ms training
  [    3.436373312,3] PHB#0001[0:1]: TRACE: 0x00001d0811000000 49ms trained
  [    3.436420752,3] PHB#0001[0:1]: TRACE: Link trained.
  [    3.436967856,7] PHB#0001[0:1]: LINK: Start polling
  [    3.437482240,7] PHB#0001[0:1]: LINK: Electrical link detected
  [    3.437996864,7] PHB#0001[0:1]: LINK: Link is up
  [    4.438000048,7] PHB#0001[0:1]: LINK: Link is stable

Enabled via nvram using:
  nvram -p ibm,skiboot --update-config pci-tracing=true

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 hw/phb4.c           | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/phb4-regs.h |  1 +
 2 files changed, 57 insertions(+)

Comments

Stewart Smith July 25, 2017, 8:26 a.m. UTC | #1
Michael Neuling <mikey@neuling.org> writes:
> Add a mode to PHB4 to trace training process closely. This activates
> as soon as PERST is deasserted and produces human readable output of
> the process.
>
> This may increase training times since it duplicates some of the
> training code.  This code has it's own simple checks for fence and
> timeout but will fall through to the default training code once done.
>
> Output produced, looks like the "TRACE:" lines below:
>
>   [    3.410799664,7] PHB#0001[0:1]: FRESET: Starts
>   [    3.410802000,7] PHB#0001[0:1]: FRESET: Prepare for link down
>   [    3.410806624,7] PHB#0001[0:1]: FRESET: Assert skipped
>   [    3.410808848,7] PHB#0001[0:1]: FRESET: Deassert
>   [    3.410812176,3] PHB#0001[0:1]: TRACE: 0x0000000101000000  0ms
>   [    3.417170176,3] PHB#0001[0:1]: TRACE: 0x0000100101000000 12ms presence
>   [    3.436289104,3] PHB#0001[0:1]: TRACE: 0x0000180101000000 49ms training
>   [    3.436373312,3] PHB#0001[0:1]: TRACE: 0x00001d0811000000 49ms trained
>   [    3.436420752,3] PHB#0001[0:1]: TRACE: Link trained.
>   [    3.436967856,7] PHB#0001[0:1]: LINK: Start polling
>   [    3.437482240,7] PHB#0001[0:1]: LINK: Electrical link detected
>   [    3.437996864,7] PHB#0001[0:1]: LINK: Link is up
>   [    4.438000048,7] PHB#0001[0:1]: LINK: Link is stable
>
> Enabled via nvram using:
>   nvram -p ibm,skiboot --update-config pci-tracing=true
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>

Merged to master as of b4c69f3126ecbe85f415d8a6aa06efab80653cbc
diff mbox

Patch

diff --git a/hw/phb4.c b/hw/phb4.c
index 5c9b822acc..133657fe6e 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -138,6 +138,7 @@  static void phb4_init_hw(struct phb4 *p, bool first_init);
 #endif
 
 static bool verbose_eeh;
+static bool pci_tracing;
 
 enum capi_dma_tvt {
 	CAPI_DMA_TVT0,
@@ -2285,6 +2286,58 @@  static int64_t phb4_retry_state(struct pci_slot *slot)
 	return pci_slot_set_sm_timeout(slot, msecs_to_tb(1));
 }
 
+static void phb4_train_info(struct phb4 *p, uint64_t reg, unsigned long time)
+{
+	char s[80];
+
+	snprintf(s, sizeof(s), "TRACE: 0x%016llx % 2lims",
+		 reg, tb_to_msecs(time));
+
+	if (reg & PHB_PCIE_DLP_TL_LINKACT)
+		snprintf(s, sizeof(s), "%s trained", s);
+	else if (reg & PHB_PCIE_DLP_TRAINING)
+		snprintf(s, sizeof(s), "%s training", s);
+	else if (reg & PHB_PCIE_DLP_INBAND_PRESENCE)
+		snprintf(s, sizeof(s), "%s presence", s);
+
+	PHBERR(p, "%s\n", s);
+}
+
+/*
+ * This is a trace function to watch what's happening duing pcie link
+ * training.  If any errors are detected it simply returns so the
+ * normal code can deal with it.
+ */
+static void phb4_training_trace(struct phb4 *p)
+{
+	uint64_t reg, reglast = -1;
+	unsigned long now, start = mftb();
+
+	if (!pci_tracing)
+		return;
+
+	while(1) {
+		now = mftb();
+		reg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);
+		if (reg != reglast)
+			phb4_train_info(p, reg, now - start);
+		reglast = reg;
+
+		if (!phb4_check_reg(p, reg)) {
+			PHBERR(p, "TRACE: PHB fence waiting link.\n");
+			break;
+		}
+		if (reg & PHB_PCIE_DLP_TL_LINKACT) {
+			PHBERR(p, "TRACE: Link trained.\n");
+			break;
+		}
+		if ((now - start) > secs_to_tb(3)) {
+			PHBERR(p, "TRACE: Timeout waiting for link up.\n");
+			break;
+		}
+	}
+}
+
 static int64_t phb4_poll_link(struct pci_slot *slot)
 {
 	struct phb4 *p = phb_to_phb4(slot->phb);
@@ -2491,6 +2544,8 @@  static int64_t phb4_freset(struct pci_slot *slot)
 		pci_slot_set_state(slot,
 			PHB4_SLOT_FRESET_DEASSERT_DELAY);
 
+		phb4_training_trace(p);
+
 		/* Move on to link poll right away */
 		return pci_slot_set_sm_timeout(slot, msecs_to_tb(1));
 	case PHB4_SLOT_FRESET_DEASSERT_DELAY:
@@ -4710,6 +4765,7 @@  void probe_phb4(void)
 	if (verbose_eeh)
 		prlog(PR_INFO, "PHB4: Verbose EEH enabled\n");
 
+	pci_tracing = nvram_query_eq("pci-tracing", "true");
 	/* Look for PBCQ XSCOM nodes */
 	dt_for_each_compatible(dt_root, np, "ibm,power9-pbcq")
 		phb4_probe_pbcq(np);
diff --git a/include/phb4-regs.h b/include/phb4-regs.h
index 14e93511e5..932da5ba43 100644
--- a/include/phb4-regs.h
+++ b/include/phb4-regs.h
@@ -284,6 +284,7 @@ 
 #define PHB_PCIE_DLP_TRAIN_CTL		0x1A40
 #define	  PHB_PCIE_DLP_TL_LINKACT	PPC_BIT(23)
 #define   PHB_PCIE_DLP_DL_PGRESET	PPC_BIT(22)
+#define   PHB_PCIE_DLP_TRAINING		PPC_BIT(20)
 #define   PHB_PCIE_DLP_INBAND_PRESENCE  PPC_BIT(19)
 
 #define PHB_PCIE_DLP_ERRLOG1		0x1AA0