From a729bf414b8d44bbb7ca28eefe1003786d37c353 Mon Sep 17 00:00:00 2001 From: Yong Li Date: Mon, 14 Oct 2019 12:42:10 +0800 Subject: Expiration flags fix for watchdog get/set commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The expiration flags should be retain their state across system resets and power cycles. Tested: Set “BIOS FRB2” and start ipmitool raw 0x06 0x24 0x01 0x00 0x00 0x00 0x30 0x00 ipmitool mc watchdog reset after stopped: Timer Expiration Flags should be : (0x02) * BIOS FRB2 Then Set “BIOS/POST” and start, ipmitool raw 0x06 0x24 0x02 0x00 0x00 0x00 0x30 0x00 ipmitool mc watchdog reset after stopped: Timer Expiration Flags should be : (0x06) * BIOS FRB2 * BIOS/POST “impitool mc watchdog get” displays the correct Timer Expiration Flags when the timer is running; Signed-off-by: Yong Li Change-Id: Ic0c27c6c1e8bed2db8ce30fc0eec2a6538bb1992 --- app/watchdog.cpp | 43 +++++++++++++++++++++++-------------------- app/watchdog.hpp | 6 +++--- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/app/watchdog.cpp b/app/watchdog.cpp index 47eacf0..f97c45b 100644 --- a/app/watchdog.cpp +++ b/app/watchdog.cpp @@ -4,6 +4,7 @@ #include +#include #include #include #include @@ -174,8 +175,11 @@ WatchdogService::TimerUse ipmiTimerUseToWdTimerUse(IpmiTimerUse ipmiTimerUse) } static bool timerNotLogFlags = false; -static uint8_t timerUseExpirationFlags = 0; +static std::bitset<8> timerUseExpirationFlags = 0; static uint3_t timerPreTimeoutInterrupt = 0; +static constexpr uint8_t wdExpirationFlagReservedBit0 = 0x0; +static constexpr uint8_t wdExpirationFlagReservedBit6 = 0x6; +static constexpr uint8_t wdExpirationFlagReservedBit7 = 0x7; /**@brief The Set Watchdog Timer ipmi command. * @@ -190,18 +194,22 @@ static uint3_t timerPreTimeoutInterrupt = 0; * * @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) +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, + std::bitset<8> expFlagValue, uint16_t initialCountdown) { if ((timerUse == wdTimerUseResTimer1) || (timerUse == wdTimerUseResTimer2) || (timerUse == wdTimerUseResTimer3) || (timeoutAction > wdTimeoutActionMax) || (preTimeoutInterrupt == wdTimeoutInterruptTimer) || - (reserved | reserved1 | reserved2 | reserved3 | reserved4)) + (reserved | reserved1 | reserved2 | + expFlagValue.test(wdExpirationFlagReservedBit0) | + expFlagValue.test(wdExpirationFlagReservedBit6) | + expFlagValue.test(wdExpirationFlagReservedBit7))) { return ipmi::responseInvalidFieldRequest(); } @@ -234,7 +242,7 @@ ipmi::RspType<> ipmiSetWatchdogTimer( wd_service.setExpiredTimerUse(WatchdogService::TimerUse::Reserved); - timerUseExpirationFlags &= static_cast(~expFlagValue) << 2; + timerUseExpirationFlags &= ~expFlagValue; // Set the new interval and the time remaining deci -> mill seconds const uint64_t interval = initialCountdown * 100; @@ -363,14 +371,13 @@ ipmi::RspType, // expireFlags + uint16_t, // initial Countdown - Little Endian (deciseconds) + uint16_t // present Countdown - Little Endian (deciseconds) > ipmiGetWatchdogTimer() { - uint8_t expireFlags = 0; uint16_t presentCountdown = 0; uint8_t pretimeout = 0; @@ -385,27 +392,23 @@ ipmi::RspType( - wdTimerUseToIpmiTimerUse(wd_prop.expiredTimerUse)); + timerUseExpirationFlags.set(static_cast( + wdTimerUseToIpmiTimerUse(wd_prop.expiredTimerUse))); } if (wd_prop.enabled) { presentCountdown = htole16(wd_prop.timeRemaining / 100); - expireFlags = 0; } else { if (wd_prop.expiredTimerUse == WatchdogService::TimerUse::Reserved) { presentCountdown = initialCountdown; - expireFlags = 0; } else { presentCountdown = 0; - expireFlags = timerUseExpirationFlags; // Automatically clear it whenever a timer expiration occurs. timerNotLogFlags = false; } @@ -419,7 +422,7 @@ ipmi::RspType(wdTimerUseToIpmiTimerUse(wd_prop.timerUse)), 0, wd_prop.enabled, timerNotLogFlags, static_cast(wdActionToIpmiAction(wd_prop.expireAction)), 0, - timerPreTimeoutInterrupt, 0, pretimeout, expireFlags, + timerPreTimeoutInterrupt, 0, pretimeout, timerUseExpirationFlags, initialCountdown, presentCountdown); } catch (const InternalFailure& e) diff --git a/app/watchdog.hpp b/app/watchdog.hpp index a7ff62e..fa53ac7 100644 --- a/app/watchdog.hpp +++ b/app/watchdog.hpp @@ -22,8 +22,8 @@ ipmi::RspType<> ipmiAppResetWatchdogTimer(); 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); + uint1_t reserved2, uint8_t preTimeoutInterval, std::bitset<8> expFlagValue, + uint16_t initialCountdown); /**@brief The getWatchdogTimer ipmi command. * @@ -38,7 +38,7 @@ ipmi::RspType<> ipmiSetWatchdogTimer( ipmi::RspType, // expireFlags uint16_t, // initial Countdown - Little Endian (deciseconds) uint16_t // present Countdown - Little Endian (deciseconds) > -- cgit v1.2.1