DDIMM & ISDIMM:Method to get manufacturer ID

This commit implements the logic to get manufacturer ID for ISDIMMs
and DDIMMs and add it to the Parsed vpd map

Change-Id: If8b707448f9c2485c8cf837bb63fc6df23531355
Signed-off-by: Priyanga Ramasamy <priyanga24@in.ibm.com>
diff --git a/test/utest_ddimm_parser.cpp b/test/utest_ddimm_parser.cpp
index 6674c51..364a3f1 100644
--- a/test/utest_ddimm_parser.cpp
+++ b/test/utest_ddimm_parser.cpp
@@ -26,7 +26,8 @@
             {0x59, 0x48, 0x33, 0x33, 0x31, 0x54, 0x33, 0x38, 0x34, 0x30, 0x33,
              0x46}},
         std::pair<std::string, types::BinaryVector>{"CC",
-                                                    {0x33, 0x32, 0x41, 0x31}}};
+                                                    {0x33, 0x32, 0x41, 0x31}},
+        std::pair<std::string, types::BinaryVector>{"DI", {0x80, 0xCE}}};
 
     nlohmann::json l_json;
     std::string l_vpdFile("vpd_files/ddr5_ddimm.dat");
@@ -49,7 +50,8 @@
             {0x59, 0x48, 0x33, 0x35, 0x31, 0x54, 0x31, 0x35, 0x53, 0x30, 0x44,
              0x35}},
         std::pair<std::string, types::BinaryVector>{"CC",
-                                                    {0x33, 0x32, 0x37, 0x42}}};
+                                                    {0x33, 0x32, 0x37, 0x42}},
+        std::pair<std::string, types::BinaryVector>{"DI", {0x80, 0xAD}}};
 
     nlohmann::json l_json;
     std::string l_vpdFile("vpd_files/ddr4_ddimm.dat");
diff --git a/vpd-manager/include/isdimm_parser.hpp b/vpd-manager/include/isdimm_parser.hpp
index 091285c..5cd3d87 100644
--- a/vpd-manager/include/isdimm_parser.hpp
+++ b/vpd-manager/include/isdimm_parser.hpp
@@ -101,6 +101,13 @@
     std::string_view getDDR4CCIN(const std::string& i_partNumber);
 
     /**
+     * @brief This function returns manufacturer's ID for DDR4 DIMM.
+     *
+     * @return manufacturer ID.
+     */
+    types::BinaryVector getDDR4ManufacturerId();
+
+    /**
      * @brief This function calculates DIMM size from DDR5 SPD
      *
      * @param[in] i_iterator - iterator to buffer containing SPD
diff --git a/vpd-manager/src/ddimm_parser.cpp b/vpd-manager/src/ddimm_parser.cpp
index b4144aa..a480000 100644
--- a/vpd-manager/src/ddimm_parser.cpp
+++ b/vpd-manager/src/ddimm_parser.cpp
@@ -20,6 +20,8 @@
 
 static constexpr auto PRIMARY_BUS_WIDTH_32_BITS = 32;
 static constexpr auto PRIMARY_BUS_WIDTH_UNUSED = 0;
+static constexpr auto DRAM_MANUFACTURER_ID_OFFSET = 0x228;
+static constexpr auto DRAM_MANUFACTURER_ID_LENGTH = 0x02;
 
 bool DdimmVpdParser::checkValidValue(uint8_t i_ByteValue, uint8_t i_shift,
                                      uint8_t i_minValue, uint8_t i_maxValue)
@@ -368,10 +370,15 @@
     advance(i_iterator, constants::SERIAL_NUM_LEN);
     types::BinaryVector l_ccin(i_iterator, i_iterator + constants::CCIN_LEN);
 
+    types::BinaryVector l_mfgId(DRAM_MANUFACTURER_ID_LENGTH);
+    std::copy_n((m_vpdVector.cbegin() + DRAM_MANUFACTURER_ID_OFFSET),
+                DRAM_MANUFACTURER_ID_LENGTH, l_mfgId.begin());
+
     m_parsedVpdMap.emplace("FN", l_partNumber);
     m_parsedVpdMap.emplace("PN", move(l_partNumber));
     m_parsedVpdMap.emplace("SN", move(l_serialNumber));
     m_parsedVpdMap.emplace("CC", move(l_ccin));
+    m_parsedVpdMap.emplace("DI", move(l_mfgId));
 }
 
 types::VPDMapVariant DdimmVpdParser::parse()
diff --git a/vpd-manager/src/isdimm_parser.cpp b/vpd-manager/src/isdimm_parser.cpp
index 76e1dea..72e2657 100644
--- a/vpd-manager/src/isdimm_parser.cpp
+++ b/vpd-manager/src/isdimm_parser.cpp
@@ -40,6 +40,8 @@
 constexpr auto SPD_JEDEC_DDR4_SDRAM_ADDR_OFFSET = 5;
 constexpr auto SPD_JEDEC_DDR4_DRAM_PRI_PACKAGE_OFFSET = 6;
 constexpr auto SPD_JEDEC_DDR4_DRAM_MODULE_ORG_OFFSET = 12;
+static constexpr auto SPD_JEDEC_DDR4_DRAM_MANUFACTURER_ID_OFFSET = 320;
+static constexpr auto SPD_JEDEC_DRAM_MANUFACTURER_ID_LENGTH = 2;
 
 // Lookup tables
 const std::map<std::tuple<std::string, uint8_t>, std::string> pnFreqFnMap = {
@@ -204,6 +206,24 @@
     return "XXXX"; // Return default value as XXXX
 }
 
+types::BinaryVector JedecSpdParser::getDDR4ManufacturerId()
+{
+    types::BinaryVector l_mfgId(SPD_JEDEC_DRAM_MANUFACTURER_ID_LENGTH);
+
+    if (m_memSpd.size() < (SPD_JEDEC_DDR4_DRAM_MANUFACTURER_ID_OFFSET +
+                           SPD_JEDEC_DRAM_MANUFACTURER_ID_LENGTH))
+    {
+        logging::logMessage(
+            "VPD length is less than the offset of Manufacturer ID. Can't fetch it");
+        return l_mfgId;
+    }
+
+    std::copy_n((m_memSpd.cbegin() +
+                 SPD_JEDEC_DDR4_DRAM_MANUFACTURER_ID_OFFSET),
+                SPD_JEDEC_DRAM_MANUFACTURER_ID_LENGTH, l_mfgId.begin());
+    return l_mfgId;
+}
+
 auto JedecSpdParser::getDDR5DimmCapacity(
     types::BinaryVector::const_iterator& i_iterator)
 {
@@ -290,6 +310,8 @@
         getDDR4CCIN(std::string(l_fruNumber.begin(), l_fruNumber.end()));
     // PN value is made same as FN value
     auto l_displayPartNumber = l_fruNumber;
+    auto l_mfgId = getDDR4ManufacturerId();
+
     l_keywordValueMap.emplace("PN",
                               move(std::string(l_displayPartNumber.begin(),
                                                l_displayPartNumber.end())));
@@ -298,6 +320,7 @@
     l_keywordValueMap.emplace("SN", move(l_serialNumber));
     l_keywordValueMap.emplace("CC",
                               move(std::string(ccin.begin(), ccin.end())));
+    l_keywordValueMap.emplace("DI", move(l_mfgId));
 
     return l_keywordValueMap;
 }