Initial commit

This commit is contained in:
Your Name
2026-04-23 17:07:55 +08:00
commit b7e39e063b
16725 changed files with 1625565 additions and 0 deletions
@@ -0,0 +1,48 @@
From dcfe25ff7fe8874933107ff5dcfaa447722de5d1 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Thu, 26 Dec 2024 10:38:18 +0800
Subject: [PATCH] Add multiplierM offsetB bExp rExp items in
sensor_data_record.json
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
scripts/sensor_data_record_gen.py | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/scripts/sensor_data_record_gen.py b/scripts/sensor_data_record_gen.py
index 2ef58b7..fdcf691 100755
--- a/scripts/sensor_data_record_gen.py
+++ b/scripts/sensor_data_record_gen.py
@@ -12,10 +12,18 @@ def getSensorParams(sensor, sensor_params):
sensorName = sensor.get("sensorName", path[path.rfind("/") + 1 :])
sensorReadingType = sensor.get("sensorReadingType", 0)
sensorType = sensor.get("sensorType", 0)
+ multiplierM = sensor.get("multiplierM", 0)
+ offsetB = sensor.get("offsetB", 0)
+ bExp = sensor.get("bExp", 0)
+ rExp = sensor.get("rExp", 0)
sensor_params[path] = {
"sensorName": sensorName,
"sensorReadingType": sensorReadingType,
"sensorType": sensorType,
+ "multiplierM": multiplierM,
+ "offsetB": offsetB,
+ "bExp": bExp,
+ "rExp": rExp,
}
overridePaths = sensor.get("overridePaths", [])
@@ -25,6 +33,10 @@ def getSensorParams(sensor, sensor_params):
"sensorName": sensorName,
"sensorReadingType": sensorReadingType,
"sensorType": sensorType,
+ "multiplierM": multiplierM,
+ "offsetB": offsetB,
+ "bExp": bExp,
+ "rExp": rExp,
}
return sensor_params
--
2.34.1
@@ -0,0 +1,263 @@
From 57dc7fbdd1dceb8c82512dae754bf4a8370a4010 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Fri, 7 Feb 2025 14:42:30 +0800
Subject: [PATCH] Add power cycle trigger async firmware update
---
chassishandler.cpp | 216 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 216 insertions(+)
diff --git a/chassishandler.cpp b/chassishandler.cpp
index 89d3e00..8e68ac5 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -8,6 +8,7 @@
#include <mapper.h>
#include <netinet/in.h>
+#include <boost/asio.hpp>
#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
@@ -813,6 +814,196 @@ ipmi::RspType<> ipmiSetChassisCap(bool intrusion, bool fpLockout,
return ipmi::responseSuccess();
}
+//------------------------------------------------
+// Is power on (check power state before async update)
+//------------------------------------------------
+bool isPowerOn()
+{
+ std::variant<std::string> msg;
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+ try
+ {
+ auto method = bus.new_method_call("xyz.openbmc_project.State.Chassis",
+ "/xyz/openbmc_project/state/chassis0",
+ "org.freedesktop.DBus.Properties",
+ "Get");
+ method.append("xyz.openbmc_project.State.Chassis");
+ method.append("CurrentPowerState");
+ auto reply = bus.call(method);
+ reply.read(msg);
+ return std::get<std::string>(msg).find("Off") != std::string::npos
+ ? false
+ : true;
+ }
+ catch (const std::exception& /*ex*/)
+ {
+ log<level::ERR>("Can not get power status");
+ return true;
+ }
+}
+
+//------------------------------------------------
+// Async update start (return status or no value))
+//------------------------------------------------
+std::string asyncUpdateStart()
+{
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+ std::string asyncStatus{};
+ auto method = bus.new_method_call(
+ "xyz.openbmc_project.Software.AsyncUpdate",
+ "/xyz/openbmc_project/Software/AsyncUpdate",
+ "xyz.openbmc_project.Software.AsyncUpdate", "Start");
+ try
+ {
+ auto reply = bus.call(method);
+ reply.read(asyncStatus);
+ return asyncStatus;
+ }
+ catch (const sdbusplus::exception::SdBusError& /*ex*/)
+ {
+ log<level::ERR>("Error in starting async update");
+ return "";
+ }
+}
+
+//------------------------------------------------
+// Get async update status (return status or no value)
+//------------------------------------------------
+std::string asyncUpdateStatus()
+{
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+ try
+ {
+ auto status = ipmi::getDbusProperty(
+ bus, "xyz.openbmc_project.Software.AsyncUpdate",
+ "/xyz/openbmc_project/Software/AsyncUpdate",
+ "xyz.openbmc_project.Software.AsyncUpdate", "AsyncUpdateStatus");
+ return std::get<std::string>(status);
+ }
+ catch (const sdbusplus::exception::SdBusError& /*ex*/)
+ {
+ log<level::ERR>("Can not get async update status");
+ return "";
+ }
+}
+
+int initiateHostStateTransition(ipmi::Context::ptr& ctx,
+ State::Host::Transition transition);
+int initiateChassisStateTransition(ipmi::Context::ptr& ctx,
+ State::Chassis::Transition transition);
+//---------------------------------------------------------------------------
+// if power cycle wait for power on
+//---------------------------------------------------------------------------
+void waitForUpdateDone()
+{
+ static boost::asio::steady_timer timer(*getIoContext());
+ timer.expires_after(boost::asio::chrono::seconds(15));
+ timer.async_wait([&](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ return;
+ }
+ if (asyncUpdateStatus() != "Idle")
+ {
+ waitForUpdateDone();
+ return;
+ }
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+ try
+ {
+ auto method =
+ bus.new_method_call("xyz.openbmc_project.State.Host",
+ "/xyz/openbmc_project/state/host0",
+ "org.freedesktop.DBus.Properties", "Set");
+
+ method.append("xyz.openbmc_project.State.Host");
+ method.append("RequestedHostTransition");
+ method.append(std::variant<std::string>{
+ "xyz.openbmc_project.State.Host.Transition.On"});
+ bus.call_noreply(method);
+ }
+ catch (const sdbusplus::exception::SdBusError& /*ex*/)
+ {
+ log<level::ERR>("Can not power On after async update");
+ }
+ });
+}
+//---------------------------------------------------------------------------
+// wait for power off to start update
+//---------------------------------------------------------------------------
+void waitForStartUpdate(bool doPowerOn)
+{
+ static boost::asio::steady_timer timer(*getIoContext());
+ timer.expires_after(boost::asio::chrono::seconds(15));
+ timer.async_wait(
+ [doPowerOn](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ return;
+ }
+ if (isPowerOn()) // power status is not "off"
+ {
+ waitForStartUpdate(doPowerOn);
+ return;
+ }
+ try
+ {
+ asyncUpdateStart();
+ if (doPowerOn)
+ {
+ waitForUpdateDone();
+ }
+ }
+ catch (const sdbusplus::exception::SdBusError& /*ex*/)
+ {
+ log<level::ERR>("Can not start update");
+ }
+ });
+}
+
+enum class PowerControlAsyncStatus
+{
+ active,
+ running,
+ idle
+};
+
+//---------------------------------------------------------------------------
+// hook host power control to trigger async update
+// return true if async-update is not in progress
+//---------------------------------------------------------------------------
+PowerControlAsyncStatus
+ processPowerControlHost(ipmi::Context::ptr& ctx,
+ State::Host::Transition transition)
+{
+ std::string asyncStatus = asyncUpdateStatus();
+ auto doPowerOn = isPowerOn();
+ switch (transition)
+ {
+ case State::Host::Transition::Reboot:
+ if (asyncStatus == "Waiting")
+ {
+ initiateChassisStateTransition(ctx,
+ State::Chassis::Transition::Off);
+ waitForStartUpdate(doPowerOn);
+ return PowerControlAsyncStatus::active;
+ }
+ else if (asyncStatus == "Running")
+ {
+ return PowerControlAsyncStatus::running;
+ }
+ break;
+ case State::Host::Transition::On:
+ if (asyncStatus == "Running")
+ {
+ return PowerControlAsyncStatus::running;
+ }
+ break;
+ default:
+ break;
+ }
+ return PowerControlAsyncStatus::idle;
+}
//------------------------------------------
// Calls into Host State Manager Dbus object
//------------------------------------------
@@ -1363,9 +1554,18 @@ ipmi::RspType<> ipmiChassisControl(ipmi::Context::ptr& ctx,
uint8_t chassisControl)
{
int rc = 0;
+ PowerControlAsyncStatus asyncUpdateStatus = PowerControlAsyncStatus::idle;
switch (chassisControl)
{
case CMD_POWER_ON:
+ asyncUpdateStatus =
+ processPowerControlHost(ctx, State::Host::Transition::On);
+ if (asyncUpdateStatus != PowerControlAsyncStatus::idle)
+ {
+ log<level::ERR>(
+ "Power-on opertion is not allowed during the upgrade process");
+ return ipmi::responseCommandNotAvailable();
+ }
rc = initiateHostStateTransition(ctx, State::Host::Transition::On);
break;
case CMD_POWER_OFF:
@@ -1377,6 +1577,22 @@ ipmi::RspType<> ipmiChassisControl(ipmi::Context::ptr& ctx,
ctx, State::Host::Transition::ForceWarmReboot);
break;
case CMD_POWER_CYCLE:
+ asyncUpdateStatus =
+ processPowerControlHost(ctx, State::Host::Transition::Reboot);
+ if (asyncUpdateStatus == PowerControlAsyncStatus::active)
+ {
+ log<level::INFO>(
+ "Power-cycle operation will activate the async-update, let the async-update flow to do the power-cycle");
+ rc = ipmi::ccSuccess;
+ break;
+ }
+ else if (asyncUpdateStatus == PowerControlAsyncStatus::running)
+ {
+ log<level::INFO>(
+ "Power-cycle operation is not allowed during the upgrade");
+ rc = ipmi::ccCommandNotAvailable;
+ break;
+ }
rc = initiateHostStateTransition(ctx,
State::Host::Transition::Reboot);
break;
--
2.25.1
@@ -0,0 +1,31 @@
From a16e5220657aeca72ad01c2408fefed38fa3c256 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Fri, 13 Dec 2024 11:07:55 +0800
Subject: [PATCH] Fix incorrect thresholdLevelsStates response for Get Sensor
Reading command
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
sensordatahandler.hpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp
index 6c3a8e5..2867cd5 100644
--- a/sensordatahandler.hpp
+++ b/sensordatahandler.hpp
@@ -327,9 +327,9 @@ GetSensorResponse readingData(const Info& sensorInfo)
warningAlarmLow = false;
}
response.thresholdLevelsStates =
- (static_cast<uint8_t>(critAlarmHigh) << 3) |
- (static_cast<uint8_t>(critAlarmLow) << 2) |
- (static_cast<uint8_t>(warningAlarmHigh) << 1) |
+ (static_cast<uint8_t>(critAlarmHigh) << 4) |
+ (static_cast<uint8_t>(warningAlarmHigh) << 3) |
+ (static_cast<uint8_t>(critAlarmLow) << 1) |
(static_cast<uint8_t>(warningAlarmLow));
return response;
--
2.34.1
@@ -0,0 +1,160 @@
From 3079d7621187cb966f19726f2f31fb03f0080eed Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Wed, 11 Dec 2024 17:08:44 +0800
Subject: [PATCH] add sensor config file
---
scripts/meson.build | 19 +++++-
scripts/sensor_data_record_gen.py | 104 ++++++++++++++++++++++++++++++
2 files changed, 120 insertions(+), 3 deletions(-)
create mode 100755 scripts/sensor_data_record_gen.py
diff --git a/scripts/meson.build b/scripts/meson.build
index b739e6f..ae5358c 100644
--- a/scripts/meson.build
+++ b/scripts/meson.build
@@ -3,11 +3,11 @@ python_exe = find_program('python3', 'python')
sensor_gen = custom_target('sensor-gen',
output: 'sensor-gen.cpp',
- input: [ 'sensor_gen.py', get_option('sensor-yaml-gen')],
+ input: files(get_option('sensor-yaml-gen')),
command: [
python_exe,
- '@INPUT0@',
- '-i', '@INPUT1@',
+ files('sensor_gen.py'),
+ '-i', '@INPUT@',
'-o', meson.current_build_dir(),
'generate-cpp',
],
@@ -39,3 +39,16 @@ fru_gen = custom_target('fru-gen',
],
)
generated_src += fru_gen
+
+sensor_data_gen = custom_target('sensor-json-gen',
+ output: 'sensor-data-record.json',
+ input: files(get_option('sensor-yaml-gen')),
+ command: [
+ files('sensor_data_record_gen.py'),
+ '-i', '@INPUT@',
+ '-o', meson.current_build_dir(),
+ ],
+ install: true,
+ install_dir: get_option('datadir') / 'ipmi-providers',
+)
+generated_src += sensor_data_gen
diff --git a/scripts/sensor_data_record_gen.py b/scripts/sensor_data_record_gen.py
new file mode 100755
index 0000000..2ef58b7
--- /dev/null
+++ b/scripts/sensor_data_record_gen.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python3
+
+import argparse
+import json
+import os
+
+import yaml
+
+
+def getSensorParams(sensor, sensor_params):
+ path = sensor["path"]
+ sensorName = sensor.get("sensorName", path[path.rfind("/") + 1 :])
+ sensorReadingType = sensor.get("sensorReadingType", 0)
+ sensorType = sensor.get("sensorType", 0)
+ sensor_params[path] = {
+ "sensorName": sensorName,
+ "sensorReadingType": sensorReadingType,
+ "sensorType": sensorType,
+ }
+
+ overridePaths = sensor.get("overridePaths", [])
+ for item in overridePaths:
+ sensorName = item[item.rfind("/") + 1 :]
+ sensor_params[item] = {
+ "sensorName": sensorName,
+ "sensorReadingType": sensorReadingType,
+ "sensorType": sensorType,
+ }
+ return sensor_params
+
+
+def main():
+ app_description = "Convert sensor yaml to json."
+
+ parser = argparse.ArgumentParser(
+ description=app_description,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "-i",
+ "--sensor_yaml",
+ dest="sensor_yaml",
+ nargs="*",
+ type=str,
+ default=[],
+ help="input sensor yaml file list to parse",
+ )
+ parser.add_argument(
+ "-o",
+ "--output-dir",
+ dest="outputdir",
+ help="The directory of json file",
+ )
+ parser.add_argument(
+ "-f",
+ "--override-flag",
+ dest="override",
+ default="",
+ help="override flag",
+ )
+ args = parser.parse_args()
+
+ if not args.override and len(args.sensor_yaml) > 1:
+ raise RuntimeError(
+ "Not support multi machine, but there are multi sensor yamls"
+ )
+ total_sensor_params = {}
+
+ for yaml_file in args.sensor_yaml:
+ with open(yaml_file, "r") as y:
+ sensors = yaml.safe_load(y)
+ sensors = [i for i in sensors.values()]
+ sensor_params = {}
+ for s in sensors:
+ sensor_params = getSensorParams(s, sensor_params)
+ for sensor_param in sensor_params:
+ # if the sensor is already in the total_sensor_params, check the value is must same
+ if sensor_param in total_sensor_params:
+ if (
+ total_sensor_params[sensor_param]
+ != sensor_params[sensor_param]
+ ):
+ raise RuntimeError(
+ "The sensor is already in the total_sensor_params, but the value is different"
+ )
+ else:
+ total_sensor_params[sensor_param] = sensor_params[
+ sensor_param
+ ]
+ output_json = os.path.join(args.outputdir, "sensor-data-record.json")
+ with open(output_json, "w") as j:
+ j.write(
+ json.dumps(
+ total_sensor_params,
+ indent=4,
+ sort_keys=True,
+ separators=(",", ": "),
+ )
+ )
+ j.write("\n")
+
+
+if __name__ == "__main__":
+ main()
--
2.25.1
@@ -0,0 +1,93 @@
From fdcfa9e7ff6eb31fe77cd4032d202bb8f1a50f37 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Thu, 21 Nov 2024 18:23:00 +0800
Subject: [PATCH] ipmi cmd support set sel time utc offset
---
storagehandler.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/storagehandler.cpp b/storagehandler.cpp
index 4fef019..67d76ea 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -696,6 +696,63 @@ ipmi::RspType<int16_t> ipmiStorageGetSelTimeUtcOffset()
return ipmi::responseSuccess(timeEquation);
}
+/** @brief implements the Set SEL timezone command
+ * @returns IPMI completion code plus response data
+ * -current timezone
+ */
+ipmi::RspType<> ipmiStorageSetSelTimeUtcOffset(int16_t UTCOffset)
+{
+ int hrs = 0;
+ char ZoneInfoFile[128] = {0}, file[32] = {0};
+ static constexpr int16_t SEL_UTC_MAX_RANGE = 1440;
+ static constexpr int16_t SEL_UTC_MIN_RANGE = -1440;
+ static constexpr int16_t UNSPECIFIED_UTC_OFFSET = 0x7ff;
+ constexpr auto LOCALTIME = "/etc/localtime";
+
+ if (((UTCOffset > SEL_UTC_MAX_RANGE ) || (UTCOffset < SEL_UTC_MIN_RANGE) || (UTCOffset % 60 != 0)) && UTCOffset != UNSPECIFIED_UTC_OFFSET)
+ {
+ return ipmi::responseParmOutOfRange();
+ }
+
+ hrs = UTCOffset / 60;
+ if(UTCOffset == UNSPECIFIED_UTC_OFFSET)
+ {
+ hrs = 0;
+ }
+
+ if (0 > UTCOffset)
+ {
+ if (snprintf(file,sizeof(file), "GMT+%d", -hrs) >= (long int)sizeof(file))
+ {
+ return ipmi::responseUnspecifiedError();
+ }
+ }
+ else
+ {
+ if (snprintf(file,sizeof(file), "GMT-%d", hrs) >= (long int)sizeof(file))
+ {
+ return ipmi::responseUnspecifiedError();
+ }
+ }
+
+ if (snprintf (ZoneInfoFile, sizeof(ZoneInfoFile), "%s/%s", "/usr/share/zoneinfo/Etc", file) >= (long int)sizeof(ZoneInfoFile))
+ {
+ return ipmi::responseUnspecifiedError();
+ }
+
+ if((0 > unlink(LOCALTIME)) && errno != ENOENT)
+ {
+ return ipmi::responseUnspecifiedError();
+ }
+
+ if(symlink(ZoneInfoFile, LOCALTIME) < 0)
+ {
+ return ipmi::responseUnspecifiedError();
+ }
+
+ return ipmi::responseSuccess();
+}
+
/** @brief implements the reserve SEL command
* @returns IPMI completion code plus response data
* - SEL reservation ID.
@@ -952,6 +1009,12 @@ void register_netfn_storage_functions()
ipmi::Privilege::User,
ipmiStorageGetSelTimeUtcOffset);
+ // <Set SEL Timezone>
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+ ipmi::storage::cmdSetSelTimeUtcOffset,
+ ipmi::Privilege::Operator,
+ ipmiStorageSetSelTimeUtcOffset);
+
// <Get SEL Entry>
ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SEL_ENTRY, NULL,
getSELEntry, PRIVILEGE_USER);
--
2.25.1
@@ -0,0 +1,141 @@
From cfb5e13388531e1317eeb3ccf0f8eef0c6eeca60 Mon Sep 17 00:00:00 2001
From: Ren Yu <yux.ren@intel.com>
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 <yux.ren@intel.com>
Upstream-Status: Pending
---
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<IpmiPreTimeoutInterrupt>(wdPreTimeoutInterruptMask &
+ (static_cast<uint8_t>(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_t bus;
--
2.17.1
@@ -0,0 +1,21 @@
[Unit]
Description=Phosphor Inband IPMI
Wants=clear-once.service
Wants=xyz.openbmc_project.Settings.service
After=xyz.openbmc_project.Settings.service
After=clear-once.service
After=org.openbmc.HostIpmi.service
[Service]
Restart=always
ExecStart=/usr/bin/env ipmid
SyslogIdentifier=ipmid
RuntimeDirectory = ipmi
RuntimeDirectoryPreserve = yes
StateDirectory = ipmi
Type=dbus
BusName=xyz.openbmc_project.Control.Host
[Install]
WantedBy=basic.target
Alias=xyz.openbmc_project.Control.Host.service
@@ -0,0 +1,3 @@
[Unit]
Wants=mapper-wait@-xyz-openbmc_project-inventory-system-board-Lux_Baseboard-BMC_Boot.service
After=mapper-wait@-xyz-openbmc_project-inventory-system-board-Lux_Baseboard-BMC_Boot.service