From 0a408978a49fbf74e7dc2e986a433902efa3b598 Mon Sep 17 00:00:00 2001 From: George Hung Date: Thu, 9 Jul 2020 22:22:22 +0800 Subject: meta-quanta: gbs: add ipmi watchdog the upstream watchdog lose some command parameters and implementation we reference Intel-BMC repo[*1] apply patches for normal execute with x86-power-control [*1]: https://github.com/Intel-BMC/openbmc/tree/intel/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog (From meta-quanta rev: 230aee7e93f0e4873dc1e76a929e794559155cb5) Signed-off-by: George Hung Change-Id: Ib4e94948210d6d2948ab5983c962220810db45e8 Signed-off-by: Andrew Geissler --- ...re-timeout-interrupt-defined-in-IPMI-spec.patch | 57 ++++ ...25-Add-PreInterruptFlag-properity-in-DBUS.patch | 39 +++ .../dbus/phosphor-dbus-interfaces_%.bbappend | 5 + ...ize-phosphor-watchdog-for-Intel-platforms.patch | 313 +++++++++++++++++++++ .../phosphor-watchdog/phosphor-watchdog.service | 16 ++ .../watchdog/phosphor-watchdog_%.bbappend | 7 + 6 files changed, 437 insertions(+) create mode 100644 meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch create mode 100644 meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces/0025-Add-PreInterruptFlag-properity-in-DBUS.patch create mode 100644 meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend create mode 100644 meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog/0001-Customize-phosphor-watchdog-for-Intel-platforms.patch create mode 100644 meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog/phosphor-watchdog.service create mode 100644 meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend (limited to 'meta-quanta') diff --git a/meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch b/meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch new file mode 100644 index 000000000..67fa59090 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces/0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch @@ -0,0 +1,57 @@ +From 6e9a19c43acac7d4254910906329d98d7b59085a Mon Sep 17 00:00:00 2001 +From: Ren Yu +Date: Fri, 24 May 2019 14:55:10 +0800 +Subject: [PATCH] Add the pre-timeout interrupt defined in IPMI spec + +The IPMI watchdog pre-timeout interrupt is used to set the different +pre-timeout interrupt source. Add them as a dbus property, +IPMI set/get watchdog commands will use it. + +Signed-off-by: Ren Yu +--- + xyz/openbmc_project/State/Watchdog.interface.yaml | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/xyz/openbmc_project/State/Watchdog.interface.yaml b/xyz/openbmc_project/State/Watchdog.interface.yaml +index 2fc47d8..6dfa9b9 100644 +--- a/xyz/openbmc_project/State/Watchdog.interface.yaml ++++ b/xyz/openbmc_project/State/Watchdog.interface.yaml +@@ -33,6 +33,11 @@ properties: + description: > + The action the watchdog should perform when it expires. + default: 'HardReset' ++ - name: PreTimeoutInterrupt ++ type: enum[self.PreTimeoutInterruptAction] ++ description: > ++ The BMC generates the selected interrupt before the timer expires. ++ default: 'None' + - name: Interval + type: uint64 + description: > +@@ -73,6 +78,23 @@ enumerations: + description: > + Perform a power cycle of the system. + ++ - name: PreTimeoutInterruptAction ++ description: > ++ The type of PreTimeout Interrupt. ++ values: ++ - name: 'None' ++ description: > ++ Do nothing. ++ - name: 'SMI' ++ description: > ++ SMI. ++ - name: 'NMI' ++ description: > ++ NMI / Diagnostic Interrupt. ++ - name: 'MI' ++ description: > ++ Messaging Interrupt. ++ + - name: TimerUse + description: > + The type of timer use. +-- +2.7.4 + diff --git a/meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces/0025-Add-PreInterruptFlag-properity-in-DBUS.patch b/meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces/0025-Add-PreInterruptFlag-properity-in-DBUS.patch new file mode 100644 index 000000000..d7e66abd2 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces/0025-Add-PreInterruptFlag-properity-in-DBUS.patch @@ -0,0 +1,39 @@ +From b7c487750c05dcc081219ccdd4ef539beef6aa30 Mon Sep 17 00:00:00 2001 +From: Ren Yu +Date: Mon, 29 Jul 2019 10:51:12 +0800 +Subject: [PATCH] Add PreInterruptFlag properity in DBUS. + +PreTimeoutInterruptOccurFlag in DBUS would be set 'true' +when watchdog pre-timeout interrupt occurred. + +Tested: +Enable command(raw 0x06 0x31) that get message flag +can set right bit about watchdog, +need record PreTimeoutInterruptOccurFlag +at xyz.openbmmc_project.State.Watchdog when watchdog +pre-timeout interrupt occurred. + +Signed-off-by: Ren Yu +--- + xyz/openbmc_project/State/Watchdog.interface.yaml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/xyz/openbmc_project/State/Watchdog.interface.yaml b/xyz/openbmc_project/State/Watchdog.interface.yaml +index bf4cca0..6579368 100644 +--- a/xyz/openbmc_project/State/Watchdog.interface.yaml ++++ b/xyz/openbmc_project/State/Watchdog.interface.yaml +@@ -59,6 +59,11 @@ properties: + description: > + The timer user at the time of expiration. + default: 'Reserved' ++ - name: PreTimeoutInterruptOccurFlag ++ type: boolean ++ description: > ++ PreTimeoutInterruptOccurFlag that preTimeoutInterrupt action occurred. ++ default: false + + enumerations: + - name: Action +-- +2.7.4 + diff --git a/meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend b/meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend new file mode 100644 index 000000000..0b5bff905 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend @@ -0,0 +1,5 @@ +FILESEXTRAPATHS_prepend_gbs := "${THISDIR}/${PN}:" + +SRC_URI_append_gbs = " file://0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch \ + file://0025-Add-PreInterruptFlag-properity-in-DBUS.patch \ + " diff --git a/meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog/0001-Customize-phosphor-watchdog-for-Intel-platforms.patch b/meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog/0001-Customize-phosphor-watchdog-for-Intel-platforms.patch new file mode 100644 index 000000000..22670d3fc --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog/0001-Customize-phosphor-watchdog-for-Intel-platforms.patch @@ -0,0 +1,313 @@ +From ac0c216ac2c273c620579fd1308c8c225e0cca36 Mon Sep 17 00:00:00 2001 +From: James Feist +Date: Mon, 17 Jun 2019 12:00:58 -0700 +Subject: [PATCH] Customize phosphor-watchdog for Intel platforms + +This patch adds various changes to phosphor-watchdog that are +required for compatibility with Intel platforms. + + 1. Add Redfish messages for watchdog timeout and pre-interrupt + 2. Use dbus properties for power control insted of service files + 3. Use host status to enable/disable watchdog + 4. Set preTimeoutInterruptOccurFlag + +Signed-off-by: James Feist +Signed-off-by: Ren Yu +Signed-off-by: Yong Li +Signed-off-by: Jason M. Bills +--- + watchdog.cpp | 193 ++++++++++++++++++++++++++++++++++++++++++++++++--- + watchdog.hpp | 23 +++++- + 2 files changed, 206 insertions(+), 10 deletions(-) + +diff --git a/watchdog.cpp b/watchdog.cpp +index 57e9050..3b5356f 100644 +--- a/watchdog.cpp ++++ b/watchdog.cpp +@@ -1,11 +1,14 @@ + #include "watchdog.hpp" + ++#include ++ + #include + #include + #include + #include + #include + #include ++#include + + namespace phosphor + { +@@ -18,10 +21,69 @@ using namespace phosphor::logging; + using sdbusplus::exception::SdBusError; + using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; + +-// systemd service to kick start a target. +-constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; +-constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1"; +-constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; ++const static constexpr char* currentHostState = "CurrentHostState"; ++const static constexpr char* hostStatusOff = ++ "xyz.openbmc_project.State.Host.HostState.Off"; ++ ++const static constexpr char* actionDescription = " due to Watchdog timeout"; ++const static constexpr char* hardResetDescription = "Hard Reset - System reset"; ++const static constexpr char* powerOffDescription = ++ "Power Down - System power down"; ++const static constexpr char* powerCycleDescription = ++ "Power Cycle - System power cycle"; ++const static constexpr char* timerExpiredDescription = "Timer expired"; ++ ++const static constexpr char* preInterruptActionNone = ++ "xyz.openbmc_project.State.Watchdog.PreTimeoutInterruptAction.None"; ++ ++const static constexpr char* preInterruptDescriptionSMI = "SMI"; ++const static constexpr char* preInterruptDescriptionNMI = "NMI"; ++const static constexpr char* preInterruptDescriptionMI = "Messaging Interrupt"; ++ ++const static constexpr char* reservedDescription = "Reserved"; ++ ++const static constexpr char* timerUseDescriptionBIOSFRB2 = "BIOS FRB2"; ++const static constexpr char* timerUseDescriptionBIOSPOST = "BIOS/POST"; ++const static constexpr char* timerUseDescriptionOSLoad = "OSLoad"; ++const static constexpr char* timerUseDescriptionSMSOS = "SMS/OS"; ++const static constexpr char* timerUseDescriptionOEM = "OEM"; ++ ++namespace restart ++{ ++static constexpr const char* busName = ++ "xyz.openbmc_project.Control.Host.RestartCause"; ++static constexpr const char* path = ++ "/xyz/openbmc_project/control/host0/restart_cause"; ++static constexpr const char* interface = ++ "xyz.openbmc_project.Control.Host.RestartCause"; ++static constexpr const char* property = "RequestedRestartCause"; ++} // namespace restart ++ ++// chassis state manager service ++namespace chassis ++{ ++static constexpr const char* busName = "xyz.openbmc_project.State.Chassis"; ++static constexpr const char* path = "/xyz/openbmc_project/state/chassis0"; ++static constexpr const char* interface = "xyz.openbmc_project.State.Chassis"; ++static constexpr const char* request = "RequestedPowerTransition"; ++} // namespace chassis ++ ++void Watchdog::powerStateChangedHandler( ++ const std::map>& props) ++{ ++ const auto iter = props.find(currentHostState); ++ if (iter != props.end()) ++ { ++ const std::string* powerState = std::get_if(&iter->second); ++ if (powerState && (*powerState == hostStatusOff)) ++ { ++ if (timerEnabled()) ++ { ++ enabled(false); ++ } ++ } ++ } ++} + + void Watchdog::resetTimeRemaining(bool enableWatchdog) + { +@@ -107,13 +169,102 @@ uint64_t Watchdog::interval(uint64_t value) + // Optional callback function on timer expiration + void Watchdog::timeOutHandler() + { ++ PreTimeoutInterruptAction preTimeoutInterruptAction = preTimeoutInterrupt(); ++ std::string preInterruptActionMessageArgs{}; ++ + Action action = expireAction(); ++ std::string actionMessageArgs{}; ++ ++ expiredTimerUse(currentTimerUse()); ++ ++ TimerUse timeUser = expiredTimerUse(); ++ std::string timeUserMessage{}; ++ + if (!this->enabled()) + { + action = fallback->action; + } + +- expiredTimerUse(currentTimerUse()); ++ switch (timeUser) ++ { ++ case Watchdog::TimerUse::BIOSFRB2: ++ timeUserMessage = timerUseDescriptionBIOSFRB2; ++ break; ++ case Watchdog::TimerUse::BIOSPOST: ++ timeUserMessage = timerUseDescriptionBIOSPOST; ++ break; ++ case Watchdog::TimerUse::OSLoad: ++ timeUserMessage = timerUseDescriptionOSLoad; ++ break; ++ case Watchdog::TimerUse::SMSOS: ++ timeUserMessage = timerUseDescriptionSMSOS; ++ break; ++ case Watchdog::TimerUse::OEM: ++ timeUserMessage = timerUseDescriptionOEM; ++ break; ++ default: ++ timeUserMessage = reservedDescription; ++ break; ++ } ++ ++ switch (action) ++ { ++ case Watchdog::Action::HardReset: ++ actionMessageArgs = std::string(hardResetDescription) + ++ std::string(actionDescription); ++ break; ++ case Watchdog::Action::PowerOff: ++ actionMessageArgs = std::string(powerOffDescription) + ++ std::string(actionDescription); ++ break; ++ case Watchdog::Action::PowerCycle: ++ actionMessageArgs = std::string(powerCycleDescription) + ++ std::string(actionDescription); ++ break; ++ case Watchdog::Action::None: ++ actionMessageArgs = timerExpiredDescription; ++ break; ++ default: ++ actionMessageArgs = reservedDescription; ++ break; ++ } ++ ++ // Log into redfish event log ++ sd_journal_send("MESSAGE=IPMIWatchdog: Timed out ACTION=%s", ++ convertForMessage(action).c_str(), "PRIORITY=%i", LOG_INFO, ++ "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.IPMIWatchdog", ++ "REDFISH_MESSAGE_ARGS=%s. timer use: %s", ++ actionMessageArgs.c_str(), timeUserMessage.c_str(), NULL); ++ ++ switch (preTimeoutInterruptAction) ++ { ++ case Watchdog::PreTimeoutInterruptAction::SMI: ++ preInterruptActionMessageArgs = preInterruptDescriptionSMI; ++ break; ++ case Watchdog::PreTimeoutInterruptAction::NMI: ++ preInterruptActionMessageArgs = preInterruptDescriptionNMI; ++ break; ++ case Watchdog::PreTimeoutInterruptAction::MI: ++ preInterruptActionMessageArgs = preInterruptDescriptionMI; ++ break; ++ default: ++ preInterruptActionMessageArgs = reservedDescription; ++ break; ++ } ++ ++ if (preInterruptActionNone != convertForMessage(preTimeoutInterruptAction)) ++ { ++ preTimeoutInterruptOccurFlag(true); ++ ++ sd_journal_send("MESSAGE=IPMIWatchdog: Pre Timed out Interrupt=%s", ++ convertForMessage(preTimeoutInterruptAction).c_str(), ++ "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", ++ "OpenBMC.0.1.IPMIWatchdog", ++ "REDFISH_MESSAGE_ARGS=Timer interrupt - %s due to " ++ "Watchdog timeout. timer use: %s", ++ preInterruptActionMessageArgs.c_str(), ++ timeUserMessage.c_str(), NULL); ++ } + + auto target = actionTargetMap.find(action); + if (target == actionTargetMap.end()) +@@ -133,10 +284,11 @@ void Watchdog::timeOutHandler() + + try + { +- auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT, +- SYSTEMD_INTERFACE, "StartUnit"); +- method.append(target->second); +- method.append("replace"); ++ auto method = ++ bus.new_method_call(chassis::busName, chassis::path, ++ "org.freedesktop.DBus.Properties", "Set"); ++ method.append(chassis::interface, chassis::request, ++ std::variant(target->second)); + + bus.call_noreply(method); + } +@@ -147,6 +299,29 @@ void Watchdog::timeOutHandler() + entry("ERROR=%s", e.what())); + commit(); + } ++ ++ // set restart cause for watchdog HardReset & PowerCycle actions ++ if ((action == Watchdog::Action::HardReset) || ++ (action == Watchdog::Action::PowerCycle)) ++ { ++ try ++ { ++ auto method = bus.new_method_call( ++ restart::busName, restart::path, ++ "org.freedesktop.DBus.Properties", "Set"); ++ method.append( ++ restart::interface, restart::property, ++ std::variant("xyz.openbmc_project.State.Host." ++ "RestartCause.WatchdogTimer")); ++ bus.call(method); ++ } ++ catch (sdbusplus::exception_t& e) ++ { ++ log("Failed to set HostRestartCause property", ++ entry("ERROR=%s", e.what())); ++ commit(); ++ } ++ } + } + + tryFallbackOrDisable(); +diff --git a/watchdog.hpp b/watchdog.hpp +index 7de9bb3..b004b7a 100644 +--- a/watchdog.hpp ++++ b/watchdog.hpp +@@ -68,7 +68,18 @@ class Watchdog : public WatchdogInherits + WatchdogInherits(bus, objPath), + bus(bus), actionTargetMap(std::move(actionTargetMap)), + fallback(std::move(fallback)), minInterval(minInterval), +- timer(event, std::bind(&Watchdog::timeOutHandler, this)) ++ timer(event, std::bind(&Watchdog::timeOutHandler, this)), ++ powerStateChangedSignal( ++ bus, ++ sdbusplus::bus::match::rules::propertiesChanged( ++ "/xyz/openbmc_project/state/host0", ++ "xyz.openbmc_project.State.Host"), ++ [this](sdbusplus::message::message& msg) { ++ std::string objectName; ++ std::map> props; ++ msg.read(objectName, props); ++ powerStateChangedHandler(props); ++ }) + { + // We set the watchdog interval with the default value. + interval(interval()); +@@ -77,6 +88,12 @@ class Watchdog : public WatchdogInherits + tryFallbackOrDisable(); + } + ++ /** @brief Disable watchdog when power status change meet ++ * the specific requirement ++ */ ++ void powerStateChangedHandler( ++ const std::map>& props); ++ + /** @brief Resets the TimeRemaining to the configured Interval + * Optionally enables the watchdog. + * +@@ -165,6 +182,10 @@ class Watchdog : public WatchdogInherits + /** @brief Contained timer object */ + sdeventplus::utility::Timer timer; + ++ /** @brief Optional Callback handler when power status change meet ++ * the specific requirement */ ++ sdbusplus::bus::match_t powerStateChangedSignal; ++ + /** @brief Optional Callback handler on timer expirartion */ + void timeOutHandler(); + diff --git a/meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog/phosphor-watchdog.service b/meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog/phosphor-watchdog.service new file mode 100644 index 000000000..5ef1a4179 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog/phosphor-watchdog.service @@ -0,0 +1,16 @@ +[Unit] +Description=Phosphor Watchdog + +[Service] +ExecStart=/usr/bin/env phosphor-watchdog --continue --service=xyz.openbmc_project.Watchdog \ + --path=/xyz/openbmc_project/watchdog/host0 \ + --action_target=xyz.openbmc_project.State.Watchdog.Action.HardReset=xyz.openbmc_project.State.Chassis.Transition.Reset \ + --action_target=xyz.openbmc_project.State.Watchdog.Action.PowerOff=xyz.openbmc_project.State.Chassis.Transition.Off \ + --action_target=xyz.openbmc_project.State.Watchdog.Action.PowerCycle=xyz.openbmc_project.State.Chassis.Transition.PowerCycle + +SyslogIdentifier=phosphor-watchdog +BusName =xyz.openbmc_project.Watchdog +Type=dbus + +[Install] +WantedBy=basic.target diff --git a/meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend b/meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend new file mode 100644 index 000000000..9c491ecfc --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend @@ -0,0 +1,7 @@ +FILESEXTRAPATHS_prepend_gbs := "${THISDIR}/${PN}:" + +SRC_URI_append_gbs = " file://0001-Customize-phosphor-watchdog-for-Intel-platforms.patch" + +# Remove the override to keep service running after DC cycle +SYSTEMD_OVERRIDE_${PN}_remove_gbs = "poweron.conf:phosphor-watchdog@poweron.service.d/poweron.conf" +SYSTEMD_SERVICE_${PN}_gbs = "phosphor-watchdog.service" -- cgit v1.2.3