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

