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/
}