140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0 240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors 340e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation 4ac6a4445SGunnar Mills #pragma once 5ac6a4445SGunnar Mills 6d7857201SEd Tanous #include "bmcweb_config.h" 7d7857201SEd Tanous 83ccb3adbSEd Tanous #include "app.hpp" 9d7857201SEd Tanous #include "async_resp.hpp" 107a1dbc48SGeorge Liu #include "dbus_utility.hpp" 111e1e598dSJonathan Doman #include "error_messages.hpp" 12dfbf7de5SChris Cain #include "generated/enums/processor.hpp" 13539d8c6bSEd Tanous #include "generated/enums/resource.hpp" 14d7857201SEd Tanous #include "http_request.hpp" 1598eafce5SGeorge Liu #include "led.hpp" 16d7857201SEd Tanous #include "logging.hpp" 173ccb3adbSEd Tanous #include "query.hpp" 183ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 193ccb3adbSEd Tanous #include "utils/collection.hpp" 203ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 21d7857201SEd Tanous #include "utils/hex_utils.hpp" 223ccb3adbSEd Tanous #include "utils/json_utils.hpp" 23ac6a4445SGunnar Mills 24d7857201SEd Tanous #include <boost/beast/http/field.hpp> 25d7857201SEd Tanous #include <boost/beast/http/verb.hpp> 26e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 27ef4c65b7SEd Tanous #include <boost/url/format.hpp> 28dba0c291SJonathan Doman #include <sdbusplus/message/native_types.hpp> 29351053f2SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 30ac6a4445SGunnar Mills 31d7857201SEd Tanous #include <algorithm> 327a1dbc48SGeorge Liu #include <array> 33d7857201SEd Tanous #include <cstddef> 34d7857201SEd Tanous #include <cstdint> 35d7857201SEd Tanous #include <format> 36d7857201SEd Tanous #include <functional> 37b9d679d1SMichael Shen #include <limits> 38d7857201SEd Tanous #include <memory> 39d7857201SEd Tanous #include <optional> 403544d2a7SEd Tanous #include <ranges> 413c569218SEd Tanous #include <string> 427a1dbc48SGeorge Liu #include <string_view> 43d7857201SEd Tanous #include <tuple> 44d7857201SEd Tanous #include <utility> 45d7857201SEd Tanous #include <variant> 46d7857201SEd Tanous #include <vector> 477a1dbc48SGeorge Liu 48ac6a4445SGunnar Mills namespace redfish 49ac6a4445SGunnar Mills { 50ac6a4445SGunnar Mills 51c951448aSJonathan Doman // Interfaces which imply a D-Bus object represents a Processor 527a1dbc48SGeorge Liu constexpr std::array<std::string_view, 2> processorInterfaces = { 53c951448aSJonathan Doman "xyz.openbmc_project.Inventory.Item.Cpu", 54c951448aSJonathan Doman "xyz.openbmc_project.Inventory.Item.Accelerator"}; 552bab9831SJonathan Doman 5671b82f26SSharad Yadav /** 5771b82f26SSharad Yadav * @brief Fill out uuid info of a processor by 5871b82f26SSharad Yadav * requesting data from the given D-Bus object. 5971b82f26SSharad Yadav * 60ac106bf6SEd Tanous * @param[in,out] asyncResp Async HTTP response. 6171b82f26SSharad Yadav * @param[in] service D-Bus service to query. 6271b82f26SSharad Yadav * @param[in] objPath D-Bus object to query. 6371b82f26SSharad Yadav */ 64ac106bf6SEd Tanous inline void getProcessorUUID(std::shared_ptr<bmcweb::AsyncResp> asyncResp, 6571b82f26SSharad Yadav const std::string& service, 6671b82f26SSharad Yadav const std::string& objPath) 6771b82f26SSharad Yadav { 6862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Processor UUID"); 69deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 70deae6a78SEd Tanous service, objPath, "xyz.openbmc_project.Common.UUID", "UUID", 71ac106bf6SEd Tanous [objPath, asyncResp{std::move(asyncResp)}]( 72ac106bf6SEd Tanous const boost::system::error_code& ec, const std::string& property) { 7371b82f26SSharad Yadav if (ec) 7471b82f26SSharad Yadav { 7562598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 76ac106bf6SEd Tanous messages::internalError(asyncResp->res); 7771b82f26SSharad Yadav return; 7871b82f26SSharad Yadav } 79ac106bf6SEd Tanous asyncResp->res.jsonValue["UUID"] = property; 801e1e598dSJonathan Doman }); 8171b82f26SSharad Yadav } 8271b82f26SSharad Yadav 83711ac7a9SEd Tanous inline void getCpuDataByInterface( 84ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 8580f79a40SMichael Shen const dbus::utility::DBusInterfacesMap& cpuInterfacesProperties) 86ac6a4445SGunnar Mills { 8762598e31SEd Tanous BMCWEB_LOG_DEBUG("Get CPU resources by interface."); 88ac6a4445SGunnar Mills 89a1649ec6SChicago Duan // Set the default value of state 90539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled; 91539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK; 92ac6a4445SGunnar Mills 93ac6a4445SGunnar Mills for (const auto& interface : cpuInterfacesProperties) 94ac6a4445SGunnar Mills { 95ac6a4445SGunnar Mills for (const auto& property : interface.second) 96ac6a4445SGunnar Mills { 97a1649ec6SChicago Duan if (property.first == "Present") 98ac6a4445SGunnar Mills { 99a1649ec6SChicago Duan const bool* cpuPresent = std::get_if<bool>(&property.second); 100a1649ec6SChicago Duan if (cpuPresent == nullptr) 101ac6a4445SGunnar Mills { 102ac6a4445SGunnar Mills // Important property not in desired type 103ac106bf6SEd Tanous messages::internalError(asyncResp->res); 104ac6a4445SGunnar Mills return; 105ac6a4445SGunnar Mills } 106e05aec50SEd Tanous if (!*cpuPresent) 107ac6a4445SGunnar Mills { 108a1649ec6SChicago Duan // Slot is not populated 109539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 110539d8c6bSEd Tanous resource::State::Absent; 111a1649ec6SChicago Duan } 112a1649ec6SChicago Duan } 113a1649ec6SChicago Duan else if (property.first == "Functional") 114a1649ec6SChicago Duan { 115a1649ec6SChicago Duan const bool* cpuFunctional = std::get_if<bool>(&property.second); 116a1649ec6SChicago Duan if (cpuFunctional == nullptr) 117a1649ec6SChicago Duan { 118ac106bf6SEd Tanous messages::internalError(asyncResp->res); 119ac6a4445SGunnar Mills return; 120ac6a4445SGunnar Mills } 121e05aec50SEd Tanous if (!*cpuFunctional) 122a1649ec6SChicago Duan { 123539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = 124539d8c6bSEd Tanous resource::Health::Critical; 125a1649ec6SChicago Duan } 126a1649ec6SChicago Duan } 127a1649ec6SChicago Duan else if (property.first == "CoreCount") 128a1649ec6SChicago Duan { 129a1649ec6SChicago Duan const uint16_t* coresCount = 130a1649ec6SChicago Duan std::get_if<uint16_t>(&property.second); 131a1649ec6SChicago Duan if (coresCount == nullptr) 132a1649ec6SChicago Duan { 133ac106bf6SEd Tanous messages::internalError(asyncResp->res); 134a1649ec6SChicago Duan return; 135a1649ec6SChicago Duan } 136ac106bf6SEd Tanous asyncResp->res.jsonValue["TotalCores"] = *coresCount; 137ac6a4445SGunnar Mills } 138dc3fa667SJonathan Doman else if (property.first == "MaxSpeedInMhz") 139dc3fa667SJonathan Doman { 140dc3fa667SJonathan Doman const uint32_t* value = std::get_if<uint32_t>(&property.second); 141dc3fa667SJonathan Doman if (value != nullptr) 142dc3fa667SJonathan Doman { 143ac106bf6SEd Tanous asyncResp->res.jsonValue["MaxSpeedMHz"] = *value; 144dc3fa667SJonathan Doman } 145dc3fa667SJonathan Doman } 146ac6a4445SGunnar Mills else if (property.first == "Socket") 147ac6a4445SGunnar Mills { 148ac6a4445SGunnar Mills const std::string* value = 149ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 150ac6a4445SGunnar Mills if (value != nullptr) 151ac6a4445SGunnar Mills { 152ac106bf6SEd Tanous asyncResp->res.jsonValue["Socket"] = *value; 153ac6a4445SGunnar Mills } 154ac6a4445SGunnar Mills } 155ac6a4445SGunnar Mills else if (property.first == "ThreadCount") 156ac6a4445SGunnar Mills { 157dc3fa667SJonathan Doman const uint16_t* value = std::get_if<uint16_t>(&property.second); 158ac6a4445SGunnar Mills if (value != nullptr) 159ac6a4445SGunnar Mills { 160ac106bf6SEd Tanous asyncResp->res.jsonValue["TotalThreads"] = *value; 161ac6a4445SGunnar Mills } 162ac6a4445SGunnar Mills } 1631930fbd4SBrandon Kim else if (property.first == "EffectiveFamily") 164ac6a4445SGunnar Mills { 1651930fbd4SBrandon Kim const uint16_t* value = std::get_if<uint16_t>(&property.second); 1666169de2cSBrad Bishop if (value != nullptr && *value != 2) 167ac6a4445SGunnar Mills { 168ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] = 169866e4862SEd Tanous "0x" + intToHexString(*value, 4); 170ac6a4445SGunnar Mills } 171ac6a4445SGunnar Mills } 1721930fbd4SBrandon Kim else if (property.first == "EffectiveModel") 1731930fbd4SBrandon Kim { 1741930fbd4SBrandon Kim const uint16_t* value = std::get_if<uint16_t>(&property.second); 1751930fbd4SBrandon Kim if (value == nullptr) 1761930fbd4SBrandon Kim { 177ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1781930fbd4SBrandon Kim return; 1791930fbd4SBrandon Kim } 1806169de2cSBrad Bishop if (*value != 0) 1816169de2cSBrad Bishop { 182ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorId"]["EffectiveModel"] = 183866e4862SEd Tanous "0x" + intToHexString(*value, 4); 1841930fbd4SBrandon Kim } 1856169de2cSBrad Bishop } 186ac6a4445SGunnar Mills else if (property.first == "Id") 187ac6a4445SGunnar Mills { 188ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 189ac6a4445SGunnar Mills if (value != nullptr && *value != 0) 190ac6a4445SGunnar Mills { 191ac106bf6SEd Tanous asyncResp->res 192ac6a4445SGunnar Mills .jsonValue["ProcessorId"]["IdentificationRegisters"] = 193866e4862SEd Tanous "0x" + intToHexString(*value, 16); 194ac6a4445SGunnar Mills } 195ac6a4445SGunnar Mills } 1961930fbd4SBrandon Kim else if (property.first == "Microcode") 1971930fbd4SBrandon Kim { 1981930fbd4SBrandon Kim const uint32_t* value = std::get_if<uint32_t>(&property.second); 1991930fbd4SBrandon Kim if (value == nullptr) 2001930fbd4SBrandon Kim { 201ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2021930fbd4SBrandon Kim return; 2031930fbd4SBrandon Kim } 2046169de2cSBrad Bishop if (*value != 0) 2056169de2cSBrad Bishop { 206ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorId"]["MicrocodeInfo"] = 207866e4862SEd Tanous "0x" + intToHexString(*value, 8); 2081930fbd4SBrandon Kim } 2096169de2cSBrad Bishop } 2101930fbd4SBrandon Kim else if (property.first == "Step") 2111930fbd4SBrandon Kim { 2121930fbd4SBrandon Kim const uint16_t* value = std::get_if<uint16_t>(&property.second); 2131930fbd4SBrandon Kim if (value == nullptr) 2141930fbd4SBrandon Kim { 215ac106bf6SEd Tanous messages::internalError(asyncResp->res); 2161930fbd4SBrandon Kim return; 2171930fbd4SBrandon Kim } 218b9d679d1SMichael Shen if (*value != std::numeric_limits<uint16_t>::max()) 2196169de2cSBrad Bishop { 220ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorId"]["Step"] = 221866e4862SEd Tanous "0x" + intToHexString(*value, 4); 2221930fbd4SBrandon Kim } 223ac6a4445SGunnar Mills } 224ac6a4445SGunnar Mills } 225ac6a4445SGunnar Mills } 2266169de2cSBrad Bishop } 227ac6a4445SGunnar Mills 228bd79bce8SPatrick Williams inline void getCpuDataByService( 229bd79bce8SPatrick Williams std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& cpuId, 230bd79bce8SPatrick Williams const std::string& service, const std::string& objPath) 231ac6a4445SGunnar Mills { 23262598e31SEd Tanous BMCWEB_LOG_DEBUG("Get available system cpu resources by service."); 233ac6a4445SGunnar Mills 2345eb468daSGeorge Liu sdbusplus::message::object_path path("/xyz/openbmc_project/inventory"); 2355eb468daSGeorge Liu dbus::utility::getManagedObjects( 2365eb468daSGeorge Liu service, path, 237ac106bf6SEd Tanous [cpuId, service, objPath, asyncResp{std::move(asyncResp)}]( 2385e7e2dc5SEd Tanous const boost::system::error_code& ec, 239ac6a4445SGunnar Mills const dbus::utility::ManagedObjectType& dbusData) { 240ac6a4445SGunnar Mills if (ec) 241ac6a4445SGunnar Mills { 24262598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 243ac106bf6SEd Tanous messages::internalError(asyncResp->res); 244ac6a4445SGunnar Mills return; 245ac6a4445SGunnar Mills } 246ac106bf6SEd Tanous asyncResp->res.jsonValue["Id"] = cpuId; 247ac106bf6SEd Tanous asyncResp->res.jsonValue["Name"] = "Processor"; 248539d8c6bSEd Tanous asyncResp->res.jsonValue["ProcessorType"] = 249539d8c6bSEd Tanous processor::ProcessorType::CPU; 250ac6a4445SGunnar Mills 251ac6a4445SGunnar Mills for (const auto& object : dbusData) 252ac6a4445SGunnar Mills { 253ac6a4445SGunnar Mills if (object.first.str == objPath) 254ac6a4445SGunnar Mills { 255ac106bf6SEd Tanous getCpuDataByInterface(asyncResp, object.second); 256ac6a4445SGunnar Mills } 257ac6a4445SGunnar Mills } 258ac6a4445SGunnar Mills return; 2595eb468daSGeorge Liu }); 260ac6a4445SGunnar Mills } 261ac6a4445SGunnar Mills 262dfbf7de5SChris Cain /** 263dfbf7de5SChris Cain * @brief Translates throttle cause DBUS property to redfish. 264dfbf7de5SChris Cain * 265dfbf7de5SChris Cain * @param[in] dbusSource The throttle cause from DBUS 266dfbf7de5SChris Cain * 267dfbf7de5SChris Cain * @return Returns as a string, the throttle cause in Redfish terms. If 268dfbf7de5SChris Cain * translation cannot be done, returns "Unknown" throttle reason. 269dfbf7de5SChris Cain */ 270504af5a0SPatrick Williams inline processor::ThrottleCause dbusToRfThrottleCause( 271504af5a0SPatrick Williams const std::string& dbusSource) 272dfbf7de5SChris Cain { 273dfbf7de5SChris Cain if (dbusSource == 274dfbf7de5SChris Cain "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ClockLimit") 275dfbf7de5SChris Cain { 276dfbf7de5SChris Cain return processor::ThrottleCause::ClockLimit; 277dfbf7de5SChris Cain } 278dfbf7de5SChris Cain if (dbusSource == 279dfbf7de5SChris Cain "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ManagementDetectedFault") 280dfbf7de5SChris Cain { 281dfbf7de5SChris Cain return processor::ThrottleCause::ManagementDetectedFault; 282dfbf7de5SChris Cain } 283dfbf7de5SChris Cain if (dbusSource == 284dfbf7de5SChris Cain "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.PowerLimit") 285dfbf7de5SChris Cain { 286dfbf7de5SChris Cain return processor::ThrottleCause::PowerLimit; 287dfbf7de5SChris Cain } 288dfbf7de5SChris Cain if (dbusSource == 289dfbf7de5SChris Cain "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.ThermalLimit") 290dfbf7de5SChris Cain { 291dfbf7de5SChris Cain return processor::ThrottleCause::ThermalLimit; 292dfbf7de5SChris Cain } 293dfbf7de5SChris Cain if (dbusSource == 294dfbf7de5SChris Cain "xyz.openbmc_project.Control.Power.Throttle.ThrottleReasons.Unknown") 295dfbf7de5SChris Cain { 296dfbf7de5SChris Cain return processor::ThrottleCause::Unknown; 297dfbf7de5SChris Cain } 298dfbf7de5SChris Cain return processor::ThrottleCause::Invalid; 299dfbf7de5SChris Cain } 300dfbf7de5SChris Cain 301504af5a0SPatrick Williams inline void readThrottleProperties( 302504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 303dfbf7de5SChris Cain const boost::system::error_code& ec, 304dfbf7de5SChris Cain const dbus::utility::DBusPropertiesMap& properties) 305dfbf7de5SChris Cain { 306dfbf7de5SChris Cain if (ec) 307dfbf7de5SChris Cain { 30862598e31SEd Tanous BMCWEB_LOG_ERROR("Processor Throttle getAllProperties error {}", ec); 309ac106bf6SEd Tanous messages::internalError(asyncResp->res); 310dfbf7de5SChris Cain return; 311dfbf7de5SChris Cain } 312dfbf7de5SChris Cain 313dfbf7de5SChris Cain const bool* status = nullptr; 314dfbf7de5SChris Cain const std::vector<std::string>* causes = nullptr; 315dfbf7de5SChris Cain 316dfbf7de5SChris Cain if (!sdbusplus::unpackPropertiesNoThrow(dbus_utils::UnpackErrorPrinter(), 317dfbf7de5SChris Cain properties, "Throttled", status, 318dfbf7de5SChris Cain "ThrottleCauses", causes)) 319dfbf7de5SChris Cain { 320ac106bf6SEd Tanous messages::internalError(asyncResp->res); 321dfbf7de5SChris Cain return; 322dfbf7de5SChris Cain } 323dfbf7de5SChris Cain 324ac106bf6SEd Tanous asyncResp->res.jsonValue["Throttled"] = *status; 325dfbf7de5SChris Cain nlohmann::json::array_t rCauses; 326dfbf7de5SChris Cain for (const std::string& cause : *causes) 327dfbf7de5SChris Cain { 328dfbf7de5SChris Cain processor::ThrottleCause rfCause = dbusToRfThrottleCause(cause); 329dfbf7de5SChris Cain if (rfCause == processor::ThrottleCause::Invalid) 330dfbf7de5SChris Cain { 331ac106bf6SEd Tanous messages::internalError(asyncResp->res); 332dfbf7de5SChris Cain return; 333dfbf7de5SChris Cain } 334dfbf7de5SChris Cain 335dfbf7de5SChris Cain rCauses.emplace_back(rfCause); 336dfbf7de5SChris Cain } 337ac106bf6SEd Tanous asyncResp->res.jsonValue["ThrottleCauses"] = std::move(rCauses); 338dfbf7de5SChris Cain } 339dfbf7de5SChris Cain 340bd79bce8SPatrick Williams inline void getThrottleProperties( 341bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 342bd79bce8SPatrick Williams const std::string& service, const std::string& objectPath) 343dfbf7de5SChris Cain { 34462598e31SEd Tanous BMCWEB_LOG_DEBUG("Get processor throttle resources"); 345dfbf7de5SChris Cain 346deae6a78SEd Tanous dbus::utility::getAllProperties( 347deae6a78SEd Tanous service, objectPath, "xyz.openbmc_project.Control.Power.Throttle", 348ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 349dfbf7de5SChris Cain const dbus::utility::DBusPropertiesMap& properties) { 350ac106bf6SEd Tanous readThrottleProperties(asyncResp, ec, properties); 351dfbf7de5SChris Cain }); 352dfbf7de5SChris Cain } 353dfbf7de5SChris Cain 354ac106bf6SEd Tanous inline void getCpuAssetData(std::shared_ptr<bmcweb::AsyncResp> asyncResp, 355ac6a4445SGunnar Mills const std::string& service, 356ac6a4445SGunnar Mills const std::string& objPath) 357ac6a4445SGunnar Mills { 35862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Cpu Asset Data"); 359deae6a78SEd Tanous dbus::utility::getAllProperties( 360deae6a78SEd Tanous service, objPath, "xyz.openbmc_project.Inventory.Decorator.Asset", 361ac106bf6SEd Tanous [objPath, asyncResp{std::move(asyncResp)}]( 3625e7e2dc5SEd Tanous const boost::system::error_code& ec, 363351053f2SKrzysztof Grobelny const dbus::utility::DBusPropertiesMap& properties) { 364ac6a4445SGunnar Mills if (ec) 365ac6a4445SGunnar Mills { 36662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 367ac106bf6SEd Tanous messages::internalError(asyncResp->res); 368ac6a4445SGunnar Mills return; 369ac6a4445SGunnar Mills } 370ac6a4445SGunnar Mills 371351053f2SKrzysztof Grobelny const std::string* serialNumber = nullptr; 372351053f2SKrzysztof Grobelny const std::string* model = nullptr; 373351053f2SKrzysztof Grobelny const std::string* manufacturer = nullptr; 374351053f2SKrzysztof Grobelny const std::string* partNumber = nullptr; 375351053f2SKrzysztof Grobelny const std::string* sparePartNumber = nullptr; 376351053f2SKrzysztof Grobelny 377351053f2SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 378351053f2SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "SerialNumber", 379351053f2SKrzysztof Grobelny serialNumber, "Model", model, "Manufacturer", manufacturer, 380351053f2SKrzysztof Grobelny "PartNumber", partNumber, "SparePartNumber", sparePartNumber); 381351053f2SKrzysztof Grobelny 382351053f2SKrzysztof Grobelny if (!success) 383ac6a4445SGunnar Mills { 384ac106bf6SEd Tanous messages::internalError(asyncResp->res); 385351053f2SKrzysztof Grobelny return; 386ac6a4445SGunnar Mills } 387351053f2SKrzysztof Grobelny 388351053f2SKrzysztof Grobelny if (serialNumber != nullptr && !serialNumber->empty()) 389ac6a4445SGunnar Mills { 390ac106bf6SEd Tanous asyncResp->res.jsonValue["SerialNumber"] = *serialNumber; 391351053f2SKrzysztof Grobelny } 392351053f2SKrzysztof Grobelny 393351053f2SKrzysztof Grobelny if ((model != nullptr) && !model->empty()) 394ac6a4445SGunnar Mills { 395ac106bf6SEd Tanous asyncResp->res.jsonValue["Model"] = *model; 396ac6a4445SGunnar Mills } 397ac6a4445SGunnar Mills 398351053f2SKrzysztof Grobelny if (manufacturer != nullptr) 399ac6a4445SGunnar Mills { 400ac106bf6SEd Tanous asyncResp->res.jsonValue["Manufacturer"] = *manufacturer; 401ac6a4445SGunnar Mills 402ac6a4445SGunnar Mills // Otherwise would be unexpected. 403351053f2SKrzysztof Grobelny if (manufacturer->find("Intel") != std::string::npos) 404ac6a4445SGunnar Mills { 405ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorArchitecture"] = "x86"; 406ac106bf6SEd Tanous asyncResp->res.jsonValue["InstructionSet"] = "x86-64"; 407ac6a4445SGunnar Mills } 408351053f2SKrzysztof Grobelny else if (manufacturer->find("IBM") != std::string::npos) 409ac6a4445SGunnar Mills { 410ac106bf6SEd Tanous asyncResp->res.jsonValue["ProcessorArchitecture"] = "Power"; 411ac106bf6SEd Tanous asyncResp->res.jsonValue["InstructionSet"] = "PowerISA"; 412ac6a4445SGunnar Mills } 4134d0c0c42SRebecca Cran else if (manufacturer->find("Ampere") != std::string::npos) 4144d0c0c42SRebecca Cran { 4154d0c0c42SRebecca Cran asyncResp->res.jsonValue["ProcessorArchitecture"] = "ARM"; 4164d0c0c42SRebecca Cran asyncResp->res.jsonValue["InstructionSet"] = "ARM-A64"; 4174d0c0c42SRebecca Cran } 418ac6a4445SGunnar Mills } 419cba4f448SSunnySrivastava1984 420351053f2SKrzysztof Grobelny if (partNumber != nullptr) 421cba4f448SSunnySrivastava1984 { 422ac106bf6SEd Tanous asyncResp->res.jsonValue["PartNumber"] = *partNumber; 423cba4f448SSunnySrivastava1984 } 424cba4f448SSunnySrivastava1984 4256169de2cSBrad Bishop if (sparePartNumber != nullptr && !sparePartNumber->empty()) 426cba4f448SSunnySrivastava1984 { 427ac106bf6SEd Tanous asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber; 428cba4f448SSunnySrivastava1984 } 429351053f2SKrzysztof Grobelny }); 430ac6a4445SGunnar Mills } 431ac6a4445SGunnar Mills 432ac106bf6SEd Tanous inline void getCpuRevisionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp, 433ac6a4445SGunnar Mills const std::string& service, 434ac6a4445SGunnar Mills const std::string& objPath) 435ac6a4445SGunnar Mills { 43662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Cpu Revision Data"); 437deae6a78SEd Tanous dbus::utility::getAllProperties( 438deae6a78SEd Tanous service, objPath, "xyz.openbmc_project.Inventory.Decorator.Revision", 439ac106bf6SEd Tanous [objPath, asyncResp{std::move(asyncResp)}]( 4405e7e2dc5SEd Tanous const boost::system::error_code& ec, 441351053f2SKrzysztof Grobelny const dbus::utility::DBusPropertiesMap& properties) { 442ac6a4445SGunnar Mills if (ec) 443ac6a4445SGunnar Mills { 44462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 445ac106bf6SEd Tanous messages::internalError(asyncResp->res); 446ac6a4445SGunnar Mills return; 447ac6a4445SGunnar Mills } 448ac6a4445SGunnar Mills 449351053f2SKrzysztof Grobelny const std::string* version = nullptr; 450351053f2SKrzysztof Grobelny 451351053f2SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 452bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), properties, "Version", 453bd79bce8SPatrick Williams version); 454351053f2SKrzysztof Grobelny 455351053f2SKrzysztof Grobelny if (!success) 456ac6a4445SGunnar Mills { 457ac106bf6SEd Tanous messages::internalError(asyncResp->res); 458351053f2SKrzysztof Grobelny return; 459351053f2SKrzysztof Grobelny } 460351053f2SKrzysztof Grobelny 461351053f2SKrzysztof Grobelny if (version != nullptr) 462ac6a4445SGunnar Mills { 463ac106bf6SEd Tanous asyncResp->res.jsonValue["Version"] = *version; 464ac6a4445SGunnar Mills } 465351053f2SKrzysztof Grobelny }); 466ac6a4445SGunnar Mills } 467ac6a4445SGunnar Mills 4688d1b46d7Szhanghch05 inline void getAcceleratorDataByService( 469ac106bf6SEd Tanous std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& acclrtrId, 4708d1b46d7Szhanghch05 const std::string& service, const std::string& objPath) 471ac6a4445SGunnar Mills { 47262598e31SEd Tanous BMCWEB_LOG_DEBUG("Get available system Accelerator resources by service."); 473deae6a78SEd Tanous dbus::utility::getAllProperties( 474deae6a78SEd Tanous service, objPath, "", 475ac106bf6SEd Tanous [acclrtrId, asyncResp{std::move(asyncResp)}]( 4765e7e2dc5SEd Tanous const boost::system::error_code& ec, 477351053f2SKrzysztof Grobelny const dbus::utility::DBusPropertiesMap& properties) { 478ac6a4445SGunnar Mills if (ec) 479ac6a4445SGunnar Mills { 48062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 481ac106bf6SEd Tanous messages::internalError(asyncResp->res); 482ac6a4445SGunnar Mills return; 483ac6a4445SGunnar Mills } 484ac6a4445SGunnar Mills 485351053f2SKrzysztof Grobelny const bool* functional = nullptr; 486351053f2SKrzysztof Grobelny const bool* present = nullptr; 487351053f2SKrzysztof Grobelny 488351053f2SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 489351053f2SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Functional", 490351053f2SKrzysztof Grobelny functional, "Present", present); 491351053f2SKrzysztof Grobelny 492351053f2SKrzysztof Grobelny if (!success) 493ac6a4445SGunnar Mills { 494ac106bf6SEd Tanous messages::internalError(asyncResp->res); 495351053f2SKrzysztof Grobelny return; 496ac6a4445SGunnar Mills } 497ac6a4445SGunnar Mills 498ac6a4445SGunnar Mills std::string state = "Enabled"; 499ac6a4445SGunnar Mills std::string health = "OK"; 500ac6a4445SGunnar Mills 501351053f2SKrzysztof Grobelny if (present != nullptr && !*present) 502ac6a4445SGunnar Mills { 503ac6a4445SGunnar Mills state = "Absent"; 504ac6a4445SGunnar Mills } 505ac6a4445SGunnar Mills 506351053f2SKrzysztof Grobelny if (functional != nullptr && !*functional) 507ac6a4445SGunnar Mills { 508ac6a4445SGunnar Mills if (state == "Enabled") 509ac6a4445SGunnar Mills { 510ac6a4445SGunnar Mills health = "Critical"; 511ac6a4445SGunnar Mills } 512ac6a4445SGunnar Mills } 513ac6a4445SGunnar Mills 514ac106bf6SEd Tanous asyncResp->res.jsonValue["Id"] = acclrtrId; 515ac106bf6SEd Tanous asyncResp->res.jsonValue["Name"] = "Processor"; 516ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = state; 517ac106bf6SEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = health; 518539d8c6bSEd Tanous asyncResp->res.jsonValue["ProcessorType"] = 519539d8c6bSEd Tanous processor::ProcessorType::Accelerator; 520351053f2SKrzysztof Grobelny }); 521ac6a4445SGunnar Mills } 522ac6a4445SGunnar Mills 523dba0c291SJonathan Doman // OperatingConfig D-Bus Types 524dba0c291SJonathan Doman using TurboProfileProperty = std::vector<std::tuple<uint32_t, size_t>>; 525dba0c291SJonathan Doman using BaseSpeedPrioritySettingsProperty = 526dba0c291SJonathan Doman std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>; 527dba0c291SJonathan Doman // uint32_t and size_t may or may not be the same type, requiring a dedup'd 528dba0c291SJonathan Doman // variant 529dba0c291SJonathan Doman 530dba0c291SJonathan Doman /** 531dba0c291SJonathan Doman * Fill out the HighSpeedCoreIDs in a Processor resource from the given 532dba0c291SJonathan Doman * OperatingConfig D-Bus property. 533dba0c291SJonathan Doman * 534ac106bf6SEd Tanous * @param[in,out] asyncResp Async HTTP response. 535dba0c291SJonathan Doman * @param[in] baseSpeedSettings Full list of base speed priority groups, 536dba0c291SJonathan Doman * to use to determine the list of high 537dba0c291SJonathan Doman * speed cores. 538dba0c291SJonathan Doman */ 539dba0c291SJonathan Doman inline void highSpeedCoreIdsHandler( 540ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 541dba0c291SJonathan Doman const BaseSpeedPrioritySettingsProperty& baseSpeedSettings) 542dba0c291SJonathan Doman { 543dba0c291SJonathan Doman // The D-Bus property does not indicate which bucket is the "high 544dba0c291SJonathan Doman // priority" group, so let's discern that by looking for the one with 545dba0c291SJonathan Doman // highest base frequency. 546dba0c291SJonathan Doman auto highPriorityGroup = baseSpeedSettings.cend(); 547dba0c291SJonathan Doman uint32_t highestBaseSpeed = 0; 548dba0c291SJonathan Doman for (auto it = baseSpeedSettings.cbegin(); it != baseSpeedSettings.cend(); 549dba0c291SJonathan Doman ++it) 550dba0c291SJonathan Doman { 551dba0c291SJonathan Doman const uint32_t baseFreq = std::get<uint32_t>(*it); 552dba0c291SJonathan Doman if (baseFreq > highestBaseSpeed) 553dba0c291SJonathan Doman { 554dba0c291SJonathan Doman highestBaseSpeed = baseFreq; 555dba0c291SJonathan Doman highPriorityGroup = it; 556dba0c291SJonathan Doman } 557dba0c291SJonathan Doman } 558dba0c291SJonathan Doman 559ac106bf6SEd Tanous nlohmann::json& jsonCoreIds = asyncResp->res.jsonValue["HighSpeedCoreIDs"]; 560dba0c291SJonathan Doman jsonCoreIds = nlohmann::json::array(); 561dba0c291SJonathan Doman 562dba0c291SJonathan Doman // There may not be any entries in the D-Bus property, so only populate 563dba0c291SJonathan Doman // if there was actually something there. 564dba0c291SJonathan Doman if (highPriorityGroup != baseSpeedSettings.cend()) 565dba0c291SJonathan Doman { 566dba0c291SJonathan Doman jsonCoreIds = std::get<std::vector<uint32_t>>(*highPriorityGroup); 567dba0c291SJonathan Doman } 568dba0c291SJonathan Doman } 569dba0c291SJonathan Doman 570dba0c291SJonathan Doman /** 571dba0c291SJonathan Doman * Fill out OperatingConfig related items in a Processor resource by requesting 572dba0c291SJonathan Doman * data from the given D-Bus object. 573dba0c291SJonathan Doman * 574ac106bf6SEd Tanous * @param[in,out] asyncResp Async HTTP response. 575dba0c291SJonathan Doman * @param[in] cpuId CPU D-Bus name. 576dba0c291SJonathan Doman * @param[in] service D-Bus service to query. 577dba0c291SJonathan Doman * @param[in] objPath D-Bus object to query. 578dba0c291SJonathan Doman */ 579504af5a0SPatrick Williams inline void getCpuConfigData( 580504af5a0SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 581ac106bf6SEd Tanous const std::string& cpuId, const std::string& service, 582dba0c291SJonathan Doman const std::string& objPath) 583dba0c291SJonathan Doman { 58462598e31SEd Tanous BMCWEB_LOG_INFO("Getting CPU operating configs for {}", cpuId); 585dba0c291SJonathan Doman 586dba0c291SJonathan Doman // First, GetAll CurrentOperatingConfig properties on the object 587deae6a78SEd Tanous dbus::utility::getAllProperties( 588deae6a78SEd Tanous service, objPath, 589351053f2SKrzysztof Grobelny "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig", 590ac106bf6SEd Tanous [asyncResp, cpuId, 5915e7e2dc5SEd Tanous service](const boost::system::error_code& ec, 592351053f2SKrzysztof Grobelny const dbus::utility::DBusPropertiesMap& properties) { 593dba0c291SJonathan Doman if (ec) 594dba0c291SJonathan Doman { 59562598e31SEd Tanous BMCWEB_LOG_WARNING("D-Bus error: {}, {}", ec, ec.message()); 596ac106bf6SEd Tanous messages::internalError(asyncResp->res); 597dba0c291SJonathan Doman return; 598dba0c291SJonathan Doman } 599dba0c291SJonathan Doman 600ac106bf6SEd Tanous nlohmann::json& json = asyncResp->res.jsonValue; 601dba0c291SJonathan Doman 602351053f2SKrzysztof Grobelny const sdbusplus::message::object_path* appliedConfig = nullptr; 603351053f2SKrzysztof Grobelny const bool* baseSpeedPriorityEnabled = nullptr; 604351053f2SKrzysztof Grobelny 605351053f2SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 606351053f2SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "AppliedConfig", 607351053f2SKrzysztof Grobelny appliedConfig, "BaseSpeedPriorityEnabled", 608351053f2SKrzysztof Grobelny baseSpeedPriorityEnabled); 609351053f2SKrzysztof Grobelny 610351053f2SKrzysztof Grobelny if (!success) 611dba0c291SJonathan Doman { 612ac106bf6SEd Tanous messages::internalError(asyncResp->res); 613351053f2SKrzysztof Grobelny return; 614dba0c291SJonathan Doman } 615dba0c291SJonathan Doman 616351053f2SKrzysztof Grobelny if (appliedConfig != nullptr) 617351053f2SKrzysztof Grobelny { 618351053f2SKrzysztof Grobelny const std::string& dbusPath = appliedConfig->str; 6191476687dSEd Tanous nlohmann::json::object_t operatingConfig; 620ef4c65b7SEd Tanous operatingConfig["@odata.id"] = boost::urls::format( 621253f11b8SEd Tanous "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs", 622253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId); 6231476687dSEd Tanous json["OperatingConfigs"] = std::move(operatingConfig); 624dba0c291SJonathan Doman 625dba0c291SJonathan Doman // Reuse the D-Bus config object name for the Redfish 626dba0c291SJonathan Doman // URI 627dba0c291SJonathan Doman size_t baseNamePos = dbusPath.rfind('/'); 628dba0c291SJonathan Doman if (baseNamePos == std::string::npos || 629dba0c291SJonathan Doman baseNamePos == (dbusPath.size() - 1)) 630dba0c291SJonathan Doman { 631dba0c291SJonathan Doman // If the AppliedConfig was somehow not a valid path, 632dba0c291SJonathan Doman // skip adding any more properties, since everything 633dba0c291SJonathan Doman // else is tied to this applied config. 634ac106bf6SEd Tanous messages::internalError(asyncResp->res); 635351053f2SKrzysztof Grobelny return; 636dba0c291SJonathan Doman } 6371476687dSEd Tanous nlohmann::json::object_t appliedOperatingConfig; 638ef4c65b7SEd Tanous appliedOperatingConfig["@odata.id"] = boost::urls::format( 639253f11b8SEd Tanous "/redfish/v1/Systems/{}/Processors/{}/OperatingConfigs/{}", 640253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME, cpuId, 641253f11b8SEd Tanous dbusPath.substr(baseNamePos + 1)); 642bd79bce8SPatrick Williams json["AppliedOperatingConfig"] = 643bd79bce8SPatrick Williams std::move(appliedOperatingConfig); 644dba0c291SJonathan Doman 645dba0c291SJonathan Doman // Once we found the current applied config, queue another 646dba0c291SJonathan Doman // request to read the base freq core ids out of that 647dba0c291SJonathan Doman // config. 648deae6a78SEd Tanous dbus::utility::getProperty<BaseSpeedPrioritySettingsProperty>( 649deae6a78SEd Tanous service, dbusPath, 6501e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Item.Cpu." 6511e1e598dSJonathan Doman "OperatingConfig", 6521e1e598dSJonathan Doman "BaseSpeedPrioritySettings", 653bd79bce8SPatrick Williams [asyncResp](const boost::system::error_code& ec2, 654bd79bce8SPatrick Williams const BaseSpeedPrioritySettingsProperty& 655bd79bce8SPatrick Williams baseSpeedList) { 6568a592810SEd Tanous if (ec2) 657dba0c291SJonathan Doman { 658bd79bce8SPatrick Williams BMCWEB_LOG_WARNING("D-Bus Property Get error: {}", 659bd79bce8SPatrick Williams ec2); 660ac106bf6SEd Tanous messages::internalError(asyncResp->res); 661dba0c291SJonathan Doman return; 662dba0c291SJonathan Doman } 6631e1e598dSJonathan Doman 664ac106bf6SEd Tanous highSpeedCoreIdsHandler(asyncResp, baseSpeedList); 6651e1e598dSJonathan Doman }); 666dba0c291SJonathan Doman } 667351053f2SKrzysztof Grobelny 668351053f2SKrzysztof Grobelny if (baseSpeedPriorityEnabled != nullptr) 669dba0c291SJonathan Doman { 670dba0c291SJonathan Doman json["BaseSpeedPriorityState"] = 671351053f2SKrzysztof Grobelny *baseSpeedPriorityEnabled ? "Enabled" : "Disabled"; 672dba0c291SJonathan Doman } 673351053f2SKrzysztof Grobelny }); 674dba0c291SJonathan Doman } 675dba0c291SJonathan Doman 676cba4f448SSunnySrivastava1984 /** 677cba4f448SSunnySrivastava1984 * @brief Fill out location info of a processor by 678cba4f448SSunnySrivastava1984 * requesting data from the given D-Bus object. 679cba4f448SSunnySrivastava1984 * 680ac106bf6SEd Tanous * @param[in,out] asyncResp Async HTTP response. 681cba4f448SSunnySrivastava1984 * @param[in] service D-Bus service to query. 682cba4f448SSunnySrivastava1984 * @param[in] objPath D-Bus object to query. 683cba4f448SSunnySrivastava1984 */ 684ac106bf6SEd Tanous inline void getCpuLocationCode(std::shared_ptr<bmcweb::AsyncResp> asyncResp, 685cba4f448SSunnySrivastava1984 const std::string& service, 686cba4f448SSunnySrivastava1984 const std::string& objPath) 687cba4f448SSunnySrivastava1984 { 68862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Cpu Location Data"); 689deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 690deae6a78SEd Tanous service, objPath, 6911e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode", 692ac106bf6SEd Tanous [objPath, asyncResp{std::move(asyncResp)}]( 693ac106bf6SEd Tanous const boost::system::error_code& ec, const std::string& property) { 694cba4f448SSunnySrivastava1984 if (ec) 695cba4f448SSunnySrivastava1984 { 69662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 697ac106bf6SEd Tanous messages::internalError(asyncResp->res); 698cba4f448SSunnySrivastava1984 return; 699cba4f448SSunnySrivastava1984 } 700cba4f448SSunnySrivastava1984 701bd79bce8SPatrick Williams asyncResp->res 702bd79bce8SPatrick Williams .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 7031e1e598dSJonathan Doman property; 7041e1e598dSJonathan Doman }); 705cba4f448SSunnySrivastava1984 } 706cba4f448SSunnySrivastava1984 707c951448aSJonathan Doman /** 70849e429caSJonathan Doman * Populate the unique identifier in a Processor resource by requesting data 70949e429caSJonathan Doman * from the given D-Bus object. 71049e429caSJonathan Doman * 711ac106bf6SEd Tanous * @param[in,out] asyncResp Async HTTP response. 71249e429caSJonathan Doman * @param[in] service D-Bus service to query. 71349e429caSJonathan Doman * @param[in] objPath D-Bus object to query. 71449e429caSJonathan Doman */ 715ac106bf6SEd Tanous inline void getCpuUniqueId(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 71649e429caSJonathan Doman const std::string& service, 71749e429caSJonathan Doman const std::string& objectPath) 71849e429caSJonathan Doman { 71962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get CPU UniqueIdentifier"); 720deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 721deae6a78SEd Tanous service, objectPath, 7221e1e598dSJonathan Doman "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier", 7231e1e598dSJonathan Doman "UniqueIdentifier", 724ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 725ac106bf6SEd Tanous const std::string& id) { 7261e1e598dSJonathan Doman if (ec) 72749e429caSJonathan Doman { 72862598e31SEd Tanous BMCWEB_LOG_ERROR("Failed to read cpu unique id: {}", ec); 729ac106bf6SEd Tanous messages::internalError(asyncResp->res); 73049e429caSJonathan Doman return; 73149e429caSJonathan Doman } 732ac106bf6SEd Tanous asyncResp->res 733ac106bf6SEd Tanous .jsonValue["ProcessorId"]["ProtectedIdentificationNumber"] = id; 7341e1e598dSJonathan Doman }); 73549e429caSJonathan Doman } 73649e429caSJonathan Doman 73798eafce5SGeorge Liu inline void handleProcessorSubtree( 73898eafce5SGeorge Liu const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 73998eafce5SGeorge Liu const std::string& processorId, 74098eafce5SGeorge Liu const std::function< 74198eafce5SGeorge Liu void(const std::string& objectPath, 74298eafce5SGeorge Liu const dbus::utility::MapperServiceMap& serviceMap)>& callback, 74398eafce5SGeorge Liu const boost::system::error_code& ec, 74498eafce5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) 74598eafce5SGeorge Liu { 74698eafce5SGeorge Liu if (ec) 74798eafce5SGeorge Liu { 74898eafce5SGeorge Liu BMCWEB_LOG_ERROR("DBUS response error: {}", ec); 74998eafce5SGeorge Liu messages::internalError(asyncResp->res); 75098eafce5SGeorge Liu return; 75198eafce5SGeorge Liu } 75298eafce5SGeorge Liu for (const auto& [objectPath, serviceMap] : subtree) 75398eafce5SGeorge Liu { 75498eafce5SGeorge Liu // Ignore any objects which don't end with our desired cpu name 75598eafce5SGeorge Liu sdbusplus::message::object_path path(objectPath); 75698eafce5SGeorge Liu if (path.filename() == processorId) 75798eafce5SGeorge Liu { 75898eafce5SGeorge Liu // Filter out objects that don't have the CPU-specific 75998eafce5SGeorge Liu // interfaces to make sure we can return 404 on non-CPUs 76098eafce5SGeorge Liu // (e.g. /redfish/../Processors/dimm0) 76198eafce5SGeorge Liu for (const auto& [serviceName, interfaceList] : serviceMap) 76298eafce5SGeorge Liu { 76398eafce5SGeorge Liu if (std::ranges::find_first_of(interfaceList, 76498eafce5SGeorge Liu processorInterfaces) != 76598eafce5SGeorge Liu interfaceList.end()) 76698eafce5SGeorge Liu { 76798eafce5SGeorge Liu // Process the first object which matches cpu name and 76898eafce5SGeorge Liu // required interfaces, and potentially ignore any other 76998eafce5SGeorge Liu // matching objects. Assume all interfaces we want to 77098eafce5SGeorge Liu // process must be on the same object path. 77198eafce5SGeorge Liu 77298eafce5SGeorge Liu callback(objectPath, serviceMap); 77398eafce5SGeorge Liu return; 77498eafce5SGeorge Liu } 77598eafce5SGeorge Liu } 77698eafce5SGeorge Liu } 77798eafce5SGeorge Liu } 77898eafce5SGeorge Liu messages::resourceNotFound(asyncResp->res, "Processor", processorId); 77998eafce5SGeorge Liu } 78098eafce5SGeorge Liu 78149e429caSJonathan Doman /** 782c951448aSJonathan Doman * Find the D-Bus object representing the requested Processor, and call the 783c951448aSJonathan Doman * handler with the results. If matching object is not found, add 404 error to 784c951448aSJonathan Doman * response and don't call the handler. 785c951448aSJonathan Doman * 78698eafce5SGeorge Liu * @param[in,out] asyncResp Async HTTP response. 787c951448aSJonathan Doman * @param[in] processorId Redfish Processor Id. 78898eafce5SGeorge Liu * @param[in] callback Callback to continue processing request upon 789c951448aSJonathan Doman * successfully finding object. 790c951448aSJonathan Doman */ 79198eafce5SGeorge Liu inline void getProcessorObject( 79298eafce5SGeorge Liu const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 793c951448aSJonathan Doman const std::string& processorId, 79498eafce5SGeorge Liu std::function<void(const std::string& objectPath, 79598eafce5SGeorge Liu const dbus::utility::MapperServiceMap& serviceMap)>&& 79698eafce5SGeorge Liu callback) 797ac6a4445SGunnar Mills { 79862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get available system processor resources."); 799ac6a4445SGunnar Mills 800c951448aSJonathan Doman // GetSubTree on all interfaces which provide info about a Processor 801dfbf7de5SChris Cain constexpr std::array<std::string_view, 9> interfaces = { 802e99073f5SGeorge Liu "xyz.openbmc_project.Common.UUID", 803e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.Asset", 804e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.Revision", 805e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Cpu", 806e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.LocationCode", 807e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Accelerator", 808e99073f5SGeorge Liu "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig", 809dfbf7de5SChris Cain "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier", 810dfbf7de5SChris Cain "xyz.openbmc_project.Control.Power.Throttle"}; 811e99073f5SGeorge Liu dbus::utility::getSubTree( 812e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 81398eafce5SGeorge Liu [asyncResp, processorId, callback{std::move(callback)}]( 814e99073f5SGeorge Liu const boost::system::error_code& ec, 815e99073f5SGeorge Liu const dbus::utility::MapperGetSubTreeResponse& subtree) { 81698eafce5SGeorge Liu handleProcessorSubtree(asyncResp, processorId, callback, ec, 81798eafce5SGeorge Liu subtree); 818e99073f5SGeorge Liu }); 819ac6a4445SGunnar Mills } 820ac6a4445SGunnar Mills 821bd79bce8SPatrick Williams inline void getProcessorData( 822bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 823bd79bce8SPatrick Williams const std::string& processorId, const std::string& objectPath, 8245df6eda2SShantappa Teekappanavar const dbus::utility::MapperServiceMap& serviceMap) 825c951448aSJonathan Doman { 82698eafce5SGeorge Liu asyncResp->res.addHeader( 82798eafce5SGeorge Liu boost::beast::http::field::link, 82898eafce5SGeorge Liu "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby"); 82998eafce5SGeorge Liu asyncResp->res.jsonValue["@odata.type"] = "#Processor.v1_18_0.Processor"; 83098eafce5SGeorge Liu asyncResp->res.jsonValue["@odata.id"] = 83198eafce5SGeorge Liu boost::urls::format("/redfish/v1/Systems/{}/Processors/{}", 83298eafce5SGeorge Liu BMCWEB_REDFISH_SYSTEM_URI_NAME, processorId); 83398eafce5SGeorge Liu 834c951448aSJonathan Doman for (const auto& [serviceName, interfaceList] : serviceMap) 835c951448aSJonathan Doman { 836c951448aSJonathan Doman for (const auto& interface : interfaceList) 837c951448aSJonathan Doman { 838c951448aSJonathan Doman if (interface == "xyz.openbmc_project.Inventory.Decorator.Asset") 839c951448aSJonathan Doman { 840ac106bf6SEd Tanous getCpuAssetData(asyncResp, serviceName, objectPath); 841c951448aSJonathan Doman } 8420fda0f12SGeorge Liu else if (interface == 8430fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.Revision") 844c951448aSJonathan Doman { 845ac106bf6SEd Tanous getCpuRevisionData(asyncResp, serviceName, objectPath); 846c951448aSJonathan Doman } 847c951448aSJonathan Doman else if (interface == "xyz.openbmc_project.Inventory.Item.Cpu") 848c951448aSJonathan Doman { 849ac106bf6SEd Tanous getCpuDataByService(asyncResp, processorId, serviceName, 850c951448aSJonathan Doman objectPath); 851c951448aSJonathan Doman } 8520fda0f12SGeorge Liu else if (interface == 8530fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Accelerator") 854c951448aSJonathan Doman { 855ac106bf6SEd Tanous getAcceleratorDataByService(asyncResp, processorId, serviceName, 856c951448aSJonathan Doman objectPath); 857c951448aSJonathan Doman } 8580fda0f12SGeorge Liu else if ( 8590fda0f12SGeorge Liu interface == 8600fda0f12SGeorge Liu "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig") 861c951448aSJonathan Doman { 862ac106bf6SEd Tanous getCpuConfigData(asyncResp, processorId, serviceName, 863ac106bf6SEd Tanous objectPath); 864c951448aSJonathan Doman } 8650fda0f12SGeorge Liu else if (interface == 8660fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.LocationCode") 867c951448aSJonathan Doman { 868ac106bf6SEd Tanous getCpuLocationCode(asyncResp, serviceName, objectPath); 869c951448aSJonathan Doman } 87071b82f26SSharad Yadav else if (interface == "xyz.openbmc_project.Common.UUID") 87171b82f26SSharad Yadav { 872ac106bf6SEd Tanous getProcessorUUID(asyncResp, serviceName, objectPath); 87371b82f26SSharad Yadav } 8740fda0f12SGeorge Liu else if (interface == 8750fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier") 87649e429caSJonathan Doman { 877ac106bf6SEd Tanous getCpuUniqueId(asyncResp, serviceName, objectPath); 87849e429caSJonathan Doman } 879dfbf7de5SChris Cain else if (interface == "xyz.openbmc_project.Control.Power.Throttle") 880dfbf7de5SChris Cain { 881ac106bf6SEd Tanous getThrottleProperties(asyncResp, serviceName, objectPath); 882dfbf7de5SChris Cain } 88398eafce5SGeorge Liu else if (interface == "xyz.openbmc_project.Association.Definitions") 88498eafce5SGeorge Liu { 88598eafce5SGeorge Liu getLocationIndicatorActive(asyncResp, objectPath); 88698eafce5SGeorge Liu } 887c951448aSJonathan Doman } 888c951448aSJonathan Doman } 889c951448aSJonathan Doman } 890c951448aSJonathan Doman 891dba0c291SJonathan Doman /** 8923cde86f1SJonathan Doman * Handle the PATCH operation of the AppliedOperatingConfig property. Do basic 8933cde86f1SJonathan Doman * validation of the input data, and then set the D-Bus property. 8943cde86f1SJonathan Doman * 8953cde86f1SJonathan Doman * @param[in,out] resp Async HTTP response. 8963cde86f1SJonathan Doman * @param[in] processorId Processor's Id. 8973cde86f1SJonathan Doman * @param[in] appliedConfigUri New property value to apply. 8983cde86f1SJonathan Doman * @param[in] cpuObjectPath Path of CPU object to modify. 8993cde86f1SJonathan Doman * @param[in] serviceMap Service map for CPU object. 9003cde86f1SJonathan Doman */ 9013cde86f1SJonathan Doman inline void patchAppliedOperatingConfig( 9023cde86f1SJonathan Doman const std::shared_ptr<bmcweb::AsyncResp>& resp, 9033cde86f1SJonathan Doman const std::string& processorId, const std::string& appliedConfigUri, 9045df6eda2SShantappa Teekappanavar const std::string& cpuObjectPath, 9055df6eda2SShantappa Teekappanavar const dbus::utility::MapperServiceMap& serviceMap) 9063cde86f1SJonathan Doman { 9073cde86f1SJonathan Doman // Check that the property even exists by checking for the interface 9083cde86f1SJonathan Doman const std::string* controlService = nullptr; 9093cde86f1SJonathan Doman for (const auto& [serviceName, interfaceList] : serviceMap) 9103cde86f1SJonathan Doman { 9113544d2a7SEd Tanous if (std::ranges::find(interfaceList, 9123cde86f1SJonathan Doman "xyz.openbmc_project.Control.Processor." 9133cde86f1SJonathan Doman "CurrentOperatingConfig") != interfaceList.end()) 9143cde86f1SJonathan Doman { 9153cde86f1SJonathan Doman controlService = &serviceName; 9163cde86f1SJonathan Doman break; 9173cde86f1SJonathan Doman } 9183cde86f1SJonathan Doman } 9193cde86f1SJonathan Doman 9203cde86f1SJonathan Doman if (controlService == nullptr) 9213cde86f1SJonathan Doman { 9223cde86f1SJonathan Doman messages::internalError(resp->res); 9233cde86f1SJonathan Doman return; 9243cde86f1SJonathan Doman } 9253cde86f1SJonathan Doman 9263cde86f1SJonathan Doman // Check that the config URI is a child of the cpu URI being patched. 927253f11b8SEd Tanous std::string expectedPrefix(std::format("/redfish/v1/Systems/{}/Processors/", 928253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME)); 9293cde86f1SJonathan Doman expectedPrefix += processorId; 9303cde86f1SJonathan Doman expectedPrefix += "/OperatingConfigs/"; 93111ba3979SEd Tanous if (!appliedConfigUri.starts_with(expectedPrefix) || 9323cde86f1SJonathan Doman expectedPrefix.size() == appliedConfigUri.size()) 9333cde86f1SJonathan Doman { 93487c44966SAsmitha Karunanithi messages::propertyValueIncorrect(resp->res, "AppliedOperatingConfig", 93587c44966SAsmitha Karunanithi appliedConfigUri); 9363cde86f1SJonathan Doman return; 9373cde86f1SJonathan Doman } 9383cde86f1SJonathan Doman 9393cde86f1SJonathan Doman // Generate the D-Bus path of the OperatingConfig object, by assuming it's a 9403cde86f1SJonathan Doman // direct child of the CPU object. 9413cde86f1SJonathan Doman // Strip the expectedPrefix from the config URI to get the "filename", and 9423cde86f1SJonathan Doman // append to the CPU's path. 9433cde86f1SJonathan Doman std::string configBaseName = appliedConfigUri.substr(expectedPrefix.size()); 9443cde86f1SJonathan Doman sdbusplus::message::object_path configPath(cpuObjectPath); 9453cde86f1SJonathan Doman configPath /= configBaseName; 9463cde86f1SJonathan Doman 94762598e31SEd Tanous BMCWEB_LOG_INFO("Setting config to {}", configPath.str); 9483cde86f1SJonathan Doman 9493cde86f1SJonathan Doman // Set the property, with handler to check error responses 95087c44966SAsmitha Karunanithi setDbusProperty( 951e93abac6SGinu George resp, "AppliedOperatingConfig", *controlService, cpuObjectPath, 9529ae226faSGeorge Liu "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig", 953e93abac6SGinu George "AppliedConfig", configPath); 9543cde86f1SJonathan Doman } 9553cde86f1SJonathan Doman 956bd79bce8SPatrick Williams inline void handleProcessorHead( 957bd79bce8SPatrick Williams crow::App& app, const crow::Request& req, 958ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 959bd79bce8SPatrick Williams const std::string& /* systemName */, const std::string& /* processorId */) 96071a24ca4SNikhil Namjoshi { 961ac106bf6SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 96271a24ca4SNikhil Namjoshi { 96371a24ca4SNikhil Namjoshi return; 96471a24ca4SNikhil Namjoshi } 965ac106bf6SEd Tanous asyncResp->res.addHeader( 96671a24ca4SNikhil Namjoshi boost::beast::http::field::link, 96771a24ca4SNikhil Namjoshi "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby"); 96871a24ca4SNikhil Namjoshi } 96971a24ca4SNikhil Namjoshi 97071a24ca4SNikhil Namjoshi inline void handleProcessorCollectionHead( 97171a24ca4SNikhil Namjoshi crow::App& app, const crow::Request& req, 972ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 97371a24ca4SNikhil Namjoshi const std::string& /* systemName */) 97471a24ca4SNikhil Namjoshi { 975ac106bf6SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 97671a24ca4SNikhil Namjoshi { 97771a24ca4SNikhil Namjoshi return; 97871a24ca4SNikhil Namjoshi } 979ac106bf6SEd Tanous asyncResp->res.addHeader( 98071a24ca4SNikhil Namjoshi boost::beast::http::field::link, 98171a24ca4SNikhil Namjoshi "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby"); 98271a24ca4SNikhil Namjoshi } 98371a24ca4SNikhil Namjoshi 98498eafce5SGeorge Liu inline void handleProcessorGet( 98598eafce5SGeorge Liu App& app, const crow::Request& req, 98698eafce5SGeorge Liu const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 98798eafce5SGeorge Liu const std::string& systemName, const std::string& processorId) 98898eafce5SGeorge Liu { 98998eafce5SGeorge Liu if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 99098eafce5SGeorge Liu { 99198eafce5SGeorge Liu return; 99298eafce5SGeorge Liu } 99398eafce5SGeorge Liu if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 99498eafce5SGeorge Liu { 99598eafce5SGeorge Liu // Option currently returns no systems. TBD 99698eafce5SGeorge Liu messages::resourceNotFound(asyncResp->res, "ComputerSystem", 99798eafce5SGeorge Liu systemName); 99898eafce5SGeorge Liu return; 99998eafce5SGeorge Liu } 100098eafce5SGeorge Liu if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 100198eafce5SGeorge Liu { 100298eafce5SGeorge Liu messages::resourceNotFound(asyncResp->res, "ComputerSystem", 100398eafce5SGeorge Liu systemName); 100498eafce5SGeorge Liu return; 100598eafce5SGeorge Liu } 100698eafce5SGeorge Liu 100798eafce5SGeorge Liu getProcessorObject( 100898eafce5SGeorge Liu asyncResp, processorId, 100998eafce5SGeorge Liu std::bind_front(getProcessorData, asyncResp, processorId)); 101098eafce5SGeorge Liu } 101198eafce5SGeorge Liu 101298eafce5SGeorge Liu inline void doPatchProcessor( 101398eafce5SGeorge Liu const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 101498eafce5SGeorge Liu const std::string& processorId, 101598eafce5SGeorge Liu const std::optional<std::string>& appliedConfigUri, 101698eafce5SGeorge Liu std::optional<bool> locationIndicatorActive, const std::string& objectPath, 101798eafce5SGeorge Liu const dbus::utility::MapperServiceMap& serviceMap) 101898eafce5SGeorge Liu { 101998eafce5SGeorge Liu if (appliedConfigUri) 102098eafce5SGeorge Liu { 102198eafce5SGeorge Liu patchAppliedOperatingConfig(asyncResp, processorId, *appliedConfigUri, 102298eafce5SGeorge Liu objectPath, serviceMap); 102398eafce5SGeorge Liu } 102498eafce5SGeorge Liu 102598eafce5SGeorge Liu if (locationIndicatorActive) 102698eafce5SGeorge Liu { 102798eafce5SGeorge Liu // Utility function handles reporting errors 102898eafce5SGeorge Liu setLocationIndicatorActive(asyncResp, objectPath, 102998eafce5SGeorge Liu *locationIndicatorActive); 103098eafce5SGeorge Liu } 103198eafce5SGeorge Liu } 103298eafce5SGeorge Liu 103398eafce5SGeorge Liu inline void handleProcessorPatch( 103498eafce5SGeorge Liu App& app, const crow::Request& req, 103598eafce5SGeorge Liu const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 103698eafce5SGeorge Liu const std::string& systemName, const std::string& processorId) 103798eafce5SGeorge Liu { 103898eafce5SGeorge Liu if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 103998eafce5SGeorge Liu { 104098eafce5SGeorge Liu return; 104198eafce5SGeorge Liu } 104298eafce5SGeorge Liu if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 104398eafce5SGeorge Liu { 104498eafce5SGeorge Liu // Option currently returns no systems. TBD 104598eafce5SGeorge Liu messages::resourceNotFound(asyncResp->res, "ComputerSystem", 104698eafce5SGeorge Liu systemName); 104798eafce5SGeorge Liu return; 104898eafce5SGeorge Liu } 104998eafce5SGeorge Liu if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 105098eafce5SGeorge Liu { 105198eafce5SGeorge Liu messages::resourceNotFound(asyncResp->res, "ComputerSystem", 105298eafce5SGeorge Liu systemName); 105398eafce5SGeorge Liu return; 105498eafce5SGeorge Liu } 105598eafce5SGeorge Liu 105698eafce5SGeorge Liu std::optional<std::string> appliedConfigUri; 105798eafce5SGeorge Liu std::optional<bool> locationIndicatorActive; 105898eafce5SGeorge Liu if (!json_util::readJsonPatch( 105998eafce5SGeorge Liu req, asyncResp->res, // 106098eafce5SGeorge Liu "AppliedOperatingConfig/@odata.id", appliedConfigUri, // 106198eafce5SGeorge Liu "LocationIndicatorActive", locationIndicatorActive // 106298eafce5SGeorge Liu )) 106398eafce5SGeorge Liu { 106498eafce5SGeorge Liu return; 106598eafce5SGeorge Liu } 106698eafce5SGeorge Liu 106798eafce5SGeorge Liu // Check for 404 and find matching D-Bus object, then run 106898eafce5SGeorge Liu // property patch handlers if that all succeeds. 106998eafce5SGeorge Liu getProcessorObject( 107098eafce5SGeorge Liu asyncResp, processorId, 107198eafce5SGeorge Liu std::bind_front(doPatchProcessor, asyncResp, processorId, 107298eafce5SGeorge Liu appliedConfigUri, locationIndicatorActive)); 107398eafce5SGeorge Liu } 107498eafce5SGeorge Liu 1075*3b37e835SChristopher Meis inline void handleProcessorCollectionGet( 1076*3b37e835SChristopher Meis App& app, const crow::Request& req, 107745ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1078*3b37e835SChristopher Meis const std::string& systemName) 107945ca1b86SEd Tanous { 10803ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 108145ca1b86SEd Tanous { 108245ca1b86SEd Tanous return; 108345ca1b86SEd Tanous } 108425b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 10857f3e84a1SEd Tanous { 10867f3e84a1SEd Tanous // Option currently returns no systems. TBD 10877f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 10887f3e84a1SEd Tanous systemName); 10897f3e84a1SEd Tanous return; 10907f3e84a1SEd Tanous } 10917f3e84a1SEd Tanous 1092253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 109322d268cbSEd Tanous { 109422d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 109522d268cbSEd Tanous systemName); 109622d268cbSEd Tanous return; 109722d268cbSEd Tanous } 109822d268cbSEd Tanous 109971a24ca4SNikhil Namjoshi asyncResp->res.addHeader( 110071a24ca4SNikhil Namjoshi boost::beast::http::field::link, 110171a24ca4SNikhil Namjoshi "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby"); 110271a24ca4SNikhil Namjoshi 11038d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 1104ac6a4445SGunnar Mills "#ProcessorCollection.ProcessorCollection"; 11058d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Processor Collection"; 1106ac6a4445SGunnar Mills 1107*3b37e835SChristopher Meis asyncResp->res.jsonValue["@odata.id"] = std::format( 1108*3b37e835SChristopher Meis "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME); 1109ac6a4445SGunnar Mills 111005030b8eSGunnar Mills collection_util::getCollectionMembers( 1111ae9031f0SWilly Tu asyncResp, 1112253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/Processors", 1113253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME), 111436b5f1edSLakshmi Yadlapati processorInterfaces, "/xyz/openbmc_project/inventory"); 1115ac6a4445SGunnar Mills } 1116ac6a4445SGunnar Mills 11177e860f15SJohn Edward Broadbent inline void requestRoutesProcessor(App& app) 11187e860f15SJohn Edward Broadbent { 1119ac6a4445SGunnar Mills /** 1120ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 1121ac6a4445SGunnar Mills */ 1122*3b37e835SChristopher Meis BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/") 1123*3b37e835SChristopher Meis .privileges(redfish::privileges::headProcessorCollection) 1124*3b37e835SChristopher Meis .methods(boost::beast::http::verb::head)( 1125*3b37e835SChristopher Meis std::bind_front(handleProcessorCollectionHead, std::ref(app))); 1126*3b37e835SChristopher Meis 1127*3b37e835SChristopher Meis BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/") 1128*3b37e835SChristopher Meis .privileges(redfish::privileges::getProcessorCollection) 1129*3b37e835SChristopher Meis .methods(boost::beast::http::verb::get)( 1130*3b37e835SChristopher Meis std::bind_front(handleProcessorCollectionGet, std::ref(app))); 11317e860f15SJohn Edward Broadbent 113222d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/") 113371a24ca4SNikhil Namjoshi .privileges(redfish::privileges::headProcessor) 113471a24ca4SNikhil Namjoshi .methods(boost::beast::http::verb::head)( 113571a24ca4SNikhil Namjoshi std::bind_front(handleProcessorHead, std::ref(app))); 113671a24ca4SNikhil Namjoshi 113771a24ca4SNikhil Namjoshi BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/") 1138ed398213SEd Tanous .privileges(redfish::privileges::getProcessor) 113998eafce5SGeorge Liu .methods(boost::beast::http::verb::get)( 114098eafce5SGeorge Liu std::bind_front(handleProcessorGet, std::ref(app))); 11413cde86f1SJonathan Doman 114222d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/") 1143ed398213SEd Tanous .privileges(redfish::privileges::patchProcessor) 11447e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 114598eafce5SGeorge Liu std::bind_front(handleProcessorPatch, std::ref(app))); 11463cde86f1SJonathan Doman } 1147ac6a4445SGunnar Mills 1148ac6a4445SGunnar Mills } // namespace redfish 1149