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");
     }