blob: 9b9d9cb0242c5ff6ac58565c0ce922fd3583d828 [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;
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700378 std::string state = "";
Alpana Kumari32bee762019-04-25 04:47:57 -0500379
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500380 for (const auto& property : properties)
Alpana Kumari32bee762019-04-25 04:47:57 -0500381 {
382 if (property.first == "Functional")
383 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500384 accFunctional = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500385 }
386 else if (property.first == "Present")
387 {
Santosh Puranik94e1b822019-07-24 04:48:32 -0500388 accPresent = std::get_if<bool>(&property.second);
Alpana Kumari32bee762019-04-25 04:47:57 -0500389 }
390 }
391
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700392 if (!accPresent || !accFunctional)
Alpana Kumari32bee762019-04-25 04:47:57 -0500393 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700394 BMCWEB_LOG_DEBUG << "Required properties missing in DBUS "
395 "response";
396 messages::internalError(aResp->res);
397 return;
398 }
399
400 if (*accPresent && *accFunctional)
401 {
402 state = "Enabled";
403 }
404 else if (*accPresent)
405 {
406 state = "UnavailableOffline";
Alpana Kumari32bee762019-04-25 04:47:57 -0500407 }
408 else
409 {
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700410 state = "Absent";
Alpana Kumari32bee762019-04-25 04:47:57 -0500411 }
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700412 aResp->res.jsonValue["Status"]["State"] = state;
413 aResp->res.jsonValue["Status"]["Health"] = "OK";
Alpana Kumari32bee762019-04-25 04:47:57 -0500414 aResp->res.jsonValue["ProcessorType"] = "Accelerator";
415 },
416 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
417}
418
Ed Tanous23a21a12020-07-25 04:45:05 +0000419inline void getCpuData(std::shared_ptr<AsyncResp> aResp,
420 const std::string& cpuId,
421 const std::vector<const char*> inventoryItems)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200422{
423 BMCWEB_LOG_DEBUG << "Get available system cpu resources.";
Alpana Kumari32bee762019-04-25 04:47:57 -0500424
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200425 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -0800426 [cpuId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200427 const boost::system::error_code ec,
428 const boost::container::flat_map<
429 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500430 std::string, std::vector<std::string>>>&
431 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200432 if (ec)
433 {
434 BMCWEB_LOG_DEBUG << "DBUS response error";
435 messages::internalError(aResp->res);
436 return;
437 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500438 for (const auto& object : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200439 {
440 if (boost::ends_with(object.first, cpuId))
441 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500442 for (const auto& service : object.second)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200443 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500444 for (const auto& inventory : service.second)
Zhikui Ren5e54a362020-07-13 15:31:38 -0700445 {
446 if (inventory == "xyz.openbmc_project."
447 "Inventory.Decorator.Asset")
448 {
449 getCpuAssetData(aResp, service.first,
450 object.first);
451 }
452 else if (inventory ==
Zhikui Ren029cc1f2020-08-25 15:21:41 -0700453 "xyz.openbmc_project."
454 "Inventory.Decorator.Revision")
455 {
456 getCpuRevisionData(aResp, service.first,
457 object.first);
458 }
459 else if (inventory == "xyz.openbmc_project."
460 "Inventory.Item.Cpu")
Alpana Kumari32bee762019-04-25 04:47:57 -0500461 {
462 getCpuDataByService(aResp, cpuId, service.first,
463 object.first);
464 }
465 else if (inventory == "xyz.openbmc_project."
466 "Inventory.Item.Accelerator")
467 {
468 getAcceleratorDataByService(
469 aResp, cpuId, service.first, object.first);
470 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700471 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200472 }
Zhikui Ren5e54a362020-07-13 15:31:38 -0700473 return;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200474 }
475 }
476 // Object not found
477 messages::resourceNotFound(aResp->res, "Processor", cpuId);
478 return;
479 },
480 "xyz.openbmc_project.ObjectMapper",
481 "/xyz/openbmc_project/object_mapper",
482 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700483 "/xyz/openbmc_project/inventory", 0, inventoryItems);
484}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200485
James Feistc50e7c62020-07-27 15:39:36 -0700486using DimmProperty =
487 std::variant<std::string, std::vector<uint32_t>, std::vector<uint16_t>,
488 uint64_t, uint32_t, uint16_t, uint8_t, bool>;
489
490using DimmProperties = boost::container::flat_map<std::string, DimmProperty>;
491
Ed Tanous80789c82020-08-19 09:19:09 -0700492inline void dimmPropToHex(std::shared_ptr<AsyncResp> aResp, const char* key,
493 const std::pair<std::string, DimmProperty>& property)
James Feistc50e7c62020-07-27 15:39:36 -0700494{
495 const uint16_t* value = std::get_if<uint16_t>(&property.second);
496 if (value == nullptr)
497 {
498 messages::internalError(aResp->res);
499 BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first;
500 return;
501 }
502
503 aResp->res.jsonValue[key] = (boost::format("0x%04x") % *value).str();
504}
505
Ed Tanous80789c82020-08-19 09:19:09 -0700506inline void getPersistentMemoryProperties(std::shared_ptr<AsyncResp> aResp,
507 const DimmProperties& properties)
James Feistc50e7c62020-07-27 15:39:36 -0700508{
509 for (const auto& property : properties)
510 {
511 if (property.first == "ModuleManufacturerID")
512 {
513 dimmPropToHex(aResp, "ModuleManufacturerID", property);
514 }
515 else if (property.first == "ModuleProductID")
516 {
517 dimmPropToHex(aResp, "ModuleProductID", property);
518 }
519 else if (property.first == "SubsystemVendorID")
520 {
521 dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
522 property);
523 }
524 else if (property.first == "SubsystemDeviceID")
525 {
526 dimmPropToHex(aResp, "MemorySubsystemControllerProductID",
527 property);
528 }
529 else if (property.first == "VolatileRegionSizeLimitInKiB")
530 {
531 const uint64_t* value = std::get_if<uint64_t>(&property.second);
532
533 if (value == nullptr)
534 {
535 messages::internalError(aResp->res);
536 BMCWEB_LOG_DEBUG << "Invalid property type for "
537 "VolatileRegionSizeLimitKiB";
538 continue;
539 }
540 aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10;
541 }
542 else if (property.first == "PmRegionSizeLimitInKiB")
543 {
544 const uint64_t* value = std::get_if<uint64_t>(&property.second);
545
546 if (value == nullptr)
547 {
548 messages::internalError(aResp->res);
549 BMCWEB_LOG_DEBUG
550 << "Invalid property type for PmRegioSizeLimitKiB";
551 continue;
552 }
553 aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] =
554 (*value) >> 10;
555 }
556 else if (property.first == "VolatileSizeInKiB")
557 {
558 const uint64_t* value = std::get_if<uint64_t>(&property.second);
559
560 if (value == nullptr)
561 {
562 messages::internalError(aResp->res);
563 BMCWEB_LOG_DEBUG
564 << "Invalid property type for VolatileSizeInKiB";
565 continue;
566 }
567 aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10;
568 }
569 else if (property.first == "PmSizeInKiB")
570 {
571 const uint64_t* value = std::get_if<uint64_t>(&property.second);
572 if (value == nullptr)
573 {
574 messages::internalError(aResp->res);
575 BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB";
576 continue;
577 }
578 aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10;
579 }
580 else if (property.first == "CacheSizeInKB")
581 {
582 const uint64_t* value = std::get_if<uint64_t>(&property.second);
583 if (value == nullptr)
584 {
585 messages::internalError(aResp->res);
586 BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB";
587 continue;
588 }
589 aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10);
590 }
591
592 else if (property.first == "VoltaileRegionMaxSizeInKib")
593 {
594 const uint64_t* value = std::get_if<uint64_t>(&property.second);
595
596 if (value == nullptr)
597 {
598 messages::internalError(aResp->res);
599 BMCWEB_LOG_DEBUG << "Invalid property type for "
600 "VolatileRegionMaxSizeInKib";
601 continue;
602 }
603 aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10;
604 }
605 else if (property.first == "PmRegionMaxSizeInKiB")
606 {
607 const uint64_t* value = std::get_if<uint64_t>(&property.second);
608
609 if (value == nullptr)
610 {
611 messages::internalError(aResp->res);
612 BMCWEB_LOG_DEBUG
613 << "Invalid property type for PmRegionMaxSizeInKiB";
614 continue;
615 }
616 aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10;
617 }
618 else if (property.first == "AllocationIncrementInKiB")
619 {
620 const uint64_t* value = std::get_if<uint64_t>(&property.second);
621
622 if (value == nullptr)
623 {
624 messages::internalError(aResp->res);
625 BMCWEB_LOG_DEBUG << "Invalid property type for "
626 "AllocationIncrementInKiB";
627 continue;
628 }
629 aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10;
630 }
631 else if (property.first == "AllocationAlignmentInKiB")
632 {
633 const uint64_t* value = std::get_if<uint64_t>(&property.second);
634
635 if (value == nullptr)
636 {
637 messages::internalError(aResp->res);
638 BMCWEB_LOG_DEBUG << "Invalid property type for "
639 "AllocationAlignmentInKiB";
640 continue;
641 }
642 aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10;
643 }
644 else if (property.first == "VolatileRegionNumberLimit")
645 {
646 aResp->res.jsonValue["VolatileRegionNumberLimit"] = property.second;
647 }
648 else if (property.first == "PmRegionNumberLimit")
649 {
650 aResp->res.jsonValue["PersistentRegionNumberLimit"] =
651 property.second;
652 }
653 else if (property.first == "SpareDeviceCount")
654 {
655 aResp->res.jsonValue["SpareDeviceCount"] = property.second;
656 }
657 else if (property.first == "IsSpareDeviceInUse")
658 {
659 aResp->res.jsonValue["IsSpareDeviceEnabled"] = property.second;
660 }
661 else if (property.first == "IsRankSpareEnabled")
662 {
663 aResp->res.jsonValue["IsRankSpareEnabled"] = property.second;
664 }
665 else if (property.first == "MaxAveragePowerLimitmW")
666 {
667 const auto* value =
668 std::get_if<std::vector<uint32_t>>(&property.second);
669 if (value == nullptr)
670 {
671 messages::internalError(aResp->res);
672 BMCWEB_LOG_DEBUG << "Invalid property type for "
673 "MaxAveragePowerLimitmW";
674 continue;
675 }
676 aResp->res.jsonValue["MaxTDPMilliWatts"] = *value;
677 }
678 else if (property.first == "CurrentSecurityState")
679 {
680 aResp->res.jsonValue["SecurityState"] = property.second;
681 }
682 else if (property.first == "ConfigurationLocked")
683 {
684 aResp->res.jsonValue["ConfigurationLocked"] = property.second;
685 }
686 else if (property.first == "AllowedMemoryModes")
687 {
688 const std::string* value =
689 std::get_if<std::string>(&property.second);
690 if (value == nullptr)
691 {
692 messages::internalError(aResp->res);
693 BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor";
694 continue;
695 }
696 constexpr const std::array<const char*, 3> values{"Volatile",
697 "PMEM", "Block"};
698
699 for (const char* v : values)
700 {
701 if (boost::ends_with(*value, v))
702 {
703 aResp->res.jsonValue["OperatingMemoryModes "] = v;
704 break;
705 }
706 }
707 }
708 else if (property.first == "MemoryMedia")
709 {
710 const std::string* value =
711 std::get_if<std::string>(&property.second);
712 if (value == nullptr)
713 {
714 messages::internalError(aResp->res);
715 BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia";
716 continue;
717 }
718 constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
719 "Intel3DXPoint"};
720
721 for (const char* v : values)
722 {
723 if (boost::ends_with(*value, v))
724 {
725 aResp->res.jsonValue["MemoryMedia"] = v;
726 break;
727 }
728 }
729 }
730 // PersistantMemory.PowerManagmentPolicy interface
731 else if (property.first == "AveragePowerBudgetmW" ||
732 property.first == "MaxTDPmW" ||
733 property.first == "PeakPowerBudgetmW" ||
734 property.first == "PolicyEnabled")
735 {
736 std::string name =
737 boost::replace_all_copy(property.first, "mW", "MilliWatts");
738 aResp->res.jsonValue["PowerManagementPolicy"][name] =
739 property.second;
740 }
741 // PersistantMemory.SecurityCapabilites interface
742 else if (property.first == "ConfigurationLockCapable" ||
743 property.first == "DataLockCapable" ||
744 property.first == "MaxPassphraseCount" ||
745 property.first == "PassphraseCapable" ||
746 property.first == "PassphraseLockLimit")
747 {
748 aResp->res.jsonValue["SecurityCapabilities"][property.first] =
749 property.second;
750 }
751 }
752}
753
Ed Tanous80789c82020-08-19 09:19:09 -0700754inline void getDimmDataByService(std::shared_ptr<AsyncResp> aResp,
755 const std::string& dimmId,
756 const std::string& service,
757 const std::string& objPath)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200758{
James Feist35e257a2020-06-05 13:30:51 -0700759 auto health = std::make_shared<HealthPopulate>(aResp);
760 health->selfPath = objPath;
761 health->populate();
762
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200763 BMCWEB_LOG_DEBUG << "Get available system components.";
764 crow::connections::systemBus->async_method_call(
James Feistc50e7c62020-07-27 15:39:36 -0700765 [dimmId, aResp{std::move(aResp)}](const boost::system::error_code ec,
766 const DimmProperties& properties) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200767 if (ec)
768 {
769 BMCWEB_LOG_DEBUG << "DBUS response error";
770 messages::internalError(aResp->res);
771
772 return;
773 }
774 aResp->res.jsonValue["Id"] = dimmId;
775 aResp->res.jsonValue["Name"] = "DIMM Slot";
776
777 const auto memorySizeProperty = properties.find("MemorySizeInKB");
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600778 if (memorySizeProperty != properties.end())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200779 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500780 const uint32_t* memorySize =
Ed Tanousabf2add2019-01-22 16:40:12 -0800781 std::get_if<uint32_t>(&memorySizeProperty->second);
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600782 if (memorySize == nullptr)
783 {
784 // Important property not in desired type
785 messages::internalError(aResp->res);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200786
Gunnar Millsaceb7fc2018-12-10 15:17:20 -0600787 return;
788 }
789 if (*memorySize == 0)
790 {
791 // Slot is not populated, set status end return
792 aResp->res.jsonValue["Status"]["State"] = "Absent";
793 aResp->res.jsonValue["Status"]["Health"] = "OK";
794 // HTTP Code will be set up automatically, just return
795 return;
796 }
797 aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200798 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200799 aResp->res.jsonValue["Status"]["State"] = "Enabled";
800 aResp->res.jsonValue["Status"]["Health"] = "OK";
801
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500802 for (const auto& property : properties)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200803 {
804 if (property.first == "MemoryDataWidth")
805 {
806 aResp->res.jsonValue["DataWidthBits"] = property.second;
807 }
Manojkiran Eda7e236ca2019-06-25 23:06:32 +0530808 else if (property.first == "PartNumber")
809 {
810 aResp->res.jsonValue["PartNumber"] = property.second;
811 }
812 else if (property.first == "SerialNumber")
813 {
814 aResp->res.jsonValue["SerialNumber"] = property.second;
815 }
816 else if (property.first == "Manufacturer")
817 {
818 aResp->res.jsonValue["Manufacturer"] = property.second;
819 }
James Feistc50e7c62020-07-27 15:39:36 -0700820 else if (property.first == "RevisionCode")
821 {
822 const uint16_t* value =
823 std::get_if<uint16_t>(&property.second);
824
825 if (value == nullptr)
826 {
827 messages::internalError(aResp->res);
828 BMCWEB_LOG_DEBUG
829 << "Invalid property type for RevisionCode";
830 continue;
831 }
832 aResp->res.jsonValue["FirmwareRevision"] =
833 std::to_string(*value);
834 }
835 else if (property.first == "MemoryTotalWidth")
836 {
837 aResp->res.jsonValue["BusWidthBits"] = property.second;
838 }
839 else if (property.first == "ECC")
840 {
841 const std::string* value =
842 std::get_if<std::string>(&property.second);
843 if (value == nullptr)
844 {
845 messages::internalError(aResp->res);
846 BMCWEB_LOG_DEBUG << "Invalid property type for ECC";
847 continue;
848 }
849 constexpr const std::array<const char*, 4> values{
850 "NoECC", "SingleBitECC", "MultiBitECC",
851 "AddressParity"};
852
853 for (const char* v : values)
854 {
855 if (boost::ends_with(*value, v))
856 {
857 aResp->res.jsonValue["ErrorCorrection"] = v;
858 break;
859 }
860 }
861 }
862 else if (property.first == "FormFactor")
863 {
864 const std::string* value =
865 std::get_if<std::string>(&property.second);
866 if (value == nullptr)
867 {
868 messages::internalError(aResp->res);
869 BMCWEB_LOG_DEBUG
870 << "Invalid property type for FormFactor";
871 continue;
872 }
873 constexpr const std::array<const char*, 11> values{
874 "RDIMM", "UDIMM", "SO_DIMM",
875 "LRDIMM", "Mini_RDIMM", "Mini_UDIMM",
876 "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b",
877 "SO_DIMM_32b", "Die"};
878
879 for (const char* v : values)
880 {
881 if (boost::ends_with(*value, v))
882 {
883 aResp->res.jsonValue["BaseModuleType"] = v;
884 break;
885 }
886 }
887 }
888 else if (property.first == "AllowedSpeedsMT")
889 {
890 aResp->res.jsonValue["AllowedSpeedsMHz"] = property.second;
891 }
892 else if (property.first == "MemoryAttributes")
893 {
894 const uint8_t* value =
895 std::get_if<uint8_t>(&property.second);
896
897 if (value == nullptr)
898 {
899 messages::internalError(aResp->res);
900 BMCWEB_LOG_DEBUG
901 << "Invalid property type for MemoryAttributes";
902 continue;
903 }
904 aResp->res.jsonValue["RankCount"] =
905 static_cast<uint64_t>(*value);
906 }
907 else if (property.first == "MemoryConfiguredSpeedInMhz")
908 {
909 aResp->res.jsonValue["OperatingSpeedMhz"] = property.second;
910 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200911 else if (property.first == "MemoryType")
912 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500913 const auto* value =
Ed Tanousabf2add2019-01-22 16:40:12 -0800914 std::get_if<std::string>(&property.second);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200915 if (value != nullptr)
916 {
James Feistc50e7c62020-07-27 15:39:36 -0700917 size_t idx = value->rfind(".");
918 if (idx == std::string::npos ||
919 idx + 1 >= value->size())
920 {
921 messages::internalError(aResp->res);
922 BMCWEB_LOG_DEBUG << "Invalid property type for "
923 "MemoryType";
924 }
925 std::string result = value->substr(idx + 1);
926 aResp->res.jsonValue["MemoryDeviceType"] = result;
927 if (value->find("DDR") != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200928 {
929 aResp->res.jsonValue["MemoryType"] = "DRAM";
930 }
James Feistc50e7c62020-07-27 15:39:36 -0700931 else if (boost::ends_with(*value, "Logical"))
932 {
933 aResp->res.jsonValue["MemoryType"] = "IntelOptane";
934 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200935 }
936 }
James Feistc50e7c62020-07-27 15:39:36 -0700937 // memory location interface
938 else if (property.first == "Channel" ||
939 property.first == "MemoryController" ||
940 property.first == "Slot" || property.first == "Socket")
941 {
942 aResp->res.jsonValue["MemoryLocation"][property.first] =
943 property.second;
944 }
945 else
946 {
947 getPersistentMemoryProperties(aResp, properties);
948 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200949 }
950 },
951 service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
952}
953
Ed Tanous23a21a12020-07-25 04:45:05 +0000954inline void getDimmPartitionData(std::shared_ptr<AsyncResp> aResp,
955 const std::string& service,
956 const std::string& path)
James Feist45094ad2020-04-29 14:02:30 -0700957{
958 crow::connections::systemBus->async_method_call(
959 [aResp{std::move(aResp)}](
960 const boost::system::error_code ec,
961 const boost::container::flat_map<
962 std::string, std::variant<std::string, uint64_t, uint32_t,
963 bool>>& properties) {
964 if (ec)
965 {
966 BMCWEB_LOG_DEBUG << "DBUS response error";
967 messages::internalError(aResp->res);
968
969 return;
970 }
971
972 nlohmann::json& partition =
973 aResp->res.jsonValue["Regions"].emplace_back(
974 nlohmann::json::object());
975 for (const auto& [key, val] : properties)
976 {
977 if (key == "MemoryClassification")
978 {
979 partition[key] = val;
980 }
981 else if (key == "OffsetInKiB")
982 {
983 const uint64_t* value = std::get_if<uint64_t>(&val);
984 if (value == nullptr)
985 {
986 messages::internalError(aResp->res);
987 BMCWEB_LOG_DEBUG
988 << "Invalid property type for OffsetInKiB";
989 continue;
990 }
991
992 partition["OffsetMiB"] = (*value >> 10);
993 }
994 else if (key == "PartitionId")
995 {
996 partition["RegionId"] = val;
997 }
998
999 else if (key == "PassphraseState")
1000 {
1001 partition["PassphraseEnabled"] = val;
1002 }
1003 else if (key == "SizeInKiB")
1004 {
1005 const uint64_t* value = std::get_if<uint64_t>(&val);
1006 if (value == nullptr)
1007 {
1008 messages::internalError(aResp->res);
1009 BMCWEB_LOG_DEBUG
1010 << "Invalid property type for SizeInKiB";
1011 continue;
1012 }
1013 partition["SizeMiB"] = (*value >> 10);
1014 }
1015 }
1016 },
1017
1018 service, path, "org.freedesktop.DBus.Properties", "GetAll",
1019 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition");
1020}
1021
Ed Tanous23a21a12020-07-25 04:45:05 +00001022inline void getDimmData(std::shared_ptr<AsyncResp> aResp,
1023 const std::string& dimmId)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001024{
1025 BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
1026 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -08001027 [dimmId, aResp{std::move(aResp)}](
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001028 const boost::system::error_code ec,
1029 const boost::container::flat_map<
1030 std::string, boost::container::flat_map<
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001031 std::string, std::vector<std::string>>>&
1032 subtree) {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001033 if (ec)
1034 {
1035 BMCWEB_LOG_DEBUG << "DBUS response error";
1036 messages::internalError(aResp->res);
1037
1038 return;
1039 }
James Feist45094ad2020-04-29 14:02:30 -07001040 bool found = false;
1041 for (const auto& [path, object] : subtree)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001042 {
James Feist45094ad2020-04-29 14:02:30 -07001043 if (path.find(dimmId) != std::string::npos)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001044 {
James Feist45094ad2020-04-29 14:02:30 -07001045 for (const auto& [service, interfaces] : object)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001046 {
James Feist45094ad2020-04-29 14:02:30 -07001047 if (!found &&
1048 (std::find(
1049 interfaces.begin(), interfaces.end(),
1050 "xyz.openbmc_project.Inventory.Item.Dimm") !=
1051 interfaces.end()))
1052 {
1053 getDimmDataByService(aResp, dimmId, service, path);
1054 found = true;
1055 }
1056
1057 // partitions are separate as there can be multiple per
1058 // device, i.e.
1059 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
1060 // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
1061 if (std::find(interfaces.begin(), interfaces.end(),
1062 "xyz.openbmc_project.Inventory.Item."
1063 "PersistentMemory.Partition") !=
1064 interfaces.end())
1065 {
1066 getDimmPartitionData(aResp, service, path);
1067 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001068 }
1069 }
1070 }
1071 // Object not found
James Feist45094ad2020-04-29 14:02:30 -07001072 if (!found)
1073 {
1074 messages::resourceNotFound(aResp->res, "Memory", dimmId);
1075 }
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001076 return;
1077 },
1078 "xyz.openbmc_project.ObjectMapper",
1079 "/xyz/openbmc_project/object_mapper",
1080 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -07001081 "/xyz/openbmc_project/inventory", 0,
James Feist45094ad2020-04-29 14:02:30 -07001082 std::array<const char*, 2>{
1083 "xyz.openbmc_project.Inventory.Item.Dimm",
1084 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
Ed Tanous271584a2019-07-09 16:24:22 -07001085}
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001086
1087class ProcessorCollection : public Node
1088{
1089 public:
1090 /*
1091 * Default Constructor
1092 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001093 ProcessorCollection(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001094 Node(app, "/redfish/v1/Systems/system/Processors/")
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001095 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001096 entityPrivileges = {
1097 {boost::beast::http::verb::get, {{"Login"}}},
1098 {boost::beast::http::verb::head, {{"Login"}}},
1099 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1100 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1101 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1102 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1103 }
1104
1105 private:
1106 /**
1107 * Functions triggers appropriate requests on DBus
1108 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001109 void doGet(crow::Response& res, const crow::Request&,
1110 const std::vector<std::string>&) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001111 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001112 res.jsonValue["@odata.type"] =
1113 "#ProcessorCollection.ProcessorCollection";
1114 res.jsonValue["Name"] = "Processor Collection";
Ed Tanous0f74e642018-11-12 15:17:05 -08001115
Ed Tanous029573d2019-02-01 10:57:49 -08001116 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001117 auto asyncResp = std::make_shared<AsyncResp>(res);
1118
Ed Tanous029573d2019-02-01 10:57:49 -08001119 getResourceList(asyncResp, "Processors",
Alpana Kumari32bee762019-04-25 04:47:57 -05001120 {"xyz.openbmc_project.Inventory.Item.Cpu",
1121 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001122 }
1123};
1124
1125class Processor : public Node
1126{
1127 public:
1128 /*
1129 * Default Constructor
1130 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001131 Processor(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001132 Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001133 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001134 entityPrivileges = {
1135 {boost::beast::http::verb::get, {{"Login"}}},
1136 {boost::beast::http::verb::head, {{"Login"}}},
1137 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1138 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1139 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1140 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1141 }
1142
1143 private:
1144 /**
1145 * Functions triggers appropriate requests on DBus
1146 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001147 void doGet(crow::Response& res, const crow::Request&,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001148 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001149 {
1150 // Check if there is required param, truly entering this shall be
1151 // impossible
1152 if (params.size() != 1)
1153 {
1154 messages::internalError(res);
1155
1156 res.end();
1157 return;
1158 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001159 const std::string& processorId = params[0];
Zhikui Ren029cc1f2020-08-25 15:21:41 -07001160 res.jsonValue["@odata.type"] = "#Processor.v1_9_0.Processor";
Ed Tanous029573d2019-02-01 10:57:49 -08001161 res.jsonValue["@odata.id"] =
Alpana Kumari32bee762019-04-25 04:47:57 -05001162 "/redfish/v1/Systems/system/Processors/" + processorId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001163
Ed Tanous029573d2019-02-01 10:57:49 -08001164 auto asyncResp = std::make_shared<AsyncResp>(res);
1165
Alpana Kumari32bee762019-04-25 04:47:57 -05001166 getCpuData(asyncResp, processorId,
1167 {"xyz.openbmc_project.Inventory.Item.Cpu",
Zhikui Ren5e54a362020-07-13 15:31:38 -07001168 "xyz.openbmc_project.Inventory.Decorator.Asset",
Alpana Kumari32bee762019-04-25 04:47:57 -05001169 "xyz.openbmc_project.Inventory.Item.Accelerator"});
Ed Tanous029573d2019-02-01 10:57:49 -08001170 }
1171};
1172
1173class MemoryCollection : public Node
1174{
1175 public:
1176 /*
1177 * Default Constructor
1178 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001179 MemoryCollection(App& app) : Node(app, "/redfish/v1/Systems/system/Memory/")
Ed Tanous029573d2019-02-01 10:57:49 -08001180 {
1181 entityPrivileges = {
1182 {boost::beast::http::verb::get, {{"Login"}}},
1183 {boost::beast::http::verb::head, {{"Login"}}},
1184 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1185 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1186 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1187 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1188 }
1189
1190 private:
1191 /**
1192 * Functions triggers appropriate requests on DBus
1193 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001194 void doGet(crow::Response& res, const crow::Request&,
1195 const std::vector<std::string>&) override
Ed Tanous029573d2019-02-01 10:57:49 -08001196 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001197 res.jsonValue["@odata.type"] = "#MemoryCollection.MemoryCollection";
1198 res.jsonValue["Name"] = "Memory Module Collection";
James Feistc50e7c62020-07-27 15:39:36 -07001199 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001200 auto asyncResp = std::make_shared<AsyncResp>(res);
1201
Ed Tanous029573d2019-02-01 10:57:49 -08001202 getResourceList(asyncResp, "Memory",
Alpana Kumari32bee762019-04-25 04:47:57 -05001203 {"xyz.openbmc_project.Inventory.Item.Dimm"});
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001204 }
1205};
1206
1207class Memory : public Node
1208{
1209 public:
1210 /*
1211 * Default Constructor
1212 */
Ed Tanous52cc1122020-07-18 13:51:21 -07001213 Memory(App& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001214 Node(app, "/redfish/v1/Systems/system/Memory/<str>/", std::string())
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001215 {
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001216 entityPrivileges = {
1217 {boost::beast::http::verb::get, {{"Login"}}},
1218 {boost::beast::http::verb::head, {{"Login"}}},
1219 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1220 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1221 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1222 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1223 }
1224
1225 private:
1226 /**
1227 * Functions triggers appropriate requests on DBus
1228 */
Ed Tanouscb13a392020-07-25 19:02:03 +00001229 void doGet(crow::Response& res, const crow::Request&,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001230 const std::vector<std::string>& params) override
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001231 {
1232 // Check if there is required param, truly entering this shall be
1233 // impossible
Ed Tanous029573d2019-02-01 10:57:49 -08001234 if (params.size() != 1)
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001235 {
1236 messages::internalError(res);
1237 res.end();
1238 return;
1239 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001240 const std::string& dimmId = params[0];
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001241
James Feistc50e7c62020-07-27 15:39:36 -07001242 res.jsonValue["@odata.type"] = "#Memory.v1_7_0.Memory";
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001243 res.jsonValue["@odata.id"] =
Ed Tanous029573d2019-02-01 10:57:49 -08001244 "/redfish/v1/Systems/system/Memory/" + dimmId;
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001245 auto asyncResp = std::make_shared<AsyncResp>(res);
1246
Ed Tanous029573d2019-02-01 10:57:49 -08001247 getDimmData(asyncResp, dimmId);
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001248 }
1249};
1250
1251} // namespace redfish