blob: 73b0997f88a60e1fa1854b96969f8c876c592d56 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3// SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
Gunnar Millsac6a4442020-10-14 14:55:29 -05004#pragma once
5
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08006#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07007#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +08008#include "dbus_utility.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07009#include "error_messages.hpp"
Chris Caindfbf7de2023-04-13 16:01:04 -050010#include "generated/enums/processor.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070011#include "generated/enums/resource.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080012#include "query.hpp"
13#include "registries/privilege_registry.hpp"
14#include "utils/collection.hpp"
15#include "utils/dbus_utils.hpp"
16#include "utils/json_utils.hpp"
Gunnar Millsac6a4442020-10-14 14:55:29 -050017
18#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080019#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070020#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070021#include <sdbusplus/asio/property.hpp>
Jonathan Domandba0c292020-12-02 15:34:13 -080022#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelny351053f2022-07-28 15:44:22 +020023#include <sdbusplus/unpack_properties.hpp>
Jonathan Domandba0c292020-12-02 15:34:13 -080024#include <sdbusplus/utility/dedup_variant.hpp>
Gunnar Millsac6a4442020-10-14 14:55:29 -050025
George Liu7a1dbc42022-12-07 16:03:22 +080026#include <array>
Michael Shenb9d679d2023-02-13 02:29:04 +000027#include <limits>
Ed Tanous3544d2a2023-08-06 18:12:20 -070028#include <ranges>
Ed Tanous3c569212024-03-06 14:46:18 -080029#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080030#include <string_view>
31
Gunnar Millsac6a4442020-10-14 14:55:29 -050032namespace redfish
33{
34
Jonathan Domanc9514482021-02-24 09:20:51 -080035// Interfaces which imply a D-Bus object represents a Processor
George Liu7a1dbc42022-12-07 16:03:22 +080036constexpr std::array<std::string_view, 2> processorInterfaces = {
Jonathan Domanc9514482021-02-24 09:20:51 -080037 "xyz.openbmc_project.Inventory.Item.Cpu",
38 "xyz.openbmc_project.Inventory.Item.Accelerator"};
Jonathan Doman2bab9832020-12-02 15:27:40 -080039
Sharad Yadav71b82f22021-05-10 15:11:39 +053040/**
41 * @brief Fill out uuid info of a processor by
42 * requesting data from the given D-Bus object.
43 *
Ed Tanousac106bf2023-06-07 09:24:59 -070044 * @param[in,out] asyncResp Async HTTP response.
Sharad Yadav71b82f22021-05-10 15:11:39 +053045 * @param[in] service D-Bus service to query.
46 * @param[in] objPath D-Bus object to query.
47 */
Ed Tanousac106bf2023-06-07 09:24:59 -070048inline void getProcessorUUID(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Sharad Yadav71b82f22021-05-10 15:11:39 +053049 const std::string& service,
50 const std::string& objPath)
51{
Ed Tanous62598e32023-07-17 17:06:25 -070052 BMCWEB_LOG_DEBUG("Get Processor UUID");
Ed Tanousdeae6a72024-11-11 21:58:57 -080053 dbus::utility::getProperty<std::string>(
54 service, objPath, "xyz.openbmc_project.Common.UUID", "UUID",
Ed Tanousac106bf2023-06-07 09:24:59 -070055 [objPath, asyncResp{std::move(asyncResp)}](
56 const boost::system::error_code& ec, const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040057 if (ec)
58 {
59 BMCWEB_LOG_DEBUG("DBUS response error");
60 messages::internalError(asyncResp->res);
61 return;
62 }
63 asyncResp->res.jsonValue["UUID"] = property;
64 });
Sharad Yadav71b82f22021-05-10 15:11:39 +053065}
66
Ed Tanous711ac7a2021-12-20 09:34:41 -080067inline void getCpuDataByInterface(
Ed Tanousac106bf2023-06-07 09:24:59 -070068 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Michael Shen80f79a42023-08-24 13:41:53 +000069 const dbus::utility::DBusInterfacesMap& cpuInterfacesProperties)
Gunnar Millsac6a4442020-10-14 14:55:29 -050070{
Ed Tanous62598e32023-07-17 17:06:25 -070071 BMCWEB_LOG_DEBUG("Get CPU resources by interface.");
Gunnar Millsac6a4442020-10-14 14:55:29 -050072
Chicago Duana1649ec2021-03-30 16:54:58 +080073 // Set the default value of state
Ed Tanous539d8c62024-06-19 14:38:27 -070074 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
75 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
Gunnar Millsac6a4442020-10-14 14:55:29 -050076
77 for (const auto& interface : cpuInterfacesProperties)
78 {
79 for (const auto& property : interface.second)
80 {
Chicago Duana1649ec2021-03-30 16:54:58 +080081 if (property.first == "Present")
Gunnar Millsac6a4442020-10-14 14:55:29 -050082 {
Chicago Duana1649ec2021-03-30 16:54:58 +080083 const bool* cpuPresent = std::get_if<bool>(&property.second);
84 if (cpuPresent == nullptr)
Gunnar Millsac6a4442020-10-14 14:55:29 -050085 {
86 // Important property not in desired type
Ed Tanousac106bf2023-06-07 09:24:59 -070087 messages::internalError(asyncResp->res);
Gunnar Millsac6a4442020-10-14 14:55:29 -050088 return;
89 }
Ed Tanouse05aec52022-01-25 10:28:56 -080090 if (!*cpuPresent)
Gunnar Millsac6a4442020-10-14 14:55:29 -050091 {
Chicago Duana1649ec2021-03-30 16:54:58 +080092 // Slot is not populated
Ed Tanous539d8c62024-06-19 14:38:27 -070093 asyncResp->res.jsonValue["Status"]["State"] =
94 resource::State::Absent;
Chicago Duana1649ec2021-03-30 16:54:58 +080095 }
96 }
97 else if (property.first == "Functional")
98 {
99 const bool* cpuFunctional = std::get_if<bool>(&property.second);
100 if (cpuFunctional == nullptr)
101 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700102 messages::internalError(asyncResp->res);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500103 return;
104 }
Ed Tanouse05aec52022-01-25 10:28:56 -0800105 if (!*cpuFunctional)
Chicago Duana1649ec2021-03-30 16:54:58 +0800106 {
Ed Tanous539d8c62024-06-19 14:38:27 -0700107 asyncResp->res.jsonValue["Status"]["Health"] =
108 resource::Health::Critical;
Chicago Duana1649ec2021-03-30 16:54:58 +0800109 }
110 }
111 else if (property.first == "CoreCount")
112 {
113 const uint16_t* coresCount =
114 std::get_if<uint16_t>(&property.second);
115 if (coresCount == nullptr)
116 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700117 messages::internalError(asyncResp->res);
Chicago Duana1649ec2021-03-30 16:54:58 +0800118 return;
119 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700120 asyncResp->res.jsonValue["TotalCores"] = *coresCount;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500121 }
Jonathan Domandc3fa662020-10-26 23:10:24 -0700122 else if (property.first == "MaxSpeedInMhz")
123 {
124 const uint32_t* value = std::get_if<uint32_t>(&property.second);
125 if (value != nullptr)
126 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700127 asyncResp->res.jsonValue["MaxSpeedMHz"] = *value;
Jonathan Domandc3fa662020-10-26 23:10:24 -0700128 }
129 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500130 else if (property.first == "Socket")
131 {
132 const std::string* value =
133 std::get_if<std::string>(&property.second);
134 if (value != nullptr)
135 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700136 asyncResp->res.jsonValue["Socket"] = *value;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500137 }
138 }
139 else if (property.first == "ThreadCount")
140 {
Jonathan Domandc3fa662020-10-26 23:10:24 -0700141 const uint16_t* value = std::get_if<uint16_t>(&property.second);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500142 if (value != nullptr)
143 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700144 asyncResp->res.jsonValue["TotalThreads"] = *value;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500145 }
146 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700147 else if (property.first == "EffectiveFamily")
Gunnar Millsac6a4442020-10-14 14:55:29 -0500148 {
Brandon Kim1930fbd2021-09-14 17:52:51 -0700149 const uint16_t* value = std::get_if<uint16_t>(&property.second);
Brad Bishop6169de22022-09-14 13:08:32 -0400150 if (value != nullptr && *value != 2)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500151 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700152 asyncResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] =
Ed Tanous866e4862022-02-17 11:40:25 -0800153 "0x" + intToHexString(*value, 4);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500154 }
155 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700156 else if (property.first == "EffectiveModel")
157 {
158 const uint16_t* value = std::get_if<uint16_t>(&property.second);
159 if (value == nullptr)
160 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700161 messages::internalError(asyncResp->res);
Brandon Kim1930fbd2021-09-14 17:52:51 -0700162 return;
163 }
Brad Bishop6169de22022-09-14 13:08:32 -0400164 if (*value != 0)
165 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700166 asyncResp->res.jsonValue["ProcessorId"]["EffectiveModel"] =
Brad Bishop6169de22022-09-14 13:08:32 -0400167 "0x" + intToHexString(*value, 4);
168 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700169 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500170 else if (property.first == "Id")
171 {
172 const uint64_t* value = std::get_if<uint64_t>(&property.second);
173 if (value != nullptr && *value != 0)
174 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700175 asyncResp->res
Gunnar Millsac6a4442020-10-14 14:55:29 -0500176 .jsonValue["ProcessorId"]["IdentificationRegisters"] =
Ed Tanous866e4862022-02-17 11:40:25 -0800177 "0x" + intToHexString(*value, 16);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500178 }
179 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700180 else if (property.first == "Microcode")
181 {
182 const uint32_t* value = std::get_if<uint32_t>(&property.second);
183 if (value == nullptr)
184 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700185 messages::internalError(asyncResp->res);
Brandon Kim1930fbd2021-09-14 17:52:51 -0700186 return;
187 }
Brad Bishop6169de22022-09-14 13:08:32 -0400188 if (*value != 0)
189 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700190 asyncResp->res.jsonValue["ProcessorId"]["MicrocodeInfo"] =
Brad Bishop6169de22022-09-14 13:08:32 -0400191 "0x" + intToHexString(*value, 8);
192 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700193 }
194 else if (property.first == "Step")
195 {
196 const uint16_t* value = std::get_if<uint16_t>(&property.second);
197 if (value == nullptr)
198 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700199 messages::internalError(asyncResp->res);
Brandon Kim1930fbd2021-09-14 17:52:51 -0700200 return;
201 }
Michael Shenb9d679d2023-02-13 02:29:04 +0000202 if (*value != std::numeric_limits<uint16_t>::max())
Brad Bishop6169de22022-09-14 13:08:32 -0400203 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700204 asyncResp->res.jsonValue["ProcessorId"]["Step"] =
Brad Bishop6169de22022-09-14 13:08:32 -0400205 "0x" + intToHexString(*value, 4);
206 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700207 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500208 }
209 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500210}
211
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400212inline void getCpuDataByService(
213 std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& cpuId,
214 const std::string& service, const std::string& objPath)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500215{
Ed Tanous62598e32023-07-17 17:06:25 -0700216 BMCWEB_LOG_DEBUG("Get available system cpu resources by service.");
Gunnar Millsac6a4442020-10-14 14:55:29 -0500217
George Liu5eb468d2023-06-20 17:03:24 +0800218 sdbusplus::message::object_path path("/xyz/openbmc_project/inventory");
219 dbus::utility::getManagedObjects(
220 service, path,
Ed Tanousac106bf2023-06-07 09:24:59 -0700221 [cpuId, service, objPath, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800222 const boost::system::error_code& ec,
Gunnar Millsac6a4442020-10-14 14:55:29 -0500223 const dbus::utility::ManagedObjectType& dbusData) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400224 if (ec)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500225 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400226 BMCWEB_LOG_DEBUG("DBUS response error");
227 messages::internalError(asyncResp->res);
228 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700229 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400230 asyncResp->res.jsonValue["Id"] = cpuId;
231 asyncResp->res.jsonValue["Name"] = "Processor";
232 asyncResp->res.jsonValue["ProcessorType"] =
233 processor::ProcessorType::CPU;
234
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400235 for (const auto& object : dbusData)
Ed Tanous002d39b2022-05-31 08:59:27 -0700236 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400237 if (object.first.str == objPath)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500238 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400239 getCpuDataByInterface(asyncResp, object.second);
240 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400241 }
242 return;
243 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500244}
245
Chris Caindfbf7de2023-04-13 16:01:04 -0500246/**
247 * @brief Translates throttle cause DBUS property to redfish.
248 *
249 * @param[in] dbusSource The throttle cause from DBUS
250 *
251 * @return Returns as a string, the throttle cause in Redfish terms. If
252 * translation cannot be done, returns "Unknown" throttle reason.
253 */
254inline processor::ThrottleCause
255 dbusToRfThrottleCause(const std::string& dbusSource)
256{
257 if (dbusSource ==
258 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ClockLimit")
259 {
260 return processor::ThrottleCause::ClockLimit;
261 }
262 if (dbusSource ==
263 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ManagementDetectedFault")
264 {
265 return processor::ThrottleCause::ManagementDetectedFault;
266 }
267 if (dbusSource ==
268 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.PowerLimit")
269 {
270 return processor::ThrottleCause::PowerLimit;
271 }
272 if (dbusSource ==
273 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ThermalLimit")
274 {
275 return processor::ThrottleCause::ThermalLimit;
276 }
277 if (dbusSource ==
278 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.Unknown")
279 {
280 return processor::ThrottleCause::Unknown;
281 }
282 return processor::ThrottleCause::Invalid;
283}
284
285inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700286 readThrottleProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Caindfbf7de2023-04-13 16:01:04 -0500287 const boost::system::error_code& ec,
288 const dbus::utility::DBusPropertiesMap& properties)
289{
290 if (ec)
291 {
Ed Tanous62598e32023-07-17 17:06:25 -0700292 BMCWEB_LOG_ERROR("Processor Throttle getAllProperties error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700293 messages::internalError(asyncResp->res);
Chris Caindfbf7de2023-04-13 16:01:04 -0500294 return;
295 }
296
297 const bool* status = nullptr;
298 const std::vector<std::string>* causes = nullptr;
299
300 if (!sdbusplus::unpackPropertiesNoThrow(dbus_utils::UnpackErrorPrinter(),
301 properties, "Throttled", status,
302 "ThrottleCauses", causes))
303 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700304 messages::internalError(asyncResp->res);
Chris Caindfbf7de2023-04-13 16:01:04 -0500305 return;
306 }
307
Ed Tanousac106bf2023-06-07 09:24:59 -0700308 asyncResp->res.jsonValue["Throttled"] = *status;
Chris Caindfbf7de2023-04-13 16:01:04 -0500309 nlohmann::json::array_t rCauses;
310 for (const std::string& cause : *causes)
311 {
312 processor::ThrottleCause rfCause = dbusToRfThrottleCause(cause);
313 if (rfCause == processor::ThrottleCause::Invalid)
314 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700315 messages::internalError(asyncResp->res);
Chris Caindfbf7de2023-04-13 16:01:04 -0500316 return;
317 }
318
319 rCauses.emplace_back(rfCause);
320 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700321 asyncResp->res.jsonValue["ThrottleCauses"] = std::move(rCauses);
Chris Caindfbf7de2023-04-13 16:01:04 -0500322}
323
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400324inline void getThrottleProperties(
325 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
326 const std::string& service, const std::string& objectPath)
Chris Caindfbf7de2023-04-13 16:01:04 -0500327{
Ed Tanous62598e32023-07-17 17:06:25 -0700328 BMCWEB_LOG_DEBUG("Get processor throttle resources");
Chris Caindfbf7de2023-04-13 16:01:04 -0500329
Ed Tanousdeae6a72024-11-11 21:58:57 -0800330 dbus::utility::getAllProperties(
331 service, objectPath, "xyz.openbmc_project.Control.Power.Throttle",
Ed Tanousac106bf2023-06-07 09:24:59 -0700332 [asyncResp](const boost::system::error_code& ec,
333 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400334 readThrottleProperties(asyncResp, ec, properties);
335 });
Chris Caindfbf7de2023-04-13 16:01:04 -0500336}
337
Ed Tanousac106bf2023-06-07 09:24:59 -0700338inline void getCpuAssetData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Millsac6a4442020-10-14 14:55:29 -0500339 const std::string& service,
340 const std::string& objPath)
341{
Ed Tanous62598e32023-07-17 17:06:25 -0700342 BMCWEB_LOG_DEBUG("Get Cpu Asset Data");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800343 dbus::utility::getAllProperties(
344 service, objPath, "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanousac106bf2023-06-07 09:24:59 -0700345 [objPath, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800346 const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200347 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400348 if (ec)
Ed Tanous002d39b2022-05-31 08:59:27 -0700349 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400350 BMCWEB_LOG_DEBUG("DBUS response error");
351 messages::internalError(asyncResp->res);
352 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700353 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400354
355 const std::string* serialNumber = nullptr;
356 const std::string* model = nullptr;
357 const std::string* manufacturer = nullptr;
358 const std::string* partNumber = nullptr;
359 const std::string* sparePartNumber = nullptr;
360
361 const bool success = sdbusplus::unpackPropertiesNoThrow(
362 dbus_utils::UnpackErrorPrinter(), properties, "SerialNumber",
363 serialNumber, "Model", model, "Manufacturer", manufacturer,
364 "PartNumber", partNumber, "SparePartNumber", sparePartNumber);
365
366 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700367 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400368 messages::internalError(asyncResp->res);
369 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700370 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200371
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400372 if (serialNumber != nullptr && !serialNumber->empty())
373 {
374 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
375 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200376
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400377 if ((model != nullptr) && !model->empty())
378 {
379 asyncResp->res.jsonValue["Model"] = *model;
380 }
381
382 if (manufacturer != nullptr)
383 {
384 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
385
386 // Otherwise would be unexpected.
387 if (manufacturer->find("Intel") != std::string::npos)
388 {
389 asyncResp->res.jsonValue["ProcessorArchitecture"] = "x86";
390 asyncResp->res.jsonValue["InstructionSet"] = "x86-64";
391 }
392 else if (manufacturer->find("IBM") != std::string::npos)
393 {
394 asyncResp->res.jsonValue["ProcessorArchitecture"] = "Power";
395 asyncResp->res.jsonValue["InstructionSet"] = "PowerISA";
396 }
397 }
398
399 if (partNumber != nullptr)
400 {
401 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
402 }
403
404 if (sparePartNumber != nullptr && !sparePartNumber->empty())
405 {
406 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
407 }
408 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500409}
410
Ed Tanousac106bf2023-06-07 09:24:59 -0700411inline void getCpuRevisionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Millsac6a4442020-10-14 14:55:29 -0500412 const std::string& service,
413 const std::string& objPath)
414{
Ed Tanous62598e32023-07-17 17:06:25 -0700415 BMCWEB_LOG_DEBUG("Get Cpu Revision Data");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800416 dbus::utility::getAllProperties(
417 service, objPath, "xyz.openbmc_project.Inventory.Decorator.Revision",
Ed Tanousac106bf2023-06-07 09:24:59 -0700418 [objPath, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800419 const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200420 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400421 if (ec)
422 {
423 BMCWEB_LOG_DEBUG("DBUS response error");
424 messages::internalError(asyncResp->res);
425 return;
426 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500427
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400428 const std::string* version = nullptr;
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200429
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400430 const bool success = sdbusplus::unpackPropertiesNoThrow(
431 dbus_utils::UnpackErrorPrinter(), properties, "Version",
432 version);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200433
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400434 if (!success)
435 {
436 messages::internalError(asyncResp->res);
437 return;
438 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200439
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400440 if (version != nullptr)
441 {
442 asyncResp->res.jsonValue["Version"] = *version;
443 }
444 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500445}
446
zhanghch058d1b46d2021-04-01 11:18:24 +0800447inline void getAcceleratorDataByService(
Ed Tanousac106bf2023-06-07 09:24:59 -0700448 std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& acclrtrId,
zhanghch058d1b46d2021-04-01 11:18:24 +0800449 const std::string& service, const std::string& objPath)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500450{
Ed Tanous62598e32023-07-17 17:06:25 -0700451 BMCWEB_LOG_DEBUG("Get available system Accelerator resources by service.");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800452 dbus::utility::getAllProperties(
453 service, objPath, "",
Ed Tanousac106bf2023-06-07 09:24:59 -0700454 [acclrtrId, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800455 const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200456 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400457 if (ec)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500458 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400459 BMCWEB_LOG_DEBUG("DBUS response error");
460 messages::internalError(asyncResp->res);
461 return;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500462 }
463
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400464 const bool* functional = nullptr;
465 const bool* present = nullptr;
466
467 const bool success = sdbusplus::unpackPropertiesNoThrow(
468 dbus_utils::UnpackErrorPrinter(), properties, "Functional",
469 functional, "Present", present);
470
471 if (!success)
472 {
473 messages::internalError(asyncResp->res);
474 return;
475 }
476
477 std::string state = "Enabled";
478 std::string health = "OK";
479
480 if (present != nullptr && !*present)
481 {
482 state = "Absent";
483 }
484
485 if (functional != nullptr && !*functional)
486 {
487 if (state == "Enabled")
488 {
489 health = "Critical";
490 }
491 }
492
493 asyncResp->res.jsonValue["Id"] = acclrtrId;
494 asyncResp->res.jsonValue["Name"] = "Processor";
495 asyncResp->res.jsonValue["Status"]["State"] = state;
496 asyncResp->res.jsonValue["Status"]["Health"] = health;
497 asyncResp->res.jsonValue["ProcessorType"] =
498 processor::ProcessorType::Accelerator;
499 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500500}
501
Jonathan Domandba0c292020-12-02 15:34:13 -0800502// OperatingConfig D-Bus Types
503using TurboProfileProperty = std::vector<std::tuple<uint32_t, size_t>>;
504using BaseSpeedPrioritySettingsProperty =
505 std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>;
506// uint32_t and size_t may or may not be the same type, requiring a dedup'd
507// variant
Jonathan Domandba0c292020-12-02 15:34:13 -0800508
509/**
510 * Fill out the HighSpeedCoreIDs in a Processor resource from the given
511 * OperatingConfig D-Bus property.
512 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700513 * @param[in,out] asyncResp Async HTTP response.
Jonathan Domandba0c292020-12-02 15:34:13 -0800514 * @param[in] baseSpeedSettings Full list of base speed priority groups,
515 * to use to determine the list of high
516 * speed cores.
517 */
518inline void highSpeedCoreIdsHandler(
Ed Tanousac106bf2023-06-07 09:24:59 -0700519 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Domandba0c292020-12-02 15:34:13 -0800520 const BaseSpeedPrioritySettingsProperty& baseSpeedSettings)
521{
522 // The D-Bus property does not indicate which bucket is the "high
523 // priority" group, so let's discern that by looking for the one with
524 // highest base frequency.
525 auto highPriorityGroup = baseSpeedSettings.cend();
526 uint32_t highestBaseSpeed = 0;
527 for (auto it = baseSpeedSettings.cbegin(); it != baseSpeedSettings.cend();
528 ++it)
529 {
530 const uint32_t baseFreq = std::get<uint32_t>(*it);
531 if (baseFreq > highestBaseSpeed)
532 {
533 highestBaseSpeed = baseFreq;
534 highPriorityGroup = it;
535 }
536 }
537
Ed Tanousac106bf2023-06-07 09:24:59 -0700538 nlohmann::json& jsonCoreIds = asyncResp->res.jsonValue["HighSpeedCoreIDs"];
Jonathan Domandba0c292020-12-02 15:34:13 -0800539 jsonCoreIds = nlohmann::json::array();
540
541 // There may not be any entries in the D-Bus property, so only populate
542 // if there was actually something there.
543 if (highPriorityGroup != baseSpeedSettings.cend())
544 {
545 jsonCoreIds = std::get<std::vector<uint32_t>>(*highPriorityGroup);
546 }
547}
548
549/**
550 * Fill out OperatingConfig related items in a Processor resource by requesting
551 * data from the given D-Bus object.
552 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700553 * @param[in,out] asyncResp Async HTTP response.
Jonathan Domandba0c292020-12-02 15:34:13 -0800554 * @param[in] cpuId CPU D-Bus name.
555 * @param[in] service D-Bus service to query.
556 * @param[in] objPath D-Bus object to query.
557 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700558inline void
559 getCpuConfigData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
560 const std::string& cpuId, const std::string& service,
561 const std::string& objPath)
Jonathan Domandba0c292020-12-02 15:34:13 -0800562{
Ed Tanous62598e32023-07-17 17:06:25 -0700563 BMCWEB_LOG_INFO("Getting CPU operating configs for {}", cpuId);
Jonathan Domandba0c292020-12-02 15:34:13 -0800564
565 // First, GetAll CurrentOperatingConfig properties on the object
Ed Tanousdeae6a72024-11-11 21:58:57 -0800566 dbus::utility::getAllProperties(
567 service, objPath,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200568 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig",
Ed Tanousac106bf2023-06-07 09:24:59 -0700569 [asyncResp, cpuId,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800570 service](const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200571 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400572 if (ec)
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200573 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400574 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
Ed Tanousac106bf2023-06-07 09:24:59 -0700575 messages::internalError(asyncResp->res);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200576 return;
577 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200578
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400579 nlohmann::json& json = asyncResp->res.jsonValue;
580
581 const sdbusplus::message::object_path* appliedConfig = nullptr;
582 const bool* baseSpeedPriorityEnabled = nullptr;
583
584 const bool success = sdbusplus::unpackPropertiesNoThrow(
585 dbus_utils::UnpackErrorPrinter(), properties, "AppliedConfig",
586 appliedConfig, "BaseSpeedPriorityEnabled",
587 baseSpeedPriorityEnabled);
588
589 if (!success)
590 {
591 messages::internalError(asyncResp->res);
592 return;
593 }
594
595 if (appliedConfig != nullptr)
596 {
597 const std::string& dbusPath = appliedConfig->str;
598 nlohmann::json::object_t operatingConfig;
599 operatingConfig["@odata.id"] = boost::urls::format(
600 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
601 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId);
602 json["OperatingConfigs"] = std::move(operatingConfig);
603
604 // Reuse the D-Bus config object name for the Redfish
605 // URI
606 size_t baseNamePos = dbusPath.rfind('/');
607 if (baseNamePos == std::string::npos ||
608 baseNamePos == (dbusPath.size() - 1))
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200609 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400610 // If the AppliedConfig was somehow not a valid path,
611 // skip adding any more properties, since everything
612 // else is tied to this applied config.
Ed Tanousac106bf2023-06-07 09:24:59 -0700613 messages::internalError(asyncResp->res);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200614 return;
615 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400616 nlohmann::json::object_t appliedOperatingConfig;
617 appliedOperatingConfig["@odata.id"] = boost::urls::format(
618 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}",
619 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId,
620 dbusPath.substr(baseNamePos + 1));
621 json["AppliedOperatingConfig"] =
622 std::move(appliedOperatingConfig);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200623
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400624 // Once we found the current applied config, queue another
625 // request to read the base freq core ids out of that
626 // config.
Ed Tanousdeae6a72024-11-11 21:58:57 -0800627 dbus::utility::getProperty<BaseSpeedPrioritySettingsProperty>(
628 service, dbusPath,
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400629 "xyz.openbmc_project.Inventory.Item.Cpu."
630 "OperatingConfig",
631 "BaseSpeedPrioritySettings",
632 [asyncResp](const boost::system::error_code& ec2,
633 const BaseSpeedPrioritySettingsProperty&
634 baseSpeedList) {
635 if (ec2)
636 {
637 BMCWEB_LOG_WARNING("D-Bus Property Get error: {}",
638 ec2);
639 messages::internalError(asyncResp->res);
640 return;
641 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200642
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400643 highSpeedCoreIdsHandler(asyncResp, baseSpeedList);
644 });
645 }
646
647 if (baseSpeedPriorityEnabled != nullptr)
648 {
649 json["BaseSpeedPriorityState"] =
650 *baseSpeedPriorityEnabled ? "Enabled" : "Disabled";
651 }
652 });
Jonathan Domandba0c292020-12-02 15:34:13 -0800653}
654
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600655/**
656 * @brief Fill out location info of a processor by
657 * requesting data from the given D-Bus object.
658 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700659 * @param[in,out] asyncResp Async HTTP response.
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600660 * @param[in] service D-Bus service to query.
661 * @param[in] objPath D-Bus object to query.
662 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700663inline void getCpuLocationCode(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600664 const std::string& service,
665 const std::string& objPath)
666{
Ed Tanous62598e32023-07-17 17:06:25 -0700667 BMCWEB_LOG_DEBUG("Get Cpu Location Data");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800668 dbus::utility::getProperty<std::string>(
669 service, objPath,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700670 "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
Ed Tanousac106bf2023-06-07 09:24:59 -0700671 [objPath, asyncResp{std::move(asyncResp)}](
672 const boost::system::error_code& ec, const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400673 if (ec)
674 {
675 BMCWEB_LOG_DEBUG("DBUS response error");
676 messages::internalError(asyncResp->res);
677 return;
678 }
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600679
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400680 asyncResp->res
681 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
682 property;
683 });
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600684}
685
Jonathan Domanc9514482021-02-24 09:20:51 -0800686/**
Jonathan Doman49e429c2021-03-03 13:11:44 -0800687 * Populate the unique identifier in a Processor resource by requesting data
688 * from the given D-Bus object.
689 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700690 * @param[in,out] asyncResp Async HTTP response.
Jonathan Doman49e429c2021-03-03 13:11:44 -0800691 * @param[in] service D-Bus service to query.
692 * @param[in] objPath D-Bus object to query.
693 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700694inline void getCpuUniqueId(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman49e429c2021-03-03 13:11:44 -0800695 const std::string& service,
696 const std::string& objectPath)
697{
Ed Tanous62598e32023-07-17 17:06:25 -0700698 BMCWEB_LOG_DEBUG("Get CPU UniqueIdentifier");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800699 dbus::utility::getProperty<std::string>(
700 service, objectPath,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700701 "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier",
702 "UniqueIdentifier",
Ed Tanousac106bf2023-06-07 09:24:59 -0700703 [asyncResp](const boost::system::error_code& ec,
704 const std::string& id) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400705 if (ec)
706 {
707 BMCWEB_LOG_ERROR("Failed to read cpu unique id: {}", ec);
708 messages::internalError(asyncResp->res);
709 return;
710 }
711 asyncResp->res
712 .jsonValue["ProcessorId"]["ProtectedIdentificationNumber"] = id;
713 });
Jonathan Doman49e429c2021-03-03 13:11:44 -0800714}
715
716/**
Jonathan Domanc9514482021-02-24 09:20:51 -0800717 * Find the D-Bus object representing the requested Processor, and call the
718 * handler with the results. If matching object is not found, add 404 error to
719 * response and don't call the handler.
720 *
721 * @param[in,out] resp Async HTTP response.
722 * @param[in] processorId Redfish Processor Id.
723 * @param[in] handler Callback to continue processing request upon
724 * successfully finding object.
725 */
726template <typename Handler>
zhanghch058d1b46d2021-04-01 11:18:24 +0800727inline void getProcessorObject(const std::shared_ptr<bmcweb::AsyncResp>& resp,
Jonathan Domanc9514482021-02-24 09:20:51 -0800728 const std::string& processorId,
729 Handler&& handler)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500730{
Ed Tanous62598e32023-07-17 17:06:25 -0700731 BMCWEB_LOG_DEBUG("Get available system processor resources.");
Gunnar Millsac6a4442020-10-14 14:55:29 -0500732
Jonathan Domanc9514482021-02-24 09:20:51 -0800733 // GetSubTree on all interfaces which provide info about a Processor
Chris Caindfbf7de2023-04-13 16:01:04 -0500734 constexpr std::array<std::string_view, 9> interfaces = {
George Liue99073f2022-12-09 11:06:16 +0800735 "xyz.openbmc_project.Common.UUID",
736 "xyz.openbmc_project.Inventory.Decorator.Asset",
737 "xyz.openbmc_project.Inventory.Decorator.Revision",
738 "xyz.openbmc_project.Inventory.Item.Cpu",
739 "xyz.openbmc_project.Inventory.Decorator.LocationCode",
740 "xyz.openbmc_project.Inventory.Item.Accelerator",
741 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig",
Chris Caindfbf7de2023-04-13 16:01:04 -0500742 "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier",
743 "xyz.openbmc_project.Control.Power.Throttle"};
George Liue99073f2022-12-09 11:06:16 +0800744 dbus::utility::getSubTree(
745 "/xyz/openbmc_project/inventory", 0, interfaces,
Jonathan Domanc9514482021-02-24 09:20:51 -0800746 [resp, processorId, handler = std::forward<Handler>(handler)](
George Liue99073f2022-12-09 11:06:16 +0800747 const boost::system::error_code& ec,
748 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400749 if (ec)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500750 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400751 BMCWEB_LOG_DEBUG("DBUS response error: {}", ec);
752 messages::internalError(resp->res);
753 return;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500754 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400755 for (const auto& [objectPath, serviceMap] : subtree)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500756 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400757 // Ignore any objects which don't end with our desired cpu name
758 if (!objectPath.ends_with(processorId))
Gunnar Millsac6a4442020-10-14 14:55:29 -0500759 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400760 continue;
Jonathan Doman2bab9832020-12-02 15:27:40 -0800761 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400762
763 bool found = false;
764 // Filter out objects that don't have the CPU-specific
765 // interfaces to make sure we can return 404 on non-CPUs
766 // (e.g. /redfish/../Processors/dimm0)
767 for (const auto& [serviceName, interfaceList] : serviceMap)
768 {
769 if (std::ranges::find_first_of(interfaceList,
770 processorInterfaces) !=
771 std::end(interfaceList))
772 {
773 found = true;
774 break;
775 }
776 }
777
778 if (!found)
779 {
780 continue;
781 }
782
783 // Process the first object which does match our cpu name and
784 // required interfaces, and potentially ignore any other
785 // matching objects. Assume all interfaces we want to process
786 // must be on the same object path.
787
788 handler(objectPath, serviceMap);
789 return;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500790 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400791 messages::resourceNotFound(resp->res, "Processor", processorId);
792 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500793}
794
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400795inline void getProcessorData(
796 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
797 const std::string& processorId, const std::string& objectPath,
798 const dbus::utility::MapperServiceMap& serviceMap)
Jonathan Domanc9514482021-02-24 09:20:51 -0800799{
800 for (const auto& [serviceName, interfaceList] : serviceMap)
801 {
802 for (const auto& interface : interfaceList)
803 {
804 if (interface == "xyz.openbmc_project.Inventory.Decorator.Asset")
805 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700806 getCpuAssetData(asyncResp, serviceName, objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800807 }
George Liu0fda0f12021-11-16 10:06:17 +0800808 else if (interface ==
809 "xyz.openbmc_project.Inventory.Decorator.Revision")
Jonathan Domanc9514482021-02-24 09:20:51 -0800810 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700811 getCpuRevisionData(asyncResp, serviceName, objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800812 }
813 else if (interface == "xyz.openbmc_project.Inventory.Item.Cpu")
814 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700815 getCpuDataByService(asyncResp, processorId, serviceName,
Jonathan Domanc9514482021-02-24 09:20:51 -0800816 objectPath);
817 }
George Liu0fda0f12021-11-16 10:06:17 +0800818 else if (interface ==
819 "xyz.openbmc_project.Inventory.Item.Accelerator")
Jonathan Domanc9514482021-02-24 09:20:51 -0800820 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700821 getAcceleratorDataByService(asyncResp, processorId, serviceName,
Jonathan Domanc9514482021-02-24 09:20:51 -0800822 objectPath);
823 }
George Liu0fda0f12021-11-16 10:06:17 +0800824 else if (
825 interface ==
826 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig")
Jonathan Domanc9514482021-02-24 09:20:51 -0800827 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700828 getCpuConfigData(asyncResp, processorId, serviceName,
829 objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800830 }
George Liu0fda0f12021-11-16 10:06:17 +0800831 else if (interface ==
832 "xyz.openbmc_project.Inventory.Decorator.LocationCode")
Jonathan Domanc9514482021-02-24 09:20:51 -0800833 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700834 getCpuLocationCode(asyncResp, serviceName, objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800835 }
Sharad Yadav71b82f22021-05-10 15:11:39 +0530836 else if (interface == "xyz.openbmc_project.Common.UUID")
837 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700838 getProcessorUUID(asyncResp, serviceName, objectPath);
Sharad Yadav71b82f22021-05-10 15:11:39 +0530839 }
George Liu0fda0f12021-11-16 10:06:17 +0800840 else if (interface ==
841 "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier")
Jonathan Doman49e429c2021-03-03 13:11:44 -0800842 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700843 getCpuUniqueId(asyncResp, serviceName, objectPath);
Jonathan Doman49e429c2021-03-03 13:11:44 -0800844 }
Chris Caindfbf7de2023-04-13 16:01:04 -0500845 else if (interface == "xyz.openbmc_project.Control.Power.Throttle")
846 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700847 getThrottleProperties(asyncResp, serviceName, objectPath);
Chris Caindfbf7de2023-04-13 16:01:04 -0500848 }
Jonathan Domanc9514482021-02-24 09:20:51 -0800849 }
850 }
851}
852
Jonathan Domandba0c292020-12-02 15:34:13 -0800853/**
854 * Request all the properties for the given D-Bus object and fill out the
855 * related entries in the Redfish OperatingConfig response.
856 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700857 * @param[in,out] asyncResp Async HTTP response.
Jonathan Domandba0c292020-12-02 15:34:13 -0800858 * @param[in] service D-Bus service name to query.
859 * @param[in] objPath D-Bus object to query.
860 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400861inline void getOperatingConfigData(
862 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
863 const std::string& service, const std::string& objPath)
Jonathan Domandba0c292020-12-02 15:34:13 -0800864{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800865 dbus::utility::getAllProperties(
866 service, objPath,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200867 "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig",
Ed Tanousac106bf2023-06-07 09:24:59 -0700868 [asyncResp](const boost::system::error_code& ec,
869 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400870 if (ec)
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200871 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400872 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
873 messages::internalError(asyncResp->res);
874 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700875 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200876
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400877 const size_t* availableCoreCount = nullptr;
878 const uint32_t* baseSpeed = nullptr;
879 const uint32_t* maxJunctionTemperature = nullptr;
880 const uint32_t* maxSpeed = nullptr;
881 const uint32_t* powerLimit = nullptr;
882 const TurboProfileProperty* turboProfile = nullptr;
883 const BaseSpeedPrioritySettingsProperty* baseSpeedPrioritySettings =
884 nullptr;
885
886 const bool success = sdbusplus::unpackPropertiesNoThrow(
887 dbus_utils::UnpackErrorPrinter(), properties,
888 "AvailableCoreCount", availableCoreCount, "BaseSpeed",
889 baseSpeed, "MaxJunctionTemperature", maxJunctionTemperature,
890 "MaxSpeed", maxSpeed, "PowerLimit", powerLimit, "TurboProfile",
891 turboProfile, "BaseSpeedPrioritySettings",
892 baseSpeedPrioritySettings);
893
894 if (!success)
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200895 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400896 messages::internalError(asyncResp->res);
897 return;
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200898 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400899
900 nlohmann::json& json = asyncResp->res.jsonValue;
901
902 if (availableCoreCount != nullptr)
903 {
904 json["TotalAvailableCoreCount"] = *availableCoreCount;
905 }
906
907 if (baseSpeed != nullptr)
908 {
909 json["BaseSpeedMHz"] = *baseSpeed;
910 }
911
912 if (maxJunctionTemperature != nullptr)
913 {
914 json["MaxJunctionTemperatureCelsius"] = *maxJunctionTemperature;
915 }
916
917 if (maxSpeed != nullptr)
918 {
919 json["MaxSpeedMHz"] = *maxSpeed;
920 }
921
922 if (powerLimit != nullptr)
923 {
924 json["TDPWatts"] = *powerLimit;
925 }
926
927 if (turboProfile != nullptr)
928 {
929 nlohmann::json& turboArray = json["TurboProfile"];
930 turboArray = nlohmann::json::array();
931 for (const auto& [turboSpeed, coreCount] : *turboProfile)
932 {
933 nlohmann::json::object_t turbo;
934 turbo["ActiveCoreCount"] = coreCount;
935 turbo["MaxSpeedMHz"] = turboSpeed;
936 turboArray.emplace_back(std::move(turbo));
937 }
938 }
939
940 if (baseSpeedPrioritySettings != nullptr)
941 {
942 nlohmann::json& baseSpeedArray =
943 json["BaseSpeedPrioritySettings"];
944 baseSpeedArray = nlohmann::json::array();
945 for (const auto& [baseSpeedMhz, coreList] :
946 *baseSpeedPrioritySettings)
947 {
948 nlohmann::json::object_t speed;
949 speed["CoreCount"] = coreList.size();
950 speed["CoreIDs"] = coreList;
951 speed["BaseSpeedMHz"] = baseSpeedMhz;
952 baseSpeedArray.emplace_back(std::move(speed));
953 }
954 }
955 });
Jonathan Domandba0c292020-12-02 15:34:13 -0800956}
957
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800958/**
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800959 * Handle the PATCH operation of the AppliedOperatingConfig property. Do basic
960 * validation of the input data, and then set the D-Bus property.
961 *
962 * @param[in,out] resp Async HTTP response.
963 * @param[in] processorId Processor's Id.
964 * @param[in] appliedConfigUri New property value to apply.
965 * @param[in] cpuObjectPath Path of CPU object to modify.
966 * @param[in] serviceMap Service map for CPU object.
967 */
968inline void patchAppliedOperatingConfig(
969 const std::shared_ptr<bmcweb::AsyncResp>& resp,
970 const std::string& processorId, const std::string& appliedConfigUri,
Shantappa Teekappanavar5df6eda2022-01-18 12:29:28 -0600971 const std::string& cpuObjectPath,
972 const dbus::utility::MapperServiceMap& serviceMap)
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800973{
974 // Check that the property even exists by checking for the interface
975 const std::string* controlService = nullptr;
976 for (const auto& [serviceName, interfaceList] : serviceMap)
977 {
Ed Tanous3544d2a2023-08-06 18:12:20 -0700978 if (std::ranges::find(interfaceList,
979 "xyz.openbmc_project.Control.Processor."
980 "CurrentOperatingConfig") != interfaceList.end())
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800981 {
982 controlService = &serviceName;
983 break;
984 }
985 }
986
987 if (controlService == nullptr)
988 {
989 messages::internalError(resp->res);
990 return;
991 }
992
993 // Check that the config URI is a child of the cpu URI being patched.
Ed Tanous253f11b2024-05-16 09:38:31 -0700994 std::string expectedPrefix(std::format("/redfish/v1/Systems/{}/Processors/",
995 BMCWEB_REDFISH_SYSTEM_URI_NAME));
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800996 expectedPrefix += processorId;
997 expectedPrefix += "/OperatingConfigs/";
Ed Tanous11ba3972022-07-11 09:50:41 -0700998 if (!appliedConfigUri.starts_with(expectedPrefix) ||
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800999 expectedPrefix.size() == appliedConfigUri.size())
1000 {
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001001 messages::propertyValueIncorrect(resp->res, "AppliedOperatingConfig",
1002 appliedConfigUri);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001003 return;
1004 }
1005
1006 // Generate the D-Bus path of the OperatingConfig object, by assuming it's a
1007 // direct child of the CPU object.
1008 // Strip the expectedPrefix from the config URI to get the "filename", and
1009 // append to the CPU's path.
1010 std::string configBaseName = appliedConfigUri.substr(expectedPrefix.size());
1011 sdbusplus::message::object_path configPath(cpuObjectPath);
1012 configPath /= configBaseName;
1013
Ed Tanous62598e32023-07-17 17:06:25 -07001014 BMCWEB_LOG_INFO("Setting config to {}", configPath.str);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001015
1016 // Set the property, with handler to check error responses
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001017 setDbusProperty(
Ginu Georgee93abac2024-06-14 17:35:27 +05301018 resp, "AppliedOperatingConfig", *controlService, cpuObjectPath,
George Liu9ae226f2023-06-21 17:56:46 +08001019 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig",
Ginu Georgee93abac2024-06-14 17:35:27 +05301020 "AppliedConfig", configPath);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001021}
1022
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001023inline void handleProcessorHead(
1024 crow::App& app, const crow::Request& req,
1025 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1026 const std::string& /* systemName */, const std::string& /* processorId */)
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001027{
Ed Tanousac106bf2023-06-07 09:24:59 -07001028 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001029 {
1030 return;
1031 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001032 asyncResp->res.addHeader(
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001033 boost::beast::http::field::link,
1034 "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
1035}
1036
1037inline void handleProcessorCollectionHead(
1038 crow::App& app, const crow::Request& req,
Ed Tanousac106bf2023-06-07 09:24:59 -07001039 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001040 const std::string& /* systemName */)
1041{
Ed Tanousac106bf2023-06-07 09:24:59 -07001042 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001043 {
1044 return;
1045 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001046 asyncResp->res.addHeader(
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001047 boost::beast::http::field::link,
1048 "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
1049}
1050
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001051inline void requestRoutesOperatingConfigCollection(App& app)
Jonathan Domandba0c292020-12-02 15:34:13 -08001052{
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001053 BMCWEB_ROUTE(app,
1054 "/redfish/v1/Systems/<str>/Processors/<str>/OperatingConfigs/")
Ed Tanoused398212021-06-09 17:05:54 -07001055 .privileges(redfish::privileges::getOperatingConfigCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001056 .methods(
1057 boost::beast::http::verb::
1058 get)([&app](const crow::Request& req,
1059 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1060 const std::string& systemName,
1061 const std::string& cpuName) {
1062 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -07001063 {
1064 return;
1065 }
Jonathan Domandba0c292020-12-02 15:34:13 -08001066
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001067 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07001068 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001069 // Option currently returns no systems. TBD
1070 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1071 systemName);
Ed Tanous002d39b2022-05-31 08:59:27 -07001072 return;
1073 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001074
1075 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1076 {
1077 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1078 systemName);
1079 return;
1080 }
1081 asyncResp->res.jsonValue["@odata.type"] =
1082 "#OperatingConfigCollection.OperatingConfigCollection";
1083 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1084 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
1085 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName);
1086 asyncResp->res.jsonValue["Name"] = "Operating Config Collection";
1087
1088 // First find the matching CPU object so we know how to
1089 // constrain our search for related Config objects.
1090 const std::array<std::string_view, 1> interfaces = {
1091 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig"};
1092 dbus::utility::getSubTreePaths(
1093 "/xyz/openbmc_project/inventory", 0, interfaces,
1094 [asyncResp,
1095 cpuName](const boost::system::error_code& ec,
1096 const dbus::utility::MapperGetSubTreePathsResponse&
1097 objects) {
1098 if (ec)
1099 {
1100 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec,
1101 ec.message());
1102 messages::internalError(asyncResp->res);
1103 return;
1104 }
1105
1106 for (const std::string& object : objects)
1107 {
1108 if (!object.ends_with(cpuName))
1109 {
1110 continue;
1111 }
1112
1113 // Not expected that there will be multiple matching
1114 // CPU objects, but if there are just use the first
1115 // one.
1116
1117 // Use the common search routine to construct the
1118 // Collection of all Config objects under this CPU.
1119 constexpr std::array<std::string_view, 1> interface{
1120 "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
1121 collection_util::getCollectionMembers(
1122 asyncResp,
1123 boost::urls::format(
1124 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
1125 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName),
1126 interface, object);
1127 return;
1128 }
1129 });
George Liu0fda0f12021-11-16 10:06:17 +08001130 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001131}
1132
1133inline void requestRoutesOperatingConfig(App& app)
1134{
1135 BMCWEB_ROUTE(
1136 app,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001137 "/redfish/v1/Systems/<str>/Processors/<str>/OperatingConfigs/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001138 .privileges(redfish::privileges::getOperatingConfig)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001139 .methods(
1140 boost::beast::http::verb::
1141 get)([&app](const crow::Request& req,
1142 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1143 const std::string& systemName,
1144 const std::string& cpuName,
1145 const std::string& configName) {
1146 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -07001147 {
1148 return;
1149 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001150 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07001151 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001152 // Option currently returns no systems. TBD
1153 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1154 systemName);
Ed Tanous002d39b2022-05-31 08:59:27 -07001155 return;
1156 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001157
1158 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1159 {
1160 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1161 systemName);
1162 return;
1163 }
1164 // Ask for all objects implementing OperatingConfig so we can search
1165 // for one with a matching name
1166 constexpr std::array<std::string_view, 1> interfaces = {
1167 "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
1168 dbus::utility::getSubTree(
1169 "/xyz/openbmc_project/inventory", 0, interfaces,
1170 [asyncResp, cpuName, configName](
1171 const boost::system::error_code& ec,
1172 const dbus::utility::MapperGetSubTreeResponse& subtree) {
1173 if (ec)
1174 {
1175 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec,
1176 ec.message());
1177 messages::internalError(asyncResp->res);
1178 return;
1179 }
1180 const std::string expectedEnding =
1181 cpuName + '/' + configName;
1182 for (const auto& [objectPath, serviceMap] : subtree)
1183 {
1184 // Ignore any configs without matching cpuX/configY
1185 if (!objectPath.ends_with(expectedEnding) ||
1186 serviceMap.empty())
1187 {
1188 continue;
1189 }
1190
1191 nlohmann::json& json = asyncResp->res.jsonValue;
1192 json["@odata.type"] =
1193 "#OperatingConfig.v1_0_0.OperatingConfig";
1194 json["@odata.id"] = boost::urls::format(
1195 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}",
1196 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName,
1197 configName);
1198 json["Name"] = "Processor Profile";
1199 json["Id"] = configName;
1200
1201 // Just use the first implementation of the object - not
1202 // expected that there would be multiple matching
1203 // services
1204 getOperatingConfigData(
1205 asyncResp, serviceMap.begin()->first, objectPath);
1206 return;
1207 }
1208 messages::resourceNotFound(asyncResp->res,
1209 "OperatingConfig", configName);
1210 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001211 });
1212}
Jonathan Domandba0c292020-12-02 15:34:13 -08001213
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001214inline void requestRoutesProcessorCollection(App& app)
Gunnar Millsac6a4442020-10-14 14:55:29 -05001215{
Gunnar Millsac6a4442020-10-14 14:55:29 -05001216 /**
1217 * Functions triggers appropriate requests on DBus
1218 */
Ed Tanous22d268c2022-05-19 09:39:07 -07001219 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/")
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001220 .privileges(redfish::privileges::headProcessorCollection)
1221 .methods(boost::beast::http::verb::head)(
1222 std::bind_front(handleProcessorCollectionHead, std::ref(app)));
1223
1224 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/")
Ed Tanoused398212021-06-09 17:05:54 -07001225 .privileges(redfish::privileges::getProcessorCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001226 .methods(
1227 boost::beast::http::verb::
1228 get)([&app](const crow::Request& req,
1229 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1230 const std::string& systemName) {
1231 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1232 {
1233 return;
1234 }
1235 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1236 {
1237 // Option currently returns no systems. TBD
1238 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1239 systemName);
1240 return;
1241 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001242
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001243 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1244 {
1245 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1246 systemName);
1247 return;
1248 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001249
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001250 asyncResp->res.addHeader(
1251 boost::beast::http::field::link,
1252 "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001253
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001254 asyncResp->res.jsonValue["@odata.type"] =
1255 "#ProcessorCollection.ProcessorCollection";
1256 asyncResp->res.jsonValue["Name"] = "Processor Collection";
Gunnar Millsac6a4442020-10-14 14:55:29 -05001257
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001258 asyncResp->res.jsonValue["@odata.id"] =
1259 std::format("/redfish/v1/Systems/{}/Processors",
1260 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Gunnar Millsac6a4442020-10-14 14:55:29 -05001261
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001262 collection_util::getCollectionMembers(
1263 asyncResp,
1264 boost::urls::format("/redfish/v1/Systems/{}/Processors",
1265 BMCWEB_REDFISH_SYSTEM_URI_NAME),
1266 processorInterfaces, "/xyz/openbmc_project/inventory");
1267 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001268}
Gunnar Millsac6a4442020-10-14 14:55:29 -05001269
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001270inline void requestRoutesProcessor(App& app)
Gunnar Millsac6a4442020-10-14 14:55:29 -05001271{
Gunnar Millsac6a4442020-10-14 14:55:29 -05001272 /**
1273 * Functions triggers appropriate requests on DBus
1274 */
Gunnar Millsac6a4442020-10-14 14:55:29 -05001275
Ed Tanous22d268c2022-05-19 09:39:07 -07001276 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001277 .privileges(redfish::privileges::headProcessor)
1278 .methods(boost::beast::http::verb::head)(
1279 std::bind_front(handleProcessorHead, std::ref(app)));
1280
1281 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001282 .privileges(redfish::privileges::getProcessor)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001283 .methods(
1284 boost::beast::http::verb::
1285 get)([&app](const crow::Request& req,
1286 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1287 const std::string& systemName,
1288 const std::string& processorId) {
1289 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1290 {
1291 return;
1292 }
1293 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1294 {
1295 // Option currently returns no systems. TBD
1296 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1297 systemName);
1298 return;
1299 }
1300 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1301 {
1302 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1303 systemName);
1304 return;
1305 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001306
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001307 asyncResp->res.addHeader(
1308 boost::beast::http::field::link,
1309 "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
1310 asyncResp->res.jsonValue["@odata.type"] =
1311 "#Processor.v1_18_0.Processor";
1312 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1313 "/redfish/v1/Systems/{}/Processors/{}",
1314 BMCWEB_REDFISH_SYSTEM_URI_NAME, processorId);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001315
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001316 getProcessorObject(
1317 asyncResp, processorId,
1318 std::bind_front(getProcessorData, asyncResp, processorId));
1319 });
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001320
Ed Tanous22d268c2022-05-19 09:39:07 -07001321 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001322 .privileges(redfish::privileges::patchProcessor)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001323 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001324 [&app](const crow::Request& req,
1325 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001326 const std::string& systemName,
Ed Tanous45ca1b82022-03-25 13:07:27 -07001327 const std::string& processorId) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001328 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1329 {
1330 return;
1331 }
1332 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1333 {
1334 // Option currently returns no systems. TBD
1335 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1336 systemName);
1337 return;
1338 }
1339 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1340 {
1341 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1342 systemName);
1343 return;
1344 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001345
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001346 std::optional<std::string> appliedConfigUri;
1347 if (!json_util::readJsonPatch(
Myung Baeafc474a2024-10-09 00:53:29 -07001348 req, asyncResp->res, //
1349 "AppliedOperatingConfig/@odata.id", appliedConfigUri //
1350 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001351 {
1352 return;
1353 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001354
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001355 if (appliedConfigUri)
1356 {
1357 // Check for 404 and find matching D-Bus object, then run
1358 // property patch handlers if that all succeeds.
1359 getProcessorObject(
1360 asyncResp, processorId,
1361 std::bind_front(patchAppliedOperatingConfig, asyncResp,
1362 processorId, *appliedConfigUri));
1363 }
1364 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001365}
Gunnar Millsac6a4442020-10-14 14:55:29 -05001366
1367} // namespace redfish