update cpu information to cpu interface
update cpu summary and cpu information to
cpu interface.
https://github.com/openbmc/phosphor-dbus-interfaces/commit/259f49e0c40b287d9ea79f77db1654da47161340
Tested:
1. Verified redfish validator passed
*** /redfish/v1/Systems/system/Processors/cpu0
INFO - Type (#Processor.v1_9_0.Processor), GET SUCCESS (time: 1.091324)
INFO - PASS
INFO -
*** /redfish/v1/Systems/system/Processors/cpu1
INFO - Type (#Processor.v1_9_0.Processor), GET SUCCESS (time: 0.993352)
INFO - PASS
INFO -
2. Get cpu details from Redfish
GET: https://<BMC-IP>/redfish/v1/Systems/system/Processors/cpu0
Response:
{
"@odata.id": "/redfish/v1/Systems/system/Processors/cpu0",
"@odata.type": "#Processor.v1_7_0.Processor",
"Id": "cpu0",
"InstructionSet": "x86-64",
"Manufacturer": "Intel(R) Corporation",
"MaxSpeedMHz": 4000,
"Model": "QUZS",
"Name": "Processor",
"ProcessorArchitecture": "x86",
"ProcessorId": {
"EffectiveFamily": "Intel Xeon processor",
"IdentificationRegisters": "13829424153406867109"
},
"ProcessorType": "CPU",
"SerialNumber": "6122cca2e8a2d5c",
"Socket": "CPU0",
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Enabled"
},
"TotalCores": 32,
"TotalThreads": 64,
"Type": "Central Processor",
"Version": "Genuine Intel(R) CPU $0000%@"
}
GET: https://<BMC-IP>/redfish/v1/Systems/system/Processors/cpu1
{
"@odata.id": "/redfish/v1/Systems/system/Processors/cpu1",
"@odata.type": "#Processor.v1_9_0.Processor",
"Id": "cpu1",
"Manufacturer": "CPU1",
"Name": "Processor",
"ProcessorType": "CPU",
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Absent"
},
"Version": "CPU1"
}
Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
Change-Id: I06424c9adb1922ae70e0936c7cb33efcf522c100
diff --git a/redfish-core/lib/cpudimm.hpp b/redfish-core/lib/cpudimm.hpp
index 4f387fc..9b9d9cb 100644
--- a/redfish-core/lib/cpudimm.hpp
+++ b/redfish-core/lib/cpudimm.hpp
@@ -75,13 +75,18 @@
{
BMCWEB_LOG_DEBUG << "Get CPU resources by interface.";
- const bool* present = nullptr;
- const bool* functional = nullptr;
+ // 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 == "ProcessorCoreCount")
+ if (property.first == "CoreCount")
{
const uint16_t* coresCount =
std::get_if<uint16_t>(&property.second);
@@ -95,85 +100,58 @@
{
// Slot is not populated, set status end return
aResp->res.jsonValue["Status"]["State"] = "Absent";
- aResp->res.jsonValue["Status"]["Health"] = "OK";
// HTTP Code will be set up automatically, just return
return;
}
-
+ else
+ {
+ aResp->res.jsonValue["Status"]["State"] = "Enabled";
+ present = true;
+ }
aResp->res.jsonValue["TotalCores"] = *coresCount;
}
- else if (property.first == "ProcessorType")
- {
- aResp->res.jsonValue["Name"] = property.second;
- }
- else if (property.first == "Manufacturer")
- {
- const std::string* value =
- std::get_if<std::string>(&property.second);
- if (value != nullptr)
- {
- aResp->res.jsonValue["Manufacturer"] = property.second;
- // Otherwise would be unexpected.
- if (value->find("Intel") != std::string::npos)
- {
- aResp->res.jsonValue["ProcessorArchitecture"] = "x86";
- aResp->res.jsonValue["InstructionSet"] = "x86-64";
- }
- else if (value->find("IBM") != std::string::npos)
- {
- aResp->res.jsonValue["ProcessorArchitecture"] = "Power";
- aResp->res.jsonValue["InstructionSet"] = "PowerISA";
- }
- }
- }
- else if (property.first == "ProcessorMaxSpeed")
+ else if (property.first == "MaxSpeedInMhz")
{
aResp->res.jsonValue["MaxSpeedMHz"] = property.second;
}
- else if (property.first == "ProcessorThreadCount")
- {
- aResp->res.jsonValue["TotalThreads"] = property.second;
- }
- else if (property.first == "Model")
+ else if (property.first == "Socket")
{
const std::string* value =
std::get_if<std::string>(&property.second);
if (value != nullptr)
{
- aResp->res.jsonValue["Model"] = *value;
+ aResp->res.jsonValue["Socket"] = *value;
}
}
- else if (property.first == "PartNumber")
+ else if (property.first == "ThreadCount")
{
- aResp->res.jsonValue["PartNumber"] = property.second;
+ aResp->res.jsonValue["TotalThreads"] = property.second;
}
- else if (property.first == "SerialNumber")
+ else if (property.first == "Family")
{
- aResp->res.jsonValue["SerialNumber"] = property.second;
+ const std::string* value =
+ std::get_if<std::string>(&property.second);
+ if (value != nullptr)
+ {
+ aResp->res.jsonValue["ProcessorId"]["EffectiveFamily"] =
+ *value;
+ }
}
- else if (property.first == "Version")
+ else if (property.first == "Id")
{
- aResp->res.jsonValue["Version"] = property.second;
- }
- else if (property.first == "Present")
- {
- present = std::get_if<bool>(&property.second);
- }
- else if (property.first == "Functional")
- {
- functional = std::get_if<bool>(&property.second);
+ 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 == nullptr) || (functional == nullptr))
- {
- // Important property not in desired type
- messages::internalError(aResp->res);
- return;
- }
-
- if (*present == false)
+ if (present == false)
{
aResp->res.jsonValue["Status"]["State"] = "Absent";
aResp->res.jsonValue["Status"]["Health"] = "OK";
@@ -181,7 +159,7 @@
else
{
aResp->res.jsonValue["Status"]["State"] = "Enabled";
- if (*functional == true)
+ if (functional)
{
aResp->res.jsonValue["Status"]["Health"] = "OK";
}
@@ -215,6 +193,7 @@
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)
@@ -240,6 +219,7 @@
{
if (*present == true)
{
+ slotPresent = true;
totalCores++;
}
}
@@ -252,13 +232,16 @@
// 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 (totalCores == 0)
+ if (slotPresent)
{
- // Slot is not populated, set status end return
- aResp->res.jsonValue["Status"]["State"] = "Absent";
- aResp->res.jsonValue["Status"]["Health"] = "OK";
+ 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;
}
- aResp->res.jsonValue["TotalCores"] = totalCores;
return;
},
service, "/xyz/openbmc_project/inventory",
@@ -289,7 +272,7 @@
{
const std::string* sn =
std::get_if<std::string>(&property.second);
- if (sn != nullptr)
+ if (sn != nullptr && !sn->empty())
{
aResp->res.jsonValue["SerialNumber"] = *sn;
}
@@ -298,17 +281,77 @@
{
const std::string* model =
std::get_if<std::string>(&property.second);
- if (model != nullptr)
+ 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,
@@ -332,6 +375,7 @@
aResp->res.jsonValue["Name"] = "Processor";
const bool* accPresent = nullptr;
const bool* accFunctional = nullptr;
+ std::string state = "";
for (const auto& property : properties)
{
@@ -345,24 +389,28 @@
}
}
- if ((accPresent != nullptr) && (*accPresent == false))
+ if (!accPresent || !accFunctional)
{
- aResp->res.jsonValue["Status"]["State"] = "Absent";
- aResp->res.jsonValue["Status"]["Health"] = "OK";
+ BMCWEB_LOG_DEBUG << "Required properties missing in DBUS "
+ "response";
+ messages::internalError(aResp->res);
+ return;
+ }
+
+ if (*accPresent && *accFunctional)
+ {
+ state = "Enabled";
+ }
+ else if (*accPresent)
+ {
+ state = "UnavailableOffline";
}
else
{
- aResp->res.jsonValue["Status"]["State"] = "Enabled";
-
- if ((accFunctional != nullptr) && (*accFunctional == false))
- {
- aResp->res.jsonValue["Status"]["Health"] = "Critical";
- }
- else
- {
- aResp->res.jsonValue["Status"]["Health"] = "OK";
- }
+ state = "Absent";
}
+ aResp->res.jsonValue["Status"]["State"] = state;
+ aResp->res.jsonValue["Status"]["Health"] = "OK";
aResp->res.jsonValue["ProcessorType"] = "Accelerator";
},
service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
@@ -402,7 +450,14 @@
object.first);
}
else if (inventory ==
- "xyz.openbmc_project.Inventory.Item.Cpu")
+ "xyz.openbmc_project."
+ "Inventory.Decorator.Revision")
+ {
+ getCpuRevisionData(aResp, service.first,
+ object.first);
+ }
+ else if (inventory == "xyz.openbmc_project."
+ "Inventory.Item.Cpu")
{
getCpuDataByService(aResp, cpuId, service.first,
object.first);
@@ -1102,7 +1157,7 @@
return;
}
const std::string& processorId = params[0];
- res.jsonValue["@odata.type"] = "#Processor.v1_7_0.Processor";
+ res.jsonValue["@odata.type"] = "#Processor.v1_9_0.Processor";
res.jsonValue["@odata.id"] =
"/redfish/v1/Systems/system/Processors/" + processorId;
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 5d96649..da92be3 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -326,40 +326,59 @@
if (properties.size() > 0)
{
+ const uint32_t* processorId = nullptr;
+ const std::string* procFamily = nullptr;
+ nlohmann::json& procSummary =
+ aResp->res.jsonValue["ProcessorSumm"
+ "ary"];
+ nlohmann::json& procCount =
+ procSummary["Count"];
+
+ auto procCountPtr = procCount.get_ptr<
+ nlohmann::json::
+ number_integer_t*>();
+ if (procCountPtr == nullptr)
+ {
+ messages::internalError(aResp->res);
+ return;
+ }
for (const auto& property : properties)
{
+
+ if (property.first == "ProcessorId")
+ {
+ processorId =
+ std::get_if<uint32_t>(
+ &property.second);
+ if (nullptr != procFamily)
+ break;
+ continue;
+ }
+
if (property.first ==
"ProcessorFamily")
{
- const std::string* value =
+ procFamily =
std::get_if<std::string>(
&property.second);
- if (value != nullptr)
- {
- nlohmann::json&
- procSummary =
- aResp->res.jsonValue
- ["ProcessorSumm"
- "ary"];
- nlohmann::json& procCount =
- procSummary["Count"];
+ if (nullptr != processorId)
+ break;
+ continue;
+ }
+ }
- auto procCountPtr =
- procCount.get_ptr<
- nlohmann::json::
- number_integer_t*>();
- if (procCountPtr != nullptr)
- {
- // shouldn't be possible
- // to be nullptr
- *procCountPtr += 1;
- }
- procSummary["Status"]
- ["State"] =
- "Enabled";
- procSummary["Model"] =
- *value;
- }
+ if (procFamily != nullptr &&
+ processorId != nullptr)
+ {
+ if (procCountPtr != nullptr &&
+ *processorId != 0)
+ {
+ *procCountPtr += 1;
+ procSummary["Status"]["State"] =
+ "Enabled";
+
+ procSummary["Model"] =
+ *procFamily;
}
}
}