summaryrefslogtreecommitdiffstats
path: root/src/usr/fsiscom
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2013-08-12 10:42:41 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-09-13 13:09:17 -0500
commit907bd272887a4223e233091172a6a6e5f29cb05a (patch)
tree599d0e14d59908fdd8f1b06f202d87746ab8b122 /src/usr/fsiscom
parentb614caa4f28616bba6e27625e4430083f53679b8 (diff)
downloadtalos-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.C140
-rw-r--r--src/usr/fsiscom/fsiscom.H62
-rw-r--r--src/usr/fsiscom/test/fsiscomtest.H133
-rw-r--r--src/usr/fsiscom/test/makefile32
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,
+ &regdata,
+ 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,
+ &regdata,
+ 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,
+ &regdata,
+ 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
OpenPOWER on IntegriCloud