blob: 19b81e8d02c6e8fa567d9d30804b4058b8b84494 [file] [log] [blame]
James Feist6714a252018-09-10 15:26:18 -07001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16
Andrew Jefferye73bd0a2023-01-25 10:39:57 +103017#include "IntelCPUSensor.hpp"
Ed Tanouseacbfdd2024-04-04 12:00:24 -070018#include "Thresholds.hpp"
Andrew Jefferye73bd0a2023-01-25 10:39:57 +103019#include "Utils.hpp"
20#include "VariantVisitors.hpp"
21
Oleksandr Shulzhenko77141ac2023-03-14 14:52:36 +010022#include <peci.h>
James Feist6714a252018-09-10 15:26:18 -070023
James Feist6714a252018-09-10 15:26:18 -070024#include <boost/algorithm/string/replace.hpp>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070025#include <boost/asio/error.hpp>
26#include <boost/asio/io_context.hpp>
27#include <boost/asio/steady_timer.hpp>
Patrick Venture96e97db2019-10-31 13:44:38 -070028#include <boost/container/flat_map.hpp>
James Feist6714a252018-09-10 15:26:18 -070029#include <boost/container/flat_set.hpp>
George Liu4ab892a2025-02-20 14:35:49 +080030#include <phosphor-logging/lg2.hpp>
James Feist38fb5982020-05-28 10:09:54 -070031#include <sdbusplus/asio/connection.hpp>
32#include <sdbusplus/asio/object_server.hpp>
33#include <sdbusplus/bus/match.hpp>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070034#include <sdbusplus/message.hpp>
James Feist38fb5982020-05-28 10:09:54 -070035
Ed Tanouseacbfdd2024-04-04 12:00:24 -070036#include <algorithm>
James Feist38fb5982020-05-28 10:09:54 -070037#include <array>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070038#include <cctype>
Jakub Nowackia38e5612023-03-08 12:27:01 +010039#include <cerrno>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070040#include <chrono>
41#include <cstddef>
42#include <cstdint>
43#include <cstring>
James Feist24f02f22019-04-15 11:05:39 -070044#include <filesystem>
James Feist6714a252018-09-10 15:26:18 -070045#include <fstream>
Patrick Venture96e97db2019-10-31 13:44:38 -070046#include <functional>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070047#include <ios>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070048#include <iterator>
Patrick Venture96e97db2019-10-31 13:44:38 -070049#include <memory>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070050#include <optional>
James Feist6714a252018-09-10 15:26:18 -070051#include <regex>
Patrick Venture96e97db2019-10-31 13:44:38 -070052#include <sstream>
Patrick Venture96e97db2019-10-31 13:44:38 -070053#include <string>
54#include <utility>
55#include <variant>
56#include <vector>
James Feist6714a252018-09-10 15:26:18 -070057
James Feistf87dc4c2018-12-05 14:39:51 -080058// clang-format off
59// this needs to be included last or we'll have build issues
60#include <linux/peci-ioctl.h>
Jae Hyun Yoo201c8d92019-02-27 15:41:56 -080061#if !defined(PECI_MBX_INDEX_DDR_DIMM_TEMP)
62#define PECI_MBX_INDEX_DDR_DIMM_TEMP MBX_INDEX_DDR_DIMM_TEMP
63#endif
James Feistf87dc4c2018-12-05 14:39:51 -080064// clang-format on
65
Thu Nguyen255da6b2022-07-29 10:05:52 +070066boost::container::flat_map<std::string, std::shared_ptr<IntelCPUSensor>>
67 gCpuSensors;
James Feistc140e202019-11-14 15:23:51 -080068boost::container::flat_map<std::string,
69 std::shared_ptr<sdbusplus::asio::dbus_interface>>
70 inventoryIfaces;
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -080071
James Feist6714a252018-09-10 15:26:18 -070072enum State
73{
74 OFF, // host powered down
75 ON, // host powered on
76 READY // host powered on and mem test passed - fully ready
77};
78
79struct CPUConfig
80{
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070081 CPUConfig(const uint64_t& bus, const uint64_t& addr,
82 const std::string& name, const State& state) :
Patrick Williams2aaf7172024-08-16 15:20:40 -040083 bus(bus), addr(addr), name(name), state(state)
James Feist38fb5982020-05-28 10:09:54 -070084 {}
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070085 int bus;
James Feist6714a252018-09-10 15:26:18 -070086 int addr;
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070087 std::string name;
James Feist6714a252018-09-10 15:26:18 -070088 State state;
89
90 bool operator<(const CPUConfig& rhs) const
91 {
Andrew Jeffery92b96292021-05-27 16:41:31 +093092 // NOLINTNEXTLINE
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070093 return (name < rhs.name);
James Feist6714a252018-09-10 15:26:18 -070094 }
95};
96
Jae Hyun Yoo9c55e6a2018-10-26 10:09:01 -070097static constexpr const char* peciDev = "/dev/peci-";
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -080098static constexpr const char* peciDevPath = "/sys/bus/peci/devices/";
Paul Fertser6e699732023-03-29 12:58:30 +000099static constexpr const char* rescanPath = "/sys/bus/peci/rescan";
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700100static constexpr const unsigned int rankNumMax = 8;
James Feist6714a252018-09-10 15:26:18 -0700101
Zev Weiss054aad82022-08-18 01:37:34 -0700102static constexpr auto sensorTypes{std::to_array<const char*>({"XeonCPU"})};
Brandon Kim66558232021-11-09 16:53:08 -0800103static constexpr auto hiddenProps{std::to_array<const char*>(
Thu Nguyen255da6b2022-07-29 10:05:52 +0700104 {IntelCPUSensor::labelTcontrol, "Tthrottle", "Tjmax"})};
James Feist6714a252018-09-10 15:26:18 -0700105
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700106void detectCpuAsync(
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700107 boost::asio::steady_timer& pingTimer,
Ed Tanous1f978632023-02-28 18:16:39 -0800108 boost::asio::steady_timer& creationTimer, boost::asio::io_context& io,
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700109 sdbusplus::asio::object_server& objectServer,
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800110 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800111 boost::container::flat_set<CPUConfig>& cpuConfigs,
112 ManagedObjectType& sensorConfigs);
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700113
Zbigniew Kurzynski0eee0c12020-06-18 14:20:08 +0200114std::string createSensorName(const std::string& label, const std::string& item,
115 const int& cpuId)
116{
117 std::string sensorName = label;
Ed Tanous2049bd22022-07-09 07:20:26 -0700118 if (item != "input")
Zbigniew Kurzynski0eee0c12020-06-18 14:20:08 +0200119 {
120 sensorName += " " + item;
121 }
PavanKumarIntel40baf772024-07-03 14:32:57 +0000122
123 std::string cpuStr = "CPU" + std::to_string(cpuId);
124 constexpr const char* subLabel = "DIMM";
125 std::size_t found = label.find(subLabel);
126 if (found != std::string::npos)
127 {
128 sensorName = cpuStr + " " + sensorName;
129 }
130 else
131 {
132 sensorName += " " + cpuStr;
133 }
Zbigniew Kurzynski0eee0c12020-06-18 14:20:08 +0200134 // converting to Upper Camel case whole name
135 bool isWordEnd = true;
136 std::transform(sensorName.begin(), sensorName.end(), sensorName.begin(),
137 [&isWordEnd](int c) {
Patrick Williams2aaf7172024-08-16 15:20:40 -0400138 if (std::isspace(c) != 0)
139 {
140 isWordEnd = true;
141 }
142 else
143 {
144 if (isWordEnd)
145 {
146 isWordEnd = false;
147 return std::toupper(c);
148 }
149 }
150 return c;
151 });
Zbigniew Kurzynski0eee0c12020-06-18 14:20:08 +0200152 return sensorName;
153}
154
Ed Tanous1f978632023-02-28 18:16:39 -0800155bool createSensors(boost::asio::io_context& io,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800156 sdbusplus::asio::object_server& objectServer,
157 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
158 boost::container::flat_set<CPUConfig>& cpuConfigs,
159 ManagedObjectType& sensorConfigs)
James Feist6714a252018-09-10 15:26:18 -0700160{
161 bool available = false;
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800162 for (const CPUConfig& cpu : cpuConfigs)
James Feist6714a252018-09-10 15:26:18 -0700163 {
164 if (cpu.state != State::OFF)
165 {
166 available = true;
Zev Weiss9702c9d2021-04-21 22:41:51 -0500167 std::shared_ptr<sdbusplus::asio::dbus_interface>& iface =
James Feistc140e202019-11-14 15:23:51 -0800168 inventoryIfaces[cpu.name];
169 if (iface != nullptr)
170 {
171 continue;
172 }
173 iface = objectServer.add_interface(
174 cpuInventoryPath + std::string("/") + cpu.name,
175 "xyz.openbmc_project.Inventory.Item");
176 iface->register_property("PrettyName", cpu.name);
177 iface->register_property("Present", true);
178 iface->initialize();
James Feist6714a252018-09-10 15:26:18 -0700179 }
180 }
181 if (!available)
182 {
Yoo, Jae Hyunf78d0a42018-10-10 11:03:11 -0700183 return false;
James Feist6714a252018-09-10 15:26:18 -0700184 }
185
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800186 if (sensorConfigs.empty())
James Feist6714a252018-09-10 15:26:18 -0700187 {
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800188 return false;
James Feist6714a252018-09-10 15:26:18 -0700189 }
190
Ed Tanous2e466962025-01-30 10:59:49 -0800191 std::vector<std::filesystem::path> hwmonNamePaths;
192 findFiles(std::filesystem::path(peciDevPath),
Paul Fertser6e699732023-03-29 12:58:30 +0000193 R"(peci-\d+/\d+-.+/peci[-_].+/hwmon/hwmon\d+/name$)",
194 hwmonNamePaths, 6);
195 if (hwmonNamePaths.empty())
James Feist6714a252018-09-10 15:26:18 -0700196 {
George Liu4ab892a2025-02-20 14:35:49 +0800197 lg2::error("No CPU sensors in system");
Paul Fertser75f92582023-03-29 12:48:07 +0000198 return false;
James Feist6714a252018-09-10 15:26:18 -0700199 }
200
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700201 boost::container::flat_set<std::string> scannedDirectories;
202 boost::container::flat_set<std::string> createdSensors;
203
Ed Tanous2e466962025-01-30 10:59:49 -0800204 for (const std::filesystem::path& hwmonNamePath : hwmonNamePaths)
James Feist6714a252018-09-10 15:26:18 -0700205 {
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700206 auto hwmonDirectory = hwmonNamePath.parent_path();
207
208 auto ret = scannedDirectories.insert(hwmonDirectory.string());
209 if (!ret.second)
James Feist6714a252018-09-10 15:26:18 -0700210 {
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700211 continue; // already searched this path
212 }
213
Ed Tanous2e466962025-01-30 10:59:49 -0800214 std::filesystem::path::iterator it = hwmonNamePath.begin();
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700215 std::advance(it, 6); // pick the 6th part for a PECI client device name
216 std::string deviceName = *it;
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700217
218 size_t bus = 0;
219 size_t addr = 0;
Akshit Shah03d333e2023-08-23 22:14:28 +0000220 if (!getDeviceBusAddr(deviceName, bus, addr))
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700221 {
222 continue;
223 }
224
225 std::ifstream nameFile(hwmonNamePath);
226 if (!nameFile.good())
227 {
George Liu4ab892a2025-02-20 14:35:49 +0800228 lg2::error("Failure reading '{PATH}'", "PATH", hwmonNamePath);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700229 continue;
230 }
231 std::string hwmonName;
232 std::getline(nameFile, hwmonName);
James Feist6714a252018-09-10 15:26:18 -0700233 nameFile.close();
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800234 if (hwmonName.empty())
James Feist6714a252018-09-10 15:26:18 -0700235 {
236 // shouldn't have an empty name file
237 continue;
238 }
Alexander Hansen89be6142025-09-18 15:36:16 +0200239 lg2::debug("Checking: '{PATH}': '{NAME}'", "PATH", hwmonNamePath,
240 "NAME", hwmonName);
James Feist6714a252018-09-10 15:26:18 -0700241
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700242 std::string sensorType;
James Feist6714a252018-09-10 15:26:18 -0700243 const SensorData* sensorData = nullptr;
244 const std::string* interfacePath = nullptr;
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700245 const SensorBaseConfiguration* baseConfiguration = nullptr;
James Feist6714a252018-09-10 15:26:18 -0700246
Zev Weiss8908b3c2022-08-12 18:21:01 -0700247 for (const auto& [path, cfgData] : sensorConfigs)
James Feist6714a252018-09-10 15:26:18 -0700248 {
Zev Weiss8908b3c2022-08-12 18:21:01 -0700249 sensorData = &cfgData;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700250 for (const char* type : sensorTypes)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700251 {
Zev Weiss26fb1492022-08-17 15:33:46 -0700252 sensorType = type;
Zev Weiss054aad82022-08-18 01:37:34 -0700253 auto sensorBase =
254 sensorData->find(configInterfaceName(sensorType));
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700255 if (sensorBase != sensorData->end())
256 {
257 baseConfiguration = &(*sensorBase);
258 break;
259 }
260 }
261 if (baseConfiguration == nullptr)
262 {
George Liu4ab892a2025-02-20 14:35:49 +0800263 lg2::error("error finding base configuration for '{NAME}'",
264 "NAME", hwmonName);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700265 continue;
266 }
267 auto configurationBus = baseConfiguration->second.find("Bus");
268 auto configurationAddress =
269 baseConfiguration->second.find("Address");
270
271 if (configurationBus == baseConfiguration->second.end() ||
272 configurationAddress == baseConfiguration->second.end())
273 {
George Liu4ab892a2025-02-20 14:35:49 +0800274 lg2::error("error finding bus or address in configuration");
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700275 continue;
276 }
277
James Feist3eb82622019-02-08 13:10:22 -0800278 if (std::get<uint64_t>(configurationBus->second) != bus ||
279 std::get<uint64_t>(configurationAddress->second) != addr)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700280 {
281 continue;
282 }
283
Zev Weiss8908b3c2022-08-12 18:21:01 -0700284 interfacePath = &path.str;
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700285 break;
286 }
287 if (interfacePath == nullptr)
288 {
George Liu4ab892a2025-02-20 14:35:49 +0800289 lg2::error("failed to find match for '{NAME}'", "NAME", hwmonName);
James Feist6714a252018-09-10 15:26:18 -0700290 continue;
291 }
292
293 auto findCpuId = baseConfiguration->second.find("CpuID");
294 if (findCpuId == baseConfiguration->second.end())
295 {
George Liu4ab892a2025-02-20 14:35:49 +0800296 lg2::error("could not determine CPU ID for '{NAME}'", "NAME",
297 hwmonName);
James Feist6714a252018-09-10 15:26:18 -0700298 continue;
299 }
Patrick Williams2aaf7172024-08-16 15:20:40 -0400300 int cpuId =
301 std::visit(VariantToUnsignedIntVisitor(), findCpuId->second);
James Feist6714a252018-09-10 15:26:18 -0700302
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700303 auto directory = hwmonNamePath.parent_path();
Ed Tanous2e466962025-01-30 10:59:49 -0800304 std::vector<std::filesystem::path> inputPaths;
Zbigniew Kurzynski8d8d8d72020-05-29 19:21:24 +0200305 if (!findFiles(directory, R"((temp|power)\d+_(input|average|cap)$)",
Zbigniew Kurzynski0a4c4802020-04-01 11:22:27 +0200306 inputPaths, 0))
James Feist6714a252018-09-10 15:26:18 -0700307 {
George Liu4ab892a2025-02-20 14:35:49 +0800308 lg2::error("No temperature sensors in system");
James Feist6714a252018-09-10 15:26:18 -0700309 continue;
310 }
311
312 // iterate through all found temp sensors
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800313 for (const auto& inputPath : inputPaths)
James Feist6714a252018-09-10 15:26:18 -0700314 {
Zbigniew Kurzynski63f38662020-06-09 13:02:11 +0200315 auto fileParts = splitFileName(inputPath);
Zbigniew Kurzynski0a4c4802020-04-01 11:22:27 +0200316 if (!fileParts)
317 {
318 continue;
319 }
Zbigniew Kurzynskidbfd4662020-09-28 18:06:00 +0200320 auto& [type, nr, item] = *fileParts;
James Feist6714a252018-09-10 15:26:18 -0700321 auto inputPathStr = inputPath.string();
Patrick Williams2aaf7172024-08-16 15:20:40 -0400322 auto labelPath =
323 boost::replace_all_copy(inputPathStr, item, "label");
James Feist6714a252018-09-10 15:26:18 -0700324 std::ifstream labelFile(labelPath);
325 if (!labelFile.good())
326 {
George Liu4ab892a2025-02-20 14:35:49 +0800327 lg2::error("Failure reading '{PATH}'", "PATH", labelPath);
James Feist6714a252018-09-10 15:26:18 -0700328 continue;
329 }
330 std::string label;
331 std::getline(labelFile, label);
332 labelFile.close();
Jae Hyun Yoo13f48882019-02-19 13:37:07 -0800333
Zbigniew Kurzynski0eee0c12020-06-18 14:20:08 +0200334 std::string sensorName = createSensorName(label, item, cpuId);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700335
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800336 auto findSensor = gCpuSensors.find(sensorName);
337 if (findSensor != gCpuSensors.end())
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700338 {
Alexander Hansen89be6142025-09-18 15:36:16 +0200339 lg2::debug("Skipped: '{PATH}': '{NAME}' is already created",
340 "PATH", inputPath, "NAME", sensorName);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700341 continue;
342 }
343
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800344 // check hidden properties
345 bool show = true;
346 for (const char* prop : hiddenProps)
347 {
348 if (label == prop)
349 {
350 show = false;
351 break;
352 }
353 }
354
Vijay Khemka86dea2b2019-06-06 11:14:37 -0700355 /*
356 * Find if there is DtsCritOffset is configured in config file
357 * set it if configured or else set it to 0
358 */
359 double dtsOffset = 0;
360 if (label == "DTS")
361 {
362 auto findThrOffset =
363 baseConfiguration->second.find("DtsCritOffset");
364 if (findThrOffset != baseConfiguration->second.end())
365 {
366 dtsOffset = std::visit(VariantToDoubleVisitor(),
367 findThrOffset->second);
368 }
369 }
370
James Feist6714a252018-09-10 15:26:18 -0700371 std::vector<thresholds::Threshold> sensorThresholds;
Ed Tanous8a57ec02020-10-09 12:46:52 -0700372 std::string labelHead = label.substr(0, label.find(' '));
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700373 parseThresholdsFromConfig(*sensorData, sensorThresholds,
Yoo, Jae Hyun81a464c2018-10-09 16:38:58 -0700374 &labelHead);
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800375 if (sensorThresholds.empty())
James Feist6714a252018-09-10 15:26:18 -0700376 {
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700377 if (!parseThresholdsFromAttr(sensorThresholds, inputPathStr,
Thu Nguyen255da6b2022-07-29 10:05:52 +0700378 IntelCPUSensor::sensorScaleFactor,
Chris Sidesa3279232023-04-24 16:08:13 -0500379 dtsOffset, 0))
James Feist6714a252018-09-10 15:26:18 -0700380 {
George Liu4ab892a2025-02-20 14:35:49 +0800381 lg2::error("error populating thresholds for '{NAME}'",
382 "NAME", sensorName);
James Feist6714a252018-09-10 15:26:18 -0700383 }
384 }
James Feistc140e202019-11-14 15:23:51 -0800385 auto& sensorPtr = gCpuSensors[sensorName];
386 // make sure destructor fires before creating a new one
387 sensorPtr = nullptr;
Thu Nguyen255da6b2022-07-29 10:05:52 +0700388 sensorPtr = std::make_shared<IntelCPUSensor>(
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700389 inputPathStr, sensorType, objectServer, dbusConnection, io,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800390 sensorName, std::move(sensorThresholds), *interfacePath, cpuId,
Vijay Khemka86dea2b2019-06-06 11:14:37 -0700391 show, dtsOffset);
Arun P. Mohanan04d05062021-10-29 20:30:26 +0530392 sensorPtr->setupRead();
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700393 createdSensors.insert(sensorName);
Alexander Hansen89be6142025-09-18 15:36:16 +0200394 lg2::debug("Mapped: '{PATH}' to '{NAME}'", "PATH", inputPath,
395 "NAME", sensorName);
James Feist6714a252018-09-10 15:26:18 -0700396 }
397 }
Yoo, Jae Hyunf78d0a42018-10-10 11:03:11 -0700398
Ed Tanous2049bd22022-07-09 07:20:26 -0700399 if (static_cast<unsigned int>(!createdSensors.empty()) != 0U)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700400 {
George Liu4ab892a2025-02-20 14:35:49 +0800401 if (createdSensors.size() == 1)
402 {
403 lg2::info("Sensor is created");
404 }
405 else
406 {
407 lg2::info("Sensors are created");
408 }
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700409 }
Yoo, Jae Hyuna441f3c2018-10-09 16:43:03 -0700410
Yoo, Jae Hyunf78d0a42018-10-10 11:03:11 -0700411 return true;
James Feist6714a252018-09-10 15:26:18 -0700412}
413
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800414bool exportDevice(const CPUConfig& config)
James Feist6714a252018-09-10 15:26:18 -0700415{
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700416 std::ostringstream hex;
417 hex << std::hex << config.addr;
418 const std::string& addrHexStr = hex.str();
419 std::string busStr = std::to_string(config.bus);
420
421 std::string parameters = "peci-client 0x" + addrHexStr;
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800422 std::string devPath = peciDevPath;
423 std::string delDevice = devPath + "peci-" + busStr + "/delete_device";
424 std::string newDevice = devPath + "peci-" + busStr + "/new_device";
425 std::string newClient = devPath + busStr + "-" + addrHexStr + "/driver";
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700426
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800427 std::filesystem::path devicePath(newDevice);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700428 const std::string& dir = devicePath.parent_path().string();
James Feistcf3bce62019-01-08 10:07:19 -0800429 for (const auto& path : std::filesystem::directory_iterator(dir))
James Feist6714a252018-09-10 15:26:18 -0700430 {
James Feistcf3bce62019-01-08 10:07:19 -0800431 if (!std::filesystem::is_directory(path))
James Feist6714a252018-09-10 15:26:18 -0700432 {
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700433 continue;
James Feist6714a252018-09-10 15:26:18 -0700434 }
435
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700436 const std::string& directoryName = path.path().filename();
Zev Weiss6c106d62022-08-17 20:50:00 -0700437 if (directoryName.starts_with(busStr) &&
438 directoryName.ends_with(addrHexStr))
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700439 {
Alexander Hansen89be6142025-09-18 15:36:16 +0200440 lg2::debug("'{PARAMETERS}' on bus '{BUS}' is already exported",
441 "PARAMETERS", parameters, "BUS", busStr);
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800442
443 std::ofstream delDeviceFile(delDevice);
444 if (!delDeviceFile.good())
445 {
George Liu4ab892a2025-02-20 14:35:49 +0800446 lg2::error("Error opening '{DEVICE}'", "DEVICE", delDevice);
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800447 return false;
448 }
449 delDeviceFile << parameters;
450 delDeviceFile.close();
451
452 break;
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700453 }
James Feist6714a252018-09-10 15:26:18 -0700454 }
455
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800456 std::ofstream deviceFile(newDevice);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700457 if (!deviceFile.good())
James Feist6714a252018-09-10 15:26:18 -0700458 {
George Liu4ab892a2025-02-20 14:35:49 +0800459 lg2::error("Error opening '{DEVICE}'", "DEVICE", newDevice);
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800460 return false;
James Feist6714a252018-09-10 15:26:18 -0700461 }
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700462 deviceFile << parameters;
463 deviceFile.close();
464
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800465 if (!std::filesystem::exists(newClient))
466 {
George Liu4ab892a2025-02-20 14:35:49 +0800467 lg2::error("Error creating '{CLIENT}'", "CLIENT", newClient);
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800468 return false;
469 }
470
George Liu4ab892a2025-02-20 14:35:49 +0800471 lg2::info("'{PARAMETERS}' on bus '{BUS}' is exported", "PARAMETERS",
472 parameters, "BUS", busStr);
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800473
474 return true;
James Feist6714a252018-09-10 15:26:18 -0700475}
476
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700477void detectCpu(boost::asio::steady_timer& pingTimer,
478 boost::asio::steady_timer& creationTimer,
Ed Tanous1f978632023-02-28 18:16:39 -0800479 boost::asio::io_context& io,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800480 sdbusplus::asio::object_server& objectServer,
481 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
482 boost::container::flat_set<CPUConfig>& cpuConfigs,
483 ManagedObjectType& sensorConfigs)
James Feist6714a252018-09-10 15:26:18 -0700484{
James Feist6714a252018-09-10 15:26:18 -0700485 size_t rescanDelaySeconds = 0;
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700486 static bool keepPinging = false;
Oleksandr Shulzhenko28c56bf2023-05-11 15:42:53 +0200487 int peciFd = -1;
Jae Hyun Yoo9c55e6a2018-10-26 10:09:01 -0700488
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800489 for (CPUConfig& config : cpuConfigs)
James Feist6714a252018-09-10 15:26:18 -0700490 {
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800491 if (config.state == State::READY)
492 {
493 continue;
494 }
495
Paul Fertser6e699732023-03-29 12:58:30 +0000496 std::fstream rescan{rescanPath, std::ios::out};
497 if (rescan.is_open())
498 {
Ed Tanous2e466962025-01-30 10:59:49 -0800499 std::vector<std::filesystem::path> peciPaths;
Paul Fertser6e699732023-03-29 12:58:30 +0000500 std::ostringstream searchPath;
501 searchPath << std::hex << "peci-" << config.bus << "/" << config.bus
502 << "-" << config.addr;
Ed Tanous2e466962025-01-30 10:59:49 -0800503 findFiles(std::filesystem::path(peciDevPath + searchPath.str()),
Paul Fertser6e699732023-03-29 12:58:30 +0000504 R"(peci_cpu.dimmtemp.+/hwmon/hwmon\d+/name$)", peciPaths,
505 3);
506 if (!peciPaths.empty())
507 {
508 config.state = State::READY;
509 rescanDelaySeconds = 1;
510 }
511 else
512 {
Ed Tanous2e466962025-01-30 10:59:49 -0800513 findFiles(std::filesystem::path(peciDevPath + searchPath.str()),
Paul Fertser6e699732023-03-29 12:58:30 +0000514 R"(peci_cpu.cputemp.+/hwmon/hwmon\d+/name$)",
515 peciPaths, 3);
516 if (!peciPaths.empty())
517 {
518 config.state = State::ON;
519 rescanDelaySeconds = 3;
520 }
521 else
522 {
523 // https://www.kernel.org/doc/html/latest/admin-guide/abi-testing.html#abi-sys-bus-peci-rescan
524 rescan << "1";
525 }
526 }
527 if (config.state != State::READY)
528 {
529 keepPinging = true;
530 }
531
532 continue;
533 }
534
Jae Hyun Yoo9c55e6a2018-10-26 10:09:01 -0700535 std::string peciDevPath = peciDev + std::to_string(config.bus);
Ed Tanous99c44092022-01-14 09:59:09 -0800536
Oleksandr Shulzhenko28c56bf2023-05-11 15:42:53 +0200537 peci_SetDevName(peciDevPath.data());
538
Ed Tanous99c44092022-01-14 09:59:09 -0800539 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
Oleksandr Shulzhenko28c56bf2023-05-11 15:42:53 +0200540 if ((peci_Lock(&peciFd, PECI_NO_WAIT) != PECI_CC_SUCCESS) ||
541 (peciFd < 0))
Jae Hyun Yoo9c55e6a2018-10-26 10:09:01 -0700542 {
George Liu4ab892a2025-02-20 14:35:49 +0800543 lg2::error("unable to open '{PATH}', '{ERRNO}'", "PATH",
544 peciDevPath, "ERRNO", std::strerror(errno));
Jakub Nowackia38e5612023-03-08 12:27:01 +0100545 detectCpuAsync(pingTimer, creationTimer, io, objectServer,
546 dbusConnection, cpuConfigs, sensorConfigs);
547 return;
Jae Hyun Yoo9c55e6a2018-10-26 10:09:01 -0700548 }
549
Ed Tanousa771f6a2022-01-14 09:36:51 -0800550 State newState = State::OFF;
Ed Tanous99c44092022-01-14 09:59:09 -0800551
552 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
Oleksandr Shulzhenko77141ac2023-03-14 14:52:36 +0100553 if (peci_Ping(config.addr) == PECI_CC_SUCCESS)
James Feist6714a252018-09-10 15:26:18 -0700554 {
555 bool dimmReady = false;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700556 for (unsigned int rank = 0; rank < rankNumMax; rank++)
James Feist6714a252018-09-10 15:26:18 -0700557 {
Oleksandr Shulzhenko77141ac2023-03-14 14:52:36 +0100558 std::array<uint8_t, 8> pkgConfig{};
559 uint8_t cc = 0;
Ed Tanous99c44092022-01-14 09:59:09 -0800560
561 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
Oleksandr Shulzhenko77141ac2023-03-14 14:52:36 +0100562 if (peci_RdPkgConfig(config.addr, PECI_MBX_INDEX_DDR_DIMM_TEMP,
Patrick Williams2aaf7172024-08-16 15:20:40 -0400563 rank, 4, pkgConfig.data(), &cc) ==
564 PECI_CC_SUCCESS)
James Feist6714a252018-09-10 15:26:18 -0700565 {
Matt Simmering38857572023-08-10 14:41:46 -0700566 // Depending on CPU generation, both 0 and 0xFF can be used
567 // to indicate no DIMM presence
568 if (((pkgConfig[0] != 0xFF) && (pkgConfig[0] != 0U)) ||
569 ((pkgConfig[1] != 0xFF) && (pkgConfig[1] != 0U)))
James Feist6714a252018-09-10 15:26:18 -0700570 {
571 dimmReady = true;
572 break;
573 }
574 }
575 else
576 {
577 break;
578 }
579 }
Yoo, Jae Hyuna441f3c2018-10-09 16:43:03 -0700580
James Feist6714a252018-09-10 15:26:18 -0700581 if (dimmReady)
582 {
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700583 newState = State::READY;
James Feist6714a252018-09-10 15:26:18 -0700584 }
585 else
586 {
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700587 newState = State::ON;
James Feist6714a252018-09-10 15:26:18 -0700588 }
589 }
James Feist6714a252018-09-10 15:26:18 -0700590
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700591 if (config.state != newState)
James Feist6714a252018-09-10 15:26:18 -0700592 {
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700593 if (newState != State::OFF)
James Feist6714a252018-09-10 15:26:18 -0700594 {
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700595 if (config.state == State::OFF)
596 {
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800597 std::array<uint8_t, 8> pkgConfig{};
598 uint8_t cc = 0;
599
600 if (peci_RdPkgConfig(config.addr, PECI_MBX_INDEX_CPU_ID, 0,
Patrick Williams2aaf7172024-08-16 15:20:40 -0400601 4, pkgConfig.data(), &cc) ==
602 PECI_CC_SUCCESS)
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800603 {
George Liu4ab892a2025-02-20 14:35:49 +0800604 lg2::info("'{NAME}' is detected", "NAME", config.name);
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800605 if (!exportDevice(config))
606 {
607 newState = State::OFF;
608 }
609 }
610 else
611 {
612 newState = State::OFF;
613 }
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700614 }
James Feist6714a252018-09-10 15:26:18 -0700615
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700616 if (newState == State::ON)
617 {
618 rescanDelaySeconds = 3;
619 }
620 else if (newState == State::READY)
621 {
622 rescanDelaySeconds = 5;
George Liu4ab892a2025-02-20 14:35:49 +0800623 lg2::info("DIMM(s) on '{NAME}' is/are detected", "NAME",
624 config.name);
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700625 }
Yoo, Jae Hyunf78d0a42018-10-10 11:03:11 -0700626 }
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700627
628 config.state = newState;
Yoo, Jae Hyunf78d0a42018-10-10 11:03:11 -0700629 }
630
631 if (config.state != State::READY)
James Feist6714a252018-09-10 15:26:18 -0700632 {
633 keepPinging = true;
634 }
635
Alexander Hansen89be6142025-09-18 15:36:16 +0200636 lg2::debug("'{NAME}', state: '{STATE}'", "NAME", config.name, "STATE",
637 config.state);
Wang Xiaohua4cd5a902023-07-04 16:28:43 +0800638 peci_Unlock(peciFd);
James Feist6714a252018-09-10 15:26:18 -0700639 }
640
Ed Tanous2049bd22022-07-09 07:20:26 -0700641 if (rescanDelaySeconds != 0U)
James Feist6714a252018-09-10 15:26:18 -0700642 {
Ed Tanous83db50c2023-03-01 10:20:24 -0800643 creationTimer.expires_after(std::chrono::seconds(rescanDelaySeconds));
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700644 creationTimer.async_wait([&](const boost::system::error_code& ec) {
645 if (ec == boost::asio::error::operation_aborted)
646 {
647 return; // we're being canceled
648 }
649
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800650 if (!createSensors(io, objectServer, dbusConnection, cpuConfigs,
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700651 sensorConfigs) ||
652 keepPinging)
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700653 {
654 detectCpuAsync(pingTimer, creationTimer, io, objectServer,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800655 dbusConnection, cpuConfigs, sensorConfigs);
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700656 }
657 });
James Feist6714a252018-09-10 15:26:18 -0700658 }
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700659 else if (keepPinging)
James Feist6714a252018-09-10 15:26:18 -0700660 {
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800661 detectCpuAsync(pingTimer, creationTimer, io, objectServer,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800662 dbusConnection, cpuConfigs, sensorConfigs);
James Feist6714a252018-09-10 15:26:18 -0700663 }
664}
665
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700666void detectCpuAsync(
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700667 boost::asio::steady_timer& pingTimer,
Ed Tanous1f978632023-02-28 18:16:39 -0800668 boost::asio::steady_timer& creationTimer, boost::asio::io_context& io,
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700669 sdbusplus::asio::object_server& objectServer,
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800670 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800671 boost::container::flat_set<CPUConfig>& cpuConfigs,
672 ManagedObjectType& sensorConfigs)
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700673{
Ed Tanous83db50c2023-03-01 10:20:24 -0800674 pingTimer.expires_after(std::chrono::seconds(1));
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700675 pingTimer.async_wait([&](const boost::system::error_code& ec) {
676 if (ec == boost::asio::error::operation_aborted)
677 {
678 return; // we're being canceled
679 }
680
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800681 detectCpu(pingTimer, creationTimer, io, objectServer, dbusConnection,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800682 cpuConfigs, sensorConfigs);
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700683 });
684}
685
James Feistc140e202019-11-14 15:23:51 -0800686bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
687 boost::container::flat_set<CPUConfig>& cpuConfigs,
688 ManagedObjectType& sensorConfigs,
689 sdbusplus::asio::object_server& objectServer)
James Feist6714a252018-09-10 15:26:18 -0700690{
James Feist6714a252018-09-10 15:26:18 -0700691 bool useCache = false;
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800692 sensorConfigs.clear();
James Feist6714a252018-09-10 15:26:18 -0700693 // use new data the first time, then refresh
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700694 for (const char* type : sensorTypes)
James Feist6714a252018-09-10 15:26:18 -0700695 {
Zev Weiss26fb1492022-08-17 15:33:46 -0700696 if (!getSensorConfiguration(type, systemBus, sensorConfigs, useCache))
James Feist6714a252018-09-10 15:26:18 -0700697 {
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700698 return false;
James Feist6714a252018-09-10 15:26:18 -0700699 }
700 useCache = true;
701 }
702
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700703 // check PECI client addresses and names from CPU configuration
James Feist6714a252018-09-10 15:26:18 -0700704 // before starting ping operation
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700705 for (const char* type : sensorTypes)
James Feist6714a252018-09-10 15:26:18 -0700706 {
Zev Weiss8908b3c2022-08-12 18:21:01 -0700707 for (const auto& [path, cfgData] : sensorConfigs)
James Feist6714a252018-09-10 15:26:18 -0700708 {
Zev Weiss8908b3c2022-08-12 18:21:01 -0700709 for (const auto& [intf, cfg] : cfgData)
James Feist6714a252018-09-10 15:26:18 -0700710 {
Zev Weiss054aad82022-08-18 01:37:34 -0700711 if (intf != configInterfaceName(type))
James Feist6714a252018-09-10 15:26:18 -0700712 {
713 continue;
714 }
715
Zev Weiss8908b3c2022-08-12 18:21:01 -0700716 auto findName = cfg.find("Name");
717 if (findName == cfg.end())
James Feist6714a252018-09-10 15:26:18 -0700718 {
719 continue;
720 }
Patrick Williams2aaf7172024-08-16 15:20:40 -0400721 std::string nameRaw =
722 std::visit(VariantToStringVisitor(), findName->second);
723 std::string name =
724 std::regex_replace(nameRaw, illegalDbusRegex, "_");
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700725
James Feistc140e202019-11-14 15:23:51 -0800726 auto present = std::optional<bool>();
727 // if we can't detect it via gpio, we set presence later
Zev Weiss8908b3c2022-08-12 18:21:01 -0700728 for (const auto& [suppIntf, suppCfg] : cfgData)
James Feist58295ad2019-05-30 15:01:41 -0700729 {
Zev Weiss8908b3c2022-08-12 18:21:01 -0700730 if (suppIntf.find("PresenceGpio") != std::string::npos)
James Feist58295ad2019-05-30 15:01:41 -0700731 {
Zev Weiss8908b3c2022-08-12 18:21:01 -0700732 present = cpuIsPresent(suppCfg);
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700733 break;
James Feist58295ad2019-05-30 15:01:41 -0700734 }
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700735 }
736
Patrick Williams80c68052025-05-13 23:31:49 -0400737 if (!inventoryIfaces.contains(name) && present)
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700738 {
739 auto iface = objectServer.add_interface(
740 cpuInventoryPath + std::string("/") + name,
741 "xyz.openbmc_project.Inventory.Item");
742 iface->register_property("PrettyName", name);
James Feistc140e202019-11-14 15:23:51 -0800743 iface->register_property("Present", *present);
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700744 iface->initialize();
745 inventoryIfaces[name] = std::move(iface);
746 }
James Feist58295ad2019-05-30 15:01:41 -0700747
Zev Weiss8908b3c2022-08-12 18:21:01 -0700748 auto findBus = cfg.find("Bus");
749 if (findBus == cfg.end())
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700750 {
George Liu4ab892a2025-02-20 14:35:49 +0800751 lg2::error("Can't find 'Bus' setting in '{NAME}'", "NAME",
752 name);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700753 continue;
754 }
Patrick Williams2aaf7172024-08-16 15:20:40 -0400755 uint64_t bus =
756 std::visit(VariantToUnsignedIntVisitor(), findBus->second);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700757
Zev Weiss8908b3c2022-08-12 18:21:01 -0700758 auto findAddress = cfg.find("Address");
759 if (findAddress == cfg.end())
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700760 {
George Liu4ab892a2025-02-20 14:35:49 +0800761 lg2::error("Can't find 'Address' setting in '{NAME}'",
762 "NAME", name);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700763 continue;
764 }
James Feist3eb82622019-02-08 13:10:22 -0800765 uint64_t addr = std::visit(VariantToUnsignedIntVisitor(),
766 findAddress->second);
James Feist6714a252018-09-10 15:26:18 -0700767
Alexander Hansen89be6142025-09-18 15:36:16 +0200768 lg2::debug(
769 "bus: {BUS}, addr: {ADDR}, name: {NAME}, type: {TYPE}",
770 "BUS", bus, "ADDR", addr, "NAME", name, "TYPE", type);
James Feist6714a252018-09-10 15:26:18 -0700771
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800772 cpuConfigs.emplace(bus, addr, name, State::OFF);
James Feist6714a252018-09-10 15:26:18 -0700773 }
774 }
775 }
Yoo, Jae Hyuna441f3c2018-10-09 16:43:03 -0700776
Ed Tanous2049bd22022-07-09 07:20:26 -0700777 if (static_cast<unsigned int>(!cpuConfigs.empty()) != 0U)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700778 {
George Liu4ab892a2025-02-20 14:35:49 +0800779 if (cpuConfigs.size() == 1)
780 {
781 lg2::info("CPU config is parsed");
782 }
783 else
784 {
785 lg2::info("CPU configs are parsed");
786 }
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700787 return true;
788 }
789
790 return false;
James Feist6714a252018-09-10 15:26:18 -0700791}
792
James Feistb6c0b912019-07-09 12:21:44 -0700793int main()
James Feist6714a252018-09-10 15:26:18 -0700794{
Ed Tanous1f978632023-02-28 18:16:39 -0800795 boost::asio::io_context io;
James Feist6714a252018-09-10 15:26:18 -0700796 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800797 boost::container::flat_set<CPUConfig> cpuConfigs;
James Feist6714a252018-09-10 15:26:18 -0700798
Ed Tanous14ed5e92022-07-12 15:50:23 -0700799 sdbusplus::asio::object_server objectServer(systemBus, true);
800 objectServer.add_manager("/xyz/openbmc_project/sensors");
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700801 boost::asio::steady_timer pingTimer(io);
802 boost::asio::steady_timer creationTimer(io);
803 boost::asio::steady_timer filterTimer(io);
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800804 ManagedObjectType sensorConfigs;
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700805
Ed Tanous83db50c2023-03-01 10:20:24 -0800806 filterTimer.expires_after(std::chrono::seconds(1));
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700807 filterTimer.async_wait([&](const boost::system::error_code& ec) {
808 if (ec == boost::asio::error::operation_aborted)
809 {
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700810 return; // we're being canceled
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700811 }
812
James Feistc140e202019-11-14 15:23:51 -0800813 if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer))
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700814 {
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800815 detectCpuAsync(pingTimer, creationTimer, io, objectServer,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800816 systemBus, cpuConfigs, sensorConfigs);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700817 }
818 });
819
Patrick Williams92f8f512022-07-22 19:26:55 -0500820 std::function<void(sdbusplus::message_t&)> eventHandler =
821 [&](sdbusplus::message_t& message) {
Patrick Williams2aaf7172024-08-16 15:20:40 -0400822 if (message.is_method_error())
James Feist6714a252018-09-10 15:26:18 -0700823 {
George Liu4ab892a2025-02-20 14:35:49 +0800824 lg2::error("callback method error");
Patrick Williams2aaf7172024-08-16 15:20:40 -0400825 return;
James Feist6714a252018-09-10 15:26:18 -0700826 }
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700827
Alexander Hansen89be6142025-09-18 15:36:16 +0200828 lg2::debug("'{PATH}' is changed", "PATH", message.get_path());
Patrick Williams2aaf7172024-08-16 15:20:40 -0400829
830 // this implicitly cancels the timer
831 filterTimer.expires_after(std::chrono::seconds(1));
832 filterTimer.async_wait([&](const boost::system::error_code& ec) {
833 if (ec == boost::asio::error::operation_aborted)
834 {
835 return; // we're being canceled
836 }
837
838 if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs,
839 objectServer))
840 {
841 detectCpuAsync(pingTimer, creationTimer, io, objectServer,
842 systemBus, cpuConfigs, sensorConfigs);
843 }
844 });
845 };
James Feist6714a252018-09-10 15:26:18 -0700846
Zev Weiss214d9712022-08-12 12:54:31 -0700847 std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
848 setupPropertiesChangedMatches(*systemBus, sensorTypes, eventHandler);
James Feist6714a252018-09-10 15:26:18 -0700849
Thu Nguyen255da6b2022-07-29 10:05:52 +0700850 systemBus->request_name("xyz.openbmc_project.IntelCPUSensor");
Bruce Lee1263c3d2021-06-04 15:16:33 +0800851
852 setupManufacturingModeMatch(*systemBus);
James Feist6714a252018-09-10 15:26:18 -0700853 io.run();
Zhikui Ren8685b172021-06-29 15:16:52 -0700854 return 0;
James Feist6714a252018-09-10 15:26:18 -0700855}