summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorWilliam Bryan <wilbryan@us.ibm.com>2016-12-12 14:12:31 -0600
committerWilliam A. Bryan <wilbryan@us.ibm.com>2016-12-15 13:57:45 -0500
commit48173d1181eb89c7efed5d6ffd30c8e89666aee5 (patch)
tree8df43001cd86a38a5df61ef335ff8749b1d3042e /src/tools
parente29c6746a230904209290fa6d2a940898c581639 (diff)
downloadtalos-occ-48173d1181eb89c7efed5d6ffd30c8e89666aee5.tar.gz
talos-occ-48173d1181eb89c7efed5d6ffd30c8e89666aee5.zip
FFDC parsing tool
Change-Id: Iada745ba30af2b4d6160770b2e2fc82c15b5d523 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33746 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com> Reviewed-by: Martha Broyles <mbroyles@us.ibm.com> Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/ffdcparser/Makefile26
-rw-r--r--src/tools/ffdcparser/ffdcparser.c382
2 files changed, 408 insertions, 0 deletions
diff --git a/src/tools/ffdcparser/Makefile b/src/tools/ffdcparser/Makefile
new file mode 100644
index 0000000..3521af1
--- /dev/null
+++ b/src/tools/ffdcparser/Makefile
@@ -0,0 +1,26 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/ffdcparser/Makefile $
+#
+# OpenPOWER OnChipController Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+# [+] International Business Machines 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.
+#
+# IBM_PROLOG_END_TAG
+all: ffdcparser.c
+ gcc ffdcparser.c -o ../../../obj/ppetools/ffdcparser
diff --git a/src/tools/ffdcparser/ffdcparser.c b/src/tools/ffdcparser/ffdcparser.c
new file mode 100644
index 0000000..4c45936
--- /dev/null
+++ b/src/tools/ffdcparser/ffdcparser.c
@@ -0,0 +1,382 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ffdcparser/ffdcparser.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* [+] International Business Machines 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. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <stdio.h>
+#include <stdint.h>
+
+// NOTE: This tool is to be used when FFDC is dumped by the OCC, and currently
+// only accepts input files in binary format.
+
+typedef struct thread_dump
+{
+ uint8_t len;
+ uint8_t pri;
+ uint8_t state;
+ uint8_t flags;
+ uint32_t timer;
+ uint32_t sem;
+ uint32_t srr0;
+ uint32_t srr1;
+ uint32_t srr2;
+ uint32_t srr3;
+ uint32_t lr;
+ uint32_t stack_trace[8];
+} thread_dump_t;
+
+// FFDC struct
+typedef struct __attribute__((packed,aligned(4))) ffdc
+{
+ uint8_t seq; // Sequence Number (0x00 for FFDC)
+ uint8_t cmd; // Command (0x00 for FFDC)
+ uint8_t excp; // Exception Code
+ uint16_t len; // FFDC data length
+ uint8_t reserved; // (0x00 for FFDC)
+ uint16_t ckpt; // Checkpoint (usually 0x0F00 for FFDC)
+ uint32_t ssx_panic; // SSX Panic Code
+ uint32_t panic_addr; // Address of panic instruction
+ uint32_t lr; // Link Register
+ uint32_t msr; // Machine Status Register
+ uint32_t cr; // Condition Register
+ uint32_t ctr; // Count Register
+ uint32_t gpr[32]; // GPR0 - GPR31
+ uint32_t evpr; // Exception Vector Prefix Register
+ uint32_t xer; // Fixedpoint Exception Register
+ uint32_t esr; // Exception Syndrome Register
+ uint32_t dear; // Bad Address
+ uint32_t srr0; // Return Address for Non-Crit Interrupts
+ uint32_t srr1; // MSR at time of non-crit interrupt
+ uint32_t srr2; // Return Address for Crit Interrupts
+ uint32_t srr3; // MSR at time of crit interrupt
+ uint32_t mcsr; // Machine Check Syndrome Register
+ uint32_t pid; // Process ID Register
+ uint32_t zpr; // Zone Protection Register
+ uint32_t usprg0; // User SPR General Purpose Register
+ uint32_t sprg[8]; // SPRG0 - SPRG7
+ uint32_t tcr; // Timer Control Register
+ uint32_t tsr; // Timer Status Register
+ uint32_t dbcr0; // Debug Control Register0
+ uint32_t dbcr1; // Debug Control Register1
+ uint32_t dbsr; // Debug Status Register
+ uint32_t ocb_oisr0;
+ uint32_t ocb_oisr1;
+ uint32_t ocb_ouder0;
+ uint32_t ocb_ouder1;
+ uint32_t ocb_oimr0;
+ uint32_t ocb_oimr1;
+ uint32_t ocb_oitr0;
+ uint32_t ocb_oitr1;
+ uint32_t ocb_oiepr0;
+ uint32_t ocb_oiepr1;
+ uint32_t ocb_ocir0;
+ uint32_t ocb_ocir1;
+ uint32_t ocb_onisr0;
+ uint32_t ocb_onisr1;
+ uint32_t ocb_ocisr0;
+ uint32_t ocb_ocisr1;
+ uint32_t ocb_her0;
+ uint32_t ocb_her1;
+ uint32_t ssx_timebase;
+ char buildname[16];
+ uint64_t occlfir;
+ uint64_t pbafir;
+ uint32_t cores_deconf;
+ thread_dump_t main;
+ thread_dump_t cmdh;
+ thread_dump_t dcom;
+ uint32_t stack_trace[8];
+ uint32_t eye_catcher;
+} ffdc_t;
+
+uint64_t get_uint64(FILE* i_fhndl)
+{
+ int i = 0;
+ uint64_t ret = 0;
+ uint8_t byte = 0;
+
+ for(i = 7; i >= 0; i--)
+ {
+ byte = fgetc(i_fhndl);
+ if(EOF != byte)
+ {
+ ret |= (byte << (i*8));
+ }
+ }
+
+ return ret;
+}
+
+uint32_t get_uint32(FILE* i_fhndl)
+{
+ int i = 0;
+ uint32_t ret = 0;
+ uint8_t byte = 0;
+
+ for(i = 3; i >= 0; i--)
+ {
+ byte = fgetc(i_fhndl);
+ if(EOF != byte)
+ {
+ ret |= (byte << (i*8));
+ }
+ }
+
+ return ret;
+}
+
+uint16_t get_uint16(FILE* i_fhndl)
+{
+ int i = 0;
+ uint16_t ret = 0;
+ uint8_t byte = 0;
+
+ for(i = 1; i >= 0; i--)
+ {
+ byte = fgetc(i_fhndl);
+ if(EOF != byte)
+ {
+ ret |= (byte << (i*8));
+ }
+ }
+
+ return ret;
+}
+
+int file_length_valid(FILE* i_fhndl, uint16_t i_exp_size)
+{
+ uint32_t len = 0;
+
+ while(EOF != fgetc(i_fhndl))
+ {
+ len++;
+ }
+
+ return (len < i_exp_size) ? 0 : 1;
+}
+
+void get_thread_data(FILE* i_fhndl, thread_dump_t * i_thrd)
+{
+ uint32_t i = 0;
+ i_thrd->len = fgetc(i_fhndl);
+ i_thrd->pri = fgetc(i_fhndl);
+ i_thrd->state = fgetc(i_fhndl);
+ i_thrd->flags = fgetc(i_fhndl);
+ i_thrd->timer = get_uint32(i_fhndl);
+ i_thrd->sem = get_uint32(i_fhndl);
+ i_thrd->srr0 = get_uint32(i_fhndl);
+ i_thrd->srr1 = get_uint32(i_fhndl);
+ i_thrd->srr2 = get_uint32(i_fhndl);
+ i_thrd->srr3 = get_uint32(i_fhndl);
+ i_thrd->lr = get_uint32(i_fhndl);
+ for(i = 0; i < 8; i++)
+ i_thrd->stack_trace[i] = get_uint32(i_fhndl);
+}
+
+void print_thread_data(thread_dump_t * i_thrd, char* i_name)
+{
+ uint32_t i = 0;
+
+ printf("%s Thread Dump\n", i_name);
+ printf("\tPriority: 0x%02X\n", i_thrd->pri);
+ printf("\tState: 0x%02X\n", i_thrd->state);
+ printf("\tFlags: 0x%02X\n", i_thrd->flags);
+ printf("\tTimer: 0x%08X\n", i_thrd->timer);
+ printf("\tSemaphore: 0x%08X\n", i_thrd->sem);
+ printf("\tSRR0: 0x%08X\n", i_thrd->srr0);
+ printf("\tSRR1: 0x%08X\n", i_thrd->srr1);
+ printf("\tSRR2: 0x%08X\n", i_thrd->srr2);
+ printf("\tSRR3: 0x%08X\n", i_thrd->srr3);
+ printf("\tStack Trace\n");
+ for(i = 0; i < 8; i++)
+ printf("\t\t%d: 0x%08X\n", i+1, i_thrd->stack_trace[i]);
+}
+
+void dump_ffdc(ffdc_t * data)
+{
+ uint32_t i = 0;
+
+ printf("Exception Code: 0x%02X\n", data->excp);
+ printf("Checkpoint: 0x%04X\n", data->ckpt);
+ printf("SSX Panic Code: 0x%08X\n", data->ssx_panic);
+ printf("Panic Address: 0x%08X\n", data->panic_addr);
+ printf("LR: 0x%08X\n", data->lr);
+ printf("MSR: 0x%08X\n", data->msr);
+ printf("CR: 0x%08X\n", data->cr);
+ printf("CTR: 0x%08X\n", data->ctr);
+ for(i = 0; i < 32; i++)
+ printf("GPR%d: 0x%08X\n", i, data->gpr[i]);
+ printf("EVPR: 0x%08X\n", data->evpr);
+ printf("XER: 0x%08X\n", data->xer);
+ printf("ESR: 0x%08X\n", data->esr);
+ printf("DEAR: 0x%08X\n", data->dear);
+ printf("SRR0: 0x%08X\n", data->srr0);
+ printf("SRR1: 0x%08X\n", data->srr1);
+ printf("SRR2: 0x%08X\n", data->srr2);
+ printf("SRR3: 0x%08X\n", data->srr3);
+ printf("MCSR: 0x%08X\n", data->mcsr);
+ printf("PID:: 0x%08X\n", data->pid);
+ printf("ZPR: 0x%08X\n", data->zpr);
+ printf("USPRG0: 0x%08X\n", data->usprg0);
+ for(i = 0; i < 8; i++)
+ printf("SPRG%d: 0x%08X\n", i, data->sprg[i]);
+ printf("TCR: 0x%08X\n", data->tcr);
+ printf("TSR: 0x%08X\n", data->tsr);
+ printf("DBCR0: 0x%08X\n", data->dbcr0);
+ printf("DBCR1: 0x%08X\n", data->dbcr1);
+ printf("DBSR: 0x%08X\n", data->dbsr);
+ printf("OCB_OISR0: 0x%08X\n", data->ocb_oisr0);
+ printf("OCB_OISR1: 0x%08X\n", data->ocb_oisr1);
+ printf("OCB_OUDER0: 0x%08X\n", data->ocb_ouder0);
+ printf("OCB_OUDER1: 0x%08X\n", data->ocb_ouder1);
+ printf("OCB_OIMR0: 0x%08X\n", data->ocb_oimr0);
+ printf("OCB_OIMR1: 0x%08X\n", data->ocb_oimr1);
+ printf("OCB_OITR0: 0x%08X\n", data->ocb_oitr0);
+ printf("OCB_OITR1: 0x%08X\n", data->ocb_oitr1);
+ printf("OCB_OIEPR0: 0x%08X\n", data->ocb_oiepr0);
+ printf("OCB_OIEPR1: 0x%08X\n", data->ocb_oiepr1);
+ printf("OCB_OCIR0: 0x%08X\n", data->ocb_ocir0);
+ printf("OCB_OCIR1: 0x%08X\n", data->ocb_ocir1);
+ printf("OCB_ONISR0: 0x%08X\n", data->ocb_onisr0);
+ printf("OCB_ONISR1: 0x%08X\n", data->ocb_onisr1);
+ printf("OCB_OCISR0: 0x%08X\n", data->ocb_ocisr0);
+ printf("OCB_OCISR1: 0x%08X\n", data->ocb_ocisr1);
+ printf("OCB_HER0: 0x%08X\n", data->ocb_her0);
+ printf("OCB_HER1: 0x%08X\n", data->ocb_her1);
+ printf("SSX Timebase: 0x%08X\n", data->ssx_timebase);
+ printf("OCC Buildname: %s\n", data->buildname);
+ printf("OCC LFIR: 0x%016X\n", data->occlfir);
+ printf("PBA FIR: 0x%016X\n", data->pbafir);
+ printf("Cores Deconfigured: 0x%08X\n", data->cores_deconf);
+ print_thread_data(&data->main, "MAIN");
+ print_thread_data(&data->cmdh, "CMDH");
+ print_thread_data(&data->dcom, "DCOM");
+ printf("Stack Trace:\n");
+ for(i = 0; i < 8; i++)
+ printf("\t%d: 0x%08X\n", i+1, data->stack_trace[i]);
+}
+
+int main(int argc, char** argv)
+{
+ FILE* ffdc_file = NULL;
+ ffdc_t data = {0};
+ uint32_t i = 0;
+
+ // Verify a file was passed as an argument
+ if(argc < 2)
+ {
+ fprintf(stderr, "ERROR: Requires a file with the binary FFDC data\n");
+ return -1;
+ }
+ else
+ {
+ ffdc_file = fopen(argv[1], "rb");
+ if(ffdc_file == NULL)
+ {
+ fprintf(stderr, "ERROR: %s cannot be opened or does not exist\n", argv[1]);
+ return -1;
+ }
+ }
+
+ // Binary file is open, parse it
+ data.seq = fgetc(ffdc_file);
+ data.cmd = fgetc(ffdc_file);
+ data.excp = fgetc(ffdc_file);
+ data.len = get_uint16(ffdc_file);
+
+ if( (!file_length_valid(ffdc_file, data.len)) )
+ {
+ fprintf(stderr, "ERROR: FFDC file not valid size\n");
+ return -1;
+ }
+
+ if(fseek(ffdc_file, 5, SEEK_SET))
+ {
+ fprintf(stderr, "ERROR: Something happened when changing offsets in ffdc file\n");
+ return -1;
+ }
+
+ data.reserved = fgetc(ffdc_file);
+ data.ckpt = get_uint16(ffdc_file);
+ data.ssx_panic = get_uint32(ffdc_file);
+ data.panic_addr = get_uint32(ffdc_file);
+ data.lr = get_uint32(ffdc_file);
+ data.msr = get_uint32(ffdc_file);
+ data.cr = get_uint32(ffdc_file);
+ data.ctr = get_uint32(ffdc_file);
+ for(i = 0; i < 32; i++)
+ data.gpr[i] = get_uint32(ffdc_file);
+ data.evpr = get_uint32(ffdc_file);
+ data.xer = get_uint32(ffdc_file);
+ data.esr = get_uint32(ffdc_file);
+ data.dear = get_uint32(ffdc_file);
+ data.srr0 = get_uint32(ffdc_file);
+ data.srr1 = get_uint32(ffdc_file);
+ data.srr2 = get_uint32(ffdc_file);
+ data.srr3 = get_uint32(ffdc_file);
+ data.mcsr = get_uint32(ffdc_file);
+ data.pid = get_uint32(ffdc_file);
+ data.zpr = get_uint32(ffdc_file);
+ data.usprg0 = get_uint32(ffdc_file);
+ for(i = 0; i < 8; i++)
+ data.sprg[i] = get_uint32(ffdc_file);
+ data.tcr = get_uint32(ffdc_file);
+ data.tsr = get_uint32(ffdc_file);
+ data.dbcr0 = get_uint32(ffdc_file);
+ data.dbcr1 = get_uint32(ffdc_file);
+ data.dbsr = get_uint32(ffdc_file);
+ data.ocb_oisr0 = get_uint32(ffdc_file);
+ data.ocb_oisr1 = get_uint32(ffdc_file);
+ data.ocb_ouder0 = get_uint32(ffdc_file);
+ data.ocb_ouder1 = get_uint32(ffdc_file);
+ data.ocb_oimr0 = get_uint32(ffdc_file);
+ data.ocb_oimr1 = get_uint32(ffdc_file);
+ data.ocb_oitr0 = get_uint32(ffdc_file);
+ data.ocb_oitr1 = get_uint32(ffdc_file);
+ data.ocb_oiepr0 = get_uint32(ffdc_file);
+ data.ocb_oiepr1 = get_uint32(ffdc_file);
+ data.ocb_ocir0 = get_uint32(ffdc_file);
+ data.ocb_ocir1 = get_uint32(ffdc_file);
+ data.ocb_onisr0 = get_uint32(ffdc_file);
+ data.ocb_onisr1 = get_uint32(ffdc_file);
+ data.ocb_ocisr0 = get_uint32(ffdc_file);
+ data.ocb_ocisr1 = get_uint32(ffdc_file);
+ data.ocb_her0 = get_uint32(ffdc_file);
+ data.ocb_her1 = get_uint32(ffdc_file);
+ data.ssx_timebase = get_uint32(ffdc_file);
+ fgets(data.buildname, 16, ffdc_file);
+ fgetc(ffdc_file);
+ data.occlfir = get_uint64(ffdc_file);
+ data.pbafir = get_uint64(ffdc_file);
+ data.cores_deconf = get_uint32(ffdc_file);
+ get_thread_data(ffdc_file, &data.main);
+ get_thread_data(ffdc_file, &data.cmdh);
+ get_thread_data(ffdc_file, &data.dcom);
+ for(i=0; i<8; i++)
+ data.stack_trace[i] = get_uint32(ffdc_file);
+ data.eye_catcher = get_uint32(ffdc_file);
+ dump_ffdc(&data);
+ if(data.eye_catcher != 0xFFDCFFDC)
+ printf("WARNING: Eye catcher(0x%08X) was not 0xFFDCFFDC\n", data.eye_catcher);
+
+ return 0;
+}
OpenPOWER on IntegriCloud