[Pdbg] [PATCH RFC 3/4] pdbg: add timeer facility TB error injections.

Mahesh Salgaonkar mahesh at linux.ibm.com
Mon May 11 18:41:38 AEST 2020


# ./pdbg -p0 -c3 -t3 inject
Usage: pdbg inject <component> <error>
 <component>:
    ?          Show component list
    tb
# ./pdbg -p0 -c3 -t3 inject tb ?
Usage: pdbg inject tb <error>:
 <error>:
    ?               Show error list
    tfmr_parity     TFMR parity error
    hdec_parity     HDEC parity error
    tb_residue      TB parity/residue error
    purr_parity     PURR parity error
    spurr_parity    SPURR parity error
    dec_parity      DEC parity error

# ./pdbg -p0 -c1 -t3  inject tb dec_parity
p0:c1:t3: 0x20010a84 = 0x001e000000000000
#
# ./pdbg -p0 -c1,2  inject tb hdec_parity
p0:c1: 0x20010a84 = 0x0002000000000000
p0:c2: 0x20010a84 = 0x0002000000000000
#

Signed-off-by: Mahesh Salgaonkar <mahesh at linux.ibm.com>
---
 Makefile.am         |    3 +
 src/err_inject.c    |   46 +++++++++++++++++++++
 src/err_inject.h    |   43 +++++++++++++++++++
 src/timefac_error.c |  114 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 205 insertions(+), 1 deletion(-)
 create mode 100644 src/timefac_error.c

diff --git a/Makefile.am b/Makefile.am
index 05522cf..ed97505 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -122,7 +122,8 @@ pdbg_SOURCES = \
 	src/util.c \
 	src/util.h \
 	src/err_inject.c \
-	src/err_inject.h
+	src/err_inject.h \
+	src/timefac_error.c
 
 pdbg_CFLAGS = -I$(top_srcdir)/libpdbg -Wall -Werror -DGIT_SHA1=\"${GIT_SHA1}\" \
 	      $(ARCH_FLAGS)
diff --git a/src/err_inject.c b/src/err_inject.c
index ef6bc97..c059ef8 100644
--- a/src/err_inject.c
+++ b/src/err_inject.c
@@ -22,6 +22,7 @@
 
 #include <libpdbg.h>
 #include <ccan/list/list.h>
+#include <bitutils.h>
 
 #include "main.h"
 #include "optcmd.h"
@@ -162,9 +163,54 @@ static void inject_errors(char *component, char *error)
 	}
 }
 
+static char *target_short_path(struct pdbg_target *target)
+{
+	char result[255];
+	char *bufp = result;
+	int proc_index = -1, chip_index = -1, thread_index = -1;
+	int n = 0;
+
+	if (get_target_type(target) == TARGET_TYPE_THREAD) {
+		thread_index = pdbg_target_index(target);
+		target = pdbg_target_parent("core", target);
+	}
+	if (get_target_type(target) == TARGET_TYPE_CORE) {
+		chip_index = pdbg_target_index(target);
+		target = pdbg_target_parent("pib", target);
+	}
+	if (get_target_type(target) == TARGET_TYPE_PROC)
+		proc_index = pdbg_target_index(target);
+
+	if (proc_index >= 0)
+		n += sprintf(bufp + n, "p%d:", proc_index);
+	if (chip_index >= 0)
+		n += sprintf(bufp + n, "c%d:", chip_index);
+	if (thread_index >= 0)
+		n += sprintf(bufp + n, "t%d:", thread_index);
+
+	return strdup(result);
+}
+
+int target_inject_error(struct pdbg_target *target, uint32_t scom_addr,
+							uint64_t val)
+{
+	char *short_path;
+	int rc;
+
+	rc = pib_write(target, scom_addr, val);
+	if (rc)
+		return rc;
+
+	short_path = target_short_path(target);
+	printf("%s 0x%x = 0x%016llx\n", short_path, scom_addr, val);
+	free(short_path);
+	return 0;
+}
+
 static void error_inject_init(void)
 {
 	/* Call error inject init routines. */
+	timefac_err_init();
 }
 
 static int inject(char *component, char *error)
diff --git a/src/err_inject.h b/src/err_inject.h
index 76acee7..d295470 100644
--- a/src/err_inject.h
+++ b/src/err_inject.h
@@ -3,6 +3,12 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <libpdbg.h>
+
+/* Target types */
+#define TARGET_TYPE_PROC	1
+#define TARGET_TYPE_CORE	2
+#define TARGET_TYPE_THREAD	3
 
 typedef int (*inject_error_t)(struct pdbg_target *target, void *data);
 
@@ -17,4 +23,41 @@ typedef int (*inject_error_t)(struct pdbg_target *target, void *data);
  */
 extern int register_error_inject(char *component, char *error,
 			char *error_desc, inject_error_t func, void *data);
