summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Kumar Sahu <deepakx.sahu@intel.com>2019-05-20 14:58:58 +0000
committerVernon Mauery <vernon.mauery@linux.intel.com>2019-09-10 23:39:02 +0000
commitcfae948b82765c8dbaec809e0f13744e8dedb934 (patch)
treeb6059a45953b8ef96d8c62f84b17bb74386b8347
parent7dc4ac0246bfae3da04c11e7a2053d28acfde35c (diff)
downloadphosphor-host-ipmid-cfae948b82765c8dbaec809e0f13744e8dedb934.tar.gz
phosphor-host-ipmid-cfae948b82765c8dbaec809e0f13744e8dedb934.zip
Watchdog: move get and set watchdog to new api.
Rewrite "get and set watchdog" command to use the newly introduced ipmi api. Tested: Verified using ipmitool "get and set watchdog", timer behavior is same before and after the changes. Testing Procedure: default watchdog timer is 11.2 seconds. ipmitool raw 0x06 0x25 ---> Get Output: 00 00 00 00 70 17 70 17 Note: Here 70 count(hex value)->112 count(decimal value)->112*100=11200ms [100ms per count]->11.2sec (watchdog timer) watchdog timer set to 20 seconds. ipmitool raw 0x06 0x24 0x44 0x01 0x00 0x10 0xc8 0x00 ----> Set output: ipmitool raw 0x06 0x25 ---> Get output: 04 01 00 00 c8 00 c8 00 Note: Here 20sec->20000ms->200count->c8 (hex value) Signed-off-by: Deepak Kumar Sahu <deepakx.sahu@intel.com> Change-Id: Id8c096bc1635d1900ee842a9726c49fb690fa8bc
-rw-r--r--app/watchdog.cpp188
-rw-r--r--app/watchdog.hpp61
-rw-r--r--app/watchdog_service.cpp5
-rw-r--r--app/watchdog_service.hpp8
-rw-r--r--apphandler.cpp10
5 files changed, 166 insertions, 106 deletions
diff --git a/app/watchdog.cpp b/app/watchdog.cpp
index 25ca4b1..ff07b02 100644
--- a/app/watchdog.cpp
+++ b/app/watchdog.cpp
@@ -82,7 +82,12 @@ ipmi::RspType<> ipmiAppResetWatchdogTimer()
static constexpr uint8_t wd_dont_stop = 0x1 << 6;
static constexpr uint8_t wd_timeout_action_mask = 0x3;
-static constexpr uint8_t wdTimerUseMask = 0x7;
+static constexpr uint8_t wdTimerUseResTimer1 = 0x0;
+static constexpr uint8_t wdTimerUseResTimer2 = 0x6;
+static constexpr uint8_t wdTimerUseResTimer3 = 0x7;
+
+static constexpr uint8_t wdTimeoutActionTimer = 0x40;
+static constexpr uint8_t wdTimeoutInterruptTimer = 0x04;
enum class IpmiAction : uint8_t
{
@@ -168,55 +173,72 @@ WatchdogService::TimerUse ipmiTimerUseToWdTimerUse(IpmiTimerUse ipmiTimerUse)
}
}
-struct wd_set_req
-{
- uint8_t timer_use;
- uint8_t timer_action;
- uint8_t pretimeout; // (seconds)
- uint8_t expire_flags;
- uint16_t initial_countdown; // Little Endian (deciseconds)
-} __attribute__((packed));
-static_assert(sizeof(wd_set_req) == 6, "wd_set_req has invalid size.");
-static_assert(sizeof(wd_set_req) <= MAX_IPMI_BUFFER,
- "wd_get_res can't fit in request buffer.");
-
-ipmi_ret_t ipmi_app_watchdog_set(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request,
- ipmi_response_t response,
- ipmi_data_len_t data_len,
- ipmi_context_t context)
+static uint8_t timerLogFlags = 0;
+static uint8_t timerActions = 0;
+static uint8_t timerUseExpirationFlags = 0;
+
+/**@brief The Set Watchdog Timer ipmi command.
+ *
+ * @param
+ * - timerUse
+ * - dontStopTimer
+ * - dontLog
+ * - timerAction
+ * - pretimeout
+ * - expireFlags
+ * - initialCountdown
+ *
+ * @return completion code on success.
+ **/
+ipmi::RspType<> ipmiSetWatchdogTimer(
+ uint3_t timerUse, uint3_t reserved, bool dontStopTimer, bool dontLog,
+ uint3_t timeoutAction, uint1_t reserved1, uint3_t preTimeoutInterrupt,
+ uint1_t reserved2, uint8_t preTimeoutInterval, uint1_t reserved3,
+ uint5_t expFlagValue, uint2_t reserved4, uint16_t initialCountdown)
{
- // Extract the request data
- if (*data_len != sizeof(wd_set_req))
+ if ((timerUse == wdTimerUseResTimer1) ||
+ (timerUse == wdTimerUseResTimer2) ||
+ (timerUse == wdTimerUseResTimer3) ||
+ (timeoutAction == wdTimeoutActionTimer) ||
+ (preTimeoutInterrupt == wdTimeoutInterruptTimer) ||
+ (reserved1 | reserved2 | reserved3 | reserved4))
+ {
+ return ipmi::responseInvalidFieldRequest();
+ }
+
+ if (preTimeoutInterval > (initialCountdown / 10))
{
- *data_len = 0;
- return IPMI_CC_REQ_DATA_LEN_INVALID;
+ return ipmi::responseInvalidFieldRequest();
}
- wd_set_req req;
- memcpy(&req, request, sizeof(req));
- req.initial_countdown = le16toh(req.initial_countdown);
- *data_len = 0;
+
+ timerLogFlags = static_cast<uint8_t>(dontLog);
+ timerActions &= static_cast<uint8_t>(timeoutAction) |
+ static_cast<uint8_t>(preTimeoutInterrupt) << 4;
try
{
WatchdogService wd_service;
// Stop the timer if the don't stop bit is not set
- if (!(req.timer_use & wd_dont_stop))
+ if (!(dontStopTimer))
{
wd_service.setEnabled(false);
}
// Set the action based on the request
- const auto ipmi_action =
- static_cast<IpmiAction>(req.timer_action & wd_timeout_action_mask);
+ const auto ipmi_action = static_cast<IpmiAction>(
+ static_cast<uint8_t>(timeoutAction) & wd_timeout_action_mask);
wd_service.setExpireAction(ipmiActionToWdAction(ipmi_action));
const auto ipmiTimerUse =
- static_cast<IpmiTimerUse>(req.timer_use & wdTimerUseMask);
+ static_cast<IpmiTimerUse>(static_cast<uint8_t>(timerUse));
wd_service.setTimerUse(ipmiTimerUseToWdTimerUse(ipmiTimerUse));
+ wd_service.setExpiredTimerUse(WatchdogService::TimerUse::Reserved);
+
+ timerUseExpirationFlags &= static_cast<uint8_t>(~expFlagValue) << 2;
+
// Set the new interval and the time remaining deci -> mill seconds
- const uint64_t interval = req.initial_countdown * 100;
+ const uint64_t interval = initialCountdown * 100;
wd_service.setInterval(interval);
wd_service.setTimeRemaining(interval);
@@ -224,29 +246,29 @@ ipmi_ret_t ipmi_app_watchdog_set(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
wd_service.setInitialized(true);
lastCallSuccessful = true;
- return IPMI_CC_OK;
+ return ipmi::responseSuccess();
}
catch (const std::domain_error&)
{
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ return ipmi::responseInvalidFieldRequest();
}
catch (const InternalFailure& e)
{
reportError();
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
catch (const std::exception& e)
{
const std::string e_str = std::string("wd_set: ") + e.what();
log<level::ERR>(e_str.c_str());
reportError();
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
catch (...)
{
log<level::ERR>("wd_set: Unknown Error");
reportError();
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
}
@@ -320,30 +342,30 @@ IpmiTimerUse wdTimerUseToIpmiTimerUse(WatchdogService::TimerUse wdTimerUse)
}
}
-struct wd_get_res
-{
- uint8_t timer_use;
- uint8_t timer_action;
- uint8_t pretimeout;
- uint8_t expire_flags;
- uint16_t initial_countdown; // Little Endian (deciseconds)
- uint16_t present_countdown; // Little Endian (deciseconds)
-} __attribute__((packed));
-static_assert(sizeof(wd_get_res) == 8, "wd_get_res has invalid size.");
-static_assert(sizeof(wd_get_res) <= MAX_IPMI_BUFFER,
- "wd_get_res can't fit in response buffer.");
-
-static constexpr uint8_t wd_dont_log = 0x1 << 7;
static constexpr uint8_t wd_running = 0x1 << 6;
-ipmi_ret_t ipmi_app_watchdog_get(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request,
- ipmi_response_t response,
- ipmi_data_len_t data_len,
- ipmi_context_t context)
+/**@brief The getWatchdogTimer ipmi command.
+ *
+ * @return Completion code plus timer details.
+ * - timerUse
+ * - timerAction
+ * - pretimeout
+ * - expireFlags
+ * - initialCountdown
+ * - presentCountdown
+ **/
+ipmi::RspType<uint8_t, // timerUse
+ uint8_t, // timerAction
+ uint8_t, // pretimeout
+ uint8_t, // expireFlags
+ uint16_t, // initial Countdown - Little Endian (deciseconds)
+ uint16_t // present Countdown - Little Endian (deciseconds)
+ >
+ ipmiGetWatchdogTimer()
{
- // Assume we will fail and send no data outside the return code
- *data_len = 0;
+ uint8_t expireFlags = 0;
+ uint16_t presentCountdown = 0;
+ uint8_t pretimeout = 0;
try
{
@@ -351,50 +373,68 @@ ipmi_ret_t ipmi_app_watchdog_get(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
WatchdogService::Properties wd_prop = wd_service.getProperties();
// Build and return the response
- wd_get_res res;
- res.timer_use = wd_dont_log;
- res.timer_action =
- static_cast<uint8_t>(wdActionToIpmiAction(wd_prop.expireAction));
+ uint8_t timerUse = 0;
+ timerUse |= timerLogFlags;
+
+ uint8_t timerAction = timerActions;
// Interval and timeRemaining need converted from milli -> deci seconds
- res.initial_countdown = htole16(wd_prop.interval / 100);
+ uint16_t initialCountdown = htole16(wd_prop.interval / 100);
+
+ if (wd_prop.expiredTimerUse != WatchdogService::TimerUse::Reserved)
+ {
+ timerUseExpirationFlags |=
+ 1 << static_cast<uint8_t>(
+ wdTimerUseToIpmiTimerUse(wd_prop.expiredTimerUse));
+ }
+
if (wd_prop.enabled)
{
- res.timer_use |= wd_running;
- res.present_countdown = htole16(wd_prop.timeRemaining / 100);
+ timerUse |= wd_running;
+ presentCountdown = htole16(wd_prop.timeRemaining / 100);
+ expireFlags = 0;
}
else
{
- res.present_countdown = res.initial_countdown;
+ if (wd_prop.expiredTimerUse == WatchdogService::TimerUse::Reserved)
+ {
+ presentCountdown = initialCountdown;
+ expireFlags = 0;
+ }
+ else
+ {
+ presentCountdown = 0;
+ expireFlags = timerUseExpirationFlags;
+ }
}
- res.timer_use |=
+ timerUse |=
static_cast<uint8_t>(wdTimerUseToIpmiTimerUse(wd_prop.timerUse));
// TODO: Do something about having pretimeout support
- res.pretimeout = 0;
- res.expire_flags = 0;
- memcpy(response, &res, sizeof(res));
- *data_len = sizeof(res);
+ pretimeout = 0;
+
lastCallSuccessful = true;
- return IPMI_CC_OK;
+ return ipmi::responseSuccess(timerUse, timerAction, pretimeout,
+ expireFlags, initialCountdown,
+ presentCountdown);
}
catch (const InternalFailure& e)
{
reportError();
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
catch (const std::exception& e)
{
const std::string e_str = std::string("wd_get: ") + e.what();
log<level::ERR>(e_str.c_str());
reportError();
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
catch (...)
{
log<level::ERR>("wd_get: Unknown Error");
reportError();
- return IPMI_CC_UNSPECIFIED_ERROR;
+ return ipmi::responseUnspecifiedError();
}
}
diff --git a/app/watchdog.hpp b/app/watchdog.hpp
index 3f91f4f..d52b6e6 100644
--- a/app/watchdog.hpp
+++ b/app/watchdog.hpp
@@ -6,35 +6,40 @@
*/
ipmi::RspType<> ipmiAppResetWatchdogTimer();
-/** @brief The SET watchdog IPMI command.
+/**@brief The setWatchdogTimer ipmi command.
*
- * @param[in] netfn
- * @param[in] cmd
- * @param[in] request
- * @param[in,out] response
- * @param[out] data_len
- * @param[in] context
+ * @param
+ * - timerUse
+ * - dontStopTimer
+ * - dontLog
+ * - timerAction
+ * - pretimeout
+ * - expireFlags
+ * - initialCountdown
*
- * @return IPMI_CC_OK on success, an IPMI error code otherwise.
- */
-ipmi_ret_t ipmi_app_watchdog_set(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request,
- ipmi_response_t response,
- ipmi_data_len_t data_len,
- ipmi_context_t context);
+ * @return completion code on success.
+ **/
+ipmi::RspType<> ipmiSetWatchdogTimer(
+ uint3_t timerUse, uint3_t reserved, bool dontStopTimer, bool dontLog,
+ uint3_t timeoutAction, uint1_t reserved1, uint3_t preTimeoutInterrupt,
+ uint1_t reserved2, uint8_t preTimeoutInterval, uint1_t reserved3,
+ uint5_t expFlagValue, uint2_t reserved4, uint16_t initialCountdown);
-/** @brief The GET watchdog IPMI command.
- * @param[in] netfn
- * @param[in] cmd
- * @param[in] request
- * @param[in,out] response
- * @param[out] data_len
- * @param[in] context
+/**@brief The getWatchdogTimer ipmi command.
*
- * @return IPMI_CC_OK on success, an IPMI error code otherwise.
- */
-ipmi_ret_t ipmi_app_watchdog_get(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request,
- ipmi_response_t response,
- ipmi_data_len_t data_len,
- ipmi_context_t context);
+ * @return
+ * - timerUse
+ * - timerActions
+ * - pretimeout
+ * - timeruseFlags
+ * - initialCountdown
+ * - presentCountdown
+ **/
+ipmi::RspType<uint8_t, // timerUse
+ uint8_t, // timerAction
+ uint8_t, // pretimeout
+ uint8_t, // expireFlags
+ uint16_t, // initial Countdown - Little Endian (deciseconds)
+ uint16_t // present Countdown - Little Endian (deciseconds)
+ >
+ ipmiGetWatchdogTimer();
diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp
index 0b88369..c567ca9 100644
--- a/app/watchdog_service.cpp
+++ b/app/watchdog_service.cpp
@@ -186,6 +186,11 @@ void WatchdogService::setTimerUse(TimerUse timerUse)
setProperty("CurrentTimerUse", convertForMessage(timerUse));
}
+void WatchdogService::setExpiredTimerUse(TimerUse timerUse)
+{
+ setProperty("ExpiredTimerUse", convertForMessage(timerUse));
+}
+
void WatchdogService::setInterval(uint64_t interval)
{
setProperty("Interval", interval);
diff --git a/app/watchdog_service.hpp b/app/watchdog_service.hpp
index 0cf1c74..ed64a3c 100644
--- a/app/watchdog_service.hpp
+++ b/app/watchdog_service.hpp
@@ -35,6 +35,7 @@ class WatchdogService
bool enabled;
Action expireAction;
TimerUse timerUse;
+ TimerUse expiredTimerUse;
uint64_t interval;
uint64_t timeRemaining;
};
@@ -78,6 +79,13 @@ class WatchdogService
*/
void setTimerUse(TimerUse timerUse);
+ /** @brief Sets the value of the ExpiredTimerUse property on the host
+ * watchdog
+ *
+ * @param[in] timerUse - The new timerUse value
+ */
+ void setExpiredTimerUse(TimerUse timerUse);
+
/** @brief Sets the value of the interval property on the host watchdog
*
* @param[in] interval - The new interval value
diff --git a/apphandler.cpp b/apphandler.cpp
index a12e220..030031c 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -1243,12 +1243,14 @@ void register_netfn_app_functions()
ipmi::Privilege::Operator, ipmiAppResetWatchdogTimer);
// <Set Watchdog Timer>
- ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_WD, NULL,
- ipmi_app_watchdog_set, PRIVILEGE_OPERATOR);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+ ipmi::app::cmdSetWatchdogTimer,
+ ipmi::Privilege::Operator, ipmiSetWatchdogTimer);
// <Get Watchdog Timer>
- ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_WD, NULL,
- ipmi_app_watchdog_get, PRIVILEGE_OPERATOR);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+ ipmi::app::cmdGetWatchdogTimer,
+ ipmi::Privilege::Operator, ipmiGetWatchdogTimer);
// <Get Self Test Results>
ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
OpenPOWER on IntegriCloud