summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2016-09-01 14:35:48 +0800
committerchrome-bot <chrome-bot@chromium.org>2016-09-06 22:02:27 -0700
commit107cb0df63efb527a470553b0a4e6f1f1ab17eb6 (patch)
tree53d3db1cfb60445ef0da82df66ea81989f0e0497 /util
parent03a3f864796d02196de8419b3c12c78f425b946c (diff)
downloadchrome-ec-107cb0df63efb527a470553b0a4e6f1f1ab17eb6.tar.gz
util: Add ec_parse_panicinfo tool to parse binary panicinfo
To be able to parse binary panicinfo from feedback reports, we need a host tool: - Move panicinfo generic parsing functions to a separate C file - Create a new host utility to parse panicinfo BRANCH=none BUG=chromium:643062 TEST=base64 -d | ec_parse_panicinfo Change-Id: Idd8560a2894f270d0ab3a9f654c333135759e57f Reviewed-on: https://chromium-review.googlesource.com/379639 Commit-Ready: Nicolas Boichat <drinkcat@chromium.org> Tested-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'util')
-rw-r--r--util/build.mk7
-rw-r--r--util/ec_panicinfo.c125
-rw-r--r--util/ec_panicinfo.h19
-rw-r--r--util/ec_parse_panicinfo.c22
-rw-r--r--util/ectool.c110
5 files changed, 173 insertions, 110 deletions
diff --git a/util/build.mk b/util/build.mk
index 4b382f1156..89772f9746 100644
--- a/util/build.mk
+++ b/util/build.mk
@@ -6,7 +6,8 @@
# Host tools build
#
-host-util-bin=ectool lbplay stm32mon ec_sb_firmware_update lbcc
+host-util-bin=ectool lbplay stm32mon ec_sb_firmware_update lbcc \
+ ec_parse_panicinfo
build-util-bin=ec_uartd iteflash
ifeq ($(CHIP),npcx)
build-util-bin+=ecst
@@ -15,7 +16,9 @@ endif
comm-objs=$(util-lock-objs:%=lock/%) comm-host.o comm-dev.o
comm-objs+=comm-lpc.o comm-i2c.o misc_util.o
-ectool-objs=ectool.o ectool_keyscan.o ec_flash.o $(comm-objs)
+ectool-objs=ectool.o ectool_keyscan.o ec_flash.o ec_panicinfo.o $(comm-objs)
ec_sb_firmware_update-objs=ec_sb_firmware_update.o $(comm-objs) misc_util.o
ec_sb_firmware_update-objs+=powerd_lock.o
lbplay-objs=lbplay.o $(comm-objs)
+
+ec_parse_panicinfo-objs=ec_parse_panicinfo.o ec_panicinfo.o
diff --git a/util/ec_panicinfo.c b/util/ec_panicinfo.c
new file mode 100644
index 0000000000..47de4b2a4c
--- /dev/null
+++ b/util/ec_panicinfo.c
@@ -0,0 +1,125 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include "ec_panicinfo.h"
+
+static void print_panic_reg(int regnum, const uint32_t *regs, int index)
+{
+ static const char * const regname[] = {
+ "r0 ", "r1 ", "r2 ", "r3 ", "r4 ",
+ "r5 ", "r6 ", "r7 ", "r8 ", "r9 ",
+ "r10", "r11", "r12", "sp ", "lr ",
+ "pc "};
+
+ printf("%s:", regname[regnum]);
+ if (regs)
+ printf("%08x", regs[index]);
+ else
+ printf(" ");
+ printf((regnum & 3) == 3 ? "\n" : " ");
+}
+
+static int parse_panic_info_cm(const struct panic_data *pdata)
+{
+ const uint32_t *lregs = pdata->cm.regs;
+ const uint32_t *sregs = NULL;
+ enum {
+ ORIG_UNKNOWN = 0,
+ ORIG_PROCESS,
+ ORIG_HANDLER
+ } origin = ORIG_UNKNOWN;
+ int i;
+ const char *panic_origins[3] = {"", "PROCESS", "HANDLER"};
+
+ printf("Saved panic data:%s\n",
+ (pdata->flags & PANIC_DATA_FLAG_OLD_HOSTCMD ? "" : " (NEW)"));
+
+ if (pdata->struct_version == 2)
+ origin = ((lregs[11] & 0xf) == 1 || (lregs[11] & 0xf) == 9) ?
+ ORIG_HANDLER : ORIG_PROCESS;
+
+ /*
+ * In pdata struct, 'regs', which is allocated before 'frame', has
+ * one less elements in version 1. Therefore, if the data is from
+ * version 1, shift 'sregs' by one element to align with 'frame' in
+ * version 1.
+ */
+ if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID)
+ sregs = pdata->cm.frame - (pdata->struct_version == 1 ? 1 : 0);
+
+ printf("=== %s EXCEPTION: %02x ====== xPSR: %08x ===\n",
+ panic_origins[origin],
+ lregs[1] & 0xff, sregs ? sregs[7] : -1);
+ for (i = 0; i < 4; ++i)
+ print_panic_reg(i, sregs, i);
+ for (i = 4; i < 10; ++i)
+ print_panic_reg(i, lregs, i - 1);
+ print_panic_reg(10, lregs, 9);
+ print_panic_reg(11, lregs, 10);
+ print_panic_reg(12, sregs, 4);
+ print_panic_reg(13, lregs, origin == ORIG_HANDLER ? 2 : 0);
+ print_panic_reg(14, sregs, 5);
+ print_panic_reg(15, sregs, 6);
+
+ return 0;
+}
+
+static int parse_panic_info_nds32(const struct panic_data *pdata)
+{
+ const uint32_t *regs = pdata->nds_n8.regs;
+ uint32_t itype = pdata->nds_n8.itype;
+ uint32_t ipc = pdata->nds_n8.ipc;
+ uint32_t ipsw = pdata->nds_n8.ipsw;
+
+ printf("Saved panic data:%s\n",
+ (pdata->flags & PANIC_DATA_FLAG_OLD_HOSTCMD ? "" : " (NEW)"));
+
+ printf("=== EXCEP: ITYPE=%x ===\n", itype);
+ printf("R0 %08x R1 %08x R2 %08x R3 %08x\n",
+ regs[0], regs[1], regs[2], regs[3]);
+ printf("R4 %08x R5 %08x R6 %08x R7 %08x\n",
+ regs[4], regs[5], regs[6], regs[7]);
+ printf("R8 %08x R9 %08x R10 %08x R15 %08x\n",
+ regs[8], regs[9], regs[10], regs[11]);
+ printf("FP %08x GP %08x LP %08x SP %08x\n",
+ regs[12], regs[13], regs[14], regs[15]);
+ printf("IPC %08x IPSW %05x\n", ipc, ipsw);
+ printf("SWID of ITYPE: %x\n", ((itype >> 16) & 0x7fff));
+
+ return 0;
+}
+
+int parse_panic_info(const struct panic_data *pdata)
+{
+ /*
+ * We only understand panic data with version <= 2. Warn the user
+ * of higher versions.
+ */
+ if (pdata->struct_version > 2)
+ fprintf(stderr,
+ "Unknown panic data version (%d). "
+ "Following data may be incorrect!\n",
+ pdata->struct_version);
+
+ /* Validate magic number */
+ if (pdata->magic != PANIC_DATA_MAGIC)
+ fprintf(stderr,
+ "Incorrect panic magic (%d). "
+ "Following data may be incorrect!\n",
+ pdata->magic);
+
+ switch (pdata->arch) {
+ case PANIC_ARCH_CORTEX_M:
+ return parse_panic_info_cm(pdata);
+ case PANIC_ARCH_NDS32_N8:
+ return parse_panic_info_nds32(pdata);
+ default:
+ fprintf(stderr, "Unknown architecture (%d).\n", pdata->arch);
+ break;
+ }
+ return -1;
+}
diff --git a/util/ec_panicinfo.h b/util/ec_panicinfo.h
new file mode 100644
index 0000000000..f70c58e59f
--- /dev/null
+++ b/util/ec_panicinfo.h
@@ -0,0 +1,19 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef EC_PANICINFO_H
+#define EC_PANICINFO_H
+
+#include "panic.h"
+
+/**
+ * Prints panic information to stdout.
+ *
+ * @param pdata Panic information to print
+ * @return 0 if success or non-zero error code if error.
+ */
+int parse_panic_info(const struct panic_data *pdata);
+
+#endif /* EC_PANICINFO_H */
diff --git a/util/ec_parse_panicinfo.c b/util/ec_parse_panicinfo.c
new file mode 100644
index 0000000000..5db8ed2e05
--- /dev/null
+++ b/util/ec_parse_panicinfo.c
@@ -0,0 +1,22 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Standalone utility to parse EC panicinfo.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include "ec_panicinfo.h"
+
+int main(int argc, char *argv[])
+{
+ struct panic_data pdata;
+
+ if (fread(&pdata, sizeof(pdata), 1, stdin) != 1) {
+ fprintf(stderr, "Error reading panicinfo from stdin.\n");
+ return 1;
+ }
+
+ return parse_panic_info(&pdata) ? 1 : 0;
+}
diff --git a/util/ectool.c b/util/ectool.c
index 57660597bb..b8e5415c22 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -17,6 +17,7 @@
#include "battery.h"
#include "comm-host.h"
#include "compile_time_macros.h"
+#include "ec_panicinfo.h"
#include "ec_flash.h"
#include "ectool.h"
#include "lightbar.h"
@@ -4420,94 +4421,6 @@ int cmd_keyboard_factory_test(int argc, char *argv[])
return 0;
}
-static void print_panic_reg(int regnum, const uint32_t *regs, int index)
-{
- static const char * const regname[] = {
- "r0 ", "r1 ", "r2 ", "r3 ", "r4 ",
- "r5 ", "r6 ", "r7 ", "r8 ", "r9 ",
- "r10", "r11", "r12", "sp ", "lr ",
- "pc "};
-
- printf("%s:", regname[regnum]);
- if (regs)
- printf("%08x", regs[index]);
- else
- printf(" ");
- printf((regnum & 3) == 3 ? "\n" : " ");
-}
-
-int cmd_panic_info_cm(int argc, char *argv[])
-{
- struct panic_data *pdata = (struct panic_data *)ec_inbuf;
- const uint32_t *lregs = pdata->cm.regs;
- const uint32_t *sregs = NULL;
- enum {
- ORIG_UNKNOWN = 0,
- ORIG_PROCESS,
- ORIG_HANDLER
- } origin = ORIG_UNKNOWN;
- int i;
- const char *panic_origins[3] = {"", "PROCESS", "HANDLER"};
-
- printf("Saved panic data:%s\n",
- (pdata->flags & PANIC_DATA_FLAG_OLD_HOSTCMD ? "" : " (NEW)"));
-
- if (pdata->struct_version == 2)
- origin = ((lregs[11] & 0xf) == 1 || (lregs[11] & 0xf) == 9) ?
- ORIG_HANDLER : ORIG_PROCESS;
-
- /*
- * In pdata struct, 'regs', which is allocated before 'frame', has
- * one less elements in version 1. Therefore, if the data is from
- * version 1, shift 'sregs' by one element to align with 'frame' in
- * version 1.
- */
- if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID)
- sregs = pdata->cm.frame - (pdata->struct_version == 1 ? 1 : 0);
-
- printf("=== %s EXCEPTION: %02x ====== xPSR: %08x ===\n",
- panic_origins[origin],
- lregs[1] & 0xff, sregs ? sregs[7] : -1);
- for (i = 0; i < 4; ++i)
- print_panic_reg(i, sregs, i);
- for (i = 4; i < 10; ++i)
- print_panic_reg(i, lregs, i - 1);
- print_panic_reg(10, lregs, 9);
- print_panic_reg(11, lregs, 10);
- print_panic_reg(12, sregs, 4);
- print_panic_reg(13, lregs, origin == ORIG_HANDLER ? 2 : 0);
- print_panic_reg(14, sregs, 5);
- print_panic_reg(15, sregs, 6);
-
- return 0;
-}
-
-int cmd_panic_info_nds32(int argc, char *argv[])
-{
- struct panic_data *pdata = (struct panic_data *)ec_inbuf;
- const uint32_t *regs = pdata->nds_n8.regs;
- uint32_t itype = pdata->nds_n8.itype;
- uint32_t ipc = pdata->nds_n8.ipc;
- uint32_t ipsw = pdata->nds_n8.ipsw;
-
- printf("Saved panic data:%s\n",
- (pdata->flags & PANIC_DATA_FLAG_OLD_HOSTCMD ? "" : " (NEW)"));
-
- printf("=== EXCEP: ITYPE=%x ===\n", itype);
- printf("R0 %08x R1 %08x R2 %08x R3 %08x\n",
- regs[0], regs[1], regs[2], regs[3]);
- printf("R4 %08x R5 %08x R6 %08x R7 %08x\n",
- regs[4], regs[5], regs[6], regs[7]);
- printf("R8 %08x R9 %08x R10 %08x R15 %08x\n",
- regs[8], regs[9], regs[10], regs[11]);
- printf("FP %08x GP %08x LP %08x SP %08x\n",
- regs[12], regs[13], regs[14], regs[15]);
- printf("IPC %08x IPSW %05x\n", ipc, ipsw);
- printf("SWID of ITYPE: %x\n", ((itype >> 16) & 0x7fff));
-
- return 0;
-}
-
int cmd_panic_info(int argc, char *argv[])
{
int rv;
@@ -4523,26 +4436,7 @@ int cmd_panic_info(int argc, char *argv[])
return 0;
}
- /*
- * We only understand panic data with version <= 2. Warn the user
- * of higher versions.
- */
- if (pdata->struct_version > 2)
- fprintf(stderr,
- "Unknown panic data version (%d). "
- "Following data may be incorrect!\n",
- pdata->struct_version);
-
- switch (pdata->arch) {
- case PANIC_ARCH_CORTEX_M:
- return cmd_panic_info_cm(argc, argv);
- case PANIC_ARCH_NDS32_N8:
- return cmd_panic_info_nds32(argc, argv);
- default:
- fprintf(stderr, "Unknown architecture (%d).\n", pdata->arch);
- break;
- }
- return -1;
+ return parse_panic_info(pdata);
}