From 9d538eb746f20eb7efb1a81cace692b2f7b3c8df Mon Sep 17 00:00:00 2001 From: George Hung Date: Wed, 28 Apr 2021 10:26:40 +0800 Subject: meta-quanta: gbs: update chassis control and support signed sensor - Update IPMI Chassis Control command transition requests: https://gerrit.openbmc-project.xyz/29051 - Add Chassis State Transition interface https://gerrit.openbmc-project.xyz/29050 - Update Host State Transition function https://gerrit.openbmc-project.xyz/29049 - Fix issues and support signed sensor values https://gerrit.openbmc-project.xyz/26754 Signed-off-by: George Hung Change-Id: Ice305cb9a9e390099a828e872af451e832d59749 --- ...01-Add-Chassis-State-Transition-interface.patch | 79 +++++++++ ...x-issues-and-support-signed-sensor-values.patch | 169 +++++++++++++++++++ ...002-Update-Host-State-Transition-function.patch | 137 ++++++++++++++++ ...-Chassis-Control-command-transition-reque.patch | 180 +++++++++++++++++++++ ...he-pre-timeout-interrupt-in-dbus-property.patch | 138 ---------------- 5 files changed, 565 insertions(+), 138 deletions(-) create mode 100644 meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-Chassis-State-Transition-interface.patch create mode 100644 meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Fix-issues-and-support-signed-sensor-values.patch create mode 100644 meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Update-Host-State-Transition-function.patch create mode 100644 meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0003-Update-IPMI-Chassis-Control-command-transition-reque.patch delete mode 100644 meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch (limited to 'meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host') diff --git a/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-Chassis-State-Transition-interface.patch b/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-Chassis-State-Transition-interface.patch new file mode 100644 index 000000000..74f982b33 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-Chassis-State-Transition-interface.patch @@ -0,0 +1,79 @@ +From a1f9d797753e32b36e08e7d611ff88b10e9bbad2 Mon Sep 17 00:00:00 2001 +From: "Jason M. Bills" +Date: Thu, 30 Jan 2020 16:18:33 -0800 +Subject: [PATCH 1/3] Add Chassis State Transition interface + +This adds the Chassis State Transition interface in preparation +to support the mapping defined in the design document below. + +ref: https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/22358 + +Tested: +Ran each IPMI chassis control command to confirm the expected +behavior: +ipmitool power on: system is powered-on +ipmitool power off: system is forced off +ipmitool power cycle: system is forced off then powered-on +ipmitool power reset: system is hard reset +ipmitool power soft: soft power-off requested from system software + +Change-Id: I6acfb795a9a33ff5227a5d6e1830774ab732ac0c +Signed-off-by: Jason M. Bills +--- + chassishandler.cpp | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/chassishandler.cpp b/chassishandler.cpp +index 0d318647..fdbb9fa5 100644 +--- a/chassishandler.cpp ++++ b/chassishandler.cpp +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -865,6 +866,38 @@ int initiate_state_transition(State::Host::Transition transition) + return rc; + } + ++//------------------------------------------ ++// Calls into Chassis State Manager Dbus object ++//------------------------------------------ ++int initiateChassisStateTransition(State::Chassis::Transition transition) ++{ ++ // OpenBMC Chassis State Manager dbus framework ++ constexpr auto chassisStatePath = "/xyz/openbmc_project/state/chassis0"; ++ constexpr auto chassisStateIntf = "xyz.openbmc_project.State.Chassis"; ++ ++ auto service = ++ ipmi::getService(*getSdBus(), chassisStateIntf, chassisStatePath); ++ ++ // Convert to string equivalent of the passed in transition enum. ++ auto request = State::convertForMessage(transition); ++ ++ try ++ { ++ ipmi::setDbusProperty(*getSdBus(), service, chassisStatePath, ++ chassisStateIntf, "RequestedPowerTransition", ++ request); ++ } ++ catch (std::exception& e) ++ { ++ log( ++ "Failed to initiate transition", ++ entry("EXCEPTION=%s, REQUEST=%s", e.what(), request.c_str())); ++ return -1; ++ } ++ ++ return 0; ++} ++ + //------------------------------------------ + // Set Enabled property to inform NMI source + // handling to trigger a NMI_OUT BSOD. +-- +2.21.0 + diff --git a/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Fix-issues-and-support-signed-sensor-values.patch b/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Fix-issues-and-support-signed-sensor-values.patch new file mode 100644 index 000000000..6d13f9297 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Fix-issues-and-support-signed-sensor-values.patch @@ -0,0 +1,169 @@ +From 8ce91a760fca8c945540679c92770f841629e179 Mon Sep 17 00:00:00 2001 +From: Tony Lee +Date: Thu, 31 Oct 2019 17:24:16 +0800 +Subject: [PATCH] Fix issues and support signed sensor values + +Sensor will get "disable" when the command "ipmitool sdr elist" is +executed that if sensorReadingType is 0x6F. + +sensor_units_1 is always set to 0 currently. To support the display of +signed sensor values, we add the attribute "sensorUnits1" to the sensor +mapping yaml. This attribute can be used to determine whether the +sensor is signed. + +It were making negative values 0 in get::readingData(). Fix the issue +by using a int32_t and add an overflow check. + +Change-Id: I705defcf18805db9ada7d0de0738a59aedab61df +Signed-off-by: Tony Lee +--- + include/ipmid/types.hpp | 2 ++ + scripts/sensor-example.yaml | 2 ++ + scripts/writesensor.mako.cpp | 2 ++ + sensordatahandler.cpp | 2 -- + sensordatahandler.hpp | 31 ++++++++++++++++++++++++++++--- + sensorhandler.cpp | 5 ++--- + 6 files changed, 36 insertions(+), 8 deletions(-) + +diff --git a/include/ipmid/types.hpp b/include/ipmid/types.hpp +index e62c8192..bd1fac2b 100644 +--- a/include/ipmid/types.hpp ++++ b/include/ipmid/types.hpp +@@ -133,6 +133,7 @@ using Unit = std::string; + using EntityType = uint8_t; + using EntityInst = uint8_t; + using SensorName = std::string; ++using SensorUnits1 = uint8_t; + + enum class Mutability + { +@@ -167,6 +168,7 @@ struct Info + Exponent exponentR; + bool hasScale; + Scale scale; ++ SensorUnits1 sensorUnits1; + Unit unit; + std::function updateFunc; + std::function getFunc; +diff --git a/scripts/sensor-example.yaml b/scripts/sensor-example.yaml +index 9760cd01..bddd2e6d 100644 +--- a/scripts/sensor-example.yaml ++++ b/scripts/sensor-example.yaml +@@ -112,6 +112,8 @@ + # Applies for analog sensors, the actual reading value for the sensor is + # Value * 10^N + scale: -3 ++ # Indicate Analog Data Format, Rate unit, Modifier unit and Percentage ++ sensorUnits1 : 0x80 + mutability: Mutability::Write|Mutability::Read + serviceInterface: org.freedesktop.DBus.Properties + readingType: readingData +diff --git a/scripts/writesensor.mako.cpp b/scripts/writesensor.mako.cpp +index 8b268052..813f9404 100644 +--- a/scripts/writesensor.mako.cpp ++++ b/scripts/writesensor.mako.cpp +@@ -49,6 +49,7 @@ extern const IdInfoMap sensors = { + offsetB = sensor.get("offsetB", 0) + bExp = sensor.get("bExp", 0) + rExp = sensor.get("rExp", 0) ++ sensorUnits1 = sensor.get("sensorUnits1", 0) + unit = sensor.get("unit", "") + scale = sensor.get("scale", 0) + hasScale = "true" if "scale" in sensor.keys() else "false" +@@ -91,6 +92,7 @@ extern const IdInfoMap sensors = { + .exponentR = ${rExp}, + .hasScale = ${hasScale}, + .scale = ${scale}, ++ .sensorUnits1 = ${sensorUnits1}, + .unit = "${unit}", + .updateFunc = ${updateFunc}, + .getFunc = ${getFunc}, +diff --git a/sensordatahandler.cpp b/sensordatahandler.cpp +index 06f5f429..fc74b8f8 100644 +--- a/sensordatahandler.cpp ++++ b/sensordatahandler.cpp +@@ -7,8 +7,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + +diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp +index 5cad58c5..c48140a3 100644 +--- a/sensordatahandler.hpp ++++ b/sensordatahandler.hpp +@@ -8,6 +8,8 @@ + #include + #include + #include ++#include ++#include + #include + + namespace ipmi +@@ -28,6 +30,7 @@ using ServicePath = std::pair; + using Interfaces = std::vector; + + using MapperResponseType = std::map>; ++using namespace phosphor::logging; + + /** @brief get the D-Bus service and service path + * @param[in] bus - The Dbus bus object +@@ -225,10 +228,32 @@ GetSensorResponse readingData(const Info& sensorInfo) + + double value = std::get(propValue) * + std::pow(10, sensorInfo.scale - sensorInfo.exponentR); ++ int32_t rawData = ++ (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM; + +- auto rawData = static_cast((value - sensorInfo.scaledOffset) / +- sensorInfo.coefficientM); +- setReading(rawData, &response); ++ constexpr uint8_t sensorUnitsSignedBits = 2 << 6; ++ constexpr uint8_t signedDataFormat = 0x80; ++ // if sensorUnits1 [7:6] = 10b, sensor is signed ++ if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat) ++ { ++ if (rawData > std::numeric_limits::max() || ++ rawData < std::numeric_limits::lowest()) ++ { ++ log("Value out of range"); ++ throw std::out_of_range("Value out of range"); ++ } ++ setReading(static_cast(rawData), &response); ++ } ++ else ++ { ++ if (rawData > std::numeric_limits::max() || ++ rawData < std::numeric_limits::lowest()) ++ { ++ log("Value out of range"); ++ throw std::out_of_range("Value out of range"); ++ } ++ setReading(static_cast(rawData), &response); ++ } + + return response; + } +diff --git a/sensorhandler.cpp b/sensorhandler.cpp +index 36998715..260331a0 100644 +--- a/sensorhandler.cpp ++++ b/sensorhandler.cpp +@@ -700,9 +700,8 @@ ipmi_ret_t populate_record_from_dbus(get_sdr::SensorDataFullRecordBody* body, + /* Functional sensor case */ + if (isAnalogSensor(info->propertyInterfaces.begin()->first)) + { +- +- body->sensor_units_1 = 0; // unsigned, no rate, no modifier, not a % +- ++ body->sensor_units_1 = info->sensorUnits1; // default is 0. unsigned, no ++ // rate, no modifier, not a % + /* Unit info */ + setUnitFieldsForObject(info, body); + +-- +2.21.0 + diff --git a/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Update-Host-State-Transition-function.patch b/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Update-Host-State-Transition-function.patch new file mode 100644 index 000000000..156327b9c --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Update-Host-State-Transition-function.patch @@ -0,0 +1,137 @@ +From 8079e1e39e1953458bd2e59c7f546a3d879558db Mon Sep 17 00:00:00 2001 +From: "Jason M. Bills" +Date: Thu, 30 Jan 2020 16:02:39 -0800 +Subject: [PATCH 2/3] Update Host State Transition function + +This updates the Host State Transition function to use the new +IPMI DBus APIs for transition requests. + +Tested: +Ran each IPMI chassis control command to confirm the expected +behavior: +ipmitool power on: system is powered-on +ipmitool power off: system is forced off +ipmitool power cycle: system is forced off then powered-on +ipmitool power reset: system is hard reset +ipmitool power soft: soft power-off requested from system software + +Change-Id: Id2253a9c0060e892bc318dd02a6221ac1a2ae2d9 +Signed-off-by: Jason M. Bills +--- + chassishandler.cpp | 64 +++++++++++++--------------------------------- + 1 file changed, 18 insertions(+), 46 deletions(-) + +diff --git a/chassishandler.cpp b/chassishandler.cpp +index fdbb9fa5..af9cba72 100644 +--- a/chassishandler.cpp ++++ b/chassishandler.cpp +@@ -811,59 +811,31 @@ ipmi::RspType<> ipmiSetChassisCap(bool intrusion, bool fpLockout, + //------------------------------------------ + // Calls into Host State Manager Dbus object + //------------------------------------------ +-int initiate_state_transition(State::Host::Transition transition) ++int initiateHostStateTransition(State::Host::Transition transition) + { + // OpenBMC Host State Manager dbus framework +- constexpr auto HOST_STATE_MANAGER_ROOT = "/xyz/openbmc_project/state/host0"; +- constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host"; +- constexpr auto DBUS_PROPERTY_IFACE = "org.freedesktop.DBus.Properties"; +- constexpr auto PROPERTY = "RequestedHostTransition"; ++ constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0"; ++ constexpr auto hostStateIntf = "xyz.openbmc_project.State.Host"; + +- // sd_bus error +- int rc = 0; +- char* busname = NULL; +- +- // SD Bus error report mechanism. +- sd_bus_error bus_error = SD_BUS_ERROR_NULL; +- +- // Gets a hook onto either a SYSTEM or SESSION bus +- sd_bus* bus_type = ipmid_get_sd_bus_connection(); +- rc = mapper_get_service(bus_type, HOST_STATE_MANAGER_ROOT, &busname); +- if (rc < 0) +- { +- log( +- "Failed to get bus name", +- entry("ERRNO=0x%X, OBJPATH=%s", -rc, HOST_STATE_MANAGER_ROOT)); +- return rc; +- } ++ auto service = ipmi::getService(*getSdBus(), hostStateIntf, hostStatePath); + + // Convert to string equivalent of the passed in transition enum. + auto request = State::convertForMessage(transition); + +- rc = sd_bus_call_method(bus_type, // On the system bus +- busname, // Service to contact +- HOST_STATE_MANAGER_ROOT, // Object path +- DBUS_PROPERTY_IFACE, // Interface name +- "Set", // Method to be called +- &bus_error, // object to return error +- nullptr, // Response buffer if any +- "ssv", // Takes 3 arguments +- HOST_STATE_MANAGER_IFACE, PROPERTY, "s", +- request.c_str()); +- if (rc < 0) ++ try + { +- log("Failed to initiate transition", +- entry("ERRNO=0x%X, REQUEST=%s", -rc, request.c_str())); ++ ipmi::setDbusProperty(*getSdBus(), service, hostStatePath, ++ hostStateIntf, "RequestedHostTransition", ++ request); + } +- else ++ catch (std::exception& e) + { +- log("Transition request initiated successfully"); ++ log( ++ "Failed to initiate transition", ++ entry("EXCEPTION=%s, REQUEST=%s", e.what(), request.c_str())); ++ return -1; + } +- +- sd_bus_error_free(&bus_error); +- free(busname); +- +- return rc; ++ return 0; + } + + //------------------------------------------ +@@ -1411,7 +1383,7 @@ ipmi::RspType<> ipmiChassisControl(uint8_t chassisControl) + switch (chassisControl) + { + case CMD_POWER_ON: +- rc = initiate_state_transition(State::Host::Transition::On); ++ rc = initiateHostStateTransition(State::Host::Transition::On); + break; + case CMD_POWER_OFF: + // This path would be hit in 2 conditions. +@@ -1439,7 +1411,7 @@ ipmi::RspType<> ipmiChassisControl(uint8_t chassisControl) + indicate_no_softoff_needed(); + + // Now request the shutdown +- rc = initiate_state_transition(State::Host::Transition::Off); ++ rc = initiateHostStateTransition(State::Host::Transition::Off); + } + else + { +@@ -1460,12 +1432,12 @@ ipmi::RspType<> ipmiChassisControl(uint8_t chassisControl) + // originating via a soft power off SMS request) + indicate_no_softoff_needed(); + +- rc = initiate_state_transition(State::Host::Transition::Reboot); ++ rc = initiateHostStateTransition(State::Host::Transition::Reboot); + break; + + case CMD_SOFT_OFF_VIA_OVER_TEMP: + // Request Host State Manager to do a soft power off +- rc = initiate_state_transition(State::Host::Transition::Off); ++ rc = initiateHostStateTransition(State::Host::Transition::Off); + break; + + case CMD_PULSE_DIAGNOSTIC_INTR: +-- +2.21.0 + diff --git a/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0003-Update-IPMI-Chassis-Control-command-transition-reque.patch b/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0003-Update-IPMI-Chassis-Control-command-transition-reque.patch new file mode 100644 index 000000000..271af3f5b --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0003-Update-IPMI-Chassis-Control-command-transition-reque.patch @@ -0,0 +1,180 @@ +From 291629d5c3e5bea31925c9d025688897c90eb783 Mon Sep 17 00:00:00 2001 +From: "Jason M. Bills" +Date: Thu, 30 Jan 2020 16:22:24 -0800 +Subject: [PATCH 3/3] Update IPMI Chassis Control command transition requests + +This change updates the IPMI Chassis Control command to use the new +host state transitions and chassis off transition based on the +mapping in the design document below. This allows each chassis +control action to more closely follow the behavior defined in the +IPMI spec. + +ref: https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/22358 + +Tested: +Ran each IPMI chassis control command to confirm the expected +behavior: +ipmitool power on: system is powered-on using Host.On +ipmitool power off: system is forced off using Chassis.Off +ipmitool power cycle: system is forced off then powered-on using + Host.Reboot +ipmitool power reset: system is hard reset using Host.ForceWarmReboot +ipmitool power soft: soft power-off requested from system software + using Host.Off + +Change-Id: Ieb42722102fde0e51a49dc4aaa3ff227a3394066 +Signed-off-by: Jason M. Bills +--- + chassishandler.cpp | 121 ++------------------------------------------- + 1 file changed, 5 insertions(+), 116 deletions(-) + +diff --git a/chassishandler.cpp b/chassishandler.cpp +index af9cba72..663081de 100644 +--- a/chassishandler.cpp ++++ b/chassishandler.cpp +@@ -1301,76 +1301,6 @@ ipmi::RspType("Failed to set property in SoftPowerOff object", +- entry("ERRNO=0x%X", -rc)); +- } +- +- // TODO openbmc/openbmc#1661 - Mapper refactor +- // free(busname); +- return rc; +-} +- +-//---------------------------------------------------------------------- +-// Create file to indicate there is no need for softoff notification to host +-//---------------------------------------------------------------------- +-void indicate_no_softoff_needed() +-{ +- fs::path path{HOST_INBAND_REQUEST_DIR}; +- if (!fs::is_directory(path)) +- { +- fs::create_directory(path); +- } +- +- // Add the host instance (default 0 for now) to the file name +- std::string file{HOST_INBAND_REQUEST_FILE}; +- auto size = std::snprintf(nullptr, 0, file.c_str(), 0); +- size++; // null +- std::unique_ptr buf(new char[size]); +- std::snprintf(buf.get(), size, file.c_str(), 0); +- +- // Append file name to directory and create it +- path /= buf.get(); +- std::ofstream(path.c_str()); +-} +- + /** @brief Implementation of chassis control command + * + * @param - chassisControl command byte +@@ -1386,60 +1316,19 @@ ipmi::RspType<> ipmiChassisControl(uint8_t chassisControl) + rc = initiateHostStateTransition(State::Host::Transition::On); + break; + case CMD_POWER_OFF: +- // This path would be hit in 2 conditions. +- // 1: When user asks for power off using ipmi chassis command 0x04 +- // 2: Host asking for power off post shutting down. +- +- // If it's a host requested power off, then need to nudge Softoff +- // application that it needs to stop the watchdog timer if running. +- // If it is a user requested power off, then this is not really +- // needed. But then we need to differentiate between user and host +- // calling this same command +- +- // For now, we are going ahead with trying to nudge the soft off and +- // interpret the failure to do so as a non softoff case +- rc = stop_soft_off_timer(); +- +- // Only request the Off transition if the soft power off +- // application is not running +- if (rc < 0) +- { +- // First create a file to indicate to the soft off application +- // that it should not run. Not doing this will result in State +- // manager doing a default soft power off when asked for power +- // off. +- indicate_no_softoff_needed(); +- +- // Now request the shutdown +- rc = initiateHostStateTransition(State::Host::Transition::Off); +- } +- else +- { +- log("Soft off is running, so let shutdown target " +- "stop the host"); +- } ++ rc = ++ initiateChassisStateTransition(State::Chassis::Transition::Off); + break; +- + case CMD_HARD_RESET: ++ rc = initiateHostStateTransition( ++ State::Host::Transition::ForceWarmReboot); ++ break; + case CMD_POWER_CYCLE: +- // SPEC has a section that says certain implementations can trigger +- // PowerOn if power is Off when a command to power cycle is +- // requested +- +- // First create a file to indicate to the soft off application +- // that it should not run since this is a direct user initiated +- // power reboot request (i.e. a reboot request that is not +- // originating via a soft power off SMS request) +- indicate_no_softoff_needed(); +- + rc = initiateHostStateTransition(State::Host::Transition::Reboot); + break; +- + case CMD_SOFT_OFF_VIA_OVER_TEMP: +- // Request Host State Manager to do a soft power off + rc = initiateHostStateTransition(State::Host::Transition::Off); + break; +- + case CMD_PULSE_DIAGNOSTIC_INTR: + rc = setNmiProperty(true); + break; +-- +2.21.0 + diff --git a/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch b/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch deleted file mode 100644 index d815cde72..000000000 --- a/meta-quanta/meta-gbs/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 9deb72959477700216326c033c930236e58f965f Mon Sep 17 00:00:00 2001 -From: Ren Yu -Date: Tue, 28 May 2019 17:11:17 +0800 -Subject: [PATCH] Save the pre-timeout interrupt in dbus property - -Get the watchdog pre-timeout interrupt value from ipmi watchdog set command, -and store it into dbus property. - -Tested: -Config IPMI watchdog: BIOS FRB2 Power Cycle after 1 seconds: -ipmitool raw 0x06 0x24 0x01 0x13 0x0 0x2 0xa 0x00 -Start watchdog: -Ipmitool mc watchdog reset -Check the watchdog pre-timeout interrupt in below: -https://BMCIP/redfish/v1/Systems/system/LogServices/EventLog/Entries - -Signed-off-by: Ren Yu - ---- - app/watchdog.cpp | 47 ++++++++++++++++++++++++++++++++++++++++ - app/watchdog_service.cpp | 6 +++++ - app/watchdog_service.hpp | 9 ++++++++ - 3 files changed, 62 insertions(+) - -diff --git a/app/watchdog.cpp b/app/watchdog.cpp -index 03c373e..cb0b1fd 100644 ---- a/app/watchdog.cpp -+++ b/app/watchdog.cpp -@@ -80,6 +80,7 @@ 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 wdPreTimeoutInterruptMask = 0x3; - - static constexpr uint8_t wdTimerUseResTimer1 = 0x0; - static constexpr uint8_t wdTimerUseResTimer2 = 0x6; -@@ -127,6 +128,45 @@ WatchdogService::Action ipmiActionToWdAction(IpmiAction ipmi_action) - } - } - -+enum class IpmiPreTimeoutInterrupt : uint8_t -+{ -+ None = 0x0, -+ SMI = 0x1, -+ NMI = 0x2, -+ MI = 0x3, -+}; -+/** @brief Converts an IPMI Watchdog PreTimeoutInterrupt to DBUS defined action -+ * @param[in] ipmi_action The IPMI Watchdog PreTimeoutInterrupt -+ * @return The Watchdog PreTimeoutInterrupt that the ipmi_action maps to -+ */ -+WatchdogService::PreTimeoutInterruptAction ipmiPreTimeoutInterruptToWdAction( -+ IpmiPreTimeoutInterrupt ipmiPreTimeOutInterrupt) -+{ -+ switch (ipmiPreTimeOutInterrupt) -+ { -+ case IpmiPreTimeoutInterrupt::None: -+ { -+ return WatchdogService::PreTimeoutInterruptAction::None; -+ } -+ case IpmiPreTimeoutInterrupt::SMI: -+ { -+ return WatchdogService::PreTimeoutInterruptAction::SMI; -+ } -+ case IpmiPreTimeoutInterrupt::NMI: -+ { -+ return WatchdogService::PreTimeoutInterruptAction::NMI; -+ } -+ case IpmiPreTimeoutInterrupt::MI: -+ { -+ return WatchdogService::PreTimeoutInterruptAction::MI; -+ } -+ default: -+ { -+ throw std::domain_error("IPMI PreTimeoutInterrupt is invalid"); -+ } -+ } -+} -+ - enum class IpmiTimerUse : uint8_t - { - Reserved = 0x0, -@@ -250,6 +290,13 @@ ipmi::RspType<> - // Mark as initialized so that future resets behave correctly - wd_service.setInitialized(true); - -+ // pretimeOutAction -+ const auto ipmiPreTimeoutInterrupt = -+ static_cast(wdPreTimeoutInterruptMask & -+ (static_cast(preTimeoutInterrupt))); -+ wd_service.setPreTimeoutInterrupt( -+ ipmiPreTimeoutInterruptToWdAction(ipmiPreTimeoutInterrupt)); -+ - lastCallSuccessful = true; - return ipmi::responseSuccess(); - } -diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp -index 3534e89..4df1ab6 100644 ---- a/app/watchdog_service.cpp -+++ b/app/watchdog_service.cpp -@@ -198,3 +198,9 @@ void WatchdogService::setInterval(uint64_t interval) - { - setProperty("Interval", interval); - } -+ -+void WatchdogService::setPreTimeoutInterrupt( -+ PreTimeoutInterruptAction preTimeoutInterrupt) -+{ -+ setProperty("PreTimeoutInterrupt", convertForMessage(preTimeoutInterrupt)); -+} -\ No newline at end of file -diff --git a/app/watchdog_service.hpp b/app/watchdog_service.hpp -index 141bdb7..32b7461 100644 ---- a/app/watchdog_service.hpp -+++ b/app/watchdog_service.hpp -@@ -15,6 +15,8 @@ class WatchdogService - - using Action = - sdbusplus::xyz::openbmc_project::State::server::Watchdog::Action; -+ using PreTimeoutInterruptAction = sdbusplus::xyz::openbmc_project::State:: -+ server::Watchdog::PreTimeoutInterruptAction; - using TimerUse = - sdbusplus::xyz::openbmc_project::State::server::Watchdog::TimerUse; - -@@ -92,6 +94,13 @@ class WatchdogService - */ - void setInterval(uint64_t interval); - -+ /** @brief Sets the value of the PreTimeoutInterrupt property on the host -+ * watchdog -+ * -+ * @param[in] PreTimeoutInterrupt - The new PreTimeoutInterrupt value -+ */ -+ void setPreTimeoutInterrupt(PreTimeoutInterruptAction preTimeoutInterrupt); -+ - private: - /** @brief sdbusplus handle */ - sdbusplus::bus::bus bus; -- cgit v1.2.3