blob: d0893812604c8fe517ee6c32a9bb8ccf0e7cb893 [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");
Ed Tanousdeae6a72024-11-11 21:58:57 -080065 dbus::utility::getProperty<std::string>(
66 service, objPath, "xyz.openbmc_project.Common.UUID", "UUID",
Ed Tanousac106bf2023-06-07 09:24:59 -070067 [objPath, asyncResp{std::move(asyncResp)}](
68 const boost::system::error_code& ec, const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040069 if (ec)
70 {
71 BMCWEB_LOG_DEBUG("DBUS response error");
72 messages::internalError(asyncResp->res);
73 return;
74 }
75 asyncResp->res.jsonValue["UUID"] = property;
76 });
Sharad Yadav71b82f22021-05-10 15:11:39 +053077}
78
Ed Tanous711ac7a2021-12-20 09:34:41 -080079inline void getCpuDataByInterface(
Ed Tanousac106bf2023-06-07 09:24:59 -070080 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Michael Shen80f79a42023-08-24 13:41:53 +000081 const dbus::utility::DBusInterfacesMap& cpuInterfacesProperties)
Gunnar Millsac6a4442020-10-14 14:55:29 -050082{
Ed Tanous62598e32023-07-17 17:06:25 -070083 BMCWEB_LOG_DEBUG("Get CPU resources by interface.");
Gunnar Millsac6a4442020-10-14 14:55:29 -050084
Chicago Duana1649ec2021-03-30 16:54:58 +080085 // Set the default value of state
Ed Tanous539d8c62024-06-19 14:38:27 -070086 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
87 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
Gunnar Millsac6a4442020-10-14 14:55:29 -050088
89 for (const auto& interface : cpuInterfacesProperties)
90 {
91 for (const auto& property : interface.second)
92 {
Chicago Duana1649ec2021-03-30 16:54:58 +080093 if (property.first == "Present")
Gunnar Millsac6a4442020-10-14 14:55:29 -050094 {
Chicago Duana1649ec2021-03-30 16:54:58 +080095 const bool* cpuPresent = std::get_if<bool>(&property.second);
96 if (cpuPresent == nullptr)
Gunnar Millsac6a4442020-10-14 14:55:29 -050097 {
98 // Important property not in desired type
Ed Tanousac106bf2023-06-07 09:24:59 -070099 messages::internalError(asyncResp->res);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500100 return;
101 }
Ed Tanouse05aec52022-01-25 10:28:56 -0800102 if (!*cpuPresent)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500103 {
Chicago Duana1649ec2021-03-30 16:54:58 +0800104 // Slot is not populated
Ed Tanous539d8c62024-06-19 14:38:27 -0700105 asyncResp->res.jsonValue["Status"]["State"] =
106 resource::State::Absent;
Chicago Duana1649ec2021-03-30 16:54:58 +0800107 }
108 }
109 else if (property.first == "Functional")
110 {
111 const bool* cpuFunctional = std::get_if<bool>(&property.second);
112 if (cpuFunctional == nullptr)
113 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700114 messages::internalError(asyncResp->res);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500115 return;
116 }
Ed Tanouse05aec52022-01-25 10:28:56 -0800117 if (!*cpuFunctional)
Chicago Duana1649ec2021-03-30 16:54:58 +0800118 {
Ed Tanous539d8c62024-06-19 14:38:27 -0700119 asyncResp->res.jsonValue["Status"]["Health"] =
120 resource::Health::Critical;
Chicago Duana1649ec2021-03-30 16:54:58 +0800121 }
122 }
123 else if (property.first == "CoreCount")
124 {
125 const uint16_t* coresCount =
126 std::get_if<uint16_t>(&property.second);
127 if (coresCount == nullptr)
128 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700129 messages::internalError(asyncResp->res);
Chicago Duana1649ec2021-03-30 16:54:58 +0800130 return;
131 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700132 asyncResp->res.jsonValue["TotalCores"] = *coresCount;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500133 }
Jonathan Domandc3fa662020-10-26 23:10:24 -0700134 else if (property.first == "MaxSpeedInMhz")
135 {
136 const uint32_t* value = std::get_if<uint32_t>(&property.second);
137 if (value != nullptr)
138 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700139 asyncResp->res.jsonValue["MaxSpeedMHz"] = *value;
Jonathan Domandc3fa662020-10-26 23:10:24 -0700140 }
141 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500142 else if (property.first == "Socket")
143 {
144 const std::string* value =
145 std::get_if<std::string>(&property.second);
146 if (value != nullptr)
147 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700148 asyncResp->res.jsonValue["Socket"] = *value;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500149 }
150 }
151 else if (property.first == "ThreadCount")
152 {
Jonathan Domandc3fa662020-10-26 23:10:24 -0700153 const uint16_t* value = std::get_if<uint16_t>(&property.second);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500154 if (value != nullptr)
155 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700156 asyncResp->res.jsonValue["TotalThreads"] = *value;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500157 }
158 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700159 else if (property.first == "EffectiveFamily")
Gunnar Millsac6a4442020-10-14 14:55:29 -0500160 {
Brandon Kim1930fbd2021-09-14 17:52:51 -0700161 const uint16_t* value = std::get_if<uint16_t>(&property.second);
Brad Bishop6169de22022-09-14 13:08:32 -0400162 if (value != nullptr && *value != 2)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500163 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700164 asyncResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] =
Ed Tanous866e4862022-02-17 11:40:25 -0800165 "0x" + intToHexString(*value, 4);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500166 }
167 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700168 else if (property.first == "EffectiveModel")
169 {
170 const uint16_t* value = std::get_if<uint16_t>(&property.second);
171 if (value == nullptr)
172 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700173 messages::internalError(asyncResp->res);
Brandon Kim1930fbd2021-09-14 17:52:51 -0700174 return;
175 }
Brad Bishop6169de22022-09-14 13:08:32 -0400176 if (*value != 0)
177 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700178 asyncResp->res.jsonValue["ProcessorId"]["EffectiveModel"] =
Brad Bishop6169de22022-09-14 13:08:32 -0400179 "0x" + intToHexString(*value, 4);
180 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700181 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500182 else if (property.first == "Id")
183 {
184 const uint64_t* value = std::get_if<uint64_t>(&property.second);
185 if (value != nullptr && *value != 0)
186 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700187 asyncResp->res
Gunnar Millsac6a4442020-10-14 14:55:29 -0500188 .jsonValue["ProcessorId"]["IdentificationRegisters"] =
Ed Tanous866e4862022-02-17 11:40:25 -0800189 "0x" + intToHexString(*value, 16);
Gunnar Millsac6a4442020-10-14 14:55:29 -0500190 }
191 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700192 else if (property.first == "Microcode")
193 {
194 const uint32_t* value = std::get_if<uint32_t>(&property.second);
195 if (value == nullptr)
196 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700197 messages::internalError(asyncResp->res);
Brandon Kim1930fbd2021-09-14 17:52:51 -0700198 return;
199 }
Brad Bishop6169de22022-09-14 13:08:32 -0400200 if (*value != 0)
201 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700202 asyncResp->res.jsonValue["ProcessorId"]["MicrocodeInfo"] =
Brad Bishop6169de22022-09-14 13:08:32 -0400203 "0x" + intToHexString(*value, 8);
204 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700205 }
206 else if (property.first == "Step")
207 {
208 const uint16_t* value = std::get_if<uint16_t>(&property.second);
209 if (value == nullptr)
210 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700211 messages::internalError(asyncResp->res);
Brandon Kim1930fbd2021-09-14 17:52:51 -0700212 return;
213 }
Michael Shenb9d679d2023-02-13 02:29:04 +0000214 if (*value != std::numeric_limits<uint16_t>::max())
Brad Bishop6169de22022-09-14 13:08:32 -0400215 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700216 asyncResp->res.jsonValue["ProcessorId"]["Step"] =
Brad Bishop6169de22022-09-14 13:08:32 -0400217 "0x" + intToHexString(*value, 4);
218 }
Brandon Kim1930fbd2021-09-14 17:52:51 -0700219 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500220 }
221 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500222}
223
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400224inline void getCpuDataByService(
225 std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& cpuId,
226 const std::string& service, const std::string& objPath)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500227{
Ed Tanous62598e32023-07-17 17:06:25 -0700228 BMCWEB_LOG_DEBUG("Get available system cpu resources by service.");
Gunnar Millsac6a4442020-10-14 14:55:29 -0500229
George Liu5eb468d2023-06-20 17:03:24 +0800230 sdbusplus::message::object_path path("/xyz/openbmc_project/inventory");
231 dbus::utility::getManagedObjects(
232 service, path,
Ed Tanousac106bf2023-06-07 09:24:59 -0700233 [cpuId, service, objPath, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800234 const boost::system::error_code& ec,
Gunnar Millsac6a4442020-10-14 14:55:29 -0500235 const dbus::utility::ManagedObjectType& dbusData) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400236 if (ec)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500237 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400238 BMCWEB_LOG_DEBUG("DBUS response error");
239 messages::internalError(asyncResp->res);
240 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700241 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400242 asyncResp->res.jsonValue["Id"] = cpuId;
243 asyncResp->res.jsonValue["Name"] = "Processor";
244 asyncResp->res.jsonValue["ProcessorType"] =
245 processor::ProcessorType::CPU;
246
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400247 for (const auto& object : dbusData)
Ed Tanous002d39b2022-05-31 08:59:27 -0700248 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400249 if (object.first.str == objPath)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500250 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400251 getCpuDataByInterface(asyncResp, object.second);
252 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400253 }
254 return;
255 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500256}
257
Chris Caindfbf7de2023-04-13 16:01:04 -0500258/**
259 * @brief Translates throttle cause DBUS property to redfish.
260 *
261 * @param[in] dbusSource The throttle cause from DBUS
262 *
263 * @return Returns as a string, the throttle cause in Redfish terms. If
264 * translation cannot be done, returns "Unknown" throttle reason.
265 */
266inline processor::ThrottleCause
267 dbusToRfThrottleCause(const std::string& dbusSource)
268{
269 if (dbusSource ==
270 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ClockLimit")
271 {
272 return processor::ThrottleCause::ClockLimit;
273 }
274 if (dbusSource ==
275 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ManagementDetectedFault")
276 {
277 return processor::ThrottleCause::ManagementDetectedFault;
278 }
279 if (dbusSource ==
280 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.PowerLimit")
281 {
282 return processor::ThrottleCause::PowerLimit;
283 }
284 if (dbusSource ==
285 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ThermalLimit")
286 {
287 return processor::ThrottleCause::ThermalLimit;
288 }
289 if (dbusSource ==
290 "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.Unknown")
291 {
292 return processor::ThrottleCause::Unknown;
293 }
294 return processor::ThrottleCause::Invalid;
295}
296
297inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700298 readThrottleProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Caindfbf7de2023-04-13 16:01:04 -0500299 const boost::system::error_code& ec,
300 const dbus::utility::DBusPropertiesMap& properties)
301{
302 if (ec)
303 {
Ed Tanous62598e32023-07-17 17:06:25 -0700304 BMCWEB_LOG_ERROR("Processor Throttle getAllProperties error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700305 messages::internalError(asyncResp->res);
Chris Caindfbf7de2023-04-13 16:01:04 -0500306 return;
307 }
308
309 const bool* status = nullptr;
310 const std::vector<std::string>* causes = nullptr;
311
312 if (!sdbusplus::unpackPropertiesNoThrow(dbus_utils::UnpackErrorPrinter(),
313 properties, "Throttled", status,
314 "ThrottleCauses", causes))
315 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700316 messages::internalError(asyncResp->res);
Chris Caindfbf7de2023-04-13 16:01:04 -0500317 return;
318 }
319
Ed Tanousac106bf2023-06-07 09:24:59 -0700320 asyncResp->res.jsonValue["Throttled"] = *status;
Chris Caindfbf7de2023-04-13 16:01:04 -0500321 nlohmann::json::array_t rCauses;
322 for (const std::string& cause : *causes)
323 {
324 processor::ThrottleCause rfCause = dbusToRfThrottleCause(cause);
325 if (rfCause == processor::ThrottleCause::Invalid)
326 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700327 messages::internalError(asyncResp->res);
Chris Caindfbf7de2023-04-13 16:01:04 -0500328 return;
329 }
330
331 rCauses.emplace_back(rfCause);
332 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700333 asyncResp->res.jsonValue["ThrottleCauses"] = std::move(rCauses);
Chris Caindfbf7de2023-04-13 16:01:04 -0500334}
335
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400336inline void getThrottleProperties(
337 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
338 const std::string& service, const std::string& objectPath)
Chris Caindfbf7de2023-04-13 16:01:04 -0500339{
Ed Tanous62598e32023-07-17 17:06:25 -0700340 BMCWEB_LOG_DEBUG("Get processor throttle resources");
Chris Caindfbf7de2023-04-13 16:01:04 -0500341
Ed Tanousdeae6a72024-11-11 21:58:57 -0800342 dbus::utility::getAllProperties(
343 service, objectPath, "xyz.openbmc_project.Control.Power.Throttle",
Ed Tanousac106bf2023-06-07 09:24:59 -0700344 [asyncResp](const boost::system::error_code& ec,
345 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400346 readThrottleProperties(asyncResp, ec, properties);
347 });
Chris Caindfbf7de2023-04-13 16:01:04 -0500348}
349
Ed Tanousac106bf2023-06-07 09:24:59 -0700350inline void getCpuAssetData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Millsac6a4442020-10-14 14:55:29 -0500351 const std::string& service,
352 const std::string& objPath)
353{
Ed Tanous62598e32023-07-17 17:06:25 -0700354 BMCWEB_LOG_DEBUG("Get Cpu Asset Data");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800355 dbus::utility::getAllProperties(
356 service, objPath, "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanousac106bf2023-06-07 09:24:59 -0700357 [objPath, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800358 const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200359 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400360 if (ec)
Ed Tanous002d39b2022-05-31 08:59:27 -0700361 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400362 BMCWEB_LOG_DEBUG("DBUS response error");
363 messages::internalError(asyncResp->res);
364 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700365 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400366
367 const std::string* serialNumber = nullptr;
368 const std::string* model = nullptr;
369 const std::string* manufacturer = nullptr;
370 const std::string* partNumber = nullptr;
371 const std::string* sparePartNumber = nullptr;
372
373 const bool success = sdbusplus::unpackPropertiesNoThrow(
374 dbus_utils::UnpackErrorPrinter(), properties, "SerialNumber",
375 serialNumber, "Model", model, "Manufacturer", manufacturer,
376 "PartNumber", partNumber, "SparePartNumber", sparePartNumber);
377
378 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700379 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400380 messages::internalError(asyncResp->res);
381 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700382 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200383
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400384 if (serialNumber != nullptr && !serialNumber->empty())
385 {
386 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
387 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200388
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400389 if ((model != nullptr) && !model->empty())
390 {
391 asyncResp->res.jsonValue["Model"] = *model;
392 }
393
394 if (manufacturer != nullptr)
395 {
396 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
397
398 // Otherwise would be unexpected.
399 if (manufacturer->find("Intel") != std::string::npos)
400 {
401 asyncResp->res.jsonValue["ProcessorArchitecture"] = "x86";
402 asyncResp->res.jsonValue["InstructionSet"] = "x86-64";
403 }
404 else if (manufacturer->find("IBM") != std::string::npos)
405 {
406 asyncResp->res.jsonValue["ProcessorArchitecture"] = "Power";
407 asyncResp->res.jsonValue["InstructionSet"] = "PowerISA";
408 }
409 }
410
411 if (partNumber != nullptr)
412 {
413 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
414 }
415
416 if (sparePartNumber != nullptr && !sparePartNumber->empty())
417 {
418 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
419 }
420 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500421}
422
Ed Tanousac106bf2023-06-07 09:24:59 -0700423inline void getCpuRevisionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Millsac6a4442020-10-14 14:55:29 -0500424 const std::string& service,
425 const std::string& objPath)
426{
Ed Tanous62598e32023-07-17 17:06:25 -0700427 BMCWEB_LOG_DEBUG("Get Cpu Revision Data");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800428 dbus::utility::getAllProperties(
429 service, objPath, "xyz.openbmc_project.Inventory.Decorator.Revision",
Ed Tanousac106bf2023-06-07 09:24:59 -0700430 [objPath, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800431 const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200432 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400433 if (ec)
434 {
435 BMCWEB_LOG_DEBUG("DBUS response error");
436 messages::internalError(asyncResp->res);
437 return;
438 }
Gunnar Millsac6a4442020-10-14 14:55:29 -0500439
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400440 const std::string* version = nullptr;
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200441
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400442 const bool success = sdbusplus::unpackPropertiesNoThrow(
443 dbus_utils::UnpackErrorPrinter(), properties, "Version",
444 version);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200445
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400446 if (!success)
447 {
448 messages::internalError(asyncResp->res);
449 return;
450 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200451
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400452 if (version != nullptr)
453 {
454 asyncResp->res.jsonValue["Version"] = *version;
455 }
456 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500457}
458
zhanghch058d1b46d2021-04-01 11:18:24 +0800459inline void getAcceleratorDataByService(
Ed Tanousac106bf2023-06-07 09:24:59 -0700460 std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& acclrtrId,
zhanghch058d1b46d2021-04-01 11:18:24 +0800461 const std::string& service, const std::string& objPath)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500462{
Ed Tanous62598e32023-07-17 17:06:25 -0700463 BMCWEB_LOG_DEBUG("Get available system Accelerator resources by service.");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800464 dbus::utility::getAllProperties(
465 service, objPath, "",
Ed Tanousac106bf2023-06-07 09:24:59 -0700466 [acclrtrId, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800467 const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200468 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400469 if (ec)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500470 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400471 BMCWEB_LOG_DEBUG("DBUS response error");
472 messages::internalError(asyncResp->res);
473 return;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500474 }
475
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400476 const bool* functional = nullptr;
477 const bool* present = nullptr;
478
479 const bool success = sdbusplus::unpackPropertiesNoThrow(
480 dbus_utils::UnpackErrorPrinter(), properties, "Functional",
481 functional, "Present", present);
482
483 if (!success)
484 {
485 messages::internalError(asyncResp->res);
486 return;
487 }
488
489 std::string state = "Enabled";
490 std::string health = "OK";
491
492 if (present != nullptr && !*present)
493 {
494 state = "Absent";
495 }
496
497 if (functional != nullptr && !*functional)
498 {
499 if (state == "Enabled")
500 {
501 health = "Critical";
502 }
503 }
504
505 asyncResp->res.jsonValue["Id"] = acclrtrId;
506 asyncResp->res.jsonValue["Name"] = "Processor";
507 asyncResp->res.jsonValue["Status"]["State"] = state;
508 asyncResp->res.jsonValue["Status"]["Health"] = health;
509 asyncResp->res.jsonValue["ProcessorType"] =
510 processor::ProcessorType::Accelerator;
511 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500512}
513
Jonathan Domandba0c292020-12-02 15:34:13 -0800514// OperatingConfig D-Bus Types
515using TurboProfileProperty = std::vector<std::tuple<uint32_t, size_t>>;
516using BaseSpeedPrioritySettingsProperty =
517 std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>;
518// uint32_t and size_t may or may not be the same type, requiring a dedup'd
519// variant
Jonathan Domandba0c292020-12-02 15:34:13 -0800520
521/**
522 * Fill out the HighSpeedCoreIDs in a Processor resource from the given
523 * OperatingConfig D-Bus property.
524 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700525 * @param[in,out] asyncResp Async HTTP response.
Jonathan Domandba0c292020-12-02 15:34:13 -0800526 * @param[in] baseSpeedSettings Full list of base speed priority groups,
527 * to use to determine the list of high
528 * speed cores.
529 */
530inline void highSpeedCoreIdsHandler(
Ed Tanousac106bf2023-06-07 09:24:59 -0700531 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Domandba0c292020-12-02 15:34:13 -0800532 const BaseSpeedPrioritySettingsProperty& baseSpeedSettings)
533{
534 // The D-Bus property does not indicate which bucket is the "high
535 // priority" group, so let's discern that by looking for the one with
536 // highest base frequency.
537 auto highPriorityGroup = baseSpeedSettings.cend();
538 uint32_t highestBaseSpeed = 0;
539 for (auto it = baseSpeedSettings.cbegin(); it != baseSpeedSettings.cend();
540 ++it)
541 {
542 const uint32_t baseFreq = std::get<uint32_t>(*it);
543 if (baseFreq > highestBaseSpeed)
544 {
545 highestBaseSpeed = baseFreq;
546 highPriorityGroup = it;
547 }
548 }
549
Ed Tanousac106bf2023-06-07 09:24:59 -0700550 nlohmann::json& jsonCoreIds = asyncResp->res.jsonValue["HighSpeedCoreIDs"];
Jonathan Domandba0c292020-12-02 15:34:13 -0800551 jsonCoreIds = nlohmann::json::array();
552
553 // There may not be any entries in the D-Bus property, so only populate
554 // if there was actually something there.
555 if (highPriorityGroup != baseSpeedSettings.cend())
556 {
557 jsonCoreIds = std::get<std::vector<uint32_t>>(*highPriorityGroup);
558 }
559}
560
561/**
562 * Fill out OperatingConfig related items in a Processor resource by requesting
563 * data from the given D-Bus object.
564 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700565 * @param[in,out] asyncResp Async HTTP response.
Jonathan Domandba0c292020-12-02 15:34:13 -0800566 * @param[in] cpuId CPU D-Bus name.
567 * @param[in] service D-Bus service to query.
568 * @param[in] objPath D-Bus object to query.
569 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700570inline void
571 getCpuConfigData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
572 const std::string& cpuId, const std::string& service,
573 const std::string& objPath)
Jonathan Domandba0c292020-12-02 15:34:13 -0800574{
Ed Tanous62598e32023-07-17 17:06:25 -0700575 BMCWEB_LOG_INFO("Getting CPU operating configs for {}", cpuId);
Jonathan Domandba0c292020-12-02 15:34:13 -0800576
577 // First, GetAll CurrentOperatingConfig properties on the object
Ed Tanousdeae6a72024-11-11 21:58:57 -0800578 dbus::utility::getAllProperties(
579 service, objPath,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200580 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig",
Ed Tanousac106bf2023-06-07 09:24:59 -0700581 [asyncResp, cpuId,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800582 service](const boost::system::error_code& ec,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200583 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400584 if (ec)
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200585 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400586 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
Ed Tanousac106bf2023-06-07 09:24:59 -0700587 messages::internalError(asyncResp->res);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200588 return;
589 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200590
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400591 nlohmann::json& json = asyncResp->res.jsonValue;
592
593 const sdbusplus::message::object_path* appliedConfig = nullptr;
594 const bool* baseSpeedPriorityEnabled = nullptr;
595
596 const bool success = sdbusplus::unpackPropertiesNoThrow(
597 dbus_utils::UnpackErrorPrinter(), properties, "AppliedConfig",
598 appliedConfig, "BaseSpeedPriorityEnabled",
599 baseSpeedPriorityEnabled);
600
601 if (!success)
602 {
603 messages::internalError(asyncResp->res);
604 return;
605 }
606
607 if (appliedConfig != nullptr)
608 {
609 const std::string& dbusPath = appliedConfig->str;
610 nlohmann::json::object_t operatingConfig;
611 operatingConfig["@odata.id"] = boost::urls::format(
612 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
613 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId);
614 json["OperatingConfigs"] = std::move(operatingConfig);
615
616 // Reuse the D-Bus config object name for the Redfish
617 // URI
618 size_t baseNamePos = dbusPath.rfind('/');
619 if (baseNamePos == std::string::npos ||
620 baseNamePos == (dbusPath.size() - 1))
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200621 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400622 // If the AppliedConfig was somehow not a valid path,
623 // skip adding any more properties, since everything
624 // else is tied to this applied config.
Ed Tanousac106bf2023-06-07 09:24:59 -0700625 messages::internalError(asyncResp->res);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200626 return;
627 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400628 nlohmann::json::object_t appliedOperatingConfig;
629 appliedOperatingConfig["@odata.id"] = boost::urls::format(
630 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}",
631 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId,
632 dbusPath.substr(baseNamePos + 1));
633 json["AppliedOperatingConfig"] =
634 std::move(appliedOperatingConfig);
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200635
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400636 // Once we found the current applied config, queue another
637 // request to read the base freq core ids out of that
638 // config.
Ed Tanousdeae6a72024-11-11 21:58:57 -0800639 dbus::utility::getProperty<BaseSpeedPrioritySettingsProperty>(
640 service, dbusPath,
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400641 "xyz.openbmc_project.Inventory.Item.Cpu."
642 "OperatingConfig",
643 "BaseSpeedPrioritySettings",
644 [asyncResp](const boost::system::error_code& ec2,
645 const BaseSpeedPrioritySettingsProperty&
646 baseSpeedList) {
647 if (ec2)
648 {
649 BMCWEB_LOG_WARNING("D-Bus Property Get error: {}",
650 ec2);
651 messages::internalError(asyncResp->res);
652 return;
653 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200654
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400655 highSpeedCoreIdsHandler(asyncResp, baseSpeedList);
656 });
657 }
658
659 if (baseSpeedPriorityEnabled != nullptr)
660 {
661 json["BaseSpeedPriorityState"] =
662 *baseSpeedPriorityEnabled ? "Enabled" : "Disabled";
663 }
664 });
Jonathan Domandba0c292020-12-02 15:34:13 -0800665}
666
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600667/**
668 * @brief Fill out location info of a processor by
669 * requesting data from the given D-Bus object.
670 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700671 * @param[in,out] asyncResp Async HTTP response.
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600672 * @param[in] service D-Bus service to query.
673 * @param[in] objPath D-Bus object to query.
674 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700675inline void getCpuLocationCode(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600676 const std::string& service,
677 const std::string& objPath)
678{
Ed Tanous62598e32023-07-17 17:06:25 -0700679 BMCWEB_LOG_DEBUG("Get Cpu Location Data");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800680 dbus::utility::getProperty<std::string>(
681 service, objPath,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700682 "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
Ed Tanousac106bf2023-06-07 09:24:59 -0700683 [objPath, asyncResp{std::move(asyncResp)}](
684 const boost::system::error_code& ec, const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400685 if (ec)
686 {
687 BMCWEB_LOG_DEBUG("DBUS response error");
688 messages::internalError(asyncResp->res);
689 return;
690 }
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600691
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400692 asyncResp->res
693 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
694 property;
695 });
SunnySrivastava1984cba4f442021-01-07 12:48:16 -0600696}
697
Jonathan Domanc9514482021-02-24 09:20:51 -0800698/**
Jonathan Doman49e429c2021-03-03 13:11:44 -0800699 * Populate the unique identifier in a Processor resource by requesting data
700 * from the given D-Bus object.
701 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700702 * @param[in,out] asyncResp Async HTTP response.
Jonathan Doman49e429c2021-03-03 13:11:44 -0800703 * @param[in] service D-Bus service to query.
704 * @param[in] objPath D-Bus object to query.
705 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700706inline void getCpuUniqueId(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman49e429c2021-03-03 13:11:44 -0800707 const std::string& service,
708 const std::string& objectPath)
709{
Ed Tanous62598e32023-07-17 17:06:25 -0700710 BMCWEB_LOG_DEBUG("Get CPU UniqueIdentifier");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800711 dbus::utility::getProperty<std::string>(
712 service, objectPath,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700713 "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier",
714 "UniqueIdentifier",
Ed Tanousac106bf2023-06-07 09:24:59 -0700715 [asyncResp](const boost::system::error_code& ec,
716 const std::string& id) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400717 if (ec)
718 {
719 BMCWEB_LOG_ERROR("Failed to read cpu unique id: {}", ec);
720 messages::internalError(asyncResp->res);
721 return;
722 }
723 asyncResp->res
724 .jsonValue["ProcessorId"]["ProtectedIdentificationNumber"] = id;
725 });
Jonathan Doman49e429c2021-03-03 13:11:44 -0800726}
727
728/**
Jonathan Domanc9514482021-02-24 09:20:51 -0800729 * Find the D-Bus object representing the requested Processor, and call the
730 * handler with the results. If matching object is not found, add 404 error to
731 * response and don't call the handler.
732 *
733 * @param[in,out] resp Async HTTP response.
734 * @param[in] processorId Redfish Processor Id.
735 * @param[in] handler Callback to continue processing request upon
736 * successfully finding object.
737 */
738template <typename Handler>
zhanghch058d1b46d2021-04-01 11:18:24 +0800739inline void getProcessorObject(const std::shared_ptr<bmcweb::AsyncResp>& resp,
Jonathan Domanc9514482021-02-24 09:20:51 -0800740 const std::string& processorId,
741 Handler&& handler)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500742{
Ed Tanous62598e32023-07-17 17:06:25 -0700743 BMCWEB_LOG_DEBUG("Get available system processor resources.");
Gunnar Millsac6a4442020-10-14 14:55:29 -0500744
Jonathan Domanc9514482021-02-24 09:20:51 -0800745 // GetSubTree on all interfaces which provide info about a Processor
Chris Caindfbf7de2023-04-13 16:01:04 -0500746 constexpr std::array<std::string_view, 9> interfaces = {
George Liue99073f2022-12-09 11:06:16 +0800747 "xyz.openbmc_project.Common.UUID",
748 "xyz.openbmc_project.Inventory.Decorator.Asset",
749 "xyz.openbmc_project.Inventory.Decorator.Revision",
750 "xyz.openbmc_project.Inventory.Item.Cpu",
751 "xyz.openbmc_project.Inventory.Decorator.LocationCode",
752 "xyz.openbmc_project.Inventory.Item.Accelerator",
753 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig",
Chris Caindfbf7de2023-04-13 16:01:04 -0500754 "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier",
755 "xyz.openbmc_project.Control.Power.Throttle"};
George Liue99073f2022-12-09 11:06:16 +0800756 dbus::utility::getSubTree(
757 "/xyz/openbmc_project/inventory", 0, interfaces,
Jonathan Domanc9514482021-02-24 09:20:51 -0800758 [resp, processorId, handler = std::forward<Handler>(handler)](
George Liue99073f2022-12-09 11:06:16 +0800759 const boost::system::error_code& ec,
760 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400761 if (ec)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500762 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400763 BMCWEB_LOG_DEBUG("DBUS response error: {}", ec);
764 messages::internalError(resp->res);
765 return;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500766 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400767 for (const auto& [objectPath, serviceMap] : subtree)
Gunnar Millsac6a4442020-10-14 14:55:29 -0500768 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400769 // Ignore any objects which don't end with our desired cpu name
770 if (!objectPath.ends_with(processorId))
Gunnar Millsac6a4442020-10-14 14:55:29 -0500771 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400772 continue;
Jonathan Doman2bab9832020-12-02 15:27:40 -0800773 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400774
775 bool found = false;
776 // Filter out objects that don't have the CPU-specific
777 // interfaces to make sure we can return 404 on non-CPUs
778 // (e.g. /redfish/../Processors/dimm0)
779 for (const auto& [serviceName, interfaceList] : serviceMap)
780 {
781 if (std::ranges::find_first_of(interfaceList,
782 processorInterfaces) !=
783 std::end(interfaceList))
784 {
785 found = true;
786 break;
787 }
788 }
789
790 if (!found)
791 {
792 continue;
793 }
794
795 // Process the first object which does match our cpu name and
796 // required interfaces, and potentially ignore any other
797 // matching objects. Assume all interfaces we want to process
798 // must be on the same object path.
799
800 handler(objectPath, serviceMap);
801 return;
Gunnar Millsac6a4442020-10-14 14:55:29 -0500802 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400803 messages::resourceNotFound(resp->res, "Processor", processorId);
804 });
Gunnar Millsac6a4442020-10-14 14:55:29 -0500805}
806
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400807inline void getProcessorData(
808 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
809 const std::string& processorId, const std::string& objectPath,
810 const dbus::utility::MapperServiceMap& serviceMap)
Jonathan Domanc9514482021-02-24 09:20:51 -0800811{
812 for (const auto& [serviceName, interfaceList] : serviceMap)
813 {
814 for (const auto& interface : interfaceList)
815 {
816 if (interface == "xyz.openbmc_project.Inventory.Decorator.Asset")
817 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700818 getCpuAssetData(asyncResp, serviceName, objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800819 }
George Liu0fda0f12021-11-16 10:06:17 +0800820 else if (interface ==
821 "xyz.openbmc_project.Inventory.Decorator.Revision")
Jonathan Domanc9514482021-02-24 09:20:51 -0800822 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700823 getCpuRevisionData(asyncResp, serviceName, objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800824 }
825 else if (interface == "xyz.openbmc_project.Inventory.Item.Cpu")
826 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700827 getCpuDataByService(asyncResp, processorId, serviceName,
Jonathan Domanc9514482021-02-24 09:20:51 -0800828 objectPath);
829 }
George Liu0fda0f12021-11-16 10:06:17 +0800830 else if (interface ==
831 "xyz.openbmc_project.Inventory.Item.Accelerator")
Jonathan Domanc9514482021-02-24 09:20:51 -0800832 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700833 getAcceleratorDataByService(asyncResp, processorId, serviceName,
Jonathan Domanc9514482021-02-24 09:20:51 -0800834 objectPath);
835 }
George Liu0fda0f12021-11-16 10:06:17 +0800836 else if (
837 interface ==
838 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig")
Jonathan Domanc9514482021-02-24 09:20:51 -0800839 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700840 getCpuConfigData(asyncResp, processorId, serviceName,
841 objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800842 }
George Liu0fda0f12021-11-16 10:06:17 +0800843 else if (interface ==
844 "xyz.openbmc_project.Inventory.Decorator.LocationCode")
Jonathan Domanc9514482021-02-24 09:20:51 -0800845 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700846 getCpuLocationCode(asyncResp, serviceName, objectPath);
Jonathan Domanc9514482021-02-24 09:20:51 -0800847 }
Sharad Yadav71b82f22021-05-10 15:11:39 +0530848 else if (interface == "xyz.openbmc_project.Common.UUID")
849 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700850 getProcessorUUID(asyncResp, serviceName, objectPath);
Sharad Yadav71b82f22021-05-10 15:11:39 +0530851 }
George Liu0fda0f12021-11-16 10:06:17 +0800852 else if (interface ==
853 "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier")
Jonathan Doman49e429c2021-03-03 13:11:44 -0800854 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700855 getCpuUniqueId(asyncResp, serviceName, objectPath);
Jonathan Doman49e429c2021-03-03 13:11:44 -0800856 }
Chris Caindfbf7de2023-04-13 16:01:04 -0500857 else if (interface == "xyz.openbmc_project.Control.Power.Throttle")
858 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700859 getThrottleProperties(asyncResp, serviceName, objectPath);
Chris Caindfbf7de2023-04-13 16:01:04 -0500860 }
Jonathan Domanc9514482021-02-24 09:20:51 -0800861 }
862 }
863}
864
Jonathan Domandba0c292020-12-02 15:34:13 -0800865/**
866 * Request all the properties for the given D-Bus object and fill out the
867 * related entries in the Redfish OperatingConfig response.
868 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700869 * @param[in,out] asyncResp Async HTTP response.
Jonathan Domandba0c292020-12-02 15:34:13 -0800870 * @param[in] service D-Bus service name to query.
871 * @param[in] objPath D-Bus object to query.
872 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400873inline void getOperatingConfigData(
874 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
875 const std::string& service, const std::string& objPath)
Jonathan Domandba0c292020-12-02 15:34:13 -0800876{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800877 dbus::utility::getAllProperties(
878 service, objPath,
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200879 "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig",
Ed Tanousac106bf2023-06-07 09:24:59 -0700880 [asyncResp](const boost::system::error_code& ec,
881 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400882 if (ec)
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200883 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400884 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message());
885 messages::internalError(asyncResp->res);
886 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700887 }
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200888
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400889 const size_t* availableCoreCount = nullptr;
890 const uint32_t* baseSpeed = nullptr;
891 const uint32_t* maxJunctionTemperature = nullptr;
892 const uint32_t* maxSpeed = nullptr;
893 const uint32_t* powerLimit = nullptr;
894 const TurboProfileProperty* turboProfile = nullptr;
895 const BaseSpeedPrioritySettingsProperty* baseSpeedPrioritySettings =
896 nullptr;
897
898 const bool success = sdbusplus::unpackPropertiesNoThrow(
899 dbus_utils::UnpackErrorPrinter(), properties,
900 "AvailableCoreCount", availableCoreCount, "BaseSpeed",
901 baseSpeed, "MaxJunctionTemperature", maxJunctionTemperature,
902 "MaxSpeed", maxSpeed, "PowerLimit", powerLimit, "TurboProfile",
903 turboProfile, "BaseSpeedPrioritySettings",
904 baseSpeedPrioritySettings);
905
906 if (!success)
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200907 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400908 messages::internalError(asyncResp->res);
909 return;
Krzysztof Grobelny351053f2022-07-28 15:44:22 +0200910 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400911
912 nlohmann::json& json = asyncResp->res.jsonValue;
913
914 if (availableCoreCount != nullptr)
915 {
916 json["TotalAvailableCoreCount"] = *availableCoreCount;
917 }
918
919 if (baseSpeed != nullptr)
920 {
921 json["BaseSpeedMHz"] = *baseSpeed;
922 }
923
924 if (maxJunctionTemperature != nullptr)
925 {
926 json["MaxJunctionTemperatureCelsius"] = *maxJunctionTemperature;
927 }
928
929 if (maxSpeed != nullptr)
930 {
931 json["MaxSpeedMHz"] = *maxSpeed;
932 }
933
934 if (powerLimit != nullptr)
935 {
936 json["TDPWatts"] = *powerLimit;
937 }
938
939 if (turboProfile != nullptr)
940 {
941 nlohmann::json& turboArray = json["TurboProfile"];
942 turboArray = nlohmann::json::array();
943 for (const auto& [turboSpeed, coreCount] : *turboProfile)
944 {
945 nlohmann::json::object_t turbo;
946 turbo["ActiveCoreCount"] = coreCount;
947 turbo["MaxSpeedMHz"] = turboSpeed;
948 turboArray.emplace_back(std::move(turbo));
949 }
950 }
951
952 if (baseSpeedPrioritySettings != nullptr)
953 {
954 nlohmann::json& baseSpeedArray =
955 json["BaseSpeedPrioritySettings"];
956 baseSpeedArray = nlohmann::json::array();
957 for (const auto& [baseSpeedMhz, coreList] :
958 *baseSpeedPrioritySettings)
959 {
960 nlohmann::json::object_t speed;
961 speed["CoreCount"] = coreList.size();
962 speed["CoreIDs"] = coreList;
963 speed["BaseSpeedMHz"] = baseSpeedMhz;
964 baseSpeedArray.emplace_back(std::move(speed));
965 }
966 }
967 });
Jonathan Domandba0c292020-12-02 15:34:13 -0800968}
969
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800970/**
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800971 * Handle the PATCH operation of the AppliedOperatingConfig property. Do basic
972 * validation of the input data, and then set the D-Bus property.
973 *
974 * @param[in,out] resp Async HTTP response.
975 * @param[in] processorId Processor's Id.
976 * @param[in] appliedConfigUri New property value to apply.
977 * @param[in] cpuObjectPath Path of CPU object to modify.
978 * @param[in] serviceMap Service map for CPU object.
979 */
980inline void patchAppliedOperatingConfig(
981 const std::shared_ptr<bmcweb::AsyncResp>& resp,
982 const std::string& processorId, const std::string& appliedConfigUri,
Shantappa Teekappanavar5df6eda2022-01-18 12:29:28 -0600983 const std::string& cpuObjectPath,
984 const dbus::utility::MapperServiceMap& serviceMap)
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800985{
986 // Check that the property even exists by checking for the interface
987 const std::string* controlService = nullptr;
988 for (const auto& [serviceName, interfaceList] : serviceMap)
989 {
Ed Tanous3544d2a2023-08-06 18:12:20 -0700990 if (std::ranges::find(interfaceList,
991 "xyz.openbmc_project.Control.Processor."
992 "CurrentOperatingConfig") != interfaceList.end())
Jonathan Doman3cde86f2020-12-02 14:50:45 -0800993 {
994 controlService = &serviceName;
995 break;
996 }
997 }
998
999 if (controlService == nullptr)
1000 {
1001 messages::internalError(resp->res);
1002 return;
1003 }
1004
1005 // Check that the config URI is a child of the cpu URI being patched.
Ed Tanous253f11b2024-05-16 09:38:31 -07001006 std::string expectedPrefix(std::format("/redfish/v1/Systems/{}/Processors/",
1007 BMCWEB_REDFISH_SYSTEM_URI_NAME));
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001008 expectedPrefix += processorId;
1009 expectedPrefix += "/OperatingConfigs/";
Ed Tanous11ba3972022-07-11 09:50:41 -07001010 if (!appliedConfigUri.starts_with(expectedPrefix) ||
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001011 expectedPrefix.size() == appliedConfigUri.size())
1012 {
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001013 messages::propertyValueIncorrect(resp->res, "AppliedOperatingConfig",
1014 appliedConfigUri);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001015 return;
1016 }
1017
1018 // Generate the D-Bus path of the OperatingConfig object, by assuming it's a
1019 // direct child of the CPU object.
1020 // Strip the expectedPrefix from the config URI to get the "filename", and
1021 // append to the CPU's path.
1022 std::string configBaseName = appliedConfigUri.substr(expectedPrefix.size());
1023 sdbusplus::message::object_path configPath(cpuObjectPath);
1024 configPath /= configBaseName;
1025
Ed Tanous62598e32023-07-17 17:06:25 -07001026 BMCWEB_LOG_INFO("Setting config to {}", configPath.str);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001027
1028 // Set the property, with handler to check error responses
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001029 setDbusProperty(
Ginu Georgee93abac2024-06-14 17:35:27 +05301030 resp, "AppliedOperatingConfig", *controlService, cpuObjectPath,
George Liu9ae226f2023-06-21 17:56:46 +08001031 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig",
Ginu Georgee93abac2024-06-14 17:35:27 +05301032 "AppliedConfig", configPath);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001033}
1034
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001035inline void handleProcessorHead(
1036 crow::App& app, const crow::Request& req,
1037 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1038 const std::string& /* systemName */, const std::string& /* processorId */)
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001039{
Ed Tanousac106bf2023-06-07 09:24:59 -07001040 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001041 {
1042 return;
1043 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001044 asyncResp->res.addHeader(
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001045 boost::beast::http::field::link,
1046 "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
1047}
1048
1049inline void handleProcessorCollectionHead(
1050 crow::App& app, const crow::Request& req,
Ed Tanousac106bf2023-06-07 09:24:59 -07001051 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001052 const std::string& /* systemName */)
1053{
Ed Tanousac106bf2023-06-07 09:24:59 -07001054 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001055 {
1056 return;
1057 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001058 asyncResp->res.addHeader(
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001059 boost::beast::http::field::link,
1060 "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
1061}
1062
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001063inline void requestRoutesOperatingConfigCollection(App& app)
Jonathan Domandba0c292020-12-02 15:34:13 -08001064{
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001065 BMCWEB_ROUTE(app,
1066 "/redfish/v1/Systems/<str>/Processors/<str>/OperatingConfigs/")
Ed Tanoused398212021-06-09 17:05:54 -07001067 .privileges(redfish::privileges::getOperatingConfigCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001068 .methods(
1069 boost::beast::http::verb::
1070 get)([&app](const crow::Request& req,
1071 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1072 const std::string& systemName,
1073 const std::string& cpuName) {
1074 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -07001075 {
1076 return;
1077 }
Jonathan Domandba0c292020-12-02 15:34:13 -08001078
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001079 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07001080 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001081 // Option currently returns no systems. TBD
1082 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1083 systemName);
Ed Tanous002d39b2022-05-31 08:59:27 -07001084 return;
1085 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001086
1087 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1088 {
1089 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1090 systemName);
1091 return;
1092 }
1093 asyncResp->res.jsonValue["@odata.type"] =
1094 "#OperatingConfigCollection.OperatingConfigCollection";
1095 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1096 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
1097 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName);
1098 asyncResp->res.jsonValue["Name"] = "Operating Config Collection";
1099
1100 // First find the matching CPU object so we know how to
1101 // constrain our search for related Config objects.
1102 const std::array<std::string_view, 1> interfaces = {
1103 "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig"};
1104 dbus::utility::getSubTreePaths(
1105 "/xyz/openbmc_project/inventory", 0, interfaces,
1106 [asyncResp,
1107 cpuName](const boost::system::error_code& ec,
1108 const dbus::utility::MapperGetSubTreePathsResponse&
1109 objects) {
1110 if (ec)
1111 {
1112 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec,
1113 ec.message());
1114 messages::internalError(asyncResp->res);
1115 return;
1116 }
1117
1118 for (const std::string& object : objects)
1119 {
1120 if (!object.ends_with(cpuName))
1121 {
1122 continue;
1123 }
1124
1125 // Not expected that there will be multiple matching
1126 // CPU objects, but if there are just use the first
1127 // one.
1128
1129 // Use the common search routine to construct the
1130 // Collection of all Config objects under this CPU.
1131 constexpr std::array<std::string_view, 1> interface{
1132 "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
1133 collection_util::getCollectionMembers(
1134 asyncResp,
1135 boost::urls::format(
1136 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs",
1137 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName),
1138 interface, object);
1139 return;
1140 }
1141 });
George Liu0fda0f12021-11-16 10:06:17 +08001142 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001143}
1144
1145inline void requestRoutesOperatingConfig(App& app)
1146{
1147 BMCWEB_ROUTE(
1148 app,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001149 "/redfish/v1/Systems/<str>/Processors/<str>/OperatingConfigs/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001150 .privileges(redfish::privileges::getOperatingConfig)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001151 .methods(
1152 boost::beast::http::verb::
1153 get)([&app](const crow::Request& req,
1154 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1155 const std::string& systemName,
1156 const std::string& cpuName,
1157 const std::string& configName) {
1158 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -07001159 {
1160 return;
1161 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001162 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07001163 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001164 // Option currently returns no systems. TBD
1165 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1166 systemName);
Ed Tanous002d39b2022-05-31 08:59:27 -07001167 return;
1168 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001169
1170 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1171 {
1172 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1173 systemName);
1174 return;
1175 }
1176 // Ask for all objects implementing OperatingConfig so we can search
1177 // for one with a matching name
1178 constexpr std::array<std::string_view, 1> interfaces = {
1179 "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
1180 dbus::utility::getSubTree(
1181 "/xyz/openbmc_project/inventory", 0, interfaces,
1182 [asyncResp, cpuName, configName](
1183 const boost::system::error_code& ec,
1184 const dbus::utility::MapperGetSubTreeResponse& subtree) {
1185 if (ec)
1186 {
1187 BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec,
1188 ec.message());
1189 messages::internalError(asyncResp->res);
1190 return;
1191 }
1192 const std::string expectedEnding =
1193 cpuName + '/' + configName;
1194 for (const auto& [objectPath, serviceMap] : subtree)
1195 {
1196 // Ignore any configs without matching cpuX/configY
1197 if (!objectPath.ends_with(expectedEnding) ||
1198 serviceMap.empty())
1199 {
1200 continue;
1201 }
1202
1203 nlohmann::json& json = asyncResp->res.jsonValue;
1204 json["@odata.type"] =
1205 "#OperatingConfig.v1_0_0.OperatingConfig";
1206 json["@odata.id"] = boost::urls::format(
1207 "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}",
1208 BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuName,
1209 configName);
1210 json["Name"] = "Processor Profile";
1211 json["Id"] = configName;
1212
1213 // Just use the first implementation of the object - not
1214 // expected that there would be multiple matching
1215 // services
1216 getOperatingConfigData(
1217 asyncResp, serviceMap.begin()->first, objectPath);
1218 return;
1219 }
1220 messages::resourceNotFound(asyncResp->res,
1221 "OperatingConfig", configName);
1222 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001223 });
1224}
Jonathan Domandba0c292020-12-02 15:34:13 -08001225
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001226inline void requestRoutesProcessorCollection(App& app)
Gunnar Millsac6a4442020-10-14 14:55:29 -05001227{
Gunnar Millsac6a4442020-10-14 14:55:29 -05001228 /**
1229 * Functions triggers appropriate requests on DBus
1230 */
Ed Tanous22d268c2022-05-19 09:39:07 -07001231 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/")
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001232 .privileges(redfish::privileges::headProcessorCollection)
1233 .methods(boost::beast::http::verb::head)(
1234 std::bind_front(handleProcessorCollectionHead, std::ref(app)));
1235
1236 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/")
Ed Tanoused398212021-06-09 17:05:54 -07001237 .privileges(redfish::privileges::getProcessorCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001238 .methods(
1239 boost::beast::http::verb::
1240 get)([&app](const crow::Request& req,
1241 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1242 const std::string& systemName) {
1243 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1244 {
1245 return;
1246 }
1247 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1248 {
1249 // Option currently returns no systems. TBD
1250 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1251 systemName);
1252 return;
1253 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001254
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001255 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1256 {
1257 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1258 systemName);
1259 return;
1260 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001261
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001262 asyncResp->res.addHeader(
1263 boost::beast::http::field::link,
1264 "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001265
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001266 asyncResp->res.jsonValue["@odata.type"] =
1267 "#ProcessorCollection.ProcessorCollection";
1268 asyncResp->res.jsonValue["Name"] = "Processor Collection";
Gunnar Millsac6a4442020-10-14 14:55:29 -05001269
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001270 asyncResp->res.jsonValue["@odata.id"] =
1271 std::format("/redfish/v1/Systems/{}/Processors",
1272 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Gunnar Millsac6a4442020-10-14 14:55:29 -05001273
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001274 collection_util::getCollectionMembers(
1275 asyncResp,
1276 boost::urls::format("/redfish/v1/Systems/{}/Processors",
1277 BMCWEB_REDFISH_SYSTEM_URI_NAME),
1278 processorInterfaces, "/xyz/openbmc_project/inventory");
1279 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001280}
Gunnar Millsac6a4442020-10-14 14:55:29 -05001281
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001282inline void requestRoutesProcessor(App& app)
Gunnar Millsac6a4442020-10-14 14:55:29 -05001283{
Gunnar Millsac6a4442020-10-14 14:55:29 -05001284 /**
1285 * Functions triggers appropriate requests on DBus
1286 */
Gunnar Millsac6a4442020-10-14 14:55:29 -05001287
Ed Tanous22d268c2022-05-19 09:39:07 -07001288 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
Nikhil Namjoshi71a24ca2022-11-11 01:52:32 +00001289 .privileges(redfish::privileges::headProcessor)
1290 .methods(boost::beast::http::verb::head)(
1291 std::bind_front(handleProcessorHead, std::ref(app)));
1292
1293 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001294 .privileges(redfish::privileges::getProcessor)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001295 .methods(
1296 boost::beast::http::verb::
1297 get)([&app](const crow::Request& req,
1298 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1299 const std::string& systemName,
1300 const std::string& processorId) {
1301 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1302 {
1303 return;
1304 }
1305 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1306 {
1307 // Option currently returns no systems. TBD
1308 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1309 systemName);
1310 return;
1311 }
1312 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1313 {
1314 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1315 systemName);
1316 return;
1317 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001318
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001319 asyncResp->res.addHeader(
1320 boost::beast::http::field::link,
1321 "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
1322 asyncResp->res.jsonValue["@odata.type"] =
1323 "#Processor.v1_18_0.Processor";
1324 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1325 "/redfish/v1/Systems/{}/Processors/{}",
1326 BMCWEB_REDFISH_SYSTEM_URI_NAME, processorId);
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001327
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001328 getProcessorObject(
1329 asyncResp, processorId,
1330 std::bind_front(getProcessorData, asyncResp, processorId));
1331 });
Jonathan Doman3cde86f2020-12-02 14:50:45 -08001332
Ed Tanous22d268c2022-05-19 09:39:07 -07001333 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001334 .privileges(redfish::privileges::patchProcessor)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001335 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001336 [&app](const crow::Request& req,
1337 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001338 const std::string& systemName,
Ed Tanous45ca1b82022-03-25 13:07:27 -07001339 const std::string& processorId) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001340 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1341 {
1342 return;
1343 }
1344 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1345 {
1346 // Option currently returns no systems. TBD
1347 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1348 systemName);
1349 return;
1350 }
1351 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1352 {
1353 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1354 systemName);
1355 return;
1356 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001357
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001358 std::optional<std::string> appliedConfigUri;
1359 if (!json_util::readJsonPatch(
Myung Baeafc474a2024-10-09 00:53:29 -07001360 req, asyncResp->res, //
1361 "AppliedOperatingConfig/@odata.id", appliedConfigUri //
1362 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001363 {
1364 return;
1365 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001366
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001367 if (appliedConfigUri)
1368 {
1369 // Check for 404 and find matching D-Bus object, then run
1370 // property patch handlers if that all succeeds.
1371 getProcessorObject(
1372 asyncResp, processorId,
1373 std::bind_front(patchAppliedOperatingConfig, asyncResp,
1374 processorId, *appliedConfigUri));
1375 }
1376 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001377}
Gunnar Millsac6a4442020-10-14 14:55:29 -05001378
1379} // namespace redfish