summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDean Sanner <dsanner@us.ibm.com>2017-10-09 06:20:29 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2017-11-06 11:20:30 -0500
commit97f6525326d7ad9fa099be2b503a971c9325f503 (patch)
treeca00507985ae3805e22b672c82c6f94bbca183c1 /src
parentcb260675de9f4f9025e0fc99687f6776e5f1bbac (diff)
downloadtalos-hostboot-97f6525326d7ad9fa099be2b503a971c9325f503.tar.gz
talos-hostboot-97f6525326d7ad9fa099be2b503a971c9325f503.zip
Control Host reboots for manufacturing
In a manufacturing environment it is desired to reboot once (and only once) to get the FIRDATA analysis on checkstop. This commit adds functionality to control the auto reboot policy on the BMC. It then "remembers" the state using the HB VOLATILE PNOR partition to enable reboots when in MFG mode. Note that when in this mode, any reboot (even from host) will terminate the boot. Change-Id: If5ce133b59e10c659d7024d1ae08a40988e35190 RTC:180772 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/48116 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Corey V. Swenson <cswenson@us.ibm.com> Reviewed-by: Dean Sanner <dsanner@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/ipmi/ipmi_reasoncodes.H2
-rw-r--r--src/include/usr/ipmi/ipmisensor.H66
-rw-r--r--src/include/usr/isteps/istep_reasoncodes.H2
-rw-r--r--src/include/usr/util/utilsemipersist.H6
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C18
-rw-r--r--src/usr/ipmi/ipmisensor.C82
-rw-r--r--src/usr/isteps/istep06/host_set_ipl_parms.C3
-rw-r--r--src/usr/isteps/istep06/host_start_occ_xstop_handler.C113
-rw-r--r--src/usr/isteps/istep16/call_host_ipl_complete.C3
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/attribute_types.xml5
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/attribute_types_hb.xml5
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types_openpower.xml8
12 files changed, 288 insertions, 25 deletions
diff --git a/src/include/usr/ipmi/ipmi_reasoncodes.H b/src/include/usr/ipmi/ipmi_reasoncodes.H
index c8931bdb0..972391675 100644
--- a/src/include/usr/ipmi/ipmi_reasoncodes.H
+++ b/src/include/usr/ipmi/ipmi_reasoncodes.H
@@ -42,6 +42,7 @@ namespace IPMI
MOD_IPMISENSOR_TYPE = 0x08, // IPMI::getSensorType
MOD_IPMISENSOR_ENTITY_ID = 0x09, // IPMI::getSensorEntityId
MOD_IPMISENSOR_NAME = 0x0A, // IPMI::getSensorName
+ MOD_IPMISENSOR_REBOOTCNTRL = 0x0B, // IPMI::SENSOR getRebootControl
};
enum IPMIReasonCode
@@ -61,6 +62,7 @@ namespace IPMI
RC_SENSOR_NOT_FOUND = IPMI_COMP_ID | 0x0d,
RC_INVALID_VPD_DATA = IPMI_COMP_ID | 0x0e,
RC_INVALID_SENSOR_NUMBER = IPMI_COMP_ID | 0x0f,
+ RC_INVALID_SENSOR_SETTING = IPMI_COMP_ID | 0x10,
};
};
diff --git a/src/include/usr/ipmi/ipmisensor.H b/src/include/usr/ipmi/ipmisensor.H
index 5b59a45c5..15499ce13 100644
--- a/src/include/usr/ipmi/ipmisensor.H
+++ b/src/include/usr/ipmi/ipmisensor.H
@@ -635,6 +635,72 @@ namespace SENSOR
};
/**
+ * @class RebootControlSensor
+ *
+ * @brief Specialized class for the system reboot control
+ *
+ * @par Detailed Description:
+ * Provides the functionality needed to enable/disable auto reboot
+ * control controlled by the BMC.
+ *
+ * Usage:
+ * RebootControlSensor l_rbotCtl;
+ * l_rbotCtl.setRebootControl( autoRebootSetting::ENABLE_REBOOTS );
+ * l_rbotCtl.setRebootControl( autoRebootSetting::DISABLE_REBOOTS );
+ *
+ */
+ class RebootControlSensor : public SensorBase
+ {
+
+ public:
+ /**
+ * @enum autoRebootSetting
+ * enum to define the contr
+ */
+ enum autoRebootSetting
+ {
+ DISABLE_REBOOTS = 0x00, // keep current state
+ ENABLE_REBOOTS = 0x01, // allow reboot for FIRDATA analysis
+ };
+
+ /**
+ * @brief Constructor for the RebootControlSensor
+ *
+ * The system target holds the IPMI sensor number for this sensor.
+ *
+ */
+ RebootControlSensor();
+
+ /**
+ * @brief Destructor for the RebootControlSensor
+ *
+ */
+ ~RebootControlSensor();
+
+ /**
+ * @brief Set reboots to enabled or disabled
+ *
+ * @param[in] i_setting - enable/disable
+ *
+ * @return Errorlog handle
+ *
+ */
+ errlHndl_t setRebootControl( autoRebootSetting i_setting );
+
+ /**
+ * @brief get the value of the reboot control from the BMC.
+ *
+ * @param[o] i_setting - reboot control value
+ *
+ * @return Errorlog handle
+ *
+ */
+ errlHndl_t getRebootControl( autoRebootSetting& o_setting );
+
+ };
+
+
+ /**
* @class StatusSensor
*
* @brief Specialized class to handle DIMM, PROC and Core status.
diff --git a/src/include/usr/isteps/istep_reasoncodes.H b/src/include/usr/isteps/istep_reasoncodes.H
index cd6f47bdc..5895c11ee 100644
--- a/src/include/usr/isteps/istep_reasoncodes.H
+++ b/src/include/usr/isteps/istep_reasoncodes.H
@@ -62,6 +62,7 @@ namespace ISTEP
MOD_SBE_PERFORM_UPDATE_CHECK = 0x1A,
MOD_SBE_GET_FFDC_HANDLER = 0x1C,
MOD_SET_IPL_PARMS = 0x1D,
+ MOD_OCC_XSTOP_HANDLER = 0x1E,
};
/**
@@ -123,6 +124,7 @@ namespace ISTEP
RC_NO_FFDC_RETURNED = ISTEP_COMP_ID | 0x33,
RC_RETURNED_FFDC = ISTEP_COMP_ID | 0x34,
RC_P9N_DD1_NOT_SUPPORTED = ISTEP_COMP_ID | 0x35,
+ RC_PREVENT_REBOOT_IN_MFG_TERM_MODE = ISTEP_COMP_ID | 0x36,
};
};
diff --git a/src/include/usr/util/utilsemipersist.H b/src/include/usr/util/utilsemipersist.H
index 82943825e..9e56536d1 100644
--- a/src/include/usr/util/utilsemipersist.H
+++ b/src/include/usr/util/utilsemipersist.H
@@ -51,12 +51,14 @@ namespace Util
enum
{
PERSIST_MAGIC = 0x48425f56, // HB_V
+ MFG_TERM_REBOOT_ENABLE = 0x4d464754, // MFGT
};
struct semiPersistData_t
{
- uint32_t magic; //HB_V
- uint32_t reboot_cnt; // Number of reboots with valid data
+ uint32_t magic; //HB_V
+ uint32_t reboot_cnt; // Number of reboots with valid data
+ uint32_t mfg_term_reboot; // Manufacturing Terminate set for reboot
semiPersistData_t(): magic(0), reboot_cnt(0) {};
} PACKED;
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index fd3165b80..d11067734 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -743,6 +743,24 @@ errlHndl_t IStepDispatcher::executeAllISteps()
// Stop the IPL
stop();
#else
+ //Disable reboots so system really halts
+ SENSOR::RebootControlSensor l_rbotCtl;
+ err_ipmi = l_rbotCtl.setRebootControl(
+ SENSOR::RebootControlSensor::autoRebootSetting::DISABLE_REBOOTS
+ );
+
+ if(err_ipmi)
+ {
+ #ifdef CONFIG_CONSOLE
+ CONSOLE::displayf(NULL, "Failed to disable BMC auto reboots....");
+ CONSOLE::flush();
+ #endif
+ TRACFCOMP(g_trac_initsvc,
+ "Failed to disable BMC auto reboots....");
+ err_ipmi->collectTrace("INITSVC");
+ errlCommit(err_ipmi, INITSVC_COMP_ID );
+ }
+
// Shutdown with a TI
doShutdown( SHUTDOWN_MFG_TERM );
#endif
diff --git a/src/usr/ipmi/ipmisensor.C b/src/usr/ipmi/ipmisensor.C
index c5d8ef345..6cd03acb0 100644
--- a/src/usr/ipmi/ipmisensor.C
+++ b/src/usr/ipmi/ipmisensor.C
@@ -623,6 +623,88 @@ namespace SENSOR
}
//
+ // RebootControlSensor constructor - uses system target
+ //
+ RebootControlSensor::RebootControlSensor()
+ :SensorBase(TARGETING::SENSOR_NAME_HOST_AUTO_REBOOT_CONTROL, NULL)
+ {
+ // message buffer created and initialized in base object.
+
+ }
+
+ //
+ // RebootCountSensor destructor
+ //
+ RebootControlSensor::~RebootControlSensor(){};
+
+ //
+ // setRebootControl - turn reboots on or off to the BMC
+ //
+ errlHndl_t RebootControlSensor::setRebootControl(
+ autoRebootSetting i_setting )
+ {
+ // adjust the operation to overwrite the sensor reading
+ // to the value we send.
+ iv_msg->iv_operation = SET_SENSOR_VALUE_OPERATION;
+
+ // the Reboot Control Sensor is defined as a discrete sensor
+ // but the assertion bytes are being used to transfer the state
+ iv_msg->iv_assertion_mask = le16toh(i_setting);
+
+ TRACFCOMP(g_trac_ipmi,"RebootControlSensor::setRebootControl(%d)",
+ i_setting);
+
+ return writeSensorData();
+ }
+
+ //
+ // getRebootCount - get the reboot setting from the BMC
+ //
+ errlHndl_t RebootControlSensor::getRebootControl(
+ autoRebootSetting &o_setting )
+ {
+ // the Reboot control sensor is defined as a discrete sensor
+ // DISABLE_REBOOT - keep current state (no reboot)
+ // ENABLE_REBOOT - Allow analysis of FIRDATA on XSTOP
+ getSensorReadingData l_data;
+
+ errlHndl_t l_err = readSensorData( l_data );
+
+ if( l_err == NULL )
+ {
+ // this value is already byteswapped
+ if (l_data.event_status <= ENABLE_REBOOTS)
+ {
+ o_setting = static_cast<autoRebootSetting>(l_data.event_status);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_ipmi,"Unknown reboot control setting: %d",
+ l_data.event_status);
+
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid IPMI::MOD_IPMISENSOR_REBOOTCNTRL
+ * @reasoncode IPMI::RC_INVALID_SENSOR_SETTING
+ * @userdata1 Invalid reboot control setting
+ * @userdata2 <unused>
+ * @devdesc The sensor returned an invalid setting
+ * @custdesc Unable to find a valid sensor setting.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ IPMI::MOD_IPMISENSOR_REBOOTCNTRL,
+ IPMI::RC_INVALID_SENSOR_SETTING,
+ l_data.event_status,
+ 0,
+ false);
+ }
+ }
+ return l_err;
+ }
+
+
+ //
// StatusSensor constructor - uses system DIMM/CORE/PROC target
//
StatusSensor::StatusSensor( TARGETING::ConstTargetHandle_t i_target )
diff --git a/src/usr/isteps/istep06/host_set_ipl_parms.C b/src/usr/isteps/istep06/host_set_ipl_parms.C
index c42f90998..ab581b850 100644
--- a/src/usr/isteps/istep06/host_set_ipl_parms.C
+++ b/src/usr/isteps/istep06/host_set_ipl_parms.C
@@ -60,8 +60,9 @@ void* host_set_ipl_parms( void *io_pArgs )
// 2) clear all gard records of type GARD_Reconfig
else
{
- memset(&l_semiData, 0x0, sizeof(Util::semiPersistData_t));
l_semiData.magic = Util::PERSIST_MAGIC;
+ l_semiData.reboot_cnt = 0;
+ //Intentionally don't change mfg_term_reboot
l_err = HWAS::clearGardByType(HWAS::GARD_Reconfig);
if (l_err)
diff --git a/src/usr/isteps/istep06/host_start_occ_xstop_handler.C b/src/usr/isteps/istep06/host_start_occ_xstop_handler.C
index 0747333bc..683041916 100644
--- a/src/usr/isteps/istep06/host_start_occ_xstop_handler.C
+++ b/src/usr/isteps/istep06/host_start_occ_xstop_handler.C
@@ -35,6 +35,11 @@
#include <targeting/common/commontargeting.H>
#include <isteps/pm/occCheckstop.H>
#include <util/misc.H>
+#include <util/utilsemipersist.H>
+#ifdef CONFIG_BMC_IPMI
+#include <ipmi/ipmisensor.H>
+#endif
+
namespace ISTEP_06
{
@@ -44,32 +49,95 @@ void* host_start_occ_xstop_handler( void *io_pArgs )
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"host_start_occ_xstop_handler entry" );
-#ifdef CONFIG_IPLTIME_CHECKSTOP_ANALYSIS
- errlHndl_t l_errl = NULL;
- TARGETING::Target * l_sys = nullptr;
- TARGETING::targetService().getTopLevelTarget( l_sys );
- assert(l_sys != nullptr);
-
- TARGETING::Target* masterproc = NULL;
- TARGETING::targetService().masterProcChipTargetHandle(masterproc);
-
- void* l_homerVirtAddrBase = reinterpret_cast<void*>
- (VmmManager::INITIAL_MEM_SIZE);
- uint64_t l_homerPhysAddrBase = mm_virt_to_phys(l_homerVirtAddrBase);
- uint64_t l_commonPhysAddr = l_homerPhysAddrBase + VMM_HOMER_REGION_SIZE;
-
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "host_start_occ_xstop_handler:"
- " l_homerPhysAddrBase=0x%x, l_commonPhysAddr=0x%x",
- l_homerPhysAddrBase, l_commonPhysAddr);
+
do
{
// if ( Util::isSimicsRunning() ) break; //Skip if running in Simics
+ TARGETING::Target * l_sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget( l_sys );
+ assert(l_sys != nullptr);
+
+#ifndef CONFIG_HANG_ON_MFG_SRC_TERM
+ //When in MNFG_FLAG_SRC_TERM mode enable reboots to allow HB
+ //to analyze now that the OCC is up and alive
+ auto l_mnfgFlags =
+ l_sys->getAttr<TARGETING::ATTR_MNFG_FLAGS>();
+
+ // Check to see if SRC_TERM bit is set in MNFG flags
+ if ((l_mnfgFlags & TARGETING::MNFG_FLAG_SRC_TERM) &&
+ !(l_mnfgFlags & TARGETING::MNFG_FLAG_IMMEDIATE_HALT))
+ {
+ errlHndl_t l_err = nullptr;
+
+ //If HB_VOLATILE MFG_TERM_REBOOT_ENABLE flag is set at this point
+ //Create errorlog to terminate the boot.
+ Util::semiPersistData_t l_semiData;
+ Util::readSemiPersistData(l_semiData);
+ if (l_semiData.mfg_term_reboot == Util::MFG_TERM_REBOOT_ENABLE)
+ {
+ /*@
+ * @errortype
+ * @moduleid ISTEP::MOD_OCC_XSTOP_HANDLER
+ * @reasoncode ISTEP::RC_PREVENT_REBOOT_IN_MFG_TERM_MODE
+ * @devdesc System rebooted without xstop in MFG TERM mode.
+ * @custdesc A problem occurred during the IPL of the system.
+ */
+ l_err = new ERRORLOG::ErrlEntry
+ (ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ ISTEP::MOD_OCC_XSTOP_HANDLER,
+ ISTEP::RC_PREVENT_REBOOT_IN_MFG_TERM_MODE,
+ 0,
+ 0,
+ true /*HB SW error*/ );
+ l_stepError.addErrorDetails(l_err);
+ ERRORLOG::errlCommit(l_err, ISTEP_COMP_ID);
+ break;
+ }
+
+ //Put a mark in HB VOLATILE
+ Util::semiPersistData_t l_newSemiData; //inits to 0s
+ Util::readSemiPersistData(l_newSemiData);
+ l_newSemiData.mfg_term_reboot = Util::MFG_TERM_REBOOT_ENABLE;
+ Util::writeSemiPersistData(l_newSemiData);
+
+ //Enable reboots so FIRDATA will be analyzed on XSTOP
+ SENSOR::RebootControlSensor l_rbotCtl;
+ l_err = l_rbotCtl.setRebootControl(
+ SENSOR::RebootControlSensor::autoRebootSetting::ENABLE_REBOOTS);
+
+ if(l_err)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "Failed to enable BMC auto reboots....");
+ l_stepError.addErrorDetails(l_err);
+ ERRORLOG::errlCommit(l_err, HWPF_COMP_ID);
+ break;
+ }
+ }
+#endif
+
+
+#ifdef CONFIG_IPLTIME_CHECKSTOP_ANALYSIS
+ errlHndl_t l_errl = NULL;
+
+ TARGETING::Target* masterproc = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(masterproc);
+
+ void* l_homerVirtAddrBase = reinterpret_cast<void*>
+ (VmmManager::INITIAL_MEM_SIZE);
+ uint64_t l_homerPhysAddrBase = mm_virt_to_phys(l_homerVirtAddrBase);
+ uint64_t l_commonPhysAddr = l_homerPhysAddrBase + VMM_HOMER_REGION_SIZE;
+
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "host_start_occ_xstop_handler:"
+ " l_homerPhysAddrBase=0x%x, l_commonPhysAddr=0x%x",
+ l_homerPhysAddrBase, l_commonPhysAddr);
+
l_errl = HBPM::loadPMComplex(masterproc,
- l_homerPhysAddrBase,
- l_commonPhysAddr,
- HBPM::PM_LOAD,
- true);
+ l_homerPhysAddrBase,
+ l_commonPhysAddr,
+ HBPM::PM_LOAD,
+ true);
if(l_errl)
{
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
@@ -88,9 +156,10 @@ void* host_start_occ_xstop_handler( void *io_pArgs )
ERRORLOG::errlCommit(l_errl, HWPF_COMP_ID);
break;
}
+#endif
}while(0);
-#endif
+
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"host_start_occ_xstop_handler exit" );
diff --git a/src/usr/isteps/istep16/call_host_ipl_complete.C b/src/usr/isteps/istep16/call_host_ipl_complete.C
index 12397d6c6..40484d107 100644
--- a/src/usr/isteps/istep16/call_host_ipl_complete.C
+++ b/src/usr/isteps/istep16/call_host_ipl_complete.C
@@ -70,8 +70,11 @@ void* call_host_ipl_complete (void *io_pArgs)
//No more reconfig loops are supported from this point
//forward. Clean up the semi persistent area
// 1) clear magic number (so next boot thinks it is cold)
+ // a) DON'T clear mfg term setting (so read-modify)
// 2) clear any reconfig specific gard records
Util::semiPersistData_t l_semiData; //inits to 0s
+ Util::readSemiPersistData(l_semiData);
+ l_semiData.magic = 0x0;
Util::writeSemiPersistData(l_semiData);
l_err = HWAS::clearGardByType(HWAS::GARD_Reconfig);
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 96b02e053..c82aa1243 100755
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -5092,6 +5092,11 @@
<name>UPDATE_BOTH_SIDES_OF_SBE</name>
<value>0x00040000</value>
</enumerator>
+ <enumerator>
+ <!-- Update both sides of SBE Image if update is needed -->
+ <name>IMMEDIATE_HALT</name>
+ <value>0x00080000</value>
+ </enumerator>
</enumerationType>
<enumerationType>
diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
index 4fc537b4a..ab13a4e5b 100755
--- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
@@ -485,6 +485,10 @@
<value>0x07D0</value>
</enumerator>
<enumerator>
+ <name>HOST_AUTO_REBOOT_CONTROL</name>
+ <value>0x0921</value>
+ </enumerator>
+ <enumerator>
<name>DIMM_STATE</name>
<value>0x0C20</value>
</enumerator>
@@ -574,6 +578,7 @@
<value>0xCC03</value>
</enumerator>
</enumerationType>
+
<attribute>
<id>SBE_FFDC_ADDR</id>
<description>
diff --git a/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml b/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml
index 04be53218..2904f6c1b 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml
@@ -788,6 +788,10 @@
<value>0x20</value>
</enumerator>
<enumerator>
+ <name>SYS_MGMT_SOFTWARE</name>
+ <value>0x21</value>
+ </enumerator>
+ <enumerator>
<name>BIOS</name>
<value>0x22</value>
</enumerator>
@@ -852,6 +856,10 @@
<value>0x07</value>
</enumerator>
<enumerator>
+ <name>POWER_UNIT</name>
+ <value>0x09</value>
+ </enumerator>
+ <enumerator>
<name>MEMORY</name>
<value>0x0c</value>
</enumerator>
OpenPOWER on IntegriCloud