diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2013-08-12 10:42:41 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-09-13 13:09:17 -0500 |
commit | 907bd272887a4223e233091172a6a6e5f29cb05a (patch) | |
tree | 599d0e14d59908fdd8f1b06f202d87746ab8b122 /src/usr/fsiscom | |
parent | b614caa4f28616bba6e27625e4430083f53679b8 (diff) | |
download | talos-hostboot-907bd272887a4223e233091172a6a6e5f29cb05a.tar.gz talos-hostboot-907bd272887a4223e233091172a6a6e5f29cb05a.zip |
FSI SCOM Error Handling
Change-Id: I1538fbf386d5480e473f3f0b049492d494412624
RTC: 35064
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5825
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/fsiscom')
-rw-r--r-- | src/usr/fsiscom/fsiscom.C | 140 | ||||
-rw-r--r-- | src/usr/fsiscom/fsiscom.H | 62 | ||||
-rw-r--r-- | src/usr/fsiscom/test/fsiscomtest.H | 133 | ||||
-rw-r--r-- | src/usr/fsiscom/test/makefile | 32 |
4 files changed, 258 insertions, 109 deletions
diff --git a/src/usr/fsiscom/fsiscom.C b/src/usr/fsiscom/fsiscom.C index d87a6f393..0c3e94361 100644 --- a/src/usr/fsiscom/fsiscom.C +++ b/src/usr/fsiscom/fsiscom.C @@ -28,14 +28,18 @@ #include <trace/interface.H> #include <errl/errlentry.H> #include <errl/errlmanager.H> +#include <errl/errludtarget.H> +#include <xscom/piberror.H> #include <fsiscom/fsiscom_reasoncodes.H> +#include <fsi/fsiif.H> +#include <sys/time.h> #include "fsiscom.H" //Globals/Constants // Trace definition trace_desc_t* g_trac_fsiscom = NULL; -TRAC_INIT(&g_trac_fsiscom, "FSISCOM", 2*KILOBYTE); //2K +TRAC_INIT(&g_trac_fsiscom, FSISCOM_COMP_NAME, 2*KILOBYTE); //2K // Easy macro replace for unit testing //#define TRACUCOMP(args...) TRACFCOMP(args) @@ -54,8 +58,55 @@ union ioData6432 }; }; -//@fixme - not full tested due to simics instability. Will full test when -// enabling the scom test cases. +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +void pib_error_handler( TARGETING::Target* i_target, + errlHndl_t i_errlog, + uint32_t i_status ) +{ + //Add this target to the FFDC + ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target").addToLog(i_errlog); + + //Add the callouts for the specific PCB/PIB error + uint32_t pib_error = i_status >> 12; + PIB::addFruCallouts( i_target, + pib_error, + i_errlog ); + + //Grab the PIB2OPB Status reg for a Resource Occupied error + if( pib_error == PIB::PIB_RESOURCE_OCCUPIED ) //piberr=001 + { + FSI::getFsiFFDC( FSI::FFDC_PIB_FAIL, + i_errlog, + i_target ); + } + + //Recovery sequence from Markus + // if SCOM fails and FSI Master displays "MasterTimeOut" + // then 7,6 <covered by FSI driver> + // else if SCOM fails and FSI2PIB Status shows PIB abort + // then just perform unit reset (6) and wait 1 ms + // else (PIB_abort='0' but PIB error is unequal 0) + // then just perform unit reset (6) (wait not needed). + uint32_t l_command = 0; + size_t op_size = sizeof(uint32_t); + errlHndl_t l_err = DeviceFW::deviceOp( DeviceFW::WRITE, + i_target, + &l_command, + op_size, + DEVICE_FSI_ADDRESS(ENGINE_RESET_REG)); + if(l_err) + { + TRACFCOMP( g_trac_fsiscom, + ERR_MRK"Error resetting FSI : %.4X", + ERRL_GETRC_SAFE(l_err) ); + l_err->plid(i_errlog->plid()); + errlCommit(l_err,FSISCOM_COMP_ID); + } + + nanosleep( 0,NS_PER_MSEC ); //sleep for ms + +} /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -87,36 +138,41 @@ errlHndl_t fsiScomPerformOp(DeviceFW::OperationType i_opType, * @reasoncode FSISCOM::RC_INVALID_LENGTH * @userdata1 SCOM Address * @userdata2 Data Length - * @devdesc FSISCOM: fsiScomPerformOp> Invalid data length (!= 8 bytes) + * @devdesc fsiScomPerformOp> Invalid data length (!= 8 bytes) */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, FSISCOM::MOD_FSISCOM_PERFORMOP, FSISCOM::RC_INVALID_LENGTH, l_scomAddr, TO_UINT64(io_buflen)); - //@fixme: Need to callout target somehow. Need to decide how to callout target and where - // it should be done (this layer or somewhere higher in the call stack?) + l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_LOW ); + ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). + addToLog(l_err); break; } if( (l_scomAddr & 0xFFFFFFFF80000000) != 0) { - TRACFCOMP( g_trac_fsiscom, ERR_MRK "fsiScomPerformOp> Address contains more than 31 bits : l_scomAddr=0x%.8x", l_scomAddr ); + TRACFCOMP( g_trac_fsiscom, ERR_MRK "fsiScomPerformOp> Address contains more than 31 bits : l_scomAddr=0x%.16X", l_scomAddr ); /*@ * @errortype * @moduleid FSISCOM::MOD_FSISCOM_PERFORMOP * @reasoncode FSISCOM::RC_INVALID_ADDRESS * @userdata1 SCOM Address * @userdata2 0 - * @devdesc FSISCOM: fsiScomPerformOp> Address contains more than 31 bits. + * @devdesc fsiScomPerformOp> Address contains + * more than 31 bits. */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, FSISCOM::MOD_FSISCOM_PERFORMOP, FSISCOM::RC_INVALID_ADDRESS, l_scomAddr, - 0); - //@fixme: Need to callout target somehow. Need to decide how to callout target and where - // it should be done (this layer or somewhere higher in the call stack?) + TARGETING::get_huid(i_target)); + l_err->addProcedureCallout( HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_LOW ); + ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). + addToLog(l_err); break; } @@ -183,12 +239,9 @@ errlHndl_t fsiScomPerformOp(DeviceFW::OperationType i_opType, break; } - // atomic section << - need_unlock = false; - mutex_unlock(l_mutex); - - //bits 17-19 indicates PCB/PIB error - if(l_status & 0x00007000) + // Check the status reg for errors + if( (l_status & PIB_ERROR_BITS) // PCB/PIB Errors + || (l_status & PIB_ABORT_BIT) ) // PIB Abort { TRACFCOMP( g_trac_fsiscom, ERR_MRK"fsiScomPerformOp:Write: PCB/PIB error received: l_status=0x%X)", l_status); /*@ @@ -197,17 +250,18 @@ errlHndl_t fsiScomPerformOp(DeviceFW::OperationType i_opType, * @reasoncode FSISCOM::RC_WRITE_ERROR * @userdata1 SCOM Addr * @userdata2 SCOM Status Reg - * @devdesc fsiScomPerformOp> Error returned from SCOM Engine after write + * @devdesc fsiScomPerformOp> Error returned + * from SCOM Engine after write */ - l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - FSISCOM::MOD_FSISCOM_PERFORMOP, - FSISCOM::RC_WRITE_ERROR, - l_scomAddr, - TO_UINT64(l_status)); + l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + FSISCOM::MOD_FSISCOM_PERFORMOP, + FSISCOM::RC_WRITE_ERROR, + l_scomAddr, + TO_UINT64(l_status)); - //@fixme: Need to callout target somehow. Need to decide how to callout target and where - // it should be done (this layer or somewhere higher in the call stack?) - //@todo: May add recover actions later. Currently undefined + // call common error handler to do callouts and recovery + pib_error_handler( i_target, l_err, l_status ); //Grab the PIB2OPB Status reg for a XSCOM Block error if( (l_status & 0x00007000) == 0x00001000 ) //piberr=001 @@ -234,8 +288,9 @@ errlHndl_t fsiScomPerformOp(DeviceFW::OperationType i_opType, break; } - - + // atomic section << + need_unlock = false; + mutex_unlock(l_mutex); } else if(i_opType == DeviceFW::READ) { @@ -269,8 +324,9 @@ errlHndl_t fsiScomPerformOp(DeviceFW::OperationType i_opType, break; } - //bits 17-19 indicates PCB/PIB error - if((l_status & 0x00007000) != 0) + // Check the status reg for errors + if( (l_status & PIB_ERROR_BITS) // PCB/PIB Errors + || (l_status & PIB_ABORT_BIT) ) // PIB Abort { TRACFCOMP( g_trac_fsiscom, ERR_MRK"fsiScomPerformOp:Read: PCB/PIB error received: l_status=0x%0.8X)", l_status); @@ -288,9 +344,9 @@ errlHndl_t fsiScomPerformOp(DeviceFW::OperationType i_opType, l_scomAddr, TO_UINT64(l_status)); - //@fixme: Need to callout target somehow. Need to decide how to callout target and where - // it should be done (this layer or somewhere higher in the call stack?) - //@todo: May add recover actions later. Currently undefined + // call common error handler to do callouts and recovery + pib_error_handler( i_target, l_err, l_status ); + break; } @@ -332,18 +388,24 @@ errlHndl_t fsiScomPerformOp(DeviceFW::OperationType i_opType, * @errortype * @moduleid FSISCOM::MOD_FSISCOM_PERFORMOP * @reasoncode FSISCOM::RC_INVALID_OPTYPE - * @userdata1 Operation Type (i_opType) : 0=READ, 1=WRITE - * @userdata2 0 + * @userdata1[0:31] Operation Type (i_opType) : 0=READ, 1=WRITE + * @userdata1[32:64] Input scom address + * @userdata2 Target HUID * @devdesc fsiScomPerformOp> Unsupported Operation Type specified */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, FSISCOM::MOD_FSISCOM_PERFORMOP, FSISCOM::RC_INVALID_OPTYPE, - TO_UINT64(i_opType), - 0); + TWO_UINT32_TO_UINT64(i_opType, + l_scomAddr), + TARGETING::get_huid(i_target)); + //Add this target to the FFDC + ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target"). + addToLog(l_err); + + l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH); - //@fixme: Need to callout target somehow. Need to decide how to callout target and where - // it should be done (this layer or somewhere higher in the call stack?) break; } diff --git a/src/usr/fsiscom/fsiscom.H b/src/usr/fsiscom/fsiscom.H index 62ed12f27..0c17946b3 100644 --- a/src/usr/fsiscom/fsiscom.H +++ b/src/usr/fsiscom/fsiscom.H @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/fsiscom/fsiscom.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fsiscom/fsiscom.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __FSISCOM_H #define __FSISCOM_H @@ -31,12 +31,18 @@ namespace FSISCOM { enum { - //FSI addresses are byte offsets, so need to multiply by 4 since each register is 4 bytes long. - //prefix with 0x10xx for engine offset - DATA0_REG = 0x1000, /* SCOM Data Register 0 (0x00) */ - DATA1_REG = 0x1004, /* SCOM Data Register 1 (0x01) */ - COMMAND_REG = 0x1008, /* SCOM Command Register (0x02) */ - STATUS_REG = 0x101C, /* STATUS Register (0x07) */ + //FSI addresses are byte offsets, so need to multiply by 4 + // since each register is 4 bytes long. + // prefix with 0x10xx for FSI2PIB engine offset + DATA0_REG = 0x1000, /* SCOM Data Register 0 (0x00) */ + DATA1_REG = 0x1004, /* SCOM Data Register 1 (0x01) */ + COMMAND_REG = 0x1008, /* SCOM Command Register (0x02) */ + ENGINE_RESET_REG = 0x1018, /* Engine Reset Register (0x06) */ + STATUS_REG = 0x101C, /* STATUS Register (0x07) */ + PIB_RESET_REG = 0x101C, /* PIB Reset Register (0x07) */ + + PIB_ABORT_BIT = 0x00100000, /* 12= PIB Abort */ + PIB_ERROR_BITS = 0x00007000, /* 17:19= PCB/PIB Errors */ }; /** diff --git a/src/usr/fsiscom/test/fsiscomtest.H b/src/usr/fsiscom/test/fsiscomtest.H index 5c570793b..16481987d 100644 --- a/src/usr/fsiscom/test/fsiscomtest.H +++ b/src/usr/fsiscom/test/fsiscomtest.H @@ -1,43 +1,124 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/fsiscom/test/fsiscomtest.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fsiscom/test/fsiscomtest.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #include <cxxtest/TestSuite.H> #include <errl/errlmanager.H> #include <errl/errlentry.H> #include <limits.h> #include <devicefw/driverif.H> +#include <fsiscom/fsiscom_reasoncodes.H> +extern trace_desc_t* g_trac_fsiscom; class FsiScomTest : public CxxTest::TestSuite { public: /** - * @brief test1 + * @brief Test error path and recovery */ - void test_fsiScom(void) + void test_Error(void) { + TRACFCOMP( g_trac_fsiscom, "FsiScomTest::test_Error> Start" ); - //FSISCOM testing driving by SCOM device driver. This allows for testing FSISCOM <-> XSCOM - //coherency. + //@fixme: RTC:80081 + TRACFCOMP( g_trac_fsiscom, "FsiScomTest::test_Error> Disabling test until D892724 is in a build" ); +#if 0 + uint64_t fails = 0; + uint64_t total = 0; + errlHndl_t l_err = NULL; + uint64_t regdata = 0; + size_t op_size = sizeof(uint64_t); + + // Centaur target + TARGETING::EntityPath epath(TARGETING::EntityPath::PATH_PHYSICAL); + epath.addLast(TARGETING::TYPE_SYS,0); + epath.addLast(TARGETING::TYPE_NODE,0); + epath.addLast(TARGETING::TYPE_MEMBUF,4); + TARGETING::Target* fsi_target = + TARGETING::targetService().toTarget(epath); + if( fsi_target == NULL ) + { + TRACFCOMP( g_trac_fsiscom, "FsiScomTest::test_Error> Target is NULL" ); + TS_FAIL( "FsiScomTest::test_Error> Target is NULL" ); + } + + // Bad address read + total++; + l_err = DeviceFW::deviceOp( + DeviceFW::READ, + fsi_target, + ®data, + op_size, + DEVICE_FSISCOM_ADDRESS(0x11111111) ); + if( l_err && (l_err->reasonCode() == FSISCOM::RC_READ_ERROR) ) + { + delete l_err; + } + else + { + TRACFCOMP(g_trac_fsiscom, "FsiScomTest::test_Error> No/wrong error for bad address read, RC=%X", ERRL_GETRC_SAFE(l_err) ); + TS_FAIL( "FsiScomTest::test_Error> No/wrong error for bad address read" ); + fails++; + if( l_err ) { errlCommit(l_err,FSISCOM_COMP_ID); } + } + + // Bad address write + total++; + l_err = DeviceFW::deviceOp( + DeviceFW::WRITE, + fsi_target, + ®data, + op_size, + DEVICE_FSISCOM_ADDRESS(0x00222222) ); + if( l_err && (l_err->reasonCode() == FSISCOM::RC_WRITE_ERROR) ) + { + delete l_err; + } + else + { + TRACFCOMP(g_trac_fsiscom, "FsiScomTest::test_Error> No/wrong error for bad address write, RC=%X", ERRL_GETRC_SAFE(l_err) ); + TS_FAIL( "FsiScomTest::test_Error> No/wrong error for bad address write" ); + fails++; + if( l_err ) { errlCommit(l_err,FSISCOM_COMP_ID); } + } + + // Do a good scom to prove things are working again + total++; + l_err = DeviceFW::deviceOp( + DeviceFW::READ, + fsi_target, + ®data, + op_size, + DEVICE_FSISCOM_ADDRESS(0x02011403) ); + if( l_err ) + { + TRACFCOMP(g_trac_fsiscom, "FsiScomTest::test_Error> Error reading 0x02011403, RC=%X", ERRL_GETRC_SAFE(l_err) ); + TS_FAIL( "FsiScomTest::test_Error> Error reading 0x02011403" ); + fails++; + errlCommit(l_err,FSISCOM_COMP_ID); + } + + TRACFCOMP( g_trac_fsiscom, "FsiScomTest::test_Error> %d/%d fails", fails, total ); +#endif }; }; diff --git a/src/usr/fsiscom/test/makefile b/src/usr/fsiscom/test/makefile index b6c001ea8..7753f9a1a 100644 --- a/src/usr/fsiscom/test/makefile +++ b/src/usr/fsiscom/test/makefile @@ -1,29 +1,29 @@ -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. # -# $Source: src/usr/fsiscom/test/makefile $ +# $Source: src/usr/fsiscom/test/makefile $ # -# IBM CONFIDENTIAL +# IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2011 +# COPYRIGHT International Business Machines Corp. 2011,2013 # -# p1 +# p1 # -# Object Code Only (OCO) source materials -# Licensed Internal Code Source Materials -# IBM HostBoot Licensed Internal Code +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code # -# The source code for this program is not published or other- -# wise divested of its trade secrets, irrespective of what has -# been deposited with the U.S. Copyright Office. +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. # -# Origin: 30 +# Origin: 30 # -# IBM_PROLOG_END +# IBM_PROLOG_END_TAG ROOTPATH = ../../../.. -#MODULE = testfsiscom Disabled as we don't currently have any tests defined. -#TESTS = *.H +MODULE = testfsiscom +TESTS = *.H include ${ROOTPATH}/config.mk |