blob: 7d1491572feca2831ff36dea4cfb8652d0858d46 [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>
James Feist38fb5982020-05-28 10:09:54 -070030#include <sdbusplus/asio/connection.hpp>
31#include <sdbusplus/asio/object_server.hpp>
32#include <sdbusplus/bus/match.hpp>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070033#include <sdbusplus/message.hpp>
James Feist38fb5982020-05-28 10:09:54 -070034
Ed Tanouseacbfdd2024-04-04 12:00:24 -070035#include <algorithm>
James Feist38fb5982020-05-28 10:09:54 -070036#include <array>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070037#include <cctype>
Jakub Nowackia38e5612023-03-08 12:27:01 +010038#include <cerrno>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070039#include <chrono>
40#include <cstddef>
41#include <cstdint>
42#include <cstring>
James Feist24f02f22019-04-15 11:05:39 -070043#include <filesystem>
James Feist6714a252018-09-10 15:26:18 -070044#include <fstream>
Patrick Venture96e97db2019-10-31 13:44:38 -070045#include <functional>
Ed Tanouseacbfdd2024-04-04 12:00:24 -070046#include <ios>
47#include <iostream>
48#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
Ed Tanous8a57ec02020-10-09 12:46:52 -070066static constexpr bool debug = false;
James Feist6714a252018-09-10 15:26:18 -070067
Thu Nguyen255da6b2022-07-29 10:05:52 +070068boost::container::flat_map<std::string, std::shared_ptr<IntelCPUSensor>>
69 gCpuSensors;
James Feistc140e202019-11-14 15:23:51 -080070boost::container::flat_map<std::string,
71 std::shared_ptr<sdbusplus::asio::dbus_interface>>
72 inventoryIfaces;
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -080073
James Feist6714a252018-09-10 15:26:18 -070074enum State
75{
76 OFF, // host powered down
77 ON, // host powered on
78 READY // host powered on and mem test passed - fully ready
79};
80
81struct CPUConfig
82{
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070083 CPUConfig(const uint64_t& bus, const uint64_t& addr,
84 const std::string& name, const State& state) :
85 bus(bus),
86 addr(addr), name(name), state(state)
James Feist38fb5982020-05-28 10:09:54 -070087 {}
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070088 int bus;
James Feist6714a252018-09-10 15:26:18 -070089 int addr;
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070090 std::string name;
James Feist6714a252018-09-10 15:26:18 -070091 State state;
92
93 bool operator<(const CPUConfig& rhs) const
94 {
Andrew Jeffery92b96292021-05-27 16:41:31 +093095 // NOLINTNEXTLINE
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -070096 return (name < rhs.name);
James Feist6714a252018-09-10 15:26:18 -070097 }
98};
99
Jae Hyun Yoo9c55e6a2018-10-26 10:09:01 -0700100static constexpr const char* peciDev = "/dev/peci-";
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800101static constexpr const char* peciDevPath = "/sys/bus/peci/devices/";
Paul Fertser6e699732023-03-29 12:58:30 +0000102static constexpr const char* rescanPath = "/sys/bus/peci/rescan";
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700103static constexpr const unsigned int rankNumMax = 8;
James Feist6714a252018-09-10 15:26:18 -0700104
James Feistcf3bce62019-01-08 10:07:19 -0800105namespace fs = std::filesystem;
James Feist3eb82622019-02-08 13:10:22 -0800106
Zev Weiss054aad82022-08-18 01:37:34 -0700107static constexpr auto sensorTypes{std::to_array<const char*>({"XeonCPU"})};
Brandon Kim66558232021-11-09 16:53:08 -0800108static constexpr auto hiddenProps{std::to_array<const char*>(
Thu Nguyen255da6b2022-07-29 10:05:52 +0700109 {IntelCPUSensor::labelTcontrol, "Tthrottle", "Tjmax"})};
James Feist6714a252018-09-10 15:26:18 -0700110
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700111void detectCpuAsync(
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700112 boost::asio::steady_timer& pingTimer,
Ed Tanous1f978632023-02-28 18:16:39 -0800113 boost::asio::steady_timer& creationTimer, boost::asio::io_context& io,
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700114 sdbusplus::asio::object_server& objectServer,
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800115 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800116 boost::container::flat_set<CPUConfig>& cpuConfigs,
117 ManagedObjectType& sensorConfigs);
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700118
Zbigniew Kurzynski0eee0c12020-06-18 14:20:08 +0200119std::string createSensorName(const std::string& label, const std::string& item,
120 const int& cpuId)
121{
122 std::string sensorName = label;
Ed Tanous2049bd22022-07-09 07:20:26 -0700123 if (item != "input")
Zbigniew Kurzynski0eee0c12020-06-18 14:20:08 +0200124 {
125 sensorName += " " + item;
126 }
PavanKumarIntel40baf772024-07-03 14:32:57 +0000127
128 std::string cpuStr = "CPU" + std::to_string(cpuId);
129 constexpr const char* subLabel = "DIMM";
130 std::size_t found = label.find(subLabel);
131 if (found != std::string::npos)
132 {
133 sensorName = cpuStr + " " + sensorName;
134 }
135 else
136 {
137 sensorName += " " + cpuStr;
138 }
Zbigniew Kurzynski0eee0c12020-06-18 14:20:08 +0200139 // converting to Upper Camel case whole name
140 bool isWordEnd = true;
141 std::transform(sensorName.begin(), sensorName.end(), sensorName.begin(),
142 [&isWordEnd](int c) {
Ed Tanous2049bd22022-07-09 07:20:26 -0700143 if (std::isspace(c) != 0)
Ed Tanousbb679322022-05-16 16:10:00 -0700144 {
145 isWordEnd = true;
146 }
147 else
148 {
149 if (isWordEnd)
150 {
151 isWordEnd = false;
152 return std::toupper(c);
153 }
154 }
155 return c;
156 });
Zbigniew Kurzynski0eee0c12020-06-18 14:20:08 +0200157 return sensorName;
158}
159
Ed Tanous1f978632023-02-28 18:16:39 -0800160bool createSensors(boost::asio::io_context& io,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800161 sdbusplus::asio::object_server& objectServer,
162 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
163 boost::container::flat_set<CPUConfig>& cpuConfigs,
164 ManagedObjectType& sensorConfigs)
James Feist6714a252018-09-10 15:26:18 -0700165{
166 bool available = false;
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800167 for (const CPUConfig& cpu : cpuConfigs)
James Feist6714a252018-09-10 15:26:18 -0700168 {
169 if (cpu.state != State::OFF)
170 {
171 available = true;
Zev Weiss9702c9d2021-04-21 22:41:51 -0500172 std::shared_ptr<sdbusplus::asio::dbus_interface>& iface =
James Feistc140e202019-11-14 15:23:51 -0800173 inventoryIfaces[cpu.name];
174 if (iface != nullptr)
175 {
176 continue;
177 }
178 iface = objectServer.add_interface(
179 cpuInventoryPath + std::string("/") + cpu.name,
180 "xyz.openbmc_project.Inventory.Item");
181 iface->register_property("PrettyName", cpu.name);
182 iface->register_property("Present", true);
183 iface->initialize();
James Feist6714a252018-09-10 15:26:18 -0700184 }
185 }
186 if (!available)
187 {
Yoo, Jae Hyunf78d0a42018-10-10 11:03:11 -0700188 return false;
James Feist6714a252018-09-10 15:26:18 -0700189 }
190
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800191 if (sensorConfigs.empty())
James Feist6714a252018-09-10 15:26:18 -0700192 {
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800193 return false;
James Feist6714a252018-09-10 15:26:18 -0700194 }
195
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700196 std::vector<fs::path> hwmonNamePaths;
Paul Fertser6e699732023-03-29 12:58:30 +0000197 findFiles(fs::path(peciDevPath),
198 R"(peci-\d+/\d+-.+/peci[-_].+/hwmon/hwmon\d+/name$)",
199 hwmonNamePaths, 6);
200 if (hwmonNamePaths.empty())
James Feist6714a252018-09-10 15:26:18 -0700201 {
202 std::cerr << "No CPU sensors in system\n";
Paul Fertser75f92582023-03-29 12:48:07 +0000203 return false;
James Feist6714a252018-09-10 15:26:18 -0700204 }
205
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700206 boost::container::flat_set<std::string> scannedDirectories;
207 boost::container::flat_set<std::string> createdSensors;
208
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800209 for (const fs::path& hwmonNamePath : hwmonNamePaths)
James Feist6714a252018-09-10 15:26:18 -0700210 {
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700211 auto hwmonDirectory = hwmonNamePath.parent_path();
212
213 auto ret = scannedDirectories.insert(hwmonDirectory.string());
214 if (!ret.second)
James Feist6714a252018-09-10 15:26:18 -0700215 {
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700216 continue; // already searched this path
217 }
218
219 fs::path::iterator it = hwmonNamePath.begin();
220 std::advance(it, 6); // pick the 6th part for a PECI client device name
221 std::string deviceName = *it;
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700222
223 size_t bus = 0;
224 size_t addr = 0;
Akshit Shah03d333e2023-08-23 22:14:28 +0000225 if (!getDeviceBusAddr(deviceName, bus, addr))
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700226 {
227 continue;
228 }
229
230 std::ifstream nameFile(hwmonNamePath);
231 if (!nameFile.good())
232 {
233 std::cerr << "Failure reading " << hwmonNamePath << "\n";
234 continue;
235 }
236 std::string hwmonName;
237 std::getline(nameFile, hwmonName);
James Feist6714a252018-09-10 15:26:18 -0700238 nameFile.close();
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800239 if (hwmonName.empty())
James Feist6714a252018-09-10 15:26:18 -0700240 {
241 // shouldn't have an empty name file
242 continue;
243 }
Ed Tanous8a57ec02020-10-09 12:46:52 -0700244 if (debug)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700245 {
246 std::cout << "Checking: " << hwmonNamePath << ": " << hwmonName
247 << "\n";
248 }
James Feist6714a252018-09-10 15:26:18 -0700249
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700250 std::string sensorType;
James Feist6714a252018-09-10 15:26:18 -0700251 const SensorData* sensorData = nullptr;
252 const std::string* interfacePath = nullptr;
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700253 const SensorBaseConfiguration* baseConfiguration = nullptr;
James Feist6714a252018-09-10 15:26:18 -0700254
Zev Weiss8908b3c2022-08-12 18:21:01 -0700255 for (const auto& [path, cfgData] : sensorConfigs)
James Feist6714a252018-09-10 15:26:18 -0700256 {
Zev Weiss8908b3c2022-08-12 18:21:01 -0700257 sensorData = &cfgData;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700258 for (const char* type : sensorTypes)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700259 {
Zev Weiss26fb1492022-08-17 15:33:46 -0700260 sensorType = type;
Zev Weiss054aad82022-08-18 01:37:34 -0700261 auto sensorBase =
262 sensorData->find(configInterfaceName(sensorType));
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700263 if (sensorBase != sensorData->end())
264 {
265 baseConfiguration = &(*sensorBase);
266 break;
267 }
268 }
269 if (baseConfiguration == nullptr)
270 {
271 std::cerr << "error finding base configuration for" << hwmonName
272 << "\n";
273 continue;
274 }
275 auto configurationBus = baseConfiguration->second.find("Bus");
276 auto configurationAddress =
277 baseConfiguration->second.find("Address");
278
279 if (configurationBus == baseConfiguration->second.end() ||
280 configurationAddress == baseConfiguration->second.end())
281 {
282 std::cerr << "error finding bus or address in configuration";
283 continue;
284 }
285
James Feist3eb82622019-02-08 13:10:22 -0800286 if (std::get<uint64_t>(configurationBus->second) != bus ||
287 std::get<uint64_t>(configurationAddress->second) != addr)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700288 {
289 continue;
290 }
291
Zev Weiss8908b3c2022-08-12 18:21:01 -0700292 interfacePath = &path.str;
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700293 break;
294 }
295 if (interfacePath == nullptr)
296 {
297 std::cerr << "failed to find match for " << hwmonName << "\n";
James Feist6714a252018-09-10 15:26:18 -0700298 continue;
299 }
300
301 auto findCpuId = baseConfiguration->second.find("CpuID");
302 if (findCpuId == baseConfiguration->second.end())
303 {
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700304 std::cerr << "could not determine CPU ID for " << hwmonName << "\n";
James Feist6714a252018-09-10 15:26:18 -0700305 continue;
306 }
Patrick Williams779c96a2023-05-10 07:50:42 -0500307 int cpuId = std::visit(VariantToUnsignedIntVisitor(),
308 findCpuId->second);
James Feist6714a252018-09-10 15:26:18 -0700309
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700310 auto directory = hwmonNamePath.parent_path();
James Feist6714a252018-09-10 15:26:18 -0700311 std::vector<fs::path> inputPaths;
Zbigniew Kurzynski8d8d8d72020-05-29 19:21:24 +0200312 if (!findFiles(directory, R"((temp|power)\d+_(input|average|cap)$)",
Zbigniew Kurzynski0a4c4802020-04-01 11:22:27 +0200313 inputPaths, 0))
James Feist6714a252018-09-10 15:26:18 -0700314 {
315 std::cerr << "No temperature sensors in system\n";
316 continue;
317 }
318
319 // iterate through all found temp sensors
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800320 for (const auto& inputPath : inputPaths)
James Feist6714a252018-09-10 15:26:18 -0700321 {
Zbigniew Kurzynski63f38662020-06-09 13:02:11 +0200322 auto fileParts = splitFileName(inputPath);
Zbigniew Kurzynski0a4c4802020-04-01 11:22:27 +0200323 if (!fileParts)
324 {
325 continue;
326 }
Zbigniew Kurzynskidbfd4662020-09-28 18:06:00 +0200327 auto& [type, nr, item] = *fileParts;
James Feist6714a252018-09-10 15:26:18 -0700328 auto inputPathStr = inputPath.string();
Patrick Williams779c96a2023-05-10 07:50:42 -0500329 auto labelPath = boost::replace_all_copy(inputPathStr, item,
330 "label");
James Feist6714a252018-09-10 15:26:18 -0700331 std::ifstream labelFile(labelPath);
332 if (!labelFile.good())
333 {
334 std::cerr << "Failure reading " << labelPath << "\n";
335 continue;
336 }
337 std::string label;
338 std::getline(labelFile, label);
339 labelFile.close();
Jae Hyun Yoo13f48882019-02-19 13:37:07 -0800340
Zbigniew Kurzynski0eee0c12020-06-18 14:20:08 +0200341 std::string sensorName = createSensorName(label, item, cpuId);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700342
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800343 auto findSensor = gCpuSensors.find(sensorName);
344 if (findSensor != gCpuSensors.end())
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700345 {
Ed Tanous8a57ec02020-10-09 12:46:52 -0700346 if (debug)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700347 {
348 std::cout << "Skipped: " << inputPath << ": " << sensorName
349 << " is already created\n";
350 }
351 continue;
352 }
353
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800354 // check hidden properties
355 bool show = true;
356 for (const char* prop : hiddenProps)
357 {
358 if (label == prop)
359 {
360 show = false;
361 break;
362 }
363 }
364
Vijay Khemka86dea2b2019-06-06 11:14:37 -0700365 /*
366 * Find if there is DtsCritOffset is configured in config file
367 * set it if configured or else set it to 0
368 */
369 double dtsOffset = 0;
370 if (label == "DTS")
371 {
372 auto findThrOffset =
373 baseConfiguration->second.find("DtsCritOffset");
374 if (findThrOffset != baseConfiguration->second.end())
375 {
376 dtsOffset = std::visit(VariantToDoubleVisitor(),
377 findThrOffset->second);
378 }
379 }
380
James Feist6714a252018-09-10 15:26:18 -0700381 std::vector<thresholds::Threshold> sensorThresholds;
Ed Tanous8a57ec02020-10-09 12:46:52 -0700382 std::string labelHead = label.substr(0, label.find(' '));
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700383 parseThresholdsFromConfig(*sensorData, sensorThresholds,
Yoo, Jae Hyun81a464c2018-10-09 16:38:58 -0700384 &labelHead);
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800385 if (sensorThresholds.empty())
James Feist6714a252018-09-10 15:26:18 -0700386 {
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700387 if (!parseThresholdsFromAttr(sensorThresholds, inputPathStr,
Thu Nguyen255da6b2022-07-29 10:05:52 +0700388 IntelCPUSensor::sensorScaleFactor,
Chris Sidesa3279232023-04-24 16:08:13 -0500389 dtsOffset, 0))
James Feist6714a252018-09-10 15:26:18 -0700390 {
Yoo, Jae Hyun81a464c2018-10-09 16:38:58 -0700391 std::cerr << "error populating thresholds for "
392 << sensorName << "\n";
James Feist6714a252018-09-10 15:26:18 -0700393 }
394 }
James Feistc140e202019-11-14 15:23:51 -0800395 auto& sensorPtr = gCpuSensors[sensorName];
396 // make sure destructor fires before creating a new one
397 sensorPtr = nullptr;
Thu Nguyen255da6b2022-07-29 10:05:52 +0700398 sensorPtr = std::make_shared<IntelCPUSensor>(
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700399 inputPathStr, sensorType, objectServer, dbusConnection, io,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800400 sensorName, std::move(sensorThresholds), *interfacePath, cpuId,
Vijay Khemka86dea2b2019-06-06 11:14:37 -0700401 show, dtsOffset);
Arun P. Mohanan04d05062021-10-29 20:30:26 +0530402 sensorPtr->setupRead();
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700403 createdSensors.insert(sensorName);
Ed Tanous8a57ec02020-10-09 12:46:52 -0700404 if (debug)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700405 {
James Feist6714a252018-09-10 15:26:18 -0700406 std::cout << "Mapped: " << inputPath << " to " << sensorName
407 << "\n";
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700408 }
James Feist6714a252018-09-10 15:26:18 -0700409 }
410 }
Yoo, Jae Hyunf78d0a42018-10-10 11:03:11 -0700411
Ed Tanous2049bd22022-07-09 07:20:26 -0700412 if (static_cast<unsigned int>(!createdSensors.empty()) != 0U)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700413 {
414 std::cout << "Sensor" << (createdSensors.size() == 1 ? " is" : "s are")
415 << " created\n";
416 }
Yoo, Jae Hyuna441f3c2018-10-09 16:43:03 -0700417
Yoo, Jae Hyunf78d0a42018-10-10 11:03:11 -0700418 return true;
James Feist6714a252018-09-10 15:26:18 -0700419}
420
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800421bool exportDevice(const CPUConfig& config)
James Feist6714a252018-09-10 15:26:18 -0700422{
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700423 std::ostringstream hex;
424 hex << std::hex << config.addr;
425 const std::string& addrHexStr = hex.str();
426 std::string busStr = std::to_string(config.bus);
427
428 std::string parameters = "peci-client 0x" + addrHexStr;
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800429 std::string devPath = peciDevPath;
430 std::string delDevice = devPath + "peci-" + busStr + "/delete_device";
431 std::string newDevice = devPath + "peci-" + busStr + "/new_device";
432 std::string newClient = devPath + busStr + "-" + addrHexStr + "/driver";
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700433
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800434 std::filesystem::path devicePath(newDevice);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700435 const std::string& dir = devicePath.parent_path().string();
James Feistcf3bce62019-01-08 10:07:19 -0800436 for (const auto& path : std::filesystem::directory_iterator(dir))
James Feist6714a252018-09-10 15:26:18 -0700437 {
James Feistcf3bce62019-01-08 10:07:19 -0800438 if (!std::filesystem::is_directory(path))
James Feist6714a252018-09-10 15:26:18 -0700439 {
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700440 continue;
James Feist6714a252018-09-10 15:26:18 -0700441 }
442
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700443 const std::string& directoryName = path.path().filename();
Zev Weiss6c106d62022-08-17 20:50:00 -0700444 if (directoryName.starts_with(busStr) &&
445 directoryName.ends_with(addrHexStr))
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700446 {
Ed Tanous8a57ec02020-10-09 12:46:52 -0700447 if (debug)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700448 {
449 std::cout << parameters << " on bus " << busStr
450 << " is already exported\n";
451 }
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800452
453 std::ofstream delDeviceFile(delDevice);
454 if (!delDeviceFile.good())
455 {
456 std::cerr << "Error opening " << delDevice << "\n";
457 return false;
458 }
459 delDeviceFile << parameters;
460 delDeviceFile.close();
461
462 break;
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700463 }
James Feist6714a252018-09-10 15:26:18 -0700464 }
465
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800466 std::ofstream deviceFile(newDevice);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700467 if (!deviceFile.good())
James Feist6714a252018-09-10 15:26:18 -0700468 {
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800469 std::cerr << "Error opening " << newDevice << "\n";
470 return false;
James Feist6714a252018-09-10 15:26:18 -0700471 }
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700472 deviceFile << parameters;
473 deviceFile.close();
474
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800475 if (!std::filesystem::exists(newClient))
476 {
477 std::cerr << "Error creating " << newClient << "\n";
478 return false;
479 }
480
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700481 std::cout << parameters << " on bus " << busStr << " is exported\n";
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800482
483 return true;
James Feist6714a252018-09-10 15:26:18 -0700484}
485
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700486void detectCpu(boost::asio::steady_timer& pingTimer,
487 boost::asio::steady_timer& creationTimer,
Ed Tanous1f978632023-02-28 18:16:39 -0800488 boost::asio::io_context& io,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800489 sdbusplus::asio::object_server& objectServer,
490 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
491 boost::container::flat_set<CPUConfig>& cpuConfigs,
492 ManagedObjectType& sensorConfigs)
James Feist6714a252018-09-10 15:26:18 -0700493{
James Feist6714a252018-09-10 15:26:18 -0700494 size_t rescanDelaySeconds = 0;
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700495 static bool keepPinging = false;
Oleksandr Shulzhenko28c56bf2023-05-11 15:42:53 +0200496 int peciFd = -1;
Jae Hyun Yoo9c55e6a2018-10-26 10:09:01 -0700497
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800498 for (CPUConfig& config : cpuConfigs)
James Feist6714a252018-09-10 15:26:18 -0700499 {
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800500 if (config.state == State::READY)
501 {
502 continue;
503 }
504
Paul Fertser6e699732023-03-29 12:58:30 +0000505 std::fstream rescan{rescanPath, std::ios::out};
506 if (rescan.is_open())
507 {
508 std::vector<fs::path> peciPaths;
509 std::ostringstream searchPath;
510 searchPath << std::hex << "peci-" << config.bus << "/" << config.bus
511 << "-" << config.addr;
512 findFiles(fs::path(peciDevPath + searchPath.str()),
513 R"(peci_cpu.dimmtemp.+/hwmon/hwmon\d+/name$)", peciPaths,
514 3);
515 if (!peciPaths.empty())
516 {
517 config.state = State::READY;
518 rescanDelaySeconds = 1;
519 }
520 else
521 {
522 findFiles(fs::path(peciDevPath + searchPath.str()),
523 R"(peci_cpu.cputemp.+/hwmon/hwmon\d+/name$)",
524 peciPaths, 3);
525 if (!peciPaths.empty())
526 {
527 config.state = State::ON;
528 rescanDelaySeconds = 3;
529 }
530 else
531 {
532 // https://www.kernel.org/doc/html/latest/admin-guide/abi-testing.html#abi-sys-bus-peci-rescan
533 rescan << "1";
534 }
535 }
536 if (config.state != State::READY)
537 {
538 keepPinging = true;
539 }
540
541 continue;
542 }
543
Jae Hyun Yoo9c55e6a2018-10-26 10:09:01 -0700544 std::string peciDevPath = peciDev + std::to_string(config.bus);
Ed Tanous99c44092022-01-14 09:59:09 -0800545
Oleksandr Shulzhenko28c56bf2023-05-11 15:42:53 +0200546 peci_SetDevName(peciDevPath.data());
547
Ed Tanous99c44092022-01-14 09:59:09 -0800548 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
Oleksandr Shulzhenko28c56bf2023-05-11 15:42:53 +0200549 if ((peci_Lock(&peciFd, PECI_NO_WAIT) != PECI_CC_SUCCESS) ||
550 (peciFd < 0))
Jae Hyun Yoo9c55e6a2018-10-26 10:09:01 -0700551 {
Jakub Nowackia38e5612023-03-08 12:27:01 +0100552 std::cerr << "unable to open " << peciDevPath << " "
553 << std::strerror(errno) << "\n";
554 detectCpuAsync(pingTimer, creationTimer, io, objectServer,
555 dbusConnection, cpuConfigs, sensorConfigs);
556 return;
Jae Hyun Yoo9c55e6a2018-10-26 10:09:01 -0700557 }
558
Ed Tanousa771f6a2022-01-14 09:36:51 -0800559 State newState = State::OFF;
Ed Tanous99c44092022-01-14 09:59:09 -0800560
561 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
Oleksandr Shulzhenko77141ac2023-03-14 14:52:36 +0100562 if (peci_Ping(config.addr) == PECI_CC_SUCCESS)
James Feist6714a252018-09-10 15:26:18 -0700563 {
564 bool dimmReady = false;
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700565 for (unsigned int rank = 0; rank < rankNumMax; rank++)
James Feist6714a252018-09-10 15:26:18 -0700566 {
Oleksandr Shulzhenko77141ac2023-03-14 14:52:36 +0100567 std::array<uint8_t, 8> pkgConfig{};
568 uint8_t cc = 0;
Ed Tanous99c44092022-01-14 09:59:09 -0800569
570 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
Oleksandr Shulzhenko77141ac2023-03-14 14:52:36 +0100571 if (peci_RdPkgConfig(config.addr, PECI_MBX_INDEX_DDR_DIMM_TEMP,
Ed Tanousde366c82024-04-03 19:04:51 -0700572 rank, 4, pkgConfig.data(),
Oleksandr Shulzhenko77141ac2023-03-14 14:52:36 +0100573 &cc) == PECI_CC_SUCCESS)
James Feist6714a252018-09-10 15:26:18 -0700574 {
Matt Simmering38857572023-08-10 14:41:46 -0700575 // Depending on CPU generation, both 0 and 0xFF can be used
576 // to indicate no DIMM presence
577 if (((pkgConfig[0] != 0xFF) && (pkgConfig[0] != 0U)) ||
578 ((pkgConfig[1] != 0xFF) && (pkgConfig[1] != 0U)))
James Feist6714a252018-09-10 15:26:18 -0700579 {
580 dimmReady = true;
581 break;
582 }
583 }
584 else
585 {
586 break;
587 }
588 }
Yoo, Jae Hyuna441f3c2018-10-09 16:43:03 -0700589
James Feist6714a252018-09-10 15:26:18 -0700590 if (dimmReady)
591 {
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700592 newState = State::READY;
James Feist6714a252018-09-10 15:26:18 -0700593 }
594 else
595 {
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700596 newState = State::ON;
James Feist6714a252018-09-10 15:26:18 -0700597 }
598 }
James Feist6714a252018-09-10 15:26:18 -0700599
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700600 if (config.state != newState)
James Feist6714a252018-09-10 15:26:18 -0700601 {
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700602 if (newState != State::OFF)
James Feist6714a252018-09-10 15:26:18 -0700603 {
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700604 if (config.state == State::OFF)
605 {
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800606 std::array<uint8_t, 8> pkgConfig{};
607 uint8_t cc = 0;
608
609 if (peci_RdPkgConfig(config.addr, PECI_MBX_INDEX_CPU_ID, 0,
Ed Tanousde366c82024-04-03 19:04:51 -0700610 4, pkgConfig.data(),
Jae Hyun Yoo6d0f27b2021-01-27 15:52:16 -0800611 &cc) == PECI_CC_SUCCESS)
612 {
613 std::cout << config.name << " is detected\n";
614 if (!exportDevice(config))
615 {
616 newState = State::OFF;
617 }
618 }
619 else
620 {
621 newState = State::OFF;
622 }
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700623 }
James Feist6714a252018-09-10 15:26:18 -0700624
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700625 if (newState == State::ON)
626 {
627 rescanDelaySeconds = 3;
628 }
629 else if (newState == State::READY)
630 {
631 rescanDelaySeconds = 5;
632 std::cout << "DIMM(s) on " << config.name
633 << " is/are detected\n";
634 }
Yoo, Jae Hyunf78d0a42018-10-10 11:03:11 -0700635 }
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700636
637 config.state = newState;
Yoo, Jae Hyunf78d0a42018-10-10 11:03:11 -0700638 }
639
640 if (config.state != State::READY)
James Feist6714a252018-09-10 15:26:18 -0700641 {
642 keepPinging = true;
643 }
644
Ed Tanous8a57ec02020-10-09 12:46:52 -0700645 if (debug)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700646 {
647 std::cout << config.name << ", state: " << config.state << "\n";
648 }
Wang Xiaohua4cd5a902023-07-04 16:28:43 +0800649 peci_Unlock(peciFd);
James Feist6714a252018-09-10 15:26:18 -0700650 }
651
Ed Tanous2049bd22022-07-09 07:20:26 -0700652 if (rescanDelaySeconds != 0U)
James Feist6714a252018-09-10 15:26:18 -0700653 {
Ed Tanous83db50c2023-03-01 10:20:24 -0800654 creationTimer.expires_after(std::chrono::seconds(rescanDelaySeconds));
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700655 creationTimer.async_wait([&](const boost::system::error_code& ec) {
656 if (ec == boost::asio::error::operation_aborted)
657 {
658 return; // we're being canceled
659 }
660
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800661 if (!createSensors(io, objectServer, dbusConnection, cpuConfigs,
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700662 sensorConfigs) ||
663 keepPinging)
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700664 {
665 detectCpuAsync(pingTimer, creationTimer, io, objectServer,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800666 dbusConnection, cpuConfigs, sensorConfigs);
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700667 }
668 });
James Feist6714a252018-09-10 15:26:18 -0700669 }
Jae Hyun Yoo18ae22f2019-04-02 10:11:30 -0700670 else if (keepPinging)
James Feist6714a252018-09-10 15:26:18 -0700671 {
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800672 detectCpuAsync(pingTimer, creationTimer, io, objectServer,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800673 dbusConnection, cpuConfigs, sensorConfigs);
James Feist6714a252018-09-10 15:26:18 -0700674 }
675}
676
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700677void detectCpuAsync(
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700678 boost::asio::steady_timer& pingTimer,
Ed Tanous1f978632023-02-28 18:16:39 -0800679 boost::asio::steady_timer& creationTimer, boost::asio::io_context& io,
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700680 sdbusplus::asio::object_server& objectServer,
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800681 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800682 boost::container::flat_set<CPUConfig>& cpuConfigs,
683 ManagedObjectType& sensorConfigs)
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700684{
Ed Tanous83db50c2023-03-01 10:20:24 -0800685 pingTimer.expires_after(std::chrono::seconds(1));
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700686 pingTimer.async_wait([&](const boost::system::error_code& ec) {
687 if (ec == boost::asio::error::operation_aborted)
688 {
689 return; // we're being canceled
690 }
691
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800692 detectCpu(pingTimer, creationTimer, io, objectServer, dbusConnection,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800693 cpuConfigs, sensorConfigs);
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700694 });
695}
696
James Feistc140e202019-11-14 15:23:51 -0800697bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
698 boost::container::flat_set<CPUConfig>& cpuConfigs,
699 ManagedObjectType& sensorConfigs,
700 sdbusplus::asio::object_server& objectServer)
James Feist6714a252018-09-10 15:26:18 -0700701{
James Feist6714a252018-09-10 15:26:18 -0700702 bool useCache = false;
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800703 sensorConfigs.clear();
James Feist6714a252018-09-10 15:26:18 -0700704 // use new data the first time, then refresh
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700705 for (const char* type : sensorTypes)
James Feist6714a252018-09-10 15:26:18 -0700706 {
Zev Weiss26fb1492022-08-17 15:33:46 -0700707 if (!getSensorConfiguration(type, systemBus, sensorConfigs, useCache))
James Feist6714a252018-09-10 15:26:18 -0700708 {
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700709 return false;
James Feist6714a252018-09-10 15:26:18 -0700710 }
711 useCache = true;
712 }
713
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700714 // check PECI client addresses and names from CPU configuration
James Feist6714a252018-09-10 15:26:18 -0700715 // before starting ping operation
Jae Hyun Yoo9ced0a32018-10-25 10:42:39 -0700716 for (const char* type : sensorTypes)
James Feist6714a252018-09-10 15:26:18 -0700717 {
Zev Weiss8908b3c2022-08-12 18:21:01 -0700718 for (const auto& [path, cfgData] : sensorConfigs)
James Feist6714a252018-09-10 15:26:18 -0700719 {
Zev Weiss8908b3c2022-08-12 18:21:01 -0700720 for (const auto& [intf, cfg] : cfgData)
James Feist6714a252018-09-10 15:26:18 -0700721 {
Zev Weiss054aad82022-08-18 01:37:34 -0700722 if (intf != configInterfaceName(type))
James Feist6714a252018-09-10 15:26:18 -0700723 {
724 continue;
725 }
726
Zev Weiss8908b3c2022-08-12 18:21:01 -0700727 auto findName = cfg.find("Name");
728 if (findName == cfg.end())
James Feist6714a252018-09-10 15:26:18 -0700729 {
730 continue;
731 }
Patrick Williams779c96a2023-05-10 07:50:42 -0500732 std::string nameRaw = std::visit(VariantToStringVisitor(),
733 findName->second);
734 std::string name = std::regex_replace(nameRaw, illegalDbusRegex,
735 "_");
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700736
James Feistc140e202019-11-14 15:23:51 -0800737 auto present = std::optional<bool>();
738 // if we can't detect it via gpio, we set presence later
Zev Weiss8908b3c2022-08-12 18:21:01 -0700739 for (const auto& [suppIntf, suppCfg] : cfgData)
James Feist58295ad2019-05-30 15:01:41 -0700740 {
Zev Weiss8908b3c2022-08-12 18:21:01 -0700741 if (suppIntf.find("PresenceGpio") != std::string::npos)
James Feist58295ad2019-05-30 15:01:41 -0700742 {
Zev Weiss8908b3c2022-08-12 18:21:01 -0700743 present = cpuIsPresent(suppCfg);
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700744 break;
James Feist58295ad2019-05-30 15:01:41 -0700745 }
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700746 }
747
James Feistc140e202019-11-14 15:23:51 -0800748 if (inventoryIfaces.find(name) == inventoryIfaces.end() &&
749 present)
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700750 {
751 auto iface = objectServer.add_interface(
752 cpuInventoryPath + std::string("/") + name,
753 "xyz.openbmc_project.Inventory.Item");
754 iface->register_property("PrettyName", name);
James Feistc140e202019-11-14 15:23:51 -0800755 iface->register_property("Present", *present);
Jae Hyun Yooffa07e22019-07-17 10:47:18 -0700756 iface->initialize();
757 inventoryIfaces[name] = std::move(iface);
758 }
James Feist58295ad2019-05-30 15:01:41 -0700759
Zev Weiss8908b3c2022-08-12 18:21:01 -0700760 auto findBus = cfg.find("Bus");
761 if (findBus == cfg.end())
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700762 {
763 std::cerr << "Can't find 'Bus' setting in " << name << "\n";
764 continue;
765 }
Patrick Williams779c96a2023-05-10 07:50:42 -0500766 uint64_t bus = std::visit(VariantToUnsignedIntVisitor(),
767 findBus->second);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700768
Zev Weiss8908b3c2022-08-12 18:21:01 -0700769 auto findAddress = cfg.find("Address");
770 if (findAddress == cfg.end())
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700771 {
772 std::cerr << "Can't find 'Address' setting in " << name
773 << "\n";
774 continue;
775 }
James Feist3eb82622019-02-08 13:10:22 -0800776 uint64_t addr = std::visit(VariantToUnsignedIntVisitor(),
777 findAddress->second);
James Feist6714a252018-09-10 15:26:18 -0700778
Ed Tanous8a57ec02020-10-09 12:46:52 -0700779 if (debug)
James Feist6714a252018-09-10 15:26:18 -0700780 {
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700781 std::cout << "bus: " << bus << "\n";
James Feist6714a252018-09-10 15:26:18 -0700782 std::cout << "addr: " << addr << "\n";
783 std::cout << "name: " << name << "\n";
784 std::cout << "type: " << type << "\n";
James Feist6714a252018-09-10 15:26:18 -0700785 }
786
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800787 cpuConfigs.emplace(bus, addr, name, State::OFF);
James Feist6714a252018-09-10 15:26:18 -0700788 }
789 }
790 }
Yoo, Jae Hyuna441f3c2018-10-09 16:43:03 -0700791
Ed Tanous2049bd22022-07-09 07:20:26 -0700792 if (static_cast<unsigned int>(!cpuConfigs.empty()) != 0U)
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700793 {
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800794 std::cout << "CPU config" << (cpuConfigs.size() == 1 ? " is" : "s are")
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700795 << " parsed\n";
796 return true;
797 }
798
799 return false;
James Feist6714a252018-09-10 15:26:18 -0700800}
801
James Feistb6c0b912019-07-09 12:21:44 -0700802int main()
James Feist6714a252018-09-10 15:26:18 -0700803{
Ed Tanous1f978632023-02-28 18:16:39 -0800804 boost::asio::io_context io;
James Feist6714a252018-09-10 15:26:18 -0700805 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800806 boost::container::flat_set<CPUConfig> cpuConfigs;
James Feist6714a252018-09-10 15:26:18 -0700807
Ed Tanous14ed5e92022-07-12 15:50:23 -0700808 sdbusplus::asio::object_server objectServer(systemBus, true);
809 objectServer.add_manager("/xyz/openbmc_project/sensors");
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700810 boost::asio::steady_timer pingTimer(io);
811 boost::asio::steady_timer creationTimer(io);
812 boost::asio::steady_timer filterTimer(io);
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800813 ManagedObjectType sensorConfigs;
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700814
Ed Tanous83db50c2023-03-01 10:20:24 -0800815 filterTimer.expires_after(std::chrono::seconds(1));
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700816 filterTimer.async_wait([&](const boost::system::error_code& ec) {
817 if (ec == boost::asio::error::operation_aborted)
818 {
Jae Hyun Yood64262b2018-11-01 13:31:16 -0700819 return; // we're being canceled
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700820 }
821
James Feistc140e202019-11-14 15:23:51 -0800822 if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer))
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700823 {
Jae Hyun Yooe8b60d02019-01-14 15:27:13 -0800824 detectCpuAsync(pingTimer, creationTimer, io, objectServer,
Jae Hyun Yoo73ca5512019-02-28 21:20:17 -0800825 systemBus, cpuConfigs, sensorConfigs);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700826 }
827 });
828
Patrick Williams92f8f512022-07-22 19:26:55 -0500829 std::function<void(sdbusplus::message_t&)> eventHandler =
830 [&](sdbusplus::message_t& message) {
Ed Tanousbb679322022-05-16 16:10:00 -0700831 if (message.is_method_error())
832 {
833 std::cerr << "callback method error\n";
834 return;
835 }
836
837 if (debug)
838 {
839 std::cout << message.get_path() << " is changed\n";
840 }
841
842 // this implicitly cancels the timer
Ed Tanous83db50c2023-03-01 10:20:24 -0800843 filterTimer.expires_after(std::chrono::seconds(1));
Ed Tanousbb679322022-05-16 16:10:00 -0700844 filterTimer.async_wait([&](const boost::system::error_code& ec) {
845 if (ec == boost::asio::error::operation_aborted)
James Feist6714a252018-09-10 15:26:18 -0700846 {
Ed Tanousbb679322022-05-16 16:10:00 -0700847 return; // we're being canceled
James Feist6714a252018-09-10 15:26:18 -0700848 }
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700849
Ed Tanousbb679322022-05-16 16:10:00 -0700850 if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs,
851 objectServer))
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700852 {
Ed Tanousbb679322022-05-16 16:10:00 -0700853 detectCpuAsync(pingTimer, creationTimer, io, objectServer,
854 systemBus, cpuConfigs, sensorConfigs);
Jae Hyun Yoo8d9886d2018-10-22 15:24:29 -0700855 }
Ed Tanousbb679322022-05-16 16:10:00 -0700856 });
857 };
James Feist6714a252018-09-10 15:26:18 -0700858
Zev Weiss214d9712022-08-12 12:54:31 -0700859 std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
860 setupPropertiesChangedMatches(*systemBus, sensorTypes, eventHandler);
James Feist6714a252018-09-10 15:26:18 -0700861
Thu Nguyen255da6b2022-07-29 10:05:52 +0700862 systemBus->request_name("xyz.openbmc_project.IntelCPUSensor");
Bruce Lee1263c3d2021-06-04 15:16:33 +0800863
864 setupManufacturingModeMatch(*systemBus);
James Feist6714a252018-09-10 15:26:18 -0700865 io.run();
Zhikui Ren8685b172021-06-29 15:16:52 -0700866 return 0;
James Feist6714a252018-09-10 15:26:18 -0700867}