blob: c0d3103fb85600fbe8f869b96422ebaec832b297 [file] [log] [blame]
Gunnar Millsac6a4442020-10-14 14:55:29 -05001/*
Ed Tanous6be832e2024-09-10 11:44:48 -07002Copyright (c) 2018 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
Gunnar Millsac6a4442020-10-14 14:55:29 -050015*/
16#pragma once
17
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080018#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070019#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080020#include "dbus_utility.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070021#include "error_messages.hpp"
Chris Caindfbf7de2023-04-13 16:01:04 -050022#include "generated/enums/processor.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070023#include "generated/enums/resource.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080024#include "query.hpp"
25#include "registries/privilege_registry.hpp"
26#include "utils/collection.hpp"
27#include "utils/dbus_utils.hpp"
28#include "utils/json_utils.hpp"
Gunnar Millsac6a4442020-10-14 14:55:29 -050029
30#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080031#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070032#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070033#include <sdbusplus/asio/property.hpp>
Jonathan Domandba0c292020-12-02 15:34:13 -080034#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelny351053f2022-07-28 15:44:22 +020035#include <sdbusplus/unpack_properties.hpp>
Jonathan Domandba0c292020-12-02 15:34:13 -080036#include <sdbusplus/utility/dedup_variant.hpp>
Gunnar Millsac6a4442020-10-14 14:55:29 -050037
George Liu7a1dbc42022-12-07 16:03:22 +080038#include <array>
Michael Shenb9d679d2023-02-13 02:29:04 +000039#include <limits>
Ed Tanous3544d2a2023-08-06 18:12:20 -070040#include <ranges>
Ed Tanous3c569212024-03-06 14:46:18 -080041#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080042#include <string_view>
43
Gunnar Millsac6a4442020-10-14 14:55:29 -050044namespace redfish
45{
46
Jonathan Domanc9514482021-02-24 09:20:51 -080047// Interfaces which imply a D-Bus object represents a Processor
George Liu7a1dbc42022-12-07 16:03:22 +080048constexpr std::array<std::string_view, 2> processorInterfaces = {
Jonathan Domanc9514482021-02-24 09:20:51 -080049 "xyz.openbmc_project.Inventory.Item.Cpu",
50 "xyz.openbmc_project.Inventory.Item.Accelerator"};
Jonathan Doman2bab9832020-12-02 15:27:40 -080051
Sharad Yadav71b82f22021-05-10 15:11:39 +053052/**
53 * @brief Fill out uuid info of a processor by
54 * requesting data from the given D-Bus object.
55 *
Ed Tanousac106bf2023-06-07 09:24:59 -070056 * @param[in,out] asyncResp Async HTTP response.
Sharad Yadav71b82f22021-05-10 15:11:39 +053057 * @param[in] service D-Bus service to query.
58 * @param[in] objPath D-Bus object to query.
59 */
Ed Tanousac106bf2023-06-07 09:24:59 -070060inline void getProcessorUUID(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Sharad Yadav71b82f22021-05-10 15:11:39 +053061 const std::string& service,
62 const std::string& objPath)
63{
Ed Tanous62598e32023-07-17 17:06:25 -070064 BMCWEB_LOG_DEBUG("Get Processor UUID");
Jonathan Doman1e1e5982021-06-11 09:36:17 -070065 sdbusplus::asio::getProperty<std::string>(
66 *crow::connections::systemBus, service, objPath,
67 "xyz.openbmc_project.Common.UUID", "UUID",
Ed Tanousac106bf2023-06-07 09:24:59 -070068 [objPath, asyncResp{std::move(asyncResp)}](
69 const boost::system::error_code& ec, const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040070 if (ec)
71 {
72 BMCWEB_LOG_DEBUG("DBUS response error");
73 messages::internalError(asyncResp->res);
74 return;
75 }
76 asyncResp->res.jsonValue["UUID"] = property;
77 });
Sharad Yadav71b82f22021-05-10 15:11:39 +053078}
79
Ed Tanous711ac7a2021-12-20 09:34:41 -080080inline void getCpuDataByInterface(
Ed Tanousac106bf2023-06-07 09:24:59 -070081 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Michael Shen80f79a42023-08-24 13:41:53 +000082 const dbus::utility::DBusInterfacesMap& cpuInterfacesProperties)
Gunnar Millsac6a4442020-10-14 14:55:29 -050083{
Ed Tanous62598e32023-07-17 17:06:25 -070084 BMCWEB_LOG_DEBUG("Get CPU resources by interface.");
Gunnar Millsac6a4442020-10-14 14:55:29 -050085
Chicago Duana1649ec2021-03-30 16:54:58 +080086 // Set the default value of state
Ed Tanous539d8c62024-06-19 14:38:27 -070087 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
88 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
Gunnar Millsac6a4442020-10-14 14:55:29 -050089
90 for (const auto& interface : cpuInterfacesProperties)
91 {
92 for (const auto& property : interface.second)
93 {
Chicago Duana1649ec2021-03-30 16:54:58 +080094 if (property.first == "Present")
Gunnar Millsac6a4442020-10-14 14:55:29 -050095 {
Chicago Duana1649ec2021-03-30 16:54:58 +080096 const bool* cpuPresent = std::get_if<bool>(&property.second);
97 if (cpuPresent == nullptr)
Gunnar Millsac6a4442020-10-14 14:55:29 -050098 {
99 // Important property not in desired type
Ed Tanousac106bf2023-06-07 09:24:59 -0700100 messages::internalError(asyncResp->res);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500101 return;
102 }
Ed Tanouse05aec52022-01-25 10:28:56 -0800103 if (!*cpuPresent)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500104 {
Chicago Duana1649ec2021-03-30 16:54:58 +0800105 // Slot is not populated
Ed Tanous539d8c62024-06-19 14:38:27 -0700106 asyncResp->res.jsonValue["Status"]["State"] =
107 resource::State::Absent;
Chicago Duana1649ec2021-03-30 16:54:58 +0800108 }
109 }
110 else if (property.first == "Functional")
111 {
112 const bool* cpuFunctional = std::get_if<bool>(&property.second);
113 if (cpuFunctional == nullptr)
114 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700115 messages::internalError(asyncResp->res);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500116 return;
117 }
Ed Tanouse05aec52022-01-25 10:28:56 -0800118 if (!*cpuFunctional)
Chicago Duana1649ec2021-03-30 16:54:58 +0800119 {
Ed Tanous539d8c62024-06-19 14:38:27 -0700120 asyncResp->res.jsonValue["Status"]["Health"] =
121 resource::Health::Critical;
Chicago Duana1649ec2021-03-30 16:54:58 +0800122 }
123 }
124 else if (property.first == "CoreCount")
125 {
126 const uint16_t* coresCount =
127 std::get_if<uint16_t>(&property.second);
128 if (coresCount == nullptr)
129 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700130 messages::internalError(asyncResp->res);
Chicago Duana1649ec2021-03-30 16:54:58 +0800131 return;
132 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700133 asyncResp->res.jsonValue["TotalCores"] = *coresCount;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500134 }
Jonathan Domandc3fa662020-10-26 23:10:24 -0700135 else if (property.first == "MaxSpeedInMhz")
136 {
137 const uint32_t* value = std::get_if<uint32_t>(&property.second);
138 if (value != nullptr)
139 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700140 asyncResp->res.jsonValue["MaxSpeedMHz"] = *value;
Jonathan Domandc3fa662020-10-26 23:10:24 -0700141 }
142 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500143 else if (property.first == "Socket")
144 {
145 const std::string* value =
146 std::get_if<std::string>(&property.second);
147 if (value != nullptr)
148 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700149 asyncResp->res.jsonValue["Socket"] = *value;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500150 }
151 }
152 else if (property.first == "ThreadCount")
153 {
Jonathan Domandc3fa662020-10-26 23:10:24 -0700154 const uint16_t* value = std::get_if<uint16_t>(&property.second);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500155 if (value != nullptr)
156 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700157 asyncResp->res.jsonValue["TotalThreads"] = *value;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500158 }
159 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700160 else if (property.first == "EffectiveFamily")
Gunnar Millsac6a4442020-10-14 14:55:29 -0500161 {
Brandon Kim1930fbd2021-09-14 17:52:51 -0700162 const uint16_t* value = std::get_if<uint16_t>(&property.second);
Brad Bishop6169de22022-09-14 13:08:32 -0400163 if (value != nullptr && *value != 2)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500164 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700165 asyncResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] =
Ed Tanous866e4862022-02-17 11:40:25 -0800166 "0x" + intToHexString(*value, 4);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500167 }
168 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700169 else if (property.first == "EffectiveModel")
170 {
171 const uint16_t* value = std::get_if<uint16_t>(&property.second);
172 if (value == nullptr)
173 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700174 messages::internalError(asyncResp->res);
Brandon Kim1930fbd2021-09-14 17:52:51 -0700175 return;
176 }
Brad Bishop6169de22022-09-14 13:08:32 -0400177 if (*value != 0)
178 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700179 asyncResp->res.jsonValue["ProcessorId"]["EffectiveModel"] =
Brad Bishop6169de22022-09-14 13:08:32 -0400180 "0x" + intToHexString(*value, 4);
181 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700182 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500183 else if (property.first == "Id")
184 {
185 const uint64_t* value = std::get_if<uint64_t>(&property.second);
186 if (value != nullptr && *value != 0)
187 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700188 asyncResp->res
Gunnar Millsac6a4442020-10-14 14:55:29 -0500189 .jsonValue["ProcessorId"]["IdentificationRegisters"] =
Ed Tanous866e4862022-02-17 11:40:25 -0800190 "0x" + intToHexString(*value, 16);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500191 }
192 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700193 else if (property.first == "Microcode")
194 {
195 const uint32_t* value = std::get_if<uint32_t>(&property.second);
196 if (value == nullptr)
197 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700198 messages::internalError(asyncResp->res);
Brandon Kim1930fbd2021-09-14 17:52:51 -0700199 return;
200 }
Brad Bishop6169de22022-09-14 13:08:32 -0400201 if (*value != 0)
202 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700203 asyncResp->res.jsonValue["ProcessorId"]["MicrocodeInfo"] =
Brad Bishop6169de22022-09-14 13:08:32 -0400204 "0x" + intToHexString(*value, 8);
205 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700206 }
207 else if (property.first == "Step")
208 {
209 const uint16_t* value = std::get_if<uint16_t>(&property.second);
210 if (value == nullptr)
211 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700212 messages::internalError(asyncResp->res);
Brandon Kim1930fbd2021-09-14 17:52:51 -0700213 return;
214 }
Michael Shenb9d679d2023-02-13 02:29:04 +0000215 if (*value != std::numeric_limits<uint16_t>::max())
Brad Bishop6169de22022-09-14 13:08:32 -0400216 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700217 asyncResp->res.jsonValue["ProcessorId"]["Step"] =
Brad Bishop6169de22022-09-14 13:08:32 -0400218 "0x" + intToHexString(*value, 4);
219 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700220 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500221 }
222 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500223}
224
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400225inline void getCpuDataByService(
226 std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& cpuId,
227 const std::string& service, const std::string& objPath)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500228{
Ed Tanous62598e32023-07-17 17:06:25 -0700229 BMCWEB_LOG_DEBUG("Get available system cpu resources by service.");
Gunnar Millsac6a4442020-10-14 14:55:29 -0500230
George Liu5eb468d2023-06-20 17:03:24 +0800231 sdbusplus::message::object_path path("/xyz/openbmc_project/inventory");
232 dbus::utility::getManagedObjects(
233 service, path,
Ed Tanousac106bf2023-06-07 09:24:59 -0700234 [cpuId, service, objPath, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800235 const boost::system::error_code& ec,
Gunnar Millsac6a4442020-10-14 14:55:29 -0500236 const dbus::utility::ManagedObjectType& dbusData) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400237 if (ec)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500238 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400239 BMCWEB_LOG_DEBUG("DBUS response error");
240 messages::internalError(asyncResp->res);
241 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700242 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400243 asyncResp->res.jsonValue["Id"] = cpuId;
244 asyncResp->res.jsonValue["Name"] = "Processor";
245 asyncResp->res.jsonValue["ProcessorType"] =
246 processor::ProcessorType::CPU;
247
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400248 for (const auto& object : dbusData)
Ed Tanous002d39b2022-05-31 08:59:27 -0700249 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400250 if (object.first.str == objPath)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500251 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400252 getCpuDataByInterface(asyncResp, object.second);
253 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400254 }
255 return;
256 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500257}
258
Chris Caindfbf7de2023-04-13 16:01:04 -0500259/**
260 * @brief Translates throttle cause DBUS property to redfish.
261 *
262 * @param[in] dbusSource The throttle cause from DBUS
263 *
264 * @return Returns as a string, the throttle cause in Redfish terms. If
265 * translation cannot be done, returns "Unknown" throttle reason.
266 */
267inline processor::ThrottleCause
268 dbusToRfThrottleCause(const std::string& dbusSource)
269{
270 if (dbusSource ==
271 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ClockLimit")
272 {
273 return processor::ThrottleCause::ClockLimit;
274 }
275 if (dbusSource ==
276 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ManagementDetectedFault")
277 {
278 return processor::ThrottleCause::ManagementDetectedFault;
279 }
280 if (dbusSource ==
281 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.PowerLimit")
282 {
283 return processor::ThrottleCause::PowerLimit;
284 }
285 if (dbusSource ==
286 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ThermalLimit")
287 {
288 return processor::ThrottleCause::ThermalLimit;
289 }
290 if (dbusSource ==
291 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.Unknown")
292 {
293 return processor::ThrottleCause::Unknown;
294 }
295 return processor::ThrottleCause::Invalid;
296}
297
298inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700299 readThrottleProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Caindfbf7de2023-04-13 16:01:04 -0500300 const boost::system::error_code& ec,
301 const dbus::utility::DBusPropertiesMap& properties)
302{
303 if (ec)
304 {
Ed Tanous62598e32023-07-17 17:06:25 -0700305 BMCWEB_LOG_ERROR("Processor Throttle getAllProperties error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700306 messages::internalError(asyncResp->res);
Chris Caindfbf7de2023-04-13 16:01:04 -0500307 return;
308 }
309
310 const bool* status = nullptr;
311 const std::vector<std::string>* causes = nullptr;
312
313 if (!sdbusplus::unpackPropertiesNoThrow(dbus_utils::UnpackErrorPrinter(),
314 properties, "Throttled", status,
315 "ThrottleCauses", causes))
316 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700317 messages::internalError(asyncResp->res);
Chris Caindfbf7de2023-04-13 16:01:04 -0500318 return;
319 }
320
Ed Tanousac106bf2023-06-07 09:24:59 -0700321 asyncResp->res.jsonValue["Throttled"] = *status;
Chris Caindfbf7de2023-04-13 16:01:04 -0500322 nlohmann::json::array_t rCauses;
323 for (const std::string& cause : *causes)
324 {
325 processor::ThrottleCause rfCause = dbusToRfThrottleCause(cause);
326 if (rfCause == processor::ThrottleCause::Invalid)
327 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700328 messages::internalError(asyncResp->res);
Chris Caindfbf7de2023-04-13 16:01:04 -0500329 return;
330 }
331
332 rCauses.emplace_back(rfCause);
333 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700334 asyncResp->res.jsonValue["ThrottleCauses"] = std::move(rCauses);
Chris Caindfbf7de2023-04-13 16:01:04 -0500335}
336
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400337inline void getThrottleProperties(
338 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
339 const std::string& service, const std::string& objectPath)
Chris Caindfbf7de2023-04-13 16:01:04 -0500340{
Ed Tanous62598e32023-07-17 17:06:25 -0700341 BMCWEB_LOG_DEBUG("Get processor throttle resources");
Chris Caindfbf7de2023-04-13 16:01:04 -0500342
343 sdbusplus::asio::getAllProperties(
344 *crow::connections::systemBus, service, objectPath,
345 "xyz.openbmc_project.Control.Power.Throttle",
Ed Tanousac106bf2023-06-07 09:24:59 -0700346 [asyncResp](const boost::system::error_code& ec,
347 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400348 readThrottleProperties(asyncResp, ec, properties);
349 });
Chris Caindfbf7de2023-04-13 16:01:04 -0500350}
351
Ed Tanousac106bf2023-06-07 09:24:59 -0700352inline void getCpuAssetData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Millsac6a4442020-10-14 14:55:29 -0500353 const std::string& service,
354 const std::string& objPath)
355{
Ed Tanous62598e32023-07-17 17:06:25 -0700356 BMCWEB_LOG_DEBUG("Get Cpu Asset Data");
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200357 sdbusplus::asio::getAllProperties(
358 *crow::connections::systemBus, service, objPath,
359 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanousac106bf2023-06-07 09:24:59 -0700360 [objPath, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800361 const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200362 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400363 if (ec)
Ed Tanous002d39b2022-05-31 08:59:27 -0700364 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400365 BMCWEB_LOG_DEBUG("DBUS response error");
366 messages::internalError(asyncResp->res);
367 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700368 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400369
370 const std::string* serialNumber = nullptr;
371 const std::string* model = nullptr;
372 const std::string* manufacturer = nullptr;
373 const std::string* partNumber = nullptr;
374 const std::string* sparePartNumber = nullptr;
375
376 const bool success = sdbusplus::unpackPropertiesNoThrow(
377 dbus_utils::UnpackErrorPrinter(), properties, "SerialNumber",
378 serialNumber, "Model", model, "Manufacturer", manufacturer,
379 "PartNumber", partNumber, "SparePartNumber", sparePartNumber);
380
381 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700382 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400383 messages::internalError(asyncResp->res);
384 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700385 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200386
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400387 if (serialNumber != nullptr && !serialNumber->empty())
388 {
389 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
390 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200391
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400392 if ((model != nullptr) && !model->empty())
393 {
394 asyncResp->res.jsonValue["Model"] = *model;
395 }
396
397 if (manufacturer != nullptr)
398 {
399 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
400
401 // Otherwise would be unexpected.
402 if (manufacturer->find("Intel") != std::string::npos)
403 {
404 asyncResp->res.jsonValue["ProcessorArchitecture"] = "x86";
405 asyncResp->res.jsonValue["InstructionSet"] = "x86-64";
406 }
407 else if (manufacturer->find("IBM") != std::string::npos)
408 {
409 asyncResp->res.jsonValue["ProcessorArchitecture"] = "Power";
410 asyncResp->res.jsonValue["InstructionSet"] = "PowerISA";
411 }
412 }
413
414 if (partNumber != nullptr)
415 {
416 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
417 }
418
419 if (sparePartNumber != nullptr && !sparePartNumber->empty())
420 {
421 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
422 }
423 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500424}
425
Ed Tanousac106bf2023-06-07 09:24:59 -0700426inline void getCpuRevisionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Millsac6a4442020-10-14 14:55:29 -0500427 const std::string& service,
428 const std::string& objPath)
429{
Ed Tanous62598e32023-07-17 17:06:25 -0700430 BMCWEB_LOG_DEBUG("Get Cpu Revision Data");
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200431 sdbusplus::asio::getAllProperties(
432 *crow::connections::systemBus, service, objPath,
433 "xyz.openbmc_project.Inventory.Decorator.Revision",
Ed Tanousac106bf2023-06-07 09:24:59 -0700434 [objPath, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800435 const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200436 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400437 if (ec)
438 {
439 BMCWEB_LOG_DEBUG("DBUS response error");
440 messages::internalError(asyncResp->res);
441 return;
442 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500443
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400444 const std::string* version = nullptr;
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200445
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400446 const bool success = sdbusplus::unpackPropertiesNoThrow(
447 dbus_utils::UnpackErrorPrinter(), properties, "Version",
448 version);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200449
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400450 if (!success)
451 {
452 messages::internalError(asyncResp->res);
453 return;
454 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200455
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400456 if (version != nullptr)
457 {
458 asyncResp->res.jsonValue["Version"] = *version;
459 }
460 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500461}
462
zhanghch058d1b46d2021-04-01 11:18:24 +0800463inline void getAcceleratorDataByService(
Ed Tanousac106bf2023-06-07 09:24:59 -0700464 std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& acclrtrId,
zhanghch058d1b46d2021-04-01 11:18:24 +0800465 const std::string& service, const std::string& objPath)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500466{
Ed Tanous62598e32023-07-17 17:06:25 -0700467 BMCWEB_LOG_DEBUG("Get available system Accelerator resources by service.");
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200468 sdbusplus::asio::getAllProperties(
469 *crow::connections::systemBus, service, objPath, "",
Ed Tanousac106bf2023-06-07 09:24:59 -0700470 [acclrtrId, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800471 const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200472 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400473 if (ec)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500474 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400475 BMCWEB_LOG_DEBUG("DBUS response error");
476 messages::internalError(asyncResp->res);
477 return;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500478 }
479
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400480 const bool* functional = nullptr;
481 const bool* present = nullptr;
482
483 const bool success = sdbusplus::unpackPropertiesNoThrow(
484 dbus_utils::UnpackErrorPrinter(), properties, "Functional",
485 functional, "Present", present);
486
487 if (!success)
488 {
489 messages::internalError(asyncResp->res);
490 return;
491 }
492
493 std::string state = "Enabled";
494 std::string health = "OK";
495
496 if (present != nullptr && !*present)
497 {
498 state = "Absent";
499 }
500
501 if (functional != nullptr && !*functional)
502 {
503 if (state == "Enabled")
504 {
505 health = "Critical";
506 }
507 }
508
509 asyncResp->res.jsonValue["Id"] = acclrtrId;
510 asyncResp->res.jsonValue["Name"] = "Processor";
511 asyncResp->res.jsonValue["Status"]["State"] = state;
512 asyncResp->res.jsonValue["Status"]["Health"] = health;
513 asyncResp->res.jsonValue["ProcessorType"] =
514 processor::ProcessorType::Accelerator;
515 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500516}
517
Jonathan Domandba0c292020-12-02 15:34:13 -0800518// OperatingConfig D-Bus Types
519using TurboProfileProperty = std::vector<std::tuple<uint32_t, size_t>>;
520using BaseSpeedPrioritySettingsProperty =
521 std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>;
522// uint32_t and size_t may or may not be the same type, requiring a dedup'd
523// variant
Jonathan Domandba0c292020-12-02 15:34:13 -0800524
525/**
526 * Fill out the HighSpeedCoreIDs in a Processor resource from the given
527 * OperatingConfig D-Bus property.
528 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700529 * @param[in,out] asyncResp Async HTTP response.
Jonathan Domandba0c292020-12-02 15:34:13 -0800530 * @param[in] baseSpeedSettings Full list of base speed priority groups,
531 * to use to determine the list of high
532 * speed cores.
533 */
534inline void highSpeedCoreIdsHandler(
Ed Tanousac106bf2023-06-07 09:24:59 -0700535 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Domandba0c292020-12-02 15:34:13 -0800536 const BaseSpeedPrioritySettingsProperty& baseSpeedSettings)
537{
538 // The D-Bus property does not indicate which bucket is the "high
539 // priority" group, so let's discern that by looking for the one with
540 // highest base frequency.
541 auto highPriorityGroup = baseSpeedSettings.cend();
542 uint32_t highestBaseSpeed = 0;
543 for (auto it = baseSpeedSettings.cbegin(); it != baseSpeedSettings.cend();
544 ++it)
545 {
546 const uint32_t baseFreq = std::get<uint32_t>(*it);
547 if (baseFreq > highestBaseSpeed)
548 {
549 highestBaseSpeed = baseFreq;
550 highPriorityGroup = it;
551 }
552 }
553
Ed Tanousac106bf2023-06-07 09:24:59 -0700554 nlohmann::json& jsonCoreIds = asyncResp->res.jsonValue["HighSpeedCoreIDs"];
Jonathan Domandba0c292020-12-02 15:34:13 -0800555 jsonCoreIds = nlohmann::json::array();
556
557 // There may not be any entries in the D-Bus property, so only populate
558 // if there was actually something there.
559 if (highPriorityGroup != baseSpeedSettings.cend())
560 {
561 jsonCoreIds = std::get<std::vector<uint32_t>>(*highPriorityGroup);
562 }
563}
564
565/**
566 * Fill out OperatingConfig related items in a Processor resource by requesting
567 * data from the given D-Bus object.
568 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700569 * @param[in,out] asyncResp Async HTTP response.
Jonathan Domandba0c292020-12-02 15:34:13 -0800570 * @param[in] cpuId CPU D-Bus name.
571 * @param[in] service D-Bus service to query.
572 * @param[in] objPath D-Bus object to query.
573 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700574inline void
575 getCpuConfigData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
576 const std::string& cpuId, const std::string& service,
577 const std::string& objPath)
Jonathan Domandba0c292020-12-02 15:34:13 -0800578{
Ed Tanous62598e32023-07-17 17:06:25 -0700579 BMCWEB_LOG_INFO("Getting CPU operating configs for {}", cpuId);
Jonathan Domandba0c292020-12-02 15:34:13 -0800580
581 // First, GetAll CurrentOperatingConfig properties on the object
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200582 sdbusplus::asio::getAllProperties(
583 *crow::connections::systemBus, service, objPath,
584 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig",
Ed Tanousac106bf2023-06-07 09:24:59 -0700585 [asyncResp, cpuId,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800586 service](const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200587 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400588 if (ec)
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200589 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400590 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
Ed Tanousac106bf2023-06-07 09:24:59 -0700591 messages::internalError(asyncResp->res);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200592 return;
593 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200594
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400595 nlohmann::json& json = asyncResp->res.jsonValue;
596
597 const sdbusplus::message::object_path* appliedConfig = nullptr;
598 const bool* baseSpeedPriorityEnabled = nullptr;
599
600 const bool success = sdbusplus::unpackPropertiesNoThrow(
601 dbus_utils::UnpackErrorPrinter(), properties, "AppliedConfig",
602 appliedConfig, "BaseSpeedPriorityEnabled",
603 baseSpeedPriorityEnabled);
604
605 if (!success)
606 {
607 messages::internalError(asyncResp->res);
608 return;
609 }
610
611 if (appliedConfig != nullptr)
612 {
613 const std::string& dbusPath = appliedConfig->str;
614 nlohmann::json::object_t operatingConfig;
615 operatingConfig["@odata.id"] = boost::urls::format(
616 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
617 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId);
618 json["OperatingConfigs"] = std::move(operatingConfig);
619
620 // Reuse the D-Bus config object name for the Redfish
621 // URI
622 size_t baseNamePos = dbusPath.rfind('/');
623 if (baseNamePos == std::string::npos ||
624 baseNamePos == (dbusPath.size() - 1))
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200625 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400626 // If the AppliedConfig was somehow not a valid path,
627 // skip adding any more properties, since everything
628 // else is tied to this applied config.
Ed Tanousac106bf2023-06-07 09:24:59 -0700629 messages::internalError(asyncResp->res);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200630 return;
631 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400632 nlohmann::json::object_t appliedOperatingConfig;
633 appliedOperatingConfig["@odata.id"] = boost::urls::format(
634 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}",
635 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId,
636 dbusPath.substr(baseNamePos + 1));
637 json["AppliedOperatingConfig"] =
638 std::move(appliedOperatingConfig);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200639
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400640 // Once we found the current applied config, queue another
641 // request to read the base freq core ids out of that
642 // config.
643 sdbusplus::asio::getProperty<BaseSpeedPrioritySettingsProperty>(
644 *crow::connections::systemBus, service, dbusPath,
645 "xyz.openbmc_project.Inventory.Item.Cpu."
646 "OperatingConfig",
647 "BaseSpeedPrioritySettings",
648 [asyncResp](const boost::system::error_code& ec2,
649 const BaseSpeedPrioritySettingsProperty&
650 baseSpeedList) {
651 if (ec2)
652 {
653 BMCWEB_LOG_WARNING("D-Bus Property Get error: {}",
654 ec2);
655 messages::internalError(asyncResp->res);
656 return;
657 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200658
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400659 highSpeedCoreIdsHandler(asyncResp, baseSpeedList);
660 });
661 }
662
663 if (baseSpeedPriorityEnabled != nullptr)
664 {
665 json["BaseSpeedPriorityState"] =
666 *baseSpeedPriorityEnabled ? "Enabled" : "Disabled";
667 }
668 });
Jonathan Domandba0c292020-12-02 15:34:13 -0800669}
670
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600671/**
672 * @brief Fill out location info of a processor by
673 * requesting data from the given D-Bus object.
674 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700675 * @param[in,out] asyncResp Async HTTP response.
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600676 * @param[in] service D-Bus service to query.
677 * @param[in] objPath D-Bus object to query.
678 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700679inline void getCpuLocationCode(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600680 const std::string& service,
681 const std::string& objPath)
682{
Ed Tanous62598e32023-07-17 17:06:25 -0700683 BMCWEB_LOG_DEBUG("Get Cpu Location Data");
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700684 sdbusplus::asio::getProperty<std::string>(
685 *crow::connections::systemBus, service, objPath,
686 "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
Ed Tanousac106bf2023-06-07 09:24:59 -0700687 [objPath, asyncResp{std::move(asyncResp)}](
688 const boost::system::error_code& ec, const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400689 if (ec)
690 {
691 BMCWEB_LOG_DEBUG("DBUS response error");
692 messages::internalError(asyncResp->res);
693 return;
694 }
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600695
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400696 asyncResp->res
697 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
698 property;
699 });
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600700}
701
Jonathan Domanc9514482021-02-24 09:20:51 -0800702/**
Jonathan Doman49e429c2021-03-03 13:11:44 -0800703 * Populate the unique identifier in a Processor resource by requesting data
704 * from the given D-Bus object.
705 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700706 * @param[in,out] asyncResp Async HTTP response.
Jonathan Doman49e429c2021-03-03 13:11:44 -0800707 * @param[in] service D-Bus service to query.
708 * @param[in] objPath D-Bus object to query.
709 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700710inline void getCpuUniqueId(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman49e429c2021-03-03 13:11:44 -0800711 const std::string& service,
712 const std::string& objectPath)
713{
Ed Tanous62598e32023-07-17 17:06:25 -0700714 BMCWEB_LOG_DEBUG("Get CPU UniqueIdentifier");
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700715 sdbusplus::asio::getProperty<std::string>(
716 *crow::connections::systemBus, service, objectPath,
717 "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier",
718 "UniqueIdentifier",
Ed Tanousac106bf2023-06-07 09:24:59 -0700719 [asyncResp](const boost::system::error_code& ec,
720 const std::string& id) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400721 if (ec)
722 {
723 BMCWEB_LOG_ERROR("Failed to read cpu unique id: {}", ec);
724 messages::internalError(asyncResp->res);
725 return;
726 }
727 asyncResp->res
728 .jsonValue["ProcessorId"]["ProtectedIdentificationNumber"] = id;
729 });
Jonathan Doman49e429c2021-03-03 13:11:44 -0800730}
731
732/**
Jonathan Domanc9514482021-02-24 09:20:51 -0800733 * Find the D-Bus object representing the requested Processor, and call the
734 * handler with the results. If matching object is not found, add 404 error to
735 * response and don't call the handler.
736 *
737 * @param[in,out] resp Async HTTP response.
738 * @param[in] processorId Redfish Processor Id.
739 * @param[in] handler Callback to continue processing request upon
740 * successfully finding object.
741 */
742template <typename Handler>
zhanghch058d1b46d2021-04-01 11:18:24 +0800743inline void getProcessorObject(const std::shared_ptr<bmcweb::AsyncResp>& resp,
Jonathan Domanc9514482021-02-24 09:20:51 -0800744 const std::string& processorId,
745 Handler&& handler)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500746{
Ed Tanous62598e32023-07-17 17:06:25 -0700747 BMCWEB_LOG_DEBUG("Get available system processor resources.");
Gunnar Millsac6a4442020-10-14 14:55:29 -0500748
Jonathan Domanc9514482021-02-24 09:20:51 -0800749 // GetSubTree on all interfaces which provide info about a Processor
Chris Caindfbf7de2023-04-13 16:01:04 -0500750 constexpr std::array<std::string_view, 9> interfaces = {
George Liue99073f2022-12-09 11:06:16 +0800751 "xyz.openbmc_project.Common.UUID",
752 "xyz.openbmc_project.Inventory.Decorator.Asset",
753 "xyz.openbmc_project.Inventory.Decorator.Revision",
754 "xyz.openbmc_project.Inventory.Item.Cpu",
755 "xyz.openbmc_project.Inventory.Decorator.LocationCode",
756 "xyz.openbmc_project.Inventory.Item.Accelerator",
757 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig",
Chris Caindfbf7de2023-04-13 16:01:04 -0500758 "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier",
759 "xyz.openbmc_project.Control.Power.Throttle"};
George Liue99073f2022-12-09 11:06:16 +0800760 dbus::utility::getSubTree(
761 "/xyz/openbmc_project/inventory", 0, interfaces,
Jonathan Domanc9514482021-02-24 09:20:51 -0800762 [resp, processorId, handler = std::forward<Handler>(handler)](
George Liue99073f2022-12-09 11:06:16 +0800763 const boost::system::error_code& ec,
764 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400765 if (ec)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500766 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400767 BMCWEB_LOG_DEBUG("DBUS response error: {}", ec);
768 messages::internalError(resp->res);
769 return;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500770 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400771 for (const auto& [objectPath, serviceMap] : subtree)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500772 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400773 // Ignore any objects which don't end with our desired cpu name
774 if (!objectPath.ends_with(processorId))
Gunnar Millsac6a4442020-10-14 14:55:29 -0500775 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400776 continue;
Jonathan Doman2bab9832020-12-02 15:27:40 -0800777 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400778
779 bool found = false;
780 // Filter out objects that don't have the CPU-specific
781 // interfaces to make sure we can return 404 on non-CPUs
782 // (e.g. /redfish/../Processors/dimm0)
783 for (const auto& [serviceName, interfaceList] : serviceMap)
784 {
785 if (std::ranges::find_first_of(interfaceList,
786 processorInterfaces) !=
787 std::end(interfaceList))
788 {
789 found = true;
790 break;
791 }
792 }
793
794 if (!found)
795 {
796 continue;
797 }
798
799 // Process the first object which does match our cpu name and
800 // required interfaces, and potentially ignore any other
801 // matching objects. Assume all interfaces we want to process
802 // must be on the same object path.
803
804 handler(objectPath, serviceMap);
805 return;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500806 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400807 messages::resourceNotFound(resp->res, "Processor", processorId);
808 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500809}
810
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400811inline void getProcessorData(
812 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
813 const std::string& processorId, const std::string& objectPath,
814 const dbus::utility::MapperServiceMap& serviceMap)
Jonathan Domanc9514482021-02-24 09:20:51 -0800815{
816 for (const auto& [serviceName, interfaceList] : serviceMap)
817 {
818 for (const auto& interface : interfaceList)
819 {
820 if (interface == "xyz.openbmc_project.Inventory.Decorator.Asset")
821 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700822 getCpuAssetData(asyncResp, serviceName, objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800823 }
George Liu0fda0f12021-11-16 10:06:17 +0800824 else if (interface ==
825 "xyz.openbmc_project.Inventory.Decorator.Revision")
Jonathan Domanc9514482021-02-24 09:20:51 -0800826 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700827 getCpuRevisionData(asyncResp, serviceName, objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800828 }
829 else if (interface == "xyz.openbmc_project.Inventory.Item.Cpu")
830 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700831 getCpuDataByService(asyncResp, processorId, serviceName,
Jonathan Domanc9514482021-02-24 09:20:51 -0800832 objectPath);
833 }
George Liu0fda0f12021-11-16 10:06:17 +0800834 else if (interface ==
835 "xyz.openbmc_project.Inventory.Item.Accelerator")
Jonathan Domanc9514482021-02-24 09:20:51 -0800836 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700837 getAcceleratorDataByService(asyncResp, processorId, serviceName,
Jonathan Domanc9514482021-02-24 09:20:51 -0800838 objectPath);
839 }
George Liu0fda0f12021-11-16 10:06:17 +0800840 else if (
841 interface ==
842 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig")
Jonathan Domanc9514482021-02-24 09:20:51 -0800843 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700844 getCpuConfigData(asyncResp, processorId, serviceName,
845 objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800846 }
George Liu0fda0f12021-11-16 10:06:17 +0800847 else if (interface ==
848 "xyz.openbmc_project.Inventory.Decorator.LocationCode")
Jonathan Domanc9514482021-02-24 09:20:51 -0800849 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700850 getCpuLocationCode(asyncResp, serviceName, objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800851 }
Sharad Yadav71b82f22021-05-10 15:11:39 +0530852 else if (interface == "xyz.openbmc_project.Common.UUID")
853 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700854 getProcessorUUID(asyncResp, serviceName, objectPath);
Sharad Yadav71b82f22021-05-10 15:11:39 +0530855 }
George Liu0fda0f12021-11-16 10:06:17 +0800856 else if (interface ==
857 "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier")
Jonathan Doman49e429c2021-03-03 13:11:44 -0800858 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700859 getCpuUniqueId(asyncResp, serviceName, objectPath);
Jonathan Doman49e429c2021-03-03 13:11:44 -0800860 }
Chris Caindfbf7de2023-04-13 16:01:04 -0500861 else if (interface == "xyz.openbmc_project.Control.Power.Throttle")
862 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700863 getThrottleProperties(asyncResp, serviceName, objectPath);
Chris Caindfbf7de2023-04-13 16:01:04 -0500864 }
Jonathan Domanc9514482021-02-24 09:20:51 -0800865 }
866 }
867}
868
Jonathan Domandba0c292020-12-02 15:34:13 -0800869/**
870 * Request all the properties for the given D-Bus object and fill out the
871 * related entries in the Redfish OperatingConfig response.
872 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700873 * @param[in,out] asyncResp Async HTTP response.
Jonathan Domandba0c292020-12-02 15:34:13 -0800874 * @param[in] service D-Bus service name to query.
875 * @param[in] objPath D-Bus object to query.
876 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400877inline void getOperatingConfigData(
878 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
879 const std::string& service, const std::string& objPath)
Jonathan Domandba0c292020-12-02 15:34:13 -0800880{
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200881 sdbusplus::asio::getAllProperties(
882 *crow::connections::systemBus, service, objPath,
883 "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig",
Ed Tanousac106bf2023-06-07 09:24:59 -0700884 [asyncResp](const boost::system::error_code& ec,
885 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400886 if (ec)
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200887 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400888 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
889 messages::internalError(asyncResp->res);
890 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700891 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200892
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400893 const size_t* availableCoreCount = nullptr;
894 const uint32_t* baseSpeed = nullptr;
895 const uint32_t* maxJunctionTemperature = nullptr;
896 const uint32_t* maxSpeed = nullptr;
897 const uint32_t* powerLimit = nullptr;
898 const TurboProfileProperty* turboProfile = nullptr;
899 const BaseSpeedPrioritySettingsProperty* baseSpeedPrioritySettings =
900 nullptr;
901
902 const bool success = sdbusplus::unpackPropertiesNoThrow(
903 dbus_utils::UnpackErrorPrinter(), properties,
904 "AvailableCoreCount", availableCoreCount, "BaseSpeed",
905 baseSpeed, "MaxJunctionTemperature", maxJunctionTemperature,
906 "MaxSpeed", maxSpeed, "PowerLimit", powerLimit, "TurboProfile",
907 turboProfile, "BaseSpeedPrioritySettings",
908 baseSpeedPrioritySettings);
909
910 if (!success)
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200911 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400912 messages::internalError(asyncResp->res);
913 return;
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200914 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400915
916 nlohmann::json& json = asyncResp->res.jsonValue;
917
918 if (availableCoreCount != nullptr)
919 {
920 json["TotalAvailableCoreCount"] = *availableCoreCount;
921 }
922
923 if (baseSpeed != nullptr)
924 {
925 json["BaseSpeedMHz"] = *baseSpeed;
926 }
927
928 if (maxJunctionTemperature != nullptr)
929 {
930 json["MaxJunctionTemperatureCelsius"] = *maxJunctionTemperature;
931 }
932
933 if (maxSpeed != nullptr)
934 {
935 json["MaxSpeedMHz"] = *maxSpeed;
936 }
937
938 if (powerLimit != nullptr)
939 {
940 json["TDPWatts"] = *powerLimit;
941 }
942
943 if (turboProfile != nullptr)
944 {
945 nlohmann::json& turboArray = json["TurboProfile"];
946 turboArray = nlohmann::json::array();
947 for (const auto& [turboSpeed, coreCount] : *turboProfile)
948 {
949 nlohmann::json::object_t turbo;
950 turbo["ActiveCoreCount"] = coreCount;
951 turbo["MaxSpeedMHz"] = turboSpeed;
952 turboArray.emplace_back(std::move(turbo));
953 }
954 }
955
956 if (baseSpeedPrioritySettings != nullptr)
957 {
958 nlohmann::json& baseSpeedArray =
959 json["BaseSpeedPrioritySettings"];
960 baseSpeedArray = nlohmann::json::array();
961 for (const auto& [baseSpeedMhz, coreList] :
962 *baseSpeedPrioritySettings)
963 {
964 nlohmann::json::object_t speed;
965 speed["CoreCount"] = coreList.size();
966 speed["CoreIDs"] = coreList;
967 speed["BaseSpeedMHz"] = baseSpeedMhz;
968 baseSpeedArray.emplace_back(std::move(speed));
969 }
970 }
971 });
Jonathan Domandba0c292020-12-02 15:34:13 -0800972}
973
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800974/**
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800975 * Handle the PATCH operation of the AppliedOperatingConfig property. Do basic
976 * validation of the input data, and then set the D-Bus property.
977 *
978 * @param[in,out] resp Async HTTP response.
979 * @param[in] processorId Processor's Id.
980 * @param[in] appliedConfigUri New property value to apply.
981 * @param[in] cpuObjectPath Path of CPU object to modify.
982 * @param[in] serviceMap Service map for CPU object.
983 */
984inline void patchAppliedOperatingConfig(
985 const std::shared_ptr<bmcweb::AsyncResp>& resp,
986 const std::string& processorId, const std::string& appliedConfigUri,
Shantappa Teekappanavar5df6eda2022-01-18 12:29:28 -0600987 const std::string& cpuObjectPath,
988 const dbus::utility::MapperServiceMap& serviceMap)
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800989{
990 // Check that the property even exists by checking for the interface
991 const std::string* controlService = nullptr;
992 for (const auto& [serviceName, interfaceList] : serviceMap)
993 {
Ed Tanous3544d2a2023-08-06 18:12:20 -0700994 if (std::ranges::find(interfaceList,
995 "xyz.openbmc_project.Control.Processor."
996 "CurrentOperatingConfig") != interfaceList.end())
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800997 {
998 controlService = &serviceName;
999 break;
1000 }
1001 }
1002
1003 if (controlService == nullptr)
1004 {
1005 messages::internalError(resp->res);
1006 return;
1007 }
1008
1009 // Check that the config URI is a child of the cpu URI being patched.
Ed Tanous253f11b2024-05-16 09:38:31 -07001010 std::string expectedPrefix(std::format("/redfish/v1/Systems/{}/Processors/",
1011 BMCWEB_REDFISH_SYSTEM_URI_NAME));
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001012 expectedPrefix += processorId;
1013 expectedPrefix += "/OperatingConfigs/";
Ed Tanous11ba3972022-07-11 09:50:41 -07001014 if (!appliedConfigUri.starts_with(expectedPrefix) ||
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001015 expectedPrefix.size() == appliedConfigUri.size())
1016 {
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001017 messages::propertyValueIncorrect(resp->res, "AppliedOperatingConfig",
1018 appliedConfigUri);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001019 return;
1020 }
1021
1022 // Generate the D-Bus path of the OperatingConfig object, by assuming it's a
1023 // direct child of the CPU object.
1024 // Strip the expectedPrefix from the config URI to get the "filename", and
1025 // append to the CPU's path.
1026 std::string configBaseName = appliedConfigUri.substr(expectedPrefix.size());
1027 sdbusplus::message::object_path configPath(cpuObjectPath);
1028 configPath /= configBaseName;
1029
Ed Tanous62598e32023-07-17 17:06:25 -07001030 BMCWEB_LOG_INFO("Setting config to {}", configPath.str);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001031
1032 // Set the property, with handler to check error responses
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001033 setDbusProperty(
Ginu Georgee93abac2024-06-14 17:35:27 +05301034 resp, "AppliedOperatingConfig", *controlService, cpuObjectPath,
George Liu9ae226f2023-06-21 17:56:46 +08001035 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig",
Ginu Georgee93abac2024-06-14 17:35:27 +05301036 "AppliedConfig", configPath);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001037}
1038
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001039inline void handleProcessorHead(
1040 crow::App& app, const crow::Request& req,
1041 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1042 const std::string& /* systemName */, const std::string& /* processorId */)
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001043{
Ed Tanousac106bf2023-06-07 09:24:59 -07001044 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001045 {
1046 return;
1047 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001048 asyncResp->res.addHeader(
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001049 boost::beast::http::field::link,
1050 "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
1051}
1052
1053inline void handleProcessorCollectionHead(
1054 crow::App& app, const crow::Request& req,
Ed Tanousac106bf2023-06-07 09:24:59 -07001055 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001056 const std::string& /* systemName */)
1057{
Ed Tanousac106bf2023-06-07 09:24:59 -07001058 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001059 {
1060 return;
1061 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001062 asyncResp->res.addHeader(
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001063 boost::beast::http::field::link,
1064 "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
1065}
1066
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001067inline void requestRoutesOperatingConfigCollection(App& app)
Jonathan Domandba0c292020-12-02 15:34:13 -08001068{
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001069 BMCWEB_ROUTE(app,
1070 "/redfish/v1/Systems/<str>/Processors/<str>/OperatingConfigs/")
Ed Tanoused398212021-06-09 17:05:54 -07001071 .privileges(redfish::privileges::getOperatingConfigCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001072 .methods(
1073 boost::beast::http::verb::
1074 get)([&app](const crow::Request& req,
1075 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1076 const std::string& systemName,
1077 const std::string& cpuName) {
1078 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -07001079 {
1080 return;
1081 }
Jonathan Domandba0c292020-12-02 15:34:13 -08001082
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001083 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07001084 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001085 // Option currently returns no systems. TBD
1086 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1087 systemName);
Ed Tanous002d39b2022-05-31 08:59:27 -07001088 return;
1089 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001090
1091 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1092 {
1093 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1094 systemName);
1095 return;
1096 }
1097 asyncResp->res.jsonValue["@odata.type"] =
1098 "#OperatingConfigCollection.OperatingConfigCollection";
1099 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1100 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
1101 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName);
1102 asyncResp->res.jsonValue["Name"] = "Operating Config Collection";
1103
1104 // First find the matching CPU object so we know how to
1105 // constrain our search for related Config objects.
1106 const std::array<std::string_view, 1> interfaces = {
1107 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig"};
1108 dbus::utility::getSubTreePaths(
1109 "/xyz/openbmc_project/inventory", 0, interfaces,
1110 [asyncResp,
1111 cpuName](const boost::system::error_code& ec,
1112 const dbus::utility::MapperGetSubTreePathsResponse&
1113 objects) {
1114 if (ec)
1115 {
1116 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec,
1117 ec.message());
1118 messages::internalError(asyncResp->res);
1119 return;
1120 }
1121
1122 for (const std::string& object : objects)
1123 {
1124 if (!object.ends_with(cpuName))
1125 {
1126 continue;
1127 }
1128
1129 // Not expected that there will be multiple matching
1130 // CPU objects, but if there are just use the first
1131 // one.
1132
1133 // Use the common search routine to construct the
1134 // Collection of all Config objects under this CPU.
1135 constexpr std::array<std::string_view, 1> interface{
1136 "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
1137 collection_util::getCollectionMembers(
1138 asyncResp,
1139 boost::urls::format(
1140 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
1141 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName),
1142 interface, object);
1143 return;
1144 }
1145 });
George Liu0fda0f12021-11-16 10:06:17 +08001146 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001147}
1148
1149inline void requestRoutesOperatingConfig(App& app)
1150{
1151 BMCWEB_ROUTE(
1152 app,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001153 "/redfish/v1/Systems/<str>/Processors/<str>/OperatingConfigs/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001154 .privileges(redfish::privileges::getOperatingConfig)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001155 .methods(
1156 boost::beast::http::verb::
1157 get)([&app](const crow::Request& req,
1158 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1159 const std::string& systemName,
1160 const std::string& cpuName,
1161 const std::string& configName) {
1162 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -07001163 {
1164 return;
1165 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001166 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07001167 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001168 // Option currently returns no systems. TBD
1169 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1170 systemName);
Ed Tanous002d39b2022-05-31 08:59:27 -07001171 return;
1172 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001173
1174 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1175 {
1176 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1177 systemName);
1178 return;
1179 }
1180 // Ask for all objects implementing OperatingConfig so we can search
1181 // for one with a matching name
1182 constexpr std::array<std::string_view, 1> interfaces = {
1183 "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
1184 dbus::utility::getSubTree(
1185 "/xyz/openbmc_project/inventory", 0, interfaces,
1186 [asyncResp, cpuName, configName](
1187 const boost::system::error_code& ec,
1188 const dbus::utility::MapperGetSubTreeResponse& subtree) {
1189 if (ec)
1190 {
1191 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec,
1192 ec.message());
1193 messages::internalError(asyncResp->res);
1194 return;
1195 }
1196 const std::string expectedEnding =
1197 cpuName + '/' + configName;
1198 for (const auto& [objectPath, serviceMap] : subtree)
1199 {
1200 // Ignore any configs without matching cpuX/configY
1201 if (!objectPath.ends_with(expectedEnding) ||
1202 serviceMap.empty())
1203 {
1204 continue;
1205 }
1206
1207 nlohmann::json& json = asyncResp->res.jsonValue;
1208 json["@odata.type"] =
1209 "#OperatingConfig.v1_0_0.OperatingConfig";
1210 json["@odata.id"] = boost::urls::format(
1211 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}",
1212 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName,
1213 configName);
1214 json["Name"] = "Processor Profile";
1215 json["Id"] = configName;
1216
1217 // Just use the first implementation of the object - not
1218 // expected that there would be multiple matching
1219 // services
1220 getOperatingConfigData(
1221 asyncResp, serviceMap.begin()->first, objectPath);
1222 return;
1223 }
1224 messages::resourceNotFound(asyncResp->res,
1225 "OperatingConfig", configName);
1226 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001227 });
1228}
Jonathan Domandba0c292020-12-02 15:34:13 -08001229
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001230inline void requestRoutesProcessorCollection(App& app)
Gunnar Millsac6a4442020-10-14 14:55:29 -05001231{
Gunnar Millsac6a4442020-10-14 14:55:29 -05001232 /**
1233 * Functions triggers appropriate requests on DBus
1234 */
Ed Tanous22d268c2022-05-19 09:39:07 -07001235 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/")
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001236 .privileges(redfish::privileges::headProcessorCollection)
1237 .methods(boost::beast::http::verb::head)(
1238 std::bind_front(handleProcessorCollectionHead, std::ref(app)));
1239
1240 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/")
Ed Tanoused398212021-06-09 17:05:54 -07001241 .privileges(redfish::privileges::getProcessorCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001242 .methods(
1243 boost::beast::http::verb::
1244 get)([&app](const crow::Request& req,
1245 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1246 const std::string& systemName) {
1247 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1248 {
1249 return;
1250 }
1251 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1252 {
1253 // Option currently returns no systems. TBD
1254 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1255 systemName);
1256 return;
1257 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001258
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001259 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1260 {
1261 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1262 systemName);
1263 return;
1264 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001265
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001266 asyncResp->res.addHeader(
1267 boost::beast::http::field::link,
1268 "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001269
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001270 asyncResp->res.jsonValue["@odata.type"] =
1271 "#ProcessorCollection.ProcessorCollection";
1272 asyncResp->res.jsonValue["Name"] = "Processor Collection";
Gunnar Millsac6a4442020-10-14 14:55:29 -05001273
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001274 asyncResp->res.jsonValue["@odata.id"] =
1275 std::format("/redfish/v1/Systems/{}/Processors",
1276 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Gunnar Millsac6a4442020-10-14 14:55:29 -05001277
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001278 collection_util::getCollectionMembers(
1279 asyncResp,
1280 boost::urls::format("/redfish/v1/Systems/{}/Processors",
1281 BMCWEB_REDFISH_SYSTEM_URI_NAME),
1282 processorInterfaces, "/xyz/openbmc_project/inventory");
1283 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001284}
Gunnar Millsac6a4442020-10-14 14:55:29 -05001285
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001286inline void requestRoutesProcessor(App& app)
Gunnar Millsac6a4442020-10-14 14:55:29 -05001287{
Gunnar Millsac6a4442020-10-14 14:55:29 -05001288 /**
1289 * Functions triggers appropriate requests on DBus
1290 */
Gunnar Millsac6a4442020-10-14 14:55:29 -05001291
Ed Tanous22d268c2022-05-19 09:39:07 -07001292 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001293 .privileges(redfish::privileges::headProcessor)
1294 .methods(boost::beast::http::verb::head)(
1295 std::bind_front(handleProcessorHead, std::ref(app)));
1296
1297 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001298 .privileges(redfish::privileges::getProcessor)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001299 .methods(
1300 boost::beast::http::verb::
1301 get)([&app](const crow::Request& req,
1302 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1303 const std::string& systemName,
1304 const std::string& processorId) {
1305 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1306 {
1307 return;
1308 }
1309 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1310 {
1311 // Option currently returns no systems. TBD
1312 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1313 systemName);
1314 return;
1315 }
1316 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1317 {
1318 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1319 systemName);
1320 return;
1321 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001322
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001323 asyncResp->res.addHeader(
1324 boost::beast::http::field::link,
1325 "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
1326 asyncResp->res.jsonValue["@odata.type"] =
1327 "#Processor.v1_18_0.Processor";
1328 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1329 "/redfish/v1/Systems/{}/Processors/{}",
1330 BMCWEB_REDFISH_SYSTEM_URI_NAME, processorId);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001331
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001332 getProcessorObject(
1333 asyncResp, processorId,
1334 std::bind_front(getProcessorData, asyncResp, processorId));
1335 });
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001336
Ed Tanous22d268c2022-05-19 09:39:07 -07001337 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001338 .privileges(redfish::privileges::patchProcessor)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001339 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001340 [&app](const crow::Request& req,
1341 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001342 const std::string& systemName,
Ed Tanous45ca1b82022-03-25 13:07:27 -07001343 const std::string& processorId) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001344 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1345 {
1346 return;
1347 }
1348 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1349 {
1350 // Option currently returns no systems. TBD
1351 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1352 systemName);
1353 return;
1354 }
1355 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1356 {
1357 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1358 systemName);
1359 return;
1360 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001361
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001362 std::optional<std::string> appliedConfigUri;
1363 if (!json_util::readJsonPatch(
Myung Baeafc474a2024-10-09 00:53:29 -07001364 req, asyncResp->res, //
1365 "AppliedOperatingConfig/@odata.id", appliedConfigUri //
1366 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001367 {
1368 return;
1369 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001370
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001371 if (appliedConfigUri)
1372 {
1373 // Check for 404 and find matching D-Bus object, then run
1374 // property patch handlers if that all succeeds.
1375 getProcessorObject(
1376 asyncResp, processorId,
1377 std::bind_front(patchAppliedOperatingConfig, asyncResp,
1378 processorId, *appliedConfigUri));
1379 }
1380 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001381}
Gunnar Millsac6a4442020-10-14 14:55:29 -05001382
1383} // namespace redfish