Adding ISDIMM support
Added ISDIMM support for Bonnell machine
Change-Id: Ifdb2fc9e2d38267c8eb6cd5848d30102ab48efd1
Signed-off-by: jinuthomas <jinu.joy.thomas@in.ibm.com>
diff --git a/const.hpp b/const.hpp
index 4bbee6c..5afa3fd 100644
--- a/const.hpp
+++ b/const.hpp
@@ -72,6 +72,19 @@
static constexpr auto CCIN_LEN = 4;
static constexpr auto CONVERT_MB_TO_KB = 1024;
+static constexpr auto SPD_BYTE_2 = 2;
+static constexpr auto SPD_BYTE_3 = 3;
+static constexpr auto SPD_BYTE_4 = 4;
+static constexpr auto SPD_BYTE_6 = 6;
+static constexpr auto SPD_BYTE_12 = 12;
+static constexpr auto SPD_BYTE_13 = 13;
+static constexpr auto SPD_BYTE_BIT_0_3_MASK = 0x0F;
+static constexpr auto SPD_BYTE_MASK = 0xFF;
+
+static constexpr auto SPD_MODULE_TYPE_DDIMM = 0x0A;
+static constexpr auto SPD_DRAM_TYPE_DDR5 = 0x12;
+static constexpr auto SPD_DRAM_TYPE_DDR4 = 0x0C;
+
constexpr auto pimPath = "/xyz/openbmc_project/inventory";
constexpr auto pimIntf = "xyz.openbmc_project.Inventory.Manager";
constexpr auto kwdVpdInf = "com.ibm.ipzvpd.VINI";
@@ -149,10 +162,13 @@
*/
enum vpdType
{
- IPZ_VPD, /**< IPZ VPD type */
- KEYWORD_VPD, /**< Keyword VPD type */
- MEMORY_VPD, /**< Memory VPD type */
- INVALID_VPD_FORMAT /**< Invalid VPD type */
+ IPZ_VPD, /**< IPZ VPD type */
+ KEYWORD_VPD, /**< Keyword VPD type */
+ DDR4_DDIMM_MEMORY_VPD, /**< DDR4 DDIMM Memory VPD type */
+ DDR5_DDIMM_MEMORY_VPD, /**< DDR5 DDIMM Memory VPD type */
+ DDR4_ISDIMM_MEMORY_VPD, /**< DDR4 ISDIMM Memory VPD type */
+ DDR5_ISDIMM_MEMORY_VPD, /**< DDR5 ISDIMM Memory VPD type */
+ INVALID_VPD_FORMAT /**< Invalid VPD type */
};
enum PelSeverity
diff --git a/ibm_vpd_utils.cpp b/ibm_vpd_utils.cpp
index ef9f058..388d869 100644
--- a/ibm_vpd_utils.cpp
+++ b/ibm_vpd_utils.cpp
@@ -371,10 +371,29 @@
// KEYWORD VPD FORMAT
return vpdType::KEYWORD_VPD;
}
- else if (is11SFormat.compare(MEMORY_VPD_START_TAG) == 0)
+ else if (((vpdVector[SPD_BYTE_3] & SPD_BYTE_BIT_0_3_MASK) ==
+ SPD_MODULE_TYPE_DDIMM) &&
+ (is11SFormat.compare(MEMORY_VPD_START_TAG)))
{
- // Memory VPD format
- return vpdType::MEMORY_VPD;
+ // DDIMM Memory VPD format
+ if ((vpdVector[SPD_BYTE_2] & SPD_BYTE_MASK) == SPD_DRAM_TYPE_DDR5)
+ {
+ return vpdType::DDR5_DDIMM_MEMORY_VPD;
+ }
+ else if ((vpdVector[SPD_BYTE_2] & SPD_BYTE_MASK) == SPD_DRAM_TYPE_DDR4)
+ {
+ return vpdType::DDR4_DDIMM_MEMORY_VPD;
+ }
+ }
+ else if ((vpdVector[SPD_BYTE_2] & SPD_BYTE_MASK) == SPD_DRAM_TYPE_DDR5)
+ {
+ // ISDIMM Memory VPD format
+ return vpdType::DDR5_ISDIMM_MEMORY_VPD;
+ }
+ else if ((vpdVector[SPD_BYTE_2] & SPD_BYTE_MASK) == SPD_DRAM_TYPE_DDR4)
+ {
+ // ISDIMM Memory VPD format
+ return vpdType::DDR4_ISDIMM_MEMORY_VPD;
}
// INVALID VPD FORMAT
diff --git a/meson.build b/meson.build
index e809776..9dd5fea 100644
--- a/meson.build
+++ b/meson.build
@@ -110,6 +110,7 @@
common_SOURCES =['common_utility.cpp',
'vpd-parser/parser_factory.cpp',
'vpd-parser/memory_vpd_parser.cpp',
+ 'vpd-parser/isdimm_vpd_parser.cpp',
'vpd-parser/keyword_vpd_parser.cpp',
'vpd-parser/ipz_parser.cpp', 'impl.cpp', 'ibm_vpd_utils.cpp',
]
diff --git a/test/meson.build b/test/meson.build
index 0e1121f..805a653 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -33,7 +33,8 @@
'../vpd-parser/keyword_vpd_parser.cpp',
'../vpd-manager/editor_impl.cpp',
'../vpd-parser/parser_factory.cpp',
- '../vpd-parser/memory_vpd_parser.cpp'
+ '../vpd-parser/memory_vpd_parser.cpp',
+ '../vpd-parser/isdimm_vpd_parser.cpp'
]
foreach t : vpd_test
diff --git a/types.hpp b/types.hpp
index 7619aef..a98a4f3 100644
--- a/types.hpp
+++ b/types.hpp
@@ -29,7 +29,7 @@
using Property = std::string;
using Value = std::variant<bool, size_t, int64_t, std::string, Binary>;
using PropertyMap = std::map<Property, Value>;
-using kwdVpdValueTypes = std::variant<size_t, Binary>;
+using kwdVpdValueTypes = std::variant<size_t, Binary, std::string>;
using Interface = std::string;
using InterfaceMap = std::map<Interface, PropertyMap>;
diff --git a/vpd-parser/isdimm_vpd_parser.cpp b/vpd-parser/isdimm_vpd_parser.cpp
new file mode 100644
index 0000000..253203b
--- /dev/null
+++ b/vpd-parser/isdimm_vpd_parser.cpp
@@ -0,0 +1,339 @@
+#include "isdimm_vpd_parser.hpp"
+
+#include <iostream>
+#include <numeric>
+#include <string>
+
+namespace openpower
+{
+namespace vpd
+{
+namespace memory
+{
+namespace parser
+{
+static constexpr auto SPD_JEDEC_DDR4_SDRAM_CAP_MASK = 0x0F;
+static constexpr auto SPD_JEDEC_DDR4_PRI_BUS_WIDTH_MASK = 0x07;
+static constexpr auto SPD_JEDEC_DDR4_SDRAM_WIDTH_MASK = 0x07;
+static constexpr auto SPD_JEDEC_DDR4_NUM_RANKS_MASK = 0x38;
+static constexpr auto SPD_JEDEC_DDR4_DIE_COUNT_MASK = 0x70;
+static constexpr auto SPD_JEDEC_DDR4_SINGLE_LOAD_STACK = 0x02;
+static constexpr auto SPD_JEDEC_DDR4_SIGNAL_LOADING_MASK = 0x03;
+
+static constexpr auto SPD_JEDEC_DDR4_SDRAMCAP_MULTIPLIER = 256;
+static constexpr auto SPD_JEDEC_DDR4_PRI_BUS_WIDTH_MULTIPLIER = 8;
+static constexpr auto SPD_JEDEC_DDR4_SDRAM_WIDTH_MULTIPLIER = 4;
+static constexpr auto SPD_JEDEC_DDR4_SDRAMCAP_RESERVED = 8;
+static constexpr auto SPD_JEDEC_DDR4_4_RESERVED_BITS = 4;
+static constexpr auto SPD_JEDEC_DDR4_3_RESERVED_BITS = 3;
+static constexpr auto SPD_JEDEC_DDR4_DIE_COUNT_RIGHT_SHIFT = 4;
+
+static constexpr auto SPD_JEDEC_DDR4_MFG_ID_MSB_OFFSET = 321;
+static constexpr auto SPD_JEDEC_DDR4_MFG_ID_LSB_OFFSET = 320;
+static constexpr auto SPD_JEDEC_DDR4_SN_BYTE0_OFFSET = 325;
+static constexpr auto SPD_JEDEC_DDR4_SN_BYTE1_OFFSET = 326;
+static constexpr auto SPD_JEDEC_DDR4_SN_BYTE2_OFFSET = 327;
+static constexpr auto SPD_JEDEC_DDR4_SN_BYTE3_OFFSET = 328;
+static constexpr auto SPD_JEDEC_DDR4_SDRAM_DENSITY_BANK_OFFSET = 4;
+static constexpr auto SPD_JEDEC_DDR4_SDRAM_ADDR_OFFSET = 5;
+static constexpr auto SPD_JEDEC_DDR4_DRAM_PRI_PACKAGE_OFFSET = 6;
+static constexpr auto SPD_JEDEC_DDR4_DRAM_MODULE_ORG_OFFSET = 12;
+
+// DDR5 JEDEC specification constants
+static constexpr auto SPD_JEDEC_DDR5_SUB_CHANNELS_PER_DIMM = 235;
+static constexpr auto SPD_JEDEC_DDR5_SUB_CHANNELS_PER_DIMM_MASK = 0x60;
+static constexpr auto SPD_JEDEC_DDR5_PRI_BUS_WIDTH_PER_CHANNEL = 235;
+static constexpr auto SPD_JEDEC_DDR5_PRI_BUS_WIDTH_PER_CHANNEL_MASK = 0x07;
+static constexpr auto SPD_JEDEC_DDR5_SDRAM_IO_WIDTH_SYM_ALL = 6;
+static constexpr auto SPD_JEDEC_DDR5_SDRAM_IO_WIDTH_ASYM_EVEN = 6;
+static constexpr auto SPD_JEDEC_DDR5_SDRAM_IO_WIDTH_ASYM_ODD = 10;
+static constexpr auto SPD_JEDEC_DDR5_SDRAM_IO_WIDTH_MASK = 0xE0;
+static constexpr auto SPD_JEDEC_DDR5_DIE_PER_PKG_SYM_ALL = 4;
+static constexpr auto SPD_JEDEC_DDR5_DIE_PER_PKG_ASYM_EVEN = 4;
+static constexpr auto SPD_JEDEC_DDR5_DIE_PER_PKG_ASYM_ODD = 8;
+static constexpr auto SPD_JEDEC_DDR5_DIE_PER_PKG_MASK = 0xE0;
+static constexpr auto SPD_JEDEC_DDR5_SDRAM_DENSITY_PER_DIE_SYM_ALL = 4;
+static constexpr auto SPD_JEDEC_DDR5_SDRAM_DENSITY_PER_DIE_ASYM_EVEN = 4;
+static constexpr auto SPD_JEDEC_DDR5_SDRAM_DENSITY_PER_DIE_ASYM_ODD = 8;
+static constexpr auto SPD_JEDEC_DDR5_SDRAM_DENSITY_PER_DIE_MASK = 0x1F;
+static constexpr auto SPD_JEDEC_DDR5_RANK_MIX = 234;
+static constexpr auto SPD_JEDEC_DDR5_RANK_MIX_SYMMETRICAL_MASK = 0x40;
+
+auto isdimmVpdParser::getDDR4DimmCapacity(Binary::const_iterator& iterator)
+{
+ size_t tmp = 0, dimmSize = 0;
+
+ size_t sdramCap = 1, priBusWid = 1, sdramWid = 1, logicalRanksPerDimm = 1;
+ Byte dieCount = 1;
+
+ // NOTE: This calculation is Only for DDR4
+
+ // Calculate SDRAM capacity
+ tmp = iterator[constants::SPD_BYTE_4] & SPD_JEDEC_DDR4_SDRAM_CAP_MASK;
+ /* Make sure the bits are not Reserved */
+ if (tmp >= SPD_JEDEC_DDR4_SDRAMCAP_RESERVED)
+ {
+ std::cerr
+ << "Bad data in spd byte 4. Can't calculate SDRAM capacity and so "
+ "dimm size.\n ";
+ return dimmSize;
+ }
+
+ sdramCap = (sdramCap << tmp) * SPD_JEDEC_DDR4_SDRAMCAP_MULTIPLIER;
+
+ /* Calculate Primary bus width */
+ tmp = iterator[constants::SPD_BYTE_13] & SPD_JEDEC_DDR4_PRI_BUS_WIDTH_MASK;
+ if (tmp >= SPD_JEDEC_DDR4_4_RESERVED_BITS)
+ {
+ std::cerr
+ << "Bad data in spd byte 13. Can't calculate primary bus width "
+ "and so dimm size.\n ";
+ return dimmSize;
+ }
+ priBusWid = (priBusWid << tmp) * SPD_JEDEC_DDR4_PRI_BUS_WIDTH_MULTIPLIER;
+
+ /* Calculate SDRAM width */
+ tmp = iterator[constants::SPD_BYTE_12] & SPD_JEDEC_DDR4_SDRAM_WIDTH_MASK;
+ if (tmp >= SPD_JEDEC_DDR4_4_RESERVED_BITS)
+ {
+ std::cerr
+ << "Bad data in vpd byte 12. Can't calculate SDRAM width and so "
+ "dimm size.\n ";
+ return dimmSize;
+ }
+ sdramWid = (sdramWid << tmp) * SPD_JEDEC_DDR4_SDRAM_WIDTH_MULTIPLIER;
+
+ tmp = iterator[constants::SPD_BYTE_6] & SPD_JEDEC_DDR4_SIGNAL_LOADING_MASK;
+
+ if (tmp == SPD_JEDEC_DDR4_SINGLE_LOAD_STACK)
+ {
+ // Fetch die count
+ tmp = iterator[constants::SPD_BYTE_6] & SPD_JEDEC_DDR4_DIE_COUNT_MASK;
+ tmp >>= SPD_JEDEC_DDR4_DIE_COUNT_RIGHT_SHIFT;
+ dieCount = tmp + 1;
+ }
+
+ /* Calculate Number of ranks */
+ tmp = iterator[constants::SPD_BYTE_12] & SPD_JEDEC_DDR4_NUM_RANKS_MASK;
+ tmp >>= SPD_JEDEC_DDR4_3_RESERVED_BITS;
+
+ if (tmp >= SPD_JEDEC_DDR4_4_RESERVED_BITS)
+ {
+ std::cerr << "Can't calculate number of ranks. Invalid data found.\n ";
+ return dimmSize;
+ }
+ logicalRanksPerDimm = (tmp + 1) * dieCount;
+
+ dimmSize = (sdramCap / SPD_JEDEC_DDR4_PRI_BUS_WIDTH_MULTIPLIER) *
+ (priBusWid / sdramWid) * logicalRanksPerDimm;
+
+ return dimmSize;
+}
+
+auto isdimmVpdParser::getDDR4PartNumber(Binary::const_iterator& iterator)
+{
+
+ char tmpPN[constants::PART_NUM_LEN + 1] = {'\0'};
+ sprintf(tmpPN, "%02X%02X%02X%X",
+ iterator[SPD_JEDEC_DDR4_SDRAM_DENSITY_BANK_OFFSET],
+ iterator[SPD_JEDEC_DDR4_SDRAM_ADDR_OFFSET],
+ iterator[SPD_JEDEC_DDR4_DRAM_PRI_PACKAGE_OFFSET],
+ iterator[SPD_JEDEC_DDR4_DRAM_MODULE_ORG_OFFSET] & 0x0F);
+ std::string partNumber(tmpPN, sizeof(tmpPN));
+ return partNumber;
+}
+
+auto isdimmVpdParser::getDDR4SerialNumber(Binary::const_iterator& iterator)
+{
+ char tmpSN[constants::SERIAL_NUM_LEN + 1] = {'\0'};
+ sprintf(tmpSN, "%02X%02X%02X%02X%02X%02X",
+ iterator[SPD_JEDEC_DDR4_MFG_ID_MSB_OFFSET],
+ iterator[SPD_JEDEC_DDR4_MFG_ID_LSB_OFFSET],
+ iterator[SPD_JEDEC_DDR4_SN_BYTE0_OFFSET],
+ iterator[SPD_JEDEC_DDR4_SN_BYTE1_OFFSET],
+ iterator[SPD_JEDEC_DDR4_SN_BYTE2_OFFSET],
+ iterator[SPD_JEDEC_DDR4_SN_BYTE3_OFFSET]);
+ std::string serialNumber(tmpSN, sizeof(tmpSN));
+ return serialNumber;
+}
+
+auto isdimmVpdParser::getDDR4FruNumber(const std::string& partNumber)
+{
+ // check for 128GB ISRDIMM not implemented
+ //(128GB 2RX4(8GX72) IS RDIMM 36*(16GBIT, 2H),1.2V 288PIN,1.2" ROHS) - NA
+
+ static std::unordered_map<std::string, std::string> pnFruMap = {
+ {"8421000", "78P4191"}, {"8421008", "78P4192"}, {"8529000", "78P4197"},
+ {"8529008", "78P4198"}, {"8529928", "78P4199"}, {"8529B28", "78P4200"},
+ {"8631008", "78P6815"}, {"8631928", "78P6925"}};
+
+ std::string fruNumber;
+ auto itr = pnFruMap.find(partNumber);
+ if (itr != pnFruMap.end())
+ {
+ fruNumber = itr->second;
+ }
+ else
+ {
+ fruNumber = "FFFFFFF";
+ }
+ return fruNumber;
+}
+
+auto isdimmVpdParser::getDDR4CCIN(const std::string& partNumber)
+{
+ static std::unordered_map<std::string, std::string> pnCCINMap = {
+ {"8421000", "324D"}, {"8421008", "324E"}, {"8529000", "324E"},
+ {"8529008", "324F"}, {"8529928", "325A"}, {"8529B28", "324C"},
+ {"8631008", "32BB"}, {"8631928", "32BC"}};
+
+ std::string ccin;
+ auto itr = pnCCINMap.find(partNumber);
+ if (itr != pnCCINMap.end())
+ {
+ ccin = itr->second;
+ }
+ else
+ {
+ ccin = "XXXX";
+ }
+ return ccin;
+}
+
+auto isdimmVpdParser::getDDR5DimmCapacity(Binary::const_iterator& iterator)
+{
+ // dummy implementation to be updated when required
+ size_t dimmSize = 0;
+ (void)iterator;
+ return dimmSize;
+}
+
+auto isdimmVpdParser::getDDR5PartNumber(Binary::const_iterator& iterator)
+{
+ // dummy implementation to be updated when required
+ std::string partNumber;
+ (void)iterator;
+ partNumber = "0123456";
+ return partNumber;
+}
+
+auto isdimmVpdParser::getDDR5SerialNumber(Binary::const_iterator& iterator)
+{
+ // dummy implementation to be updated when required
+ std::string serialNumber;
+ (void)iterator;
+ serialNumber = "444444444444";
+ return serialNumber;
+}
+
+auto isdimmVpdParser::getDDR5FruNumber(const std::string& partNumber)
+{
+ // dummy implementation to be updated when required
+ static std::unordered_map<std::string, std::string> pnFruMap = {
+ {"1234567", "XXXXXXX"}};
+
+ std::string fruNumber;
+ auto itr = pnFruMap.find(partNumber);
+ if (itr != pnFruMap.end())
+ {
+ fruNumber = itr->second;
+ }
+ else
+ {
+ fruNumber = "FFFFFFF";
+ }
+ return fruNumber;
+}
+
+auto isdimmVpdParser::getDDR5CCIN(const std::string& partNumber)
+{
+ // dummy implementation to be updated when required
+ static std::unordered_map<std::string, std::string> pnCCINMap = {
+ {"1234567", "XXXX"}};
+
+ std::string ccin;
+ auto itr = pnCCINMap.find(partNumber);
+ if (itr != pnCCINMap.end())
+ {
+ ccin = itr->second;
+ }
+ else
+ {
+ ccin = "XXXX";
+ }
+ return ccin;
+}
+
+kwdVpdMap isdimmVpdParser::readKeywords(Binary::const_iterator& iterator)
+{
+ inventory::KeywordVpdMap keywordValueMap{};
+ if ((iterator[constants::SPD_BYTE_2] & constants::SPD_BYTE_MASK) ==
+ constants::SPD_DRAM_TYPE_DDR5)
+ {
+ auto dimmSize = getDDR5DimmCapacity(iterator);
+ if (!dimmSize)
+ {
+ std::cerr << "Error: Calculated dimm size is 0.";
+ }
+ else if (dimmSize < constants::CONVERT_MB_TO_KB)
+ {
+ keywordValueMap.emplace("MemorySizeInMB", dimmSize);
+ }
+ else
+ {
+ size_t dimmCapacityInGB = dimmSize / constants::CONVERT_MB_TO_KB;
+ keywordValueMap.emplace("MemorySizeInGB", dimmCapacityInGB);
+ }
+ auto partNumber = getDDR5PartNumber(iterator);
+ keywordValueMap.emplace("PN", move(partNumber));
+ auto fruNumber = getDDR5FruNumber(partNumber);
+ keywordValueMap.emplace("FN", move(fruNumber));
+ auto serialNumber = getDDR5SerialNumber(iterator);
+ keywordValueMap.emplace("SN", move(serialNumber));
+ auto ccin = getDDR5CCIN(partNumber);
+ keywordValueMap.emplace("CC", move(ccin));
+ }
+ else if ((iterator[constants::SPD_BYTE_2] & constants::SPD_BYTE_MASK) ==
+ constants::SPD_DRAM_TYPE_DDR4)
+ {
+ auto dimmSize = getDDR4DimmCapacity(iterator);
+ if (!dimmSize)
+ {
+ std::cerr << "Error: Calculated dimm size is 0.";
+ }
+ else if (dimmSize < constants::CONVERT_MB_TO_KB)
+ {
+ keywordValueMap.emplace("MemorySizeInMB", dimmSize);
+ }
+ else
+ {
+ size_t dimmCapacityInGB = dimmSize / constants::CONVERT_MB_TO_KB;
+ keywordValueMap.emplace("MemorySizeInGB", dimmCapacityInGB);
+ }
+ size_t dimmCapacityInGB = dimmSize / constants::CONVERT_MB_TO_KB;
+ keywordValueMap.emplace("MemorySizeInGB", dimmCapacityInGB);
+ auto partNumber = getDDR4PartNumber(iterator);
+ keywordValueMap.emplace("PN", move(partNumber));
+ auto fruNumber = getDDR4FruNumber(partNumber);
+ keywordValueMap.emplace("FN", move(fruNumber));
+ auto serialNumber = getDDR4SerialNumber(iterator);
+ keywordValueMap.emplace("SN", move(serialNumber));
+ auto ccin = getDDR4CCIN(partNumber);
+ keywordValueMap.emplace("CC", move(ccin));
+ }
+ return keywordValueMap;
+}
+
+std::variant<kwdVpdMap, Store> isdimmVpdParser::parse()
+{
+ // Read the data and return the map
+ auto iterator = memVpd.cbegin();
+ auto vpdDataMap = readKeywords(iterator);
+
+ return vpdDataMap;
+}
+
+} // namespace parser
+} // namespace memory
+} // namespace vpd
+} // namespace openpower
\ No newline at end of file
diff --git a/vpd-parser/isdimm_vpd_parser.hpp b/vpd-parser/isdimm_vpd_parser.hpp
new file mode 100644
index 0000000..cbcb1d5
--- /dev/null
+++ b/vpd-parser/isdimm_vpd_parser.hpp
@@ -0,0 +1,153 @@
+#pragma once
+
+#include "impl.hpp"
+#include "parser_interface.hpp"
+#include "types.hpp"
+
+namespace openpower
+{
+namespace vpd
+{
+namespace memory
+{
+namespace parser
+{
+using ParserInterface = openpower::vpd::parser::interface::ParserInterface;
+using kwdVpdMap = inventory::KeywordVpdMap;
+
+class isdimmVpdParser : public ParserInterface
+{
+ public:
+ isdimmVpdParser() = delete;
+ isdimmVpdParser(const isdimmVpdParser&) = delete;
+ isdimmVpdParser& operator=(const isdimmVpdParser&) = delete;
+ isdimmVpdParser(isdimmVpdParser&&) = delete;
+ isdimmVpdParser& operator=(isdimmVpdParser&&) = delete;
+ ~isdimmVpdParser() = default;
+
+ /**
+ * @brief Constructor
+ *
+ * Move memVpdVector to parser object's memVpdVector
+ */
+ isdimmVpdParser(const Binary& VpdVector) : memVpd(VpdVector)
+ {
+ }
+
+ /**
+ * @brief Parse the memory SPD binary data.
+ * Collects and emplace the keyword-value pairs in map.
+ *
+ * @return map of keyword:value
+ */
+ std::variant<kwdVpdMap, Store> parse();
+
+ /**
+ * @brief An api to return interface name with respect to
+ * published data on cache
+ *
+ * @return - Interface name for that vpd type.
+ */
+ std::string getInterfaceName() const;
+
+ private:
+ /**
+ * @brief An api to read keywords.
+ *
+ * @return- map of kwd:value
+ */
+ kwdVpdMap readKeywords(Binary::const_iterator& iterator);
+
+ /**
+ * @brief This function calculates DIMM size from SPD
+ *
+ * @param[in] iterator - iterator to buffer containing SPD
+ * @return calculated data or 0 in case of any error.
+ */
+ auto getDDR4DimmCapacity(Binary::const_iterator& iterator);
+
+ /**
+ * @brief This function calculates part number from SPD
+ *
+ * @param[in] iterator - iterator to buffer containing SPD
+ * @return calculated part number.
+ */
+ auto getDDR4PartNumber(Binary::const_iterator& iterator);
+
+ /**
+ * @brief This function calculates serial number from SPD
+ *
+ * @param[in] iterator - iterator to buffer containing SPD
+ * @return calculated serial number.
+ */
+ auto getDDR4SerialNumber(Binary::const_iterator& iterator);
+
+ /**
+ * @brief This function allocates FRU number based on part number
+ *
+ * @param[in] partNumber - part number of the DIMM
+ * @return allocated FRU number.
+ */
+ auto getDDR4FruNumber(const std::string& partNumber);
+
+ /**
+ * @brief This function allocates CCIN based on part number
+ *
+ * @param[in] partNumber - part number of the DIMM
+ * @return allocated CCIN.
+ */
+ auto getDDR4CCIN(const std::string& partNumber);
+
+ /**
+ * @brief This function calculates DIMM size from SPD
+ *
+ * @param[in] iterator - iterator to buffer containing SPD
+ * @return calculated data or 0 in case of any error.
+ */
+ auto getDDR5DimmCapacity(Binary::const_iterator& iterator);
+
+ /**
+ * @brief This function calculates part number from SPD
+ *
+ * @param[in] iterator - iterator to buffer containing SPD
+ * @return calculated part number.
+ */
+ auto getDDR5PartNumber(Binary::const_iterator& iterator);
+
+ /**
+ * @brief This function calculates serial number from SPD
+ *
+ * @param[in] iterator - iterator to buffer containing SPD
+ * @return calculated serial number.
+ */
+ auto getDDR5SerialNumber(Binary::const_iterator& iterator);
+
+ /**
+ * @brief This function allocates FRU number based on part number
+ *
+ * @param[in] partNumber - part number of the DIMM
+ * @return allocated FRU number.
+ */
+ auto getDDR5FruNumber(const std::string& partNumber);
+
+ /**
+ * @brief This function allocates CCIN based on part number
+ *
+ * @param[in] partNumber - part number of the DIMM
+ * @return allocated CCIN.
+ */
+ auto getDDR5CCIN(const std::string& partNumber);
+
+ // vdp file to be parsed
+ const Binary& memVpd;
+};
+
+inline std::string isdimmVpdParser::getInterfaceName() const
+{
+ return constants::memVpdInf;
+}
+
+} // namespace parser
+} // namespace memory
+} // namespace vpd
+} // namespace openpower
diff --git a/vpd-parser/parser_factory.cpp b/vpd-parser/parser_factory.cpp
index f7d0f04..27fae5a 100644
--- a/vpd-parser/parser_factory.cpp
+++ b/vpd-parser/parser_factory.cpp
@@ -3,6 +3,7 @@
#include "const.hpp"
#include "ibm_vpd_utils.hpp"
#include "ipz_parser.hpp"
+#include "isdimm_vpd_parser.hpp"
#include "keyword_vpd_parser.hpp"
#include "memory_vpd_parser.hpp"
#include "vpd_exceptions.hpp"
@@ -40,11 +41,18 @@
return new KeywordVpdParser(vpdVector);
}
- case MEMORY_VPD:
+ case DDR4_DDIMM_MEMORY_VPD:
+ case DDR5_DDIMM_MEMORY_VPD:
{
return new memoryVpdParser(vpdVector);
}
+ case DDR4_ISDIMM_MEMORY_VPD:
+ case DDR5_ISDIMM_MEMORY_VPD:
+ {
+ return new isdimmVpdParser(vpdVector);
+ }
+
default:
throw VpdDataException("Unable to determine VPD format");
}