summaryrefslogtreecommitdiffstats
path: root/src/usr/fsi
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2012-06-27 15:49:23 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-07-11 12:58:16 -0500
commit9ad69342d2d0621b534f0fcb41906c9fd96a60c3 (patch)
tree8c65efb69e3c940021ca6272759f90417ad6e6e5 /src/usr/fsi
parentf184b684beb77df5878662616bb23c205d5fae67 (diff)
downloadtalos-hostboot-9ad69342d2d0621b534f0fcb41906c9fd96a60c3.tar.gz
talos-hostboot-9ad69342d2d0621b534f0fcb41906c9fd96a60c3.zip
Use VPD to verify FSI presence detect
Changing the presence detect logic for the chips to look at VPD in addition to the FSI presence. Creates errors if they don't agree, except in VPO where FSI presence detection is busted. Change-Id: I17246413abad5c8cb78a9166606f666bb860c081 RTC: 44075 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1277 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/fsi')
-rw-r--r--src/usr/fsi/fsipres.C331
1 files changed, 287 insertions, 44 deletions
diff --git a/src/usr/fsi/fsipres.C b/src/usr/fsi/fsipres.C
index a22002a44..7332b09c3 100644
--- a/src/usr/fsi/fsipres.C
+++ b/src/usr/fsi/fsipres.C
@@ -1,43 +1,45 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/fsi/fsipres.C $
-//
-// 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/fsi/fsipres.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2011-2012
+ *
+ * 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_TAG
+ */
#include <devicefw/driverif.H>
#include <targeting/common/attributes.H>
+#include <fsi/fsiif.H>
#include <fsi/fsi_reasoncodes.H>
-#include "fsidd.H"
+#include <mvpd/mvpdenums.H>
+#include <errl/errlmanager.H>
+#include <targeting/common/predicates/predicatectm.H>
extern trace_desc_t* g_trac_fsi;
namespace FSI
{
-// Forward declaration from fsidd.C.
-bool isSlavePresent( const TARGETING::Target* i_target );
-
/**
- * @brief Performs a presence detect operation.
+ * @brief Performs a presence detect operation on a Processor Chip.
*
- * This function does FSI presence detect, following the pre-defined prototype
- * for a device-driver framework function.
+ * This function does FSI presence detect and compares it to the Module
+ * VPD that is present, following the pre-defined prototype for a
+ * device-driver framework function.
*
* @param[in] i_opType Operation type, see DeviceFW::OperationType
* in driverif.H
@@ -51,35 +53,38 @@ bool isSlavePresent( const TARGETING::Target* i_target );
* In this function, there are no arguments.
* @return errlHndl_t
*/
-errlHndl_t presenceDetect(DeviceFW::OperationType i_opType,
- TARGETING::Target* i_target,
- void* io_buffer,
- size_t& io_buflen,
- int64_t i_accessType,
- va_list i_args)
+errlHndl_t procPresenceDetect(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
{
+ errlHndl_t l_errl = NULL;
+
if (unlikely(io_buflen < sizeof(bool)))
{
TRACFCOMP(g_trac_fsi,
- ERR_MRK "FSI::presenceDetect> Invalid data length: %d",
+ ERR_MRK "FSI::procPresenceDetect> Invalid data length: %d",
io_buflen);
/*@
* @errortype
- * @moduleid FSI::MOD_FSIPRES_PRESENCEDETECT
+ * @moduleid FSI::MOD_FSIPRES_PROCPRESENCEDETECT
* @reasoncode FSI::RC_INVALID_LENGTH
* @userdata1 Data Length
* @devdesc presenceDetect> Invalid data length (!= 1 bytes)
*/
- errlHndl_t l_errl =
+ l_errl =
new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- FSI::MOD_FSIPRES_PRESENCEDETECT,
+ FSI::MOD_FSIPRES_PROCPRESENCEDETECT,
FSI::RC_INVALID_LENGTH,
TO_UINT64(io_buflen));
io_buflen = 0;
return l_errl;
}
- bool present = false;
+ // First look for FSI presence bits
+ bool fsi_present = false;
TARGETING::Target* l_masterChip = NULL;
TARGETING::targetService().masterProcChipTargetHandle(l_masterChip);
@@ -87,27 +92,265 @@ errlHndl_t presenceDetect(DeviceFW::OperationType i_opType,
if ((i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) ||
(i_target == l_masterChip))
{
- present = true;
+ fsi_present = true;
+ }
+ else
+ {
+ fsi_present = isSlavePresent(i_target);
+ }
+
+ // Next look for valid Module VPD by reading the PG record
+ bool mvpd_present = false;
+ size_t theSize = 0;
+ l_errl = deviceRead( i_target,
+ NULL,
+ theSize,
+ DEVICE_MVPD_ADDRESS( MVPD::CP00,
+ MVPD::VD ) );
+ if( l_errl )
+ {
+ if( fsi_present )
+ {
+ // commit this log because we expected to have VPD
+ errlCommit( l_errl,
+ FSI_COMP_ID );
+ }
+ else
+ {
+ // just delete this
+ delete l_errl;
+ }
+ }
+
+ if( theSize > 0 )
+ {
+ uint8_t theData[theSize];
+ l_errl = deviceRead( i_target,
+ theData,
+ theSize,
+ DEVICE_MVPD_ADDRESS( MVPD::CP00,
+ MVPD::VD ) );
+ if( l_errl )
+ {
+ if( fsi_present )
+ {
+ // commit this log because we expected to have VPD
+ errlCommit( l_errl,
+ FSI_COMP_ID );
+ }
+ else
+ {
+ // just delete this
+ delete l_errl;
+ }
+ }
+ else
+ {
+ mvpd_present = true;
+ }
+ }
+
+ //@fixme-RTC:35551 : FSI presence detection is wrong in VPO
+ // Force FSI to follow MVPD
+ if( (fsi_present != mvpd_present) && TARGETING::is_vpo() )
+ {
+ TRACFCOMP(g_trac_fsi,
+ ERR_MRK "FSI::procPresenceDetect> Lying about FSI presence for %.8X",
+ TARGETING::get_huid(i_target));
+ fsi_present = mvpd_present;
+ }
+
+ // Finally compare the 2 methods
+ if( fsi_present != mvpd_present )
+ {
+ TRACFCOMP(g_trac_fsi,
+ ERR_MRK "FSI::procPresenceDetect> FSI (=%d) and MVPD (=%d) do not agree for %.8X",
+ fsi_present, mvpd_present, TARGETING::get_huid(i_target));
+ /*@
+ * @errortype
+ * @moduleid FSI::MOD_FSIPRES_PROCPRESENCEDETECT
+ * @reasoncode FSI::RC_FSI_MVPD_MISMATCH
+ * @userdata1 HUID of processor
+ * @userdata2[0:31] FSI Presence
+ * @userdata2[32:63] MVPD Presence
+ * @devdesc presenceDetect> FSI and MVPD do not agree
+ */
+ l_errl =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSI::MOD_FSIPRES_PROCPRESENCEDETECT,
+ FSI::RC_FSI_MVPD_MISMATCH,
+ TWO_UINT32_TO_UINT64(
+ fsi_present,
+ mvpd_present));
+
+ //@todo-callout the processor
+ //l_errl->addHwCallout( i_target, LOW, NO_DECONFIG, NO_GARD );
+
+ // commit this log and move on
+ errlCommit( l_errl,
+ FSI_COMP_ID );
+ }
+
+
+ bool present = fsi_present & mvpd_present;
+ memcpy(io_buffer, &present, sizeof(present));
+ io_buflen = sizeof(present);
+
+ return NULL;
+}
+
+/**
+ * @brief Performs a presence detect operation on a Membuf Chip.
+ *
+ * This function does FSI presence detect, following the pre-defined prototype
+ * for a device-driver framework function.
+ *
+ * @param[in] i_opType Operation type, see DeviceFW::OperationType
+ * in driverif.H
+ * @param[in] i_target Presence detect target
+ * @param[in/out] io_buffer Read: Pointer to output data storage
+ * Write: Pointer to input data storage
+ * @param[in/out] io_buflen Input: size of io_buffer (in bytes, always 1)
+ * Output: Success = 1, Failure = 0
+ * @param[in] i_accessType DeviceFW::AccessType enum (userif.H)
+ * @param[in] i_args This is an argument list for DD framework.
+ * In this function, there are no arguments.
+ * @return errlHndl_t
+ */
+errlHndl_t membPresenceDetect(DeviceFW::OperationType i_opType,
+ TARGETING::Target* i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
+{
+ errlHndl_t l_errl = NULL;
+
+ if (unlikely(io_buflen < sizeof(bool)))
+ {
+ TRACFCOMP(g_trac_fsi,
+ ERR_MRK "FSI::membPresenceDetect> Invalid data length: %d",
+ io_buflen);
+ /*@
+ * @errortype
+ * @moduleid FSI::MOD_FSIPRES_MEMBPRESENCEDETECT
+ * @reasoncode FSI::RC_INVALID_LENGTH
+ * @userdata1 Data Length
+ * @devdesc presenceDetect> Invalid data length (!= 1 bytes)
+ */
+ l_errl =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSI::MOD_FSIPRES_MEMBPRESENCEDETECT,
+ FSI::RC_INVALID_LENGTH,
+ TO_UINT64(io_buflen));
+ io_buflen = 0;
+ return l_errl;
+ }
+
+ // First look for FSI presence bits
+ bool fsi_present = isSlavePresent(i_target);
+
+
+ //@todo-RTC:44254 : Switch to FRU VPD (vs DIMM)
+
+ // Next look for some associated DIMM VPD
+ bool vpd_present = false;
+
+ // find all of the CDIMMs associated with this membuf
+ TARGETING::PredicateCTM l_dimm(TARGETING::CLASS_LOGICAL_CARD,
+ TARGETING::TYPE_DIMM,
+ TARGETING::MODEL_CDIMM);
+ TARGETING::PredicatePostfixExpr dimm_query;
+ dimm_query.push(&l_dimm);
+
+ TARGETING::TargetHandleList dimm_list;
+ TARGETING::targetService().getAssociated(dimm_list,
+ i_target,
+ TARGETING::TargetService::CHILD_BY_AFFINITY,
+ TARGETING::TargetService::ALL,
+ &dimm_query);
+
+ if( dimm_list.empty() )
+ {
+ vpd_present = false;
}
else
+ {
+ size_t presentSize = sizeof(vpd_present);
+ for( TARGETING::TargetHandleList::iterator dimm = dimm_list.begin();
+ (dimm != dimm_list.end()) && !vpd_present && !l_errl;
+ ++dimm )
+ {
+ l_errl = deviceRead(*dimm,
+ &vpd_present,
+ presentSize,
+ DEVICE_PRESENT_ADDRESS());
+ }
+ if( l_errl )
+ {
+ // commit this log because we never expect this call to fail
+ errlCommit( l_errl,
+ FSI_COMP_ID );
+ }
+ }
+
+ //@fixme-RTC:35551 : FSI presence detection is wrong in VPO
+ // Force FSI to follow VPD
+ if( (fsi_present != vpd_present) && TARGETING::is_vpo() )
{
- present = isSlavePresent(i_target);
+ TRACFCOMP(g_trac_fsi,
+ ERR_MRK "FSI::membPresenceDetect> Lying about FSI presence for %.8X",
+ TARGETING::get_huid(i_target));
+ fsi_present = vpd_present;
}
+ // Finally compare the 2 methods
+ if( fsi_present != vpd_present )
+ {
+ TRACFCOMP(g_trac_fsi,
+ ERR_MRK "FSI::membPresenceDetect> FSI (=%d) and VPD (=%d) do not agree for %.8X",
+ fsi_present, vpd_present, TARGETING::get_huid(i_target));
+ /*@
+ * @errortype
+ * @moduleid FSI::MOD_FSIPRES_MEMBPRESENCEDETECT
+ * @reasoncode FSI::RC_FSI_MVPD_MISMATCH
+ * @userdata1 HUID of processor
+ * @userdata2[0:31] FSI Presence
+ * @userdata2[32:63] VPD Presence
+ * @devdesc presenceDetect> FSI and MVPD do not agree
+ */
+ l_errl =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ FSI::MOD_FSIPRES_MEMBPRESENCEDETECT,
+ FSI::RC_FSI_MVPD_MISMATCH,
+ TWO_UINT32_TO_UINT64(
+ fsi_present,
+ vpd_present));
+
+ //@todo-callout the membuf
+ //l_errl->addHwCallout( i_target, LOW, NO_DECONFIG, NO_GARD );
+
+ // commit this log and move on
+ errlCommit( l_errl,
+ FSI_COMP_ID );
+ }
+
+ bool present = fsi_present & vpd_present;
memcpy(io_buffer, &present, sizeof(present));
io_buflen = sizeof(present);
return NULL;
}
+
// Register as the presence detect for processor and memory buffers.
DEVICE_REGISTER_ROUTE(DeviceFW::READ,
DeviceFW::PRESENT,
TARGETING::TYPE_PROC,
- presenceDetect);
+ procPresenceDetect);
DEVICE_REGISTER_ROUTE(DeviceFW::READ,
DeviceFW::PRESENT,
TARGETING::TYPE_MEMBUF,
- presenceDetect);
+ membPresenceDetect);
};
OpenPOWER on IntegriCloud