summaryrefslogtreecommitdiff
path: root/redfish-core/lib
diff options
context:
space:
mode:
authorGunnar Mills <gmills@us.ibm.com>2020-10-14 22:55:29 +0300
committerGunnar Mills <gmills@us.ibm.com>2020-10-16 16:09:57 +0300
commitac6a4445047df7f9fa198cca2ae1eeffd943a627 (patch)
tree5e947f5cf3b4dfeaeafa4fae89442abf6d5c225e /redfish-core/lib
parent116bcc5c254d6dc8af09ba30f36c90c47b269a82 (diff)
downloadbmcweb-ac6a4445047df7f9fa198cca2ae1eeffd943a627.tar.xz
cpudimm.hpp: Separate Memory and Processor functionality
To match other files move Redfish Memory classes and functions to a separate memory.hpp file. This naming "memory" (after the Redfish schemas) matches other filenames. Do the same with Processor classes and functions, moving to a separate processor.hpp. cpudimm.hpp had grown to 1300+ lines. Makes development and review easier. Tested: Validator passes. Resources look the same. Change-Id: I7e23ecaf9b4b69cc72aad6d94ad3a555ee76b28a Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
Diffstat (limited to 'redfish-core/lib')
-rw-r--r--redfish-core/lib/memory.hpp (renamed from redfish-core/lib/cpudimm.hpp)499
-rw-r--r--redfish-core/lib/processor.hpp527
2 files changed, 527 insertions, 499 deletions
diff --git a/redfish-core/lib/cpudimm.hpp b/redfish-core/lib/memory.hpp
index 9351f6ab6d..a172233b5a 100644
--- a/redfish-core/lib/cpudimm.hpp
+++ b/redfish-core/lib/memory.hpp
@@ -26,418 +26,6 @@
namespace redfish
{
-using InterfacesProperties = boost::container::flat_map<
- std::string,
- boost::container::flat_map<std::string, dbus::utility::DbusVariantType>>;
-
-inline void
- getCpuDataByInterface(const std::shared_ptr<AsyncResp>& aResp,
- const InterfacesProperties& cpuInterfacesProperties)
-{
- BMCWEB_LOG_DEBUG << "Get CPU resources by interface.";
-
- // Added for future purpose. Once present and functional attributes added
- // in busctl call, need to add actual logic to fetch original values.
- bool present = false;
- const bool functional = true;
- auto health = std::make_shared<HealthPopulate>(aResp);
- health->populate();
-
- for (const auto& interface : cpuInterfacesProperties)
- {
- for (const auto& property : interface.second)
- {
- if (property.first == "CoreCount")
- {
- const uint16_t* coresCount =
- std::get_if<uint16_t>(&property.second);
- if (coresCount == nullptr)
- {
- // Important property not in desired type
- messages::internalError(aResp->res);
- return;
- }
- if (*coresCount == 0)
- {
- // Slot is not populated, set status end return
- aResp->res.jsonValue["Status"]["State"] = "Absent";
- // HTTP Code will be set up automatically, just return
- return;
- }
- aResp->res.jsonValue["Status"]["State"] = "Enabled";
- present = true;
- aResp->res.jsonValue["TotalCores"] = *coresCount;
- }
- else if (property.first == "Socket")
- {
- const std::string* value =
- std::get_if<std::string>(&property.second);
- if (value != nullptr)
- {
- aResp->res.jsonValue["Socket"] = *value;
- }
- }
- else if (property.first == "ThreadCount")
- {
- const int64_t* value = std::get_if<int64_t>(&property.second);
- if (value != nullptr)
- {
- aResp->res.jsonValue["TotalThreads"] = *value;
- }
- }
- else if (property.first == "Family")
- {
- const std::string* value =
- std::get_if<std::string>(&property.second);
- if (value != nullptr)
- {
- aResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] =
- *value;
- }
- }
- else if (property.first == "Id")
- {
- const uint64_t* value = std::get_if<uint64_t>(&property.second);
- if (value != nullptr && *value != 0)
- {
- present = true;
- aResp->res
- .jsonValue["ProcessorId"]["IdentificationRegisters"] =
- boost::lexical_cast<std::string>(*value);
- }
- }
- }
- }
-
- if (present == false)
- {
- aResp->res.jsonValue["Status"]["State"] = "Absent";
- aResp->res.jsonValue["Status"]["Health"] = "OK";
- }
- else
- {
- aResp->res.jsonValue["Status"]["State"] = "Enabled";
- if (functional)
- {
- aResp->res.jsonValue["Status"]["Health"] = "OK";
- }
- else
- {
- aResp->res.jsonValue["Status"]["Health"] = "Critical";
- }
- }
-
- return;
-}
-
-inline void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
- const std::string& cpuId,
- const std::string& service,
- const std::string& objPath)
-{
- BMCWEB_LOG_DEBUG << "Get available system cpu resources by service.";
-
- crow::connections::systemBus->async_method_call(
- [cpuId, service, objPath, aResp{std::move(aResp)}](
- const boost::system::error_code ec,
- const dbus::utility::ManagedObjectType& dbusData) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG << "DBUS response error";
- messages::internalError(aResp->res);
- return;
- }
- aResp->res.jsonValue["Id"] = cpuId;
- aResp->res.jsonValue["Name"] = "Processor";
- aResp->res.jsonValue["ProcessorType"] = "CPU";
-
- bool slotPresent = false;
- std::string corePath = objPath + "/core";
- size_t totalCores = 0;
- for (const auto& object : dbusData)
- {
- if (object.first.str == objPath)
- {
- getCpuDataByInterface(aResp, object.second);
- }
- else if (boost::starts_with(object.first.str, corePath))
- {
- for (const auto& interface : object.second)
- {
- if (interface.first ==
- "xyz.openbmc_project.Inventory.Item")
- {
- for (const auto& property : interface.second)
- {
- if (property.first == "Present")
- {
- const bool* present =
- std::get_if<bool>(&property.second);
- if (present != nullptr)
- {
- if (*present == true)
- {
- slotPresent = true;
- totalCores++;
- }
- }
- }
- }
- }
- }
- }
- }
- // In getCpuDataByInterface(), state and health are set
- // based on the present and functional status. If core
- // count is zero, then it has a higher precedence.
- if (slotPresent)
- {
- if (totalCores == 0)
- {
- // Slot is not populated, set status end return
- aResp->res.jsonValue["Status"]["State"] = "Absent";
- aResp->res.jsonValue["Status"]["Health"] = "OK";
- }
- aResp->res.jsonValue["TotalCores"] = totalCores;
- }
- return;
- },
- service, "/xyz/openbmc_project/inventory",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-}
-
-inline void getCpuAssetData(std::shared_ptr<AsyncResp> aResp,
- const std::string& service,
- const std::string& objPath)
-{
- BMCWEB_LOG_DEBUG << "Get Cpu Asset Data";
- crow::connections::systemBus->async_method_call(
- [objPath, aResp{std::move(aResp)}](
- const boost::system::error_code ec,
- const boost::container::flat_map<
- std::string, std::variant<std::string, uint32_t, uint16_t,
- bool>>& properties) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG << "DBUS response error";
- messages::internalError(aResp->res);
- return;
- }
-
- for (const auto& property : properties)
- {
- if (property.first == "SerialNumber")
- {
- const std::string* sn =
- std::get_if<std::string>(&property.second);
- if (sn != nullptr && !sn->empty())
- {
- aResp->res.jsonValue["SerialNumber"] = *sn;
- }
- }
- else if (property.first == "Model")
- {
- const std::string* model =
- std::get_if<std::string>(&property.second);
- if (model != nullptr && !model->empty())
- {
- aResp->res.jsonValue["Model"] = *model;
- }
- }
- else if (property.first == "Manufacturer")
- {
-
- const std::string* mfg =
- std::get_if<std::string>(&property.second);
- if (mfg != nullptr)
- {
- aResp->res.jsonValue["Manufacturer"] = *mfg;
-
- // Otherwise would be unexpected.
- if (mfg->find("Intel") != std::string::npos)
- {
- aResp->res.jsonValue["ProcessorArchitecture"] =
- "x86";
- aResp->res.jsonValue["InstructionSet"] = "x86-64";
- }
- else if (mfg->find("IBM") != std::string::npos)
- {
- aResp->res.jsonValue["ProcessorArchitecture"] =
- "Power";
- aResp->res.jsonValue["InstructionSet"] = "PowerISA";
- }
- }
- }
- }
- },
- service, objPath, "org.freedesktop.DBus.Properties", "GetAll",
- "xyz.openbmc_project.Inventory.Decorator.Asset");
-}
-
-inline void getCpuRevisionData(std::shared_ptr<AsyncResp> aResp,
- const std::string& service,
- const std::string& objPath)
-{
- BMCWEB_LOG_DEBUG << "Get Cpu Revision Data";
- crow::connections::systemBus->async_method_call(
- [objPath, aResp{std::move(aResp)}](
- const boost::system::error_code ec,
- const boost::container::flat_map<
- std::string, std::variant<std::string, uint32_t, uint16_t,
- bool>>& properties) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG << "DBUS response error";
- messages::internalError(aResp->res);
- return;
- }
-
- for (const auto& property : properties)
- {
- if (property.first == "Version")
- {
- const std::string* ver =
- std::get_if<std::string>(&property.second);
- if (ver != nullptr)
- {
- aResp->res.jsonValue["Version"] = *ver;
- }
- break;
- }
- }
- },
- service, objPath, "org.freedesktop.DBus.Properties", "GetAll",
- "xyz.openbmc_project.Inventory.Decorator.Revision");
-}
-
-inline void getAcceleratorDataByService(std::shared_ptr<AsyncResp> aResp,
- const std::string& acclrtrId,
- const std::string& service,
- const std::string& objPath)
-{
- BMCWEB_LOG_DEBUG
- << "Get available system Accelerator resources by service.";
- crow::connections::systemBus->async_method_call(
- [acclrtrId, aResp{std::move(aResp)}](
- const boost::system::error_code ec,
- const boost::container::flat_map<
- std::string, std::variant<std::string, uint32_t, uint16_t,
- bool>>& properties) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG << "DBUS response error";
- messages::internalError(aResp->res);
- return;
- }
- aResp->res.jsonValue["Id"] = acclrtrId;
- aResp->res.jsonValue["Name"] = "Processor";
- const bool* accPresent = nullptr;
- const bool* accFunctional = nullptr;
-
- for (const auto& property : properties)
- {
- if (property.first == "Functional")
- {
- accFunctional = std::get_if<bool>(&property.second);
- }
- else if (property.first == "Present")
- {
- accPresent = std::get_if<bool>(&property.second);
- }
- }
-
- std::string state = "Enabled";
- std::string health = "OK";
-
- if (accPresent != nullptr && *accPresent == false)
- {
- state = "Absent";
- }
-
- if ((accFunctional != nullptr) && (*accFunctional == false))
- {
- if (state == "Enabled")
- {
- health = "Critical";
- }
- }
-
- aResp->res.jsonValue["Status"]["State"] = state;
- aResp->res.jsonValue["Status"]["Health"] = health;
- aResp->res.jsonValue["ProcessorType"] = "Accelerator";
- },
- service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
-}
-
-inline void getProcessorData(std::shared_ptr<AsyncResp> aResp,
- const std::string& processorId,
- const std::vector<const char*>& inventoryItems)
-{
- BMCWEB_LOG_DEBUG << "Get available system processor resources.";
-
- crow::connections::systemBus->async_method_call(
- [processorId, aResp{std::move(aResp)}](
- const boost::system::error_code ec,
- const boost::container::flat_map<
- std::string, boost::container::flat_map<
- std::string, std::vector<std::string>>>&
- subtree) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG << "DBUS response error";
- messages::internalError(aResp->res);
- return;
- }
- for (const auto& object : subtree)
- {
- if (boost::ends_with(object.first, processorId))
- {
- for (const auto& service : object.second)
- {
- for (const auto& inventory : service.second)
- {
- if (inventory == "xyz.openbmc_project."
- "Inventory.Decorator.Asset")
- {
- getCpuAssetData(aResp, service.first,
- object.first);
- }
- else if (inventory ==
- "xyz.openbmc_project."
- "Inventory.Decorator.Revision")
- {
- getCpuRevisionData(aResp, service.first,
- object.first);
- }
- else if (inventory == "xyz.openbmc_project."
- "Inventory.Item.Cpu")
- {
- getCpuDataByService(aResp, processorId,
- service.first,
- object.first);
- }
- else if (inventory == "xyz.openbmc_project."
- "Inventory.Item.Accelerator")
- {
- getAcceleratorDataByService(aResp, processorId,
- service.first,
- object.first);
- }
- }
- }
- return;
- }
- }
- // Object not found
- messages::resourceNotFound(aResp->res, "Processor", processorId);
- return;
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTree",
- "/xyz/openbmc_project/inventory", 0, inventoryItems);
-}
-
using DimmProperty =
std::variant<std::string, std::vector<uint32_t>, std::vector<uint16_t>,
uint64_t, uint32_t, uint16_t, uint8_t, bool>;
@@ -1148,93 +736,6 @@ inline void getDimmData(std::shared_ptr<AsyncResp> aResp,
"xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
}
-class ProcessorCollection : public Node
-{
- public:
- /*
- * Default Constructor
- */
- ProcessorCollection(App& app) :
- Node(app, "/redfish/v1/Systems/system/Processors/")
- {
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
- }
-
- private:
- /**
- * Functions triggers appropriate requests on DBus
- */
- void doGet(crow::Response& res, const crow::Request&,
- const std::vector<std::string>&) override
- {
- res.jsonValue["@odata.type"] =
- "#ProcessorCollection.ProcessorCollection";
- res.jsonValue["Name"] = "Processor Collection";
-
- res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/";
- auto asyncResp = std::make_shared<AsyncResp>(res);
-
- collection_util::getResourceList(
- asyncResp, "Processors",
- {"xyz.openbmc_project.Inventory.Item.Cpu",
- "xyz.openbmc_project.Inventory.Item.Accelerator"});
- }
-};
-
-class Processor : public Node
-{
- public:
- /*
- * Default Constructor
- */
- Processor(App& app) :
- Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
- {
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
- }
-
- private:
- /**
- * Functions triggers appropriate requests on DBus
- */
- void doGet(crow::Response& res, const crow::Request&,
- const std::vector<std::string>& params) override
- {
- // Check if there is required param, truly entering this shall be
- // impossible
- if (params.size() != 1)
- {
- messages::internalError(res);
-
- res.end();
- return;
- }
- const std::string& processorId = params[0];
- res.jsonValue["@odata.type"] = "#Processor.v1_9_0.Processor";
- res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/system/Processors/" + processorId;
-
- auto asyncResp = std::make_shared<AsyncResp>(res);
-
- getProcessorData(asyncResp, processorId,
- {"xyz.openbmc_project.Inventory.Item.Cpu",
- "xyz.openbmc_project.Inventory.Decorator.Asset",
- "xyz.openbmc_project.Inventory.Item.Accelerator"});
- }
-};
-
class MemoryCollection : public Node
{
public:
diff --git a/redfish-core/lib/processor.hpp b/redfish-core/lib/processor.hpp
new file mode 100644
index 0000000000..5c986845f4
--- /dev/null
+++ b/redfish-core/lib/processor.hpp
@@ -0,0 +1,527 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+
+#include "health.hpp"
+
+#include <boost/container/flat_map.hpp>
+#include <node.hpp>
+#include <utils/collection.hpp>
+#include <utils/json_utils.hpp>
+
+namespace redfish
+{
+
+using InterfacesProperties = boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<std::string, dbus::utility::DbusVariantType>>;
+
+inline void
+ getCpuDataByInterface(const std::shared_ptr<AsyncResp>& aResp,
+ const InterfacesProperties& cpuInterfacesProperties)
+{
+ BMCWEB_LOG_DEBUG << "Get CPU resources by interface.";
+
+ // Added for future purpose. Once present and functional attributes added
+ // in busctl call, need to add actual logic to fetch original values.
+ bool present = false;
+ const bool functional = true;
+ auto health = std::make_shared<HealthPopulate>(aResp);
+ health->populate();
+
+ for (const auto& interface : cpuInterfacesProperties)
+ {
+ for (const auto& property : interface.second)
+ {
+ if (property.first == "CoreCount")
+ {
+ const uint16_t* coresCount =
+ std::get_if<uint16_t>(&property.second);
+ if (coresCount == nullptr)
+ {
+ // Important property not in desired type
+ messages::internalError(aResp->res);
+ return;
+ }
+ if (*coresCount == 0)
+ {
+ // Slot is not populated, set status end return
+ aResp->res.jsonValue["Status"]["State"] = "Absent";
+ // HTTP Code will be set up automatically, just return
+ return;
+ }
+ aResp->res.jsonValue["Status"]["State"] = "Enabled";
+ present = true;
+ aResp->res.jsonValue["TotalCores"] = *coresCount;
+ }
+ else if (property.first == "Socket")
+ {
+ const std::string* value =
+ std::get_if<std::string>(&property.second);
+ if (value != nullptr)
+ {
+ aResp->res.jsonValue["Socket"] = *value;
+ }
+ }
+ else if (property.first == "ThreadCount")
+ {
+ const int64_t* value = std::get_if<int64_t>(&property.second);
+ if (value != nullptr)
+ {
+ aResp->res.jsonValue["TotalThreads"] = *value;
+ }
+ }
+ else if (property.first == "Family")
+ {
+ const std::string* value =
+ std::get_if<std::string>(&property.second);
+ if (value != nullptr)
+ {
+ aResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] =
+ *value;
+ }
+ }
+ else if (property.first == "Id")
+ {
+ const uint64_t* value = std::get_if<uint64_t>(&property.second);
+ if (value != nullptr && *value != 0)
+ {
+ present = true;
+ aResp->res
+ .jsonValue["ProcessorId"]["IdentificationRegisters"] =
+ boost::lexical_cast<std::string>(*value);
+ }
+ }
+ }
+ }
+
+ if (present == false)
+ {
+ aResp->res.jsonValue["Status"]["State"] = "Absent";
+ aResp->res.jsonValue["Status"]["Health"] = "OK";
+ }
+ else
+ {
+ aResp->res.jsonValue["Status"]["State"] = "Enabled";
+ if (functional)
+ {
+ aResp->res.jsonValue["Status"]["Health"] = "OK";
+ }
+ else
+ {
+ aResp->res.jsonValue["Status"]["Health"] = "Critical";
+ }
+ }
+
+ return;
+}
+
+inline void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
+ const std::string& cpuId,
+ const std::string& service,
+ const std::string& objPath)
+{
+ BMCWEB_LOG_DEBUG << "Get available system cpu resources by service.";
+
+ crow::connections::systemBus->async_method_call(
+ [cpuId, service, objPath, aResp{std::move(aResp)}](
+ const boost::system::error_code ec,
+ const dbus::utility::ManagedObjectType& dbusData) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error";
+ messages::internalError(aResp->res);
+ return;
+ }
+ aResp->res.jsonValue["Id"] = cpuId;
+ aResp->res.jsonValue["Name"] = "Processor";
+ aResp->res.jsonValue["ProcessorType"] = "CPU";
+
+ bool slotPresent = false;
+ std::string corePath = objPath + "/core";
+ size_t totalCores = 0;
+ for (const auto& object : dbusData)
+ {
+ if (object.first.str == objPath)
+ {
+ getCpuDataByInterface(aResp, object.second);
+ }
+ else if (boost::starts_with(object.first.str, corePath))
+ {
+ for (const auto& interface : object.second)
+ {
+ if (interface.first ==
+ "xyz.openbmc_project.Inventory.Item")
+ {
+ for (const auto& property : interface.second)
+ {
+ if (property.first == "Present")
+ {
+ const bool* present =
+ std::get_if<bool>(&property.second);
+ if (present != nullptr)
+ {
+ if (*present == true)
+ {
+ slotPresent = true;
+ totalCores++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // In getCpuDataByInterface(), state and health are set
+ // based on the present and functional status. If core
+ // count is zero, then it has a higher precedence.
+ if (slotPresent)
+ {
+ if (totalCores == 0)
+ {
+ // Slot is not populated, set status end return
+ aResp->res.jsonValue["Status"]["State"] = "Absent";
+ aResp->res.jsonValue["Status"]["Health"] = "OK";
+ }
+ aResp->res.jsonValue["TotalCores"] = totalCores;
+ }
+ return;
+ },
+ service, "/xyz/openbmc_project/inventory",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+}
+
+inline void getCpuAssetData(std::shared_ptr<AsyncResp> aResp,
+ const std::string& service,
+ const std::string& objPath)
+{
+ BMCWEB_LOG_DEBUG << "Get Cpu Asset Data";
+ crow::connections::systemBus->async_method_call(
+ [objPath, aResp{std::move(aResp)}](
+ const boost::system::error_code ec,
+ const boost::container::flat_map<
+ std::string, std::variant<std::string, uint32_t, uint16_t,
+ bool>>& properties) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error";
+ messages::internalError(aResp->res);
+ return;
+ }
+
+ for (const auto& property : properties)
+ {
+ if (property.first == "SerialNumber")
+ {
+ const std::string* sn =
+ std::get_if<std::string>(&property.second);
+ if (sn != nullptr && !sn->empty())
+ {
+ aResp->res.jsonValue["SerialNumber"] = *sn;
+ }
+ }
+ else if (property.first == "Model")
+ {
+ const std::string* model =
+ std::get_if<std::string>(&property.second);
+ if (model != nullptr && !model->empty())
+ {
+ aResp->res.jsonValue["Model"] = *model;
+ }
+ }
+ else if (property.first == "Manufacturer")
+ {
+
+ const std::string* mfg =
+ std::get_if<std::string>(&property.second);
+ if (mfg != nullptr)
+ {
+ aResp->res.jsonValue["Manufacturer"] = *mfg;
+
+ // Otherwise would be unexpected.
+ if (mfg->find("Intel") != std::string::npos)
+ {
+ aResp->res.jsonValue["ProcessorArchitecture"] =
+ "x86";
+ aResp->res.jsonValue["InstructionSet"] = "x86-64";
+ }
+ else if (mfg->find("IBM") != std::string::npos)
+ {
+ aResp->res.jsonValue["ProcessorArchitecture"] =
+ "Power";
+ aResp->res.jsonValue["InstructionSet"] = "PowerISA";
+ }
+ }
+ }
+ }
+ },
+ service, objPath, "org.freedesktop.DBus.Properties", "GetAll",
+ "xyz.openbmc_project.Inventory.Decorator.Asset");
+}
+
+inline void getCpuRevisionData(std::shared_ptr<AsyncResp> aResp,
+ const std::string& service,
+ const std::string& objPath)
+{
+ BMCWEB_LOG_DEBUG << "Get Cpu Revision Data";
+ crow::connections::systemBus->async_method_call(
+ [objPath, aResp{std::move(aResp)}](
+ const boost::system::error_code ec,
+ const boost::container::flat_map<
+ std::string, std::variant<std::string, uint32_t, uint16_t,
+ bool>>& properties) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error";
+ messages::internalError(aResp->res);
+ return;
+ }
+
+ for (const auto& property : properties)
+ {
+ if (property.first == "Version")
+ {
+ const std::string* ver =
+ std::get_if<std::string>(&property.second);
+ if (ver != nullptr)
+ {
+ aResp->res.jsonValue["Version"] = *ver;
+ }
+ break;
+ }
+ }
+ },
+ service, objPath, "org.freedesktop.DBus.Properties", "GetAll",
+ "xyz.openbmc_project.Inventory.Decorator.Revision");
+}
+
+inline void getAcceleratorDataByService(std::shared_ptr<AsyncResp> aResp,
+ const std::string& acclrtrId,
+ const std::string& service,
+ const std::string& objPath)
+{
+ BMCWEB_LOG_DEBUG
+ << "Get available system Accelerator resources by service.";
+ crow::connections::systemBus->async_method_call(
+ [acclrtrId, aResp{std::move(aResp)}](
+ const boost::system::error_code ec,
+ const boost::container::flat_map<
+ std::string, std::variant<std::string, uint32_t, uint16_t,
+ bool>>& properties) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error";
+ messages::internalError(aResp->res);
+ return;
+ }
+ aResp->res.jsonValue["Id"] = acclrtrId;
+ aResp->res.jsonValue["Name"] = "Processor";
+ const bool* accPresent = nullptr;
+ const bool* accFunctional = nullptr;
+
+ for (const auto& property : properties)
+ {
+ if (property.first == "Functional")
+ {
+ accFunctional = std::get_if<bool>(&property.second);
+ }
+ else if (property.first == "Present")
+ {
+ accPresent = std::get_if<bool>(&property.second);
+ }
+ }
+
+ std::string state = "Enabled";
+ std::string health = "OK";
+
+ if (accPresent != nullptr && *accPresent == false)
+ {
+ state = "Absent";
+ }
+
+ if ((accFunctional != nullptr) && (*accFunctional == false))
+ {
+ if (state == "Enabled")
+ {
+ health = "Critical";
+ }
+ }
+
+ aResp->res.jsonValue["Status"]["State"] = state;
+ aResp->res.jsonValue["Status"]["Health"] = health;
+ aResp->res.jsonValue["ProcessorType"] = "Accelerator";
+ },
+ service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
+}
+
+inline void getProcessorData(std::shared_ptr<AsyncResp> aResp,
+ const std::string& processorId,
+ const std::vector<const char*>& inventoryItems)
+{
+ BMCWEB_LOG_DEBUG << "Get available system processor resources.";
+
+ crow::connections::systemBus->async_method_call(
+ [processorId, aResp{std::move(aResp)}](
+ const boost::system::error_code ec,
+ const boost::container::flat_map<
+ std::string, boost::container::flat_map<
+ std::string, std::vector<std::string>>>&
+ subtree) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error";
+ messages::internalError(aResp->res);
+ return;
+ }
+ for (const auto& object : subtree)
+ {
+ if (boost::ends_with(object.first, processorId))
+ {
+ for (const auto& service : object.second)
+ {
+ for (const auto& inventory : service.second)
+ {
+ if (inventory == "xyz.openbmc_project."
+ "Inventory.Decorator.Asset")
+ {
+ getCpuAssetData(aResp, service.first,
+ object.first);
+ }
+ else if (inventory ==
+ "xyz.openbmc_project."
+ "Inventory.Decorator.Revision")
+ {
+ getCpuRevisionData(aResp, service.first,
+ object.first);
+ }
+ else if (inventory == "xyz.openbmc_project."
+ "Inventory.Item.Cpu")
+ {
+ getCpuDataByService(aResp, processorId,
+ service.first,
+ object.first);
+ }
+ else if (inventory == "xyz.openbmc_project."
+ "Inventory.Item.Accelerator")
+ {
+ getAcceleratorDataByService(aResp, processorId,
+ service.first,
+ object.first);
+ }
+ }
+ }
+ return;
+ }
+ }
+ // Object not found
+ messages::resourceNotFound(aResp->res, "Processor", processorId);
+ return;
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/inventory", 0, inventoryItems);
+}
+
+class ProcessorCollection : public Node
+{
+ public:
+ /*
+ * Default Constructor
+ */
+ ProcessorCollection(App& app) :
+ Node(app, "/redfish/v1/Systems/system/Processors/")
+ {
+ entityPrivileges = {
+ {boost::beast::http::verb::get, {{"Login"}}},
+ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+ }
+
+ private:
+ /**
+ * Functions triggers appropriate requests on DBus
+ */
+ void doGet(crow::Response& res, const crow::Request&,
+ const std::vector<std::string>&) override
+ {
+ res.jsonValue["@odata.type"] =
+ "#ProcessorCollection.ProcessorCollection";
+ res.jsonValue["Name"] = "Processor Collection";
+
+ res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/";
+ auto asyncResp = std::make_shared<AsyncResp>(res);
+
+ collection_util::getResourceList(
+ asyncResp, "Processors",
+ {"xyz.openbmc_project.Inventory.Item.Cpu",
+ "xyz.openbmc_project.Inventory.Item.Accelerator"});
+ }
+};
+
+class Processor : public Node
+{
+ public:
+ /*
+ * Default Constructor
+ */
+ Processor(App& app) :
+ Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
+ {
+ entityPrivileges = {
+ {boost::beast::http::verb::get, {{"Login"}}},
+ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+ }
+
+ private:
+ /**
+ * Functions triggers appropriate requests on DBus
+ */
+ void doGet(crow::Response& res, const crow::Request&,
+ const std::vector<std::string>& params) override
+ {
+ // Check if there is required param, truly entering this shall be
+ // impossible
+ if (params.size() != 1)
+ {
+ messages::internalError(res);
+
+ res.end();
+ return;
+ }
+ const std::string& processorId = params[0];
+ res.jsonValue["@odata.type"] = "#Processor.v1_9_0.Processor";
+ res.jsonValue["@odata.id"] =
+ "/redfish/v1/Systems/system/Processors/" + processorId;
+
+ auto asyncResp = std::make_shared<AsyncResp>(res);
+
+ getProcessorData(asyncResp, processorId,
+ {"xyz.openbmc_project.Inventory.Item.Cpu",
+ "xyz.openbmc_project.Inventory.Decorator.Asset",
+ "xyz.openbmc_project.Inventory.Item.Accelerator"});
+ }
+};
+
+} // namespace redfish