[Pdbg] [PATCH v2 3/3] Add fircheck support

Balbir Singh bsingharora at gmail.com
Fri May 11 15:43:07 AEST 2018


The device tree supports basic understanding of chiplets.
On fircheck we iterate through all ibm,power9-chiplet nodes
and compare their masks from what with a value obtained
via multicast scom to get all top level FIRs

TODOs:

1. Differentiate between recoverable scoms and checkstops
2. Do deeper analysis of the root cause of the checkstop
   (longer term)

This patch also converts for_each_target to an exported
routine, we can avoid this by moving all the code from
libpdbg/fir.c to src/main.c, but the separation might
be a good thing in the long term

Sample output:

p1: FIR bit set for chiplet n3
p0: FIR bit set for chiplet chiplet at 25000000

I don't like chiplet at 25000000 as the name, but that's an
independent fix to follow

Signed-off-by: Balbir Singh <bsingharora at gmail.com>
---
 Makefile.am   |   3 +-
 libpdbg/fir.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/main.c    |  17 ++++++++--
 3 files changed, 118 insertions(+), 4 deletions(-)
 create mode 100644 libpdbg/fir.c

diff --git a/Makefile.am b/Makefile.am
index c6668d8..eff8dba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -52,7 +52,8 @@ libpdbg_la_SOURCES = \
 	libpdbg/adu.c \
 	libpdbg/device.c \
 	libpdbg/target.c \
-	libpdbg/htm.c
+	libpdbg/htm.c	\
+	libpdbg/fir.c
 
 M4_V = $(M4_V_$(V))
 M4_V_ = $(M4_V_$(AM_DEFAULT_VERBOSITY))
diff --git a/libpdbg/fir.c b/libpdbg/fir.c
new file mode 100644
index 0000000..2342037
--- /dev/null
+++ b/libpdbg/fir.c
@@ -0,0 +1,102 @@
+/* Copyright 2018 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "operations.h"
+#include "bitutils.h"
+#include "target.h"
+#include "device.h"
+
+static uint64_t global_mc_fir_addr;
+
+extern int for_each_target(char *class, int (*cb)(struct pdbg_target *, uint32_t, uint64_t *, uint64_t *),
+				uint64_t *arg1, uint64_t *arg2);
+
+static int getfir(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *ignored)
+{
+	int rc;
+	uint64_t value;
+	struct pdbg_target *dn;
+	uint32_t i;
+
+	rc = pib_read(target, *addr, &value);
+	if (value == 0)
+		printf("%s%d: No checkstop detected\n", "p", index);
+
+	dt_for_each_compatible(dt_root, dn, "ibm,power9-chiplet") {
+		i = dt_prop_get_u32(dn, "index");
+		if (!i)
+			continue; /* we should abort really */
+		if (value & PPC_BIT(i)) {
+			printf("%s%d: FIR bit set for chiplet %s\n", "p", index, dn->dn_name);
+			value &= (value - 1);
+		}
+	}
+
+	return rc;
+}
+
+/*
+ * Print a summary of the FIR check errors.
+ *
+ * NOTE: The current implementation looks at the top most bits
+ * there is much more to do. We need to dig deeper and look at
+ * recoverable and xstop bits and in the future FFDC bits as
+ * well
+ */
+int handle_fircheck(int optind, int argc, char *argv[])
+{
+	struct pdbg_target *global_fir_dn;
+	int rc;
+
+	global_fir_dn = dt_find_by_name(dt_root, "global_fir");
+	if (!global_fir_dn) {
+		rc = -1;
+		PR_ERROR("Failed to find global multicast scom fir address"
+			 "Please check the device tree bindings\n");
+		goto out;
+	}
+
+	if (!global_mc_fir_addr)
+		global_mc_fir_addr = dt_get_address(global_fir_dn, 0, NULL);
+	if (!global_mc_fir_addr) {
+		rc = -1;
+		PR_ERROR("Failed to find global multicast scom fir address"
+			 "Please check the device tree bindings\n");
+		goto out;
+	}
+
+	rc = for_each_target("pib", getfir, &global_mc_fir_addr, NULL);
+	if (rc) {
+		PR_ERROR("Failed to read value from multicast scom"
+			 "address %llx\n", global_mc_fir_addr);
+		goto out;
+	}
+
+out:
+	return !rc;
+}
+
diff --git a/src/main.c b/src/main.c
index a121972..6d38c93 100644
--- a/src/main.c
+++ b/src/main.c
@@ -64,6 +64,7 @@ static int *chipsel[MAX_PROCESSORS][MAX_CHIPS];
 static int threadsel[MAX_PROCESSORS][MAX_CHIPS][MAX_THREADS];
 
 static int handle_probe(int optind, int argc, char *argv[]);
+extern int handle_fircheck(int optind, int argc, char *argv[]);
 
 static struct {
 	const char *name;
@@ -100,6 +101,7 @@ static struct {
 	{ "htm_analyse", "", "[derepcated use 'htm nest analyse'] Stop and dump buffer to file", &run_htm_analyse },
 	{ "htm", "(core | nest) (start | stop | status | reset | dump | trace | analyse", "Hardware Trace Macro", &run_htm },
 	{ "probe", "", "", &handle_probe },
+	{ "fircheck", "", "Get information about triggered FIR bits", &handle_fircheck },
 };
 
 static void print_usage(char *pname)
@@ -481,10 +483,19 @@ void print_target(struct pdbg_target *target, int level)
 		else if (!strcmp(pdbg_target_class_name(target), "thread"))
 			c = 't';
 
-		if (c)
-			printf("%c%d: %s\n", c, pdbg_target_index(target), pdbg_target_name(target));
-		else
+		if (c) {
+			/*
+			 * For power9 the core chiplets are indexed from 32. Find a better way
+			 * to do this
+			 */
+			if (!strncmp(target->compatible, "ibm,power9-core", strlen(target->compatible))) {
+				printf("%c%d: %s\n", c, pdbg_target_index(target)-32, pdbg_target_name(target));
+			} else {
+				printf("%c%d: %s\n", c, pdbg_target_index(target), pdbg_target_name(target));
+			}
+		} else {
 			printf("%s\n", pdbg_target_name(target));
+		}
 	}
 
 	pdbg_for_each_child_target(target, next) {
-- 
2.13.6



More information about the Pdbg mailing list