+
+/* Get target type */
+static inline int get_target_type(struct pdbg_target *target)
+{
+	const char *classname;
+
+	classname = pdbg_target_class_name(target);
+	if (!strcmp(classname, "pib"))
+		return TARGET_TYPE_PROC;
+
+	if (!strcmp(classname, "core"))
+		return TARGET_TYPE_CORE;
+
+	if (!strcmp(classname, "thread"))
+		return TARGET_TYPE_THREAD;
+
+	return 0;
+}
+
+/**
+ * @brief Inject an error on specified target using scom addr/value.
+ * @param[in] target     pdbg target where error to be injected.
+ * @param[in] scom_adddr SCOM address to use.
+ * @param[in] val        Value to set for a given scom address.
+ *
+ * This function uses pib_write() to write to scom address and on
+ * successfull injection it prints out target short path along with
+ * scom address and data written.
+ * e.g.
+ *	p0:c1:t3: 0x20010a84 = 0x001e000000000000
+ */
+int target_inject_error(struct pdbg_target *target, uint32_t scom_addr,
+							uint64_t val);
+
+/* Error inject init functions */
+extern void timefac_err_init(void);
+
 #endif
diff --git a/src/timefac_error.c b/src/timefac_error.c
new file mode 100644
index 0000000..cb6c9ac
--- /dev/null
+++ b/src/timefac_error.c
@@ -0,0 +1,114 @@
+/* Copyright 2020 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.
+ */
+#include <errno.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <libpdbg.h>
+#include <ccan/list/list.h>
+#include <ccan/array_size/array_size.h>
+#include <bitutils.h>
+
+#include "main.h"
+#include "optcmd.h"
+#include "path.h"
+#include "err_inject.h"
+
+/* SPR_MODE scom address */
+#define P9_SCOM_SPR_MODE	0x20010A84
+
+/* TB Errors */
+#define TB_ERROR_MASK		PPC_BITMASK(10, 15)
+/* Core level TB errors */
+#define TB_ERROR_TFMR_PARITY	0x1
+#define TB_ERROR_HDEC_PARITY	0x2
+#define TB_ERROR_TB_PARITY	0x3
+/* Thread level TB errors */
+#define TB_ERROR_PURR_PARITY	0x4
+#define TB_ERROR_SPURR_PARITY	0x5
+#define TB_ERROR_DEC_PARITY	0x6
+
+typedef struct error_type {
+	char *name;
+	char *desc;
+	uint64_t error;
+} error_type_t;
+
+static error_type_t tb_error_type[] = {
+	{ "tfmr_parity", "TFMR parity error", TB_ERROR_TFMR_PARITY },
+	{ "hdec_parity", "HDEC parity error", TB_ERROR_HDEC_PARITY },
+	{ "tb_residue", "TB parity/residue error", TB_ERROR_TB_PARITY },
+	{ "purr_parity", "PURR parity error", TB_ERROR_PURR_PARITY },
+	{ "spurr_parity", "SPURR parity error", TB_ERROR_SPURR_PARITY },
+	{ "dec_parity", "DEC parity error", TB_ERROR_DEC_PARITY },
+};
+
+static int timefac_inject_tb_error(struct pdbg_target *target, void *data)
+{
+	int target_type = 0;
+	uint64_t err_type;
+	uint64_t val;
+	uint64_t tindex;
+	int rc;
+
+	err_type = *((uint64_t *)data);
+	if (err_type < TB_ERROR_PURR_PARITY)
+		target_type = TARGET_TYPE_CORE;
+	else
+		target_type = TARGET_TYPE_THREAD;
+
+	if (target_type != get_target_type(target))
+		return -EINVAL;
+
+	/*
+	 * TODO: Add a check for proc type p8/p9/p10 and then use scom
+	 *       address appropriately.
+	 */
+	rc = pib_read(target, P9_SCOM_SPR_MODE, &val);
+	if (rc) {
+		/* just print the error message and continue. */
+		printf("Failed to read scom addr: %x\n", P9_SCOM_SPR_MODE);
+		val = 0;
+	}
+
+	/* set the error type and thread index where error to be injected */
+	if (target_type == TARGET_TYPE_THREAD) {
+		tindex = pdbg_target_index(target);
+		err_type |= (tindex << 3);
+	}
+	val = SETFIELD(TB_ERROR_MASK, val, err_type);
+
+	rc = target_inject_error(target, P9_SCOM_SPR_MODE, val);
+	if (rc) {
+		printf("Failed to inject\n");
+	}
+	return rc;
+}
+
+void timefac_err_init(void)
+{
+	int i;
+
+	/* Register Tb error injects. */
+	for (i = 0; i < ARRAY_SIZE(tb_error_type); i++)
+		register_error_inject("tb", tb_error_type[i].name,
+				tb_error_type[i].desc, timefac_inject_tb_error,
+				&tb_error_type[i].error);
+
+}



More information about the Pdbg mailing list