DDIMM DDR5 calculation fix

Changed the way the number of channels and the package ranks were
calculated

Change-Id: I8341ac21a0659e484dd1960df4a3e96f7adeebb4
Signed-off-by: Jinu Joy Thomas <jinu.joy.thomas@in.ibm.com>
diff --git a/const.hpp b/const.hpp
index b8499a9..bbe6ee9 100644
--- a/const.hpp
+++ b/const.hpp
@@ -99,6 +99,8 @@
 static constexpr auto VALUE_7 = 7;
 static constexpr auto VALUE_8 = 8;
 
+static constexpr auto MASK_BYTE_BITS_6 = 0x40;
+static constexpr auto MASK_BYTE_BITS_7 = 0x80;
 static constexpr auto MASK_BYTE_BITS_01 = 0x03;
 static constexpr auto MASK_BYTE_BITS_345 = 0x38;
 static constexpr auto MASK_BYTE_BITS_012 = 0x07;
diff --git a/vpd-parser/memory_vpd_parser.cpp b/vpd-parser/memory_vpd_parser.cpp
index 30e44aa..ea45792 100644
--- a/vpd-parser/memory_vpd_parser.cpp
+++ b/vpd-parser/memory_vpd_parser.cpp
@@ -127,11 +127,12 @@
                              constants::VALUE_3))
         {
             std::cerr
-                << "Capacity calculation failed for channels per DIMM. DDIMM Byte 235 value ["
+                << "Capacity calculation failed for channels per DIMM. DDIMM "
+                   "Byte 235 value ["
                 << iterator[constants::SPD_BYTE_235] << "]";
             break;
         }
-        uint8_t l_channelsPerDDimm =
+        uint8_t l_channelsPerPhy =
             (((iterator[constants::SPD_BYTE_235] & constants::MASK_BYTE_BITS_01)
                   ? constants::VALUE_1
                   : constants::VALUE_0) +
@@ -140,13 +141,22 @@
                   ? constants::VALUE_1
                   : constants::VALUE_0));
 
+        uint8_t l_channelsPerDdimm = (((iterator[constants::SPD_BYTE_235] &
+                                        constants::MASK_BYTE_BITS_6) >>
+                                       constants::VALUE_6) +
+                                      ((iterator[constants::SPD_BYTE_235] &
+                                        constants::MASK_BYTE_BITS_7) >>
+                                       constants::VALUE_7)) *
+                                     l_channelsPerPhy;
+
         if (!checkValidValue(iterator[constants::SPD_BYTE_235] &
                                  constants::MASK_BYTE_BITS_012,
                              constants::SHIFT_BITS_0, constants::VALUE_1,
                              constants::VALUE_3))
         {
             std::cerr
-                << "Capacity calculation failed for bus width per channel. DDIMM Byte 235 value ["
+                << "Capacity calculation failed for bus width per channel. "
+                   "DDIMM Byte 235 value ["
                 << iterator[constants::SPD_BYTE_235] << "]";
             break;
         }
@@ -161,7 +171,8 @@
                              constants::VALUE_5))
         {
             std::cerr
-                << "Capacity calculation failed for die per package. DDIMM Byte 4 value ["
+                << "Capacity calculation failed for die per package. DDIMM "
+                   "Byte 4 value ["
                 << iterator[constants::SPD_BYTE_4] << "]";
             break;
         }
@@ -175,19 +186,48 @@
                              constants::VALUE_8))
         {
             std::cerr
-                << "Capacity calculation failed for SDRAM Density per Die. DDIMM Byte 4 value ["
+                << "Capacity calculation failed for SDRAM Density per Die. "
+                   "DDIMM Byte 4 value ["
                 << iterator[constants::SPD_BYTE_4] << "]";
             break;
         }
         uint8_t l_densityPerDie = getDDR5DensityPerDie(
             iterator[constants::SPD_BYTE_4] & constants::MASK_BYTE_BITS_01234);
 
-        uint8_t l_ranksPerChannel = ((iterator[constants::SPD_BYTE_234] &
-                                      constants::MASK_BYTE_BITS_345) >>
-                                     constants::VALUE_3) +
-                                    (iterator[constants::SPD_BYTE_234] &
-                                     constants::MASK_BYTE_BITS_012) +
-                                    constants::VALUE_2;
+        uint8_t l_ranksPerChannel = 0;
+        if (((iterator[constants::SPD_BYTE_235] &
+              constants::MASK_BYTE_BITS_7) >>
+             constants::VALUE_7))
+        {
+            l_ranksPerChannel = ((iterator[constants::SPD_BYTE_234] &
+                                  constants::MASK_BYTE_BITS_345) >>
+                                 constants::VALUE_3) +
+                                constants::VALUE_1;
+        }
+        else if (((iterator[constants::SPD_BYTE_235] &
+                   constants::MASK_BYTE_BITS_6) >>
+                  constants::VALUE_6))
+        {
+            l_ranksPerChannel = (iterator[constants::SPD_BYTE_234] &
+                                 constants::MASK_BYTE_BITS_012) +
+                                constants::VALUE_1;
+        }
+#if 0
+        // Old Style capacity calculation kept for reference
+        // will be removed later
+        uint8_t l_ranksPerChannel =
+            (((iterator[constants::SPD_BYTE_234] &
+               constants::MASK_BYTE_BITS_345) >>
+              constants::VALUE_3) *
+             ((iterator[constants::SPD_BYTE_235] &
+               constants::MASK_BYTE_BITS_7) >>
+              constants::VALUE_7)) +
+            ((iterator[constants::SPD_BYTE_234] &
+              constants::MASK_BYTE_BITS_012) +
+             constants::VALUE_2 * ((iterator[constants::SPD_BYTE_235] &
+                                    constants::MASK_BYTE_BITS_6) >>
+                                   constants::VALUE_6));
+#endif
 
         if (!checkValidValue(iterator[constants::SPD_BYTE_6] &
                                  constants::MASK_BYTE_BITS_567,
@@ -204,7 +244,7 @@
                                             constants::MASK_BYTE_BITS_567) >>
                                            constants::VALUE_5));
 
-        dimmSize = (l_channelsPerDDimm * l_busWidthPerChannel *
+        dimmSize = (l_channelsPerDdimm * l_busWidthPerChannel *
                     l_diePerPackage * l_densityPerDie * l_ranksPerChannel) /
                    (8 * l_dramWidth);