[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