summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/sys/time.h10
-rw-r--r--src/include/usr/ipmi/ipmiif.H3
-rw-r--r--src/include/usr/ipmi/ipmiwatchdog.H141
-rw-r--r--src/usr/diag/mdia/mdiasm.C20
-rw-r--r--src/usr/hwpf/hwp/start_payload/start_payload.C44
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C32
-rw-r--r--src/usr/ipmi/ipmiwatchdog.C149
-rw-r--r--src/usr/ipmi/makefile1
8 files changed, 396 insertions, 4 deletions
diff --git a/src/include/sys/time.h b/src/include/sys/time.h
index 51bccfe23..1a0a02ec4 100644
--- a/src/include/sys/time.h
+++ b/src/include/sys/time.h
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2010,2014 */
+/* Contributors Listed Below - COPYRIGHT 2010,2014 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -30,6 +32,12 @@
// Macros
//******************************************************************************
+
+/**
+ * @brief number of milliseconds per second
+ */
+#define MS_PER_SEC (1000)
+
/**
* @brief Number of nanoseconds per second
*/
diff --git a/src/include/usr/ipmi/ipmiif.H b/src/include/usr/ipmi/ipmiif.H
index 0226eb2dd..ae03f8394 100644
--- a/src/include/usr/ipmi/ipmiif.H
+++ b/src/include/usr/ipmi/ipmiif.H
@@ -120,6 +120,9 @@ namespace IPMI
inline const command_t set_watchdog(void)
{ return std::make_pair(NETFUN_APP, 0x24); }
+ inline const command_t reset_watchdog(void)
+ { return std::make_pair(NETFUN_APP, 0x22); }
+
inline const command_t get_capabilities(void)
{ return std::make_pair(NETFUN_APP, 0x36); }
diff --git a/src/include/usr/ipmi/ipmiwatchdog.H b/src/include/usr/ipmi/ipmiwatchdog.H
new file mode 100644
index 000000000..7c39ac5da
--- /dev/null
+++ b/src/include/usr/ipmi/ipmiwatchdog.H
@@ -0,0 +1,141 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/ipmi/ipmiwatchdog.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __IPMIWATCHDOG_IPMIWATCHDOG_H
+#define __IPMIWATCHDOG_IPMIWATCHDOG_H
+/**
+ * @file ipmiwatchdog.H
+ *
+ * IPMI watchdog interface launched from the IStep Dispatcher
+ *
+ */
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+#include <errl/errlentry.H>
+
+namespace IPMIWATCHDOG
+{
+/******************************************************************************/
+// Globals/Constants
+/******************************************************************************/
+/**
+ * @brief the default watchdog countdown setting it to 15 secs since progress
+ * have to be sent every 15 secs.
+ */
+const uint16_t DEFAULT_WATCHDOG_COUNTDOWN = 15;
+
+/**
+ * @brief the default watchdog countdown for transition between hostboot
+ * and OPAL (value is in seconds)
+ */
+const uint16_t DEFAULT_HB_OPAL_TRANSITION_COUNTDOWN = 30;
+
+/******************************************************************************/
+// Typedef/Enumerations
+/******************************************************************************/
+/**
+ * @brief Used in Byte 1 field of the set watchdog command
+ */
+enum TIMER_USE
+{
+ DO_NOT_LOG = 0x80, // bit 7
+ DO_NOT_STOP = 0x40, // bit 6
+ BIOS_FRB2 = 0x01, // bit 0
+ BIOS_POST = 0x02, // bit 1
+ OS_LOAD = 0x03, // bits 0 & 1
+ SMS_OS = 0x04, // bit 2
+ OEM = 0x05, // bits 2 & 0
+
+};
+
+/**
+ * @brief Used in Byte 2 field of the set watchdog command
+ */
+enum TIMER_ACTIONS
+{
+ PRE_TIMEOUT_INT_SMI = 0x10, // bit 4
+ PRE_TIMEOUT_INT_NMI = 0x20, // bit 5
+ PRE_TIMEOUT_INT_MSG = 0x30, // bits 4 & 5
+ TIMEOUT_HARD_RESET = 0x01, // bit 0
+ TIMEOUT_PWR_DOWN = 0x02, // bit 1
+ TIMEOUT_PWR_CYCLE = 0x03, // bits 0 & 1
+
+};
+
+/**
+ * @brief Used in Byte 4 field of the set watchdog command
+ * set to 1 to clear the flag set to 0 to leave alone
+ */
+enum TIMER_USE_CLR_FLAGS
+{
+ OEM_FLAG = 0x20, // bit 5
+ SMS_OS_FLAG = 0x10, // bit 4
+ OS_LOAD_FLAG = 0x08, // bit 3
+ BIOS_POST_FLAG = 0x04, // bit 2
+ BIOS_FRB2_FLAG = 0x02, // bit 1
+
+};
+
+
+/******************************************************************************/
+// Functions
+/******************************************************************************/
+
+/**
+ * @brief Sets the ipmi watchdog timer on the BMC
+ *
+ * Called by hostboot to set a watchdog timer on the BMC
+ * @param[in] i_countdown_secs, initial countdown in seconds
+ * @param[in] i_timer_use, Sets watchdog timer use bits.
+ * @param[in] i_timer_action, Sets watchdog timer experation action.
+ * @param[in] i_timer_clr_flag, Sets the Watchdog interrupt flag to clear.
+ * @return none
+ */
+
+errlHndl_t setWatchDogTimer( const uint16_t i_countdown_secs,
+ const uint8_t i_timer_use
+ = static_cast<uint8_t>(DO_NOT_STOP | BIOS_FRB2),
+ const TIMER_ACTIONS i_timer_action
+ = TIMEOUT_PWR_CYCLE,
+ const TIMER_USE_CLR_FLAGS i_timer_clr_flag
+ = BIOS_FRB2_FLAG);
+
+/**
+ * @brief Resets the ipmi watchdog timer on the BMC
+ *
+ * Called by hostboot to reset a watchdog timer countdown on the BMC.
+ * If the BMC returns an error code indicating the watchdog timer
+ * has not been started, this function will start the watchdog timer.
+ *
+ * @return error
+ */
+errlHndl_t resetWatchDogTimer();
+
+
+} // namespace
+
+#endif
diff --git a/src/usr/diag/mdia/mdiasm.C b/src/usr/diag/mdia/mdiasm.C
index eeefd3b05..d6846ff18 100644
--- a/src/usr/diag/mdia/mdiasm.C
+++ b/src/usr/diag/mdia/mdiasm.C
@@ -43,6 +43,8 @@
#include <targeting/common/utilFilter.H>
#include <errl/errludlogregister.H>
#include <initservice/istepdispatcherif.H>
+#include <ipmi/ipmiwatchdog.H>
+#include <config.h>
using namespace TARGETING;
using namespace ERRORLOG;
@@ -1117,10 +1119,22 @@ bool StateMachine::processMaintCommandEvent(const MaintCommandEvent & i_event)
eventType = SKIP_MBA;
}
- switch(eventType)
+#ifdef CONFIG_BMC_IPMI
+ // Reset the watchdog timer after running each pattern
+ errlHndl_t err_ipmi = IPMIWATCHDOG::resetWatchDogTimer();
+
+ if(err_ipmi)
{
- case COMMAND_COMPLETE:
+ MDIA_FAST("sm executeWorkitem: IPMI reset watchdog failed");
+ err_ipmi->collectTrace("MDIA_FAST",1024);
+ errlCommit(err_ipmi, MDIA_COMP_ID );
+
+ }
+#endif
+ switch(eventType)
+ case COMMAND_COMPLETE:
+ {
// command stopped or complete at end of last rank
wfp.restartCommand = false;
@@ -1129,13 +1143,13 @@ bool StateMachine::processMaintCommandEvent(const MaintCommandEvent & i_event)
++wfp.workItem;
+
// done with this maint command
flags = DELETE_CMD | START_NEXT_CMD;
wfp.data = NULL;
break;
-
case COMMAND_STOPPED:
// command stopped at end of some other rank
diff --git a/src/usr/hwpf/hwp/start_payload/start_payload.C b/src/usr/hwpf/hwp/start_payload/start_payload.C
index 2c90b1c7b..9c23ae2f9 100644
--- a/src/usr/hwpf/hwp/start_payload/start_payload.C
+++ b/src/usr/hwpf/hwp/start_payload/start_payload.C
@@ -86,6 +86,8 @@
#include <sys/mm.h>
#include <algorithm>
#include <config.h>
+#include <ipmi/ipmiwatchdog.H>
+
// Uncomment these files as they become available:
// #include "host_start_payload/host_start_payload.H"
@@ -492,6 +494,48 @@ void* call_host_start_payload( void *io_pArgs )
task_affinity_unpin();
+#ifdef CONFIG_BMC_IPMI
+
+ // TODO ISSUE 118082
+ // ENABLE CODE BELOW ONCE OPAL COMPLETES ipmi WATCHDOG
+#if 0
+ //run the ipmi watchdog for a longer period to transition
+ // to opel
+ errlHndl_t err_ipmi = IPMIWATCHDOG::setWatchDogTimer(
+ IPMIWATCHDOG::DEFAULT_HB_OPAL_TRANSITION_COUNTDOWN);
+
+ if(err_ipmi)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "init: ERROR: Set IPMI watchdog Failed");
+ err_ipmi->collectTrace("ISTEPS_TRACE",256);
+ errlCommit(err_ipmi, ISTEP_COMP_ID );
+
+ }
+#endif
+
+ // TODO ISSUE 118082
+ // REMOVE CODE BELOW ONCE OPAL COMPLETES IPMI WATCHDOG
+ // THE CODE BELOW STOPS THE IPMI TIMER FROM RUNNING
+ // TO PREVENT IT GETTING TRIGGERED DURING HB_OPAL TRANSITION
+
+ // Call setWatchdogTimer without the default DON'T STOP
+ // flag to stop the watchdog timer
+ errlHndl_t err_ipmi = IPMIWATCHDOG::setWatchDogTimer(
+ IPMIWATCHDOG::DEFAULT_HB_OPAL_TRANSITION_COUNTDOWN,
+ IPMIWATCHDOG::BIOS_FRB2);
+
+ if(err_ipmi)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "init: ERROR: Set IPMI watchdog Failed");
+ err_ipmi->collectTrace("ISTEPS_TRACE",256);
+ errlCommit(err_ipmi, ISTEP_COMP_ID );
+
+ }
+
+#endif
+
// broadcast shutdown to other HB instances.
l_errl = broadcastShutdown(this_node);
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index 6d0df0c3f..97c6d32be 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -65,6 +65,8 @@
#include <console/consoleif.H>
#include <hwpisteperror.H>
#include <pnor/pnorif.H>
+#include <ipmi/ipmiwatchdog.H> //IPMI watchdog timer
+#include <config.h>
namespace ISTEPS_TRACE
{
@@ -215,6 +217,22 @@ void IStepDispatcher::init(errlHndl_t &io_rtaskRetErrl)
}
else
{
+
+#ifdef CONFIG_BMC_IPMI
+ //run the ipmi watchdog in non istep mode only
+ errlHndl_t err_ipmi = IPMIWATCHDOG::setWatchDogTimer(
+ IPMIWATCHDOG::DEFAULT_WATCHDOG_COUNTDOWN);
+
+ if(err_ipmi)
+ {
+ TRACFCOMP(g_trac_initsvc,
+ "init: ERROR: Set IPMI watchdog Failed");
+ err_ipmi->collectTrace("INITSVC", 1024);
+ errlCommit(err_ipmi, INITSVC_COMP_ID );
+
+ }
+#endif
+
// Non-IStep mode (run all isteps automatically)
if(iv_spBaseServicesEnabled)
{
@@ -1628,6 +1646,20 @@ errlHndl_t IStepDispatcher::sendProgressCode(bool i_needsLock)
CONSOLE::flush();
#endif
+#ifdef CONFIG_BMC_IPMI
+ //Reset the watchdog before every istep
+ errlHndl_t err_ipmi = IPMIWATCHDOG::resetWatchDogTimer();
+
+ if(err_ipmi)
+ {
+ TRACFCOMP(g_trac_initsvc,
+ "init: ERROR: reset IPMI watchdog Failed");
+ err_ipmi->collectTrace("INITSVC", 1024);
+ errlCommit(err_ipmi, INITSVC_COMP_ID );
+
+ }
+#endif
+
msg_t * myMsg = msg_allocate();
myMsg->type = IPL_PROGRESS_CODE;
myMsg->data[0] = iv_curIStep;
diff --git a/src/usr/ipmi/ipmiwatchdog.C b/src/usr/ipmi/ipmiwatchdog.C
new file mode 100644
index 000000000..354bd5324
--- /dev/null
+++ b/src/usr/ipmi/ipmiwatchdog.C
@@ -0,0 +1,149 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/ipmi/ipmiwatchdog.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __IPMIWATCHDOG_IPMIWATCHDOG_C
+#define __IPMIWATCHDOG_IPMIWATCHDOG_C
+/**
+ * @file ipmiwatchdog.C
+ *
+ * Ipmi watchdog timer
+ *
+ */
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+#include <errl/errlentry.H>
+#include <ipmi/ipmiwatchdog.H>
+#include <ipmi/ipmiif.H>
+#include <sys/time.h>
+
+/******************************************************************************/
+// Globals/Constants
+/******************************************************************************/
+// Defined in ipmidd.C
+extern trace_desc_t * g_trac_ipmi;
+#define IPMI_TRAC(printf_string,args...) \
+ TRACFCOMP(g_trac_ipmi,"wd: "printf_string,##args)
+
+namespace IPMIWATCHDOG
+{
+
+/******************************************************************************/
+// Functions
+/******************************************************************************/
+
+
+errlHndl_t setWatchDogTimer( const uint16_t i_countdown_secs,
+ const uint8_t i_timer_use,
+ const TIMER_ACTIONS i_timer_action,
+ const TIMER_USE_CLR_FLAGS i_timer_clr_flag)
+{
+ errlHndl_t err_ipmi = NULL;
+
+ // Convert secs into lsb and msb values
+ // the ipmi spec uses the count which is 100ms/count
+ static const uint16_t ms_per_count = 100;
+ static const uint8_t bits_to_shift_for_nxt_byte = 8;
+ static const uint8_t byte_mask = 0xFF;
+
+ uint16_t countdown = (i_countdown_secs * MS_PER_SEC)
+ / ms_per_count;
+
+ uint8_t init_countdown_lsb = static_cast<uint8_t>
+ (countdown & byte_mask);
+
+ uint8_t init_countdown_msb = static_cast<uint8_t>(
+ (countdown >> bits_to_shift_for_nxt_byte)
+ & byte_mask);
+
+
+ size_t len = 6; // IPMI spec has request data at 6 bytes
+
+ //create request data buffer
+ uint8_t* data = new uint8_t[len];
+
+ IPMI::completion_code cc = IPMI::CC_UNKBAD;
+
+ data[0] = i_timer_use; // byte 1 timer use
+ data[1] = i_timer_action; // byte 2 timer actions
+ data[2] = 0x00; // byte 3 pre-interval timeout in secs
+ data[3] = i_timer_clr_flag; // byte 4 timer use flags to clear
+ data[4] = init_countdown_lsb; // byte 5 initial countdown timer LSByte
+ data[5] = init_countdown_msb; // byte 6 initial countdown timer MSByte
+
+ err_ipmi = IPMI::sendrecv(IPMI::set_watchdog(), cc, len, data);
+
+ //cleanup buffer
+ delete[] data; data = NULL;
+
+ if(cc != IPMI::CC_OK)
+ {
+ IPMI_TRAC("Watchdog: BMC returned not ok CC[%x]",cc);
+ // should we log error and then retry?
+ // what happens if the communication is broken
+ // reset will try and set it again.
+ }
+
+ return err_ipmi;
+}
+
+
+errlHndl_t resetWatchDogTimer()
+{
+ errlHndl_t err_ipmi = NULL;
+
+
+ // reset command does not take any request data
+ size_t len = 0;
+ uint8_t* data = NULL;
+
+
+ do
+ {
+
+ // Don't worry about the return just send the msg over
+ // If there is an error during the reset
+ // we don't care about it since the watchdog will trip
+ //send ipmi command
+ err_ipmi = IPMI::send(IPMI::reset_watchdog(), len, data);
+
+ if(err_ipmi)
+ {
+ //got an error sending IPMI msg
+ //progate error upstream.
+ break;
+ }
+
+ }
+ while(0);
+
+ return err_ipmi;
+}
+
+
+} // namespace
+
+#endif
diff --git a/src/usr/ipmi/makefile b/src/usr/ipmi/makefile
index 92cf4362b..730a340d5 100644
--- a/src/usr/ipmi/makefile
+++ b/src/usr/ipmi/makefile
@@ -31,6 +31,7 @@ OBJS += ipmirp.o
OBJS += $(if $(CONFIG_BMC_BT_LPC_IPMI),ipmidd.o)
OBJS += ipmiconfig.o
OBJS += ipmisensor.o
+OBJS += ipmiwatchdog.o
#SUBDIRS += test.d
OpenPOWER on IntegriCloud