diff options
author | Zane Shelley <zshelle@us.ibm.com> | 2015-02-10 17:18:45 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-02-27 23:43:21 -0600 |
commit | b640d9b9361402f45b5c88a6bb2384ab2995accc (patch) | |
tree | e4632e8853fb82c3f5c00cc127bddb5b72b4a910 /src/usr | |
parent | 67d0c761b1cb25b4df27b7ea794352aa2bb40e36 (diff) | |
download | talos-hostboot-b640d9b9361402f45b5c88a6bb2384ab2995accc.tar.gz talos-hostboot-b640d9b9361402f45b5c88a6bb2384ab2995accc.zip |
PRD: FIR data definition and support for OCC CS analysis
Change-Id: If2dc455e587c2cf752fcac156c7c6f206fd622fa
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/15656
Tested-by: Jenkins Server
Reviewed-by: Christopher T. Phan <cphan@us.ibm.com>
Reviewed-by: Prem Shanker Jha <premjha2@in.ibm.com>
Reviewed-by: Bilicon Patil <bilpatil@in.ibm.com>
Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Reviewed-by: Zane Shelley <zshelle@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
-rwxr-xr-x | src/usr/diag/prdf/makefile | 2 | ||||
-rw-r--r-- | src/usr/diag/prdf/occ_firdata/firDataConst_common.h | 75 | ||||
-rw-r--r-- | src/usr/diag/prdf/occ_firdata/homerData_common.h | 170 | ||||
-rw-r--r-- | src/usr/diag/prdf/occ_firdata/pnorData_common.h | 152 | ||||
-rw-r--r-- | src/usr/diag/prdf/occ_firdata/prdfReadPnorFirData.C | 298 | ||||
-rw-r--r-- | src/usr/diag/prdf/occ_firdata/prdfReadPnorFirData.H | 83 | ||||
-rw-r--r-- | src/usr/diag/prdf/prdf_hb_only.mk | 5 |
7 files changed, 784 insertions, 1 deletions
diff --git a/src/usr/diag/prdf/makefile b/src/usr/diag/prdf/makefile index 1ed358a7a..088af87a0 100755 --- a/src/usr/diag/prdf/makefile +++ b/src/usr/diag/prdf/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2012,2014 +# Contributors Listed Below - COPYRIGHT 2012,2015 # [+] International Business Machines Corp. # # diff --git a/src/usr/diag/prdf/occ_firdata/firDataConst_common.h b/src/usr/diag/prdf/occ_firdata/firDataConst_common.h new file mode 100644 index 000000000..62fe1916c --- /dev/null +++ b/src/usr/diag/prdf/occ_firdata/firDataConst_common.h @@ -0,0 +1,75 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/occ_firdata/firDataConst_common.h $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] 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 */ + +#ifndef __firDataConst_common_h +#define __firDataConst_common_h + +/** NOTE: This file is common between OCC and Hosboot. Any change to this file + * must be mirrored to both repositories. */ + +#include <stdint.h> + +/** Target types for all supported targets. */ +typedef enum +{ + // NOTE: These will be used as array indexes. + FIRST_TRGT = 0, + PROC = FIRST_TRGT, + EX, + MCS, + MEMB, + MBA, + MAX_TRGTS, + +} TrgtType_t; + +/** Boundary/position ranges for each target type. */ +typedef enum +{ + MAX_PROC_PER_NODE = 8, + MAX_EX_PER_PROC = 16, + MAX_MCS_PER_PROC = 8, + MAX_MEMB_PER_PROC = MAX_MCS_PER_PROC, + MAX_MEMB_PER_NODE = MAX_MEMB_PER_PROC * MAX_PROC_PER_NODE, + MAX_MBA_PER_MEMB = 2, + MAX_MBA_PER_PROC = MAX_MEMB_PER_PROC * MAX_MBA_PER_MEMB, + +} TrgtPos_t; + +/** All register types. */ +typedef enum +{ + // NOTE: These will be used as array indexes. + FIRST_REG = 0, + GLBL = FIRST_REG, + FIR, + REG, + IDFIR, + IDREG, + MAX_REGS, + +} RegType_t; + +#endif // __firDataConst_common_h diff --git a/src/usr/diag/prdf/occ_firdata/homerData_common.h b/src/usr/diag/prdf/occ_firdata/homerData_common.h new file mode 100644 index 000000000..3f396c43c --- /dev/null +++ b/src/usr/diag/prdf/occ_firdata/homerData_common.h @@ -0,0 +1,170 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/occ_firdata/homerData_common.h $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] 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 */ + +#ifndef __homerData_common_h +#define __homerData_common_h + +/** NOTE: This file is common between OCC and Hosboot. Any change to this file + * must be mirrored to both repositories. */ + +#include <firDataConst_common.h> +#include <string.h> + +/** This file is used to define the format of the register list stored in the + * HOMER data that the OCC will use to determine what register data to capture + * in the event of a system checkstop. The data will be stored in the following + * format: + * + * - HOMER_Data_t struct - This has all of the information characterizing what + * hardware is configured and how many addresses are in each register + * list. See the struct definition below. + * + * - Rgister address lists - These lists vary in size depending on the number + * of register addresses needed in each list. The list counts are + * stored in HOMER_Data_t::counts. All lists for each target type will + * be stored in the following order: + * - PROC lists + * - EX lists + * - MCS lists + * - MEMB lists + * - MBA lists + * Each target type will have a set of lists that will be stored in the + * following order: + * - Global FIRs 32-bit addresses + * - FIRs 32-bit addresses + * - Registers 32-bit addresses + * - Indirect-SCOM FIRs 64-bit addresses + * - Indirect-SCOM registers 64-bit addresses + * + * Note that FIRs and indirect-SCOM FIRs characterize a set of registers to + * capture. In addition to capturing the FIR (or ID FIR), the OCC will need to + * capture the following addresses for each type: + * - FIR + * - MASK (FIR address + 3) + * - ACT0 (FIR address + 6) + * - ACT1 (FIR address + 7) + * - WOF (FIR address + 8) + * - ID FIR + * - ID MASK (ID FIR address + 0x300000000ll) + * - ID ACT0 (ID FIR address + 0x600000000ll) + * - ID ACT1 (ID FIR address + 0x700000000ll) + * - ID WOF (ID FIR address + 0x800000000ll) + */ + +typedef enum +{ + HOMER_FIR1 = 0x46495231, ///< FIR data version 1 ("FIR1" in ascii) + +} HOMER_Version_t; + +/** PNOR information contained within the HOMER data. */ +typedef struct +{ + uint32_t pnorOffset; ///< Physical offset of FIRDATA in PNOR + uint32_t pnorSize; ///< Maximum size of FIRDATA (includes ECC) + uint32_t mmioOffset; ///< Address of MMIO access + uint32_t norWorkarounds; ///< NOR flash vendor + +} HOMER_PnorInfo_t; + +/** HOMER data header information containing hardware configurations and + * register counts. */ +typedef struct +{ + uint32_t header; ///< Magic number to indicate valid data and version + + uint16_t reserved; + + uint8_t masterProc; ///< The position of the master PROC + + /** Bitwise mask to indicate which PROCs are configured (max 8). The mask + * bit position is consistant with PROC ATTR_POSITION attribute. */ + uint8_t procMask; + + /** Bitwise masks to indicate which EXs are configured (16 per PROC). The + * array index is the associated PROC position. The mask bit position is + * consistant with the EX's ATTR_CHIP_UNIT attribute. */ + uint16_t exMasks[MAX_PROC_PER_NODE]; + + /** Bitwise masks to indicate which MCSs are configured (8 per PROC). The + * array index is the associated PROC position. The mask bit position is + * consistant with the MCS's ATTR_CHIP_UNIT attribute. */ + uint8_t mcsMasks[MAX_PROC_PER_NODE]; + + /** Bitwise masks to indicate which MEMBs are configured (8 per PROC). The + * array index is the associated PROC position. The mask bit position is + * consistant with the ATTR_CHIP_UNIT attribute of the connected MCS. */ + uint8_t membMasks[MAX_PROC_PER_NODE]; + + /** Bitwise masks to indicate which MBAs are configured (16 per PROC). The + * array index is the associated PROC position. The mask bit position is + * calculated as: + * (MEMB position * MAX_MBA_PER_MEMB) + MBA's ATTR_CHIP_UNIT attribute + */ + uint16_t mbaMasks[MAX_PROC_PER_NODE]; + + /** Contains number of registers per type for each target type. */ + uint8_t counts[MAX_TRGTS][MAX_REGS]; + + /** FSI base address for each PROC chip. */ + uint32_t procFsiBaseAddr[MAX_PROC_PER_NODE]; + + /** FSI base address for each MEMB chip. */ + uint32_t membFsiBaseAddr[MAX_PROC_PER_NODE][MAX_MEMB_PER_PROC]; + + /** Information regarding the PNOR location and size. */ + HOMER_PnorInfo_t pnorInfo; + +} HOMER_Data_t; + +/** @return An initialized HOMER_Data_t struct. */ +static inline HOMER_Data_t HOMER_getData() +{ + HOMER_PnorInfo_t p; + HOMER_Data_t d; + + p.pnorOffset = 0; + p.pnorSize = 0; + p.mmioOffset = 0; + p.norWorkarounds = 0; + + d.header = HOMER_FIR1; + d.reserved = 0; + d.masterProc = 0; + d.procMask = 0; + d.pnorInfo = p; + + memset( d.exMasks, 0x00, sizeof(d.exMasks) ); + memset( d.mcsMasks, 0x00, sizeof(d.mcsMasks) ); + memset( d.membMasks, 0x00, sizeof(d.membMasks) ); + memset( d.mbaMasks, 0x00, sizeof(d.mbaMasks) ); + memset( d.counts, 0x00, sizeof(d.counts) ); + memset( d.procFsiBaseAddr, 0xff, sizeof(d.procFsiBaseAddr) ); + memset( d.membFsiBaseAddr, 0xff, sizeof(d.membFsiBaseAddr) ); + + return d; +} + +#endif // __homerData_common_h diff --git a/src/usr/diag/prdf/occ_firdata/pnorData_common.h b/src/usr/diag/prdf/occ_firdata/pnorData_common.h new file mode 100644 index 000000000..85deaaaf5 --- /dev/null +++ b/src/usr/diag/prdf/occ_firdata/pnorData_common.h @@ -0,0 +1,152 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/occ_firdata/pnorData_common.h $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] 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 */ + +#ifndef __pnorData_common_h +#define __pnorData_common_h + +/** NOTE: This file is common between OCC and Hosboot. Any change to this file + * must be mirrored to both repositories. */ + +#include <firDataConst_common.h> + +/** This file is used to define the format of the register data captured by the + * OCC and stored in PNOR. The data will be stored in the following format: + * + * - PNOR_Data_t struct - This has all of the information characterizing how + * many targets that have register data. + * - For each target with register data, the following format will be used: + * - PNOR_Trgt_t struct - Contains the target type, position, and how many + * registers are in the register list. + * - A list of all regular registers (PNOR_Reg_t). + * - A list of all indirect-SCOM registers (PNOR_IdReg_t). + * + * The PNOR has limited data space. So the following rules will apply: + * - Any registers with the value of zero will not be captured. + * - Registers with SCOM errors will not be captured, however, the number + * of SCOM errors detected should be stored in each PNOR_Trgt_t struct. + * - If the value of a FIR (or ID FIR) is zero, do not capture the + * associated ACT0 and ACT1 registers. Note that the associated MASK and + * WOF registers are still needed. + * - Each target type may have associated global registers. If none exist, + * simply capture all registers for that type. However, if they do exist + * and the values of ALL the global registers are zero, skip capturing + * the associated targets using the following rules: + * - For a PROC, skip this PROC and all associated EXs, and MCSs. + * - For an EX, skip this EX. + * - For an MCS, skip this MCS. + * - For a MEMB, skip this MEMB and all associated MBAs. + * - For an MBA, skip this MBA. + * - If for some reason we run out of space in the PNOR, do not SCOM any + * more registers, set the 'full' bit in the PNOR_Data_t struct, and + * write all data successfully captured to PNOR. + */ + +typedef enum +{ + PNOR_FIR1 = 0x46495231, ///< FIR data version 1 ("FIR1" in ascii) + +} PNOR_Version_t; + +/** PNOR data header information. */ +typedef struct +{ + uint32_t header; ///< Magic number to indicate valid data and version + + uint32_t trgts : 8; ///< Number of targets with register data + uint32_t full : 1; ///< 1 if PNOR data is full and data may be missing + uint32_t reserved : 23; + +} PNOR_Data_t; + +/** @return An initialized PNOR_Data_t struct. */ +static inline PNOR_Data_t PNOR_getData() +{ + PNOR_Data_t d; + d.header = PNOR_FIR1; + d.trgts = 0; + d.full = 0; + d.reserved = 0; + + return d; +}; + +/** These values will match the corresponding bit fields in PNOR_Trgt_t. */ +typedef enum +{ + PNOR_Trgt_MAX_REGS_PER_TRGT = 511, // Currently expect 266 on the PROC + PNOR_Trgt_MAX_ID_REGS_PER_TRGT = 15, // Currently expect 9 on the MBA + PNOR_Trgt_MAX_SCOM_ERRORS = 511, // Should be plenty + +} PNOR_Trgt_RegLimits_t; + +/** Information for each target with SCOM data. */ +typedef struct +{ + uint32_t type : 3; ///< Target type. See enum TrgtType_t + uint32_t procPos : 3; ///< The processor position (0-7) + uint32_t unitPos : 4; ///< Unit position relative to the processor (0-15) + uint32_t regs : 9; ///< Number of normal registers + uint32_t idRegs : 4; ///< Number of indirect-SCOM registers + uint32_t scomErrs : 9; ///< Number of SCOM errors detected + +} PNOR_Trgt_t; + +/** @param i_type Target type. See enum TrgtType_t. + * @param i_procPos The processor position. + * @param i_procUnitPos Unit position relative to the processor. + * @return An initialized PNOR_Data_t struct. + */ +static inline PNOR_Trgt_t PNOR_getTrgt( uint32_t i_type, uint32_t i_procPos, + uint32_t i_procUnitPos ) +{ + PNOR_Trgt_t t; + t.type = i_type; + t.procPos = i_procPos; + t.unitPos = i_procUnitPos; + t.regs = 0; + t.idRegs = 0; + t.scomErrs = 0; + + return t; +}; + +/** Information for a normal register. */ +typedef struct +{ + uint32_t addr; ///< 32-bit address + uint64_t val; ///< 64-bit value + +} PNOR_Reg_t; + +/** Information for an indirect-SCOM register. */ +typedef struct +{ + uint64_t addr; ///< 64-bit address + uint32_t val; ///< 32-bit value + +} PNOR_IdReg_t; + +#endif // __pnorData_common_h + diff --git a/src/usr/diag/prdf/occ_firdata/prdfReadPnorFirData.C b/src/usr/diag/prdf/occ_firdata/prdfReadPnorFirData.C new file mode 100644 index 000000000..16d71ae44 --- /dev/null +++ b/src/usr/diag/prdf/occ_firdata/prdfReadPnorFirData.C @@ -0,0 +1,298 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/occ_firdata/prdfReadPnorFirData.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] 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 <prdfReadPnorFirData.H> + +#include <prdfTrace.H> + +#include <pnor/pnorif.H> +#include <prdfErrlUtil.H> + +using namespace TARGETING; + +namespace PRDF +{ + +using namespace PlatServices; + +class FirData +{ + public: + + /** @brief Constructor + * @param i_pBuf Pointer to the PNOR data buffer + * @param i_maxPBufSize Maximum size of the PNOR data buffer + */ + FirData( uint8_t * i_pBuf, size_t i_maxPBufSize ) : + iv_pBuf(i_pBuf), iv_maxPBufSize(i_maxPBufSize), iv_pBufSize(0) + {} + + /** @brief Template function to get data from the PNOR buffer. + * @param o_data Data to extract from the buffer. + * @return True if the PNOR buffer is full, false if there was room. + */ + template <typename T> + bool getData( T & o_data ) + { + size_t sz_data = sizeof(*o_data); + bool full = (iv_maxPBufSize < iv_pBufSize + sz_data); + if ( !full ) + { + o_data = reinterpret_cast<T>(&iv_pBuf[iv_pBufSize]); + iv_pBufSize += sz_data; + } + return full; + } + + private: + + uint8_t * iv_pBuf; ///< Pointer to the PNOR data buffer + uint32_t iv_maxPBufSize; ///< Maximum size of the PNOR data buffer + size_t iv_pBufSize; ///< Current size of the PNOR data buffer +}; + +//------------------------------------------------------------------------------ + +TargetHandle_t getTargetHandle( PNOR_Trgt_t * i_pTrgt ) +{ + TargetHandle_t o_trgt = NULL; + + do + { + // Get the target type. + TYPE type = TYPE_LAST_IN_RANGE; + switch ( i_pTrgt->type ) + { + case PROC: type = TYPE_PROC; break; + case EX: type = TYPE_EX; break; + case MCS: type = TYPE_MCS; break; + case MEMB: type = TYPE_MEMBUF; break; + case MBA: type = TYPE_MBA; break; + } + if ( TYPE_LAST_IN_RANGE == type ) break; + + // Get the PROC target. + TargetHandle_t procTrgt = NULL; + TargetHandleList procList = getFunctionalTargetList( TYPE_PROC ); + for ( TargetHandleList::iterator i = procList.begin(); + i != procList.end(); ++i ) + { + if ( i_pTrgt->procPos == getTargetPosition(*i) ) + { + procTrgt = *i; + break; + } + } + if ( NULL == procTrgt ) break; + + if ( TYPE_PROC == type ) + { + o_trgt = procTrgt; // nothing more to do. + } + else if ( TYPE_EX == type || TYPE_MCS == type || TYPE_MEMBUF == type ) + { + // Get the connected child + o_trgt = getConnectedChild( procTrgt, type, i_pTrgt->unitPos ); + } + else if ( TYPE_MBA == type ) + { + uint32_t membPos = i_pTrgt->unitPos / MAX_MBA_PER_MEMBUF; + uint32_t mbaPos = i_pTrgt->unitPos % MAX_MBA_PER_MEMBUF; + + // Get the connected MEMBUF + TargetHandle_t membTrgt = getConnectedChild( procTrgt, TYPE_MEMBUF, + membPos ); + if ( NULL != membTrgt ) + { + // Get the connected MBA + o_trgt = getConnectedChild( membTrgt, type, mbaPos ); + } + } + + } while (0); + + return o_trgt; +} + +//------------------------------------------------------------------------------ + +int32_t readPnorData( uint8_t * & o_pBuf, size_t & o_pBufSize ) +{ + #define FUNC "[PRDF::readPnorData] " + + int32_t rc = SUCCESS; + + PNOR::SectionInfo_t info; + errlHndl_t errl = PNOR::getSectionInfo( PNOR::FIRDATA, info ); + if ( NULL != errl ) + { + ERRORLOG::errlCommit( errl, PRDF_COMP_ID ); + PRDF_ERR( FUNC"getSectionInfo() failed" ); + rc = FAIL; + } + else + { + o_pBuf = reinterpret_cast<uint8_t *>(info.vaddr); + o_pBufSize = info.size; + } + + return rc; + + #undef FUNC +} + +//------------------------------------------------------------------------------ + +int32_t readPnorFirData( bool & o_validData, PnorTrgtMap & o_trgtMap, + PnorFfdc & o_ffdc, PnorTrgtFfdcMap & o_trgtFfdc ) +{ + #define FUNC "[PRDF::readPnorFirData] " + + int32_t rc = SUCCESS; + + o_validData = false; + + bool full = false; + uint8_t * pBuf = NULL; + size_t sz_pBuf = 0; + + do + { + // Read the PNOR data. + rc = readPnorData( pBuf, sz_pBuf ); + if ( SUCCESS != rc ) + { + PRDF_ERR( FUNC"readPnorData() failed" ); + break; + } + + FirData firData ( pBuf, sz_pBuf ); + + // Get the PNOR header data. + PNOR_Data_t * data = NULL; + bool full = firData.getData( data ); + if ( full ) + { + PRDF_ERR( FUNC"PNOR buffer size %d is less than PNOR header data " + "size %d", sz_pBuf, sizeof(*data) ); + rc = FAIL; + break; + } + + // Check the header for valid data. + if ( PNOR_FIR1 != data->header ) + { + break; // nothing to analyze + } + + // Gather FFDC from header data. + o_ffdc.trgts = data->trgts; + o_ffdc.full = (0 == data->full) ? false : true; + + // Iterate each target and get the register data. + for ( uint32_t t = 0; t < data->trgts; t++ ) + { + PNOR_Trgt_t * pTrgt = NULL; + full = firData.getData( pTrgt ); + if ( full ) break; + + TargetHandle_t trgtHndl = getTargetHandle( pTrgt ); + if ( NULL == trgtHndl ) + { + PRDF_ERR( FUNC"getTargetHandle() failed" ); + rc = FAIL; + break; + } + + // Gather FFDC from target. + if ( 0 != pTrgt->scomErrs ) + { + o_trgtFfdc[trgtHndl].scomErrs = pTrgt->scomErrs; + } + + // Iterate the regular registers. + for ( uint32_t r = 0; r < pTrgt->regs; r++ ) + { + PNOR_Reg_t * reg = NULL; + full = firData.getData( reg ); + if ( full ) break; + + o_trgtMap[trgtHndl][(uint64_t)reg->addr] = reg->val; + } + if ( full ) break; + + // Iterate the indirect-SCOM registers. + for ( uint32_t r = 0; r < pTrgt->idRegs; r++ ) + { + PNOR_IdReg_t * reg = NULL; + full = firData.getData( reg ); + if ( full ) break; + + o_trgtMap[trgtHndl][reg->addr] = (uint64_t)reg->val; + } + if ( full ) break; + + } + if ( full ) break; + + o_validData = true; + + } while (0); + + if ( full ) + { + PRDF_ERR( FUNC"Needed more data than availabe in PNOR (%d bytes)", + sz_pBuf ); + rc = FAIL; + } + + return rc; + + #undef FUNC +} + +//------------------------------------------------------------------------------ + +int32_t clearPnorFirData() +{ + #define FUNC "[PRDF::clearPnorFirData] " + + int32_t rc = SUCCESS; + + errlHndl_t errl = PNOR::clearSection( PNOR::FIRDATA ); + if ( NULL != errl ) + { + ERRORLOG::errlCommit( errl, PRDF_COMP_ID ); + PRDF_ERR( FUNC"clearSection() failed" ); + rc = FAIL; + } + + return rc; + + #undef FUNC +} + +}; // end namespace PRDF + diff --git a/src/usr/diag/prdf/occ_firdata/prdfReadPnorFirData.H b/src/usr/diag/prdf/occ_firdata/prdfReadPnorFirData.H new file mode 100644 index 000000000..6e184bae6 --- /dev/null +++ b/src/usr/diag/prdf/occ_firdata/prdfReadPnorFirData.H @@ -0,0 +1,83 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/occ_firdata/prdfReadPnorFirData.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015 */ +/* [+] 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 */ + +#ifndef __prdfReadPnorFirData_H +#define __prdfReadPnorFirData_H + +#include <map> + +#include <pnorData_common.h> +#include <prdfPlatServices.H> + +namespace PRDF +{ + +typedef std::map<uint64_t, uint64_t> PnorRegMap; + +typedef std::map<TARGETING::TargetHandle_t, PnorRegMap> PnorTrgtMap; + +struct PnorFfdc +{ + uint8_t trgts; ///< Total number of target in the PNOR data. + bool full; ///< True if the PNOR data was unable to capture all regs. + + PnorFfdc() : trgts(0), full(false) {} + PnorFfdc( uint8_t t, bool f ) : trgts(t), full(f) {} +}; + +struct PnorTrgtFfdc +{ + uint16_t scomErrs; ///< Total number of SCOM error detected on this target + + PnorTrgtFfdc() : scomErrs(0) {} + PnorTrgtFfdc(uint16_t s) : scomErrs(s) {} +}; + +typedef std::map<TARGETING::TargetHandle_t, PnorTrgtFfdc> PnorTrgtFfdcMap; + +/** @brief Read register data captured by the OCC in the event of a system + * checkstop. + * @param o_validData True, if there the was a system checkstop and the OCC + * stored valid data in the PNOR. False otherwise. + * @param o_trgtMap If the data if valid, a map containing the register + * values for each target and address. + * @param o_ffdc PNOR FFDC data for debug. + * @param o_trgtFfdc PNOR target FFDC data for debug. + * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. + */ +int32_t readPnorFirData( bool & o_validData, PnorTrgtMap & o_trgtMap, + PnorFfdc & o_ffdc, PnorTrgtFfdcMap & o_trgtFfdc ); + +/** @brief Clears the OCC FIR data from the PNOR. This must be done after the + * checkstop analysis is complete so that analysis is not repeated on + * subsequent IPLs. + * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. + */ +int32_t clearPnorFirData(); + +}; // end namespace PRDF + +#endif // __prdfReadPnorFirData_H + diff --git a/src/usr/diag/prdf/prdf_hb_only.mk b/src/usr/diag/prdf/prdf_hb_only.mk index c071a4a8b..31f950fea 100644 --- a/src/usr/diag/prdf/prdf_hb_only.mk +++ b/src/usr/diag/prdf/prdf_hb_only.mk @@ -38,6 +38,7 @@ prd_vpath += ${PRD_SRC_PATH}/framework/config prd_vpath += ${PRD_SRC_PATH}/framework/resolution prd_vpath += ${PRD_SRC_PATH}/framework/service prd_vpath += ${PRD_SRC_PATH}/mnfgtools +prd_vpath += ${PRD_SRC_PATH}/occ_firdata prd_vpath += ${PRD_SRC_PATH}/plat prd_vpath += ${PRD_SRC_PATH}/plat/pegasus @@ -49,6 +50,7 @@ prd_incpath += ${PRD_SRC_PATH}/framework/config prd_incpath += ${PRD_SRC_PATH}/framework/resolution prd_incpath += ${PRD_SRC_PATH}/framework/service prd_incpath += ${PRD_SRC_PATH}/mnfgtools +prd_incpath += ${PRD_SRC_PATH}/occ_firdata prd_incpath += ${PRD_SRC_PATH}/plat/pegasus # External header paths @@ -105,6 +107,9 @@ prd_obj += prdfPlatServices_ipl.o # mnfgtools/ prd_obj += prdfMfgSync.o +# occ_firdata/ +prd_obj += $(if $(CONFIG_ENABLE_CHECKSTOP_ANALYSIS), prdfReadPnorFirData.o) + # plat/pegasus/ (non-rule plugin related) prd_obj += prdfCenMbaIplCeStats.o prd_obj += prdfCenMbaTdCtlr_ipl.o |