summaryrefslogtreecommitdiffstats
path: root/src/usr/fsiscom/fsiscom.C
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/fsiscom.C
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/fsiscom.C')
-rw-r--r--src/usr/fsiscom/fsiscom.C140
1 files changed, 101 insertions, 39 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;
}
OpenPOWER on IntegriCloud