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,37 @@
From ca1ba3ae07328386bc2ef188859e60af400e1e83 Mon Sep 17 00:00:00 2001
From: Anuj Agrawal <anuj.agrawal@intel.com>
Date: Thu, 23 Jun 2022 07:40:08 +0000
Subject: [PATCH] Post Complete Signal Handling
1.PostComplete Signal handling is changed from GPIO-based to Dbus-based.
2. Removed the WorkAround patch.
Tested: Tested on AVC, Property is changing as expected.
Signed-off-by: Anuj Agrawal <anuj.agrawal@intel.com>
Upstream-Status: Pending
---
config/power-config-host0.json | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/config/power-config-host0.json b/config/power-config-host0.json
index 3224457..b655692 100644
--- a/config/power-config-host0.json
+++ b/config/power-config-host0.json
@@ -21,8 +21,11 @@
{
"Name": "PostComplete",
"LineName": "POST_COMPLETE",
- "Type": "GPIO",
- "Polarity": "ActiveLow"
+ "Type" : "DBUS",
+ "DbusName" : "xyz.openbmc_project.Host.Misc.Manager",
+ "Path" : "/xyz/openbmc_project/misc/platform_state",
+ "Interface" : "xyz.openbmc_project.State.Host.Misc",
+ "Property" : "PostComplete"
},
{
"Name": "PowerButton",
--
2.17.1
@@ -0,0 +1,62 @@
From 1a69465a1b75db75087fd9d060109284feafe190 Mon Sep 17 00:00:00 2001
From: Nikhil Jain C S <nikhil.jain.c.s@intel.com>
Date: Fri, 24 Jun 2022 16:54:25 +0530
Subject: [PATCH] Polarity Issue
Reversing the polarity on D-Bus
Tested on AVC.
Power is off -> OSStatus Inactive
Power is On -> OSStatus Standby
Signed-off-by: Nikhil Jain C S <nikhil.jain.c.s@intel.com>
Upstream-Status: Pending
---
src/power_control.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/power_control.cpp b/src/power_control.cpp
index bc30b71..cfd0eb0 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -2276,12 +2276,12 @@ static void postCompleteHandler(bool state)
if (!state)
{
sendPowerControlEvent(Event::postCompleteAssert);
- setOperatingSystemState(OperatingSystemStateStage::Standby);
+ setOperatingSystemState(OperatingSystemStateStage::Inactive);
}
else
{
sendPowerControlEvent(Event::postCompleteDeAssert);
- setOperatingSystemState(OperatingSystemStateStage::Inactive);
+ setOperatingSystemState(OperatingSystemStateStage::Standby);
}
}
@@ -2565,8 +2565,8 @@ void setInitialValue(const ConfigData& configData, bool initialValue)
else if (configData.name == "PostComplete")
{
OperatingSystemStateStage osState =
- (initialValue ? OperatingSystemStateStage::Inactive
- : OperatingSystemStateStage::Standby);
+ (initialValue ? OperatingSystemStateStage::Standby
+ : OperatingSystemStateStage::Inactive);
setOperatingSystemState(osState);
}
else
@@ -3412,8 +3412,8 @@ int main(int argc, char* argv[])
else
{
osState = getProperty(postCompleteConfig) > 0
- ? OperatingSystemStateStage::Inactive
- : OperatingSystemStateStage::Standby;
+ ? OperatingSystemStateStage::Standby
+ : OperatingSystemStateStage::Inactive;
}
osIface->register_property(
--
2.25.1
@@ -0,0 +1,27 @@
From 52afd4c45be3a724976093e3a63c71731b4c68fd Mon Sep 17 00:00:00 2001
From: Jan Sowinski <jan.sowinski@intel.com>
Date: Wed, 9 Nov 2022 11:54:34 +0100
Subject: [PATCH] Update NMIOut LineName to match DTS
Signed-off-by: Jan Sowinski <jan.sowinski@intel.com>
Upstream-Status: Pending
---
config/power-config-host0.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/power-config-host0.json b/config/power-config-host0.json
index b655692..9341d90 100644
--- a/config/power-config-host0.json
+++ b/config/power-config-host0.json
@@ -14,7 +14,7 @@
},
{
"Name": "NMIOut",
- "LineName": "NMI_OUT",
+ "LineName": "IRQ_BMC_CPU_NMI_P0",
"Type": "GPIO",
"Polarity": "ActiveHigh"
},
--
2.17.1
@@ -0,0 +1,91 @@
From 0d413f596ebcb180b629c73adcc11acd1e58d003 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Thu, 22 Aug 2024 11:28:40 +0800
Subject: [PATCH] Remove the GPIO configuration for unused pins
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
config/power-config-host0.json | 42 ----------------------------------
src/power_control.cpp | 6 +----
2 files changed, 1 insertion(+), 47 deletions(-)
diff --git a/config/power-config-host0.json b/config/power-config-host0.json
index 9b39d57..5a68242 100644
--- a/config/power-config-host0.json
+++ b/config/power-config-host0.json
@@ -6,18 +6,6 @@
"Type": "GPIO",
"Polarity": "ActiveLow"
},
- {
- "Name": "NMIButton",
- "LineName": "NMI_BUTTON",
- "Type": "GPIO",
- "Polarity": "ActiveLow"
- },
- {
- "Name": "NMIOut",
- "LineName": "IRQ_BMC_CPU_NMI_P0",
- "Type": "GPIO",
- "Polarity": "ActiveHigh"
- },
{
"Name": "PostComplete",
"LineName": "POST_COMPLETE",
@@ -44,36 +32,6 @@
"LineName": "POWER_OUT",
"Type": "GPIO",
"Polarity": "ActiveLow"
- },
- {
- "Name": "ResetButton",
- "LineName": "RESET_BUTTON",
- "Type": "GPIO",
- "Polarity": "ActiveLow"
- },
- {
- "Name": "ResetOut",
- "LineName": "RESET_OUT",
- "Type": "GPIO",
- "Polarity": "ActiveLow"
- },
- {
- "Name": "SioOnControl",
- "LineName": "SIO_ONCONTROL",
- "Type": "GPIO",
- "Polarity": "ActiveLow"
- },
- {
- "Name": "SioPowerGood",
- "LineName": "SIO_POWER_GOOD",
- "Type": "GPIO",
- "Polarity": "ActiveHigh"
- },
- {
- "Name": "SIOS5",
- "LineName": "SIO_S5",
- "Type": "GPIO",
- "Polarity": "ActiveLow"
}
],
"timing_configs": {
diff --git a/src/power_control.cpp b/src/power_control.cpp
index cfd0eb0..7a47957 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -2886,11 +2886,7 @@ int main(int argc, char* argv[])
return -1;
}
}
- else
- {
- lg2::error("ResetOut name should be configured from json config file");
- return -1;
- }
+
// Release line
line.reset();
--
2.34.1
@@ -0,0 +1,164 @@
From fa312c462de18b25a67f08c8f7be51f9fbdc4df5 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Thu, 19 Sep 2024 15:11:18 +0800
Subject: [PATCH] Implement power reset control
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/power_control.cpp | 128 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 126 insertions(+), 2 deletions(-)
diff --git a/src/power_control.cpp b/src/power_control.cpp
index 7a47957..586d1e3 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -27,10 +27,18 @@
#include <nlohmann/json.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/asio/object_server.hpp>
-
#include <filesystem>
#include <fstream>
#include <string_view>
+#include <thread>
+#include <chrono>
+#include <iostream>
+
+extern "C"
+{
+#include <i2c/smbus.h>
+#include <linux/i2c-dev.h>
+}
namespace power_control
{
@@ -1408,9 +1416,125 @@ static void forcePowerOff()
});
}
+int i2cWriteRead(std::string& i2cDev, const uint8_t slaveAddr,
+ std::vector<uint8_t> writeData,
+ std::vector<uint8_t>& readBuf)
+{
+ int fd = open(i2cDev.c_str(), O_RDWR | O_CLOEXEC);
+ if (fd < 0)
+ {
+ lg2::error("unable to open i2c device");
+ return -1;
+ }
+
+ const size_t writeCount = writeData.size();
+ const size_t readCount = readBuf.size();
+
+ int msgCount = 0;
+ struct i2c_msg i2cmsg[2];
+
+ memset(i2cmsg, 0, sizeof(i2cmsg));
+
+ if (writeCount)
+ {
+ // Data will be writtern to the slave address
+ i2cmsg[msgCount].addr = slaveAddr;
+ i2cmsg[msgCount].flags = 0x00;
+ i2cmsg[msgCount].len = writeCount;
+ i2cmsg[msgCount].buf = writeData.data();
+ msgCount++;
+ }
+
+ if (readCount)
+ {
+ // Data will be read into the buffer from the slave address
+ i2cmsg[msgCount].addr = slaveAddr;
+ i2cmsg[msgCount].flags = I2C_M_RD;
+ i2cmsg[msgCount].len = readCount;
+ i2cmsg[msgCount].buf = readBuf.data();
+ msgCount++;
+ }
+
+ struct i2c_rdwr_ioctl_data msgReadWrite;
+ memset((void*)&msgReadWrite, 0, sizeof(msgReadWrite));
+ msgReadWrite.msgs = i2cmsg;
+ msgReadWrite.nmsgs = msgCount;
+
+ int ret = ioctl(fd, I2C_RDWR, &msgReadWrite);
+ close(fd);
+ if (ret < 0)
+ {
+ lg2::error("I2C Read Write Failed.");
+ return -1;
+ }
+
+ if (readCount)
+ {
+ readBuf.resize(msgReadWrite.msgs[msgCount - 1].len);
+ }
+
+ return 0;
+}
+
+#define BIT2 (1 << 2)
+void luxResetChassis()
+{
+ int ret = 0;
+ std::string i2cDev = "/dev/i2c-0";
+ // Perform the combined write/read
+
+ std::vector<uint8_t> readBuf(1);
+ std::vector<uint8_t> writeData = {0x30, 0x01};
+ const uint8_t slaveAddr = 0x0D;
+ uint8_t regVal, tmp;
+
+ ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf);
+ if (ret < 0)
+ {
+ lg2::error("i2c failed to read regVal.");
+ goto err;
+ }
+
+ regVal = readBuf[0];
+ readBuf.resize(0);
+ tmp = regVal & (~BIT2);
+ writeData.push_back(tmp);
+
+ ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf);
+ if (ret < 0)
+ {
+ lg2::error("i2c WriteRead failed.");
+ goto err;
+ }
+
+ writeData.pop_back();
+ tmp = regVal | BIT2;
+ writeData.push_back(tmp);
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(400));
+
+ ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf);
+ if (ret < 0)
+ {
+ lg2::error("i2c WriteRead failed.");
+ goto err;
+ }
+
+ lg2::error("Success to reset Host.");
+ return;
+err:
+ lg2::error("Fail to reset Host.");
+ return;
+}
+
static void reset()
{
- assertGPIOForMs(resetOutConfig, TimerMap["ResetPulseMs"]);
+ if (!resetOutConfig.lineName.empty())
+ assertGPIOForMs(resetOutConfig, TimerMap["ResetPulseMs"]);
+ else {
+ std::thread myThread(luxResetChassis);
+ myThread.join();
+ }
}
static void gracefulPowerOffTimerStart()
--
2.34.1
@@ -0,0 +1,95 @@
diff --git a/src/power_control.cpp b/src/power_control.cpp
index 586d1e3..b671b23 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -558,6 +558,58 @@ static constexpr std::string_view getChassisState(const PowerState state)
break;
}
};
+
+static void powerStateLog(const PowerState state)
+{
+ constexpr const char* selService = "xyz.openbmc_project.Logging.IPMI";
+ constexpr const char* selPath = "/xyz/openbmc_project/Logging/IPMI";
+ constexpr const char* selInterface = "xyz.openbmc_project.Logging.IPMI";
+ constexpr const char* selMethod = "IpmiSelAdd";
+ constexpr const char* sensorPath =
+ "/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/ACPI_State";
+
+ auto bus = sdbusplus::bus::new_default();
+ std::string stateStr = std::string(getChassisState(state));
+
+ auto method =
+ bus.new_method_call(selService, selPath, selInterface, selMethod);
+
+ method.append("SEL Entry");
+ method.append(sensorPath);
+
+ if (stateStr == "xyz.openbmc_project.State.Chassis.PowerState.On")
+ {
+ std::cerr << "Send Power State On SEL Log\n";
+ method.append(
+ std::array<uint8_t, 3>({0x00, 0xFF, 0xFF})); // S0/G0: working
+ }
+ else if (stateStr == "xyz.openbmc_project.State.Chassis.PowerState.Off")
+ {
+ std::cerr << "Send Power State Off SEL Log\n";
+ method.append(
+ std::array<uint8_t, 3>({0x06, 0xFF, 0xFF})); // S4/S5: soft-off
+ }
+ else
+ {
+ std::cerr << "Send Power State SEL Log Error\n";
+ return;
+ }
+
+ method.append(true); // assert is true and deassert is false
+ method.append(uint16_t(0x0020)); // generator ID
+ try
+ {
+ bus.call_noreply(method);
+ }
+ catch (const sdbusplus::exception::SdBusError& ex)
+ {
+ lg2::error(
+ "Failed to call sel log {SELPATH}, {SELINTERFACE}, {SELMRTHOD}",
+ "SELPATH", selPath, "SELINTERFACE", selInterface, "SELMRTHOD",
+ selMethod);
+ }
+}
+
#ifdef CHASSIS_SYSTEM_RESET
enum class SlotPowerState
{
@@ -1890,6 +1942,7 @@ static void powerStateWaitForPSPowerOK(const Event event)
else
{
setPowerState(PowerState::on);
+ powerStateLog(PowerState::on);
}
break;
}
@@ -1941,6 +1994,7 @@ static void powerStateOff(const Event event)
else
{
setPowerState(PowerState::on);
+ powerStateLog(PowerState::on);
}
break;
}
@@ -1975,6 +2029,7 @@ static void powerStateTransitionToOff(const Event event)
// Cancel any GPIO assertions held during the transition
gpioAssertTimer.cancel();
setPowerState(PowerState::off);
+ powerStateLog(PowerState::off);
break;
default:
lg2::info("No action taken.");
@@ -2064,6 +2119,7 @@ static void powerStateTransitionToCycleOff(const Event event)
// Cancel any GPIO assertions held during the transition
gpioAssertTimer.cancel();
setPowerState(PowerState::cycleOff);
+ powerStateLog(PowerState::cycleOff);
powerCycleTimerStart();
break;
default:
@@ -0,0 +1,91 @@
From 5a8896cc3a8e02e3d09be450a0c7fcc5a5266b55 Mon Sep 17 00:00:00 2001
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
Date: Wed, 23 Oct 2024 13:34:12 +0800
Subject: [PATCH 7/7] Add power button sensor
---
src/power_control.cpp | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/src/power_control.cpp b/src/power_control.cpp
index b671b23..fbc9605 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -277,6 +277,7 @@ enum class PowerState
transitionToCycleOff,
gracefulTransitionToCycleOff,
checkForWarmReset,
+ powerButtonPressed,
};
static PowerState powerState;
static std::string getPowerStateName(PowerState state)
@@ -553,6 +554,9 @@ static constexpr std::string_view getChassisState(const PowerState state)
case PowerState::cycleOff:
return "xyz.openbmc_project.State.Chassis.PowerState.Off";
break;
+ case PowerState::powerButtonPressed:
+ return "ButtonPressed";
+ break;
default:
return "";
break;
@@ -565,7 +569,7 @@ static void powerStateLog(const PowerState state)
constexpr const char* selPath = "/xyz/openbmc_project/Logging/IPMI";
constexpr const char* selInterface = "xyz.openbmc_project.Logging.IPMI";
constexpr const char* selMethod = "IpmiSelAdd";
- constexpr const char* sensorPath =
+ std::string sensorPath =
"/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/ACPI_State";
auto bus = sdbusplus::bus::new_default();
@@ -574,21 +578,30 @@ static void powerStateLog(const PowerState state)
auto method =
bus.new_method_call(selService, selPath, selInterface, selMethod);
- method.append("SEL Entry");
- method.append(sensorPath);
+ method.append("SEL Entry");
if (stateStr == "xyz.openbmc_project.State.Chassis.PowerState.On")
{
std::cerr << "Send Power State On SEL Log\n";
+ method.append(sensorPath.c_str());
method.append(
std::array<uint8_t, 3>({0x00, 0xFF, 0xFF})); // S0/G0: working
}
else if (stateStr == "xyz.openbmc_project.State.Chassis.PowerState.Off")
{
std::cerr << "Send Power State Off SEL Log\n";
+ method.append(sensorPath.c_str());
method.append(
std::array<uint8_t, 3>({0x06, 0xFF, 0xFF})); // S4/S5: soft-off
}
+ else if (stateStr == "ButtonPressed")
+ {
+ std::cerr << "Send Power State Button Pressed SEL Log\n";
+ sensorPath = "/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/Power_Button";
+ method.append(sensorPath.c_str());
+ method.append(
+ std::array<uint8_t, 3>({0x00, 0xFF, 0xFF})); // power button pressed
+ }
else
{
std::cerr << "Send Power State SEL Log Error\n";
@@ -826,9 +839,11 @@ static void powerRestorePolicyLog()
static void powerButtonPressLog()
{
- sd_journal_send("MESSAGE=PowerControl: power button pressed", "PRIORITY=%i",
- LOG_INFO, "REDFISH_MESSAGE_ID=%s",
- "OpenBMC.0.1.PowerButtonPressed", NULL);
+ // sd_journal_send("MESSAGE=PowerControl: power button pressed", "PRIORITY=%i",
+ // LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+ // "OpenBMC.0.1.PowerButtonPressed", NULL);
+ powerStateLog(PowerState::powerButtonPressed);
+
}
static void resetButtonPressLog()
--
2.25.1
@@ -0,0 +1,90 @@
From fd9fd44b8adda86cc292943fbb477293b321f390 Mon Sep 17 00:00:00 2001
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
Date: Tue, 5 Nov 2024 19:15:22 +0800
Subject: [PATCH 8/8] Add ACPI_State event monitoring Test ACPI_State |
FBh | ok | 7.70 | S4/S5: soft-off 3 | 04/03/23 | 20:59:16 UTC | System
ACPI Power State ACPI_State | S4/S5: soft-off | Asserted ipmitool power on
reboot ACPI_State | FBh | ok | 7.70 | S0/G0: working 5 | 04/03/23 |
21:03:14 UTC | System ACPI Power State ACPI_State | S0/G0: working | Asserted
---
...bmc_project.Chassis.Control.Power@.service | 4 ++-
src/power_control.cpp | 26 +++++++++++++++++++
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/service_files/xyz.openbmc_project.Chassis.Control.Power@.service b/service_files/xyz.openbmc_project.Chassis.Control.Power@.service
index 4d676c2..03a1782 100644
--- a/service_files/xyz.openbmc_project.Chassis.Control.Power@.service
+++ b/service_files/xyz.openbmc_project.Chassis.Control.Power@.service
@@ -1,6 +1,8 @@
[Unit]
Description=Intel Power Control for the Host %i
ConditionPathExists=/usr/share/x86-power-control/power-config-host%i.json
+Wants=obmc-fru-fault-monitor.service
+After=obmc-fru-fault-monitor.service
[Service]
Restart=always
@@ -10,4 +12,4 @@ Type=dbus
BusName=xyz.openbmc_project.State.Host%i
[Install]
-WantedBy=sysinit.target
+WantedBy=sysinit.target
\ No newline at end of file
diff --git a/src/power_control.cpp b/src/power_control.cpp
index fbc9605..bfb55ef 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -177,6 +177,8 @@ static boost::asio::steady_timer pohCounterTimer(io);
// Time when to allow restart cause updates
static boost::asio::steady_timer restartCauseTimer(io);
static boost::asio::steady_timer slotPowerCycleTimer(io);
+// SEL timer
+static boost::asio::steady_timer selTimer(io);
// Map containing timers used for D-Bus get-property retries
static boost::container::flat_map<std::string, boost::asio::steady_timer>
@@ -2810,8 +2812,31 @@ void reschedulePropertyRead(const ConfigData& configData)
}
});
}
+
+static void ACPIStateSel(void)
+{
+ const static constexpr int TimeMs = 20000;
+ selTimer.expires_after(std::chrono::milliseconds(TimeMs));
+ selTimer.async_wait([](const boost::system::error_code ec) {
+ if (ec)
+ {
+ // operation_aborted is expected if timer is canceled before
+ // completion.
+ if (ec != boost::asio::error::operation_aborted)
+ {
+ lg2::info("ACPI State timer error: {ERROR}", "ERROR",
+ ec.message());
+ }
+ }
+ lg2::info("ACPI State sel");
+ powerStateLog(powerState);
+ });
+
+}
+
} // namespace power_control
+
int main(int argc, char* argv[])
{
using namespace power_control;
@@ -3106,6 +3131,7 @@ int main(int argc, char* argv[])
powerState = PowerState::on;
}
}
+ ACPIStateSel();
// Check if we need to start the Power Restore policy
if (powerState != PowerState::on)
{
--
2.25.1
@@ -0,0 +1,80 @@
From c30e74c4dc90960f935401fe403c833eac3bb7fd Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Wed, 6 Nov 2024 15:18:08 +0800
Subject: [PATCH] Control uidLed in uid button handler
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/power_control.cpp | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/src/power_control.cpp b/src/power_control.cpp
index bfb55ef..8d462be 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -118,6 +118,13 @@ static std::string buttonDbusName = "xyz.openbmc_project.Chassis.Buttons";
static std::string nmiDbusName = "xyz.openbmc_project.Control.Host.NMI";
static std::string rstCauseDbusName =
"xyz.openbmc_project.Control.Host.RestartCause";
+constexpr const char* uidLedPath = "/xyz/openbmc_project/led/groups/uid_btn";
+constexpr const char* ledIface = "xyz.openbmc_project.Led.Group";
+constexpr const char* ledAssertProp = "Asserted";
+constexpr const char* ledManagerBusname =
+ "xyz.openbmc_project.LED.GroupManager";
+static bool uidLastState = false;
+
static std::shared_ptr<sdbusplus::asio::dbus_interface> hostIface;
static std::shared_ptr<sdbusplus::asio::dbus_interface> chassisIface;
#ifdef CHASSIS_SYSTEM_RESET
@@ -580,7 +587,7 @@ static void powerStateLog(const PowerState state)
auto method =
bus.new_method_call(selService, selPath, selInterface, selMethod);
- method.append("SEL Entry");
+ method.append("SEL Entry");
if (stateStr == "xyz.openbmc_project.State.Chassis.PowerState.On")
{
@@ -845,7 +852,7 @@ static void powerButtonPressLog()
// LOG_INFO, "REDFISH_MESSAGE_ID=%s",
// "OpenBMC.0.1.PowerButtonPressed", NULL);
powerStateLog(PowerState::powerButtonPressed);
-
+
}
static void resetButtonPressLog()
@@ -2416,9 +2423,30 @@ static void nmiButtonHandler(bool state)
}
}
+static void setUidLed()
+{
+ conn->async_method_call(
+ [&uidLastState](const boost::system::error_code ec) {
+ if (ec)
+ {
+ std::cerr << "Cannot set uidLed to "
+ << std::boolalpha
+ << !uidLastState << "\n";
+ }
+
+ uidLastState = !uidLastState;
+ },
+ ledManagerBusname, uidLedPath,
+ "org.freedesktop.DBus.Properties", "Set", ledIface,
+ ledAssertProp, std::variant<bool>(!uidLastState));
+}
+
static void idButtonHandler(bool state)
{
idButtonIface->set_property("ButtonPressed", !state);
+ if(!state) {
+ setUidLed();
+ }
}
static void pltRstHandler(bool pltRst)
--
2.34.1
@@ -0,0 +1,432 @@
From 8b6def70a95ddab05ec565db1c5437ad17423d20 Mon Sep 17 00:00:00 2001
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
Date: Tue, 3 Dec 2024 21:23:28 +0800
Subject: [PATCH 10/10] Fix soft-shutdown without SEL
---
src/power_control.cpp | 275 +++++++++++++++++++++++++++++++++++-------
1 file changed, 233 insertions(+), 42 deletions(-)
diff --git a/src/power_control.cpp b/src/power_control.cpp
index 2a72473..cfe6e57 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -94,6 +94,22 @@ static ConfigData idButtonConfig;
static ConfigData nmiButtonConfig;
static ConfigData slotPowerConfig;
+struct LogData
+{
+ bool assert;
+ uint16_t generatorID;
+ std::vector<uint8_t> selData;
+ std::string sensorPath;
+};
+
+struct LogData acpiStatusOffSensor = {true, 0x0020, {6, 255, 255}, "null"};
+struct LogData acpiStatusOnSensor = {true, 0x0020, {0, 255, 255}, "null"};
+struct LogData osBootSensor = {true, 0x0020, {6, 255, 255}, "null"};
+struct LogData sysBootPowerUpSensor = {true, 0x0020, {0, 255, 255}, "null"};
+struct LogData sysBootHardResetSensor = {true, 0x0020, {1, 255, 255}, "null"};
+struct LogData sysBootWarmResetSensor = {true, 0x0020, {2, 255, 255}, "null"};
+struct LogData powerButtonPressedSensor = {true, 0x0020, {0, 255, 255}, "null"};
+
// map for storing list of gpio parameters whose config are to be read from x86
// power control json config
boost::container::flat_map<std::string, ConfigData*> powerSignalMap = {
@@ -578,47 +594,48 @@ static void powerStateLog(const PowerState state)
constexpr const char* selPath = "/xyz/openbmc_project/Logging/IPMI";
constexpr const char* selInterface = "xyz.openbmc_project.Logging.IPMI";
constexpr const char* selMethod = "IpmiSelAdd";
- std::string sensorPath =
- "/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/ACPI_State";
+ struct LogData powerStatusSensor;
auto bus = sdbusplus::bus::new_default();
- std::string stateStr = std::string(getChassisState(state));
+
auto method =
bus.new_method_call(selService, selPath, selInterface, selMethod);
- method.append("SEL Entry");
-
- if (stateStr == "xyz.openbmc_project.State.Chassis.PowerState.On")
- {
- std::cerr << "Send Power State On SEL Log\n";
- method.append(sensorPath.c_str());
- method.append(
- std::array<uint8_t, 3>({0x00, 0xFF, 0xFF})); // S0/G0: working
- }
- else if (stateStr == "xyz.openbmc_project.State.Chassis.PowerState.Off")
- {
- std::cerr << "Send Power State Off SEL Log\n";
- method.append(sensorPath.c_str());
- method.append(
- std::array<uint8_t, 3>({0x06, 0xFF, 0xFF})); // S4/S5: soft-off
- }
- else if (stateStr == "ButtonPressed")
- {
- std::cerr << "Send Power State Button Pressed SEL Log\n";
- sensorPath = "/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/Power_Button";
- method.append(sensorPath.c_str());
- method.append(
- std::array<uint8_t, 3>({0x00, 0xFF, 0xFF})); // power button pressed
- }
- else
+ switch (state)
{
- std::cerr << "Send Power State SEL Log Error\n";
- return;
+ case PowerState::on:
+ std::cout << "PowerState:: on" << std::endl;
+ powerStatusSensor = acpiStatusOnSensor;
+ break;
+ // both off and cycleOff will call acpiStatusOffSensor
+ case PowerState::off:
+ case PowerState::cycleOff:
+ std::cout << "PowerState:: off" << std::endl;
+ powerStatusSensor = acpiStatusOffSensor;
+ break;
+ case PowerState::transitionToCycleOff:
+ powerStatusSensor = sysBootHardResetSensor;
+ break;
+ case PowerState::waitForPSPowerOK:
+ powerStatusSensor = sysBootPowerUpSensor;
+ break;
+ case PowerState::checkForWarmReset:
+ powerStatusSensor = sysBootWarmResetSensor;
+ break;
+ case PowerState::powerButtonPressed:
+ powerStatusSensor = powerButtonPressedSensor;
+ break;
+ default:
+ break;
}
- method.append(true); // assert is true and deassert is false
- method.append(uint16_t(0x0020)); // generator ID
+ method.append("SEL Entry");
+ method.append(powerStatusSensor.sensorPath);
+ method.append(powerStatusSensor.selData);
+ method.append(
+ powerStatusSensor.assert); // assert is true and deassert is false
+ method.append(powerStatusSensor.generatorID); // generator ID
try
{
bus.call_noreply(method);
@@ -851,6 +868,7 @@ static void powerButtonPressLog()
// sd_journal_send("MESSAGE=PowerControl: power button pressed", "PRIORITY=%i",
// LOG_INFO, "REDFISH_MESSAGE_ID=%s",
// "OpenBMC.0.1.PowerButtonPressed", NULL);
+ std::cout << "power button pressed" << __LINE__ << std::endl;
powerStateLog(PowerState::powerButtonPressed);
}
@@ -1829,9 +1847,10 @@ static void currentHostStateMonitor()
pohCounterTimerStart();
// Clear the restart cause set for the next restart
clearRestartCause();
- sd_journal_send("MESSAGE=Host system DC power is on", "PRIORITY=%i",
- LOG_INFO, "REDFISH_MESSAGE_ID=%s",
- "OpenBMC.0.1.DCPowerOn", NULL);
+ std::cout << "Host system DC power is on" << __LINE__ << std::endl;
+ //sd_journal_send("MESSAGE=Host system DC power is on", "PRIORITY=%i",
+ // LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+ // "OpenBMC.0.1.DCPowerOn", NULL);
}
else
{
@@ -1848,9 +1867,10 @@ static void currentHostStateMonitor()
#ifdef USE_ACBOOT
resetACBootProperty();
#endif // USE_ACBOOT
- sd_journal_send("MESSAGE=Host system DC power is off",
- "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
- "OpenBMC.0.1.DCPowerOff", NULL);
+ std::cout << "Host system DC power is off" << __LINE__ << std::endl;
+ //sd_journal_send("MESSAGE=Host system DC power is off",
+ // "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+ // "OpenBMC.0.1.DCPowerOff", NULL);
}
});
}
@@ -1966,6 +1986,7 @@ static void powerStateWaitForPSPowerOK(const Event event)
else
{
setPowerState(PowerState::on);
+ std::cout << "powerStateWaitForPSPowerOK" << __LINE__ << std::endl;
powerStateLog(PowerState::on);
}
break;
@@ -2018,7 +2039,6 @@ static void powerStateOff(const Event event)
else
{
setPowerState(PowerState::on);
- powerStateLog(PowerState::on);
}
break;
}
@@ -2053,6 +2073,7 @@ static void powerStateTransitionToOff(const Event event)
// Cancel any GPIO assertions held during the transition
gpioAssertTimer.cancel();
setPowerState(PowerState::off);
+ std::cout << "powerStateTransitionToOff" << __LINE__ << std::endl;
powerStateLog(PowerState::off);
break;
default:
@@ -2069,6 +2090,8 @@ static void powerStateGracefulTransitionToOff(const Event event)
case Event::psPowerOKDeAssert:
gracefulPowerOffTimer.cancel();
setPowerState(PowerState::off);
+ std::cout << "powerStateGracefulTransitionToOff power off" << __LINE__ << std::endl;
+ powerStateLog(PowerState::off);
break;
case Event::gracefulPowerOffTimerExpired:
setPowerState(PowerState::on);
@@ -2110,6 +2133,7 @@ static void powerStateCycleOff(const Event event)
else
{
setPowerState(PowerState::on);
+ std::cout << "powerStateCycleOff:power on" << __LINE__ << std::endl;
}
break;
}
@@ -2143,6 +2167,7 @@ static void powerStateTransitionToCycleOff(const Event event)
// Cancel any GPIO assertions held during the transition
gpioAssertTimer.cancel();
setPowerState(PowerState::cycleOff);
+ std::cout << "powerStateTransitionToCycleOff power off" << __LINE__ << std::endl;
powerStateLog(PowerState::cycleOff);
powerCycleTimerStart();
break;
@@ -2160,6 +2185,8 @@ static void powerStateGracefulTransitionToCycleOff(const Event event)
case Event::psPowerOKDeAssert:
gracefulPowerOffTimer.cancel();
setPowerState(PowerState::cycleOff);
+ std::cout << "powerStateGracefulTransitionToCycleOff power off" << __LINE__ << std::endl;
+ powerStateLog(PowerState::cycleOff);
powerCycleTimerStart();
break;
case Event::gracefulPowerOffTimerExpired:
@@ -2201,6 +2228,8 @@ static void powerStateCheckForWarmReset(const Event event)
case Event::psPowerOKDeAssert:
warmResetCheckTimer.cancel();
setPowerState(PowerState::off);
+ std::cout << "powerStateCheckForWarmReset power off" << __LINE__ << std::endl;
+ powerStateLog(PowerState::cycleOff);
// DC power is unexpectedly lost, beep
beep(beepPowerFail);
break;
@@ -2496,12 +2525,43 @@ static void pltRstHandler(bool pltRst)
}
}
+static void postCompleteLog()
+{
+ constexpr const char* selService = "xyz.openbmc_project.Logging.IPMI";
+ constexpr const char* selPath = "/xyz/openbmc_project/Logging/IPMI";
+ constexpr const char* selInterface = "xyz.openbmc_project.Logging.IPMI";
+ constexpr const char* selMethod = "IpmiSelAdd";
+
+ auto bus = sdbusplus::bus::new_default();
+
+ auto method =
+ bus.new_method_call(selService, selPath, selInterface, selMethod);
+
+ method.append("SEL Entry");
+ method.append(osBootSensor.sensorPath);
+ method.append(osBootSensor.selData);
+ method.append(osBootSensor.assert); // assert is true and deassert is false
+ method.append(osBootSensor.generatorID); // generator ID
+ try
+ {
+ bus.call_noreply(method);
+ }
+ catch (const sdbusplus::exception::SdBusError& ex)
+ {
+ lg2::error(
+ "Failed to call sel log {SELPATH}, {SELINTERFACE}, {SELMRTHOD}",
+ "SELPATH", selPath, "SELINTERFACE", selInterface, "SELMRTHOD",
+ selMethod);
+ }
+}
+
static void postCompleteHandler(bool state)
{
if (!state)
{
sendPowerControlEvent(Event::postCompleteAssert);
setOperatingSystemState(OperatingSystemStateStage::Inactive);
+ //postCompleteLog();
}
else
{
@@ -2510,6 +2570,107 @@ static void postCompleteHandler(bool state)
}
}
+std::optional<std::string> getDiscretePrefixFromFile()
+{
+ constexpr auto boardNameFile = "/usr/share/boardname/boardname.conf";
+ constexpr auto boardPrefix = "/xyz/openbmc_project/inventory/system/board/";
+
+ std::ifstream file(boardNameFile);
+ if (!file.is_open())
+ {
+ lg2::error("Fail to open {FILE}", "FILE", boardNameFile);
+ return std::nullopt;
+ }
+
+ std::string boardName{};
+ std::getline(file, boardName);
+ if (boardName.empty())
+ {
+ lg2::error("Fail to read {FILE}", "FILE", boardNameFile);
+ return std::nullopt;
+ }
+ lg2::info("Board name is {BOARD}", "BOARD", boardName);
+ return boardPrefix + boardName;
+}
+
+std::optional<std::vector<std::string>>
+ getSubTreePaths(sdbusplus::bus::bus& bus, const std::string& objectPath,
+ const std::string& interface)
+{
+ constexpr auto mapperBusname = "xyz.openbmc_project.ObjectMapper";
+ constexpr auto mapperObjPath = "/xyz/openbmc_project/object_mapper";
+ constexpr auto mapperIface = "xyz.openbmc_project.ObjectMapper";
+ std::vector<std::string> paths;
+
+ auto method = bus.new_method_call(mapperBusname, mapperObjPath, mapperIface,
+ "GetSubTreePaths");
+ method.append(objectPath.c_str());
+ method.append(0); // Depth 0 to search all
+ method.append(std::vector<std::string>({interface.c_str()}));
+
+ try
+ {
+ auto reply = bus.call(method);
+ reply.read(paths);
+ return paths;
+ }
+ catch (const sdbusplus::exception::SdBusError& e)
+ {
+ lg2::error("Fail to get chassis path");
+ return std::nullopt;
+ }
+
+ return std::nullopt;
+}
+
+std::optional<std::string> getDiscreteSensorPath(const std::string& sensorName)
+{
+ static std::string discreteSensorPathPrefix{};
+ if (discreteSensorPathPrefix.empty())
+ {
+ // First try to get the path from the file
+ auto prefix = getDiscretePrefixFromFile();
+ if (prefix)
+ {
+ discreteSensorPathPrefix = *prefix;
+ }
+ else
+ {
+ // If the file doesn't exist, get the path from the dbus
+ constexpr auto discreteSensorUpperPath =
+ "/xyz/openbmc_project/inventory";
+ constexpr auto discreteSensorInterface =
+ "xyz.openbmc_project.Configuration.Status";
+ auto bus = sdbusplus::bus::new_default();
+ auto sensorPaths = getSubTreePaths(bus, discreteSensorUpperPath,
+ discreteSensorInterface);
+ // if call fail or empty, return nullopt
+ if (!sensorPaths || sensorPaths.value().size() == 0)
+ {
+ return std::nullopt;
+ }
+ // if any sensor path is find, get the prefix of the path
+ // because all discrete sensor path in the inventory has the same
+ // prefix
+ for (const auto& sensorPath : sensorPaths.value())
+ {
+ discreteSensorPathPrefix =
+ sensorPath.substr(0, sensorPath.find_last_of('/'));
+ break;
+ }
+ if (discreteSensorPathPrefix.empty())
+ {
+ return std::nullopt;
+ }
+ }
+ }
+
+ std::string path = discreteSensorPathPrefix;
+ path.append("/");
+ path.append(sensorName);
+ return path;
+}
+
static int loadConfigValues()
{
const std::string configFilePath =
@@ -2661,6 +2822,33 @@ static int loadConfigValues()
nmiWhenPoweredOff = events.value("NMIWhenPoweredOff", true);
}
+ auto acpiSensorPath = getDiscreteSensorPath("ACPI_State");
+ if (acpiSensorPath != std::nullopt)
+ {
+ acpiStatusOnSensor.sensorPath = acpiSensorPath.value();
+ acpiStatusOffSensor.sensorPath = acpiSensorPath.value();
+ }
+
+ auto sysbootSensorPath = getDiscreteSensorPath("SYS_Boot");
+ if (sysbootSensorPath != std::nullopt)
+ {
+ sysBootPowerUpSensor.sensorPath = sysbootSensorPath.value();
+ sysBootHardResetSensor.sensorPath = sysbootSensorPath.value();
+ sysBootWarmResetSensor.sensorPath = sysbootSensorPath.value();
+ }
+
+ auto osbootSensorPath = getDiscreteSensorPath("OS_Boot");
+ if (osbootSensorPath != std::nullopt)
+ {
+ osBootSensor.sensorPath = osbootSensorPath.value();
+ }
+
+ auto powerbuttonSensorPath = getDiscreteSensorPath("Power_Button");
+ if (powerbuttonSensorPath != std::nullopt)
+ {
+ powerButtonPressedSensor.sensorPath = powerbuttonSensorPath.value();
+ }
+
return 0;
}
@@ -2840,7 +3028,7 @@ void reschedulePropertyRead(const ConfigData& configData)
}
});
}
-
+bool bmcReset = true;
static void ACPIStateSel(void)
{
const static constexpr int TimeMs = 20000;
@@ -2856,8 +3044,11 @@ static void ACPIStateSel(void)
ec.message());
}
}
- lg2::info("ACPI State sel");
- powerStateLog(powerState);
+ std::cout << "BMC reboot:power state" << __LINE__ << std::endl;
+ if (bmcReset == true){
+ powerStateLog(powerState);
+ }
+ bmcReset = false;
});
}
--
2.25.1
@@ -0,0 +1,18 @@
FILESEXTRAPATHS:append := "${THISDIR}/${PN}:"
SRC_URI += " \
file://0001-Post-Complete-Signal-Handling.patch \
file://0002-Polarity-Issue.patch \
file://0003-Update-NMIOut-LineName-to-match-DTS.patch \
file://0004-Remove-the-GPIO-configuration-for-unused-pins.patch \
file://0005-Implement-power-reset-control.patch \
file://0006-Add-power-control-SEL.patch \
file://0007-Add-power-button-sensor.patch \
file://0008-Add-ACPI_State-event-monitoring.patch \
file://0009-Control-uidLed-in-uid-button-handler.patch \
file://0010-Fix-soft-shutdown-without-SEL.patch \
"
do_install:append() {
mkdir -p ${D}${sysconfdir}/systemd/system/xyz.openbmc_project.Chassis.Control.Power@.service.d/
}
@@ -0,0 +1,11 @@
SUMMARY = "boardname configuration for Lux_Baseboard"
PR = "r1"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
SRC_URI += "file://boardname.conf"
do_install() {
install -d ${D}/usr/share/boardname
install -m 0444 ${WORKDIR}/boardname.conf ${D}/usr/share/boardname
}
@@ -0,0 +1 @@
Lux_Baseboard
@@ -0,0 +1,83 @@
From 8d85b0f37638c606e195753553fe21cbe8663cd1 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Tue, 15 Oct 2024 18:42:41 +0800
Subject: [PATCH] Add Status interface to settableInterfaces
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
%% original patch: 0001-Add-Status-interface-to-settableInterfaces.patch
---
src/entity_manager.cpp | 36 +++++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/src/entity_manager.cpp b/src/entity_manager.cpp
index ee08c00..24da084 100644
--- a/src/entity_manager.cpp
+++ b/src/entity_manager.cpp
@@ -52,6 +52,9 @@ constexpr const char* tempConfigDir = "/tmp/configuration/";
constexpr const char* lastConfiguration = "/tmp/configuration/last.json";
constexpr const char* currentConfiguration = "/var/configuration/system.json";
constexpr const char* globalSchema = "global.json";
+constexpr auto configIfaceName = "xyz.openbmc_project.Configuration.Status";
+constexpr auto statusPropName = "Status";
+bool internalSet = false;
const boost::container::flat_map<const char*, probe_type_codes, CmpStr>
probeTypes{{{"FALSE", probe_type_codes::FALSE_T},
@@ -61,8 +64,8 @@ const boost::container::flat_map<const char*, probe_type_codes, CmpStr>
{"FOUND", probe_type_codes::FOUND},
{"MATCH_ONE", probe_type_codes::MATCH_ONE}}};
-static constexpr std::array<const char*, 6> settableInterfaces = {
- "FanProfile", "Pid", "Pid.Zone", "Stepwise", "Thresholds", "Polling"};
+static constexpr std::array<const char*, 9> settableInterfaces = {
+ "FanProfile", "Pid", "Pid.Zone", "Stepwise", "Thresholds", "Polling", "Status", "Description", "Health"};
using JsonVariantType =
std::variant<std::vector<std::string>, std::vector<double>, std::string,
int64_t, uint64_t, double, int32_t, uint32_t, int16_t,
@@ -216,9 +219,31 @@ void addProperty(const std::string& name, const PropertyType& value,
iface->register_property(
name, value,
[&systemConfiguration,
- jsonPointerString{std::string(jsonPointerString)}](
- const PropertyType& newVal, PropertyType& val) {
- val = newVal;
+ jsonPointerString{std::string(jsonPointerString)},
+ interface = iface->get_interface_name(),
+ propertyName = name](const PropertyType& newVal, PropertyType& val) {
+ // if set from external source, for status property, only
+ // keep the bits 0..15
+ if (!internalSet && interface == configIfaceName &&
+ propertyName == statusPropName)
+ {
+ if constexpr (std::is_same_v<PropertyType, double>)
+ {
+ auto tmp = static_cast<uint32_t>(newVal);
+ tmp &= 0xFFFF;
+ val = static_cast<double>(
+ (static_cast<uint32_t>(val) & ~0xFFFF) | tmp);
+ }
+ else
+ {
+ val = newVal;
+ }
+ }
+ else
+ {
+ val = newVal;
+ }
+
if (!setJsonFromPointer(jsonPointerString, val, systemConfiguration))
{
std::cerr << "error setting json field\n";
@@ -1280,6 +1305,7 @@ int main()
entityIface->register_method("ReScan", [&]() {
propertiesChangedCallback(systemConfiguration, objServer);
});
+
entityIface->initialize();
if (fwVersionIsSame())
--
2.34.1
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,401 @@
{
"Exposes": [
{
"Name": "System Fan connector 1",
"Pwm": 0,
"Tachs": [
0,
1
],
"Type": "IntelFanConnector"
},
{
"Name": "System Fan connector 2",
"Pwm": 1,
"Tachs": [
2,
3
],
"Type": "IntelFanConnector"
},
{
"Name": "System Fan connector 3",
"Pwm": 2,
"Tachs": [
4,
5
],
"Type": "IntelFanConnector"
},
{
"Name": "System Fan connector 4",
"Pwm": 3,
"Tachs": [
6,
7
],
"Type": "IntelFanConnector"
},
{
"Name": "System Fan connector 5",
"Pwm": 4,
"Tachs": [
8,
9
],
"Type": "IntelFanConnector"
},
{
"Name": "System Fan connector 6",
"Pwm": 5,
"Tachs": [
10,
11
],
"Type": "IntelFanConnector"
},
{
"BindConnector": "System Fan connector 1",
"Index": 0,
"Name": "Fan 1 Inlet",
"Type": "AspeedFan"
},
{
"BindConnector": "System Fan connector 1",
"Index": 1,
"Name": "Fan 1 Outlet",
"Type": "AspeedFan"
},
{
"BindConnector": "System Fan connector 2",
"Index": 2,
"Name": "Fan 2 Inlet",
"Type": "AspeedFan"
},
{
"BindConnector": "System Fan connector 2",
"Index": 3,
"Name": "Fan 2 Outlet",
"Type": "AspeedFan"
},
{
"BindConnector": "System Fan connector 3",
"Index": 4,
"Name": "Fan 3 Inlet",
"Type": "AspeedFan"
},
{
"BindConnector": "System Fan connector 3",
"Index": 5,
"Name": "Fan 3 Outlet",
"Type": "AspeedFan"
},
{
"BindConnector": "System Fan connector 4",
"Index": 6,
"Name": "Fan 4 Inlet",
"Type": "AspeedFan"
},
{
"BindConnector": "System Fan connector 4",
"Index": 7,
"Name": "Fan 4 Outlet",
"Type": "AspeedFan"
},
{
"BindConnector": "System Fan connector 5",
"Index": 8,
"Name": "Fan 5 Inlet",
"Type": "AspeedFan"
},
{
"BindConnector": "System Fan connector 5",
"Index": 9,
"Name": "Fan 5 Outlet",
"Type": "AspeedFan"
},
{
"Class": "fan",
"FFGainCoefficient": 0.01,
"FFOffCoefficient": 0.0,
"ICoefficient": 0.0,
"ILimitMax": 0.0,
"ILimitMin": 0.0,
"Inputs": [
"Fan 1 Inlet",
"Fan 1 Outlet"
],
"Name": "Fan 1",
"NegativeHysteresis": 2.0,
"OutLimitMax": 100.0,
"OutLimitMin": 30.0,
"Outputs": [
"Pwm 1"
],
"PCoefficient": 0.0,
"PositiveHysteresis": 0.0,
"SlewNeg": 0.0,
"SlewPos": 0.0,
"Type": "Pid",
"Zones": [
"Fan1"
]
},
{
"Class": "fan",
"FFGainCoefficient": 0.01,
"FFOffCoefficient": 0.0,
"ICoefficient": 0.0,
"ILimitMax": 0.0,
"ILimitMin": 0.0,
"Inputs": [
"Fan 2 Inlet",
"Fan 2 Outlet"
],
"Name": "Fan 2",
"NegativeHysteresis": 2.0,
"OutLimitMax": 100.0,
"OutLimitMin": 30.0,
"Outputs": [
"Pwm 2"
],
"PCoefficient": 0.0,
"PositiveHysteresis": 0.0,
"SlewNeg": 0.0,
"SlewPos": 0.0,
"Type": "Pid",
"Zones": [
"Fan2"
]
},
{
"Class": "fan",
"FFGainCoefficient": 0.01,
"FFOffCoefficient": 0.0,
"ICoefficient": 0.0,
"ILimitMax": 0.0,
"ILimitMin": 0.0,
"Inputs": [
"Fan 3 Inlet",
"Fan 3 Outlet"
],
"Name": "Fan 3",
"NegativeHysteresis": 2.0,
"OutLimitMax": 100.0,
"OutLimitMin": 30.0,
"Outputs": [
"Pwm 3"
],
"PCoefficient": 0.0,
"PositiveHysteresis": 0.0,
"SlewNeg": 0.0,
"SlewPos": 0.0,
"Type": "Pid",
"Zones": [
"Fan3"
]
},
{
"Class": "fan",
"FFGainCoefficient": 0.01,
"FFOffCoefficient": 0.0,
"ICoefficient": 0.0,
"ILimitMax": 0.0,
"ILimitMin": 0.0,
"Inputs": [
"Fan 4 Inlet",
"Fan 4 Outlet"
],
"Name": "Fan 4",
"NegativeHysteresis": 2.0,
"OutLimitMax": 100.0,
"OutLimitMin": 30.0,
"Outputs": [
"Pwm 4"
],
"PCoefficient": 0.0,
"PositiveHysteresis": 0.0,
"SlewNeg": 0.0,
"SlewPos": 0.0,
"Type": "Pid",
"Zones": [
"Fan4"
]
},
{
"Class": "fan",
"FFGainCoefficient": 0.01,
"FFOffCoefficient": 0.0,
"ICoefficient": 0.0,
"ILimitMax": 0.0,
"ILimitMin": 0.0,
"Inputs": [
"Fan 5 Inlet",
"Fan 5 Outlet"
],
"Name": "Fan 5",
"NegativeHysteresis": 2.0,
"OutLimitMax": 100.0,
"OutLimitMin": 30.0,
"Outputs": [
"Pwm 5"
],
"PCoefficient": 0.0,
"PositiveHysteresis": 0.0,
"SlewNeg": 0.0,
"SlewPos": 0.0,
"Type": "Pid",
"Zones": [
"Fan5"
]
},
{
"FailSafePercent": 100,
"MinThermalRpm": 3000,
"Name": "Fan1",
"Type": "Pid.Zone"
},
{
"FailSafePercent": 100,
"MinThermalRpm": 3000,
"Name": "Fan2",
"Type": "Pid.Zone"
},
{
"FailSafePercent": 100,
"MinThermalRpm": 3000,
"Name": "Fan3",
"Type": "Pid.Zone"
},
{
"FailSafePercent": 100,
"MinThermalRpm": 3000,
"Name": "Fan4",
"Type": "Pid.Zone"
},
{
"FailSafePercent": 100,
"MinThermalRpm": 3000,
"Name": "Fan5",
"Type": "Pid.Zone"
},
{
"AllowedFailures": 1,
"Name": "FanRedundancy",
"Type": "FanRedundancy"
},
{
"Class": "temp",
"FFGainCoefficient": 0.0,
"FFOffCoefficient": 0.0,
"ICoefficient": -0.2,
"ILimitMax": 100,
"ILimitMin": 30,
"Inputs": [
"CPU0 Temp0"
],
"Name": "CPU0",
"NegativeHysteresis": 2.0,
"OutLimitMax": 100,
"OutLimitMin": 30,
"Outputs": [],
"PCoefficient": -3.0,
"PositiveHysteresis": 0.0,
"SetPoint": 45.0,
"SlewNeg": -1,
"SlewPos": 0.0,
"Type": "Pid",
"Zones": [
"Fan1",
"Fan2",
"Fan3",
"Fan4",
"Fan5"
]
},
{
"Class": "temp",
"FFGainCoefficient": 0.0,
"FFOffCoefficient": 0.0,
"ICoefficient": -0.2,
"ILimitMax": 100,
"ILimitMin": 30,
"Inputs": [
"CPU1 Temp0"
],
"Name": "CPU1",
"OutLimitMax": 100,
"OutLimitMin": 30,
"Outputs": [],
"PCoefficient": -3.0,
"SetPoint": 45.0,
"SlewNeg": -1,
"SlewPos": 0.0,
"Type": "Pid",
"Zones": [
"Fan1",
"Fan2",
"Fan3",
"Fan4",
"Fan5"
]
},
{
"Class": "Floor",
"Inputs": [
"XXX Temp"
],
"Name": "Front Panel LCC",
"NegativeHysteresis": 2,
"Output": [
50.0,
60.0
],
"PositiveHysteresis": 0,
"Reading": [
20.0,
30.0
],
"Type": "Stepwise",
"Zones": [
"Fan1",
"Fan2"
]
},
{
"Class": "Ceiling",
"Inputs": [
"Front Panel Temp"
],
"Name": "Front Panel UCC",
"NegativeHysteresis": 2,
"Output": [
70.0,
80.0
],
"PositiveHysteresis": 0,
"Reading": [
22.0,
32.0
],
"Type": "Stepwise",
"Zones": [
"Fan3",
"Fan4"
]
}
],
"Name": "Board Fan",
"Probe": "TRUE",
"Type": "Board",
"xyz.openbmc_project.Inventory.Decorator.Asset": {
"Manufacturer": "",
"Model": "",
"PartNumber": "",
"SerialNumber": ""
},
"xyz.openbmc_project.Inventory.Item.Bmc": {
"Present": true,
"Functional": true
}
}
@@ -0,0 +1,4 @@
{
"buses": [
]
}
@@ -0,0 +1,15 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI:append = " \
file://blacklist.json \
file://Lux-Baseboard.json \
file://0001-Add-Status-interface-to-settableInterfaces.patch \
"
do_install:append () {
rm -rf ${D}/usr/share/entity-manager/configurations/*.json
install -d ${D}${datadir}/${PN}
install -d ${D}/usr/share/entity-manager/configurations
install -m 0644 -D ${WORKDIR}/blacklist.json ${D}${datadir}/${PN}/blacklist.json
install -m 0444 ${WORKDIR}/Lux-Baseboard.json ${D}/usr/share/entity-manager/configurations
}
@@ -0,0 +1,31 @@
SUMMARY = "YAML configuration for luxshare"
PR = "r1"
LICENSE = "CLOSED"
inherit allarch
SRC_URI = " \
file://lux-ipmi-fru.yaml \
file://lux-ipmi-sensors.yaml \
file://lux-ipmi-fru-properties.yaml \
file://lux-ipmi-inventory-sensors.yaml \
"
S = "${WORKDIR}"
do_install() {
install -m 0644 -D lux-ipmi-fru.yaml ${D}${datadir}/${BPN}/ipmi-fru-read.yaml
install -m 0644 -D lux-ipmi-sensors.yaml ${D}${datadir}/${BPN}/ipmi-sensors.yaml
install -m 0644 -D lux-ipmi-fru-properties.yaml ${D}${datadir}/${BPN}/ipmi-extra-properties.yaml
install -m 0644 -D lux-ipmi-inventory-sensors.yaml ${D}${datadir}/${BPN}/ipmi-inventory-sensors.yaml
}
FILES:${PN}: = " \
${datadir}/${BPN}/ipmi-fru-read.yaml \
${datadir}/${BPN}/ipmi-sensors.yaml \
${datadir}/${BPN}/ipmi-extra-properties.yaml \
${datadir}/${BPN}/ipmi-inventory-sensors.yaml \
"
ALLOW_EMPTY:${PN} = "1"
@@ -0,0 +1,21 @@
/system:
xyz.openbmc_project.Inventory.Decorator.Cacheable:
Cached: 'true'
xyz.openbmc_project.Inventory.Decorator.Replaceable:
FieldReplaceable: 'true'
xyz.openbmc_project.Inventory.Item:
Present: 'true'
/system/board:
xyz.openbmc_project.Inventory.Decorator.Cacheable:
Cached: 'true'
xyz.openbmc_project.Inventory.Decorator.Replaceable:
FieldReplaceable: 'true'
xyz.openbmc_project.Inventory.Item:
Present: 'true'
/system/board/Mobile:
xyz.openbmc_project.Inventory.Decorator.Cacheable:
Cached: 'true'
xyz.openbmc_project.Inventory.Decorator.Replaceable:
FieldReplaceable: 'true'
xyz.openbmc_project.Inventory.Item:
Present: 'true'
@@ -0,0 +1,12 @@
0:
/xyz/openbmc_project/FruDevice/Mobile:
entityID: 7
entityInstance: 1
interfaces:
xyz.openbmc_project.FruDevice:
PRODUCT_MANUFACTURER:
IPMIFruProperty: Manufacturer
IPMIFruSection: Product
PRODUCT_PRODUCT_NAME:
IPMIFruProperty: Name
IPMIFruSection: Product
@@ -0,0 +1,590 @@
/xyz/openbmc_project/inventory/system:
eventReadingType: 0x6f
sensorID: 0x00
sensorType: 0x12
offset: 0x02
/xyz/openbmc_project/sensors/fan_tach/FAN1_Speed:
eventReadingType: 1
offset: 0
sensorID: 0x01
sensorType: 4
/xyz/openbmc_project/sensors/fan_tach/FAN2_Speed:
eventReadingType: 1
offset: 0
sensorID: 0x02
sensorType: 4
/xyz/openbmc_project/sensors/fan_tach/FAN3_Speed:
eventReadingType: 1
offset: 0
sensorID: 0x03
sensorType: 4
/xyz/openbmc_project/sensors/fan_tach/FAN4_Speed:
eventReadingType: 1
offset: 0
sensorID: 0x04
sensorType: 4
/xyz/openbmc_project/sensors/fan_tach/FAN5_Speed:
eventReadingType: 1
offset: 0
sensorID: 0x05
sensorType: 4
/xyz/openbmc_project/sensors/fan_pwm/PWM1:
eventReadingType: 0x1
offset: 0
sensorID: 0x8
sensorType: 4
/xyz/openbmc_project/sensors/fan_pwm/PWM2:
eventReadingType: 0x1
offset: 0
sensorID: 0x9
sensorType: 4
/xyz/openbmc_project/sensors/fan_pwm/PWM3:
eventReadingType: 0x1
offset: 0
sensorID: 0xa
sensorType: 4
/xyz/openbmc_project/sensors/fan_pwm/PWM4:
eventReadingType: 0x1
offset: 0
sensorID: 0xb
sensorType: 4
/xyz/openbmc_project/sensors/fan_pwm/PWM5:
eventReadingType: 0x1
offset: 0
sensorID: 0xc
sensorType: 4
/xyz/openbmc_project/sensors/voltage/P12V_AUX:
eventReadingType: 1
sensorID: 0x18
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/P5V_AUX:
eventReadingType: 1
sensorID: 0x19
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/P3V3_AUX:
eventReadingType: 1
sensorID: 0x1A
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/P3V_VBAT:
eventReadingType: 1
sensorID: 0x1B
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/VCCIN0_MON:
eventReadingType: 1
sensorID: 0x1C
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/VCCINFAON0_MON:
eventReadingType: 1
sensorID: 0x1D
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/EHV0_MON:
eventReadingType: 1
sensorID: 0x1E
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/EHVFIVRA0_MON:
eventReadingType: 1
sensorID: 0x1F
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/VCCD0_HV0_MON:
eventReadingType: 1
sensorID: 0x20
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/VNN_MAIN0_MON:
eventReadingType: 1
sensorID: 0x21
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/VCCD1_HV0_MON:
eventReadingType: 1
sensorID: 0x22
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/P12_CPU0:
eventReadingType: 1
sensorID: 0x23
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/P2V5_AUX:
eventReadingType: 1
sensorID: 0x24
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/P1V8_AUX:
eventReadingType: 1
sensorID: 0x25
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/P1V2_AUX:
eventReadingType: 1
sensorID: 0x26
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/P1V0_AUX:
eventReadingType: 1
sensorID: 0x27
sensorType: 2
offset: 0
/xyz/openbmc_project/sensors/voltage/PSU0_VIn:
eventReadingType: 1
offset: 0
sensorID: 0x28
sensorType: 2
# /xyz/openbmc_project/sensors/voltage/PSU1_VIn:
# eventReadingType: 1
# offset: 0
# sensorID: 0x29
# sensorType: 2
/xyz/openbmc_project/sensors/voltage/PSU0_VOut:
eventReadingType: 1
offset: 0
sensorID: 0x2A
sensorType: 2
# /xyz/openbmc_project/sensors/voltage/PSU1_VOut:
# eventReadingType: 1
# offset: 0
# sensorID: 0x2B
# sensorType: 2
/xyz/openbmc_project/sensors/current/PSU0_IIn:
eventReadingType: 1
offset: 0
sensorID: 0x2C
sensorType: 3
# /xyz/openbmc_project/sensors/current/PSU1_IIn:
# eventReadingType: 1
# offset: 0
# sensorID: 0x2D
# sensorType: 3
/xyz/openbmc_project/sensors/current/PSU0_IOut:
eventReadingType: 1
offset: 0
sensorID: 0x2E
sensorType: 3
# /xyz/openbmc_project/sensors/current/PSU1_IOut:
# eventReadingType: 1
# offset: 0
# sensorID: 0x2F
# sensorType: 3
/xyz/openbmc_project/sensors/temperature/M2_0_Temp:
eventReadingType: 1
sensorID: 0x37
sensorType: 1
offset: 0
/xyz/openbmc_project/sensors/temperature/MB_Temp:
eventReadingType: 1
sensorID: 0x38
sensorType: 1
offset: 0
/xyz/openbmc_project/sensors/temperature/CPU0_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x39
sensorType: 1
/xyz/openbmc_project/sensors/temperature/CPU1_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x3A
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_A_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x3B
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_B_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x3C
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_C_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x3D
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_D_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x3E
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_E_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x3F
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_F_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x40
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_G_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x41
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_H_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x42
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_I_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x43
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_G_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x44
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_K_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x45
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_L_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x46
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_A_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x47
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_B_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x48
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_C_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x49
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_D_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x4A
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_E_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x4B
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_F_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x4C
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_G_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x4D
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_H_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x4E
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_I_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x4F
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_G_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x50
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_K_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x51
sensorType: 1
/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_L_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x52
sensorType: 1
/xyz/openbmc_project/sensors/temperature/PSU0_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x53
sensorType: 1
# /xyz/openbmc_project/sensors/temperature/PSU1_Temp:
# eventReadingType: 1
# offset: 0
# sensorID: 0x54
# sensorType: 1
/xyz/openbmc_project/sensors/temperature/PVCCIN_CPU0_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x55
sensorType: 1
/xyz/openbmc_project/sensors/temperature/PVCCFA_CPU0_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x56
sensorType: 1
/xyz/openbmc_project/sensors/temperature/PVCCD_CPU0_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x57
sensorType: 1
/xyz/openbmc_project/sensors/temperature/PVCCIN_CPU1_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x58
sensorType: 1
/xyz/openbmc_project/sensors/temperature/PVCCFA_CPU1_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x59
sensorType: 1
/xyz/openbmc_project/sensors/temperature/PVCCFA_CPU1_Temp:
eventReadingType: 1
offset: 0
sensorID: 0x5A
sensorType: 1
/xyz/openbmc_project/sensors/power/PSU0_PIn:
eventReadingType: 1
offset: 0
sensorID: 0x60
sensorType: 8
# /xyz/openbmc_project/sensors/power/PSU1_PIn:
# eventReadingType: 1
# offset: 0
# sensorID: 0x61
# sensorType: 8
/xyz/openbmc_project/sensors/power/PSU0_POut:
eventReadingType: 1
offset: 0
sensorID: 0x62
sensorType: 8
# /xyz/openbmc_project/sensors/power/PSU1_POut:
# eventReadingType: 1
# offset: 0
# sensorID: 0x63
# sensorType: 8
/xyz/openbmc_project/sensors/power/CPU0_Power_Avg:
eventReadingType: 1
offset: 0
sensorID: 0x65
sensorType: 8
/xyz/openbmc_project/sensors/power/CPU1_Power_Avg:
eventReadingType: 1
offset: 0
sensorID: 0x66
sensorType: 8
/xyz/openbmc_project/sensors/power/Dimm_Power_CPU0:
eventReadingType: 1
offset: 0
sensorID: 0x67
sensorType: 8
/xyz/openbmc_project/sensors/power/Dimm_Power_CPU1:
eventReadingType: 1
offset: 0
sensorID: 0x68
sensorType: 8
# /xyz/openbmc_project/inventory/system/board/Lux_Baseboard/PS_Redundant:
# eventReadingType: 0x0b
# offset: 0
# sensorID: 0x6A
# sensorType: 0x0b
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/Power_Button:
eventReadingType: 0x6f
offset: 0
sensorID: 0x6E
sensorType: 20
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DDR0_Power:
eventReadingType: 1
offset: 0
sensorID: 0x6F
sensorType: 8
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DDR1_Power:
eventReadingType: 1
offset: 0
sensorID: 0x70
sensorType: 8
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DDR2_Power:
eventReadingType: 1
offset: 0
sensorID: 0x71
sensorType: 8
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DDR3_Power:
eventReadingType: 1
offset: 0
sensorID: 0x72
sensorType: 8
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/PSU0_Supply:
eventReadingType: 0x6F
offset: 0
sensorID: 0x8E
sensorType: 8
# /xyz/openbmc_project/inventory/system/board/Lux_Baseboard/PSU1_Supply:
# eventReadingType: 0x6F
# offset: 0
# sensorID: 0x8F
# sensorType: 8
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_A_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0x90
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_B_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0x92
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_C_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0x94
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_D_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0x96
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_E_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0x98
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_F_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0x9A
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_G_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0x9C
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_H_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0x9E
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_I_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xA0
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_J_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xA2
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_K_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xA4
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU0_L_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xA6
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_A_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xB0
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_B_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xB2
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_C_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xB4
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_D_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xB6
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_E_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xB8
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_F_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xBA
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_G_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xBC
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_H_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xBE
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_I_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xC0
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_J_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xC2
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_K_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xC4
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/DIMM_CPU1_L_Status:
eventReadingType: 0x6F
offset: 0
sensorID: 0xC6
sensorType: 0x0C
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/CPU0_State:
eventReadingType: 0x6F
offset: 0
sensorID: 0xE4
sensorType: 0x07
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/CPU1_State:
eventReadingType: 0x6F
offset: 0
sensorID: 0xE5
sensorType: 0x07
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/PCIe_Status:
eventReadingType: 111
offset: 0
sensorID: 0xF3
sensorType: 0x13
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/BMC_Boot:
eventReadingType: 0x6F
offset: 0
sensorID: 0xFA
sensorType: 29
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/ACPI_State:
eventReadingType: 0x6F
offset: 0
sensorID: 0xFB
sensorType: 34
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/IPMI_Watchdog:
eventReadingType: 0x6F
offset: 0
sensorID: 0xFC
sensorType: 0x23
/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/Event_Log:
eventReadingType: 0x6F
offset: 0
sensorID: 0xFE
sensorType: 16
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,139 @@
From ead759007999573bf37d1ea01bf19ae76af79e01 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Wed, 20 Nov 2024 15:16:53 +0800
Subject: [PATCH] Support SOL non-volatile bitrate and volatile bitrate
---
console-dbus.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++----
meson.build | 2 +-
2 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/console-dbus.c b/console-dbus.c
index dd53908..e0c0011 100644
--- a/console-dbus.c
+++ b/console-dbus.c
@@ -19,6 +19,7 @@
#include <err.h>
#include <string.h>
#include <sys/socket.h>
+#include <stdlib.h>
#include "console-server.h"
@@ -53,7 +54,7 @@ static void tty_change_baudrate(struct console *console)
}
}
-static int set_baud_handler(sd_bus *bus, const char *path,
+static int set_non_volatile_baud_handler(sd_bus *bus, const char *path,
const char *interface, const char *property,
sd_bus_message *msg, void *userdata,
sd_bus_error *err __attribute__((unused)))
@@ -61,6 +62,8 @@ static int set_baud_handler(sd_bus *bus, const char *path,
struct console *console = userdata;
uint64_t baudrate;
speed_t speed;
+ char buf[64] = {0};
+ int encodedBitRate = 0;
int r;
if (!console) {
@@ -84,6 +87,63 @@ static int set_baud_handler(sd_bus *bus, const char *path,
sd_bus_emit_properties_changed(bus, path, interface, property, NULL);
+ switch(baudrate)
+ {
+ case 9600:
+ encodedBitRate = 0x06;
+ break;
+ case 19200:
+ encodedBitRate = 0x07;
+ break;
+ case 38400:
+ encodedBitRate = 0x08;
+ break;
+ case 57600:
+ encodedBitRate = 0x09;
+ break;
+ case 115200:
+ encodedBitRate = 0xa;
+ break;
+ default:
+ encodedBitRate = 0xa;
+ break;
+ }
+ snprintf(buf, sizeof(buf), "fw_setenv hostserialcfg %d", encodedBitRate);
+ system(buf);
+ system("/usr/bin/sol-configure.sh setup");
+ return 1;
+}
+
+static int set_volatile_baud_handler(sd_bus *bus, const char *path,
+ const char *interface, const char *property,
+ sd_bus_message *msg, void *userdata,
+ sd_bus_error *err __attribute__((unused)))
+{
+ struct console *console = userdata;
+ uint64_t baudrate;
+ speed_t speed;
+ int r;
+
+ if (!console) {
+ return -ENOENT;
+ }
+
+ r = sd_bus_message_read(msg, "t", &baudrate);
+ if (r < 0 || baudrate > UINT32_MAX) {
+ return -EINVAL;
+ }
+
+ speed = parse_int_to_baud((uint32_t)baudrate);
+ if (!speed) {
+ warnx("Invalid baud rate: '%" PRIu64 "'", baudrate);
+ return -EINVAL;
+ }
+
+ assert(console->tty.type == TTY_DEVICE_UART);
+ console->tty.uart.baud = speed;
+ tty_change_baudrate(console);
+
+ sd_bus_emit_properties_changed(bus, path, interface, property, NULL);
return 1;
}
@@ -142,10 +202,14 @@ static int method_connect(sd_bus_message *msg, void *userdata,
static const sd_bus_vtable console_uart_vtable[] = {
SD_BUS_VTABLE_START(0),
- SD_BUS_WRITABLE_PROPERTY("Baud", "t", get_baud_handler,
- set_baud_handler, 0,
- SD_BUS_VTABLE_UNPRIVILEGED |
- SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_WRITABLE_PROPERTY("NonVbitrate", "t", get_baud_handler,
+ set_non_volatile_baud_handler, 0,
+ SD_BUS_VTABLE_UNPRIVILEGED |
+ SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_WRITABLE_PROPERTY("Vbitrate", "t", get_baud_handler,
+ set_volatile_baud_handler, 0,
+ SD_BUS_VTABLE_UNPRIVILEGED |
+ SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_VTABLE_END,
};
diff --git a/meson.build b/meson.build
index 8a570a1..c4e8cf0 100644
--- a/meson.build
+++ b/meson.build
@@ -10,7 +10,7 @@ project('obmc-console', 'c',
meson_version: '>=0.63.0',
)
-add_project_arguments('-D_GNU_SOURCE', language: 'c')
+add_project_arguments('-D_GNU_SOURCE', '-Wno-unused-result', language: 'c')
systemdsystemunitdir = dependency('systemd').get_variable('systemdsystemunitdir')
install_data('conf/obmc-console@.service.in',
--
2.25.1
@@ -0,0 +1,54 @@
From a35a3427d49a618550d6c0b252270bbe51f858cd Mon Sep 17 00:00:00 2001
From: Jonathan Doman <jonathan.doman@intel.com>
Date: Fri, 5 May 2023 17:51:42 -0700
Subject: [PATCH] Use sol-configure.sh to configure UART routing
Change-Id: I7f4945a56565b30a4baa1e241905a055a9a0ada7
Signed-off-by: Jonathan Doman <jonathan.doman@intel.com>
Upstream-Status: Pending
---
socket-handler.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/socket-handler.c b/socket-handler.c
index 5f9d383..9c2a587 100644
--- a/socket-handler.c
+++ b/socket-handler.c
@@ -299,6 +299,16 @@ err_close:
return POLLER_REMOVE;
}
+static void init_routing()
+{
+ static bool init_done = false;
+ if (!init_done) {
+ if (system("/usr/bin/sol-configure.sh setup_routing") == 0) {
+ init_done = true;
+ }
+ }
+}
+
static enum poller_ret socket_poll(struct handler *handler, int events,
void __attribute__((unused)) * data)
{
@@ -316,6 +326,8 @@ static enum poller_ret socket_poll(struct handler *handler, int events,
return POLLER_OK;
}
+ init_routing();
+
client = malloc(sizeof(*client));
memset(client, 0, sizeof(*client));
@@ -395,6 +407,8 @@ int dbus_create_socket_consumer(struct console *console)
n = sh->n_clients++;
+ init_routing();
+
/*
* We're managing an array of pointers to aggregates, so don't warn about
* sizeof() on a pointer type.
--
2.25.1
@@ -0,0 +1,26 @@
From 7e181d361f54473c5a9f914f456933feb1e64126 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Mon, 2 Dec 2024 15:02:51 +0800
Subject: [PATCH] Sol support 921600 bitrate
---
console-dbus.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/console-dbus.c b/console-dbus.c
index e0c0011..f409a16 100644
--- a/console-dbus.c
+++ b/console-dbus.c
@@ -104,6 +104,9 @@ static int set_non_volatile_baud_handler(sd_bus *bus, const char *path,
case 115200:
encodedBitRate = 0xa;
break;
+ case 921600:
+ encodedBitRate = 0xb;
+ break;
default:
encodedBitRate = 0xa;
break;
--
2.25.1
@@ -0,0 +1,3 @@
[Service]
ExecStartPre=/usr/bin/sol-configure.sh setup
ExecStopPost=/usr/bin/sol-configure.sh teardown
@@ -0,0 +1,5 @@
# This will get overwritten by sol-configure.sh
baud = 921600
local-tty = ttyS3
local-tty-baud = 921600
console-id = default
@@ -0,0 +1,76 @@
#!/bin/sh
# Copyright 2017-2020 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
ROUTER=$(echo /sys/bus/platform/drivers/aspeed-uart-routing/*.uart-routing)
[ -L "$ROUTER" ] || exit 2
route() {
echo -n "$1" > "$ROUTER/$2"
echo -n "$2" > "$ROUTER/$1"
}
setup_routing() {
echo "Enabling UART routing"
route uart1 uart3
route uart4 io1
}
setup() {
hostserialcfg=$(fw_printenv hostserialcfg 2> /dev/null)
hostserialcfg=${hostserialcfg##*=}
if [ "$hostserialcfg" = 6 ]
then
baud=9600
elif [ "$hostserialcfg" = 7 ]
then
baud=19200
elif [ "$hostserialcfg" = 8 ]
then
baud=38400
elif [ "$hostserialcfg" = 9 ]
then
baud=57600
elif [ "$hostserialcfg" = 11 ]
then
baud=921600
else
baud=115200
fi
echo "Configuring host UART for $baud baud"
CONSOLE_CONF=/etc/obmc-console/server.ttyS2.conf
cat > $CONSOLE_CONF <<-EOF
# Autogenerated by $0
baud = $baud
local-tty = ttyS3
local-tty-baud = $baud
console-id = default
EOF
}
teardown() {
echo "Disabling UART routing"
route uart1 io1
route uart3 io3
route uart4 io4
}
$1
@@ -0,0 +1,27 @@
# Enable downstream autobump - this can be removed after upstream sync
# The URI is required for the autobump script but keep it commented
# to not override the upstream value
# SRC_URI = "git://github.com/openbmc/obmc-console;branch=master;protocol=https"
SRCREV = "dfda5afb4ff7c76c4df3ebebbf496fdbda0fbbae"
FILESEXTRAPATHS:append := ":${THISDIR}/${PN}"
OBMC_CONSOLE_HOST_TTY = "ttyS2"
SRC_URI += "file://sol-configure.sh \
file://pre-post-routing.conf \
file://server.ttyS2.conf \
file://0001-Use-sol-configure.sh-to-configure-UART-routing.patch \
file://0001-Support-SOL-non-volatile-bitrate-and-volatile-bitrat.patch \
file://0002-Sol-support-921600-bitrate.patch \
"
do_install:append() {
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/sol-configure.sh ${D}${bindir}
local drop_in=${D}${sysconfdir}/systemd/system/${PN}@${OBMC_CONSOLE_HOST_TTY}
local service_drop_in=${drop_in}.service.d
# Install service drop-in override to add UART routing and baud configuration
install -d $service_drop_in
install -m 0644 ${WORKDIR}/pre-post-routing.conf $service_drop_in
}
@@ -0,0 +1,17 @@
SUMMARY = "Event policy configuration for Bios Version Write"
PR = "r1"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
inherit allarch
inherit phosphor-dbus-monitor
FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:"
SRC_URI += "file://config.yaml"
do_install() {
install -D ${WORKDIR}/config.yaml ${D}${config_dir}/config.yaml
}
FILES:${PN} += "${config_dir}/config.yaml"
@@ -0,0 +1,36 @@
- name: biosversion group
class: group
group: path
members:
- meta: PATH
path: /xyz/openbmc_project/software/bios_active
- name: biosversion property
class: group
group: property
type: string
members:
- interface: xyz.openbmc_project.Software.Version
meta: PROPERTY
property: Version
- name: watch biosversion
class: watch
watch: property
paths: biosversion group
properties: biosversion property
callback: biosversion callback
ignore_start_callback: true
- name: biosversion callback
class: callback
callback: method
service: org.freedesktop.systemd1
path: /org/freedesktop/systemd1
interface: org.freedesktop.systemd1.Manager
method: StartUnit
args:
- value: write-bios-version.service
type: string
- value: replace
type: string
@@ -0,0 +1,23 @@
From 7a64e990e43fab501b288fbe961a1a17410b193a Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Wed, 13 Nov 2024 11:06:43 +0800
Subject: [PATCH] Add FBCPLD Type for software manager
---
yaml/xyz/openbmc_project/Software/Version.interface.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/yaml/xyz/openbmc_project/Software/Version.interface.yaml b/yaml/xyz/openbmc_project/Software/Version.interface.yaml
index 3826af0..ec663c7 100644
--- a/yaml/xyz/openbmc_project/Software/Version.interface.yaml
+++ b/yaml/xyz/openbmc_project/Software/Version.interface.yaml
@@ -45,3 +45,6 @@ enumerations:
- name: CPLD
description: >
The version is a version for a CPLD.
+ - name: FBCPLD
+ description: >
+ The version is a version for a Fan Board CPLD.
--
2.25.1
@@ -0,0 +1,30 @@
From 655a0fabe1190c98bd75e7fa990c206ffb529286 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Wed, 20 Nov 2024 15:18:22 +0800
Subject: [PATCH] Add NonVbitrate and Vbitrate property for UART interface
---
yaml/xyz/openbmc_project/Console/UART.interface.yaml | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/yaml/xyz/openbmc_project/Console/UART.interface.yaml b/yaml/xyz/openbmc_project/Console/UART.interface.yaml
index e30c443..e6b9b91 100644
--- a/yaml/xyz/openbmc_project/Console/UART.interface.yaml
+++ b/yaml/xyz/openbmc_project/Console/UART.interface.yaml
@@ -4,3 +4,13 @@ properties:
- name: Baud
type: uint64
description: Data transmission rate of the serial console.
+ - name: NonVbitrate
+ type: uint64
+ default: 115200
+ description: >
+ Non volatile SOL bandrate.
+ - name: Vbitrate
+ type: uint64
+ default: 115200
+ description: >
+ Volatile SOL bandrate.
--
2.25.1
@@ -0,0 +1,76 @@
From 32127e9d8729268432dabbcafdcbb31af6d7c6ba Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Thu, 14 Nov 2024 19:14:11 +0800
Subject: [PATCH] Add ReleaseDate property for Software interface
---
.../Software/ReleaseDate/meson.build | 15 +++++++++++++++
gen/xyz/openbmc_project/Software/meson.build | 15 +++++++++++++++
.../Software/ReleaseDate.interface.yaml | 7 +++++++
3 files changed, 37 insertions(+)
create mode 100644 gen/xyz/openbmc_project/Software/ReleaseDate/meson.build
create mode 100644 yaml/xyz/openbmc_project/Software/ReleaseDate.interface.yaml
diff --git a/gen/xyz/openbmc_project/Software/ReleaseDate/meson.build b/gen/xyz/openbmc_project/Software/ReleaseDate/meson.build
new file mode 100644
index 0000000..44f9568
--- /dev/null
+++ b/gen/xyz/openbmc_project/Software/ReleaseDate/meson.build
@@ -0,0 +1,15 @@
+# Generated file; do not modify.
+generated_sources += custom_target(
+ 'xyz/openbmc_project/Software/ReleaseDate__cpp'.underscorify(),
+ input: [ '../../../../../yaml/xyz/openbmc_project/Software/ReleaseDate.interface.yaml', ],
+ output: [ 'common.hpp', 'server.cpp', 'server.hpp', 'client.hpp', ],
+ depend_files: sdbusplusplus_depfiles,
+ command: [
+ sdbuspp_gen_meson_prog, '--command', 'cpp',
+ '--output', meson.current_build_dir(),
+ '--tool', sdbusplusplus_prog,
+ '--directory', meson.current_source_dir() / '../../../../../yaml',
+ 'xyz/openbmc_project/Software/ReleaseDate',
+ ],
+)
+
diff --git a/gen/xyz/openbmc_project/Software/meson.build b/gen/xyz/openbmc_project/Software/meson.build
index ace2bcb..84424b4 100644
--- a/gen/xyz/openbmc_project/Software/meson.build
+++ b/gen/xyz/openbmc_project/Software/meson.build
@@ -89,6 +89,21 @@ generated_others += custom_target(
],
)
+subdir('ReleaseDate')
+generated_others += custom_target(
+ 'xyz/openbmc_project/Software/ReleaseDate__markdown'.underscorify(),
+ input: [ '../../../../yaml/xyz/openbmc_project/Software/ReleaseDate.interface.yaml', ],
+ output: [ 'ReleaseDate.md' ],
+ depend_files: sdbusplusplus_depfiles,
+ command: [
+ sdbuspp_gen_meson_prog, '--command', 'markdown',
+ '--output', meson.current_build_dir(),
+ '--tool', sdbusplusplus_prog,
+ '--directory', meson.current_source_dir() / '../../../../yaml',
+ 'xyz/openbmc_project/Software/ReleaseDate',
+ ],
+)
+
subdir('RedundancyPriority')
generated_others += custom_target(
'xyz/openbmc_project/Software/RedundancyPriority__markdown'.underscorify(),
diff --git a/yaml/xyz/openbmc_project/Software/ReleaseDate.interface.yaml b/yaml/xyz/openbmc_project/Software/ReleaseDate.interface.yaml
new file mode 100644
index 0000000..e0dded4
--- /dev/null
+++ b/yaml/xyz/openbmc_project/Software/ReleaseDate.interface.yaml
@@ -0,0 +1,7 @@
+description: >
+ An ReleaseDate string for a xyz.openbmc_project.Software.Version.
+properties:
+ - name: ReleaseDate
+ type: string
+ description: >
+ Firmware Release Date.
--
2.25.1
@@ -0,0 +1,145 @@
From 7b1bd6c2b0c605c2cfbfaf9e3a81f4e8c57dfee6 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Fri, 27 Dec 2024 18:28:28 +0800
Subject: [PATCH] Add applyoption and updatetarget interface
---
.../Software/UpdateTarget/meson.build | 15 ++++++++++
gen/xyz/openbmc_project/Software/meson.build | 15 ++++++++++
.../Software/Activation.interface.yaml | 4 +++
.../Software/ApplyOptions.interface.yaml | 28 ++++++++++++++-----
.../Software/UpdateTarget.interface.yaml | 17 +++++++++++
5 files changed, 72 insertions(+), 7 deletions(-)
create mode 100755 gen/xyz/openbmc_project/Software/UpdateTarget/meson.build
create mode 100755 yaml/xyz/openbmc_project/Software/UpdateTarget.interface.yaml
diff --git a/gen/xyz/openbmc_project/Software/UpdateTarget/meson.build b/gen/xyz/openbmc_project/Software/UpdateTarget/meson.build
new file mode 100755
index 0000000..c250c86
--- /dev/null
+++ b/gen/xyz/openbmc_project/Software/UpdateTarget/meson.build
@@ -0,0 +1,15 @@
+# Generated file; do not modify.
+generated_sources += custom_target(
+ 'xyz/openbmc_project/Software/UpdateTarget__cpp'.underscorify(),
+ input: [ '../../../../../yaml/xyz/openbmc_project/Software/UpdateTarget.interface.yaml', ],
+ output: [ 'common.hpp', 'server.cpp', 'server.hpp', 'client.hpp', ],
+ depend_files: sdbusplusplus_depfiles,
+ command: [
+ sdbuspp_gen_meson_prog, '--command', 'cpp',
+ '--output', meson.current_build_dir(),
+ '--tool', sdbusplusplus_prog,
+ '--directory', meson.current_source_dir() / '../../../../../yaml',
+ 'xyz/openbmc_project/Software/UpdateTarget',
+ ],
+)
+
diff --git a/gen/xyz/openbmc_project/Software/meson.build b/gen/xyz/openbmc_project/Software/meson.build
index 84424b4..b90d1f8 100644
--- a/gen/xyz/openbmc_project/Software/meson.build
+++ b/gen/xyz/openbmc_project/Software/meson.build
@@ -149,6 +149,21 @@ generated_others += custom_target(
],
)
+subdir('UpdateTarget')
+generated_others += custom_target(
+ 'xyz/openbmc_project/Software/UpdateTarget__markdown'.underscorify(),
+ input: [ '../../../../yaml/xyz/openbmc_project/Software/UpdateTarget.interface.yaml', ],
+ output: [ 'UpdateTarget.md' ],
+ depend_files: sdbusplusplus_depfiles,
+ command: [
+ sdbuspp_gen_meson_prog, '--command', 'markdown',
+ '--output', meson.current_build_dir(),
+ '--tool', sdbusplusplus_prog,
+ '--directory', meson.current_source_dir() / '../../../../yaml',
+ 'xyz/openbmc_project/Software/UpdateTarget',
+ ],
+)
+
subdir('Version')
generated_others += custom_target(
'xyz/openbmc_project/Software/Version__markdown'.underscorify(),
diff --git a/yaml/xyz/openbmc_project/Software/Activation.interface.yaml b/yaml/xyz/openbmc_project/Software/Activation.interface.yaml
index aba2a62..19c64f4 100644
--- a/yaml/xyz/openbmc_project/Software/Activation.interface.yaml
+++ b/yaml/xyz/openbmc_project/Software/Activation.interface.yaml
@@ -42,6 +42,10 @@ enumerations:
description: >
The Software.Version is currently being staged into the staging
flash area.
+ - name: AddQueue
+ description: >
+ The Software.Version is currently being added to the upgrade
+ queue and is waiting for powercycle to trigger the upgrade.
- name: RequestedActivations
description: >
The possible RequestedActivation states of a Software.Version.
diff --git a/yaml/xyz/openbmc_project/Software/ApplyOptions.interface.yaml b/yaml/xyz/openbmc_project/Software/ApplyOptions.interface.yaml
index 4d5a447..3a95d8d 100644
--- a/yaml/xyz/openbmc_project/Software/ApplyOptions.interface.yaml
+++ b/yaml/xyz/openbmc_project/Software/ApplyOptions.interface.yaml
@@ -4,14 +4,28 @@ description: >
used during firmware activation. ApplyOptions usage during firmware
activation is implementation specific, not all firmware targets need
ApplyOptions. This property is removed after activation of the firmware is
- done and when the firmware goes to Active state. The default value of this
- property is false.
+ done and when the firmware goes to Active state.
properties:
- name: ClearConfig
- type: boolean
- default: false
+ type: enum[self.ConfigManagement]
description: >
This property indicates whether to clear the software configurations
- when the firmware image update is getting applied. A value of true
- indicates the firmware configurations should be cleared along with
- firmware image activation.
+ when the firmware image update is getting applied.
+enumerations:
+ - name: ConfigManagement
+ description: >
+ An enumeration of possible purposes of the config management in
+ upgrade.
+ values:
+ - name: Keep
+ description: >
+ Keep config in upgrade.
+ - name: Clear
+ description: >
+ Clear config in upgrade.
+ - name: PartialKeep
+ description: >
+ Partial keep config in upgrade.
+ - name: FactoryReset
+ description: >
+ Factory reset config in upgrade.
\ No newline at end of file
diff --git a/yaml/xyz/openbmc_project/Software/UpdateTarget.interface.yaml b/yaml/xyz/openbmc_project/Software/UpdateTarget.interface.yaml
new file mode 100755
index 0000000..ae3366b
--- /dev/null
+++ b/yaml/xyz/openbmc_project/Software/UpdateTarget.interface.yaml
@@ -0,0 +1,17 @@
+description: >
+ Provide the setting of target slot(s) to be updated.
+
+properties:
+ - name: UpdateTargetSlot
+ type: enum[self.TargetSlot]
+ description: >
+ Indicate which slot(s) to update when an image is to be updated.
+
+enumerations:
+ - name: TargetSlot
+ description: >
+ The target slot(s) for code update.
+ values:
+ - name: Primary
+ - name: Secondary
+ - name: Both
\ No newline at end of file
--
2.25.1
@@ -0,0 +1,24 @@
From 9f6af2701407c166c87a328a2f2335546f3de078 Mon Sep 17 00:00:00 2001
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
Date: Sun, 5 Jan 2025 16:39:13 +0800
Subject: [PATCH 2/2] Set PowerSupplyRedundancyEnabled to false by default
---
.../openbmc_project/Control/PowerSupplyRedundancy.interface.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/yaml/xyz/openbmc_project/Control/PowerSupplyRedundancy.interface.yaml b/yaml/xyz/openbmc_project/Control/PowerSupplyRedundancy.interface.yaml
index 432b2c2..baec4f5 100644
--- a/yaml/xyz/openbmc_project/Control/PowerSupplyRedundancy.interface.yaml
+++ b/yaml/xyz/openbmc_project/Control/PowerSupplyRedundancy.interface.yaml
@@ -7,6 +7,7 @@ properties:
- const
description: >
When true, the power supplies are redundant.
+ default: false
- name: RotationEnabled
type: boolean
description: >
--
2.25.1
@@ -0,0 +1,58 @@
From ef1b0370f33a69ef2e61635ba82ef23228c8fb1f Mon Sep 17 00:00:00 2001
From: Ren Yu <yux.ren@intel.com>
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 <yux.ren@intel.com>
Upstream-Status: Pending
---
.../State/Watchdog.interface.yaml | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/yaml/xyz/openbmc_project/State/Watchdog.interface.yaml b/yaml/xyz/openbmc_project/State/Watchdog.interface.yaml
index 556dca1..dbca599 100644
--- a/yaml/xyz/openbmc_project/State/Watchdog.interface.yaml
+++ b/yaml/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.25.1
@@ -0,0 +1,40 @@
From 3f28ab9d280104a03a83d784a73ec74ec6a72782 Mon Sep 17 00:00:00 2001
From: Ren Yu <yux.ren@intel.com>
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 <yux.ren@intel.com>
Upstream-Status: Pending
---
yaml/xyz/openbmc_project/State/Watchdog.interface.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/yaml/xyz/openbmc_project/State/Watchdog.interface.yaml b/yaml/xyz/openbmc_project/State/Watchdog.interface.yaml
index 30d75f0..1b06363 100644
--- a/yaml/xyz/openbmc_project/State/Watchdog.interface.yaml
+++ b/yaml/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.25.1
@@ -0,0 +1,17 @@
# The URI is required for the autobump script but keep it commented
# to not override the upstream value
# SRC_URI = "git://github.com/openbmc/phosphor-dbus-interfaces.git;branch=master;protocol=https"
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI += " \
file://0024-Add-the-pre-timeout-interrupt-defined-in-IPMI-spec.patch \
file://0025-Add-PreInterruptFlag-properity-in-DBUS.patch \
file://0001-Add-FBCPLD-Type-for-software-manager.patch \
file://0001-Add-ReleaseDate-property-for-Software-interface.patch \
file://0001-Add-NonVbitrate-and-Vbitrate-property-for-UART-inter.patch \
file://0001-Add-applyoption-and-updatetarget-interface.patch \
file://0002-Set-PowerSupplyRedundancyEnabled-to-false-by-default.patch \
"
@@ -0,0 +1,3 @@
PHOSPHOR_DBUS_MONITOR_CONFIGS:append = " \
bios-version-monitor \
"
@@ -0,0 +1,25 @@
SUMMARY = "Write Bios Version to File"
DESCRIPTION = "Write Bios Version to File"
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
PR = "r1"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
SRC_URI = "\
file://write-bios-version.sh \
file://${BPN}.service \
"
inherit allarch
inherit obmc-phosphor-systemd
RDEPENDS:${PN} += "bash"
SYSTEMD_SERVICE:${PN} += "${PN}.service"
do_install() {
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/write-bios-version.sh ${D}${bindir}
}
@@ -0,0 +1,10 @@
[Unit]
Description=Write Bios Version to File
Wants=phosphor-ipmi-host.service
After=phosphor-ipmi-host.service
[Service]
Type=oneshot
Restart=no
ExecStart=/usr/bin/write-bios-version.sh
@@ -0,0 +1,39 @@
#!/bin/bash
bus=14
address=0x53
offset=0x08
biosversion=$(busctl get-property xyz.openbmc_project.Software.BMC.Updater /xyz/openbmc_project/software/bios_active xyz.openbmc_project.Software.Version Version)
ret=$?
if [ $ret != 0 ]; then
echo "Failed to get BIOS version from dbus"
exit 1
fi
biosversion=$(echo "$biosversion" |cut -d "\"" -f2)
echo "BIOS version got from dbus:$biosversion"
if [ "$biosversion" == "null" ]; then
echo "BIOS version is null, skip"
else
tmp=$(i2ctransfer -y -f $bus w2@$address $offset 0x00 r32)
for str in $tmp;do
if [[ $str != 0x00 ]]; then
str=$(printf "%d" "$str")
version=$(echo "$str" | awk '{printf("%c", $str)}')
version_str="$version_str$version"
fi
done
echo "BIOS version got from epprom:$version_str"
if [ "$biosversion" != "$version_str" ]; then
for ((j=0;j < 32;j++));do
hexArr[$j]=0
done
for ((i=0;i < 14;i++));do
ver=${biosversion:$i:1}
hexArr[$i]=$(printf "%d" "'$ver")
done
i2ctransfer -y -f $bus w34@$address $offset 0x00 "${hexArr[@]}"
echo "Write BIOS version to epprom:${biosversion}"
else
echo "BIOS version same, skip writing BIOS version"
fi
fi
@@ -0,0 +1,30 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
LICENSE = "CLOSED"
SRC_URI += " \
file://dimmSpdReader.cpp \
file://dimmSpdReader.hpp \
file://dimmSpdReaderMain.cpp \
file://i3cdev.h \
file://meson.build \
file://xyz.openbmc_project.dimmspdreader.service \
"
S = "${WORKDIR}"
inherit pkgconfig meson systemd
DEPENDS = " \
boost \
libgpiod \
nlohmann-json \
phosphor-logging \
sdbusplus \
"
SYSTEMD_PACKAGES = "${PN}"
SYSTEMD_SERVICE:${PN} = "xyz.openbmc_project.dimmspdreader.service"
do_install:append() {
install -d ${D}${systemd_unitdir}/system/
install -m 0644 ${WORKDIR}/xyz.openbmc_project.dimmspdreader.service ${D}${systemd_unitdir}/system
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,96 @@
#pragma once
#include <boost/asio/steady_timer.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/container/flat_map.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/bus/match.hpp>
#include <string>
#include <iostream>
#define MAX_CPU_ID 2
#define MAX_DIMM_RANK 12
#define STATUS_TEMP_NUM 3
#define STATUS_PMIC_RAIL_NUM 6
#define STATUS_REG_NUM 8
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_temp_inf;
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_voltage_inf;
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_current_inf;
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_power_inf;
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_statusReg_inf;
enum FieldType {
VOLTAGE,
CURRENT,
POWER,
TEMP,
STATUS
};
struct DimmData
{
uint8_t reg[STATUS_REG_NUM];
double voltage[STATUS_PMIC_RAIL_NUM];
double current[STATUS_PMIC_RAIL_NUM];
double power[STATUS_PMIC_RAIL_NUM];
double temp[STATUS_TEMP_NUM];
};
struct DimmI3CAddr
{
std::string spdAddr;
std::string pmicAddr;
};
enum PMICType {
PMIC5000 = 0,
PMIC5010,
PMIC5100,
PMIC5020,
PMIC5120,
PMIC5200,
PMIC5030
};
struct DIMMSpdReader : std::enable_shared_from_this<DIMMSpdReader>
{
DIMMSpdReader(boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
const float pollRate) : sensorPollMs(static_cast<unsigned int>(pollRate * 1000)),
objectServer(objectServer), waitTimer(io) {};
~DIMMSpdReader()
{
waitTimer.cancel();
};
void init();
void startRead();
void readDimmInfo();
int getDIMMRegsTemp(uint8_t cpuid, uint8_t rank, DimmData& dimmData);
int getDIMMRegsVol(uint8_t cpuid, uint8_t rank, DimmData& dimmData);
int getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& dimmData);
void updateDbus();
void updateToDimmInfoFile();
void setupMatches(sdbusplus::bus_t&);
void dimmI3cSwitchMatcher( std::vector<sdbusplus::bus::match_t>& matches,
sdbusplus::bus_t& connection, std::function<void(bool)>&& onMatch);
void getdimmI3cSwitchState(const std::shared_ptr<sdbusplus::asio::connection>& conn, size_t retries = 2);
int getPmicType(uint8_t cpuid, uint8_t rank);
int getPmicStatusRegs(uint8_t cpuid, uint8_t rank, DimmData& dimmData);
private:
std::vector<sdbusplus::bus::match_t> matches;
unsigned int sensorPollMs;
sdbusplus::asio::object_server& objectServer;
boost::asio::steady_timer waitTimer;
PMICType pmicType[MAX_CPU_ID][MAX_DIMM_RANK];
bool gotType[MAX_CPU_ID][MAX_DIMM_RANK];
bool twoByteMode[MAX_CPU_ID][MAX_DIMM_RANK];
int adcDelay[MAX_CPU_ID][MAX_DIMM_RANK];
uint16_t regCounter;
uint16_t pmicCounter;
};
@@ -0,0 +1,190 @@
/*
// Copyright (c) 2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
// #include <math.h>
#include <dimmSpdReader.hpp>
#include <chrono>
#include <functional>
#include <iostream>
#include <limits>
#include <memory>
#include <numeric>
#include <string>
#include <vector>
#include <unordered_map>
std::vector<std::string> dimm_table = {
{"DIMM_CPU0_A"},
{"DIMM_CPU0_B"},
{"DIMM_CPU0_C"},
{"DIMM_CPU0_D"},
{"DIMM_CPU0_E"},
{"DIMM_CPU0_F"},
{"DIMM_CPU0_G"},
{"DIMM_CPU0_H"},
{"DIMM_CPU0_I"},
{"DIMM_CPU0_J"},
{"DIMM_CPU0_K"},
{"DIMM_CPU0_L"},
{"DIMM_CPU1_A"},
{"DIMM_CPU1_B"},
{"DIMM_CPU1_C"},
{"DIMM_CPU1_D"},
{"DIMM_CPU1_E"},
{"DIMM_CPU1_F"},
{"DIMM_CPU1_G"},
{"DIMM_CPU1_H"},
{"DIMM_CPU1_I"},
{"DIMM_CPU1_J"},
{"DIMM_CPU1_K"},
{"DIMM_CPU1_L"}
};
std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_temp_inf;
std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_voltage_inf;
std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_current_inf;
std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_power_inf;
std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_statusReg_inf;
int main()
{
boost::asio::io_context io;
auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
sdbusplus::asio::object_server objectServer(systemBus, true);
std::string unit;
objectServer.add_manager("/xyz/openbmc_project/dimm");
systemBus->request_name("xyz.openbmc_project.DimmSpdReader");
for(auto& dimm : dimm_table) {
std::string interfacePath = "/xyz/openbmc_project/dimm/" + dimm;
dimm_temp_inf[dimm] = objectServer.add_interface(interfacePath,
"xyz.openbmc_project.Dimm.Temperature");
dimm_temp_inf[dimm]->register_property(
"TS0", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_temp_inf[dimm]->register_property(
"TS1", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_temp_inf[dimm]->register_property(
"SPD_TS", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
unit = "DegreesC";
dimm_temp_inf[dimm]->register_property("Unit", unit);
dimm_temp_inf[dimm]->initialize();
dimm_voltage_inf[dimm] = objectServer.add_interface(interfacePath,
"xyz.openbmc_project.Dimm.Voltage");
dimm_voltage_inf[dimm]->register_property(
"SWA", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_voltage_inf[dimm]->register_property(
"SWB", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_voltage_inf[dimm]->register_property(
"SWC", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_voltage_inf[dimm]->register_property(
"SWD", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_voltage_inf[dimm]->register_property(
"SWE", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_voltage_inf[dimm]->register_property(
"SWF", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
unit = "Volts";
dimm_voltage_inf[dimm]->register_property("Unit", unit);
dimm_voltage_inf[dimm]->initialize();
dimm_current_inf[dimm] = objectServer.add_interface(interfacePath,
"xyz.openbmc_project.Dimm.Current");
dimm_current_inf[dimm]->register_property(
"SWA", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_current_inf[dimm]->register_property(
"SWB", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_current_inf[dimm]->register_property(
"SWC", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_current_inf[dimm]->register_property(
"SWD", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_current_inf[dimm]->register_property(
"SWE", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_current_inf[dimm]->register_property(
"SWF", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
unit = "Amperes";
dimm_current_inf[dimm]->register_property("Unit", unit);
dimm_current_inf[dimm]->initialize();
dimm_power_inf[dimm] = objectServer.add_interface(interfacePath,
"xyz.openbmc_project.Dimm.Power");
dimm_power_inf[dimm]->register_property(
"SWA", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_power_inf[dimm]->register_property(
"SWB", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_power_inf[dimm]->register_property(
"SWC", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_power_inf[dimm]->register_property(
"SWD", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_power_inf[dimm]->register_property(
"SWE", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
dimm_power_inf[dimm]->register_property(
"SWF", std::numeric_limits<double>::quiet_NaN(),
sdbusplus::asio::PropertyPermission::readWrite);
unit = "Watts";
dimm_power_inf[dimm]->register_property("Unit", unit);
dimm_power_inf[dimm]->initialize();
dimm_statusReg_inf[dimm] = objectServer.add_interface(interfacePath,
"xyz.openbmc_project.Dimm.StatusReg");
dimm_statusReg_inf[dimm]->register_property(
"0x04", uint8_t(0), sdbusplus::asio::PropertyPermission::readWrite);
dimm_statusReg_inf[dimm]->register_property(
"0x05", uint8_t(0), sdbusplus::asio::PropertyPermission::readWrite);
dimm_statusReg_inf[dimm]->register_property(
"0x06", uint8_t(0), sdbusplus::asio::PropertyPermission::readWrite);
dimm_statusReg_inf[dimm]->register_property(
"0x07", uint8_t(0), sdbusplus::asio::PropertyPermission::readWrite);
dimm_statusReg_inf[dimm]->register_property(
"0x08", uint8_t(0), sdbusplus::asio::PropertyPermission::readWrite);
dimm_statusReg_inf[dimm]->register_property(
"0x09", uint8_t(0), sdbusplus::asio::PropertyPermission::readWrite);
dimm_statusReg_inf[dimm]->register_property(
"0x0a", uint8_t(0), sdbusplus::asio::PropertyPermission::readWrite);
dimm_statusReg_inf[dimm]->register_property(
"0x0b", uint8_t(0), sdbusplus::asio::PropertyPermission::readWrite);
dimm_statusReg_inf[dimm]->initialize();
}
double pollRate = 0.1;
auto reader = std::make_shared<DIMMSpdReader>(io, objectServer, pollRate);
reader->init();
reader->getdimmI3cSwitchState(systemBus);
reader->setupMatches(static_cast<sdbusplus::bus_t&>(*systemBus));
io.run();
}
@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2019 Synopsys, Inc. and/or its affiliates.
*
* Author: Vitor Soares <vitor.soares@synopsys.com>
*/
#ifndef _UAPI_I3C_DEV_H_
#define _UAPI_I3C_DEV_H_
#include <linux/types.h>
#include <linux/ioctl.h>
#define VERSION "0.1"
/* IOCTL commands */
#define I3C_DEV_IOC_MAGIC 0x07
/**
* struct i3c_ioc_priv_xfer - I3C SDR ioctl private transfer
* @data: Holds pointer to userspace buffer with transmit data.
* @len: Length of data buffer buffers, in bytes.
* @rnw: encodes the transfer direction. true for a read, false for a write
*/
struct i3c_ioc_priv_xfer {
__u64 data;
__u16 len;
__u8 rnw;
__u8 pad[5];
};
#define I3C_PRIV_XFER_SIZE(N) \
((((sizeof(struct i3c_ioc_priv_xfer)) * (N)) < (1 << _IOC_SIZEBITS)) \
? ((sizeof(struct i3c_ioc_priv_xfer)) * (N)) : 0)
#define I3C_IOC_PRIV_XFER(N) \
_IOC(_IOC_READ|_IOC_WRITE, I3C_DEV_IOC_MAGIC, 30, I3C_PRIV_XFER_SIZE(N))
#endif
@@ -0,0 +1,76 @@
project(
'dimmSpdReader',
'cpp',
default_options: [
'warning_level=3',
'werror=true',
'cpp_std=c++20'
],
license: 'Apache-2.0',
version: '0.1',
meson_version: '>=0.58.0',
)
add_project_arguments(
'-Wno-psabi',
'-Wuninitialized',
'-DBOOST_SYSTEM_NO_DEPRECATED',
'-DBOOST_ASIO_NO_DEPRECATED',
'-DBOOST_ERROR_CODE_HEADER_ONLY',
'-DBOOST_NO_RTTI',
'-DBOOST_NO_TYPEID',
'-DBOOST_ALL_NO_LIB',
'-DBOOST_ASIO_DISABLE_THREADS',
'-DBOOST_ALLOW_DEPRECATED_HEADERS',
'-DBOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT',
language: 'cpp',
)
cpp = meson.get_compiler('cpp')
gpiodcxx = dependency('libgpiodcxx',
default_options: ['bindings=cxx'],
)
sdbusplus = dependency('sdbusplus', required : true, include_type: 'system')
if not sdbusplus.found()
sdbusplus_proj = subproject('sdbusplus', required: true)
sdbusplus = sdbusplus_proj.get_variable('sdbusplus_dep')
sdbusplus = sdbusplus.as_system('system')
endif
phosphor_logging_dep = dependency('phosphor-logging')
if cpp.has_header('nlohmann/json.hpp')
nlohmann_json = declare_dependency()
else
nlohmann_json = dependency('nlohmann_json')
endif
systemd = dependency('systemd')
boost = dependency('boost',version : '>=1.79.0', required : false, include_type: 'system')
if not boost.found()
subproject('boost', required: false)
boost_inc = include_directories('subprojects/boost_1_79_0/', is_system:true)
boost = declare_dependency(include_directories : boost_inc)
boost = boost.as_system('system')
endif
default_deps = [
boost,
nlohmann_json,
phosphor_logging_dep,
sdbusplus,
gpiodcxx,
]
executable(
'dimmspdreader',
'dimmSpdReader.cpp',
'dimmSpdReaderMain.cpp',
dependencies: [
default_deps,
],
install: true,
)
@@ -0,0 +1,13 @@
[Unit]
Description=DIMM SPD Reader
StopWhenUnneeded=false
Requires=xyz.openbmc_project.EntityManager.service
After=xyz.openbmc_project.EntityManager.service xyz.openbmc_project.Host.Misc.Manager.service
[Service]
Restart=always
RestartSec=5
ExecStart=/usr/bin/dimmspdreader
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,234 @@
From b9106871dcc7cfe174c61ca8a6b2e3013d1720c6 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Thu, 14 Nov 2024 19:18:00 +0800
Subject: [PATCH] Add ReleaseDate for Software interface
---
image_manager.cpp | 5 ++++-
item_updater.cpp | 25 ++++++++++++++++++++-----
meson.build | 1 +
version.cpp | 24 ++++++++++++++++++++++++
version.hpp | 18 +++++++++++++++++-
5 files changed, 66 insertions(+), 7 deletions(-)
diff --git a/image_manager.cpp b/image_manager.cpp
index baa0571..75cd541 100644
--- a/image_manager.cpp
+++ b/image_manager.cpp
@@ -191,6 +191,9 @@ int Manager::processImage(const std::string& tarFilePath)
std::string extendedVersion = Version::getValue(manifestPath.string(),
"ExtendedVersion");
+ // Get ReleaseDate
+ std::string releaseDate = Version::getBMCReleaseDate(OS_RELEASE_FILE);
+
// Get CompatibleNames
std::vector<std::string> compatibleNames =
Version::getRepeatedValues(manifestPath.string(), "CompatibleName");
@@ -219,7 +222,7 @@ int Manager::processImage(const std::string& tarFilePath)
// Create Version object
auto versionPtr = std::make_unique<Version>(
- bus, objPath, version, purpose, extendedVersion,
+ bus, objPath, version, purpose, extendedVersion, releaseDate,
imageDirPath.string(), compatibleNames,
std::bind(&Manager::erase, this, std::placeholders::_1), id);
versionPtr->deleteObject =
diff --git a/item_updater.cpp b/item_updater.cpp
index d8348e3..36bf5b3 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -48,6 +48,7 @@ void ItemUpdater::createActivation(sdbusplus::message_t& msg)
sdbusplus::message::object_path objPath;
auto purpose = VersionPurpose::Unknown;
std::string extendedVersion;
+ std::string releaseDate;
std::string version;
std::map<std::string,
std::map<std::string,
@@ -109,6 +110,16 @@ void ItemUpdater::createActivation(sdbusplus::message_t& msg)
}
}
}
+ else if (intf.first == RELEASE_DATE_IFACE)
+ {
+ for (const auto& property : intf.second)
+ {
+ if (property.first == "ReleaseDate")
+ {
+ releaseDate = std::get<std::string>(property.second);
+ }
+ }
+ }
else if (intf.first == COMPATIBLE_IFACE)
{
for (const auto& property : intf.second)
@@ -159,7 +170,7 @@ void ItemUpdater::createActivation(sdbusplus::message_t& msg)
}
auto versionPtr = std::make_unique<VersionClass>(
- bus, path, version, purpose, extendedVersion, filePath,
+ bus, path, version, purpose, extendedVersion, releaseDate, filePath,
compatibleNames,
std::bind(&ItemUpdater::erase, this, std::placeholders::_1),
versionId);
@@ -278,6 +289,10 @@ void ItemUpdater::processBMCImage()
// Read os-release from /etc/ to get the BMC extended version
std::string extendedVersion =
VersionClass::getBMCExtendedVersion(osRelease);
+
+ // Read os-release from /etc/ to get the BMC release date
+ std::string releaseDate =
+ VersionClass::getBMCReleaseDate(osRelease);
auto path = fs::path(SOFTWARE_OBJPATH) / id;
@@ -307,7 +322,7 @@ void ItemUpdater::processBMCImage()
// Create Version instance for this version.
auto versionPtr = std::make_unique<VersionClass>(
- bus, path, version, purpose, extendedVersion, flashId,
+ bus, path, version, purpose, extendedVersion, releaseDate, flashId,
std::vector<std::string>(),
std::bind(&ItemUpdater::erase, this, std::placeholders::_1),
id);
@@ -876,7 +891,7 @@ void ItemUpdater::createBIOSObject()
// Do nothing;
};
biosVersion = std::make_unique<VersionClass>(
- bus, path, version, VersionPurpose::Host, "", "",
+ bus, path, version, VersionPurpose::Host, "", "", "",
std::vector<std::string>(),
std::bind(dummyErase, std::placeholders::_1), "");
biosVersion->deleteObject =
@@ -910,7 +925,7 @@ void ItemUpdater::createCPLDObject()
// Do nothing;
};
cpldVersion = std::make_unique<VersionClass>(
- bus, path, version, VersionPurpose::CPLD, "", "",
+ bus, path, version, VersionPurpose::CPLD, "", "", "",
std::vector<std::string>(),
std::bind(dummyErase, std::placeholders::_1), "");
cpldVersion->deleteObject =
@@ -944,7 +959,7 @@ void ItemUpdater::createFBCPLDObject()
// Do nothing;
};
FBcpldVersion = std::make_unique<VersionClass>(
- bus, path, version, VersionPurpose::FBCPLD, "", "",
+ bus, path, version, VersionPurpose::FBCPLD, "", "", "",
std::vector<std::string>(),
std::bind(dummyErase, std::placeholders::_1), "");
cpldVersion->deleteObject =
diff --git a/meson.build b/meson.build
index 009dcef..68f1f91 100644
--- a/meson.build
+++ b/meson.build
@@ -40,6 +40,7 @@ conf.set_quoted('SYSTEMD_INTERFACE', 'org.freedesktop.systemd1.Manager')
conf.set_quoted('VERSION_BUSNAME', 'xyz.openbmc_project.Software.Version')
conf.set_quoted('VERSION_IFACE', 'xyz.openbmc_project.Software.Version')
conf.set_quoted('EXTENDED_VERSION_IFACE', 'xyz.openbmc_project.Software.ExtendedVersion')
+conf.set_quoted('RELEASE_DATE_IFACE', 'xyz.openbmc_project.Software.ReleaseDate')
conf.set_quoted('COMPATIBLE_IFACE', 'xyz.openbmc_project.Inventory.Decorator.Compatible')
# Names of the forward and reverse associations
diff --git a/version.cpp b/version.cpp
index b8b1247..f40c03e 100644
--- a/version.cpp
+++ b/version.cpp
@@ -178,6 +178,30 @@ std::string Version::getBMCExtendedVersion(const std::string& releaseFilePath)
return extendedVersion;
}
+std::string Version::getBMCReleaseDate(const std::string& releaseFilePath)
+{
+ std::string releaseDateKey = "BUILD_DATE=";
+ std::string releaseDateValue{};
+ std::string releaseDate{};
+ std::ifstream efile(releaseFilePath);
+ std::string line;
+
+ while (getline(efile, line))
+ {
+ if (line.substr(0, releaseDateKey.size())
+ .find(releaseDateKey) != std::string::npos)
+ {
+ releaseDateValue = line.substr(releaseDateKey.size());
+ std::size_t pos = releaseDateValue.find_first_of('"') + 1;
+ releaseDate = releaseDateValue.substr(
+ pos, releaseDateValue.find_last_of('"') - pos);
+ break;
+ }
+ }
+
+ return releaseDate;
+}
+
std::string Version::getBMCVersion(const std::string& releaseFilePath)
{
std::string versionKey = "VERSION_ID=";
diff --git a/version.hpp b/version.hpp
index 5c74f99..d54b41d 100644
--- a/version.hpp
+++ b/version.hpp
@@ -5,6 +5,7 @@
#include "xyz/openbmc_project/Object/Delete/server.hpp"
#include "xyz/openbmc_project/Software/ExtendedVersion/server.hpp"
#include "xyz/openbmc_project/Software/Version/server.hpp"
+#include "xyz/openbmc_project/Software/ReleaseDate/server.hpp"
#include <sdbusplus/bus.hpp>
@@ -23,6 +24,7 @@ typedef std::function<void(std::string)> eraseFunc;
using VersionInherit = sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Software::server::ExtendedVersion,
+ sdbusplus::xyz::openbmc_project::Software::server::ReleaseDate,
sdbusplus::xyz::openbmc_project::Software::server::Version,
sdbusplus::xyz::openbmc_project::Common::server::FilePath,
sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::Compatible>;
@@ -76,13 +78,15 @@ class Version : public VersionInherit
* @param[in] versionString - The version string
* @param[in] versionPurpose - The version purpose
* @param[in] extVersion - The extended version
+ * @param[in] relDate - The firmware release date
* @param[in] filePath - The image filesystem path
* @param[in] compatibleNames - The device compatibility names
* @param[in] callback - The eraseFunc callback
*/
Version(sdbusplus::bus_t& bus, const std::string& objPath,
const std::string& versionString, VersionPurpose versionPurpose,
- const std::string& extVersion, const std::string& filePath,
+ const std::string& extVersion, const std::string& relDate,
+ const std::string& filePath,
const std::vector<std::string>& compatibleNames, eraseFunc callback,
const std::string& id) :
VersionInherit(bus, (objPath).c_str(),
@@ -91,6 +95,7 @@ class Version : public VersionInherit
{
// Set properties.
extendedVersion(extVersion);
+ releaseDate(relDate);
purpose(versionPurpose);
version(versionString);
path(filePath);
@@ -150,6 +155,17 @@ class Version : public VersionInherit
static std::string
getBMCExtendedVersion(const std::string& releaseFilePath);
+ /**
+ * @brief Get the BMC Release Date string.
+ *
+ * @param[in] releaseFilePath - The path to the file which contains
+ * the release machine string.
+ *
+ * @return The release date string.
+ */
+ static std::string
+ getBMCReleaseDate(const std::string& releaseFilePath);
+
/**
* @brief Get the active BMC version string.
*
--
2.25.1
@@ -0,0 +1,157 @@
From 9f12832b7a6d2056b3db4e044f88c3e5b65dee97 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Wed, 13 Nov 2024 11:04:54 +0800
Subject: [PATCH] Add fan board cpld for software manager
---
item_updater.cpp | 37 +++++++++++++++++++++++++++++++++++++
item_updater.hpp | 20 ++++++++++++++++++++
meson.build | 5 +++++
meson_options.txt | 8 ++++++++
4 files changed, 70 insertions(+)
diff --git a/item_updater.cpp b/item_updater.cpp
index 76f72d4..d8348e3 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -74,6 +74,9 @@ void ItemUpdater::createActivation(sdbusplus::message_t& msg)
#endif
#ifdef CPLD_UPGRADE
value == VersionPurpose::CPLD ||
+#endif
+#ifdef FB_CPLD_UPGRADE
+ value == VersionPurpose::FBCPLD ||
#endif
value == VersionPurpose::System)
{
@@ -916,6 +919,40 @@ void ItemUpdater::createCPLDObject()
}
#endif
+#ifdef FB_CPLD_UPGRADE
+void ItemUpdater::createFBCPLDObject()
+{
+ std::string path = FB_CPLD_OBJPATH;
+ // Get version id from last item in the path
+ auto pos = path.rfind("/");
+ if (pos == std::string::npos)
+ {
+ error("No version id found in object path {PATH}", "PATH", path);
+ return;
+ }
+
+ createActiveAssociation(path);
+ createFunctionalAssociation(path);
+
+ auto versionId = path.substr(pos + 1);
+ auto version = "null";
+ AssociationList assocs = {};
+ FBcpldActivation = std::make_unique<Activation>(
+ bus, path, *this, versionId, server::Activation::Activations::Active,
+ assocs);
+ auto dummyErase = [](std::string /*entryId*/) {
+ // Do nothing;
+ };
+ FBcpldVersion = std::make_unique<VersionClass>(
+ bus, path, version, VersionPurpose::FBCPLD, "", "",
+ std::vector<std::string>(),
+ std::bind(dummyErase, std::placeholders::_1), "");
+ cpldVersion->deleteObject =
+ std::make_unique<phosphor::software::manager::Delete>(bus, path,
+ *cpldVersion);
+}
+#endif
+
void ItemUpdater::getRunningSlot()
{
// Check /run/media/slot to get the slot number
diff --git a/item_updater.hpp b/item_updater.hpp
index 26b657d..fc8d6c3 100644
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -70,6 +70,9 @@ class ItemUpdater : public ItemUpdaterInherit
#endif
#ifdef CPLD_UPGRADE
createCPLDObject();
+#endif
+#ifdef FB_CPLD_UPGRADE
+ createFBCPLDObject();
#endif
emit_object_added();
};
@@ -299,6 +302,23 @@ class ItemUpdater : public ItemUpdaterInherit
/** @brief Persistent Version D-Bus object for CPLD */
std::unique_ptr<VersionClass> cpldVersion;
#endif
+
+#ifdef FB_CPLD_UPGRADE
+ /** @brief Create the CPLD object without knowing the version.
+ *
+ * The object is created only to provide the DBus access so that an
+ * external service could set the correct CPLD version.
+ * On CPLD code update, the version is updated accordingly.
+ */
+ void createFBCPLDObject();
+
+ /** @brief Persistent Activation D-Bus object for CPLD */
+ std::unique_ptr<Activation> FBcpldActivation;
+
+ public:
+ /** @brief Persistent Version D-Bus object for CPLD */
+ std::unique_ptr<VersionClass> FBcpldVersion;
+#endif
/** @brief Get the slot number of running image */
void getRunningSlot();
};
diff --git a/meson.build b/meson.build
index 509d9f7..009dcef 100644
--- a/meson.build
+++ b/meson.build
@@ -68,6 +68,7 @@ conf.set('MMC_LAYOUT', get_option('bmc-layout').contains('mmc'))
# Configurable features
conf.set('HOST_BIOS_UPGRADE', get_option('host-bios-upgrade').enabled())
conf.set('CPLD_UPGRADE', get_option('cpld-upgrade').enabled())
+conf.set('FB_CPLD_UPGRADE', get_option('fb-cpld-upgrade').enabled())
conf.set('WANT_SIGNATURE_VERIFY', \
get_option('verify-signature').enabled() or \
get_option('verify-full-signature').enabled())
@@ -101,6 +102,10 @@ if get_option('cpld-upgrade').enabled()
conf.set_quoted('CPLD_OBJPATH', get_option('cpld-object-path'))
endif
+if get_option('fb-cpld-upgrade').enabled()
+ conf.set_quoted('FB_CPLD_OBJPATH', get_option('fb-cpld-object-path'))
+endif
+
if get_option('bmc-static-dual-image').enabled()
conf.set('BMC_STATIC_DUAL_IMAGE', get_option('bmc-static-dual-image').enabled())
conf.set_quoted('ALT_ROFS_DIR', get_option('alt-rofs-dir'))
diff --git a/meson_options.txt b/meson_options.txt
index d638c93..2109025 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -13,6 +13,8 @@ option('host-bios-upgrade', type: 'feature', value: 'enabled',
description: 'Enable host bios upgrade support.')
option('cpld-upgrade', type: 'feature', value: 'enabled',
description: 'Enable cpld upgrade support.')
+option('fb-cpld-upgrade', type: 'feature', value: 'enabled',
+ description: 'Enable fan board cpld upgrade support.')
option('sync-bmc-files', type: 'feature', value: 'enabled',
description: 'Enable sync of filesystem files.')
@@ -129,6 +131,12 @@ option(
description: 'The CPLD DBus object path.',
)
+option(
+ 'fb-cpld-object-path', type: 'string',
+ value: '/xyz/openbmc_project/software/fb_cpld_active',
+ description: 'The Fan Board CPLD DBus object path.',
+)
+
option('bmc-static-dual-image', type: 'feature', value: 'enabled',
description: 'Enable the dual image support for static layout.')
--
2.25.1
@@ -0,0 +1,694 @@
From bfa8b769aa57a3e25299640d36dd16d3037d5859 Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Mon, 6 Jan 2025 18:11:52 +0800
Subject: [PATCH] Sypport applyoption and updatetarget parameter
---
activation.cpp | 11 +-
activation.hpp | 38 ++++
image_async_main.cpp | 360 +++++++++++++++++++++++++++++++++++
item_updater.cpp | 26 ++-
meson.build | 9 +
meson_options.txt | 5 +
obmc-async-update.service.in | 11 ++
static/flash.cpp | 77 ++++++--
8 files changed, 513 insertions(+), 24 deletions(-)
create mode 100755 image_async_main.cpp
create mode 100755 obmc-async-update.service.in
diff --git a/activation.cpp b/activation.cpp
index f866461..7fb4038 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -175,14 +175,14 @@ auto Activation::activation(Activations value) -> Activations
#else // STATIC_LAYOUT
- if (parent.runningImageSlot == 0)
- {
+ // if (parent.runningImageSlot == 0)
+ // {
// On primary, update it as before
onFlashWriteSuccess();
return softwareServer::Activation::activation(
softwareServer::Activation::Activations::Active);
- }
- // On secondary, wait for the service to complete
+ // }
+ // // On secondary, wait for the service to complete
#endif
}
else
@@ -198,6 +198,7 @@ void Activation::onFlashWriteSuccess()
activationBlocksTransition.reset(nullptr);
activationProgress.reset(nullptr);
+ applyOptions.reset();
rwVolumeCreated = false;
roVolumeCreated = false;
@@ -291,6 +292,8 @@ auto Activation::requestedActivation(RequestedActivations value)
softwareServer::Activation::RequestedActivations::Active))
{
if ((softwareServer::Activation::activation() ==
+ softwareServer::Activation::Activations::AddQueue) ||
+ (softwareServer::Activation::activation() ==
softwareServer::Activation::Activations::Ready) ||
(softwareServer::Activation::activation() ==
softwareServer::Activation::Activations::Failed))
diff --git a/activation.hpp b/activation.hpp
index 7d10472..0c6d8b5 100644
--- a/activation.hpp
+++ b/activation.hpp
@@ -11,6 +11,8 @@
#include <xyz/openbmc_project/Association/Definitions/server.hpp>
#include <xyz/openbmc_project/Software/Activation/server.hpp>
#include <xyz/openbmc_project/Software/ActivationBlocksTransition/server.hpp>
+#include <xyz/openbmc_project/Software/ApplyOptions/server.hpp>
+#include <xyz/openbmc_project/Software/UpdateTarget/server.hpp>
#ifdef WANT_SIGNATURE_VERIFY
#include <filesystem>
@@ -39,6 +41,10 @@ using RedundancyPriorityInherit = sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Software::server::RedundancyPriority>;
using ActivationProgressInherit = sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Software::server::ActivationProgress>;
+using UpdateTargetInherit = sdbusplus::server::object::object<
+ sdbusplus::xyz::openbmc_project::Software::server::UpdateTarget>;
+using ApplyOptionsInherit = sdbusplus::server::object::object<
+ sdbusplus::xyz::openbmc_project::Software::server::ApplyOptions>;
constexpr auto applyTimeImmediate =
"xyz.openbmc_project.Software.ApplyTime.RequestedApplyTimes.Immediate";
@@ -166,6 +172,32 @@ class ActivationProgress : public ActivationProgressInherit
}
};
+class UpdateTarget : public UpdateTargetInherit
+{
+ public:
+ /** @brief Constructs UpdateTarget
+ *
+ * @param[in] bus - The Dbus bus object
+ * @param[in] path - The Dbus object path
+ */
+ UpdateTarget(sdbusplus::bus::bus& bus, const std::string& path) :
+ UpdateTargetInherit(bus, path.c_str(), action::emit_interface_added)
+ {}
+};
+
+class ApplyOptions : public ApplyOptionsInherit
+{
+ public:
+ /** @brief Constructs ApplyOptions
+ *
+ * @param[in] bus - The Dbus bus object
+ * @param[in] path - The Dbus object path
+ */
+ ApplyOptions(sdbusplus::bus::bus& bus, const std::string& path) :
+ ApplyOptionsInherit(bus, path.c_str(), action::emit_interface_added)
+ {}
+};
+
/** @class Activation
* @brief OpenBMC activation software management implementation.
* @details A concrete implementation for
@@ -328,6 +360,12 @@ class Activation : public ActivationInherit, public Flash
/** @brief Persistent ActivationProgress dbus object */
std::unique_ptr<ActivationProgress> activationProgress;
+ /** @brief Persistent UpdateTarget dbus object */
+ std::unique_ptr<UpdateTarget> updateTarget;
+
+ /** @brief Persistent ApplyOptions dbus object */
+ std::unique_ptr<ApplyOptions> applyOptions;
+
/** @brief Used to subscribe to dbus systemd signals **/
sdbusplus::bus::match_t systemdSignals;
diff --git a/image_async_main.cpp b/image_async_main.cpp
new file mode 100755
index 0000000..bd17564
--- /dev/null
+++ b/image_async_main.cpp
@@ -0,0 +1,360 @@
+#include <boost/asio.hpp>
+#include <boost/chrono.hpp>
+#include <boost/container/flat_map.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/server.hpp>
+
+#include <deque>
+#include <exception>
+#include <filesystem>
+#include <iostream>
+#include <string>
+#include <utility>
+#include <variant>
+#include <vector>
+
+using namespace phosphor::logging;
+using DbusVariant = std::variant<std::vector<std::string>, std::string, bool>;
+
+static boost::asio::io_context ioCtx;
+static std::shared_ptr<sdbusplus::asio::connection> conn;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> interface;
+static std::shared_ptr<sdbusplus::bus::match::match> match;
+
+static boost::asio::steady_timer checkTimer(ioCtx);
+static boost::asio::steady_timer updateTimer(ioCtx);
+static std::string status{"Idle"};
+
+static std::deque<std::pair<std::string, std::string>> components;
+static bool powerStatus = false;
+static std::unique_ptr<sdbusplus::bus::match_t> powerMatch = nullptr;
+
+static std::string handlerStart();
+
+namespace power
+{
+const static constexpr char* busname = "xyz.openbmc_project.State.Chassis";
+const static constexpr char* interface = "xyz.openbmc_project.State.Chassis";
+const static constexpr char* path = "/xyz/openbmc_project/state/chassis0";
+const static constexpr char* property = "CurrentPowerState";
+} // namespace power
+
+namespace properties
+{
+constexpr const char* interface = "org.freedesktop.DBus.Properties";
+constexpr const char* get = "Get";
+constexpr const char* set = "Set";
+} // namespace properties
+
+static void
+ getPowerStatus(const std::shared_ptr<sdbusplus::asio::connection>& conn,
+ size_t retries = 2)
+{
+ conn->async_method_call(
+ [conn, retries](boost::system::error_code ec,
+ const std::variant<std::string>& state) {
+ if (ec)
+ {
+ if (retries != 0U)
+ {
+ auto timer = std::make_shared<boost::asio::steady_timer>(
+ conn->get_io_context());
+ timer->expires_after(std::chrono::seconds(15));
+ timer->async_wait(
+ [timer, conn, retries](boost::system::error_code) {
+ getPowerStatus(conn, retries - 1);
+ });
+ return;
+ }
+
+ // we commonly come up before power control, we'll capture the
+ // property change later
+ lg2::error("error getting power status {ERROR}", "ERROR",
+ ec.message());
+ return;
+ }
+ powerStatus = std::get<std::string>(state).ends_with(".On");
+ },
+ power::busname, power::path, properties::interface, properties::get,
+ power::interface, power::property);
+}
+
+void setupPowerMonitor(const std::shared_ptr<sdbusplus::asio::connection>& conn)
+{
+ // create a match for powergood changes, first time do a method call to
+ // cache the correct value
+ if (powerMatch)
+ {
+ return;
+ }
+
+ powerMatch = std::make_unique<sdbusplus::bus::match_t>(
+ static_cast<sdbusplus::bus_t&>(*conn),
+ "type='signal',interface='" + std::string(properties::interface) +
+ "',path='" + std::string(power::path) + "',arg0='" +
+ std::string(power::interface) + "'",
+ [](sdbusplus::message_t& message) {
+ std::string objectName;
+ std::map<std::string, std::variant<std::string>> values;
+ message.read(objectName, values);
+ auto findState = values.find(power::property);
+ if (findState != values.end())
+ {
+ powerStatus =
+ std::get<std::string>(findState->second).ends_with(".Running");
+ }
+ });
+
+ getPowerStatus(conn);
+}
+
+/**
+ * @brief remove image form bmc filesystem.
+ * @param[in] imageID - old image.
+ * @details if image type is same as in queue, remove old image.
+ *
+ */
+void removeExistImage(const std::string& imageID)
+{
+ auto oldImage = "/xyz/openbmc_project/software/" + imageID;
+ conn->async_method_call([](const boost::system::error_code& /*ec*/) {},
+ "xyz.openbmc_project.Software.BMC.Updater",
+ oldImage, "xyz.openbmc_project.Object.Delete",
+ "Delete");
+}
+
+/**
+ * @brief Async AddQueue method implementation for dbus.
+ * @param[in] versionPurpose - VersionPurpose as unique key.
+ * @param[in] imageID - get from bmc.
+ * @details REST API
+ * https://<IP>/xyz/openbmc_project/Software/AsyncUpdate/action/AddQueue for for
+ * web and update-script.
+ *
+ */
+static void handlerAddQueue(std::string& versionPurpose, std::string& imageID)
+{
+ // remove same image from bmc filesystem.
+ // position is same as before in queue
+ bool existImage = false;
+ for (auto& item : components)
+ {
+ if (item.first == versionPurpose)
+ {
+ removeExistImage(item.second);
+ item.second = imageID;
+ existImage = true;
+ break;
+ }
+ }
+ if (!existImage)
+ {
+ components.push_back(std::make_pair(versionPurpose, imageID));
+ }
+ // if Running, keep Running status.
+ if (status == "Idle")
+ {
+ status = "Waiting";
+ interface->set_property("AsyncUpdateStatus", status);
+ }
+ // set the status of async upgrade to add queue
+ auto objectPath = "/xyz/openbmc_project/software/" + imageID;
+ try
+ {
+ conn->async_method_call(
+ [](const boost::system::error_code& /*ec*/) {},
+ "xyz.openbmc_project.Software.BMC.Updater", objectPath,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Software.Activation", "Activation",
+ DbusVariant(
+ "xyz.openbmc_project.Software.Activation.Activations.AddQueue"));
+ }
+ catch (const sdbusplus::exception::SdBusError& e)
+ {
+ lg2::error("Can not to set async upgrade status: {ERROR}", "ERROR", e);
+ }
+}
+
+/**
+ * @brief Get power status.
+ * @return if true means power is off
+ * false power on
+ *
+ */
+static bool isPowerOff()
+{
+ return powerStatus == false;
+}
+
+/**
+ * @brief start update.
+ */
+static void activateImage()
+{
+ status = "Running";
+ interface->set_property("AsyncUpdateStatus", status);
+ auto imagePair = components.front();
+ auto versionId = imagePair.first;
+ auto image = imagePair.second;
+ auto currImage = "/xyz/openbmc_project/software/" + image;
+ try
+ {
+ conn->async_method_call(
+ [](const boost::system::error_code& /*ec*/) {},
+ "xyz.openbmc_project.Software.BMC.Updater", currImage,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Software.Activation", "RequestedActivation",
+ DbusVariant(
+ "xyz.openbmc_project.Software.Activation.RequestedActivations.Active"));
+ }
+ catch (const sdbusplus::exception::SdBusError& e)
+ {
+ lg2::error("Can not activate image: {ERROR}", "ERROR", e);
+ return;
+ }
+}
+
+/**
+ * @brief stop update.
+ */
+static void interruptImage(std::string& image)
+{
+ auto currImage = "/xyz/openbmc_project/software/" + image;
+ try
+ {
+ conn->async_method_call(
+ [](const boost::system::error_code& /*ec*/) {},
+ "xyz.openbmc_project.Software.BMC.Updater", currImage,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Software.Activation", "Activation",
+ DbusVariant(
+ "xyz.openbmc_project.Software.Activation.Activations.Interrupted"));
+ }
+ catch (const sdbusplus::exception::SdBusError& e)
+ {
+ lg2::error("Can not interrupt image: {IMAGE} error: {ERROR}", "IMAGE",
+ image, "ERROR", e);
+ return;
+ }
+}
+
+/**
+ * @brief dbus method callback.
+ */
+static std::string handlerStart()
+{
+ // when queue is empty return idle status
+ if (components.empty())
+ {
+ if (status == "Running")
+ {
+ status = "Idle";
+ }
+ interface->set_property("AsyncUpdateStatus", status);
+ return status;
+ }
+ // queue is not empty start async update ,use timer to check power status
+ checkTimer.expires_after(boost::asio::chrono::seconds(5));
+ checkTimer.async_wait([&](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ return;
+ }
+ if (!isPowerOff())
+ {
+ if (status == "Running")
+ {
+ lg2::error("power is on, stop async update for queued images.");
+ for (auto& item : components)
+ {
+ lg2::error(
+ "stop queued image async update, imageID: {IMAGE}, versionID: {VERSION}",
+ "IMAGE", item.second, "VERSION", item.first);
+ interruptImage(item.second);
+ }
+ components.clear();
+
+ status = "Idle";
+ interface->set_property("AsyncUpdateStatus", status);
+ return;
+ }
+ // power is on recheck power status
+ handlerStart();
+ return;
+ }
+ // power is off start async update
+ activateImage();
+ });
+ return status;
+}
+
+/**
+ * @brief dbus match callback.
+ */
+void matchJobs(sdbusplus::message::message& msg)
+{
+ uint32_t newStateID{};
+ sdbusplus::message::object_path newStateObjPath;
+ std::string newStateUnit{};
+ std::string newStateResult{};
+ // Read the msg and populate each variable
+ msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
+ // normal update will be ignore
+ if (status == "Running")
+ {
+ // if newStateUnit exist image ID, means it is a service job
+ if (newStateUnit.find(components.front().second) != std::string::npos)
+ {
+ if (newStateResult == "done")
+ {
+ lg2::info("async update image finish successfully ({SERVICE})",
+ "SERVICE", newStateUnit);
+ }
+ else if (newStateResult == "failed")
+ {
+ lg2::error("async update image failed ({SERVICE})", "SERVICE",
+ newStateUnit);
+ }
+ // when finish, remove image from queue
+ components.pop_front();
+ // start next
+ handlerStart();
+ }
+ }
+}
+
+int main(int /*argc*/, char** /*argv*/)
+{
+ const auto BUS_NAME = "xyz.openbmc_project.Software.AsyncUpdate";
+ const auto OBJECT_PATH = "/xyz/openbmc_project/Software/AsyncUpdate";
+ const auto INTERFACE_NAME = "xyz.openbmc_project.Software.AsyncUpdate";
+ conn = std::make_shared<sdbusplus::asio::connection>(ioCtx);
+ conn->request_name(BUS_NAME);
+
+ setupPowerMonitor(conn);
+ match = std::make_shared<sdbusplus::bus::match::match>(
+ *conn,
+ "type='signal',member='JobRemoved',path='/org/freedesktop/systemd1',interface='org.freedesktop.systemd1.Manager'",
+ matchJobs);
+ sdbusplus::asio::object_server hostServer =
+ sdbusplus::asio::object_server(conn);
+ interface = hostServer.add_interface(OBJECT_PATH, INTERFACE_NAME);
+ interface->register_property(
+ "AsyncUpdateStatus", status,
+ [&](const std::string& requested, std::string& resp) -> int {
+ status = requested;
+ resp = requested;
+ return 1;
+ });
+ interface->register_method("Start", handlerStart);
+ interface->register_method("AddQueue", handlerAddQueue);
+ interface->initialize();
+ ioCtx.run();
+ return 0;
+}
diff --git a/item_updater.cpp b/item_updater.cpp
index 36bf5b3..a09f704 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -179,10 +179,15 @@ void ItemUpdater::createActivation(sdbusplus::message_t& msg)
*versionPtr);
versions.insert(std::make_pair(versionId, std::move(versionPtr)));
- activations.insert(std::make_pair(
- versionId,
- std::make_unique<Activation>(bus, path, *this, versionId,
- activationState, associations)));
+ if (version == "Mismatch" || version == "Invalid")
+ {
+ activationState = server::Activation::Activations::Invalid;
+ }
+ auto activationPtr = std::make_unique<Activation>(
+ bus, path, *this, versionId, activationState, associations);
+ activationPtr->updateTarget = std::make_unique<UpdateTarget>(bus, path);
+ activationPtr->applyOptions = std::make_unique<ApplyOptions>(bus, path);
+ activations.insert(std::make_pair(versionId, std::move(activationPtr)));
}
return;
}
@@ -768,12 +773,21 @@ void ItemUpdater::resetUbootEnvVars()
void ItemUpdater::freeSpace([[maybe_unused]] const Activation& caller)
{
#ifdef BMC_STATIC_DUAL_IMAGE
- // For the golden image case, always remove the version on the primary side
+ // For dual image case, erase the slot depends on the updateTarget
+ auto targetSlot = UpdateTarget::TargetSlot::Primary;
+ if (caller.updateTarget)
+ {
+ targetSlot = caller.updateTarget->updateTargetSlot();
+ }
+ auto priorityToErase = targetSlot == UpdateTarget::TargetSlot::Primary ? 0
+ : 1;
+
std::string versionIDtoErase;
for (const auto& iter : activations)
{
if (iter.second->redundancyPriority &&
- iter.second->redundancyPriority.get()->priority() == 0)
+ iter.second->redundancyPriority.get()->priority() ==
+ priorityToErase)
{
versionIDtoErase = iter.second->versionId;
break;
diff --git a/meson.build b/meson.build
index 68f1f91..99d3645 100644
--- a/meson.build
+++ b/meson.build
@@ -247,6 +247,15 @@ if get_option('sync-bmc-files').enabled()
)
endif
+if get_option('async-update').allowed()
+ executable(
+ 'obmc-async-update',
+ 'image_async_main.cpp',
+ dependencies: deps,
+ install: true
+ )
+ unit_files += 'obmc-async-update.service.in'
+endif
if (get_option('verify-signature').enabled() or \
get_option('verify-full-signature').enabled())
image_updater_sources += files(
diff --git a/meson_options.txt b/meson_options.txt
index 2109025..53c61fd 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -40,6 +40,11 @@ option(
description: 'Automatic flash side switch on boot',
)
+option(
+ 'async-update', type: 'feature', value: 'enabled',
+ description: 'Enable Async update.',
+)
+
# Variables
option(
'active-bmc-max-allowed', type: 'integer',
diff --git a/obmc-async-update.service.in b/obmc-async-update.service.in
new file mode 100755
index 0000000..d586a55
--- /dev/null
+++ b/obmc-async-update.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=BMC async update
+
+[Service]
+Restart=always
+Type=dbus
+BusName=xyz.openbmc_project.Software.AsyncUpdate
+ExecStart=/usr/bin/obmc-async-update
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/static/flash.cpp b/static/flash.cpp
index 74316d1..812b5de 100644
--- a/static/flash.cpp
+++ b/static/flash.cpp
@@ -31,20 +31,20 @@ using namespace phosphor::software::image;
void Activation::flashWrite()
{
-#ifdef BMC_STATIC_DUAL_IMAGE
- if (parent.runningImageSlot != 0)
- {
- // It's running on the secondary chip, update the primary one
- info("Flashing primary flash from secondary, id: {ID}", "ID",
- versionId);
- auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
- SYSTEMD_INTERFACE, "StartUnit");
- auto serviceFile = FLASH_ALT_SERVICE_TMPL + versionId + ".service";
- method.append(serviceFile, "replace");
- bus.call_noreply(method);
- return;
- }
-#endif
+// #ifdef BMC_STATIC_DUAL_IMAGE
+// if (parent.runningImageSlot != 0)
+// {
+// // It's running on the secondary chip, update the primary one
+// info("Flashing primary flash from secondary, id: {ID}", "ID",
+// versionId);
+// auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+// SYSTEMD_INTERFACE, "StartUnit");
+// auto serviceFile = FLASH_ALT_SERVICE_TMPL + versionId + ".service";
+// method.append(serviceFile, "replace");
+// bus.call_noreply(method);
+// return;
+// }
+// #endif
// For static layout code update, just put images in /run/initramfs.
// It expects user to trigger a reboot and an updater script will program
// the image to flash during reboot.
@@ -57,6 +57,55 @@ void Activation::flashWrite()
fs::copy_file(uploadDir / versionId / bmcImage, toPath / bmcImage,
fs::copy_options::overwrite_existing, ec);
}
+
+ std::string old_prefix = "image-";
+ std::string new_prefix = "image-alt-";
+ auto targetSlot = UpdateTarget::TargetSlot::Primary;
+ if (updateTarget)
+ {
+ targetSlot = updateTarget->updateTargetSlot();
+ }
+
+ if (targetSlot == UpdateTarget::TargetSlot::Both)
+ {
+ for (const auto& entry : fs::directory_iterator(toPath))
+ {
+ if (entry.is_regular_file())
+ {
+ std::string old_name = entry.path().filename().string();
+ if (old_name.find(old_prefix) == 0 && old_name.find(new_prefix) == std::string::npos)
+ {
+ std::string new_name = new_prefix + old_name.substr(old_prefix.length());
+ fs::copy_file(entry.path(), entry.path().parent_path() / new_name);
+ }
+ }
+ }
+ }
+ else if (targetSlot == UpdateTarget::TargetSlot::Secondary)
+ {
+ for (const auto& entry : fs::directory_iterator(toPath))
+ {
+ if (entry.is_regular_file())
+ {
+ std::string old_name = entry.path().filename().string();
+ if (old_name.find(old_prefix) == 0 && old_name.find(new_prefix) == std::string::npos)
+ {
+ std::string new_name = new_prefix + old_name.substr(old_prefix.length());
+ fs::rename(entry.path(), entry.path().parent_path() / new_name);
+ }
+ }
+ }
+ }
+
+ auto clearConfig = ApplyOptions::ConfigManagement::Keep;
+ if (applyOptions)
+ {
+ clearConfig = applyOptions->clearConfig();
+ }
+ if (clearConfig == ApplyOptions::ConfigManagement::Clear)
+ {
+ utils::execute("/sbin/fw_setenv", "openbmconce", "factory-reset");
+ }
}
void Activation::onStateChanges([[maybe_unused]] sdbusplus::message_t& msg)
--
2.25.1
@@ -0,0 +1,20 @@
#!/bin/bash
bus=14
address=0x53
offset=0x08
tmp=$(i2ctransfer -y -f $bus w2@$address $offset 0x00 r32)
for str in $tmp;do
if [[ $str != 0x00 ]]; then
str=$(printf "%d" "$str")
version=$(echo "$str" | awk '{printf("%c", $str)}')
biosversion="$biosversion$version"
fi
done
echo "BIOS version got from epprom:$biosversion"
if [ "$biosversion" == "" ]; then
echo "BIOS version is null, skip"
else
mapper wait /xyz/openbmc_project/software/bios_active
busctl set-property xyz.openbmc_project.Software.BMC.Updater /xyz/openbmc_project/software/bios_active xyz.openbmc_project.Software.Version Version s "${biosversion}"
echo "Restored BIOS version ${biosversion}"
fi
@@ -0,0 +1,2 @@
[Service]
ExecStartPost=/usr/bin/restore-bios-version.sh
@@ -0,0 +1,14 @@
#!/bin/bash
bus=0
address=0x0d
offset=0x05
str=$(i2ctransfer -y -a $bus w2@$address $offset 0x00 r1)
version=${str:2:2}
echo "CPLD version got from I2C:$version"
if [ "$version" == "" ]; then
echo "CPLD version is null, skip"
else
mapper wait /xyz/openbmc_project/software/cpld_active
busctl set-property xyz.openbmc_project.Software.BMC.Updater /xyz/openbmc_project/software/cpld_active xyz.openbmc_project.Software.Version Version s ${version}
echo "Restored CPLD version ${version}"
fi
@@ -0,0 +1,2 @@
[Service]
ExecStartPost=/usr/bin/restore-cpld-version.sh
@@ -0,0 +1,14 @@
#!/bin/bash
bus=7
address=0x7c
offset=0x40
str=$(i2ctransfer -y -a $bus w2@$address $offset 0x00 r1)
version=${str:2:2}
echo "Fan Board CPLD version got from I2C:$version"
if [ "$version" == "" ]; then
echo "Fan Board CPLD version is null, skip"
else
mapper wait /xyz/openbmc_project/software/fb_cpld_active
busctl set-property xyz.openbmc_project.Software.BMC.Updater /xyz/openbmc_project/software/fb_cpld_active xyz.openbmc_project.Software.Version Version s ${version}
echo "Restored Fan Board CPLD version ${version}"
fi
@@ -0,0 +1,2 @@
[Service]
ExecStartPost=/usr/bin/restore-fb-cpld-version.sh
@@ -0,0 +1,40 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI += " \
file://restore-bios.conf \
file://restore-bios-version.sh \
file://restore-cpld.conf \
file://restore-cpld-version.sh \
file://restore-fb-cpld.conf \
file://restore-fb-cpld-version.sh \
"
SRC_URI += " \
file://0001-Add-fan-board-cpld-for-software-manager.patch \
file://0001-Add-ReleaseDate-for-Software-interface.patch \
file://0001-Support-applyoption-and-updatetarger-parameter.patch \
"
PACKAGECONFIG[async_update] = "-Dasync-update=enabled, -Dasync-update=disabled"
PACKAGECONFIG:append = " \
async_update \
"
SYSTEMD_SERVICE:${PN}-updater += "${@bb.utils.contains('PACKAGECONFIG', 'async_update', 'obmc-async-update.service', '', d)}"
FILES:${PN}:append = " ${systemd_system_unitdir}/xyz.openbmc_project.Software.BMC.Updater.service.d/restore-bios.conf"
FILES:${PN}:append = " ${systemd_system_unitdir}/xyz.openbmc_project.Software.BMC.Updater.service.d/restore-cpld.conf"
FILES:${PN}:append = " ${systemd_system_unitdir}/xyz.openbmc_project.Software.BMC.Updater.service.d/restore-fb-cpld.conf"
do_install:append() {
install -d ${D}${systemd_system_unitdir}/xyz.openbmc_project.Software.BMC.Updater.service.d
install -m 0644 ${WORKDIR}/restore-bios.conf ${D}${systemd_system_unitdir}/xyz.openbmc_project.Software.BMC.Updater.service.d/
install -m 0644 ${WORKDIR}/restore-cpld.conf ${D}${systemd_system_unitdir}/xyz.openbmc_project.Software.BMC.Updater.service.d/
install -m 0644 ${WORKDIR}/restore-fb-cpld.conf ${D}${systemd_system_unitdir}/xyz.openbmc_project.Software.BMC.Updater.service.d/
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/restore-bios-version.sh ${D}${bindir}
install -m 0755 ${WORKDIR}/restore-cpld-version.sh ${D}${bindir}/
install -m 0755 ${WORKDIR}/restore-fb-cpld-version.sh ${D}${bindir}/
}
@@ -0,0 +1,14 @@
[Unit]
Description=Host misc manager
[Service]
Restart=always
RestartSec=5
ExecStart=/usr/bin/host-misc-manager
StartLimitInterval=0
SyslogIdentifier=host-misc-manager
Type=dbus
BusName=xyz.openbmc_project.Host.Misc.Manager
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,12 @@
FILESEXTRAPATHS:${PN} := "${THISDIR}/${PN}:"
S = "${WORKDIR}"
LICENSE = "CLOSED"
SRC_URI = "file://host-misc-manager"
inherit obmc-phosphor-systemd
DEPENDS = " systemd sdbusplus phosphor-logging libgpiod"
SYSTEMD_SERVICE:${PN} = "xyz.openbmc_project.Host.Misc.Manager.service"
do_install() {
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/host-misc-manager ${D}${bindir}
}
@@ -0,0 +1,12 @@
OBMC_IMAGE_EXTRA_INSTALL:append = " \
dimm-fsc \
cover-heat \
phosphor-virtual-sensor \
ipmi-fru \
write-bios-version \
system-watchdog \
disable-wdt \
boardname \
dimm-spd-reader \
pre-heat \
"
@@ -0,0 +1,20 @@
diff --git a/storagehandler.cpp b/storagehandler.cpp
index 6bc207b..4fef019 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -221,10 +221,13 @@ void initSensorInfoOnDBus()
// For now the sensor path and type code are needed.
auto init = []() {
auto objServer = getObjectServer();
- std::unordered_map<std::string, uint16_t> sensorInfo;
+ // ipmi::sensor::Type, ipmi::sensor::ReadingType
+ using sensorCodes = std::vector<uint8_t>;
+ std::unordered_map<std::string, sensorCodes> sensorInfo;
for (const auto& s : invSensors)
{
- sensorInfo[s.first] = s.second.eventReadingType;
+ sensorInfo[s.first] = {s.second.sensorType,
+ s.second.eventReadingType};
}
sensorInfoInterface =
objServer->add_interface("/xyz/openbmc_project/Ipmi/SensorInfo",
@@ -0,0 +1,26 @@
From 335c1661c6dad640e941ec2378420c2128b78b8d Mon Sep 17 00:00:00 2001
From: wangbin <Bin-B.Wang@luxshare-ict.com>
Date: Thu, 30 Oct 2025 21:45:08 +0800
Subject: [PATCH] BMC status is set to normal by default
---
apphandler.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apphandler.cpp b/apphandler.cpp
index 5628b35..d01bff9 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -711,7 +711,8 @@ ipmi::RspType<uint8_t, // Device ID
devId.fw[0] &= ipmiDevIdFw1Mask;
if (!getCurrentBmcStateWithFallback(defaultActivationSetting))
{
- devId.fw[0] |= (1 << ipmiDevIdStateShift);
+ // BMC status is set to normal by default
+ // devId.fw[0] |= (1 << ipmiDevIdStateShift);
}
return ipmi::responseSuccess(
--
2.25.1
@@ -0,0 +1,158 @@
From e473399654b26eba755a11abb3f949debe62557a Mon Sep 17 00:00:00 2001
From: roly <Rolyli.Li@luxshare-ict.com>
Date: Wed, 20 Nov 2024 15:23:06 +0800
Subject: [PATCH] Support ipmi cmd set sol bitrate
---
transporthandler.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 116 insertions(+), 2 deletions(-)
diff --git a/transporthandler.cpp b/transporthandler.cpp
index dd2ac14..38faccc 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -1741,7 +1741,88 @@ RspType<> setSolConfParams(Context::ptr ctx, uint4_t channelBits,
return response(ipmiCCWriteReadParameter);
}
case SolConfParam::NonVbitrate:
+ {
+ uint4_t encodedBitRate;
+ uint4_t reserved2;
+ uint64_t baudRate;
+
+ if (req.unpack(encodedBitRate, reserved2) != 0 ||
+ !req.fullyUnpacked())
+ {
+ return responseReqDataLenInvalid();
+ }
+
+ switch (static_cast<uint8_t>(encodedBitRate))
+ {
+ case 0x06:
+ baudRate = 9600;
+ break;
+ case 0x07:
+ baudRate = 19200;
+ break;
+ case 0x08:
+ baudRate = 38400;
+ break;
+ case 0x09:
+ baudRate = 57600;
+ break;
+ case 0x0a:
+ baudRate = 115200;
+ break;
+ default:
+ return responseParmOutOfRange();
+ }
+
+ if (ipmi::setDbusProperty(
+ ctx, "xyz.openbmc_project.Console.default",
+ "/xyz/openbmc_project/console/default",
+ "xyz.openbmc_project.Console.UART", "NonVbitrate", baudRate))
+ {
+ return responseUnspecifiedError();
+ }
+ break;
+ }
case SolConfParam::Vbitrate:
+ {
+ uint4_t encodedBitRate;
+ uint4_t reserved2;
+ uint64_t baudRate;
+
+ if (req.unpack(encodedBitRate, reserved2) != 0 ||
+ !req.fullyUnpacked())
+ {
+ return responseReqDataLenInvalid();
+ }
+
+ switch (static_cast<uint8_t>(encodedBitRate))
+ {
+ case 0x06:
+ baudRate = 9600;
+ break;
+ case 0x07:
+ baudRate = 19200;
+ break;
+ case 0x08:
+ baudRate = 38400;
+ break;
+ case 0x09:
+ baudRate = 57600;
+ break;
+ case 0x0a:
+ baudRate = 115200;
+ break;
+ default:
+ return responseParmOutOfRange();
+ }
+ if (ipmi::setDbusProperty(
+ ctx, "xyz.openbmc_project.Console.default",
+ "/xyz/openbmc_project/console/default",
+ "xyz.openbmc_project.Console.UART", "Vbitrate", baudRate))
+ {
+ return responseUnspecifiedError();
+ }
+ break;
+ }
case SolConfParam::Channel:
default:
return response(ipmiCCParamNotSupported);
@@ -1895,10 +1976,10 @@ RspType<message::Payload> getSolConfParams(Context::ptr ctx,
if (ipmi::getDbusProperty(
ctx, "xyz.openbmc_project.Console.default",
"/xyz/openbmc_project/console/default",
- "xyz.openbmc_project.Console.UART", "Baud", baudRate))
+ "xyz.openbmc_project.Console.UART", "NonVbitrate", baudRate))
{
return ipmi::responseUnspecifiedError();
- }
+ }
switch (baudRate)
{
case 9600:
@@ -1923,6 +2004,39 @@ RspType<message::Payload> getSolConfParams(Context::ptr ctx,
return responseSuccess(std::move(ret));
}
case SolConfParam::Vbitrate:
+ {
+ uint64_t baudRate;
+ uint8_t encodedBitRate = 0;
+ if (ipmi::getDbusProperty(
+ ctx, "xyz.openbmc_project.Console.default",
+ "/xyz/openbmc_project/console/default",
+ "xyz.openbmc_project.Console.UART", "Vbitrate", baudRate))
+ {
+ return ipmi::responseUnspecifiedError();
+ }
+ switch (baudRate)
+ {
+ case 9600:
+ encodedBitRate = 0x06;
+ break;
+ case 19200:
+ encodedBitRate = 0x07;
+ break;
+ case 38400:
+ encodedBitRate = 0x08;
+ break;
+ case 57600:
+ encodedBitRate = 0x09;
+ break;
+ case 115200:
+ encodedBitRate = 0x0a;
+ break;
+ default:
+ break;
+ }
+ ret.pack(encodedBitRate);
+ return responseSuccess(std::move(ret));
+ }
default:
return response(ipmiCCParamNotSupported);
}
--
2.25.1
@@ -0,0 +1,96 @@
diff --git a/include/ipmid/utils.hpp b/include/ipmid/utils.hpp
index 20f9847..9d13fd0 100644
--- a/include/ipmid/utils.hpp
+++ b/include/ipmid/utils.hpp
@@ -464,4 +464,10 @@ void callDbusMethod(sdbusplus::bus_t& bus, const std::string& service,
ipmi::Cc i2cWriteRead(std::string i2cBus, const uint8_t slaveAddr,
std::vector<uint8_t> writeData,
std::vector<uint8_t>& readBuf);
+
+/** @brief Get board object path from DBUS object_mapper
+ * @param[in] bus - DBUS Bus Object.
+ * @return - string value of board object path
+ */
+std::string getBoardObjectPath(sdbusplus::bus::bus& bus);
} // namespace ipmi
diff --git a/libipmid/utils.cpp b/libipmid/utils.cpp
index 1261c2e..64a00d2 100644
--- a/libipmid/utils.cpp
+++ b/libipmid/utils.cpp
@@ -319,6 +319,36 @@ ObjectTree getAllAncestors(sdbusplus::bus_t& bus, const std::string& path,
return objectTree;
}
+std::string getBoardObjectPath(sdbusplus::bus::bus& bus)
+{
+ std::vector<std::string> paths;
+
+ auto method = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF,
+ "GetSubTreePaths");
+ method.append("/xyz/openbmc_project/inventory/system/board");
+ method.append(0); // Depth 0 to search all
+ method.append(
+ std::vector<std::string>({"xyz.openbmc_project.Inventory.Item.Board"}));
+
+ try
+ {
+ auto reply = bus.call(method);
+ reply.read(paths);
+ }
+ catch (const sdbusplus::exception::exception& e)
+ {
+ log<level::ERR>("Error get board object path ",
+ entry("ERROR=%s", e.what()));
+ }
+
+ if (paths.empty())
+ {
+ log<level::ERR>("Error board object path is EMPTY");
+ return "";
+ }
+
+ return paths[0];
+}
namespace method_no_args
{
diff --git a/storagehandler.cpp b/storagehandler.cpp
index cf5ef5e..405a8a1 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -79,6 +79,7 @@ std::unique_ptr<sdbusplus::bus::match_t> selRemovedMatch
__attribute__((init_priority(101)));
std::unique_ptr<sdbusplus::bus::match_t> selUpdatedMatch
__attribute__((init_priority(101)));
+std::string boardObjectPath __attribute__((init_priority(101)));
static inline uint16_t getLoggingId(const std::string& p)
{
@@ -532,6 +533,27 @@ ipmi::RspType<uint8_t // erase status
return ipmi::responseUnspecifiedError();
}
+ if (boardObjectPath.empty())
+ {
+ boardObjectPath = ipmi::getBoardObjectPath(bus);
+ }
+ if (boardObjectPath.empty())
+ {
+ // Still empty, fail to add sel for clear SEL event
+ log<level::ERR>("Failed to get board object path");
+ return ipmi::responseUnspecifiedError();
+ }
+ std::string dbusIntfPath = boardObjectPath + "/Event_Log";
+ constexpr auto selSystemType = 0x02;
+ constexpr uint16_t genId = 0x0020;
+ constexpr std::array<uint8_t, 3> eventData = {0x02, 0x00, 0x00};
+ constexpr bool assert = true;
+ auto selDataStr = ipmi::sel::toHexStr(eventData);
+ report<SELCreated>(
+ Created::RECORD_TYPE(selSystemType), Created::GENERATOR_ID(genId),
+ Created::SENSOR_DATA(selDataStr.c_str()), Created::EVENT_DIR(assert),
+ Created::SENSOR_PATH(dbusIntfPath.c_str()));
+
return ipmi::responseSuccess(
static_cast<uint8_t>(ipmi::sel::eraseComplete));
}
@@ -0,0 +1,117 @@
diff --git a/include/ipmid/api.hpp b/include/ipmid/api.hpp
index 68e24ea..2366b91 100644
--- a/include/ipmid/api.hpp
+++ b/include/ipmid/api.hpp
@@ -35,6 +35,8 @@ std::shared_ptr<boost::asio::io_context> getIoContext();
// any client can interact with the main sdbus
std::shared_ptr<sdbusplus::asio::connection> getSdBus();
+// any client can interact with the object server
+std::shared_ptr<sdbusplus::asio::object_server> getObjectServer();
/**
* @brief post some work to the async exection queue
diff --git a/ipmid-new.cpp b/ipmid-new.cpp
index fd93097..c0b6c7d 100644
--- a/ipmid-new.cpp
+++ b/ipmid-new.cpp
@@ -810,7 +810,8 @@ std::unique_ptr<phosphor::host::command::Manager>& ipmid_get_host_cmd_manager()
// to be used except here (or maybe a unit test), so declare them here
extern void setIoContext(std::shared_ptr<boost::asio::io_context>& newIo);
extern void setSdBus(std::shared_ptr<sdbusplus::asio::connection>& newBus);
-
+extern void
+ setObjectServer(std::shared_ptr<sdbusplus::asio::object_server>& newServer);
int main(int argc, char* argv[])
{
// Connect to system bus
@@ -874,9 +875,10 @@ int main(int argc, char* argv[])
sdbusp->request_name("xyz.openbmc_project.Ipmi.Host");
// Add bindings for inbound IPMI requests
- auto server = sdbusplus::asio::object_server(sdbusp);
- auto iface = server.add_interface("/xyz/openbmc_project/Ipmi",
- "xyz.openbmc_project.Ipmi.Server");
+ auto server = std::make_shared<sdbusplus::asio::object_server>(sdbusp);
+ setObjectServer(server);
+ auto iface = server->add_interface("/xyz/openbmc_project/Ipmi",
+ "xyz.openbmc_project.Ipmi.Server");
iface->register_method("execute", ipmi::executionEntry);
iface->initialize();
diff --git a/libipmid/sdbus-asio.cpp b/libipmid/sdbus-asio.cpp
index 0f4cdaa..2ac9c1e 100644
--- a/libipmid/sdbus-asio.cpp
+++ b/libipmid/sdbus-asio.cpp
@@ -1,5 +1,6 @@
#include <boost/asio/io_context.hpp>
#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
#include <memory>
@@ -8,6 +9,8 @@ namespace
std::shared_ptr<boost::asio::io_context> ioCtx;
std::shared_ptr<sdbusplus::asio::connection> sdbusp;
+std::shared_ptr<sdbusplus::asio::object_server> objServer;
+
} // namespace
@@ -30,3 +33,13 @@ std::shared_ptr<sdbusplus::asio::connection> getSdBus()
{
return sdbusp;
}
+
+void setObjectServer(std::shared_ptr<sdbusplus::asio::object_server>& s)
+{
+ objServer = s;
+}
+
+std::shared_ptr<sdbusplus::asio::object_server> getObjectServer()
+{
+ return objServer;
+}
\ No newline at end of file
diff --git a/storagehandler.cpp b/storagehandler.cpp
index 405a8a1..6bc207b 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -214,6 +214,28 @@ void initSELCache()
selCacheMapInitialized = true;
}
+std::shared_ptr<sdbusplus::asio::dbus_interface> sensorInfoInterface
+ __attribute__((init_priority(101)));
+void initSensorInfoOnDBus()
+{
+ // For now the sensor path and type code are needed.
+ auto init = []() {
+ auto objServer = getObjectServer();
+ std::unordered_map<std::string, uint16_t> sensorInfo;
+ for (const auto& s : invSensors)
+ {
+ sensorInfo[s.first] = s.second.eventReadingType;
+ }
+ sensorInfoInterface =
+ objServer->add_interface("/xyz/openbmc_project/Ipmi/SensorInfo",
+ "xyz.openbmc_project.IPMI.SensorInfo");
+ sensorInfoInterface->register_property("SensorInfo", sensorInfo);
+ sensorInfoInterface->initialize();
+ };
+ boost::asio::post(*getIoContext(), std::move(init));
+}
+
+
/**
* @enum Device access mode
*/
@@ -899,6 +921,7 @@ void register_netfn_storage_functions()
{
selCacheMapInitialized = false;
initSELCache();
+ initSensorInfoOnDBus();
// Handlers with dbus-sdr handler implementation.
// Do not register the hander if it dynamic sensors stack is used.
@@ -0,0 +1,58 @@
From bfcde1e1685eeb7ca78c71bc399f39cbbf9e2ecc Mon Sep 17 00:00:00 2001
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
Date: Fri, 20 Dec 2024 16:19:42 +0800
Subject: [PATCH 2/2] ClearSel Disable check SEL Reservation
---
storagehandler.cpp | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/storagehandler.cpp b/storagehandler.cpp
index 67d76ea..389a805 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -516,7 +516,7 @@ ipmi::RspType<uint16_t // deleted record ID
ipmi::RspType<uint8_t // erase status
>
- clearSEL(uint16_t reservationID, const std::array<char, 3>& clr,
+ clearSEL(uint16_t /*reservationID*/, const std::array<char, 3>& clr,
uint8_t eraseOperation)
{
static constexpr std::array<char, 3> clrOk = {'C', 'L', 'R'};
@@ -525,10 +525,10 @@ ipmi::RspType<uint8_t // erase status
return ipmi::responseInvalidFieldRequest();
}
- if (!checkSELReservation(reservationID))
- {
- return ipmi::responseInvalidReservationId();
- }
+ // if (!checkSELReservation(reservationID))
+ // {
+ // return ipmi::responseInvalidReservationId();
+ // }
/*
* Erasure status cannot be fetched from DBUS, so always return erasure
@@ -794,6 +794,8 @@ ipmi::RspType<uint16_t // recordID of the Added SEL entry
// a maintenance procedure associated with eSEL record.
static constexpr auto procedureType = 0xDE;
cancelSELReservation();
+ std::cout << "sensorNumber:" << static_cast<int>(sensorNumber) <<"sensorType:"
+ << static_cast<int>(sensorType) << std::endl;
if (recordType == systemRecordType)
{
for (const auto& it : invSensors)
@@ -805,7 +807,7 @@ ipmi::RspType<uint16_t // recordID of the Added SEL entry
}
}
auto selDataStr = ipmi::sel::toHexStr(eventData);
-
+ std::cout << "eventData:" << selDataStr << std::endl;
bool assert = (eventDir & 0x80) ? false : true;
recordID = report<SELCreated>(Created::RECORD_TYPE(recordType),
--
2.25.1
@@ -0,0 +1,68 @@
From d329d711b3a31b55fa2299692c59a3621936327c Mon Sep 17 00:00:00 2001
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
Date: Sun, 22 Dec 2024 15:41:07 +0800
Subject: [PATCH 3/3] Add-Free-Space-to-sel-info
---
storagehandler.cpp | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/storagehandler.cpp b/storagehandler.cpp
index 389a805..476031a 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -32,6 +32,7 @@
void register_netfn_storage_functions() __attribute__((constructor));
unsigned int g_sel_time = 0xFFFFFFFF;
+constexpr uint16_t MaxEvtCount =1000;
namespace ipmi
{
namespace sensor
@@ -276,7 +277,7 @@ ipmi::RspType<uint8_t, // SEL revision.
uint16_t entries = 0;
// Most recent addition timestamp.
uint32_t addTimeStamp = ipmi::sel::invalidTimeStamp;
-
+ bool overflowFlag = false;
if (!selCacheMapInitialized)
{
// In case the initSELCache() fails, try it again
@@ -301,9 +302,24 @@ ipmi::RspType<uint8_t, // SEL revision.
}
constexpr uint8_t selVersion = ipmi::sel::selVersion;
- constexpr uint16_t freeSpace = 0xFFFF;
+ uint16_t freeSpace = 0xFFFF;
constexpr uint32_t eraseTimeStamp = ipmi::sel::invalidTimeStamp;
constexpr uint3_t reserved{0};
+ uint16_t u32FreeSpace = (MaxEvtCount - entries)*sizeof(SELEntry);
+ if (u32FreeSpace >= 0xFFFF)
+ {
+ freeSpace = 0xFFFF;
+ }
+ else
+ {
+ freeSpace = u32FreeSpace;
+ }
+
+ overflowFlag = ipmi::sel::operationSupport::overflow;
+ if (entries >= MaxEvtCount)
+ {
+ overflowFlag = true;
+ }
return ipmi::responseSuccess(
selVersion, entries, freeSpace, addTimeStamp, eraseTimeStamp,
@@ -311,7 +327,7 @@ ipmi::RspType<uint8_t, // SEL revision.
ipmi::sel::operationSupport::reserveSel,
ipmi::sel::operationSupport::partialAddSelEntry,
ipmi::sel::operationSupport::deleteSel, reserved,
- ipmi::sel::operationSupport::overflow);
+ overflowFlag);
}
ipmi_ret_t getSELEntry(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
--
2.25.1
@@ -0,0 +1,144 @@
From b56e70f39943812287be1668874f9df7bc2e3422 Mon Sep 17 00:00:00 2001
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
Date: Fri, 21 Mar 2025 09:12:49 +0800
Subject: [PATCH 4/4] Keep the current IP when setting ipsrc to static
---
transporthandler.cpp | 60 ++++++++++++++++++++++++++++++++++++--------
transporthandler.hpp | 6 +++++
2 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/transporthandler.cpp b/transporthandler.cpp
index 38faccc..bab465b 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -1,5 +1,11 @@
#include "transporthandler.hpp"
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/address_v4.hpp>
+#include <boost/asio/ip/address_v6.hpp>
+#include <stdplus/net/addr/subnet.hpp>
+#include <stdplus/raw.hpp>
+
using phosphor::logging::commit;
using phosphor::logging::elog;
using phosphor::logging::entry;
@@ -162,6 +168,23 @@ auto logWithChannel(const std::optional<ChannelParams>& params, Args&&... args)
return log<level>(std::forward<Args>(args)...);
}
+/** @brief Get / Set the Property value from phosphor-networkd EthernetInterface
+ */
+template <typename T>
+static T getEthProp(sdbusplus::bus_t& bus, const ChannelParams& params,
+ const std::string& prop)
+{
+ return std::get<T>(getDbusProperty(bus, params.service, params.logicalPath,
+ INTF_ETHERNET, prop));
+}
+template <typename T>
+static void setEthProp(sdbusplus::bus_t& bus, const ChannelParams& params,
+ const std::string& prop, const T& t)
+{
+ return setDbusProperty(bus, params.service, params.logicalPath,
+ INTF_ETHERNET, prop, t);
+}
+
EthernetInterface::DHCPConf getDHCPProperty(sdbusplus::bus_t& bus,
const ChannelParams& params)
{
@@ -316,18 +339,25 @@ void deleteObjectIfExists(sdbusplus::bus_t& bus, const std::string& service,
{
auto req = bus.new_method_call(service.c_str(), path.c_str(),
ipmi::DELETE_INTERFACE, "Delete");
- bus.call_noreply(req);
+
+ bus.call_noreply(req);
}
catch (const sdbusplus::exception_t& e)
{
if (strcmp(e.name(),
"xyz.openbmc_project.Common.Error.InternalFailure") != 0 &&
- strcmp(e.name(), "org.freedesktop.DBus.Error.UnknownObject") != 0)
+ strcmp(e.name(), "org.freedesktop.DBus.Error.UnknownObject") != 0 &&
+ strcmp(e.name(), "xyz.openbmc_project.Common.Error.NotAllowed") !=
+ 0)
{
// We want to rethrow real errors
throw;
}
}
+ catch (...)
+ {
+ throw;
+ }
}
/** @brief Sets the address info configured for the interface
@@ -383,18 +413,20 @@ void reconfigureIfAddr4(sdbusplus::bus_t& bus, const ChannelParams& params,
elog<InternalFailure>();
}
uint8_t fallbackPrefix = AddrFamily<AF_INET>::defaultPrefix;
+ auto addr = address.value_or(ifaddr->address);
+ // if (!validIntfIP(addr))
+ // {
+ // log<level::ERR>("IPv4 not unicast");
+ // elog<InternalFailure>();
+ // }
if (ifaddr)
{
fallbackPrefix = ifaddr->prefix;
deleteObjectIfExists(bus, params.service, ifaddr->path);
}
-
- if (struct in_addr nullIPv4{0};
- (address == std::nullopt && prefix != std::nullopt) ||
- (address != std::nullopt &&
- (address.value().s_addr != nullIPv4.s_addr)))
+ if (addr != stdplus::In4Addr{})
{
- createIfAddr<AF_INET>(bus, params, address.value_or(ifaddr->address),
+ createIfAddr<AF_INET>(bus, params, addr,
prefix.value_or(fallbackPrefix));
}
}
@@ -980,8 +1012,16 @@ RspType<> setLan(Context::ptr ctx, uint4_t channelBits, uint4_t reserved1,
case IPSrc::Unspecified:
case IPSrc::Static:
{
- channelCall<setDHCPv4Property>(
- channel, EthernetInterface::DHCPConf::none);
+ auto ifaddr = channelCall<getIfAddr4>(channel);
+
+ //channelCall<setDHCPv4Property>(channel, EthernetInterface::DHCPConf::none);
+ channelCall<setEthProp<bool>>(channel, "DHCP4", false);
+
+ if (ifaddr)
+ {
+ channelCall<reconfigureIfAddr4>(channel, ifaddr->address, ifaddr->prefix);
+ }
+
return responseSuccess();
}
case IPSrc::BIOS:
diff --git a/transporthandler.hpp b/transporthandler.hpp
index 8e1c4fb..a4e862b 100644
--- a/transporthandler.hpp
+++ b/transporthandler.hpp
@@ -17,6 +17,12 @@
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/exception.hpp>
+
+#include <stdplus/net/addr/ether.hpp>
+#include <stdplus/net/addr/ip.hpp>
+#include <stdplus/str/conv.hpp>
+#include <stdplus/zstring_view.hpp>
+
#include <user_channel/channel_layer.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
--
2.25.1
@@ -0,0 +1,18 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
DEPENDS += " lux-yaml-config "
EXTRA_OEMESON += " \
-Dsensor-yaml-gen=${STAGING_DIR_HOST}${datadir}/lux-yaml-config/ipmi-sensors.yaml \
-Dfru-yaml-gen=${STAGING_DIR_HOST}${datadir}/lux-yaml-config/ipmi-fru-read.yaml \
-Dinvsensor-yaml-gen=${STAGING_DIR_HOST}${datadir}/lux-yaml-config/ipmi-inventory-sensors.yaml \
"
SRC_URI += "file://0001-sel-Add-sel-log-for-clear-sel.patch \
file://0001-sensor-Add-sensor-info-on-Dbus-and-getObjectServer.patch \
file://0001-Add-sensor-type-into-SensorInfo.patch \
file://0001-Support-ipmi-cmd-set-sol-bitrate.patch \
file://0001-BMC-status-is-set-to-normal-by-default.patch \
file://0002-ClearSel-Disable-check-SEL-Reservation.patch \
file://0003-Add-Free-Space-to-sel-info.patch \
file://0004-Keep-the-current-IP-when-setting-ipsrc-to-static.patch \
"
@@ -0,0 +1,21 @@
SUMMARY = "Phosphor LED Group Management for luxshare"
PR = "r1"
LICENSE = "CLOSED"
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
inherit obmc-phosphor-utils
inherit native
PROVIDES += "virtual/phosphor-led-manager-config-native"
SRC_URI += "file://led.yaml"
S = "${WORKDIR}"
# Overwrite the example led layout yaml file prior
# to building the phosphor-led-manager package
do_install() {
SRC=${S}
DEST=${D}${datadir}/phosphor-led-manager
install -D ${SRC}/led.yaml ${DEST}/led.yaml
}
@@ -0,0 +1,25 @@
bmc_booted:
power_on:
status_ok:
health_green:
Action: 'On'
health_red:
Action: 'Off'
status_fault:
health_green:
Action: 'On'
health_red:
Action: 'On'
uid_btn:
uidbtn:
Action: 'On'
dimm_fault:
health_green:
Action: 'Off'
health_red:
Action: 'On'
Binary file not shown.
@@ -0,0 +1,9 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI += " file://ipmi_pass"
do_install:append(){
install -d ${D}/${sysconfdir}
install -m 0644 ${WORKDIR}/ipmi_pass ${D}/${sysconfdir}/
}
@@ -0,0 +1,34 @@
From e9016d4e4355229b17576658ac22a11543e8e280 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Mon, 16 Dec 2024 18:37:58 +0800
Subject: [PATCH] Change the syslog level from info to debug to reduce the
unnecessary log
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
peci.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/peci.c b/peci.c
index ab69234..1656506 100644
--- a/peci.c
+++ b/peci.c
@@ -47,13 +47,13 @@ void peci_SetDevName(char* peci_dev)
peci_name_new[DEV_NAME_SIZE - 1] = '\0';
peci_device_list[0] = peci_name_new;
peci_device_list[1] = NULL;
- syslog(LOG_INFO, "PECI set dev name to %s\n", peci_device_list[0]);
+ syslog(LOG_DEBUG, "PECI set dev name to %s\n", peci_device_list[0]);
}
else
{
peci_device_list[0] = "/dev/peci-default";
peci_device_list[1] = "/dev/peci-0";
- syslog(LOG_INFO, "PECI set dev names to %s, %s\n", peci_device_list[0],
+ syslog(LOG_DEBUG, "PECI set dev names to %s, %s\n", peci_device_list[0],
peci_device_list[1]);
}
}
--
2.34.1
@@ -0,0 +1,5 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI += " \
file://0001-Change-the-syslog-level-from-info-to-debug-to-reduce.patch \
"
@@ -0,0 +1,12 @@
diff --git a/src/FanMain.cpp b/src/FanMain.cpp
index 9c8a738..8c6991e 100644
--- a/src/FanMain.cpp
+++ b/src/FanMain.cpp
@@ -66,6 +66,7 @@ std::optional<RedundancySensor> systemRedundancy;
static const std::map<std::string, FanTypes> compatibleFanTypes = {
{"aspeed,ast2400-pwm-tacho", FanTypes::aspeed},
{"aspeed,ast2500-pwm-tacho", FanTypes::aspeed},
+ {"aspeed,ast2600-pwm-tacho", FanTypes::aspeed},
{"nuvoton,npcm750-pwm-fan", FanTypes::nuvoton},
{"hpe,gxp-fan-ctrl", FanTypes::hpe}
// add compatible string here for new fan type
@@ -0,0 +1,164 @@
From 77803d9dde846804061bd7815f42768e4fe8e48e Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Tue, 24 Sep 2024 20:28:30 +0800
Subject: [PATCH] Add Intel CPU sensors
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/IntelCPUSensor.hpp | 96 ++++++++++++++++++++++++++++++++++++++
src/IntelCPUSensorMain.cpp | 26 ++++++++---
2 files changed, 116 insertions(+), 6 deletions(-)
diff --git a/src/IntelCPUSensor.hpp b/src/IntelCPUSensor.hpp
index 0417c6e..ae90ab7 100644
--- a/src/IntelCPUSensor.hpp
+++ b/src/IntelCPUSensor.hpp
@@ -17,6 +17,12 @@
#include <variant>
#include <vector>
+extern "C"
+{
+#include <i2c/smbus.h>
+#include <linux/i2c-dev.h>
+}
+
class IntelCPUSensor :
public Sensor,
public std::enable_shared_from_this<IntelCPUSensor>
@@ -114,3 +120,93 @@ inline bool cpuIsPresent(const SensorBaseConfigMap& gpioConfig)
return resp;
}
+
+inline int i2cWriteRead(std::string& i2cDev, const uint8_t slaveAddr,
+ std::vector<uint8_t> writeData,
+ std::vector<uint8_t>& readBuf)
+{
+ int fd = open(i2cDev.c_str(), O_RDWR | O_CLOEXEC);
+ if (fd < 0)
+ {
+ std::cerr << "unable to open i2c device \n";
+ return -1;
+ }
+
+ const size_t writeCount = writeData.size();
+ const size_t readCount = readBuf.size();
+
+ int msgCount = 0;
+ struct i2c_msg i2cmsg[2];
+
+ memset(i2cmsg, 0, sizeof(i2cmsg));
+
+ if (writeCount)
+ {
+ // Data will be writtern to the slave address
+ i2cmsg[msgCount].addr = slaveAddr;
+ i2cmsg[msgCount].flags = 0x00;
+ i2cmsg[msgCount].len = writeCount;
+ i2cmsg[msgCount].buf = writeData.data();
+ msgCount++;
+ }
+
+ if (readCount)
+ {
+ // Data will be read into the buffer from the slave address
+ i2cmsg[msgCount].addr = slaveAddr;
+ i2cmsg[msgCount].flags = I2C_M_RD;
+ i2cmsg[msgCount].len = readCount;
+ i2cmsg[msgCount].buf = readBuf.data();
+ msgCount++;
+ }
+
+ struct i2c_rdwr_ioctl_data msgReadWrite;
+ memset((void*)&msgReadWrite, 0, sizeof(msgReadWrite));
+ msgReadWrite.msgs = i2cmsg;
+ msgReadWrite.nmsgs = msgCount;
+
+ int ret = ioctl(fd, I2C_RDWR, &msgReadWrite);
+ close(fd);
+ if (ret < 0)
+ {
+ std::cerr << "I2C Read Write Failed. \n";
+ return -1;
+ }
+
+ if (readCount)
+ {
+ readBuf.resize(msgReadWrite.msgs[msgCount - 1].len);
+ }
+
+ return 0;
+}
+
+inline bool cpuIsPresentCPLD(int cpuId)
+{
+ int ret = 0;
+ uint8_t index;
+ std::string i2cDev = "/dev/i2c-0";
+ // Perform the combined write/read
+
+ std::vector<uint8_t> readBuf(1);
+ std::vector<uint8_t> writeData = {0x91, 0x02};
+ const uint8_t slaveAddr = 0x0D;
+ uint8_t regVal;
+
+ ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf);
+ if (ret < 0)
+ {
+ std::cerr << "i2c failed to read regVal. \n";
+ return false;
+ }
+
+ regVal = readBuf[0];
+ if(cpuId == 1)
+ index = 1;
+ else if(cpuId == 2)
+ index = 0;
+ else
+ return false;
+
+ return (regVal & (1 << index)) == 0;
+}
diff --git a/src/IntelCPUSensorMain.cpp b/src/IntelCPUSensorMain.cpp
index 0e0083a..a955c6f 100644
--- a/src/IntelCPUSensorMain.cpp
+++ b/src/IntelCPUSensorMain.cpp
@@ -721,14 +721,28 @@ bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
std::string name = std::regex_replace(nameRaw, illegalDbusRegex,
"_");
+ int cpuId = -1;
+ auto findCpuId = cfg.find("CpuID");
+ if (findCpuId != cfg.end())
+ {
+ cpuId = std::visit(VariantToUnsignedIntVisitor(),
+ findCpuId->second);
+ }
+
auto present = std::optional<bool>();
- // if we can't detect it via gpio, we set presence later
- for (const auto& [suppIntf, suppCfg] : cfgData)
+ auto findPresence = cfg.find("Presence");
+ if (findPresence != cfg.end())
{
- if (suppIntf.find("PresenceGpio") != std::string::npos)
- {
- present = cpuIsPresent(suppCfg);
- break;
+ std::string method = std::visit(VariantToStringVisitor(),
+ findPresence->second);
+ if(method == "GPIO") {
+ for (const auto& [suppIntf, suppCfg] : cfgData)
+ present = cpuIsPresent(suppCfg);
+ } else if(method == "CPLD") {
+ if(cpuId != -1)
+ present = cpuIsPresentCPLD(cpuId);
+ } else {
+ std::cerr << "Invalid Presence value \n";
}
}
--
2.34.1
@@ -0,0 +1,544 @@
From b89bbf4a2a349cfc9cb047fce70ee064a193f82e Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Wed, 25 Sep 2024 19:27:30 +0800
Subject: [PATCH] Add DIMM Temp sensors
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
meson_options.txt | 1 +
service_files/meson.build | 1 +
...xyz.openbmc_project.dimmtempsensor.service | 13 ++
src/DIMMTempSensor.cpp | 194 +++++++++++++++++
src/DIMMTempSensor.hpp | 43 ++++
src/DIMMTempSensorMain.cpp | 201 ++++++++++++++++++
src/meson.build | 15 ++
7 files changed, 468 insertions(+)
create mode 100644 service_files/xyz.openbmc_project.dimmtempsensor.service
create mode 100644 src/DIMMTempSensor.cpp
create mode 100644 src/DIMMTempSensor.hpp
create mode 100644 src/DIMMTempSensorMain.cpp
diff --git a/meson_options.txt b/meson_options.txt
index d6a8b96..79bf6b2 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -12,3 +12,4 @@ option('external', type: 'feature', value: 'enabled', description: 'Enable Exter
option('tests', type: 'feature', value: 'enabled', description: 'Build tests.',)
option('validate-unsecure-feature', type : 'feature', value : 'disabled', description : 'Enables unsecure features required by validation. Note: mustbe turned off for production images.',)
option('insecure-sensor-override', type : 'feature', value : 'disabled', description : 'Enables Sensor override feature without any check.',)
+option('dimmtemp', type: 'feature', value: 'enabled', description: 'Enable DIMMtemp sensor.',)
diff --git a/service_files/meson.build b/service_files/meson.build
index 5f5b78c..c60f76c 100644
--- a/service_files/meson.build
+++ b/service_files/meson.build
@@ -10,6 +10,7 @@ unit_files = [
['nvme', 'xyz.openbmc_project.nvmesensor.service'],
['psu', 'xyz.openbmc_project.psusensor.service'],
['external', 'xyz.openbmc_project.externalsensor.service'],
+ ['dimmtemp', 'xyz.openbmc_project.dimmtempsensor.service'],
]
foreach tuple : unit_files
diff --git a/service_files/xyz.openbmc_project.dimmtempsensor.service b/service_files/xyz.openbmc_project.dimmtempsensor.service
new file mode 100644
index 0000000..bb31e3a
--- /dev/null
+++ b/service_files/xyz.openbmc_project.dimmtempsensor.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=DIMM Temp Sensor
+StopWhenUnneeded=false
+Requires=xyz.openbmc_project.EntityManager.service
+After=xyz.openbmc_project.EntityManager.service
+
+[Service]
+Restart=always
+RestartSec=5
+ExecStart=/usr/bin/dimmtempsensor
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/src/DIMMTempSensor.cpp b/src/DIMMTempSensor.cpp
new file mode 100644
index 0000000..7b0a1cd
--- /dev/null
+++ b/src/DIMMTempSensor.cpp
@@ -0,0 +1,194 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#include "DIMMTempSensor.hpp"
+
+#include "Utils.hpp"
+#include "VariantVisitors.hpp"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/container/flat_map.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+#include <chrono>
+#include <cmath>
+#include <functional>
+#include <iostream>
+#include <limits>
+#include <memory>
+#include <numeric>
+#include <string>
+#include <vector>
+
+#include <peci.h>
+extern "C"
+{
+#include <i2c/smbus.h>
+#include <linux/i2c-dev.h>
+}
+
+constexpr const bool debug = false;
+
+#define PECI_MBX_INDEX_DDR_DIMM_TEMP 0x0E
+
+DIMMTempSensor::DIMMTempSensor(
+ std::shared_ptr<sdbusplus::asio::connection>& conn,
+ boost::asio::io_context& io, const std::string& sensorName,
+ const std::string& sensorConfiguration,
+ sdbusplus::asio::object_server& objectServer,
+ std::vector<thresholds::Threshold>&& thresholdData, const double maxReading,
+ const double minReading, const std::string& sensorType, const char* units,
+ const float pollRate, PowerState readState, uint8_t peciBus,
+ uint8_t peciAddr, uint8_t rank, double calibOffset) :
+ Sensor(boost::replace_all_copy(sensorName, " ", "_"),
+ std::move(thresholdData), sensorConfiguration, "", false, false,
+ maxReading, minReading, conn, readState),
+ sensorPollMs(static_cast<unsigned int>(pollRate * 1000)), peciBus(peciBus),
+ peciAddr(peciAddr), dimmRank(rank), calibOffset(calibOffset),
+ objectServer(objectServer), waitTimer(io)
+{
+ std::string interfacePath = "/xyz/openbmc_project/sensors/" + sensorType +
+ "/" + name;
+
+ sensorInterface = objectServer.add_interface(
+ interfacePath, "xyz.openbmc_project.Sensor.Value");
+
+ for (const auto& threshold : thresholds)
+ {
+ std::string interface = thresholds::getInterface(threshold.level);
+ thresholdInterfaces[static_cast<size_t>(threshold.level)] =
+ objectServer.add_interface(interfacePath, interface);
+ }
+
+ association = objectServer.add_interface(interfacePath,
+ association::interface);
+
+ setInitialProperties(units);
+}
+
+DIMMTempSensor::~DIMMTempSensor()
+{
+ waitTimer.cancel();
+
+ for (const auto& iface : thresholdInterfaces)
+ {
+ objectServer.remove_interface(iface);
+ }
+
+ objectServer.remove_interface(sensorInterface);
+ objectServer.remove_interface(association);
+}
+
+void DIMMTempSensor::init(void)
+{
+ read();
+}
+
+void DIMMTempSensor::checkThresholds(void)
+{
+ thresholds::checkThresholds(this);
+}
+
+int DIMMTempSensor::getDIMMRegsInfoWord(double* ps64data)
+{
+ int ret = -1;
+ ret = getDIMMRegsTemp(ps64data);
+ return ret;
+}
+
+int DIMMTempSensor::getDIMMRegsTemp(double* ps64data)
+{
+ int peciFd = -1;
+ std::string peciDevPath = "/dev/peci-" + std::to_string(peciBus);
+
+ peci_SetDevName(peciDevPath.data());
+
+ if ((peci_Lock(&peciFd, PECI_NO_WAIT) != PECI_CC_SUCCESS) ||
+ (peciFd < 0))
+ {
+ std::cerr << "unable to open " << peciDevPath << " "
+ << std::strerror(errno) << "\n";
+ return -1;
+ }
+
+ if (peci_Ping(peciAddr) == PECI_CC_SUCCESS)
+ {
+ std::array<uint8_t, 8> pkgConfig{};
+ uint8_t cc = 0;
+
+ if (peci_RdPkgConfig(peciAddr, PECI_MBX_INDEX_DDR_DIMM_TEMP,
+ dimmRank, 4, &pkgConfig[0],
+ &cc) != PECI_CC_SUCCESS)
+ {
+ std::cerr << "PECI RdPkgConfig returns failure" << "\n";
+ return -1;
+ }
+
+ *ps64data = (double)pkgConfig[0];
+
+ } else {
+ std::cerr << "PECI Ping returns failure" << "\n";
+ return -1;
+ }
+ peci_Unlock(peciFd);
+ return 0;
+}
+
+void DIMMTempSensor::read(void)
+{
+ waitTimer.expires_after(std::chrono::milliseconds(sensorPollMs));
+ waitTimer.async_wait([this](const boost::system::error_code& ec) {
+ if (ec == boost::asio::error::operation_aborted)
+ {
+ return; // we're being cancelled
+ }
+ // read timer error
+ if (ec)
+ {
+ std::cerr << "timer error\n";
+ return;
+ }
+ if (readingStateGood())
+ {
+ double temp = 0;
+ int ret = getDIMMRegsInfoWord(&temp);
+ if (ret == 0)
+ {
+ double v = temp;
+ if constexpr (debug)
+ {
+ std::cerr << "Value update to " << v << ", raw reading "
+ << temp << "\n";
+ }
+ v += calibOffset;
+ updateValue(v);
+ }
+ else
+ {
+ std::cerr << "Invalid read getDIMMRegsInfoWord.\n";
+ incrementError();
+ }
+ }
+ else
+ {
+ updateValue(std::numeric_limits<double>::quiet_NaN());
+ }
+ read();
+ });
+}
diff --git a/src/DIMMTempSensor.hpp b/src/DIMMTempSensor.hpp
new file mode 100644
index 0000000..dd52053
--- /dev/null
+++ b/src/DIMMTempSensor.hpp
@@ -0,0 +1,43 @@
+#pragma once
+#include "sensor.hpp"
+
+#include <boost/asio/steady_timer.hpp>
+#include <boost/container/flat_map.hpp>
+
+#include <chrono>
+#include <limits>
+#include <memory>
+#include <string>
+#include <vector>
+
+struct DIMMTempSensor : public Sensor
+{
+ DIMMTempSensor(std::shared_ptr<sdbusplus::asio::connection>& conn,
+ boost::asio::io_context& io, const std::string& name,
+ const std::string& sensorConfiguration,
+ sdbusplus::asio::object_server& objectServer,
+ std::vector<thresholds::Threshold>&& thresholds,
+ const double maxReading, const double minReading,
+ const std::string& sensorType, const char* units,
+ const float pollRate, PowerState readState, uint8_t peciBus,
+ uint8_t peciAddr, uint8_t rank, double calibOffset);
+ ~DIMMTempSensor() override;
+
+ void checkThresholds(void) override;
+ void read(void);
+ void init(void);
+
+ unsigned int sensorPollMs;
+
+ uint8_t peciBus;
+ uint8_t peciAddr;
+ uint8_t dimmRank;
+ double calibOffset;
+
+ private:
+ int getDIMMRegsInfoWord(double* ps64data);
+ int getDIMMRegsTemp(double* ps64data);
+ // int getDIMMRegsPower(double* ps64data);
+ sdbusplus::asio::object_server& objectServer;
+ boost::asio::steady_timer waitTimer;
+};
diff --git a/src/DIMMTempSensorMain.cpp b/src/DIMMTempSensorMain.cpp
new file mode 100644
index 0000000..042659f
--- /dev/null
+++ b/src/DIMMTempSensorMain.cpp
@@ -0,0 +1,201 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+// #include <math.h>
+#include <DIMMTempSensor.hpp>
+#include <Utils.hpp>
+#include <VariantVisitors.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/container/flat_map.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+#include <chrono>
+#include <functional>
+#include <iostream>
+#include <limits>
+#include <memory>
+#include <numeric>
+#include <string>
+#include <vector>
+
+constexpr const bool debug = false;
+constexpr const char* configInterface =
+ "xyz.openbmc_project.Configuration.DIMMTemp";
+
+static constexpr double maxTempReading = 127;
+static constexpr double minTempReading = -128;
+static constexpr double maxPowerReading = 500;
+static constexpr double minPowerReading = 0;
+
+void createSensors(
+ boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
+ boost::container::flat_map<std::string, std::unique_ptr<DIMMTempSensor>>&
+ sensors,
+ std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
+{
+ if (!dbusConnection)
+ {
+ std::cerr << "Connection not created\n";
+ return;
+ }
+
+ dbusConnection->async_method_call(
+ [&io, &objectServer, &dbusConnection, &sensors](
+ boost::system::error_code ec, const ManagedObjectType& resp) {
+ if (ec)
+ {
+ std::cerr << "Error contacting entity manager\n";
+ return;
+ }
+ for (const auto& pathPair : resp)
+ {
+ for (const auto& entry : pathPair.second)
+ {
+ if (entry.first != configInterface)
+ {
+ continue;
+ }
+ std::string name = loadVariant<std::string>(entry.second,
+ "Name");
+
+ std::vector<thresholds::Threshold> sensorThresholds;
+ if (!parseThresholdsFromConfig(pathPair.second,
+ sensorThresholds))
+ {
+ std::cerr << "error populating thresholds for " << name
+ << "\n";
+ }
+
+ float pollRate = loadVariant<double>(entry.second, "PollRate");
+ uint8_t peciBus = loadVariant<uint8_t>(entry.second, "Bus");
+ uint8_t peciAddr = loadVariant<uint8_t>(entry.second, "Address");
+ uint8_t dimmRank = loadVariant<uint8_t>(entry.second, "Rank");
+
+ /* calibration offset */
+ auto findCalibOffset = entry.second.find("Offset");
+ double calibOffset = 0;
+ if (findCalibOffset != entry.second.end())
+ {
+ calibOffset = std::visit(VariantToDoubleVisitor(),
+ findCalibOffset->second);
+ }
+
+ /* PowerState */
+ auto findPowerOn = entry.second.find("PowerState");
+ PowerState readState = PowerState::always;
+ if (findPowerOn != entry.second.end())
+ {
+ std::string powerState = std::visit(
+ VariantToStringVisitor(), findPowerOn->second);
+ setReadState(powerState, readState);
+ }
+
+ if constexpr (debug)
+ {
+ std::cerr << "Configuration parsed for \n\t" << entry.first
+ << "\n"
+ << "with\n"
+ << "\tName: " << name << "\n"
+ << "\tBus: " << static_cast<int>(peciBus) << "\n"
+ << "\tAddress: " << static_cast<int>(peciAddr)
+ << "\n"
+ << "\tDimmRank: " << static_cast<int>(dimmRank)
+ << "\tOffset: " << calibOffset << "\n";
+ }
+
+ auto& sensor = sensors[name];
+ sensor = nullptr;
+
+ if (name.ends_with("_Temp"))
+ {
+ sensor = std::make_unique<DIMMTempSensor>(
+ dbusConnection, io, name, pathPair.first, objectServer,
+ std::move(sensorThresholds), maxTempReading,
+ minTempReading, "temperature",
+ sensor_paths::unitDegreesC, pollRate, readState,
+ peciBus, peciAddr, dimmRank, 0);
+ }
+ else if (name.ends_with("_Power"))
+ {
+ sensor = std::make_unique<DIMMTempSensor>(
+ dbusConnection, io, name, pathPair.first, objectServer,
+ std::move(sensorThresholds), maxPowerReading,
+ minPowerReading, "power", sensor_paths::unitWatts,
+ pollRate, readState, peciBus, peciAddr, dimmRank, 0);
+ }
+
+ sensor->init();
+ }
+ }
+ },
+ entityManagerName, "/xyz/openbmc_project/inventory",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+}
+
+int main()
+{
+ boost::asio::io_context io;
+ auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
+ sdbusplus::asio::object_server objectServer(systemBus, true);
+
+ objectServer.add_manager("/xyz/openbmc_project/sensors");
+ systemBus->request_name("xyz.openbmc_project.DIMMTempSensor");
+
+ boost::container::flat_map<std::string, std::unique_ptr<DIMMTempSensor>>
+ sensors;
+ boost::asio::post(
+ io, [&]() { createSensors(io, objectServer, sensors, systemBus); });
+
+ boost::asio::steady_timer configTimer(io);
+ std::function<void(sdbusplus::message::message&)> eventHandler =
+ [&](sdbusplus::message::message&) {
+ configTimer.expires_after(std::chrono::seconds(1));
+ // create a timer because normally multiple properties change
+ configTimer.async_wait([&](const boost::system::error_code& ec) {
+ if (ec == boost::asio::error::operation_aborted)
+ {
+ return; // we're being canceled
+ }
+ // config timer error
+ if (ec)
+ {
+ std::cerr << "timer error\n";
+ return;
+ }
+ createSensors(io, objectServer, sensors, systemBus);
+ if (sensors.empty())
+ {
+ std::cout << "Configuration not detected\n";
+ }
+ });
+ };
+
+ sdbusplus::bus::match::match configMatch(
+ static_cast<sdbusplus::bus::bus&>(*systemBus),
+ "type='signal',member='PropertiesChanged',"
+ "path_namespace='" +
+ std::string(inventoryPath) +
+ "',"
+ "arg0namespace='" +
+ configInterface + "'",
+ eventHandler);
+
+ io.run();
+}
diff --git a/src/meson.build b/src/meson.build
index 9f56c31..7c33e3a 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -234,3 +234,18 @@ if get_option('external').enabled()
install: true,
)
endif
+
+if get_option('dimmtemp').allowed()
+ executable(
+ 'dimmtempsensor',
+ 'DIMMTempSensor.cpp',
+ 'DIMMTempSensorMain.cpp',
+ dependencies: [
+ default_deps,
+ thresholds_dep,
+ utils_dep,
+ peci_dep,
+ ],
+ install: true,
+ )
+endif
\ No newline at end of file
--
2.34.1
@@ -0,0 +1,23 @@
diff --git a/src/sensor.hpp b/src/sensor.hpp
index 9f092c6..e48036a 100644
--- a/src/sensor.hpp
+++ b/src/sensor.hpp
@@ -265,10 +265,18 @@ struct Sensor
sensorInterface->register_property("Unit", unit);
sensorInterface->register_property("MaxValue", maxValue);
sensorInterface->register_property("MinValue", minValue);
+ //Allows external overwrite DIMM temperature
+ if(sensorInterface->get_object_path().find("DIMM_CPU") != std::string::npos ){
+ sensorInterface->register_property(
+ "Value", value, [this](const double& newValue, double& oldValue) {
+ oldValue=newValue;return true;
+ });
+ }else{
sensorInterface->register_property(
"Value", value, [this](const double& newValue, double& oldValue) {
return setSensorValue(newValue, oldValue);
});
+ }
fillMissingThresholds();
@@ -0,0 +1,188 @@
From c049cf37710acb91b0361267048f8a71600677c1 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Thu, 24 Oct 2024 16:40:34 +0800
Subject: [PATCH] Add dimmLEDInterface and dimmLEDState property
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/DIMMTempSensor.cpp | 51 ++++++++++++++++++++++++++++++++------
src/DIMMTempSensor.hpp | 7 ++++--
src/DIMMTempSensorMain.cpp | 1 +
src/sensor.hpp | 1 +
4 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/src/DIMMTempSensor.cpp b/src/DIMMTempSensor.cpp
index 6fba752..94843d2 100644
--- a/src/DIMMTempSensor.cpp
+++ b/src/DIMMTempSensor.cpp
@@ -60,7 +60,7 @@ DIMMTempSensor::DIMMTempSensor(
std::move(thresholdData), sensorConfiguration, "", false, false,
maxReading, minReading, conn, readState),
sensorPollMs(static_cast<unsigned int>(pollRate * 1000)), peciBus(peciBus),
- peciAddr(peciAddr), dimmRank(rank), calibOffset(calibOffset),
+ peciAddr(peciAddr), dimmRank(rank), calibOffset(calibOffset), dimmLEDState("OFF"),
objectServer(objectServer), waitTimer(io)
{
std::string interfacePath = "/xyz/openbmc_project/sensors/" + sensorType +
@@ -69,6 +69,16 @@ DIMMTempSensor::DIMMTempSensor(
sensorInterface = objectServer.add_interface(
interfacePath, "xyz.openbmc_project.Sensor.Value");
+ dimmLEDInterface = objectServer.add_interface(
+ interfacePath, "xyz.openbmc_project.Sensor.dimmLED");
+
+ dimmLEDInterface->register_property(
+ "LEDState", dimmLEDState, [this](const std::string& newValue, std::string& oldValue) {
+ oldValue = newValue; return true;
+ });
+
+ dimmLEDInterface->initialize();
+
for (const auto& threshold : thresholds)
{
std::string interface = thresholds::getInterface(threshold.level);
@@ -95,7 +105,7 @@ DIMMTempSensor::~DIMMTempSensor()
objectServer.remove_interface(association);
}
-void DIMMTempSensor::init(void)
+void DIMMTempSensor::init()
{
read();
}
@@ -124,7 +134,7 @@ int DIMMTempSensor::getDIMMRegsTemp(double* ps64data)
{
std::cerr << "unable to open " << peciDevPath << " "
<< std::strerror(errno) << "\n";
- return -1;
+ goto err;
}
if (peci_Ping(peciAddr) == PECI_CC_SUCCESS)
@@ -137,20 +147,25 @@ int DIMMTempSensor::getDIMMRegsTemp(double* ps64data)
&cc) != PECI_CC_SUCCESS)
{
std::cerr << "PECI RdPkgConfig returns failure" << "\n";
- return -1;
+ goto err;
}
*ps64data = (double)pkgConfig[0];
} else {
std::cerr << "PECI Ping returns failure" << "\n";
- return -1;
+ goto err;
}
+
peci_Unlock(peciFd);
return 0;
+
+err:
+ peci_Unlock(peciFd);
+ return -1;
}
-void DIMMTempSensor::read(void)
+void DIMMTempSensor::read()
{
waitTimer.expires_after(std::chrono::milliseconds(sensorPollMs));
waitTimer.async_wait([this](const boost::system::error_code& ec) {
@@ -177,18 +192,40 @@ void DIMMTempSensor::read(void)
<< temp << "\n";
}
v += calibOffset;
+
+
+ updateDIMMLedState(dimmLEDInterface, dimmLEDState, "ON", "LEDState");
updateValue(v);
}
else
{
- std::cerr << "Invalid read getDIMMRegsInfoWord.\n";
+ std::cerr << "Fail to read DIMM tempture.\n";
+ updateDIMMLedState(dimmLEDInterface, dimmLEDState, "OFF", "LEDState");
incrementError();
}
}
else
{
updateValue(std::numeric_limits<double>::quiet_NaN());
+ updateDIMMLedState(dimmLEDInterface, dimmLEDState, "OFF", "LEDState");
}
read();
});
}
+
+void DIMMTempSensor::updateDIMMLedState(std::shared_ptr<sdbusplus::asio::dbus_interface>& interface,
+ std::string& oldState, const std::string& newState, const char* dbusPropertyName)
+{
+ if(oldState == newState)
+ return;
+ oldState = newState;
+
+ if (interface &&
+ !(interface->set_property(dbusPropertyName, newState)))
+ {
+ std::cerr << "error setting property " << dbusPropertyName
+ << " to " << newState << "\n";
+ }
+
+ return;
+}
diff --git a/src/DIMMTempSensor.hpp b/src/DIMMTempSensor.hpp
index dd52053..9aea017 100644
--- a/src/DIMMTempSensor.hpp
+++ b/src/DIMMTempSensor.hpp
@@ -24,8 +24,8 @@ struct DIMMTempSensor : public Sensor
~DIMMTempSensor() override;
void checkThresholds(void) override;
- void read(void);
- void init(void);
+ void read();
+ void init();
unsigned int sensorPollMs;
@@ -33,10 +33,13 @@ struct DIMMTempSensor : public Sensor
uint8_t peciAddr;
uint8_t dimmRank;
double calibOffset;
+ std::string dimmLEDState;
private:
int getDIMMRegsInfoWord(double* ps64data);
int getDIMMRegsTemp(double* ps64data);
+ void updateDIMMLedState(std::shared_ptr<sdbusplus::asio::dbus_interface>& interface,
+ std::string& oldState, const std::string& newState, const char* dbusPropertyName);
// int getDIMMRegsPower(double* ps64data);
sdbusplus::asio::object_server& objectServer;
boost::asio::steady_timer waitTimer;
diff --git a/src/DIMMTempSensorMain.cpp b/src/DIMMTempSensorMain.cpp
index 042659f..5c3573c 100644
--- a/src/DIMMTempSensorMain.cpp
+++ b/src/DIMMTempSensorMain.cpp
@@ -87,6 +87,7 @@ void createSensors(
uint8_t peciBus = loadVariant<uint8_t>(entry.second, "Bus");
uint8_t peciAddr = loadVariant<uint8_t>(entry.second, "Address");
uint8_t dimmRank = loadVariant<uint8_t>(entry.second, "Rank");
+ //std::string LEDState = loadVariant<std::string>(entry.second, "LEDState");
/* calibration offset */
auto findCalibOffset = entry.second.find("Offset");
diff --git a/src/sensor.hpp b/src/sensor.hpp
index e48036a..2c46771 100644
--- a/src/sensor.hpp
+++ b/src/sensor.hpp
@@ -97,6 +97,7 @@ struct Sensor
std::shared_ptr<sdbusplus::asio::dbus_interface> availableInterface;
std::shared_ptr<sdbusplus::asio::dbus_interface> operationalInterface;
std::shared_ptr<sdbusplus::asio::dbus_interface> valueMutabilityInterface;
+ std::shared_ptr<sdbusplus::asio::dbus_interface> dimmLEDInterface;
double value = std::numeric_limits<double>::quiet_NaN();
double rawValue = std::numeric_limits<double>::quiet_NaN();
bool overriddenState = false;
--
2.34.1
@@ -0,0 +1,87 @@
From 2a4ceaf845fd605e4f44740e08bd92ddb868c87a Mon Sep 17 00:00:00 2001
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
Date: Mon, 11 Nov 2024 13:07:48 +0800
Subject: [PATCH 6/6] Add PWM sensors
---
src/FanMain.cpp | 6 ++----
src/PwmSensor.cpp | 15 +++++++++++++++
src/PwmSensor.hpp | 2 ++
3 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/src/FanMain.cpp b/src/FanMain.cpp
index 8c6991e..fc81a93 100644
--- a/src/FanMain.cpp
+++ b/src/FanMain.cpp
@@ -161,7 +161,7 @@ bool findPwmPath(const fs::path& directory, unsigned int pwm, fs::path& pwmPath)
std::error_code ec;
/* Assuming PWM file is appeared in the same directory as fanX_input */
- auto path = directory / ("pwm" + std::to_string(pwm + 1));
+ auto path = directory / ("pwm" + std::to_string(pwm));
bool exists = fs::exists(path, ec);
if (ec || !exists)
@@ -484,12 +484,10 @@ void createSensors(
<< " no pwm channel found!\n";
continue;
}
-
- fs::path pwmEnableFile = "pwm" + std::to_string(pwm + 1) +
+ fs::path pwmEnableFile = "pwm" + std::to_string(pwm) +
"_enable";
fs::path enablePath = pwmPath.parent_path() / pwmEnableFile;
enablePwm(enablePath);
-
/* use pwm name override if found in configuration else
* use default */
auto findOverride = connector->second.find("PwmName");
diff --git a/src/PwmSensor.cpp b/src/PwmSensor.cpp
index ad54dfe..eadf1bc 100644
--- a/src/PwmSensor.cpp
+++ b/src/PwmSensor.cpp
@@ -43,6 +43,19 @@ PwmSensor::PwmSensor(const std::string& name, const std::string& sysPath,
sensorInterface = objectServer.add_interface(
"/xyz/openbmc_project/sensors/fan_pwm/" + name,
"xyz.openbmc_project.Sensor.Value");
+ aInterface = objectServer.add_interface(
+ "/xyz/openbmc_project/sensors/fan_pwm/" + name,
+ "xyz.openbmc_project.State.Decorator.Availability");
+ fInterface = objectServer.add_interface(
+ "/xyz/openbmc_project/sensors/fan_pwm/" + name,
+ "xyz.openbmc_project.State.Decorator.OperationalStatus");
+
+
+ aInterface->register_property("Available", true,[](const bool &req, bool &res)
+ {res = req;return true; });
+ fInterface->register_property("Functional", true,[](const bool &req, bool &res)
+ {res = req;return true; });
+
uint32_t pwmValue = getValue(false);
if (sensorType == "PSU")
{
@@ -150,6 +163,8 @@ PwmSensor::PwmSensor(const std::string& name, const std::string& sysPath,
});
sensorInterface->initialize();
+ aInterface->initialize();
+ fInterface->initialize();
controlInterface->initialize();
if (isValueMutable)
diff --git a/src/PwmSensor.hpp b/src/PwmSensor.hpp
index f70079b..a1f2277 100644
--- a/src/PwmSensor.hpp
+++ b/src/PwmSensor.hpp
@@ -22,6 +22,8 @@ class PwmSensor
sdbusplus::asio::object_server& objectServer;
std::string name;
std::shared_ptr<sdbusplus::asio::dbus_interface> sensorInterface;
+ std::shared_ptr<sdbusplus::asio::dbus_interface> aInterface;
+ std::shared_ptr<sdbusplus::asio::dbus_interface> fInterface;
std::shared_ptr<sdbusplus::asio::dbus_interface> controlInterface;
std::shared_ptr<sdbusplus::asio::dbus_interface> association;
std::shared_ptr<sdbusplus::asio::dbus_interface> valueMutabilityInterface;
--
2.25.1
@@ -0,0 +1,108 @@
From 8ee0eb0cdbb7c3570c4a5ae65a44b22edb3b70a6 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Mon, 11 Nov 2024 15:25:16 +0800
Subject: [PATCH] Remove updateDIMMLedState function as dimm presence state
will be set by bios
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/DIMMTempSensor.cpp | 25 ++-----------------------
src/DIMMTempSensor.hpp | 3 ---
src/DIMMTempSensorMain.cpp | 1 -
3 files changed, 2 insertions(+), 27 deletions(-)
diff --git a/src/DIMMTempSensor.cpp b/src/DIMMTempSensor.cpp
index 94843d2..1399995 100644
--- a/src/DIMMTempSensor.cpp
+++ b/src/DIMMTempSensor.cpp
@@ -60,7 +60,7 @@ DIMMTempSensor::DIMMTempSensor(
std::move(thresholdData), sensorConfiguration, "", false, false,
maxReading, minReading, conn, readState),
sensorPollMs(static_cast<unsigned int>(pollRate * 1000)), peciBus(peciBus),
- peciAddr(peciAddr), dimmRank(rank), calibOffset(calibOffset), dimmLEDState("OFF"),
+ peciAddr(peciAddr), dimmRank(rank), calibOffset(calibOffset),
objectServer(objectServer), waitTimer(io)
{
std::string interfacePath = "/xyz/openbmc_project/sensors/" + sensorType +
@@ -72,6 +72,7 @@ DIMMTempSensor::DIMMTempSensor(
dimmLEDInterface = objectServer.add_interface(
interfacePath, "xyz.openbmc_project.Sensor.dimmLED");
+ std::string dimmLEDState = "OFF";
dimmLEDInterface->register_property(
"LEDState", dimmLEDState, [this](const std::string& newValue, std::string& oldValue) {
oldValue = newValue; return true;
@@ -192,40 +193,18 @@ void DIMMTempSensor::read()
<< temp << "\n";
}
v += calibOffset;
-
-
- updateDIMMLedState(dimmLEDInterface, dimmLEDState, "ON", "LEDState");
updateValue(v);
}
else
{
std::cerr << "Fail to read DIMM tempture.\n";
- updateDIMMLedState(dimmLEDInterface, dimmLEDState, "OFF", "LEDState");
incrementError();
}
}
else
{
updateValue(std::numeric_limits<double>::quiet_NaN());
- updateDIMMLedState(dimmLEDInterface, dimmLEDState, "OFF", "LEDState");
}
read();
});
}
-
-void DIMMTempSensor::updateDIMMLedState(std::shared_ptr<sdbusplus::asio::dbus_interface>& interface,
- std::string& oldState, const std::string& newState, const char* dbusPropertyName)
-{
- if(oldState == newState)
- return;
- oldState = newState;
-
- if (interface &&
- !(interface->set_property(dbusPropertyName, newState)))
- {
- std::cerr << "error setting property " << dbusPropertyName
- << " to " << newState << "\n";
- }
-
- return;
-}
diff --git a/src/DIMMTempSensor.hpp b/src/DIMMTempSensor.hpp
index 9aea017..1f7d8d3 100644
--- a/src/DIMMTempSensor.hpp
+++ b/src/DIMMTempSensor.hpp
@@ -33,13 +33,10 @@ struct DIMMTempSensor : public Sensor
uint8_t peciAddr;
uint8_t dimmRank;
double calibOffset;
- std::string dimmLEDState;
private:
int getDIMMRegsInfoWord(double* ps64data);
int getDIMMRegsTemp(double* ps64data);
- void updateDIMMLedState(std::shared_ptr<sdbusplus::asio::dbus_interface>& interface,
- std::string& oldState, const std::string& newState, const char* dbusPropertyName);
// int getDIMMRegsPower(double* ps64data);
sdbusplus::asio::object_server& objectServer;
boost::asio::steady_timer waitTimer;
diff --git a/src/DIMMTempSensorMain.cpp b/src/DIMMTempSensorMain.cpp
index 5c3573c..042659f 100644
--- a/src/DIMMTempSensorMain.cpp
+++ b/src/DIMMTempSensorMain.cpp
@@ -87,7 +87,6 @@ void createSensors(
uint8_t peciBus = loadVariant<uint8_t>(entry.second, "Bus");
uint8_t peciAddr = loadVariant<uint8_t>(entry.second, "Address");
uint8_t dimmRank = loadVariant<uint8_t>(entry.second, "Rank");
- //std::string LEDState = loadVariant<std::string>(entry.second, "LEDState");
/* calibration offset */
auto findCalibOffset = entry.second.find("Offset");
--
2.34.1
@@ -0,0 +1,223 @@
From 8e64d466ebd5a92ec7f500ddaa0148404acb5435 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Wed, 13 Nov 2024 20:25:01 +0800
Subject: [PATCH] Fix issue that the reading value of dimm temp sensor is zero
even dimm is not present
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/DIMMTempSensor.cpp | 62 +++++++++++++++++++++++++++++++++-----
src/DIMMTempSensor.hpp | 19 +++++++-----
src/DIMMTempSensorMain.cpp | 18 ++++++-----
3 files changed, 75 insertions(+), 24 deletions(-)
diff --git a/src/DIMMTempSensor.cpp b/src/DIMMTempSensor.cpp
index 1399995..d290d63 100644
--- a/src/DIMMTempSensor.cpp
+++ b/src/DIMMTempSensor.cpp
@@ -44,9 +44,36 @@ extern "C"
}
constexpr const bool debug = false;
-
+constexpr auto dimmSensorInterface = "xyz.openbmc_project.Sensor.dimmLED";
+constexpr auto dimmSensorPath = "/xyz/openbmc_project/sensors/temperature/";
#define PECI_MBX_INDEX_DDR_DIMM_TEMP 0x0E
+static void setupDimmLEDMatch(
+ std::vector<sdbusplus::bus::match_t>& matches, sdbusplus::bus_t& connection,
+ const std::string& sensorName, std::function<void(const std::string&)>&& callback)
+{
+ std::function<void(sdbusplus::message_t & message)> eventHandler =
+ [callback{std::move(callback)}](sdbusplus::message_t& message) {
+ std::string objectName;
+ boost::container::flat_map<std::string, std::variant<std::string>>
+ values;
+ message.read(objectName, values);
+ auto findValue = values.find("LEDState");
+ if (findValue == values.end())
+ {
+ return;
+ }
+ std::string value = std::visit(VariantToStringVisitor(), findValue->second);
+
+ callback(value);
+ };
+ matches.emplace_back(connection,
+ "type='signal',member='PropertiesChanged',path_namespace='" +
+ std::string(dimmSensorPath) + std::string(sensorName) + "',arg0namespace='" +
+ std::string(dimmSensorInterface) + "'",
+ std::move(eventHandler));
+}
+
DIMMTempSensor::DIMMTempSensor(
std::shared_ptr<sdbusplus::asio::connection>& conn,
boost::asio::io_context& io, const std::string& sensorName,
@@ -54,14 +81,14 @@ DIMMTempSensor::DIMMTempSensor(
sdbusplus::asio::object_server& objectServer,
std::vector<thresholds::Threshold>&& thresholdData, const double maxReading,
const double minReading, const std::string& sensorType, const char* units,
- const float pollRate, PowerState readState, uint8_t peciBus,
- uint8_t peciAddr, uint8_t rank, double calibOffset) :
+ const float pollRate, PowerState readState, double calibOffset,
+ uint8_t peciBus, uint8_t peciAddr, uint8_t rank) :
Sensor(boost::replace_all_copy(sensorName, " ", "_"),
std::move(thresholdData), sensorConfiguration, "", false, false,
maxReading, minReading, conn, readState),
- sensorPollMs(static_cast<unsigned int>(pollRate * 1000)), peciBus(peciBus),
- peciAddr(peciAddr), dimmRank(rank), calibOffset(calibOffset),
- objectServer(objectServer), waitTimer(io)
+ sensorPollMs(static_cast<unsigned int>(pollRate * 1000)), calibOffset(calibOffset),
+ objectServer(objectServer), waitTimer(io), peciBus(peciBus), peciAddr(peciAddr),
+ dimmRank(rank), dimmSensorName(sensorName), dimmLEDState("OFF")
{
std::string interfacePath = "/xyz/openbmc_project/sensors/" + sensorType +
"/" + name;
@@ -72,7 +99,6 @@ DIMMTempSensor::DIMMTempSensor(
dimmLEDInterface = objectServer.add_interface(
interfacePath, "xyz.openbmc_project.Sensor.dimmLED");
- std::string dimmLEDState = "OFF";
dimmLEDInterface->register_property(
"LEDState", dimmLEDState, [this](const std::string& newValue, std::string& oldValue) {
oldValue = newValue; return true;
@@ -180,7 +206,7 @@ void DIMMTempSensor::read()
std::cerr << "timer error\n";
return;
}
- if (readingStateGood())
+ if (readingStateGood() && dimmLEDState == "ON")
{
double temp = 0;
int ret = getDIMMRegsInfoWord(&temp);
@@ -208,3 +234,23 @@ void DIMMTempSensor::read()
read();
});
}
+
+void DIMMTempSensor::setupMatches(const std::string& sensorName)
+{
+ std::weak_ptr<DIMMTempSensor> weakRef = weak_from_this();
+ setupDimmLEDMatch(matches, *dbusConnection, sensorName,
+ [weakRef, sensorName](const std::string& value) {
+ auto self = weakRef.lock();
+ if (!self)
+ {
+ return;
+ }
+ self->dimmLEDState = value;
+ if constexpr (debug)
+ {
+ std::cout << sensorName << " LED State" << " changed to "
+ << self->dimmLEDState << std::endl;
+ }
+ }
+ );
+}
diff --git a/src/DIMMTempSensor.hpp b/src/DIMMTempSensor.hpp
index 1f7d8d3..774ace2 100644
--- a/src/DIMMTempSensor.hpp
+++ b/src/DIMMTempSensor.hpp
@@ -10,7 +10,7 @@
#include <string>
#include <vector>
-struct DIMMTempSensor : public Sensor
+struct DIMMTempSensor : public Sensor, std::enable_shared_from_this<DIMMTempSensor>
{
DIMMTempSensor(std::shared_ptr<sdbusplus::asio::connection>& conn,
boost::asio::io_context& io, const std::string& name,
@@ -19,25 +19,28 @@ struct DIMMTempSensor : public Sensor
std::vector<thresholds::Threshold>&& thresholds,
const double maxReading, const double minReading,
const std::string& sensorType, const char* units,
- const float pollRate, PowerState readState, uint8_t peciBus,
- uint8_t peciAddr, uint8_t rank, double calibOffset);
+ const float pollRate, PowerState readState, double calibOffset,
+ uint8_t peciBus, uint8_t peciAddr, uint8_t rank);
~DIMMTempSensor() override;
void checkThresholds(void) override;
void read();
void init();
-
+ void setupMatches(const std::string& sensorName);
unsigned int sensorPollMs;
-
- uint8_t peciBus;
- uint8_t peciAddr;
- uint8_t dimmRank;
double calibOffset;
private:
int getDIMMRegsInfoWord(double* ps64data);
int getDIMMRegsTemp(double* ps64data);
// int getDIMMRegsPower(double* ps64data);
+
sdbusplus::asio::object_server& objectServer;
boost::asio::steady_timer waitTimer;
+ uint8_t peciBus;
+ uint8_t peciAddr;
+ uint8_t dimmRank;
+ std::string dimmSensorName;
+ std::string dimmLEDState;
+ std::vector<sdbusplus::bus::match_t> matches;
};
diff --git a/src/DIMMTempSensorMain.cpp b/src/DIMMTempSensorMain.cpp
index 042659f..a8fc05c 100644
--- a/src/DIMMTempSensorMain.cpp
+++ b/src/DIMMTempSensorMain.cpp
@@ -44,9 +44,11 @@ static constexpr double minTempReading = -128;
static constexpr double maxPowerReading = 500;
static constexpr double minPowerReading = 0;
+std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
+
void createSensors(
boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
- boost::container::flat_map<std::string, std::unique_ptr<DIMMTempSensor>>&
+ boost::container::flat_map<std::string, std::shared_ptr<DIMMTempSensor>>&
sensors,
std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
{
@@ -125,22 +127,22 @@ void createSensors(
if (name.ends_with("_Temp"))
{
- sensor = std::make_unique<DIMMTempSensor>(
+ sensor = std::make_shared<DIMMTempSensor>(
dbusConnection, io, name, pathPair.first, objectServer,
std::move(sensorThresholds), maxTempReading,
- minTempReading, "temperature",
- sensor_paths::unitDegreesC, pollRate, readState,
- peciBus, peciAddr, dimmRank, 0);
+ minTempReading, "temperature", sensor_paths::unitDegreesC,
+ pollRate, readState, 0, peciBus, peciAddr, dimmRank);
}
else if (name.ends_with("_Power"))
{
- sensor = std::make_unique<DIMMTempSensor>(
+ sensor = std::make_shared<DIMMTempSensor>(
dbusConnection, io, name, pathPair.first, objectServer,
std::move(sensorThresholds), maxPowerReading,
minPowerReading, "power", sensor_paths::unitWatts,
- pollRate, readState, peciBus, peciAddr, dimmRank, 0);
+ pollRate, readState, 0, peciBus, peciAddr, dimmRank);
}
+ sensor->setupMatches(name);
sensor->init();
}
}
@@ -158,7 +160,7 @@ int main()
objectServer.add_manager("/xyz/openbmc_project/sensors");
systemBus->request_name("xyz.openbmc_project.DIMMTempSensor");
- boost::container::flat_map<std::string, std::unique_ptr<DIMMTempSensor>>
+ boost::container::flat_map<std::string, std::shared_ptr<DIMMTempSensor>>
sensors;
boost::asio::post(
io, [&]() { createSensors(io, objectServer, sensors, systemBus); });
--
2.34.1
@@ -0,0 +1,176 @@
From 47e8984b64fff089ed16bf390b5739e62a53d24e Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Tue, 26 Nov 2024 21:09:21 +0800
Subject: [PATCH] switch dimmtempsensor from peci to i3c
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/DIMMTempSensor.cpp | 78 +++++++++++++++++++++++---------------
src/DIMMTempSensor.hpp | 7 ++--
src/DIMMTempSensorMain.cpp | 2 +-
3 files changed, 52 insertions(+), 35 deletions(-)
diff --git a/src/DIMMTempSensor.cpp b/src/DIMMTempSensor.cpp
index d290d63..7c4412f 100644
--- a/src/DIMMTempSensor.cpp
+++ b/src/DIMMTempSensor.cpp
@@ -46,6 +46,10 @@ extern "C"
constexpr const bool debug = false;
constexpr auto dimmSensorInterface = "xyz.openbmc_project.Sensor.dimmLED";
constexpr auto dimmSensorPath = "/xyz/openbmc_project/sensors/temperature/";
+constexpr auto dimmSpdReaderService = "xyz.openbmc_project.DimmSpdReader";
+constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
+constexpr auto tempInterface = "xyz.openbmc_project.Dimm.Temperature";
+
#define PECI_MBX_INDEX_DDR_DIMM_TEMP 0x0E
static void setupDimmLEDMatch(
@@ -132,9 +136,9 @@ DIMMTempSensor::~DIMMTempSensor()
objectServer.remove_interface(association);
}
-void DIMMTempSensor::init()
+void DIMMTempSensor::init(const std::string& sensorName)
{
- read();
+ read(sensorName);
}
void DIMMTempSensor::checkThresholds(void)
@@ -142,13 +146,7 @@ void DIMMTempSensor::checkThresholds(void)
thresholds::checkThresholds(this);
}
-int DIMMTempSensor::getDIMMRegsInfoWord(double* ps64data)
-{
- int ret = -1;
- ret = getDIMMRegsTemp(ps64data);
- return ret;
-}
-
+#if 0
int DIMMTempSensor::getDIMMRegsTemp(double* ps64data)
{
int peciFd = -1;
@@ -192,10 +190,47 @@ err:
return -1;
}
-void DIMMTempSensor::read()
+#endif
+
+void DIMMTempSensor::getDIMMRegsTemp(const std::string& sensorName)
+{
+ std::string path = "/xyz/openbmc_project/dimm/" + sensorName;
+ size_t tempPos = path.find("_Temp");
+ if (tempPos != std::string::npos) {
+ path = path.substr(0, tempPos);
+ }
+
+ std::weak_ptr<DIMMTempSensor> weakRef = weak_from_this();
+ dbusConnection->async_method_call(
+ [weakRef](const boost::system::error_code ec, const std::variant<double> value) {
+ if (ec)
+ {
+ std::cerr << "Error setting DIMM sensor Temp" << "\n";
+ return;
+ }
+ auto self = weakRef.lock();
+ if (!self)
+ {
+ return;
+ }
+ double v = std::get<double>(value);
+ if constexpr (debug)
+ {
+ std::cerr << "Dimm Temp raw reading " << v << "\n";
+ }
+ v += self->calibOffset;
+ self->updateValue(v);
+
+ },
+ dimmSpdReaderService, path, dbusProperties, "Get", tempInterface, "TS0");
+
+ return;
+}
+
+void DIMMTempSensor::read(const std::string& sensorName)
{
waitTimer.expires_after(std::chrono::milliseconds(sensorPollMs));
- waitTimer.async_wait([this](const boost::system::error_code& ec) {
+ waitTimer.async_wait([this, sensorName](const boost::system::error_code& ec) {
if (ec == boost::asio::error::operation_aborted)
{
return; // we're being cancelled
@@ -208,30 +243,13 @@ void DIMMTempSensor::read()
}
if (readingStateGood() && dimmLEDState == "ON")
{
- double temp = 0;
- int ret = getDIMMRegsInfoWord(&temp);
- if (ret == 0)
- {
- double v = temp;
- if constexpr (debug)
- {
- std::cerr << "Value update to " << v << ", raw reading "
- << temp << "\n";
- }
- v += calibOffset;
- updateValue(v);
- }
- else
- {
- std::cerr << "Fail to read DIMM tempture.\n";
- incrementError();
- }
+ getDIMMRegsTemp(sensorName);
}
else
{
updateValue(std::numeric_limits<double>::quiet_NaN());
}
- read();
+ read(sensorName);
});
}
diff --git a/src/DIMMTempSensor.hpp b/src/DIMMTempSensor.hpp
index 774ace2..5e629da 100644
--- a/src/DIMMTempSensor.hpp
+++ b/src/DIMMTempSensor.hpp
@@ -24,15 +24,14 @@ struct DIMMTempSensor : public Sensor, std::enable_shared_from_this<DIMMTempSens
~DIMMTempSensor() override;
void checkThresholds(void) override;
- void read();
- void init();
+ void read(const std::string& sensorName);
+ void init(const std::string& sensorName);
void setupMatches(const std::string& sensorName);
unsigned int sensorPollMs;
double calibOffset;
private:
- int getDIMMRegsInfoWord(double* ps64data);
- int getDIMMRegsTemp(double* ps64data);
+ void getDIMMRegsTemp(const std::string& sensorName);
// int getDIMMRegsPower(double* ps64data);
sdbusplus::asio::object_server& objectServer;
diff --git a/src/DIMMTempSensorMain.cpp b/src/DIMMTempSensorMain.cpp
index a8fc05c..b8f002b 100644
--- a/src/DIMMTempSensorMain.cpp
+++ b/src/DIMMTempSensorMain.cpp
@@ -143,7 +143,7 @@ void createSensors(
}
sensor->setupMatches(name);
- sensor->init();
+ sensor->init(name);
}
}
},
--
2.34.1
@@ -0,0 +1,161 @@
From acff0dcb9a23be3bdd5282b806e85ab1a8e7646c Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Mon, 9 Dec 2024 15:42:57 +0800
Subject: [PATCH] Add Sel log for CPU presence event
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/IntelCPUSensor.cpp | 61 ++++++++++++++++++++++++++++++++++++++
src/IntelCPUSensor.hpp | 37 +++++------------------
src/IntelCPUSensorMain.cpp | 6 +++-
3 files changed, 73 insertions(+), 31 deletions(-)
diff --git a/src/IntelCPUSensor.cpp b/src/IntelCPUSensor.cpp
index 2bebcd8..abde76f 100644
--- a/src/IntelCPUSensor.cpp
+++ b/src/IntelCPUSensor.cpp
@@ -329,3 +329,64 @@ void IntelCPUSensor::checkThresholds(void)
thresholds::checkThresholds(this);
}
}
+
+void CPUPresentStateLog(const std::shared_ptr<sdbusplus::asio::connection>& conn, const std::string CPUStateSensorName)
+{
+ constexpr const char* selService = "xyz.openbmc_project.Logging.IPMI";
+ constexpr const char* selPath = "/xyz/openbmc_project/Logging/IPMI";
+ constexpr const char* selInterface = "xyz.openbmc_project.Logging.IPMI";
+ constexpr const char* selMethod = "IpmiSelAdd";
+ std::string sensorPath ="/xyz/openbmc_project/inventory/system/board/Lux_Baseboard/" + CPUStateSensorName;
+
+ auto method =
+ conn->new_method_call(selService, selPath, selInterface, selMethod);
+
+ method.append("SEL Entry");
+ method.append(sensorPath);
+ method.append(
+ std::array<uint8_t, 3>({0x07, 0xFF, 0xFF})); // presence Detected
+
+ method.append(true); // assert is true and deassert is false
+ method.append(uint16_t(0x0020)); // generator ID
+ try
+ {
+ conn->call_noreply(method);
+ }
+ catch (const sdbusplus::exception::SdBusError& ex)
+ {
+ lg2::error(
+ "Failed to call sel log {SELPATH}, {SELINTERFACE}, {SELMRTHOD}",
+ "SELPATH", selPath, "SELINTERFACE", selInterface, "SELMRTHOD",
+ selMethod);
+ }
+}
+
+bool cpuIsPresentCPLD(int cpuId)
+{
+ int ret = 0;
+ uint8_t index;
+ std::string i2cDev = "/dev/i2c-0";
+ // Perform the combined write/read
+
+ std::vector<uint8_t> readBuf(1);
+ std::vector<uint8_t> writeData = {0x91, 0x02};
+ const uint8_t slaveAddr = 0x0D;
+ uint8_t regVal;
+
+ ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf);
+ if (ret < 0)
+ {
+ std::cerr << "i2c failed to read regVal. \n";
+ return false;
+ }
+
+ regVal = readBuf[0];
+ if(cpuId == 0)
+ index = 1;
+ else if(cpuId == 1)
+ index = 0;
+ else
+ return false;
+
+ return (regVal & (1 << index)) == 0;
+}
diff --git a/src/IntelCPUSensor.hpp b/src/IntelCPUSensor.hpp
index ae90ab7..b928894 100644
--- a/src/IntelCPUSensor.hpp
+++ b/src/IntelCPUSensor.hpp
@@ -7,6 +7,8 @@
#include <boost/container/flat_map.hpp>
#include <gpiod.hpp>
#include <sdbusplus/asio/object_server.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <phosphor-logging/elog-errors.hpp>
#include <sensor.hpp>
#include <filesystem>
@@ -65,6 +67,11 @@ class IntelCPUSensor :
extern boost::container::flat_map<std::string, std::shared_ptr<IntelCPUSensor>>
gCpuSensors;
+extern void CPUPresentStateLog(const std::shared_ptr<sdbusplus::asio::connection>& conn,
+ const std::string CPUStateSensorName);
+
+extern bool cpuIsPresentCPLD(int cpuId);
+
// this is added to intelcpusensor.hpp to avoid having every sensor have to link
// against libgpiod, if another sensor needs it we may move it to utils
inline bool cpuIsPresent(const SensorBaseConfigMap& gpioConfig)
@@ -180,33 +187,3 @@ inline int i2cWriteRead(std::string& i2cDev, const uint8_t slaveAddr,
return 0;
}
-
-inline bool cpuIsPresentCPLD(int cpuId)
-{
- int ret = 0;
- uint8_t index;
- std::string i2cDev = "/dev/i2c-0";
- // Perform the combined write/read
-
- std::vector<uint8_t> readBuf(1);
- std::vector<uint8_t> writeData = {0x91, 0x02};
- const uint8_t slaveAddr = 0x0D;
- uint8_t regVal;
-
- ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf);
- if (ret < 0)
- {
- std::cerr << "i2c failed to read regVal. \n";
- return false;
- }
-
- regVal = readBuf[0];
- if(cpuId == 1)
- index = 1;
- else if(cpuId == 2)
- index = 0;
- else
- return false;
-
- return (regVal & (1 << index)) == 0;
-}
diff --git a/src/IntelCPUSensorMain.cpp b/src/IntelCPUSensorMain.cpp
index a955c6f..7bdd9f9 100644
--- a/src/IntelCPUSensorMain.cpp
+++ b/src/IntelCPUSensorMain.cpp
@@ -739,8 +739,12 @@ bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
for (const auto& [suppIntf, suppCfg] : cfgData)
present = cpuIsPresent(suppCfg);
} else if(method == "CPLD") {
- if(cpuId != -1)
+ if(cpuId != -1) {
present = cpuIsPresentCPLD(cpuId);
+ std::string CPUPresentName = "CPU" + std::string(1, '0' + cpuId) + "_State";
+ if (present.has_value() && present.value() == true)
+ CPUPresentStateLog(systemBus, CPUPresentName);
+ }
} else {
std::cerr << "Invalid Presence value \n";
}
--
2.34.1
@@ -0,0 +1,55 @@
From 30aee385442d8ec0b691b16b5229692cbf0df0a5 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Thu, 19 Dec 2024 19:31:08 +0800
Subject: [PATCH] Ensure CPU sensor names match those in the IPMI SDR list
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/IntelCPUSensorMain.cpp | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/src/IntelCPUSensorMain.cpp b/src/IntelCPUSensorMain.cpp
index 7bdd9f9..b6dc544 100644
--- a/src/IntelCPUSensorMain.cpp
+++ b/src/IntelCPUSensorMain.cpp
@@ -106,12 +106,33 @@ void detectCpuAsync(
std::string createSensorName(const std::string& label, const std::string& item,
const int& cpuId)
{
- std::string sensorName = label;
- if (item != "input")
+ std::string sensorName{};
+
+ if (label == "DTS")
+ {
+ sensorName = "CPU" + std::to_string(cpuId) + " Temp";
+ }
+ else if (item == "average" && label == "dimm power")
{
- sensorName += " " + item;
+ sensorName = label + " CPU" + std::to_string(cpuId);
+ }
+ else if (label == "cpu power")
+ {
+ if(item == "average")
+ sensorName = "CPU" + std::to_string(cpuId) + " power " + "avg";
+ else
+ sensorName = "CPU" + std::to_string(cpuId) + " power " + item;
}
- sensorName += " CPU" + std::to_string(cpuId);
+ else
+ {
+ sensorName = label;
+ if (item != "input")
+ {
+ sensorName += " " + item;
+ }
+ sensorName += " CPU" + std::to_string(cpuId);
+ }
+
// converting to Upper Camel case whole name
bool isWordEnd = true;
std::transform(sensorName.begin(), sensorName.end(), sensorName.begin(),
--
2.34.1
@@ -0,0 +1,25 @@
From d486099eb09eee64a0e1dc45785785f22c61a4a8 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Tue, 24 Dec 2024 16:52:19 +0800
Subject: [PATCH] Set Available to false when dimm temp reading is not ready
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/DIMMTempSensor.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/DIMMTempSensor.cpp b/src/DIMMTempSensor.cpp
index 7c4412f..a0c9d76 100644
--- a/src/DIMMTempSensor.cpp
+++ b/src/DIMMTempSensor.cpp
@@ -247,6 +247,7 @@ void DIMMTempSensor::read(const std::string& sensorName)
}
else
{
+ markAvailable(false);
updateValue(std::numeric_limits<double>::quiet_NaN());
}
read(sensorName);
--
2.34.1
@@ -0,0 +1,25 @@
From 37cc98c8b90ca056ac100b33cc04d26b64c8ce9a Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Tue, 31 Dec 2024 18:10:15 +0800
Subject: [PATCH] Add INA220 sensor
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/PSUSensorMain.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/PSUSensorMain.cpp b/src/PSUSensorMain.cpp
index 2991ba0..7dd95dd 100644
--- a/src/PSUSensorMain.cpp
+++ b/src/PSUSensorMain.cpp
@@ -53,6 +53,7 @@ static const I2CDeviceTypeMap sensorTypes{
{"BMR490", I2CDeviceType{"bmr490", true}},
{"DPS800", I2CDeviceType{"dps800", true}},
{"INA219", I2CDeviceType{"ina219", true}},
+ {"INA226", I2CDeviceType{"ina226", true}},
{"INA230", I2CDeviceType{"ina230", true}},
{"IPSPS1", I2CDeviceType{"ipsps1", true}},
{"IR38060", I2CDeviceType{"ir38060", true}},
--
2.34.1
@@ -0,0 +1,195 @@
From 301fd47f7f21a780b06c4403a657d31e967934bf Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Fri, 3 Jan 2025 18:57:29 +0800
Subject: [PATCH] Trigger to read dimm temp by vwgpio1
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
%% original patch: 0014-Trigger-to-read-dimm-temp-by-vwgpio1.patch
---
src/DIMMTempSensor.cpp | 107 +++++++++++++++++++++++++++++++++++++++--
src/DIMMTempSensor.hpp | 2 +
2 files changed, 106 insertions(+), 3 deletions(-)
diff --git a/src/DIMMTempSensor.cpp b/src/DIMMTempSensor.cpp
index a0c9d76..852810b 100644
--- a/src/DIMMTempSensor.cpp
+++ b/src/DIMMTempSensor.cpp
@@ -49,6 +49,9 @@ constexpr auto dimmSensorPath = "/xyz/openbmc_project/sensors/temperature/";
constexpr auto dimmSpdReaderService = "xyz.openbmc_project.DimmSpdReader";
constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
constexpr auto tempInterface = "xyz.openbmc_project.Dimm.Temperature";
+constexpr auto HostMiscDbusName = "xyz.openbmc_project.Host.Misc.Manager";
+constexpr auto platformStatePath = "/xyz/openbmc_project/misc/platform_state";
+constexpr auto platformStateInterface = "xyz.openbmc_project.State.Host.Misc";
#define PECI_MBX_INDEX_DDR_DIMM_TEMP 0x0E
@@ -78,6 +81,60 @@ static void setupDimmLEDMatch(
std::move(eventHandler));
}
+static bool getDbusMsgState(sdbusplus::message_t& msg, bool& value)
+{
+ std::string pltStateInterface;
+ std::string event;
+ boost::container::flat_map<std::string, std::variant<bool>>
+ propertiesChanged;
+ try
+ {
+ msg.read(pltStateInterface, propertiesChanged);
+ if (propertiesChanged.empty())
+ {
+ return false;
+ }
+
+ std::string property = propertiesChanged.begin()->first;
+
+ if (property.empty() || property != "dimmI3cSwitch")
+ {
+ return false;
+ }
+
+ value = std::get<bool>(propertiesChanged.begin()->second);
+ return true;
+ }
+ catch (const std::exception& e)
+ {
+ std::cerr << "exception while reading dbus property dimmI3cSwitch" << "\n";
+ return false;
+ }
+}
+
+static void dimmI3cSwitchMatcher(
+ std::vector<sdbusplus::bus::match_t>& matches, sdbusplus::bus_t& connection,
+ std::function<void(bool)>&& onMatch)
+{
+ auto pulseEventMatcherCallback =
+ [onMatch{std::move(onMatch)}](sdbusplus::message_t& msg) {
+ bool value = false;
+ if (!getDbusMsgState(msg, value))
+ {
+ return;
+ }
+ onMatch(value);
+ };
+
+ matches.emplace_back(
+ connection,
+ "type='signal',interface='org.freedesktop.DBus.Properties',member='"
+ "PropertiesChanged',arg0='" +
+ std::string(platformStateInterface) + "'",
+ std::move(pulseEventMatcherCallback));
+}
+
+
DIMMTempSensor::DIMMTempSensor(
std::shared_ptr<sdbusplus::asio::connection>& conn,
boost::asio::io_context& io, const std::string& sensorName,
@@ -121,6 +178,8 @@ DIMMTempSensor::DIMMTempSensor(
association::interface);
setInitialProperties(units);
+
+ dimmI3cSwitchState = getdimmI3cSwitchState(io);
}
DIMMTempSensor::~DIMMTempSensor()
@@ -202,10 +261,10 @@ void DIMMTempSensor::getDIMMRegsTemp(const std::string& sensorName)
std::weak_ptr<DIMMTempSensor> weakRef = weak_from_this();
dbusConnection->async_method_call(
- [weakRef](const boost::system::error_code ec, const std::variant<double> value) {
+ [weakRef, sensorName](const boost::system::error_code ec, const std::variant<double> value) {
if (ec)
{
- std::cerr << "Error setting DIMM sensor Temp" << "\n";
+ std::cerr << "Error getting DIMM sensor " << sensorName << " Temp" << "\n";
return;
}
auto self = weakRef.lock();
@@ -241,7 +300,7 @@ void DIMMTempSensor::read(const std::string& sensorName)
std::cerr << "timer error\n";
return;
}
- if (readingStateGood() && dimmLEDState == "ON")
+ if (readingStateGood() && dimmI3cSwitchState)
{
getDIMMRegsTemp(sensorName);
}
@@ -257,6 +316,7 @@ void DIMMTempSensor::read(const std::string& sensorName)
void DIMMTempSensor::setupMatches(const std::string& sensorName)
{
std::weak_ptr<DIMMTempSensor> weakRef = weak_from_this();
+ std::shared_ptr<DIMMTempSensor> sharedRef = weakRef.lock();
setupDimmLEDMatch(matches, *dbusConnection, sensorName,
[weakRef, sensorName](const std::string& value) {
auto self = weakRef.lock();
@@ -272,4 +332,45 @@ void DIMMTempSensor::setupMatches(const std::string& sensorName)
}
}
);
+
+ dimmI3cSwitchMatcher(matches, *dbusConnection, [sharedRef](bool state)
+ {
+ if (!sharedRef)
+ {
+ return;
+ }
+ if (!state)
+ {
+ sharedRef->dimmI3cSwitchState = false;
+ }
+ else
+ {
+ sharedRef->dimmI3cSwitchState = true;
+ }
+ std::cout << "dimmI3cSwitchState: " << (int)sharedRef->dimmI3cSwitchState << std::endl;
+ });
+}
+
+bool DIMMTempSensor::getdimmI3cSwitchState(boost::asio::io_context& io)
+{
+ auto conn = std::make_shared<sdbusplus::asio::connection>(io);
+ auto mesg = conn->new_method_call(HostMiscDbusName, platformStatePath,
+ "org.freedesktop.DBus.Properties", "Get");
+ mesg.append(platformStateInterface, "dimmI3cSwitch");
+
+ bool state = false;
+ try
+ {
+ auto resp = conn->call(mesg);
+ std::variant<bool> value;
+ resp.read(value);
+ state = std::get<bool>(value);
+ std::cout << " get dimmI3cSwitch State: " << (int)state << std::endl;
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "auto shutdown: failed to read node id";
+ }
+
+ return state;
}
diff --git a/src/DIMMTempSensor.hpp b/src/DIMMTempSensor.hpp
index 5e629da..fc51928 100644
--- a/src/DIMMTempSensor.hpp
+++ b/src/DIMMTempSensor.hpp
@@ -27,6 +27,7 @@ struct DIMMTempSensor : public Sensor, std::enable_shared_from_this<DIMMTempSens
void read(const std::string& sensorName);
void init(const std::string& sensorName);
void setupMatches(const std::string& sensorName);
+ bool getdimmI3cSwitchState(boost::asio::io_context& io);
unsigned int sensorPollMs;
double calibOffset;
@@ -41,5 +42,6 @@ struct DIMMTempSensor : public Sensor, std::enable_shared_from_this<DIMMTempSens
uint8_t dimmRank;
std::string dimmSensorName;
std::string dimmLEDState;
+ bool dimmI3cSwitchState;
std::vector<sdbusplus::bus::match_t> matches;
};
--
2.34.1
@@ -0,0 +1,63 @@
From e0fca894d30279a487d375a312dd956c195b046a Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Wed, 8 Jan 2025 20:23:11 +0800
Subject: [PATCH] Get the highest temperature of TS0, TS1, SPD_Temp
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/DIMMTempSensor.cpp | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/DIMMTempSensor.cpp b/src/DIMMTempSensor.cpp
index 852810b..0fe9b83 100644
--- a/src/DIMMTempSensor.cpp
+++ b/src/DIMMTempSensor.cpp
@@ -43,6 +43,9 @@ extern "C"
#include <linux/i2c-dev.h>
}
+using PropertyMapType =
+ boost::container::flat_map<std::string, BasicVariantType>;
+
constexpr const bool debug = false;
constexpr auto dimmSensorInterface = "xyz.openbmc_project.Sensor.dimmLED";
constexpr auto dimmSensorPath = "/xyz/openbmc_project/sensors/temperature/";
@@ -261,7 +264,7 @@ void DIMMTempSensor::getDIMMRegsTemp(const std::string& sensorName)
std::weak_ptr<DIMMTempSensor> weakRef = weak_from_this();
dbusConnection->async_method_call(
- [weakRef, sensorName](const boost::system::error_code ec, const std::variant<double> value) {
+ [weakRef, sensorName](const boost::system::error_code ec, PropertyMapType& propMap) {
if (ec)
{
std::cerr << "Error getting DIMM sensor " << sensorName << " Temp" << "\n";
@@ -272,16 +275,23 @@ void DIMMTempSensor::getDIMMRegsTemp(const std::string& sensorName)
{
return;
}
- double v = std::get<double>(value);
+
+ auto ts0_temp = std::get_if<double>(&propMap["TS0"]);
+ auto ts1_temp = std::get_if<double>(&propMap["TS1"]);
+ auto spd_temp = std::get_if<double>(&propMap["SPD_TS"]);
+
+ double v = std::max(std::max(*ts0_temp, *ts1_temp), *spd_temp);
+
if constexpr (debug)
{
- std::cerr << "Dimm Temp raw reading " << v << "\n";
+ std::cout << "ts0_temp: " << *ts0_temp << " ts1_temp: " << *ts1_temp << " spd_temp: " << *spd_temp << std::endl;
+ std::cerr << "Dimm Temp max_value: " << v << std::endl;
}
v += self->calibOffset;
self->updateValue(v);
},
- dimmSpdReaderService, path, dbusProperties, "Get", tempInterface, "TS0");
+ dimmSpdReaderService, path, dbusProperties, "GetAll", tempInterface);
return;
}
--
2.34.1
@@ -0,0 +1,78 @@
From 1bb10963f47654a6fed6826bb3131401508d86cc Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Thu, 23 Jan 2025 19:07:55 +0800
Subject: [PATCH] Add retry in case unable to open intelcpu sensor file node
and initialize dimm LED to "Orange"
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/DIMMTempSensor.cpp | 2 +-
src/IntelCPUSensor.cpp | 18 ++++++++++++++----
src/IntelCPUSensor.hpp | 1 +
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/src/DIMMTempSensor.cpp b/src/DIMMTempSensor.cpp
index 0fe9b83..d2c2f65 100644
--- a/src/DIMMTempSensor.cpp
+++ b/src/DIMMTempSensor.cpp
@@ -152,7 +152,7 @@ DIMMTempSensor::DIMMTempSensor(
maxReading, minReading, conn, readState),
sensorPollMs(static_cast<unsigned int>(pollRate * 1000)), calibOffset(calibOffset),
objectServer(objectServer), waitTimer(io), peciBus(peciBus), peciAddr(peciAddr),
- dimmRank(rank), dimmSensorName(sensorName), dimmLEDState("OFF")
+ dimmRank(rank), dimmSensorName(sensorName), dimmLEDState("NA")
{
std::string interfacePath = "/xyz/openbmc_project/sensors/" + sensorType +
"/" + name;
diff --git a/src/IntelCPUSensor.cpp b/src/IntelCPUSensor.cpp
index abde76f..260ea77 100644
--- a/src/IntelCPUSensor.cpp
+++ b/src/IntelCPUSensor.cpp
@@ -47,7 +47,7 @@ IntelCPUSensor::IntelCPUSensor(
objServer(objectServer), inputDev(io), waitTimer(io),
nameTcontrol("Tcontrol CPU" + std::to_string(cpuId)), path(path),
privTcontrol(std::numeric_limits<double>::quiet_NaN()),
- dtsOffset(dtsOffset), show(show), pollTime(IntelCPUSensor::sensorPollMs)
+ dtsOffset(dtsOffset), show(show), pollTime(IntelCPUSensor::sensorPollMs), retry(10)
{
if (show)
@@ -140,10 +140,20 @@ void IntelCPUSensor::setupRead(void)
fd = open(path.c_str(), O_RDONLY | O_NONBLOCK);
if (fd < 0)
{
- std::cerr << name << " unable to open fd!\n";
- return;
+ std::cerr << name << " unable to open fd! Error code: " << errno
+ << " (" << strerror(errno) << ")\n";
+ if(retry > 0)
+ {
+ std::cout << "Call restartRead to retry opening fd, retry " << (int)retry << std::endl;
+ retry--;
+ restartRead();
+ }
+ else
+ {
+ std::cout << "Still can't open fd after retry 10 times" << std::endl;
+ return;
+ }
}
-
inputDev.assign(fd);
}
else
diff --git a/src/IntelCPUSensor.hpp b/src/IntelCPUSensor.hpp
index b928894..37e5694 100644
--- a/src/IntelCPUSensor.hpp
+++ b/src/IntelCPUSensor.hpp
@@ -62,6 +62,7 @@ class IntelCPUSensor :
void checkThresholds(void) override;
void updateMinMaxValues(void);
void restartRead(void);
+ uint8_t retry;
};
extern boost::container::flat_map<std::string, std::shared_ptr<IntelCPUSensor>>
--
2.34.1
@@ -0,0 +1,92 @@
From 5efe2a34889b828a19c84818be3a551516513907 Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Fri, 24 Jan 2025 17:27:19 +0800
Subject: [PATCH] Set DIMM LED to NA when dc on and OFF when dc off
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/DIMMTempSensor.cpp | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/src/DIMMTempSensor.cpp b/src/DIMMTempSensor.cpp
index d2c2f65..dca398e 100644
--- a/src/DIMMTempSensor.cpp
+++ b/src/DIMMTempSensor.cpp
@@ -84,7 +84,7 @@ static void setupDimmLEDMatch(
std::move(eventHandler));
}
-static bool getDbusMsgState(sdbusplus::message_t& msg, bool& value)
+static bool getDbusMsgState(sdbusplus::message_t& msg, bool& value, std::string& propertyName)
{
std::string pltStateInterface;
std::string event;
@@ -99,13 +99,13 @@ static bool getDbusMsgState(sdbusplus::message_t& msg, bool& value)
}
std::string property = propertiesChanged.begin()->first;
-
- if (property.empty() || property != "dimmI3cSwitch")
+ if (property.empty() || (property != "dimmI3cSwitch" && property != "ESpiPlatformReset"))
{
return false;
}
value = std::get<bool>(propertiesChanged.begin()->second);
+ propertyName = property;
return true;
}
catch (const std::exception& e)
@@ -117,16 +117,17 @@ static bool getDbusMsgState(sdbusplus::message_t& msg, bool& value)
static void dimmI3cSwitchMatcher(
std::vector<sdbusplus::bus::match_t>& matches, sdbusplus::bus_t& connection,
- std::function<void(bool)>&& onMatch)
+ std::function<void(std::string, bool)>&& onMatch)
{
auto pulseEventMatcherCallback =
[onMatch{std::move(onMatch)}](sdbusplus::message_t& msg) {
bool value = false;
- if (!getDbusMsgState(msg, value))
+ std::string propertyName = "";
+ if (!getDbusMsgState(msg, value, propertyName))
{
return;
}
- onMatch(value);
+ onMatch(propertyName, value);
};
matches.emplace_back(
@@ -343,21 +344,22 @@ void DIMMTempSensor::setupMatches(const std::string& sensorName)
}
);
- dimmI3cSwitchMatcher(matches, *dbusConnection, [sharedRef](bool state)
+ dimmI3cSwitchMatcher(matches, *dbusConnection, [sharedRef](std::string propertyName, bool state)
{
if (!sharedRef)
{
return;
}
- if (!state)
+
+ if (propertyName == "dimmI3cSwitch")
{
- sharedRef->dimmI3cSwitchState = false;
+ sharedRef->dimmI3cSwitchState = state;
}
- else
+ else if (propertyName == "ESpiPlatformReset")
{
- sharedRef->dimmI3cSwitchState = true;
+ std::string dimmLEDState = state ? "NA" : "OFF";
+ sharedRef->dimmLEDInterface->set_property("LEDState", dimmLEDState);
}
- std::cout << "dimmI3cSwitchState: " << (int)sharedRef->dimmI3cSwitchState << std::endl;
});
}
--
2.34.1
@@ -0,0 +1,108 @@
From b7052285e077a632bd3cc123e1327fb58540c30c Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Wed, 5 Mar 2025 19:30:42 +0800
Subject: [PATCH] Fix incorrect config state for intel cpu sensors
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
%% original patch: 0018-Fix-incorrect-config-state-for-intel-cpu-sensors.patch
---
src/IntelCPUSensorMain.cpp | 47 +++++++++++++++++++++++---------------
1 file changed, 28 insertions(+), 19 deletions(-)
diff --git a/src/IntelCPUSensorMain.cpp b/src/IntelCPUSensorMain.cpp
index b6dc544..bdb6d25 100644
--- a/src/IntelCPUSensorMain.cpp
+++ b/src/IntelCPUSensorMain.cpp
@@ -571,7 +571,6 @@ void detectCpu(boost::asio::steady_timer& pingTimer,
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
if (peci_Ping(config.addr) == PECI_CC_SUCCESS)
{
- bool dimmReady = false;
for (unsigned int rank = 0; rank < rankNumMax; rank++)
{
std::array<uint8_t, 8> pkgConfig{};
@@ -585,7 +584,7 @@ void detectCpu(boost::asio::steady_timer& pingTimer,
if ((pkgConfig[0] != 0U) || (pkgConfig[1] != 0U) ||
(pkgConfig[2] != 0U))
{
- dimmReady = true;
+ //pkgConfig for DIMM_TEMP will return 0 if i3c is switched on BMC side.
break;
}
}
@@ -595,14 +594,7 @@ void detectCpu(boost::asio::steady_timer& pingTimer,
}
}
- if (dimmReady)
- {
- newState = State::READY;
- }
- else
- {
- newState = State::ON;
- }
+ newState = State::ON;
}
if (config.state != newState)
@@ -634,29 +626,46 @@ void detectCpu(boost::asio::steady_timer& pingTimer,
{
rescanDelaySeconds = 3;
}
- else if (newState == State::READY)
- {
- rescanDelaySeconds = 5;
- std::cout << "DIMM(s) on " << config.name
- << " is/are detected\n";
- }
}
config.state = newState;
}
- if (config.state != State::READY)
+ std::vector<fs::path> peciDimmDevPaths;
+ std::ostringstream searchDimmPath;
+ searchDimmPath << std::hex << "peci-" << config.bus << "/" << config.bus
+ << "-" << config.addr;
+
+ std::string peciDevDir = "/sys/bus/peci/devices/";
+ findFiles(fs::path(peciDevDir + searchDimmPath.str()),
+ R"(peci-dimmpower.+/hwmon/hwmon\d+/name$)", peciDimmDevPaths,
+ 3);
+ if (!peciDimmDevPaths.empty())
{
- keepPinging = true;
+ config.state = State::READY;
}
if (debug)
{
- std::cout << config.name << ", state: " << config.state << "\n";
+ std::cout << config.name << ", state: " << config.state << std::endl;
}
+
peci_Unlock(peciFd);
}
+ for (CPUConfig& config : cpuConfigs)
+ {
+ if(config.state == State::READY)
+ {
+ keepPinging = false;
+ }
+ else
+ {
+ keepPinging = true;
+ break;
+ }
+ }
+
if (rescanDelaySeconds != 0U)
{
creationTimer.expires_after(std::chrono::seconds(rescanDelaySeconds));
--
2.34.1
@@ -0,0 +1,377 @@
From d9f16c1ee1b17aa3b7eb8d693a493ca7e04c9a6a Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Tue, 22 Apr 2025 16:46:48 +0800
Subject: [PATCH] Add retries to get inventory objects
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
src/DIMMTempSensorMain.cpp | 228 +++++++++++++++++++++----------------
src/IntelCPUSensorMain.cpp | 54 ++++++---
2 files changed, 171 insertions(+), 111 deletions(-)
diff --git a/src/DIMMTempSensorMain.cpp b/src/DIMMTempSensorMain.cpp
index b8f002b..04e221b 100644
--- a/src/DIMMTempSensorMain.cpp
+++ b/src/DIMMTempSensorMain.cpp
@@ -35,7 +35,7 @@
#include <string>
#include <vector>
-constexpr const bool debug = false;
+constexpr const bool debug = true;
constexpr const char* configInterface =
"xyz.openbmc_project.Configuration.DIMMTemp";
@@ -46,109 +46,147 @@ static constexpr double minPowerReading = 0;
std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
-void createSensors(
+bool createSensors(
boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
- boost::container::flat_map<std::string, std::shared_ptr<DIMMTempSensor>>&
- sensors,
+ boost::container::flat_map<std::string, std::shared_ptr<DIMMTempSensor>>& sensors,
std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
{
if (!dbusConnection)
{
std::cerr << "Connection not created\n";
- return;
+ return false;
}
- dbusConnection->async_method_call(
- [&io, &objectServer, &dbusConnection, &sensors](
- boost::system::error_code ec, const ManagedObjectType& resp) {
- if (ec)
+ ManagedObjectType resp;
+ resp.clear();
+ sdbusplus::message_t getManagedObjects =
+ dbusConnection->new_method_call(
+ entityManagerName, "/xyz/openbmc_project/inventory",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+ try
+ {
+ sdbusplus::message_t reply =
+ dbusConnection->call(getManagedObjects);
+ reply.read(resp);
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ std::cerr << "Error contacting entity manager\n";
+ return false;
+ }
+
+ for (const auto& pathPair : resp)
+ {
+ for (const auto& entry : pathPair.second)
+ {
+ if (entry.first != configInterface)
+ {
+ continue;
+ }
+ std::string name = loadVariant<std::string>(entry.second,
+ "Name");
+
+ std::vector<thresholds::Threshold> sensorThresholds;
+ if (!parseThresholdsFromConfig(pathPair.second,
+ sensorThresholds))
+ {
+ std::cerr << "error populating thresholds for " << name
+ << "\n";
+ }
+
+ float pollRate = loadVariant<double>(entry.second, "PollRate");
+ uint8_t peciBus = loadVariant<uint8_t>(entry.second, "Bus");
+ uint8_t peciAddr = loadVariant<uint8_t>(entry.second, "Address");
+ uint8_t dimmRank = loadVariant<uint8_t>(entry.second, "Rank");
+
+ /* calibration offset */
+ auto findCalibOffset = entry.second.find("Offset");
+ double calibOffset = 0;
+ if (findCalibOffset != entry.second.end())
+ {
+ calibOffset = std::visit(VariantToDoubleVisitor(),
+ findCalibOffset->second);
+ }
+
+ /* PowerState */
+ auto findPowerOn = entry.second.find("PowerState");
+ PowerState readState = PowerState::always;
+ if (findPowerOn != entry.second.end())
+ {
+ std::string powerState = std::visit(
+ VariantToStringVisitor(), findPowerOn->second);
+ setReadState(powerState, readState);
+ }
+
+ if constexpr (debug)
+ {
+ std::cerr << "Configuration parsed for \n\t" << entry.first
+ << "\n"
+ << "with\n"
+ << "\tName: " << name << "\n"
+ << "\tBus: " << static_cast<int>(peciBus) << "\n"
+ << "\tAddress: " << static_cast<int>(peciAddr)
+ << "\n"
+ << "\tDimmRank: " << static_cast<int>(dimmRank)
+ << "\tOffset: " << calibOffset << "\n";
+ }
+
+ auto& sensor = sensors[name];
+ sensor = nullptr;
+
+ if (name.ends_with("_Temp"))
+ {
+ sensor = std::make_shared<DIMMTempSensor>(
+ dbusConnection, io, name, pathPair.first, objectServer,
+ std::move(sensorThresholds), maxTempReading,
+ minTempReading, "temperature", sensor_paths::unitDegreesC,
+ pollRate, readState, 0, peciBus, peciAddr, dimmRank);
+ }
+ else if (name.ends_with("_Power"))
+ {
+ sensor = std::make_shared<DIMMTempSensor>(
+ dbusConnection, io, name, pathPair.first, objectServer,
+ std::move(sensorThresholds), maxPowerReading,
+ minPowerReading, "power", sensor_paths::unitWatts,
+ pollRate, readState, 0, peciBus, peciAddr, dimmRank);
+ }
+
+ sensor->setupMatches(name);
+ sensor->init(name);
+ }
+ }
+ return true;
+}
+
+void startCreateSensors(
+ boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
+ boost::container::flat_map<std::string, std::shared_ptr<DIMMTempSensor>>& sensors,
+ std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+ boost::asio::steady_timer& filterTimer, int& retries)
+{
+ filterTimer.expires_after(std::chrono::seconds(3));
+ filterTimer.async_wait([&](const boost::system::error_code& ec) {
+ if (ec == boost::asio::error::operation_aborted)
+ {
+ return; // we're being canceled
+ }
+
+ if (createSensors(io, objectServer, sensors, dbusConnection))
{
- std::cerr << "Error contacting entity manager\n";
- return;
+ retries = 0;
+ std::cout << "createSensors successed " << std::endl;
}
- for (const auto& pathPair : resp)
+ else
{
- for (const auto& entry : pathPair.second)
+ std::cout << "createSensors failed with retries " << retries << std::endl;
+ if (retries > 0)
{
- if (entry.first != configInterface)
- {
- continue;
- }
- std::string name = loadVariant<std::string>(entry.second,
- "Name");
-
- std::vector<thresholds::Threshold> sensorThresholds;
- if (!parseThresholdsFromConfig(pathPair.second,
- sensorThresholds))
- {
- std::cerr << "error populating thresholds for " << name
- << "\n";
- }
-
- float pollRate = loadVariant<double>(entry.second, "PollRate");
- uint8_t peciBus = loadVariant<uint8_t>(entry.second, "Bus");
- uint8_t peciAddr = loadVariant<uint8_t>(entry.second, "Address");
- uint8_t dimmRank = loadVariant<uint8_t>(entry.second, "Rank");
-
- /* calibration offset */
- auto findCalibOffset = entry.second.find("Offset");
- double calibOffset = 0;
- if (findCalibOffset != entry.second.end())
- {
- calibOffset = std::visit(VariantToDoubleVisitor(),
- findCalibOffset->second);
- }
-
- /* PowerState */
- auto findPowerOn = entry.second.find("PowerState");
- PowerState readState = PowerState::always;
- if (findPowerOn != entry.second.end())
- {
- std::string powerState = std::visit(
- VariantToStringVisitor(), findPowerOn->second);
- setReadState(powerState, readState);
- }
-
- if constexpr (debug)
- {
- std::cerr << "Configuration parsed for \n\t" << entry.first
- << "\n"
- << "with\n"
- << "\tName: " << name << "\n"
- << "\tBus: " << static_cast<int>(peciBus) << "\n"
- << "\tAddress: " << static_cast<int>(peciAddr)
- << "\n"
- << "\tDimmRank: " << static_cast<int>(dimmRank)
- << "\tOffset: " << calibOffset << "\n";
- }
-
- auto& sensor = sensors[name];
- sensor = nullptr;
-
- if (name.ends_with("_Temp"))
- {
- sensor = std::make_shared<DIMMTempSensor>(
- dbusConnection, io, name, pathPair.first, objectServer,
- std::move(sensorThresholds), maxTempReading,
- minTempReading, "temperature", sensor_paths::unitDegreesC,
- pollRate, readState, 0, peciBus, peciAddr, dimmRank);
- }
- else if (name.ends_with("_Power"))
- {
- sensor = std::make_shared<DIMMTempSensor>(
- dbusConnection, io, name, pathPair.first, objectServer,
- std::move(sensorThresholds), maxPowerReading,
- minPowerReading, "power", sensor_paths::unitWatts,
- pollRate, readState, 0, peciBus, peciAddr, dimmRank);
- }
-
- sensor->setupMatches(name);
- sensor->init(name);
+ retries--;
+ startCreateSensors(io, objectServer, sensors,
+ dbusConnection, filterTimer, retries);
}
}
- },
- entityManagerName, "/xyz/openbmc_project/inventory",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+ });
}
int main()
@@ -162,9 +200,11 @@ int main()
boost::container::flat_map<std::string, std::shared_ptr<DIMMTempSensor>>
sensors;
+
boost::asio::post(
io, [&]() { createSensors(io, objectServer, sensors, systemBus); });
+ boost::asio::steady_timer filterTimer(io);
boost::asio::steady_timer configTimer(io);
std::function<void(sdbusplus::message::message&)> eventHandler =
[&](sdbusplus::message::message&) {
@@ -181,11 +221,9 @@ int main()
std::cerr << "timer error\n";
return;
}
- createSensors(io, objectServer, sensors, systemBus);
- if (sensors.empty())
- {
- std::cout << "Configuration not detected\n";
- }
+
+ int retries = 20;
+ startCreateSensors(io, objectServer, sensors, systemBus, filterTimer, retries);
});
};
diff --git a/src/IntelCPUSensorMain.cpp b/src/IntelCPUSensorMain.cpp
index bdb6d25..bffba79 100644
--- a/src/IntelCPUSensorMain.cpp
+++ b/src/IntelCPUSensorMain.cpp
@@ -50,7 +50,7 @@
#endif
// clang-format on
-static constexpr bool debug = false;
+static constexpr bool debug = true;
boost::container::flat_map<std::string, std::shared_ptr<IntelCPUSensor>>
gCpuSensors;
@@ -718,6 +718,7 @@ bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
{
bool useCache = false;
sensorConfigs.clear();
+ cpuConfigs.clear();
// use new data the first time, then refresh
for (const char* type : sensorTypes)
{
@@ -834,6 +835,39 @@ bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
return false;
}
+void startGetCpuConfig(std::shared_ptr<sdbusplus::asio::connection>& systemBus,
+ boost::container::flat_set<CPUConfig>& cpuConfigs, ManagedObjectType& sensorConfigs,
+ sdbusplus::asio::object_server& objectServer, boost::asio::steady_timer& filterTimer,
+ boost::asio::steady_timer& pingTimer, boost::asio::steady_timer& creationTimer,
+ boost::asio::io_context& io, int& retries)
+{
+ filterTimer.expires_after(std::chrono::seconds(3));
+ filterTimer.async_wait([&](const boost::system::error_code& ec) {
+ if (ec == boost::asio::error::operation_aborted)
+ {
+ return; // we're being canceled
+ }
+
+ if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer))
+ {
+ std::cout << "getCpuConfig successed " << std::endl;
+ retries = 0;
+ detectCpuAsync(pingTimer, creationTimer, io, objectServer,
+ systemBus, cpuConfigs, sensorConfigs);
+ }
+ else
+ {
+ std::cout << "getCpuConfig failed with retries " << retries << std::endl;
+ if(retries > 0)
+ {
+ retries--;
+ startGetCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer,
+ filterTimer, pingTimer, creationTimer, io, retries);
+ }
+ }
+ });
+}
+
int main()
{
boost::asio::io_context io;
@@ -874,21 +908,9 @@ int main()
std::cout << message.get_path() << " is changed\n";
}
- // this implicitly cancels the timer
- filterTimer.expires_after(std::chrono::seconds(1));
- filterTimer.async_wait([&](const boost::system::error_code& ec) {
- if (ec == boost::asio::error::operation_aborted)
- {
- return; // we're being canceled
- }
-
- if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs,
- objectServer))
- {
- detectCpuAsync(pingTimer, creationTimer, io, objectServer,
- systemBus, cpuConfigs, sensorConfigs);
- }
- });
+ int retries = 20;
+ startGetCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer,
+ filterTimer, pingTimer, creationTimer, io, retries);
};
std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
--
2.34.1
@@ -0,0 +1,31 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI += " \
file://0001-Fix-FanSpeed-sensors-object-cannot-create.patch \
file://0002-Add-Intel-CPU-sensors.patch \
file://0003-Add-DIMM-Temp-sensors.patch \
file://0004-Allows-external-overwrite-DIMM-temperature.patch \
file://0005-Add-dimmLEDInterface-and-dimmLEDState-property.patch \
file://0006-Add-PWM-sensors.patch \
file://0007-Remove-updateDIMMLedState-function-as-dimm-presence-.patch \
file://0008-Fix-issue-that-the-reading-value-of-dimm-temp-sensor.patch \
file://0009-switch-dimmtempsensor-from-peci-to-i3c.patch \
file://0010-Add-Sel-log-for-CPU-presence-event.patch \
file://0011-Ensure-CPU-sensor-names-match-those-in-the-IPMI-SDR-.patch \
file://0012-Set-Available-to-false-when-dimm-temp-reading-is-not.patch \
file://0013-Add-INA220-sensor.patch \
file://0014-Trigger-to-read-dimm-temp-by-vwgpio1.patch \
file://0015-Get-the-highest-temperature-of-TS0-TS1-SPD_Temp.patch \
file://0016-Add-retry-in-case-unable-to-open-intelcpu-sensor-fil.patch \
file://0017-Set-DIMM-LED-to-NA-when-dc-on-and-OFF-when-dc-off.patch \
file://0018-Fix-incorrect-config-state-for-intel-cpu-sensors.patch \
file://0019-Add-retries-to-get-inventory-objects.patch \
"
PACKAGECONFIG:append = " \
dimmtempsensor \
nvmesensor \
"
PACKAGECONFIG[dimmtempsensor] = "-Ddimmtemp=enabled, -Ddimmtemp=disabled"
SYSTEMD_SERVICE:${PN} += "${@bb.utils.contains('PACKAGECONFIG', 'dimmtempsensor', \
'xyz.openbmc_project.dimmtempsensor.service', '', d)}"

Some files were not shown because too many files have changed in this diff Show More