summaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
authorcyang29 <cheng.c.yang@intel.com>2018-10-17 17:38:41 +0300
committercyang29 <cheng.c.yang@intel.com>2018-10-17 17:38:41 +0300
commitaeb90faa6c3e0cdfea9a1b3605f60673fcdff960 (patch)
tree35f4b20ea2c1ea46bed89859dfb5bbad65d5f5c0 /services
parent5503c09b879b4baf5cd94c70dbf0856766bade20 (diff)
downloadprovingground-aeb90faa6c3e0cdfea9a1b3605f60673fcdff960.tar.xz
Add CPU dbus service for MDR V2
Add all CPU information in smbios table and provide dbus interface for redfish to get CPU information. Change-Id: I86e3e4b8022e1b211e7a946bb896314b710a0df2 Signed-off-by: cyang29 <cheng.c.yang@intel.com>
Diffstat (limited to 'services')
-rw-r--r--services/smbios-mdrv2/CMakeLists.txt2
-rw-r--r--services/smbios-mdrv2/include/cpu.hpp173
-rw-r--r--services/smbios-mdrv2/include/mdrv2.hpp6
-rw-r--r--services/smbios-mdrv2/include/smbios-mdrv2.hpp110
-rw-r--r--services/smbios-mdrv2/src/cpu.cpp207
-rw-r--r--services/smbios-mdrv2/src/mdrv2.cpp55
6 files changed, 552 insertions, 1 deletions
diff --git a/services/smbios-mdrv2/CMakeLists.txt b/services/smbios-mdrv2/CMakeLists.txt
index 8cdf8a9..b707347 100644
--- a/services/smbios-mdrv2/CMakeLists.txt
+++ b/services/smbios-mdrv2/CMakeLists.txt
@@ -31,7 +31,7 @@ pkg_check_modules (DBUSINTERFACE phosphor-dbus-interfaces REQUIRED)
include_directories (${DBUSINTERFACE_INCLUDE_DIRS})
link_directories (${DBUSINTERFACE_LIBRARY_DIRS})
-set (SRC_FILES src/mdrv2.cpp src/smbios-mdrv2-main.cpp)
+set (SRC_FILES src/mdrv2.cpp src/smbios-mdrv2-main.cpp src/cpu.cpp)
include_directories (${CMAKE_CURRENT_BINARY_DIR})
diff --git a/services/smbios-mdrv2/include/cpu.hpp b/services/smbios-mdrv2/include/cpu.hpp
new file mode 100644
index 0000000..3b12c41
--- /dev/null
+++ b/services/smbios-mdrv2/include/cpu.hpp
@@ -0,0 +1,173 @@
+/*
+// 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 "smbios-mdrv2.hpp"
+
+#include <xyz/openbmc_project/Inventory/Item/Cpu/server.hpp>
+
+namespace phosphor
+{
+
+namespace smbios
+{
+
+// Definition follow smbios spec DSP0134 3.0.0
+static const std::map<uint8_t, std::string> processorTypeTable = {
+ {0x1, "Other"}, {0x2, "Unknown"}, {0x3, "Central Processor"},
+ {0x4, "Math Processor"}, {0x5, "DSP Processor"}, {0x6, "Video Processor"},
+};
+
+// Definition follow smbios spec DSP0134 3.0.0
+static const std::map<uint8_t, std::string> familyTable = {
+ {0x1, "Other"},
+ {0x2, "Unknown"},
+ {0x10, "Pentium II Xeon processor"},
+ {0xa1, "Quad-Core Intel Xeon processor 3200 Series"},
+ {0xa2, "Dual-Core Intel Xeon processor 3000 Series"},
+ {0xa3, "Quad-Core Intel Xeon processor 5300 Series"},
+ {0xa4, "Dual-Core Intel Xeon processor 5100 Series"},
+ {0xa5, "Dual-Core Intel Xeon processor 5000 Series"},
+ {0xa6, "Dual-Core Intel Xeon processor LV"},
+ {0xa7, "Dual-Core Intel Xeon processor ULV"},
+ {0xa8, "Dual-Core Intel Xeon processor 7100 Series"},
+ {0xa9, "Quad-Core Intel Xeon processor 5400 Series"},
+ {0xaa, "Quad-Core Intel Xeon processor"},
+ {0xab, "Dual-Core Intel Xeon processor 5200 Series"},
+ {0xac, "Dual-Core Intel Xeon processor 7200 Series"},
+ {0xad, "Quad-Core Intel Xeon processor 7300 Series"},
+ {0xae, "Quad-Core Intel Xeon processor 7400 Series"},
+ {0xaf, "Multi-Core Intel Xeon processor 7400 Series"},
+ {0xb0, "Pentium III Xeon processor"},
+ {0xb3, "Intel Xeon processor"},
+ {0xb5, "Intel Xeon processor MP"},
+ {0xd6, "Multi-Core Intel Xeon processor"},
+ {0xd7, "Dual-Core Intel Xeon processor 3xxx Series"},
+ {0xd8, "Quad-Core Intel Xeon processor 3xxx Series"},
+ {0xd9, "VIA Nano Processor Family"},
+ {0xda, "Dual-Core Intel Xeon processor 5xxx Series"},
+ {0xdb, "Quad-Core Intel Xeon processor 5xxx Series"},
+ {0xdd, "Dual-Core Intel Xeon processor 7xxx Series"},
+ {0xde, "Quad-Core Intel Xeon processor 7xxx Series"},
+ {0xdf, "Multi-Core Intel Xeon processor 7xxx Series"},
+ {0xe0, "Multi-Core Intel Xeon processor 3400 Series"}
+
+};
+
+// Definition follow smbios spec DSP0134 3.0.0
+static const std::string characteristicsTable[16]{"Reserved",
+ "Unknown",
+ "64-bit Capable",
+ "Multi-Core",
+ "Hardware Thread",
+ "Execute Protection",
+ "Enhanced Virtualization",
+ "Power/Performance Control",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved"};
+
+class Cpu : sdbusplus::server::object::object<
+ sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu>
+{
+ public:
+ Cpu() = delete;
+ Cpu(const Cpu &) = delete;
+ Cpu &operator=(const Cpu &) = delete;
+ Cpu(Cpu &&) = delete;
+ Cpu &operator=(Cpu &&) = delete;
+ ~Cpu() = default;
+
+ Cpu(sdbusplus::bus::bus &bus, const std::string &objPath,
+ const uint8_t &cpuId, uint8_t *smbiosTableStorage) :
+ sdbusplus::server::object::object<
+ sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu>(
+ bus, objPath.c_str()),
+ cpuNum(cpuId), storage(smbiosTableStorage)
+ {
+ processorInfoUpdate();
+ }
+
+ void processorInfoUpdate(void);
+
+ std::string processorSocket(std::string value) override;
+ std::string processorType(std::string value) override;
+ std::string processorFamily(std::string value) override;
+ std::string processorManufacturer(std::string value) override;
+ uint32_t processorId(uint32_t value) override;
+ std::string processorVersion(std::string value) override;
+ uint16_t processorMaxSpeed(uint16_t value) override;
+ std::string processorCharacteristics(std::string value) override;
+ uint16_t processorCoreCount(uint16_t value) override;
+ uint16_t processorThreadCount(uint16_t value) override;
+
+ private:
+ uint8_t cpuNum;
+
+ uint8_t *storage;
+
+ struct ProcessorInfo
+ {
+ uint8_t type;
+ uint8_t length;
+ uint16_t handle;
+ uint8_t socketDesignation;
+ uint8_t processorType;
+ uint8_t family;
+ uint8_t manufacturer;
+ uint64_t id;
+ uint8_t version;
+ uint8_t voltage;
+ uint16_t exClock;
+ uint16_t maxSpeed;
+ uint16_t currSpeed;
+ uint8_t status;
+ uint8_t upgrade;
+ uint16_t l1Handle;
+ uint16_t l2Handle;
+ uint16_t l3Handle;
+ uint8_t serialNum;
+ uint8_t assetTag;
+ uint8_t partNum;
+ uint8_t coreCount;
+ uint8_t coreEnable;
+ uint8_t threadCount;
+ uint16_t characteristics;
+ uint16_t family2;
+ uint16_t coreCount2;
+ uint16_t coreEnable2;
+ uint16_t threadCount2;
+ } __attribute__((packed));
+
+ void cpuSocket(const uint8_t positionNum, const uint8_t structLen,
+ uint8_t *dataIn);
+ void cpuType(const uint8_t value);
+ void cpuFamily(const uint8_t value);
+ void cpuManufacturer(const uint8_t positionNum, const uint8_t structLen,
+ uint8_t *dataIn);
+ void cpuVersion(const uint8_t positionNum, const uint8_t structLen,
+ uint8_t *dataIn);
+ void cpuCharacteristics(const uint16_t value);
+};
+
+} // namespace smbios
+
+} // namespace phosphor
diff --git a/services/smbios-mdrv2/include/mdrv2.hpp b/services/smbios-mdrv2/include/mdrv2.hpp
index 3a4bb23..dbb4b10 100644
--- a/services/smbios-mdrv2/include/mdrv2.hpp
+++ b/services/smbios-mdrv2/include/mdrv2.hpp
@@ -15,6 +15,7 @@
*/
#pragma once
+#include "cpu.hpp"
#include "smbios-mdrv2.hpp"
#include <sys/stat.h>
@@ -33,6 +34,7 @@ namespace smbios
{
static constexpr const char *mdrV2Path = "/xyz/openbmc_project/Smbios/MDR_V2";
+constexpr const int limitEntryLen = 0xff;
class MDR_V2 : sdbusplus::xyz::openbmc_project::Smbios::server::MDR_V2
{
@@ -103,6 +105,10 @@ class MDR_V2 : sdbusplus::xyz::openbmc_project::Smbios::server::MDR_V2
bool smbiosIsUpdating(uint8_t index);
bool smbiosIsAvailForUpdate(uint8_t index);
inline uint8_t smbiosValidFlag(uint8_t index);
+ void systemInfoUpdate(void);
+
+ int getTotalCpuSlot(void);
+ std::vector<std::unique_ptr<Cpu>> cpus;
};
} // namespace smbios
diff --git a/services/smbios-mdrv2/include/smbios-mdrv2.hpp b/services/smbios-mdrv2/include/smbios-mdrv2.hpp
index 9591e78..b468ece 100644
--- a/services/smbios-mdrv2/include/smbios-mdrv2.hpp
+++ b/services/smbios-mdrv2/include/smbios-mdrv2.hpp
@@ -116,3 +116,113 @@ struct MDRSMBIOSHeader
uint32_t timestamp;
uint32_t dataSize;
} __attribute__((packed));
+
+static constexpr const char *cpuPath =
+ "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu";
+
+typedef enum
+{
+ biosType = 0,
+ systemType = 1,
+ baseboardType = 2,
+ chassisType = 3,
+ processorsType = 4,
+ memoryControllerType = 5,
+ memoryModuleInformationType = 6,
+ cacheType = 7,
+ portConnectorType = 8,
+ systemSlots = 9,
+ onBoardDevicesType = 10,
+ oemStringsType = 11,
+ systemCconfigurationOptionsType = 12,
+ biosLanguageType = 13,
+ groupAssociatonsType = 14,
+ systemEventLogType = 15,
+ physicalMemoryArrayType = 16,
+ memoryDeviceType = 17,
+} SmbiosType;
+
+static constexpr uint8_t separateLen = 2;
+
+static inline uint8_t *smbiosNextPtr(uint8_t *smbiosDataIn)
+{
+ if (smbiosDataIn == nullptr)
+ {
+ return nullptr;
+ }
+ uint8_t *smbiosData = smbiosDataIn + *(smbiosDataIn + 1);
+ int len = 0;
+ while ((*smbiosData | *(smbiosData + 1)) != 0)
+ {
+ smbiosData++;
+ len++;
+ if (len >= mdrSMBIOSSize) // To avoid endless loop
+ {
+ return nullptr;
+ }
+ }
+ return smbiosData + separateLen;
+}
+
+// When first time run getSMBIOSTypePtr, need to send the RegionS[].regionData
+// to smbiosDataIn
+static inline uint8_t *getSMBIOSTypePtr(uint8_t *smbiosDataIn, uint8_t typeId)
+{
+ if (smbiosDataIn == nullptr)
+ {
+ return nullptr;
+ }
+ char *smbiosData = reinterpret_cast<char *>(smbiosDataIn);
+ while ((*smbiosData != '\0') || (*(smbiosData + 1) != '\0'))
+ {
+ if (*smbiosData != typeId)
+ {
+ uint32_t len = *(smbiosData + 1);
+ smbiosData += len;
+ while ((*smbiosData != '\0') || (*(smbiosData + 1) != '\0'))
+ {
+ smbiosData++;
+ len++;
+ if (len >= mdrSMBIOSSize) // To avoid endless loop
+ {
+ return nullptr;
+ }
+ }
+ smbiosData += separateLen;
+ continue;
+ }
+ return reinterpret_cast<uint8_t *>(smbiosData);
+ }
+ return nullptr;
+}
+
+static inline std::string positionToString(uint8_t positionNum,
+ uint8_t structLen, uint8_t *dataIn)
+{
+ if (dataIn == nullptr)
+ {
+ return "";
+ }
+ uint16_t limit = mdrSMBIOSSize; // set a limit to avoid endless loop
+
+ char *target = reinterpret_cast<char *>(dataIn + structLen);
+ for (uint8_t index = 1; index < positionNum; index++)
+ {
+ for (; *target != '\0'; target++)
+ {
+ limit--;
+ if (limit < 1)
+ {
+ return "";
+ }
+ }
+ target++;
+ if (*target == '\0')
+ {
+ return ""; // 0x00 0x00 means end of the entry.
+ }
+ }
+
+ std::string result = target;
+ return result;
+}
diff --git a/services/smbios-mdrv2/src/cpu.cpp b/services/smbios-mdrv2/src/cpu.cpp
new file mode 100644
index 0000000..82f4bdc
--- /dev/null
+++ b/services/smbios-mdrv2/src/cpu.cpp
@@ -0,0 +1,207 @@
+/*
+// 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.
+*/
+
+#include "cpu.hpp"
+
+#include <map>
+
+namespace phosphor
+{
+namespace smbios
+{
+
+void Cpu::cpuSocket(const uint8_t positionNum, const uint8_t structLen,
+ uint8_t *dataIn)
+{
+ std::string result = positionToString(positionNum, structLen, dataIn);
+
+ processorSocket(result);
+}
+
+std::string Cpu::processorSocket(std::string value)
+{
+ return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
+ processorSocket(value);
+}
+
+void Cpu::cpuType(const uint8_t value)
+{
+ std::map<uint8_t, std::string>::const_iterator it =
+ processorTypeTable.find(value);
+ if (it == processorTypeTable.end())
+ {
+ processorType("Unknown Processor Type");
+ }
+ else
+ {
+ processorType(it->second);
+ }
+}
+
+std::string Cpu::processorType(std::string value)
+{
+ return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
+ processorType(value);
+}
+
+void Cpu::cpuFamily(const uint8_t value)
+{
+ std::map<uint8_t, std::string>::const_iterator it = familyTable.find(value);
+ if (it == familyTable.end())
+ {
+ processorFamily("Unknown Processor Family");
+ }
+ else
+ {
+ processorFamily(it->second);
+ }
+}
+
+std::string Cpu::processorFamily(std::string value)
+{
+ return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
+ processorFamily(value);
+}
+
+void Cpu::cpuManufacturer(const uint8_t positionNum, const uint8_t structLen,
+ uint8_t *dataIn)
+{
+ std::string result = positionToString(positionNum, structLen, dataIn);
+
+ processorManufacturer(result);
+}
+
+std::string Cpu::processorManufacturer(std::string value)
+{
+ return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
+ processorManufacturer(value);
+}
+
+uint32_t Cpu::processorId(uint32_t value)
+{
+ return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
+ processorId(value);
+}
+
+void Cpu::cpuVersion(const uint8_t positionNum, const uint8_t structLen,
+ uint8_t *dataIn)
+{
+ std::string result;
+
+ result = positionToString(positionNum, structLen, dataIn);
+
+ processorVersion(result);
+}
+
+std::string Cpu::processorVersion(std::string value)
+{
+ return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
+ processorVersion(value);
+}
+
+uint16_t Cpu::processorMaxSpeed(uint16_t value)
+{
+ return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
+ processorMaxSpeed(value);
+}
+
+void Cpu::cpuCharacteristics(uint16_t value)
+{
+ std::string result = "";
+ for (uint8_t index = 0; index < (8 * sizeof(value)); index++)
+ {
+ if (value & 0x01)
+ {
+ result += characteristicsTable[index];
+ }
+ value >>= 1;
+ }
+
+ processorCharacteristics(result);
+}
+
+std::string Cpu::processorCharacteristics(std::string value)
+{
+ return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
+ processorCharacteristics(value);
+}
+
+uint16_t Cpu::processorCoreCount(uint16_t value)
+{
+ return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
+ processorCoreCount(value);
+}
+
+uint16_t Cpu::processorThreadCount(uint16_t value)
+{
+ return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
+ processorThreadCount(value);
+}
+
+static constexpr uint8_t maxOldVersionCount = 0xff;
+void Cpu::processorInfoUpdate(void)
+{
+ uint8_t *dataIn = storage;
+
+ dataIn = getSMBIOSTypePtr(dataIn, processorsType);
+ for (uint8_t index = 0; index < cpuNum; index++)
+ {
+ dataIn = smbiosNextPtr(dataIn);
+ if (dataIn == nullptr)
+ {
+ return;
+ }
+ dataIn = getSMBIOSTypePtr(dataIn, processorsType);
+ if (dataIn == nullptr)
+ {
+ return;
+ }
+ }
+
+ auto cpuInfo = reinterpret_cast<struct ProcessorInfo *>(dataIn);
+
+ cpuSocket(cpuInfo->socketDesignation, cpuInfo->length,
+ dataIn); // offset 4h
+ cpuType(cpuInfo->processorType); // offset 5h
+ cpuFamily(cpuInfo->family); // offset 6h
+ cpuManufacturer(cpuInfo->manufacturer, cpuInfo->length,
+ dataIn); // offset 7h
+ processorId(cpuInfo->id); // offset 8h
+ cpuVersion(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h
+ processorMaxSpeed(cpuInfo->maxSpeed); // offset 14h
+ if (cpuInfo->coreCount < maxOldVersionCount) // offset 23h or 2Ah
+ {
+ processorCoreCount(cpuInfo->coreCount);
+ }
+ else
+ {
+ processorCoreCount(cpuInfo->coreCount2);
+ }
+
+ if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh)
+ {
+ processorThreadCount(cpuInfo->threadCount);
+ }
+ else
+ {
+ processorThreadCount(cpuInfo->threadCount2);
+ }
+
+ cpuCharacteristics(cpuInfo->characteristics); // offset 26h
+}
+
+} // namespace smbios
+} // namespace phosphor
diff --git a/services/smbios-mdrv2/src/mdrv2.cpp b/services/smbios-mdrv2/src/mdrv2.cpp
index 3b8858e..38e21e8 100644
--- a/services/smbios-mdrv2/src/mdrv2.cpp
+++ b/services/smbios-mdrv2/src/mdrv2.cpp
@@ -357,6 +357,60 @@ uint8_t MDR_V2::directoryEntries(uint8_t value)
directoryEntries(value);
}
+void MDR_V2::systemInfoUpdate()
+{
+ cpus.clear();
+
+ int num = getTotalCpuSlot();
+ if (num == -1)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "get cpu total slot failed");
+ return;
+ }
+
+ for (int index = 0; index < num; index++)
+ {
+ std::string path = cpuPath + std::to_string(index);
+ cpus.emplace_back(std::make_unique<phosphor::smbios::Cpu>(
+ bus, path, index, smbiosDir.dir[smbiosDirIndex].dataStorage));
+ }
+}
+
+int MDR_V2::getTotalCpuSlot()
+{
+ uint8_t *dataIn = smbiosDir.dir[smbiosDirIndex].dataStorage;
+ int num = 0;
+
+ if (dataIn == nullptr)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "get cpu total slot failed - no storage data");
+ return -1;
+ }
+
+ while (1)
+ {
+ dataIn = getSMBIOSTypePtr(dataIn, processorsType);
+ if (dataIn == nullptr)
+ {
+ break;
+ }
+ num++;
+ dataIn = smbiosNextPtr(dataIn);
+ if (dataIn == nullptr)
+ {
+ break;
+ }
+ if (num >= limitEntryLen)
+ {
+ break;
+ }
+ }
+
+ return num;
+}
+
bool MDR_V2::agentSynchronizeData()
{
struct MDRSMBIOSHeader mdr2SMBIOS;
@@ -370,6 +424,7 @@ bool MDR_V2::agentSynchronizeData()
}
else
{
+ systemInfoUpdate();
smbiosDir.dir[smbiosDirIndex].common.dataVersion = mdr2SMBIOS.dirVer;
smbiosDir.dir[smbiosDirIndex].common.timestamp = mdr2SMBIOS.timestamp;
smbiosDir.dir[smbiosDirIndex].common.size = mdr2SMBIOS.dataSize;