blob: 6e658dfd049b77fd302206b736b95d256231dd09 [file] [log] [blame]
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
James Feist35e257a2020-06-05 13:30:51 -070018#include "health.hpp"
19
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020020#include <boost/container/flat_map.hpp>
James Feistc50e7c62020-07-27 15:39:36 -070021#include <boost/format.hpp>
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020022#include <node.hpp>
23#include <utils/json_utils.hpp>
24
25namespace redfish
26{
27
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060028using InterfacesProperties = boost::container::flat_map<
29 std::string,
30 boost::container::flat_map<std::string, dbus::utility::DbusVariantType>>;
31
Ed Tanous23a21a12020-07-25 04:45:05 +000032inline void getResourceList(std::shared_ptr<AsyncResp> aResp,
33 const std::string& subclass,
34 const std::vector<const char*>& collectionName)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020035{
36 BMCWEB_LOG_DEBUG << "Get available system cpu/mem resources.";
37 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -080038 [subclass, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020039 const boost::system::error_code ec,
40 const boost::container::flat_map<
41 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -050042 std::string, std::vector<std::string>>>&
43 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020044 if (ec)
45 {
46 BMCWEB_LOG_DEBUG << "DBUS response error";
47 messages::internalError(aResp->res);
48 return;
49 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -050050 nlohmann::json& members = aResp->res.jsonValue["Members"];
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020051 members = nlohmann::json::array();
52
Gunnar Mills1214b7e2020-06-04 10:11:30 -050053 for (const auto& object : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020054 {
55 auto iter = object.first.rfind("/");
56 if ((iter != std::string::npos) && (iter < object.first.size()))
57 {
58 members.push_back(
Ed Tanous029573d2019-02-01 10:57:49 -080059 {{"@odata.id", "/redfish/v1/Systems/system/" +
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020060 subclass + "/" +
61 object.first.substr(iter + 1)}});
62 }
63 }
64 aResp->res.jsonValue["Members@odata.count"] = members.size();
65 },
66 "xyz.openbmc_project.ObjectMapper",
67 "/xyz/openbmc_project/object_mapper",
68 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -070069 "/xyz/openbmc_project/inventory", 0, collectionName);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020070}
71
Ed Tanous23a21a12020-07-25 04:45:05 +000072inline void
73 getCpuDataByInterface(std::shared_ptr<AsyncResp> aResp,
74 const InterfacesProperties& cpuInterfacesProperties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020075{
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060076 BMCWEB_LOG_DEBUG << "Get CPU resources by interface.";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020077
Zhikui Ren029cc1f2020-08-25 15:21:41 -070078 // Added for future purpose. Once present and functional attributes added
79 // in busctl call, need to add actual logic to fetch original values.
80 bool present = false;
81 const bool functional = true;
82 auto health = std::make_shared<HealthPopulate>(aResp);
83 health->populate();
84
Gunnar Mills1214b7e2020-06-04 10:11:30 -050085 for (const auto& interface : cpuInterfacesProperties)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060086 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050087 for (const auto& property : interface.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060088 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -070089 if (property.first == "CoreCount")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +020090 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050091 const uint16_t* coresCount =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -060092 std::get_if<uint16_t>(&property.second);
Ed Tanous883b3112018-12-06 16:13:35 -080093 if (coresCount == nullptr)
94 {
95 // Important property not in desired type
96 messages::internalError(aResp->res);
97 return;
98 }
99 if (*coresCount == 0)
100 {
101 // Slot is not populated, set status end return
102 aResp->res.jsonValue["Status"]["State"] = "Absent";
Ed Tanous883b3112018-12-06 16:13:35 -0800103 // HTTP Code will be set up automatically, just return
104 return;
105 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700106 else
107 {
108 aResp->res.jsonValue["Status"]["State"] = "Enabled";
109 present = true;
110 }
Ed Tanous883b3112018-12-06 16:13:35 -0800111 aResp->res.jsonValue["TotalCores"] = *coresCount;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200112 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700113 else if (property.first == "MaxSpeedInMhz")
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600114 {
115 aResp->res.jsonValue["MaxSpeedMHz"] = property.second;
116 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700117 else if (property.first == "Socket")
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600118 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500119 const std::string* value =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600120 std::get_if<std::string>(&property.second);
121 if (value != nullptr)
122 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700123 aResp->res.jsonValue["Socket"] = *value;
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600124 }
125 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700126 else if (property.first == "ThreadCount")
Gunnar Millsf9dcc112020-02-13 13:19:43 -0600127 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700128 aResp->res.jsonValue["TotalThreads"] = property.second;
Gunnar Millsf9dcc112020-02-13 13:19:43 -0600129 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700130 else if (property.first == "Family")
Gunnar Millsf9dcc112020-02-13 13:19:43 -0600131 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700132 const std::string* value =
133 std::get_if<std::string>(&property.second);
134 if (value != nullptr)
135 {
136 aResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] =
137 *value;
138 }
Gunnar Millsf9dcc112020-02-13 13:19:43 -0600139 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700140 else if (property.first == "Id")
Gunnar Millsf9dcc112020-02-13 13:19:43 -0600141 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700142 const uint64_t* value = std::get_if<uint64_t>(&property.second);
143 if (value != nullptr && *value != 0)
144 {
145 present = true;
146 aResp->res
147 .jsonValue["ProcessorId"]["IdentificationRegisters"] =
148 boost::lexical_cast<std::string>(*value);
149 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600150 }
151 }
152 }
153
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700154 if (present == false)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600155 {
156 aResp->res.jsonValue["Status"]["State"] = "Absent";
157 aResp->res.jsonValue["Status"]["Health"] = "OK";
158 }
159 else
160 {
161 aResp->res.jsonValue["Status"]["State"] = "Enabled";
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700162 if (functional)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600163 {
164 aResp->res.jsonValue["Status"]["Health"] = "OK";
165 }
166 else
167 {
168 aResp->res.jsonValue["Status"]["Health"] = "Critical";
169 }
170 }
171
172 return;
173}
174
Ed Tanous23a21a12020-07-25 04:45:05 +0000175inline void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
176 const std::string& cpuId,
177 const std::string& service,
178 const std::string& objPath)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600179{
180 BMCWEB_LOG_DEBUG << "Get available system cpu resources by service.";
181
182 crow::connections::systemBus->async_method_call(
183 [cpuId, service, objPath, aResp{std::move(aResp)}](
184 const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500185 const dbus::utility::ManagedObjectType& dbusData) {
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600186 if (ec)
187 {
188 BMCWEB_LOG_DEBUG << "DBUS response error";
189 messages::internalError(aResp->res);
190 return;
191 }
192 aResp->res.jsonValue["Id"] = cpuId;
193 aResp->res.jsonValue["Name"] = "Processor";
194 aResp->res.jsonValue["ProcessorType"] = "CPU";
195
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700196 bool slotPresent = false;
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600197 std::string corePath = objPath + "/core";
198 size_t totalCores = 0;
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500199 for (const auto& object : dbusData)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600200 {
201 if (object.first.str == objPath)
202 {
203 getCpuDataByInterface(aResp, object.second);
204 }
205 else if (boost::starts_with(object.first.str, corePath))
206 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500207 for (const auto& interface : object.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600208 {
209 if (interface.first ==
210 "xyz.openbmc_project.Inventory.Item")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200211 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500212 for (const auto& property : interface.second)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600213 {
214 if (property.first == "Present")
215 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500216 const bool* present =
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600217 std::get_if<bool>(&property.second);
218 if (present != nullptr)
219 {
220 if (*present == true)
221 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700222 slotPresent = true;
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600223 totalCores++;
224 }
225 }
226 }
227 }
Gunnar Millsb957ba52019-01-31 15:58:15 -0600228 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200229 }
230 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200231 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600232 // In getCpuDataByInterface(), state and health are set
233 // based on the present and functional status. If core
234 // count is zero, then it has a higher precedence.
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700235 if (slotPresent)
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600236 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700237 if (totalCores == 0)
238 {
239 // Slot is not populated, set status end return
240 aResp->res.jsonValue["Status"]["State"] = "Absent";
241 aResp->res.jsonValue["Status"]["Health"] = "OK";
242 }
243 aResp->res.jsonValue["TotalCores"] = totalCores;
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600244 }
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600245 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200246 },
RAJESWARAN THILLAIGOVINDANec8faf92019-02-21 10:59:03 -0600247 service, "/xyz/openbmc_project/inventory",
248 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200249}
250
Ed Tanous23a21a12020-07-25 04:45:05 +0000251inline void getCpuAssetData(std::shared_ptr<AsyncResp> aResp,
252 const std::string& service,
253 const std::string& objPath)
Zhikui Ren5e54a362020-07-13 15:31:38 -0700254{
255 BMCWEB_LOG_DEBUG << "Get Cpu Asset Data";
256 crow::connections::systemBus->async_method_call(
257 [objPath, aResp{std::move(aResp)}](
258 const boost::system::error_code ec,
259 const boost::container::flat_map<
260 std::string, std::variant<std::string, uint32_t, uint16_t,
261 bool>>& properties) {
262 if (ec)
263 {
264 BMCWEB_LOG_DEBUG << "DBUS response error";
265 messages::internalError(aResp->res);
266 return;
267 }
268
269 for (const auto& property : properties)
270 {
271 if (property.first == "SerialNumber")
272 {
273 const std::string* sn =
274 std::get_if<std::string>(&property.second);
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700275 if (sn != nullptr && !sn->empty())
Zhikui Ren5e54a362020-07-13 15:31:38 -0700276 {
277 aResp->res.jsonValue["SerialNumber"] = *sn;
278 }
279 }
280 else if (property.first == "Model")
281 {
282 const std::string* model =
283 std::get_if<std::string>(&property.second);
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700284 if (model != nullptr && !model->empty())
Zhikui Ren5e54a362020-07-13 15:31:38 -0700285 {
286 aResp->res.jsonValue["Model"] = *model;
287 }
288 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700289 else if (property.first == "Manufacturer")
290 {
291
292 const std::string* mfg =
293 std::get_if<std::string>(&property.second);
294 if (mfg != nullptr)
295 {
296 aResp->res.jsonValue["Manufacturer"] = *mfg;
297
298 // Otherwise would be unexpected.
299 if (mfg->find("Intel") != std::string::npos)
300 {
301 aResp->res.jsonValue["ProcessorArchitecture"] =
302 "x86";
303 aResp->res.jsonValue["InstructionSet"] = "x86-64";
304 }
305 else if (mfg->find("IBM") != std::string::npos)
306 {
307 aResp->res.jsonValue["ProcessorArchitecture"] =
308 "Power";
309 aResp->res.jsonValue["InstructionSet"] = "PowerISA";
310 }
311 }
312 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700313 }
314 },
315 service, objPath, "org.freedesktop.DBus.Properties", "GetAll",
316 "xyz.openbmc_project.Inventory.Decorator.Asset");
317}
318
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700319inline void getCpuRevisionData(std::shared_ptr<AsyncResp> aResp,
320 const std::string& service,
321 const std::string& objPath)
322{
323 BMCWEB_LOG_DEBUG << "Get Cpu Revision Data";
324 crow::connections::systemBus->async_method_call(
325 [objPath, aResp{std::move(aResp)}](
326 const boost::system::error_code ec,
327 const boost::container::flat_map<
328 std::string, std::variant<std::string, uint32_t, uint16_t,
329 bool>>& properties) {
330 if (ec)
331 {
332 BMCWEB_LOG_DEBUG << "DBUS response error";
333 messages::internalError(aResp->res);
334 return;
335 }
336
337 for (const auto& property : properties)
338 {
339 if (property.first == "Version")
340 {
341 const std::string* ver =
342 std::get_if<std::string>(&property.second);
343 if (ver != nullptr)
344 {
345 aResp->res.jsonValue["Version"] = *ver;
346 }
347 break;
348 }
349 }
350 },
351 service, objPath, "org.freedesktop.DBus.Properties", "GetAll",
352 "xyz.openbmc_project.Inventory.Decorator.Revision");
353}
354
Ed Tanous23a21a12020-07-25 04:45:05 +0000355inline void getAcceleratorDataByService(std::shared_ptr<AsyncResp> aResp,
356 const std::string& acclrtrId,
357 const std::string& service,
358 const std::string& objPath)
Alpana Kumari32bee762019-04-25 04:47:57 -0500359{
360 BMCWEB_LOG_DEBUG
361 << "Get available system Accelerator resources by service.";
362 crow::connections::systemBus->async_method_call(
363 [acclrtrId, aResp{std::move(aResp)}](
364 const boost::system::error_code ec,
365 const boost::container::flat_map<
Santosh Puranik94e1b822019-07-24 04:48:32 -0500366 std::string, std::variant<std::string, uint32_t, uint16_t,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500367 bool>>& properties) {
Alpana Kumari32bee762019-04-25 04:47:57 -0500368 if (ec)
369 {
370 BMCWEB_LOG_DEBUG << "DBUS response error";
371 messages::internalError(aResp->res);
372 return;
373 }
374 aResp->res.jsonValue["Id"] = acclrtrId;
375 aResp->res.jsonValue["Name"] = "Processor";
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500376 const bool* accPresent = nullptr;
377 const bool* accFunctional = nullptr;
Alpana Kumari32bee762019-04-25 04:47:57 -0500378
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500379 for (const auto& property : properties)
Alpana Kumari32bee762019-04-25 04:47:57 -0500380 {
381 if (property.first == "Functional")
382 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500383 accFunctional = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500384 }
385 else if (property.first == "Present")
386 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500387 accPresent = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500388 }
389 }
390
Alpana Kumaric24e6b82020-10-01 06:58:46 -0500391 std::string state = "Enabled";
392 std::string health = "OK";
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700393
Alpana Kumaric24e6b82020-10-01 06:58:46 -0500394 if (accPresent != nullptr && *accPresent == false)
Alpana Kumari32bee762019-04-25 04:47:57 -0500395 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700396 state = "Absent";
Alpana Kumari32bee762019-04-25 04:47:57 -0500397 }
Alpana Kumaric24e6b82020-10-01 06:58:46 -0500398
399 if ((accFunctional != nullptr) && (*accFunctional == false))
400 {
401 if (state == "Enabled")
402 {
403 health = "Critical";
404 }
405 else
406 {
407 health = "UnavailableOffline";
408 }
409 }
410
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700411 aResp->res.jsonValue["Status"]["State"] = state;
Alpana Kumaric24e6b82020-10-01 06:58:46 -0500412 aResp->res.jsonValue["Status"]["Health"] = health;
Alpana Kumari32bee762019-04-25 04:47:57 -0500413 aResp->res.jsonValue["ProcessorType"] = "Accelerator";
414 },
415 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
416}
417
Ed Tanous23a21a12020-07-25 04:45:05 +0000418inline void getCpuData(std::shared_ptr<AsyncResp> aResp,
419 const std::string& cpuId,
420 const std::vector<const char*> inventoryItems)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200421{
422 BMCWEB_LOG_DEBUG << "Get available system cpu resources.";
Alpana Kumari32bee762019-04-25 04:47:57 -0500423
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200424 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800425 [cpuId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200426 const boost::system::error_code ec,
427 const boost::container::flat_map<
428 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500429 std::string, std::vector<std::string>>>&
430 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200431 if (ec)
432 {
433 BMCWEB_LOG_DEBUG << "DBUS response error";
434 messages::internalError(aResp->res);
435 return;
436 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500437 for (const auto& object : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200438 {
439 if (boost::ends_with(object.first, cpuId))
440 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500441 for (const auto& service : object.second)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200442 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500443 for (const auto& inventory : service.second)
Zhikui Ren5e54a362020-07-13 15:31:38 -0700444 {
445 if (inventory == "xyz.openbmc_project."
446 "Inventory.Decorator.Asset")
447 {
448 getCpuAssetData(aResp, service.first,
449 object.first);
450 }
451 else if (inventory ==
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700452 "xyz.openbmc_project."
453 "Inventory.Decorator.Revision")
454 {
455 getCpuRevisionData(aResp, service.first,
456 object.first);
457 }
458 else if (inventory == "xyz.openbmc_project."
459 "Inventory.Item.Cpu")
Alpana Kumari32bee762019-04-25 04:47:57 -0500460 {
461 getCpuDataByService(aResp, cpuId, service.first,
462 object.first);
463 }
464 else if (inventory == "xyz.openbmc_project."
465 "Inventory.Item.Accelerator")
466 {
467 getAcceleratorDataByService(
468 aResp, cpuId, service.first, object.first);
469 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700470 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200471 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700472 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200473 }
474 }
475 // Object not found
476 messages::resourceNotFound(aResp->res, "Processor", cpuId);
477 return;
478 },
479 "xyz.openbmc_project.ObjectMapper",
480 "/xyz/openbmc_project/object_mapper",
481 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700482 "/xyz/openbmc_project/inventory", 0, inventoryItems);
483}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200484
James Feistc50e7c62020-07-27 15:39:36 -0700485using DimmProperty =
486 std::variant<std::string, std::vector<uint32_t>, std::vector<uint16_t>,
487 uint64_t, uint32_t, uint16_t, uint8_t, bool>;
488
489using DimmProperties = boost::container::flat_map<std::string, DimmProperty>;
490
Ed Tanous80789c82020-08-19 09:19:09 -0700491inline void dimmPropToHex(std::shared_ptr<AsyncResp> aResp, const char* key,
492 const std::pair<std::string, DimmProperty>& property)
James Feistc50e7c62020-07-27 15:39:36 -0700493{
494 const uint16_t* value = std::get_if<uint16_t>(&property.second);
495 if (value == nullptr)
496 {
497 messages::internalError(aResp->res);
498 BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first;
499 return;
500 }
501
502 aResp->res.jsonValue[key] = (boost::format("0x%04x") % *value).str();
503}
504
Ed Tanous80789c82020-08-19 09:19:09 -0700505inline void getPersistentMemoryProperties(std::shared_ptr<AsyncResp> aResp,
506 const DimmProperties& properties)
James Feistc50e7c62020-07-27 15:39:36 -0700507{
508 for (const auto& property : properties)
509 {
510 if (property.first == "ModuleManufacturerID")
511 {
512 dimmPropToHex(aResp, "ModuleManufacturerID", property);
513 }
514 else if (property.first == "ModuleProductID")
515 {
516 dimmPropToHex(aResp, "ModuleProductID", property);
517 }
518 else if (property.first == "SubsystemVendorID")
519 {
520 dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
521 property);
522 }
523 else if (property.first == "SubsystemDeviceID")
524 {
525 dimmPropToHex(aResp, "MemorySubsystemControllerProductID",
526 property);
527 }
528 else if (property.first == "VolatileRegionSizeLimitInKiB")
529 {
530 const uint64_t* value = std::get_if<uint64_t>(&property.second);
531
532 if (value == nullptr)
533 {
534 messages::internalError(aResp->res);
535 BMCWEB_LOG_DEBUG << "Invalid property type for "
536 "VolatileRegionSizeLimitKiB";
537 continue;
538 }
539 aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10;
540 }
541 else if (property.first == "PmRegionSizeLimitInKiB")
542 {
543 const uint64_t* value = std::get_if<uint64_t>(&property.second);
544
545 if (value == nullptr)
546 {
547 messages::internalError(aResp->res);
548 BMCWEB_LOG_DEBUG
549 << "Invalid property type for PmRegioSizeLimitKiB";
550 continue;
551 }
552 aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] =
553 (*value) >> 10;
554 }
555 else if (property.first == "VolatileSizeInKiB")
556 {
557 const uint64_t* value = std::get_if<uint64_t>(&property.second);
558
559 if (value == nullptr)
560 {
561 messages::internalError(aResp->res);
562 BMCWEB_LOG_DEBUG
563 << "Invalid property type for VolatileSizeInKiB";
564 continue;
565 }
566 aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10;
567 }
568 else if (property.first == "PmSizeInKiB")
569 {
570 const uint64_t* value = std::get_if<uint64_t>(&property.second);
571 if (value == nullptr)
572 {
573 messages::internalError(aResp->res);
574 BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB";
575 continue;
576 }
577 aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10;
578 }
579 else if (property.first == "CacheSizeInKB")
580 {
581 const uint64_t* value = std::get_if<uint64_t>(&property.second);
582 if (value == nullptr)
583 {
584 messages::internalError(aResp->res);
585 BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB";
586 continue;
587 }
588 aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10);
589 }
590
591 else if (property.first == "VoltaileRegionMaxSizeInKib")
592 {
593 const uint64_t* value = std::get_if<uint64_t>(&property.second);
594
595 if (value == nullptr)
596 {
597 messages::internalError(aResp->res);
598 BMCWEB_LOG_DEBUG << "Invalid property type for "
599 "VolatileRegionMaxSizeInKib";
600 continue;
601 }
602 aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10;
603 }
604 else if (property.first == "PmRegionMaxSizeInKiB")
605 {
606 const uint64_t* value = std::get_if<uint64_t>(&property.second);
607
608 if (value == nullptr)
609 {
610 messages::internalError(aResp->res);
611 BMCWEB_LOG_DEBUG
612 << "Invalid property type for PmRegionMaxSizeInKiB";
613 continue;
614 }
615 aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10;
616 }
617 else if (property.first == "AllocationIncrementInKiB")
618 {
619 const uint64_t* value = std::get_if<uint64_t>(&property.second);
620
621 if (value == nullptr)
622 {
623 messages::internalError(aResp->res);
624 BMCWEB_LOG_DEBUG << "Invalid property type for "
625 "AllocationIncrementInKiB";
626 continue;
627 }
628 aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10;
629 }
630 else if (property.first == "AllocationAlignmentInKiB")
631 {
632 const uint64_t* value = std::get_if<uint64_t>(&property.second);
633
634 if (value == nullptr)
635 {
636 messages::internalError(aResp->res);
637 BMCWEB_LOG_DEBUG << "Invalid property type for "
638 "AllocationAlignmentInKiB";
639 continue;
640 }
641 aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10;
642 }
643 else if (property.first == "VolatileRegionNumberLimit")
644 {
645 aResp->res.jsonValue["VolatileRegionNumberLimit"] = property.second;
646 }
647 else if (property.first == "PmRegionNumberLimit")
648 {
649 aResp->res.jsonValue["PersistentRegionNumberLimit"] =
650 property.second;
651 }
652 else if (property.first == "SpareDeviceCount")
653 {
654 aResp->res.jsonValue["SpareDeviceCount"] = property.second;
655 }
656 else if (property.first == "IsSpareDeviceInUse")
657 {
658 aResp->res.jsonValue["IsSpareDeviceEnabled"] = property.second;
659 }
660 else if (property.first == "IsRankSpareEnabled")
661 {
662 aResp->res.jsonValue["IsRankSpareEnabled"] = property.second;
663 }
664 else if (property.first == "MaxAveragePowerLimitmW")
665 {
666 const auto* value =
667 std::get_if<std::vector<uint32_t>>(&property.second);
668 if (value == nullptr)
669 {
670 messages::internalError(aResp->res);
671 BMCWEB_LOG_DEBUG << "Invalid property type for "
672 "MaxAveragePowerLimitmW";
673 continue;
674 }
675 aResp->res.jsonValue["MaxTDPMilliWatts"] = *value;
676 }
677 else if (property.first == "CurrentSecurityState")
678 {
679 aResp->res.jsonValue["SecurityState"] = property.second;
680 }
681 else if (property.first == "ConfigurationLocked")
682 {
683 aResp->res.jsonValue["ConfigurationLocked"] = property.second;
684 }
685 else if (property.first == "AllowedMemoryModes")
686 {
687 const std::string* value =
688 std::get_if<std::string>(&property.second);
689 if (value == nullptr)
690 {
691 messages::internalError(aResp->res);
692 BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor";
693 continue;
694 }
695 constexpr const std::array<const char*, 3> values{"Volatile",
696 "PMEM", "Block"};
697
698 for (const char* v : values)
699 {
700 if (boost::ends_with(*value, v))
701 {
702 aResp->res.jsonValue["OperatingMemoryModes "] = v;
703 break;
704 }
705 }
706 }
707 else if (property.first == "MemoryMedia")
708 {
709 const std::string* value =
710 std::get_if<std::string>(&property.second);
711 if (value == nullptr)
712 {
713 messages::internalError(aResp->res);
714 BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia";
715 continue;
716 }
717 constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
718 "Intel3DXPoint"};
719
720 for (const char* v : values)
721 {
722 if (boost::ends_with(*value, v))
723 {
724 aResp->res.jsonValue["MemoryMedia"] = v;
725 break;
726 }
727 }
728 }
729 // PersistantMemory.PowerManagmentPolicy interface
730 else if (property.first == "AveragePowerBudgetmW" ||
731 property.first == "MaxTDPmW" ||
732 property.first == "PeakPowerBudgetmW" ||
733 property.first == "PolicyEnabled")
734 {
735 std::string name =
736 boost::replace_all_copy(property.first, "mW", "MilliWatts");
737 aResp->res.jsonValue["PowerManagementPolicy"][name] =
738 property.second;
739 }
740 // PersistantMemory.SecurityCapabilites interface
741 else if (property.first == "ConfigurationLockCapable" ||
742 property.first == "DataLockCapable" ||
743 property.first == "MaxPassphraseCount" ||
744 property.first == "PassphraseCapable" ||
745 property.first == "PassphraseLockLimit")
746 {
747 aResp->res.jsonValue["SecurityCapabilities"][property.first] =
748 property.second;
749 }
750 }
751}
752
Ed Tanous80789c82020-08-19 09:19:09 -0700753inline void getDimmDataByService(std::shared_ptr<AsyncResp> aResp,
754 const std::string& dimmId,
755 const std::string& service,
756 const std::string& objPath)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200757{
James Feist35e257a2020-06-05 13:30:51 -0700758 auto health = std::make_shared<HealthPopulate>(aResp);
759 health->selfPath = objPath;
760 health->populate();
761
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200762 BMCWEB_LOG_DEBUG << "Get available system components.";
763 crow::connections::systemBus->async_method_call(
James Feistc50e7c62020-07-27 15:39:36 -0700764 [dimmId, aResp{std::move(aResp)}](const boost::system::error_code ec,
765 const DimmProperties& properties) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200766 if (ec)
767 {
768 BMCWEB_LOG_DEBUG << "DBUS response error";
769 messages::internalError(aResp->res);
770
771 return;
772 }
773 aResp->res.jsonValue["Id"] = dimmId;
774 aResp->res.jsonValue["Name"] = "DIMM Slot";
775
776 const auto memorySizeProperty = properties.find("MemorySizeInKB");
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600777 if (memorySizeProperty != properties.end())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200778 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500779 const uint32_t* memorySize =
Ed Tanousabf2add2019-01-22 16:40:12 -0800780 std::get_if<uint32_t>(&memorySizeProperty->second);
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600781 if (memorySize == nullptr)
782 {
783 // Important property not in desired type
784 messages::internalError(aResp->res);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200785
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600786 return;
787 }
788 if (*memorySize == 0)
789 {
790 // Slot is not populated, set status end return
791 aResp->res.jsonValue["Status"]["State"] = "Absent";
792 aResp->res.jsonValue["Status"]["Health"] = "OK";
793 // HTTP Code will be set up automatically, just return
794 return;
795 }
796 aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200797 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200798 aResp->res.jsonValue["Status"]["State"] = "Enabled";
799 aResp->res.jsonValue["Status"]["Health"] = "OK";
800
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500801 for (const auto& property : properties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200802 {
803 if (property.first == "MemoryDataWidth")
804 {
805 aResp->res.jsonValue["DataWidthBits"] = property.second;
806 }
Manojkiran Eda7e236ca2019-06-25 23:06:32 +0530807 else if (property.first == "PartNumber")
808 {
809 aResp->res.jsonValue["PartNumber"] = property.second;
810 }
811 else if (property.first == "SerialNumber")
812 {
813 aResp->res.jsonValue["SerialNumber"] = property.second;
814 }
815 else if (property.first == "Manufacturer")
816 {
817 aResp->res.jsonValue["Manufacturer"] = property.second;
818 }
James Feistc50e7c62020-07-27 15:39:36 -0700819 else if (property.first == "RevisionCode")
820 {
821 const uint16_t* value =
822 std::get_if<uint16_t>(&property.second);
823
824 if (value == nullptr)
825 {
826 messages::internalError(aResp->res);
827 BMCWEB_LOG_DEBUG
828 << "Invalid property type for RevisionCode";
829 continue;
830 }
831 aResp->res.jsonValue["FirmwareRevision"] =
832 std::to_string(*value);
833 }
834 else if (property.first == "MemoryTotalWidth")
835 {
836 aResp->res.jsonValue["BusWidthBits"] = property.second;
837 }
838 else if (property.first == "ECC")
839 {
840 const std::string* value =
841 std::get_if<std::string>(&property.second);
842 if (value == nullptr)
843 {
844 messages::internalError(aResp->res);
845 BMCWEB_LOG_DEBUG << "Invalid property type for ECC";
846 continue;
847 }
848 constexpr const std::array<const char*, 4> values{
849 "NoECC", "SingleBitECC", "MultiBitECC",
850 "AddressParity"};
851
852 for (const char* v : values)
853 {
854 if (boost::ends_with(*value, v))
855 {
856 aResp->res.jsonValue["ErrorCorrection"] = v;
857 break;
858 }
859 }
860 }
861 else if (property.first == "FormFactor")
862 {
863 const std::string* value =
864 std::get_if<std::string>(&property.second);
865 if (value == nullptr)
866 {
867 messages::internalError(aResp->res);
868 BMCWEB_LOG_DEBUG
869 << "Invalid property type for FormFactor";
870 continue;
871 }
872 constexpr const std::array<const char*, 11> values{
873 "RDIMM", "UDIMM", "SO_DIMM",
874 "LRDIMM", "Mini_RDIMM", "Mini_UDIMM",
875 "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b",
876 "SO_DIMM_32b", "Die"};
877
878 for (const char* v : values)
879 {
880 if (boost::ends_with(*value, v))
881 {
882 aResp->res.jsonValue["BaseModuleType"] = v;
883 break;
884 }
885 }
886 }
887 else if (property.first == "AllowedSpeedsMT")
888 {
889 aResp->res.jsonValue["AllowedSpeedsMHz"] = property.second;
890 }
891 else if (property.first == "MemoryAttributes")
892 {
893 const uint8_t* value =
894 std::get_if<uint8_t>(&property.second);
895
896 if (value == nullptr)
897 {
898 messages::internalError(aResp->res);
899 BMCWEB_LOG_DEBUG
900 << "Invalid property type for MemoryAttributes";
901 continue;
902 }
903 aResp->res.jsonValue["RankCount"] =
904 static_cast<uint64_t>(*value);
905 }
906 else if (property.first == "MemoryConfiguredSpeedInMhz")
907 {
908 aResp->res.jsonValue["OperatingSpeedMhz"] = property.second;
909 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200910 else if (property.first == "MemoryType")
911 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500912 const auto* value =
Ed Tanousabf2add2019-01-22 16:40:12 -0800913 std::get_if<std::string>(&property.second);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200914 if (value != nullptr)
915 {
James Feistc50e7c62020-07-27 15:39:36 -0700916 size_t idx = value->rfind(".");
917 if (idx == std::string::npos ||
918 idx + 1 >= value->size())
919 {
920 messages::internalError(aResp->res);
921 BMCWEB_LOG_DEBUG << "Invalid property type for "
922 "MemoryType";
923 }
924 std::string result = value->substr(idx + 1);
925 aResp->res.jsonValue["MemoryDeviceType"] = result;
926 if (value->find("DDR") != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200927 {
928 aResp->res.jsonValue["MemoryType"] = "DRAM";
929 }
James Feistc50e7c62020-07-27 15:39:36 -0700930 else if (boost::ends_with(*value, "Logical"))
931 {
932 aResp->res.jsonValue["MemoryType"] = "IntelOptane";
933 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200934 }
935 }
James Feistc50e7c62020-07-27 15:39:36 -0700936 // memory location interface
937 else if (property.first == "Channel" ||
938 property.first == "MemoryController" ||
939 property.first == "Slot" || property.first == "Socket")
940 {
941 aResp->res.jsonValue["MemoryLocation"][property.first] =
942 property.second;
943 }
944 else
945 {
946 getPersistentMemoryProperties(aResp, properties);
947 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200948 }
949 },
950 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
951}
952
Ed Tanous23a21a12020-07-25 04:45:05 +0000953inline void getDimmPartitionData(std::shared_ptr<AsyncResp> aResp,
954 const std::string& service,
955 const std::string& path)
James Feist45094ad2020-04-29 14:02:30 -0700956{
957 crow::connections::systemBus->async_method_call(
958 [aResp{std::move(aResp)}](
959 const boost::system::error_code ec,
960 const boost::container::flat_map<
961 std::string, std::variant<std::string, uint64_t, uint32_t,
962 bool>>& properties) {
963 if (ec)
964 {
965 BMCWEB_LOG_DEBUG << "DBUS response error";
966 messages::internalError(aResp->res);
967
968 return;
969 }
970
971 nlohmann::json& partition =
972 aResp->res.jsonValue["Regions"].emplace_back(
973 nlohmann::json::object());
974 for (const auto& [key, val] : properties)
975 {
976 if (key == "MemoryClassification")
977 {
978 partition[key] = val;
979 }
980 else if (key == "OffsetInKiB")
981 {
982 const uint64_t* value = std::get_if<uint64_t>(&val);
983 if (value == nullptr)
984 {
985 messages::internalError(aResp->res);
986 BMCWEB_LOG_DEBUG
987 << "Invalid property type for OffsetInKiB";
988 continue;
989 }
990
991 partition["OffsetMiB"] = (*value >> 10);
992 }
993 else if (key == "PartitionId")
994 {
995 partition["RegionId"] = val;
996 }
997
998 else if (key == "PassphraseState")
999 {
1000 partition["PassphraseEnabled"] = val;
1001 }
1002 else if (key == "SizeInKiB")
1003 {
1004 const uint64_t* value = std::get_if<uint64_t>(&val);
1005 if (value == nullptr)
1006 {
1007 messages::internalError(aResp->res);
1008 BMCWEB_LOG_DEBUG
1009 << "Invalid property type for SizeInKiB";
1010 continue;
1011 }
1012 partition["SizeMiB"] = (*value >> 10);
1013 }
1014 }
1015 },
1016
1017 service, path, "org.freedesktop.DBus.Properties", "GetAll",
1018 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition");
1019}
1020
Ed Tanous23a21a12020-07-25 04:45:05 +00001021inline void getDimmData(std::shared_ptr<AsyncResp> aResp,
1022 const std::string& dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001023{
1024 BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
1025 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -08001026 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001027 const boost::system::error_code ec,
1028 const boost::container::flat_map<
1029 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001030 std::string, std::vector<std::string>>>&
1031 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001032 if (ec)
1033 {
1034 BMCWEB_LOG_DEBUG << "DBUS response error";
1035 messages::internalError(aResp->res);
1036
1037 return;
1038 }
James Feist45094ad2020-04-29 14:02:30 -07001039 bool found = false;
1040 for (const auto& [path, object] : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001041 {
James Feist45094ad2020-04-29 14:02:30 -07001042 if (path.find(dimmId) != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001043 {
James Feist45094ad2020-04-29 14:02:30 -07001044 for (const auto& [service, interfaces] : object)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001045 {
James Feist45094ad2020-04-29 14:02:30 -07001046 if (!found &&
1047 (std::find(
1048 interfaces.begin(), interfaces.end(),
1049 "xyz.openbmc_project.Inventory.Item.Dimm") !=
1050 interfaces.end()))
1051 {
1052 getDimmDataByService(aResp, dimmId, service, path);
1053 found = true;
1054 }
1055
1056 // partitions are separate as there can be multiple per
1057 // device, i.e.
1058 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
1059 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
1060 if (std::find(interfaces.begin(), interfaces.end(),
1061 "xyz.openbmc_project.Inventory.Item."
1062 "PersistentMemory.Partition") !=
1063 interfaces.end())
1064 {
1065 getDimmPartitionData(aResp, service, path);
1066 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001067 }
1068 }
1069 }
1070 // Object not found
James Feist45094ad2020-04-29 14:02:30 -07001071 if (!found)
1072 {
1073 messages::resourceNotFound(aResp->res, "Memory", dimmId);
1074 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001075 return;
1076 },
1077 "xyz.openbmc_project.ObjectMapper",
1078 "/xyz/openbmc_project/object_mapper",
1079 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -07001080 "/xyz/openbmc_project/inventory", 0,
James Feist45094ad2020-04-29 14:02:30 -07001081 std::array<const char*, 2>{
1082 "xyz.openbmc_project.Inventory.Item.Dimm",
1083 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
Ed Tanous271584a2019-07-09 16:24:22 -07001084}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001085
1086class ProcessorCollection : public Node
1087{
1088 public:
1089 /*
1090 * Default Constructor
1091 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001092 ProcessorCollection(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001093 Node(app, "/redfish/v1/Systems/system/Processors/")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001094 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001095 entityPrivileges = {
1096 {boost::beast::http::verb::get, {{"Login"}}},
1097 {boost::beast::http::verb::head, {{"Login"}}},
1098 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1099 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1100 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1101 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1102 }
1103
1104 private:
1105 /**
1106 * Functions triggers appropriate requests on DBus
1107 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001108 void doGet(crow::Response& res, const crow::Request&,
1109 const std::vector<std::string>&) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001110 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001111 res.jsonValue["@odata.type"] =
1112 "#ProcessorCollection.ProcessorCollection";
1113 res.jsonValue["Name"] = "Processor Collection";
Ed Tanous0f74e642018-11-12 15:17:05 -08001114
Ed Tanous029573d2019-02-01 10:57:49 -08001115 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001116 auto asyncResp = std::make_shared<AsyncResp>(res);
1117
Ed Tanous029573d2019-02-01 10:57:49 -08001118 getResourceList(asyncResp, "Processors",
Alpana Kumari32bee762019-04-25 04:47:57 -05001119 {"xyz.openbmc_project.Inventory.Item.Cpu",
1120 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001121 }
1122};
1123
1124class Processor : public Node
1125{
1126 public:
1127 /*
1128 * Default Constructor
1129 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001130 Processor(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001131 Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001132 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001133 entityPrivileges = {
1134 {boost::beast::http::verb::get, {{"Login"}}},
1135 {boost::beast::http::verb::head, {{"Login"}}},
1136 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1137 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1138 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1139 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1140 }
1141
1142 private:
1143 /**
1144 * Functions triggers appropriate requests on DBus
1145 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001146 void doGet(crow::Response& res, const crow::Request&,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001147 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001148 {
1149 // Check if there is required param, truly entering this shall be
1150 // impossible
1151 if (params.size() != 1)
1152 {
1153 messages::internalError(res);
1154
1155 res.end();
1156 return;
1157 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001158 const std::string& processorId = params[0];
Zhikui Ren029cc1f2020-08-25 15:21:41 -07001159 res.jsonValue["@odata.type"] = "#Processor.v1_9_0.Processor";
Ed Tanous029573d2019-02-01 10:57:49 -08001160 res.jsonValue["@odata.id"] =
Alpana Kumari32bee762019-04-25 04:47:57 -05001161 "/redfish/v1/Systems/system/Processors/" + processorId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001162
Ed Tanous029573d2019-02-01 10:57:49 -08001163 auto asyncResp = std::make_shared<AsyncResp>(res);
1164
Alpana Kumari32bee762019-04-25 04:47:57 -05001165 getCpuData(asyncResp, processorId,
1166 {"xyz.openbmc_project.Inventory.Item.Cpu",
Zhikui Ren5e54a362020-07-13 15:31:38 -07001167 "xyz.openbmc_project.Inventory.Decorator.Asset",
Alpana Kumari32bee762019-04-25 04:47:57 -05001168 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Ed Tanous029573d2019-02-01 10:57:49 -08001169 }
1170};
1171
1172class MemoryCollection : public Node
1173{
1174 public:
1175 /*
1176 * Default Constructor
1177 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001178 MemoryCollection(App& app) : Node(app, "/redfish/v1/Systems/system/Memory/")
Ed Tanous029573d2019-02-01 10:57:49 -08001179 {
1180 entityPrivileges = {
1181 {boost::beast::http::verb::get, {{"Login"}}},
1182 {boost::beast::http::verb::head, {{"Login"}}},
1183 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1184 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1185 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1186 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1187 }
1188
1189 private:
1190 /**
1191 * Functions triggers appropriate requests on DBus
1192 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001193 void doGet(crow::Response& res, const crow::Request&,
1194 const std::vector<std::string>&) override
Ed Tanous029573d2019-02-01 10:57:49 -08001195 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001196 res.jsonValue["@odata.type"] = "#MemoryCollection.MemoryCollection";
1197 res.jsonValue["Name"] = "Memory Module Collection";
James Feistc50e7c62020-07-27 15:39:36 -07001198 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001199 auto asyncResp = std::make_shared<AsyncResp>(res);
1200
Ed Tanous029573d2019-02-01 10:57:49 -08001201 getResourceList(asyncResp, "Memory",
Alpana Kumari32bee762019-04-25 04:47:57 -05001202 {"xyz.openbmc_project.Inventory.Item.Dimm"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001203 }
1204};
1205
1206class Memory : public Node
1207{
1208 public:
1209 /*
1210 * Default Constructor
1211 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001212 Memory(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001213 Node(app, "/redfish/v1/Systems/system/Memory/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001214 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001215 entityPrivileges = {
1216 {boost::beast::http::verb::get, {{"Login"}}},
1217 {boost::beast::http::verb::head, {{"Login"}}},
1218 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1219 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1220 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1221 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1222 }
1223
1224 private:
1225 /**
1226 * Functions triggers appropriate requests on DBus
1227 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001228 void doGet(crow::Response& res, const crow::Request&,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001229 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001230 {
1231 // Check if there is required param, truly entering this shall be
1232 // impossible
Ed Tanous029573d2019-02-01 10:57:49 -08001233 if (params.size() != 1)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001234 {
1235 messages::internalError(res);
1236 res.end();
1237 return;
1238 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001239 const std::string& dimmId = params[0];
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001240
James Feistc50e7c62020-07-27 15:39:36 -07001241 res.jsonValue["@odata.type"] = "#Memory.v1_7_0.Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001242 res.jsonValue["@odata.id"] =
Ed Tanous029573d2019-02-01 10:57:49 -08001243 "/redfish/v1/Systems/system/Memory/" + dimmId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001244 auto asyncResp = std::make_shared<AsyncResp>(res);
1245
Ed Tanous029573d2019-02-01 10:57:49 -08001246 getDimmData(asyncResp, dimmId);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001247 }
1248};
1249
1250} // namespace redfish