From a1e236a422182e81f7877de85f3cb46dff6fc0cd Mon Sep 17 00:00:00 2001 From: Mike Baiocchi Date: Fri, 18 May 2018 15:48:24 -0500 Subject: Improve FFDC for new Node Comm Device Driver This commit adds a new custom Node Comm Device Driver error log user details section and its parser code. It also adds a function to add the target and important HW registers to an error log. Change-Id: I11893af06b7a097b43106117d648e9a431c4f3ea RTC:191008 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/59079 Reviewed-by: ILYA SMIRNOV Reviewed-by: Nicholas E. Bofferding Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: William G. Hoffa --- src/usr/secureboot/common/errlud_secure.C | 76 +++++++++++++++ src/usr/secureboot/common/errlud_secure.H | 50 ++++++++++ src/usr/secureboot/common/plugins/errludP_secure.H | 102 +++++++++++++++++++++ .../common/plugins/secureUdParserFactory.H | 3 + src/usr/secureboot/node_comm/node_comm.C | 70 +++++++++++++- src/usr/secureboot/node_comm/node_comm.H | 17 +++- src/usr/secureboot/node_comm/node_comm_dd.C | 40 +++++++- src/usr/secureboot/node_comm/node_comm_dd.H | 9 +- src/usr/secureboot/node_comm/node_comm_test.C | 5 +- 9 files changed, 362 insertions(+), 10 deletions(-) (limited to 'src/usr') diff --git a/src/usr/secureboot/common/errlud_secure.C b/src/usr/secureboot/common/errlud_secure.C index a6b9b3d1d..c40172609 100644 --- a/src/usr/secureboot/common/errlud_secure.C +++ b/src/usr/secureboot/common/errlud_secure.C @@ -34,6 +34,8 @@ #include #include #include +#include +#include namespace SECUREBOOT { @@ -43,6 +45,7 @@ namespace SECUREBOOT //------------------------------------------------------------------------------ enum { PARSER_SIZEOF_SHA512_t = 64, + PARSER_SIZEOF_UINT64_t = 8, PARSER_SIZEOF_UINT32_t = 4, PARSER_SIZEOF_UINT8_t = 1, PARSER_SIZEOF_TARGET_HKH_SECTION = 69, @@ -219,5 +222,78 @@ UdVerifyInfo::UdVerifyInfo(const char* i_compId, l_pBuf+=PARSER_SIZEOF_SHA512_t; } + +//------------------------------------------------------------------------------ +// SECURE Node Communications Info User Details +//------------------------------------------------------------------------------ +UdNodeCommInfo::UdNodeCommInfo(const uint8_t i_opType, + const uint64_t i_buflen, + const int64_t i_accessType, + const NODECOMM::node_comm_args_t i_args ) + +{ + // Set up Ud instance variables + iv_CompId = SECURE_COMP_ID; + iv_Version = SECURE_UDT_VERSION_1; + iv_SubSection = SECURE_UDT_NODECOMM_INFO; + + //***** Node Comm SECURE_UDT_VERSION_1 Memory Layout ***** + // 4 bytes : Target HUID + // 8 bytes : Length of In/Out Buffer + // 8 bytes : Access Type (DeviceFW::AccessType) + // 1 byte : Op Type (DeviceFW::OperationType) + // 1 byte : Mode (XBUS or ABUS) + // 1 byte : LinkId + // 1 byte : MboxId + + static_assert(sizeof(uint64_t)==PARSER_SIZEOF_UINT64_t, + "Expected sizeof(uint64_t) is 8"); + + // These are necessary to keep the parsing in errludP_secure.H correct + static_assert(DeviceFW::READ==0, "Expected opType READ == 0"); + static_assert(DeviceFW::WRITE==1, "Expected opType WRITE == 1"); + static_assert(SECUREBOOT::NODECOMM::NCDD_MODE_XBUS==0, + "Expected NCDD_MODE_XBUS==0"); + static_assert(SECUREBOOT::NODECOMM::NCDD_MODE_ABUS==1, + "Expected NCDD_MODE_ABUS==1"); + + char * l_pBuf = reinterpret_cast( + reallocUsrBuf(sizeof(uint32_t) + +sizeof(uint64_t)*2 + +sizeof(uint8_t)*4 ) ); + uint64_t tmp64 = 0; + uint32_t tmp32 = 0; + uint8_t tmp8 = 0; + + tmp32 = i_args.tgt_huid; + memcpy(l_pBuf, &tmp32, sizeof(tmp32)); + l_pBuf += sizeof(tmp32); + + tmp64 = i_buflen; + memcpy(l_pBuf, &tmp64, sizeof(tmp64)); + l_pBuf += sizeof(tmp64); + + tmp64 = i_accessType; + memcpy(l_pBuf, &tmp64, sizeof(tmp64)); + l_pBuf += sizeof(tmp64); + + tmp8 = i_opType; + memcpy(l_pBuf, &tmp8, sizeof(tmp8)); + l_pBuf += sizeof(tmp8); + + tmp8 = i_args.mode; + memcpy(l_pBuf, &tmp8, sizeof(tmp8)); + l_pBuf += sizeof(tmp8); + + tmp8 = i_args.linkId; + memcpy(l_pBuf, &tmp8, sizeof(tmp8)); + l_pBuf += sizeof(tmp8); + + tmp8 = i_args.mboxId; + memcpy(l_pBuf, &tmp8, sizeof(tmp8)); + l_pBuf += sizeof(tmp8); + +}; + } // end SECUREBOOT namespace diff --git a/src/usr/secureboot/common/errlud_secure.H b/src/usr/secureboot/common/errlud_secure.H index 1e05399b1..86c03fb08 100644 --- a/src/usr/secureboot/common/errlud_secure.H +++ b/src/usr/secureboot/common/errlud_secure.H @@ -33,6 +33,8 @@ #include #include +#include +#include "../node_comm/node_comm_dd.H" namespace SECUREBOOT { @@ -223,6 +225,54 @@ class UdVerifyInfo : public ERRORLOG::ErrlUserDetails UdVerifyInfo& operator = (UdVerifyInfo&&) = delete; }; +/** + * @class UdNodeCommInfo + * + * Adds information about the Node Communications Operation to an + * error log as user detail data + */ +class UdNodeCommInfo : public ERRORLOG::ErrlUserDetails +{ + public: + /** + * @brief Constructor + * + * @param i_opType Operation Type + * @param i_buflen Length of In/Out Buffer + * @param i_accessType Access Type + * @param i_args Miscellaneous Parameters + */ + UdNodeCommInfo(const uint8_t i_opType, + const uint64_t i_buflen, + const int64_t i_accessType, + const NODECOMM::node_comm_args_t i_args ); + + /** + * @brief Destructor + */ + virtual ~UdNodeCommInfo() {} + + /** + * Delete Copy Constructor + */ + UdNodeCommInfo(const UdNodeCommInfo&) = delete; + + /** + * Delete Copy Assignment + */ + UdNodeCommInfo& operator= (const UdNodeCommInfo&) = delete; + + /** + * Delete Move Constructor + */ + UdNodeCommInfo (UdNodeCommInfo&&) = delete; + + /** + * Delete Move Assignment + */ + UdNodeCommInfo& operator = (UdNodeCommInfo&&) = delete; +}; + } // end SECUREBOOT namespace #endif diff --git a/src/usr/secureboot/common/plugins/errludP_secure.H b/src/usr/secureboot/common/plugins/errludP_secure.H index 817967bbf..acdf3032e 100644 --- a/src/usr/secureboot/common/plugins/errludP_secure.H +++ b/src/usr/secureboot/common/plugins/errludP_secure.H @@ -334,6 +334,108 @@ class UdParserVerifyInfo : public ERRORLOG::ErrlUserDetailsParser UdParserVerifyInfo & operator=(const UdParserVerifyInfo&); }; +/** + * @class UdParserNodeCommInfo + * + * Parses UdSecureNodeCommInfo + */ +class UdParserNodeCommInfo : public ERRORLOG::ErrlUserDetailsParser +{ + public: + /** + * @brief Constructor + */ + UdParserNodeCommInfo() {} + + /** + * @brief Destructor + */ + virtual ~UdParserNodeCommInfo() {} + + /** + * @brief Parses information from Node Communications operation + * user detail data from an error log + * + * @param i_version Version of the data + * @param i_parse ErrlUsrParser object for outputting information + * @param i_pBuffer Pointer to buffer containing detail data + * @param i_buflen Length of the buffer + */ + virtual void parse(errlver_t i_version, + ErrlUsrParser & i_parser, + void * i_pBuffer, + const uint32_t i_buflen) const + { + + //***** Node Comm SECURE_UDT_VERSION_1 Memory Layout ***** + // 4 bytes : Target HUID + // 8 bytes : Length of In/Out Buffer + // 8 bytes : Access Type (DeviceFW::AccessType) + // 1 byte : Op Type (DeviceFW::OperationType) + // 1 byte : Mode (XBUS or ABUS) + // 1 byte : LinkId + // 1 byte : MboxId + + char* l_databuf = static_cast(i_pBuffer); + bool l_parseError = false; + + do + { + i_parser.PrintHeading("Secure Node Comm Info"); + + i_parser.PrintNumber("Target HUID 0x","%.8lX",TO_UINT32(l_databuf)); + l_databuf += sizeof(uint32_t); + i_parser.PrintNumber("Length I/O Buff 0x","%.16lX",TO_UINT64(l_databuf)); + l_databuf += sizeof(uint64_t); + i_parser.PrintNumber("Access Type 0x","%.16lX",TO_UINT64(l_databuf)); + l_databuf += sizeof(uint64_t); + + uint8_t op = TO_UINT8(l_databuf); + if( op == 0 ) + { + i_parser.PrintHeading("Node Comm Read"); + } + else if( op == 1 ) + { + i_parser.PrintHeading("Node Comm Write"); + } + else + { + i_parser.PrintHeading("Unknown Node Comm Operation"); + } + i_parser.PrintNumber("Op Type Value 0x","%.2lX",TO_UINT8(l_databuf)); + l_databuf += sizeof(uint8_t); + + + op = TO_UINT8(l_databuf); + if( op == 0 ) + { + i_parser.PrintHeading("Node Comm Mode: XBUS"); + } + else if( op == 1 ) + { + i_parser.PrintHeading("Node Comm Mode: ABUS"); + } + else + { + i_parser.PrintHeading("INVALID Node Comm Mode"); + } + i_parser.PrintNumber("MODE 0x","%.2lX",TO_UINT8(l_databuf)); + l_databuf += sizeof(uint8_t); + + i_parser.PrintNumber("LinkId 0x","%.2lX",TO_UINT8(l_databuf)); + l_databuf += sizeof(uint8_t); + i_parser.PrintNumber("MboxId 0x","%.2lX",TO_UINT8(l_databuf)); + l_databuf += sizeof(uint8_t); + + } while(0); + } + + private: + // Disabled + UdParserNodeCommInfo(const UdParserNodeCommInfo&); + UdParserNodeCommInfo & operator=(const UdParserNodeCommInfo&); +}; } // end SECUREBOOT namespace diff --git a/src/usr/secureboot/common/plugins/secureUdParserFactory.H b/src/usr/secureboot/common/plugins/secureUdParserFactory.H index d720c1ce1..de03ab83a 100644 --- a/src/usr/secureboot/common/plugins/secureUdParserFactory.H +++ b/src/usr/secureboot/common/plugins/secureUdParserFactory.H @@ -47,6 +47,9 @@ namespace SECUREBOOT registerParser (SECURE_UDT_VERIFY_INFO); + + registerParser + (SECURE_UDT_NODECOMM_INFO); } private: diff --git a/src/usr/secureboot/node_comm/node_comm.C b/src/usr/secureboot/node_comm/node_comm.C index b47f78273..cee5da939 100644 --- a/src/usr/secureboot/node_comm/node_comm.C +++ b/src/usr/secureboot/node_comm/node_comm.C @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,6 @@ #include "node_comm.H" - using namespace TARGETING; namespace SECUREBOOT @@ -162,6 +162,9 @@ errlHndl_t nodeCommMapAttn(TARGETING::Target* i_pProc, HWAS::NO_DECONFIG, HWAS::GARD_NULL ); + // Collect FFDC + getNodeCommFFDC(i_mode, i_pProc, err); + err->collectTrace(SECURE_COMP_NAME); err->collectTrace(NODECOMM_TRACE_NAME); @@ -194,6 +197,71 @@ errlHndl_t nodeCommMapAttn(TARGETING::Target* i_pProc, } // end of nodeCommMapAttn + +/** + * @brief Add FFDC for the target to an error log + */ +void getNodeCommFFDC( node_comm_modes_t i_mode, + TARGETING::Target* i_pProc, + errlHndl_t &io_log) +{ + TRACFCOMP(g_trac_nc,ENTER_MRK + "getNodeCommFFDC: tgt=0x%X, mode=%s, err_plid=0x%X", + get_huid(i_pProc), + (i_mode == NCDD_MODE_ABUS) + ? NCDD_ABUS_STRING : NCDD_XBUS_STRING, + ERRL_GETPLID_SAFE(io_log)); + + do + { + if (io_log == nullptr) + { + TRACFCOMP(g_trac_nc,INFO_MRK"getNodeCommFFDC: io_log==nullptr, so " + "no FFDC has been collected for tgt=0x%X, mode=%s", + get_huid(i_pProc), + (i_mode == NCDD_MODE_ABUS) + ? NCDD_ABUS_STRING : NCDD_XBUS_STRING); + break; + } + + // Add Target to log + ERRORLOG::ErrlUserDetailsTarget(i_pProc,"Proc Target").addToLog(io_log); + + // Add HW regs + ERRORLOG::ErrlUserDetailsLogRegister ffdc(i_pProc); + + // FIR/Control/Status/Data Registers + ffdc.addData(DEVICE_SCOM_ADDRESS(getLinkMboxRegAddr(NCDD_REG_FIR,i_mode))); + ffdc.addData(DEVICE_SCOM_ADDRESS(getLinkMboxRegAddr(NCDD_REG_CTRL,i_mode))); + ffdc.addData(DEVICE_SCOM_ADDRESS(getLinkMboxRegAddr(NCDD_REG_DATA,i_mode))); + + // Loop Through All of the Mailbox Registers Where the Data Could End Up + uint64_t l_reg = 0; + const auto max_linkId = (i_mode==NCDD_MODE_ABUS) + ? NCDD_MAX_ABUS_LINK_ID + : NCDD_MAX_XBUS_LINK_ID; + + for (size_t linkId=0; linkId <= max_linkId ; ++linkId) + { + for (size_t mboxId=0; mboxId <= NCDD_MAX_MBOX_ID; ++mboxId) + { + l_reg = getLinkMboxReg(linkId, mboxId); + ffdc.addData(DEVICE_SCOM_ADDRESS(getLinkMboxRegAddr(l_reg,i_mode))); + } + } + + ffdc.addToLog(io_log); + + + } while( 0 ); + + TRACFCOMP(g_trac_nc,EXIT_MRK"getNodeCommFFDC"); + + return; + +} // end of getNodeCommFFDC + + } // End NODECOMM namespace } // End SECUREBOOT namespace diff --git a/src/usr/secureboot/node_comm/node_comm.H b/src/usr/secureboot/node_comm/node_comm.H index 60a6dcae7..4e8cc97a6 100644 --- a/src/usr/secureboot/node_comm/node_comm.H +++ b/src/usr/secureboot/node_comm/node_comm.H @@ -72,8 +72,8 @@ enum node_comm_registers_t : uint64_t NCDD_REG_CTRL = 0x501342E, NCDD_REG_DATA = 0x501342F, - //MailBox Registers: - NCDD_REG_LINK_MBOX_00 = 0x5013430, //(secure) + //MailBox Registers: + NCDD_REG_LINK_MBOX_00 = 0x5013430, //(secure) /* These registers are calculated by getLinkMboxReg() below NCDD_REG_LINK_MBOX_01 = 0x5013431, @@ -154,6 +154,19 @@ errlHndl_t nodeCommMapAttn(TARGETING::Target* i_pProc, uint64_t & o_linkId, uint64_t & o_mboxId); +/** + * @brief Add FFDC for the target to an error log + * + * @param[in] i_mode Specifies XBUS or ABUS mode + * @param[in] i_pProc Proc Chip Target used to collect info from + * @param[in,out] io_log Error Log to add FFDC to + * + * @return void + */ +void getNodeCommFFDC(node_comm_modes_t i_mode, + TARGETING::Target* i_pProc, + errlHndl_t &io_log); + } // end NODECOMM namespace } // end SECUREBOOT namespace diff --git a/src/usr/secureboot/node_comm/node_comm_dd.C b/src/usr/secureboot/node_comm/node_comm_dd.C index 5029068fc..f2eac3572 100644 --- a/src/usr/secureboot/node_comm/node_comm_dd.C +++ b/src/usr/secureboot/node_comm/node_comm_dd.C @@ -42,8 +42,10 @@ #include #include #include + #include "node_comm_dd.H" #include "node_comm.H" +#include "../common/errlud_secure.H" // ---------------------------------------------- // Globals @@ -197,7 +199,19 @@ errlHndl_t nodeCommPerformOp( DeviceFW::OperationType i_opType, err->collectTrace(SECURE_COMP_NAME); err->collectTrace(NODECOMM_TRACE_NAME); - // @TODO RTC:191008 Add FFDC - call to new UserDetails Section + UdNodeCommInfo(i_opType, + io_buflen, + i_accessType, + node_comm_args) + .addToLog(err); + + if (err->reasonCode() != RC_NCDD_INVALID_ARGS) + { + // Collect FFDC - Target and Registers + getNodeCommFFDC(node_comm_args.mode, + node_comm_args.tgt, + err); + } } TRACFCOMP (g_trac_nc, EXIT_MRK"nodeCommPerformOp: %s: %s: " @@ -531,6 +545,30 @@ errlHndl_t ncddWaitForCmdComp (node_comm_args_t & i_args) } // end ncddWaitForCmdComp + +void ncddHandleError( errlHndl_t & io_err, + node_comm_args_t & i_args ) +{ + TRACFCOMP( g_trac_nc,ENTER_MRK"ncddHandleError: " + TRACE_ERR_FMT, + TRACE_ERR_ARGS(io_err)); + + do + { +// @TODO RTC:191008 Implement simple reset functionality + + } while (0); + + TRACFCOMP( g_trac_nc,EXIT_MRK"ncddHandleError: " + TRACE_ERR_FMT, + TRACE_ERR_ARGS(io_err)); + + return; + +} // end ncddHandleError + + + errlHndl_t ncddRegisterOp ( DeviceFW::OperationType i_opType, uint64_t * io_data_64, uint64_t i_reg, diff --git a/src/usr/secureboot/node_comm/node_comm_dd.H b/src/usr/secureboot/node_comm/node_comm_dd.H index a42ce7fd0..10b6be99e 100644 --- a/src/usr/secureboot/node_comm/node_comm_dd.H +++ b/src/usr/secureboot/node_comm/node_comm_dd.H @@ -179,14 +179,13 @@ errlHndl_t ncddWaitForCmdComp (node_comm_args_t & i_args); * @brief Analyzes an error handle object and performs any * reset activity, if necessary * - * @param[in] i_err - The error to analyze - * @param[in] i_args - miscellaneous arguments + * @param[in/out] io_err - The error to analyze + * @param[in] i_args - miscellaneous arguments * * @return void */ -// @TODO RTC:191008 Implement simple reset functionality -void ncddHandleError( errlHndl_t & i_err, - node_comm_args_t & i_args ){}; +void ncddHandleError( errlHndl_t & io_err, + node_comm_args_t & i_args ); /** diff --git a/src/usr/secureboot/node_comm/node_comm_test.C b/src/usr/secureboot/node_comm/node_comm_test.C index 6b034361a..3c9842138 100644 --- a/src/usr/secureboot/node_comm/node_comm_test.C +++ b/src/usr/secureboot/node_comm/node_comm_test.C @@ -263,6 +263,9 @@ errlHndl_t nodeCommXbus2ProcTest(void) HWAS::NO_DECONFIG, HWAS::GARD_NULL ); + // Collect FFDC + getNodeCommFFDC(mode,read_tgt, err); + } } while( 0 ); @@ -278,7 +281,7 @@ errlHndl_t nodeCommXbus2ProcTest(void) err->collectTrace(SECURE_COMP_NAME); err->collectTrace(NODECOMM_TRACE_NAME); - // @TODO RTC:191008 Delete for now as it will fail in simics and + // @TODO RTC:184518 Delete for now as it will fail in simics and // cause a processor deconfig. delete err; err = nullptr; -- cgit v1.2.1