xref: /openbmc/openpower-vpd-parser/vpd-manager/src/ddimm_parser.cpp (revision 43fedabc032ba7c209b58111b6c35c7d95a9f14e)
1fa5e4d32SSunny Srivastava #include "ddimm_parser.hpp"
2fa5e4d32SSunny Srivastava 
3fa5e4d32SSunny Srivastava #include "constants.hpp"
4fa5e4d32SSunny Srivastava #include "exceptions.hpp"
5fa5e4d32SSunny Srivastava 
6fa5e4d32SSunny Srivastava #include <cmath>
7fa5e4d32SSunny Srivastava #include <cstdint>
8fa5e4d32SSunny Srivastava #include <iostream>
9fa5e4d32SSunny Srivastava #include <numeric>
10fa5e4d32SSunny Srivastava #include <string>
11fa5e4d32SSunny Srivastava 
12fa5e4d32SSunny Srivastava namespace vpd
13fa5e4d32SSunny Srivastava {
14fa5e4d32SSunny Srivastava 
15fa5e4d32SSunny Srivastava static constexpr auto SDRAM_DENSITY_PER_DIE_24GB = 24;
16fa5e4d32SSunny Srivastava static constexpr auto SDRAM_DENSITY_PER_DIE_32GB = 32;
17fa5e4d32SSunny Srivastava static constexpr auto SDRAM_DENSITY_PER_DIE_48GB = 48;
18fa5e4d32SSunny Srivastava static constexpr auto SDRAM_DENSITY_PER_DIE_64GB = 64;
19fa5e4d32SSunny Srivastava static constexpr auto SDRAM_DENSITY_PER_DIE_UNDEFINED = 0;
20fa5e4d32SSunny Srivastava 
21fa5e4d32SSunny Srivastava static constexpr auto PRIMARY_BUS_WIDTH_32_BITS = 32;
22fa5e4d32SSunny Srivastava static constexpr auto PRIMARY_BUS_WIDTH_UNUSED = 0;
23e606f061SPriyanga Ramasamy static constexpr auto DRAM_MANUFACTURER_ID_OFFSET = 0x228;
24e606f061SPriyanga Ramasamy static constexpr auto DRAM_MANUFACTURER_ID_LENGTH = 0x02;
25fa5e4d32SSunny Srivastava 
checkValidValue(uint8_t i_ByteValue,uint8_t i_shift,uint8_t i_minValue,uint8_t i_maxValue)26fa5e4d32SSunny Srivastava bool DdimmVpdParser::checkValidValue(uint8_t i_ByteValue, uint8_t i_shift,
27fa5e4d32SSunny Srivastava                                      uint8_t i_minValue, uint8_t i_maxValue)
28fa5e4d32SSunny Srivastava {
29fa5e4d32SSunny Srivastava     bool l_isValid = true;
30fa5e4d32SSunny Srivastava     uint8_t l_ByteValue = i_ByteValue >> i_shift;
31fa5e4d32SSunny Srivastava     if ((l_ByteValue > i_maxValue) || (l_ByteValue < i_minValue))
32fa5e4d32SSunny Srivastava     {
33fa5e4d32SSunny Srivastava         logging::logMessage(
34fa5e4d32SSunny Srivastava             "Non valid Value encountered value[" + std::to_string(l_ByteValue) +
35fa5e4d32SSunny Srivastava             "] range [" + std::to_string(i_minValue) + ".." +
36fa5e4d32SSunny Srivastava             std::to_string(i_maxValue) + "] found ");
37fa5e4d32SSunny Srivastava         return false;
38fa5e4d32SSunny Srivastava     }
39fa5e4d32SSunny Srivastava     return l_isValid;
40fa5e4d32SSunny Srivastava }
41fa5e4d32SSunny Srivastava 
getDdr5DensityPerDie(uint8_t i_ByteValue)42fa5e4d32SSunny Srivastava uint8_t DdimmVpdParser::getDdr5DensityPerDie(uint8_t i_ByteValue)
43fa5e4d32SSunny Srivastava {
44fa5e4d32SSunny Srivastava     uint8_t l_densityPerDie = SDRAM_DENSITY_PER_DIE_UNDEFINED;
45fa5e4d32SSunny Srivastava     if (i_ByteValue < constants::VALUE_5)
46fa5e4d32SSunny Srivastava     {
47fa5e4d32SSunny Srivastava         l_densityPerDie = i_ByteValue * constants::VALUE_4;
48fa5e4d32SSunny Srivastava     }
49fa5e4d32SSunny Srivastava     else
50fa5e4d32SSunny Srivastava     {
51fa5e4d32SSunny Srivastava         switch (i_ByteValue)
52fa5e4d32SSunny Srivastava         {
53fa5e4d32SSunny Srivastava             case constants::VALUE_5:
54fa5e4d32SSunny Srivastava                 l_densityPerDie = SDRAM_DENSITY_PER_DIE_24GB;
55fa5e4d32SSunny Srivastava                 break;
56fa5e4d32SSunny Srivastava 
57fa5e4d32SSunny Srivastava             case constants::VALUE_6:
58fa5e4d32SSunny Srivastava                 l_densityPerDie = SDRAM_DENSITY_PER_DIE_32GB;
59fa5e4d32SSunny Srivastava                 break;
60fa5e4d32SSunny Srivastava 
61fa5e4d32SSunny Srivastava             case constants::VALUE_7:
62fa5e4d32SSunny Srivastava                 l_densityPerDie = SDRAM_DENSITY_PER_DIE_48GB;
63fa5e4d32SSunny Srivastava                 break;
64fa5e4d32SSunny Srivastava 
65fa5e4d32SSunny Srivastava             case constants::VALUE_8:
66fa5e4d32SSunny Srivastava                 l_densityPerDie = SDRAM_DENSITY_PER_DIE_64GB;
67fa5e4d32SSunny Srivastava                 break;
68fa5e4d32SSunny Srivastava 
69fa5e4d32SSunny Srivastava             default:
70fa5e4d32SSunny Srivastava                 logging::logMessage(
71fa5e4d32SSunny Srivastava                     "default value encountered for density per die");
72fa5e4d32SSunny Srivastava                 l_densityPerDie = SDRAM_DENSITY_PER_DIE_UNDEFINED;
73fa5e4d32SSunny Srivastava                 break;
74fa5e4d32SSunny Srivastava         }
75fa5e4d32SSunny Srivastava     }
76fa5e4d32SSunny Srivastava     return l_densityPerDie;
77fa5e4d32SSunny Srivastava }
78fa5e4d32SSunny Srivastava 
getDdr5DiePerPackage(uint8_t i_ByteValue)79fa5e4d32SSunny Srivastava uint8_t DdimmVpdParser::getDdr5DiePerPackage(uint8_t i_ByteValue)
80fa5e4d32SSunny Srivastava {
81fa5e4d32SSunny Srivastava     uint8_t l_DiePerPackage = constants::VALUE_0;
82fa5e4d32SSunny Srivastava     if (i_ByteValue < constants::VALUE_2)
83fa5e4d32SSunny Srivastava     {
84fa5e4d32SSunny Srivastava         l_DiePerPackage = i_ByteValue + constants::VALUE_1;
85fa5e4d32SSunny Srivastava     }
86fa5e4d32SSunny Srivastava     else
87fa5e4d32SSunny Srivastava     {
88fa5e4d32SSunny Srivastava         l_DiePerPackage =
89fa5e4d32SSunny Srivastava             pow(constants::VALUE_2, (i_ByteValue - constants::VALUE_1));
90fa5e4d32SSunny Srivastava     }
91fa5e4d32SSunny Srivastava     return l_DiePerPackage;
92fa5e4d32SSunny Srivastava }
93fa5e4d32SSunny Srivastava 
getDdr5BasedDdimmSize(types::BinaryVector::const_iterator i_iterator)94fa5e4d32SSunny Srivastava size_t DdimmVpdParser::getDdr5BasedDdimmSize(
95fa5e4d32SSunny Srivastava     types::BinaryVector::const_iterator i_iterator)
96fa5e4d32SSunny Srivastava {
97fa5e4d32SSunny Srivastava     size_t l_dimmSize = 0;
98fa5e4d32SSunny Srivastava 
99fa5e4d32SSunny Srivastava     do
100fa5e4d32SSunny Srivastava     {
101fa5e4d32SSunny Srivastava         if (!checkValidValue(i_iterator[constants::SPD_BYTE_235] &
102fa5e4d32SSunny Srivastava                                  constants::MASK_BYTE_BITS_01,
103fa5e4d32SSunny Srivastava                              constants::SHIFT_BITS_0, constants::VALUE_1,
104fa5e4d32SSunny Srivastava                              constants::VALUE_3) ||
105fa5e4d32SSunny Srivastava             !checkValidValue(i_iterator[constants::SPD_BYTE_235] &
106fa5e4d32SSunny Srivastava                                  constants::MASK_BYTE_BITS_345,
107fa5e4d32SSunny Srivastava                              constants::SHIFT_BITS_3, constants::VALUE_1,
108fa5e4d32SSunny Srivastava                              constants::VALUE_3))
109fa5e4d32SSunny Srivastava         {
110fa5e4d32SSunny Srivastava             logging::logMessage(
111fa5e4d32SSunny Srivastava                 "Capacity calculation failed for channels per DIMM. DDIMM Byte "
112fa5e4d32SSunny Srivastava                 "235 value [" +
113fa5e4d32SSunny Srivastava                 std::to_string(i_iterator[constants::SPD_BYTE_235]) + "]");
114fa5e4d32SSunny Srivastava             break;
115fa5e4d32SSunny Srivastava         }
116fa5e4d32SSunny Srivastava         uint8_t l_channelsPerPhy =
117fa5e4d32SSunny Srivastava             (((i_iterator[constants::SPD_BYTE_235] &
118fa5e4d32SSunny Srivastava                constants::MASK_BYTE_BITS_01)
119fa5e4d32SSunny Srivastava                   ? constants::VALUE_1
120fa5e4d32SSunny Srivastava                   : constants::VALUE_0) +
121fa5e4d32SSunny Srivastava              ((i_iterator[constants::SPD_BYTE_235] &
122fa5e4d32SSunny Srivastava                constants::MASK_BYTE_BITS_345)
123fa5e4d32SSunny Srivastava                   ? constants::VALUE_1
124fa5e4d32SSunny Srivastava                   : constants::VALUE_0));
125fa5e4d32SSunny Srivastava 
126fa5e4d32SSunny Srivastava         uint8_t l_channelsPerDdimm =
127fa5e4d32SSunny Srivastava             (((i_iterator[constants::SPD_BYTE_235] &
128fa5e4d32SSunny Srivastava                constants::MASK_BYTE_BIT_6) >>
129fa5e4d32SSunny Srivastava               constants::VALUE_6) +
130fa5e4d32SSunny Srivastava              ((i_iterator[constants::SPD_BYTE_235] &
131fa5e4d32SSunny Srivastava                constants::MASK_BYTE_BIT_7) >>
132fa5e4d32SSunny Srivastava               constants::VALUE_7)) *
133fa5e4d32SSunny Srivastava             l_channelsPerPhy;
134fa5e4d32SSunny Srivastava 
135fa5e4d32SSunny Srivastava         if (!checkValidValue(i_iterator[constants::SPD_BYTE_235] &
136fa5e4d32SSunny Srivastava                                  constants::MASK_BYTE_BITS_012,
137fa5e4d32SSunny Srivastava                              constants::SHIFT_BITS_0, constants::VALUE_1,
138fa5e4d32SSunny Srivastava                              constants::VALUE_3))
139fa5e4d32SSunny Srivastava         {
140fa5e4d32SSunny Srivastava             logging::logMessage(
141fa5e4d32SSunny Srivastava                 "Capacity calculation failed for bus width per channel. DDIMM "
142fa5e4d32SSunny Srivastava                 "Byte 235 value [" +
143fa5e4d32SSunny Srivastava                 std::to_string(i_iterator[constants::SPD_BYTE_235]) + "]");
144fa5e4d32SSunny Srivastava             break;
145fa5e4d32SSunny Srivastava         }
146fa5e4d32SSunny Srivastava         uint8_t l_busWidthPerChannel =
147fa5e4d32SSunny Srivastava             (i_iterator[constants::SPD_BYTE_235] &
148fa5e4d32SSunny Srivastava              constants::MASK_BYTE_BITS_012)
149fa5e4d32SSunny Srivastava                 ? PRIMARY_BUS_WIDTH_32_BITS
150fa5e4d32SSunny Srivastava                 : PRIMARY_BUS_WIDTH_UNUSED;
151fa5e4d32SSunny Srivastava 
152fa5e4d32SSunny Srivastava         if (!checkValidValue(i_iterator[constants::SPD_BYTE_4] &
153fa5e4d32SSunny Srivastava                                  constants::MASK_BYTE_BITS_567,
154fa5e4d32SSunny Srivastava                              constants::SHIFT_BITS_5, constants::VALUE_0,
155fa5e4d32SSunny Srivastava                              constants::VALUE_5))
156fa5e4d32SSunny Srivastava         {
157fa5e4d32SSunny Srivastava             logging::logMessage(
158fa5e4d32SSunny Srivastava                 "Capacity calculation failed for die per package. DDIMM Byte 4 "
159fa5e4d32SSunny Srivastava                 "value [" +
160fa5e4d32SSunny Srivastava                 std::to_string(i_iterator[constants::SPD_BYTE_4]) + "]");
161fa5e4d32SSunny Srivastava             break;
162fa5e4d32SSunny Srivastava         }
163fa5e4d32SSunny Srivastava         uint8_t l_diePerPackage = getDdr5DiePerPackage(
164fa5e4d32SSunny Srivastava             (i_iterator[constants::SPD_BYTE_4] &
165fa5e4d32SSunny Srivastava              constants::MASK_BYTE_BITS_567) >>
166fa5e4d32SSunny Srivastava             constants::VALUE_5);
167fa5e4d32SSunny Srivastava 
168fa5e4d32SSunny Srivastava         if (!checkValidValue(i_iterator[constants::SPD_BYTE_4] &
169fa5e4d32SSunny Srivastava                                  constants::MASK_BYTE_BITS_01234,
170fa5e4d32SSunny Srivastava                              constants::SHIFT_BITS_0, constants::VALUE_1,
171fa5e4d32SSunny Srivastava                              constants::VALUE_8))
172fa5e4d32SSunny Srivastava         {
173fa5e4d32SSunny Srivastava             logging::logMessage(
174fa5e4d32SSunny Srivastava                 "Capacity calculation failed for SDRAM Density per Die. DDIMM "
175fa5e4d32SSunny Srivastava                 "Byte 4 value [" +
176fa5e4d32SSunny Srivastava                 std::to_string(i_iterator[constants::SPD_BYTE_4]) + "]");
177fa5e4d32SSunny Srivastava             break;
178fa5e4d32SSunny Srivastava         }
179fa5e4d32SSunny Srivastava         uint8_t l_densityPerDie = getDdr5DensityPerDie(
180fa5e4d32SSunny Srivastava             i_iterator[constants::SPD_BYTE_4] &
181fa5e4d32SSunny Srivastava             constants::MASK_BYTE_BITS_01234);
182fa5e4d32SSunny Srivastava 
183fa5e4d32SSunny Srivastava         uint8_t l_ranksPerChannel = 0;
184fa5e4d32SSunny Srivastava 
185fa5e4d32SSunny Srivastava         if (((i_iterator[constants::SPD_BYTE_234] &
186fa5e4d32SSunny Srivastava               constants::MASK_BYTE_BIT_7) >>
187fa5e4d32SSunny Srivastava              constants::VALUE_7))
188fa5e4d32SSunny Srivastava         {
189fa5e4d32SSunny Srivastava             l_ranksPerChannel = ((i_iterator[constants::SPD_BYTE_234] &
190fa5e4d32SSunny Srivastava                                   constants::MASK_BYTE_BITS_345) >>
191fa5e4d32SSunny Srivastava                                  constants::VALUE_3) +
192fa5e4d32SSunny Srivastava                                 constants::VALUE_1;
193fa5e4d32SSunny Srivastava         }
194fa5e4d32SSunny Srivastava         else if (((i_iterator[constants::SPD_BYTE_235] &
195fa5e4d32SSunny Srivastava                    constants::MASK_BYTE_BIT_6) >>
196fa5e4d32SSunny Srivastava                   constants::VALUE_6))
197fa5e4d32SSunny Srivastava         {
198fa5e4d32SSunny Srivastava             l_ranksPerChannel = (i_iterator[constants::SPD_BYTE_234] &
199fa5e4d32SSunny Srivastava                                  constants::MASK_BYTE_BITS_012) +
200fa5e4d32SSunny Srivastava                                 constants::VALUE_1;
201fa5e4d32SSunny Srivastava         }
202fa5e4d32SSunny Srivastava 
203fa5e4d32SSunny Srivastava         if (!checkValidValue(i_iterator[constants::SPD_BYTE_6] &
204fa5e4d32SSunny Srivastava                                  constants::MASK_BYTE_BITS_567,
205fa5e4d32SSunny Srivastava                              constants::SHIFT_BITS_5, constants::VALUE_0,
206fa5e4d32SSunny Srivastava                              constants::VALUE_3))
207fa5e4d32SSunny Srivastava         {
208fa5e4d32SSunny Srivastava             logging::logMessage(
209fa5e4d32SSunny Srivastava                 "Capacity calculation failed for dram width DDIMM Byte 6 value "
210fa5e4d32SSunny Srivastava                 "[" +
211fa5e4d32SSunny Srivastava                 std::to_string(i_iterator[constants::SPD_BYTE_6]) + "]");
212fa5e4d32SSunny Srivastava             break;
213fa5e4d32SSunny Srivastava         }
214fa5e4d32SSunny Srivastava         uint8_t l_dramWidth =
215fa5e4d32SSunny Srivastava             constants::VALUE_4 *
216fa5e4d32SSunny Srivastava             (constants::VALUE_1 << ((i_iterator[constants::SPD_BYTE_6] &
217fa5e4d32SSunny Srivastava                                      constants::MASK_BYTE_BITS_567) >>
218fa5e4d32SSunny Srivastava                                     constants::VALUE_5));
219fa5e4d32SSunny Srivastava 
220fa5e4d32SSunny Srivastava         // DDIMM size is calculated in GB
221fa5e4d32SSunny Srivastava         l_dimmSize = (l_channelsPerDdimm * l_busWidthPerChannel *
222fa5e4d32SSunny Srivastava                       l_diePerPackage * l_densityPerDie * l_ranksPerChannel) /
223fa5e4d32SSunny Srivastava                      (8 * l_dramWidth);
224fa5e4d32SSunny Srivastava 
225fa5e4d32SSunny Srivastava     } while (false);
226fa5e4d32SSunny Srivastava 
227fa5e4d32SSunny Srivastava     return constants::CONVERT_GB_TO_KB * l_dimmSize;
228fa5e4d32SSunny Srivastava }
229fa5e4d32SSunny Srivastava 
getDdr4BasedDdimmSize(types::BinaryVector::const_iterator i_iterator)230fa5e4d32SSunny Srivastava size_t DdimmVpdParser::getDdr4BasedDdimmSize(
231fa5e4d32SSunny Srivastava     types::BinaryVector::const_iterator i_iterator)
232fa5e4d32SSunny Srivastava {
233fa5e4d32SSunny Srivastava     size_t l_dimmSize = 0;
234fa5e4d32SSunny Srivastava     try
235fa5e4d32SSunny Srivastava     {
236fa5e4d32SSunny Srivastava         uint8_t l_tmpValue = 0;
237fa5e4d32SSunny Srivastava 
238fa5e4d32SSunny Srivastava         // Calculate SDRAM capacity
239fa5e4d32SSunny Srivastava         l_tmpValue = i_iterator[constants::SPD_BYTE_4] &
240fa5e4d32SSunny Srivastava                      constants::JEDEC_SDRAM_CAP_MASK;
241fa5e4d32SSunny Srivastava 
242fa5e4d32SSunny Srivastava         /* Make sure the bits are not Reserved */
243fa5e4d32SSunny Srivastava         if (l_tmpValue > constants::JEDEC_SDRAMCAP_RESERVED)
244fa5e4d32SSunny Srivastava         {
245fa5e4d32SSunny Srivastava             throw std::runtime_error(
246fa5e4d32SSunny Srivastava                 "Bad data in VPD byte 4. Can't calculate SDRAM capacity and so "
247fa5e4d32SSunny Srivastava                 "dimm size.\n ");
248fa5e4d32SSunny Srivastava         }
249fa5e4d32SSunny Srivastava 
250fa5e4d32SSunny Srivastava         uint16_t l_sdramCapacity = 1;
251fa5e4d32SSunny Srivastava         l_sdramCapacity = (l_sdramCapacity << l_tmpValue) *
252fa5e4d32SSunny Srivastava                           constants::JEDEC_SDRAMCAP_MULTIPLIER;
253fa5e4d32SSunny Srivastava 
254fa5e4d32SSunny Srivastava         /* Calculate Primary bus width */
255fa5e4d32SSunny Srivastava         l_tmpValue = i_iterator[constants::SPD_BYTE_13] &
256fa5e4d32SSunny Srivastava                      constants::JEDEC_PRI_BUS_WIDTH_MASK;
257fa5e4d32SSunny Srivastava 
258fa5e4d32SSunny Srivastava         if (l_tmpValue > constants::JEDEC_RESERVED_BITS)
259fa5e4d32SSunny Srivastava         {
260fa5e4d32SSunny Srivastava             throw std::runtime_error(
261fa5e4d32SSunny Srivastava                 "Bad data in VPD byte 13. Can't calculate primary bus width "
262fa5e4d32SSunny Srivastava                 "and so dimm size.");
263fa5e4d32SSunny Srivastava         }
264fa5e4d32SSunny Srivastava 
265fa5e4d32SSunny Srivastava         uint8_t l_primaryBusWid = 1;
266fa5e4d32SSunny Srivastava         l_primaryBusWid = (l_primaryBusWid << l_tmpValue) *
267fa5e4d32SSunny Srivastava                           constants::JEDEC_PRI_BUS_WIDTH_MULTIPLIER;
268fa5e4d32SSunny Srivastava 
269fa5e4d32SSunny Srivastava         /* Calculate SDRAM width */
270fa5e4d32SSunny Srivastava         l_tmpValue = i_iterator[constants::SPD_BYTE_12] &
271fa5e4d32SSunny Srivastava                      constants::JEDEC_SDRAM_WIDTH_MASK;
272fa5e4d32SSunny Srivastava 
273fa5e4d32SSunny Srivastava         if (l_tmpValue > constants::JEDEC_RESERVED_BITS)
274fa5e4d32SSunny Srivastava         {
275fa5e4d32SSunny Srivastava             throw std::runtime_error(
276fa5e4d32SSunny Srivastava                 "Bad data in VPD byte 12. Can't calculate SDRAM width and so "
277fa5e4d32SSunny Srivastava                 "dimm size.");
278fa5e4d32SSunny Srivastava         }
279fa5e4d32SSunny Srivastava 
280fa5e4d32SSunny Srivastava         uint8_t l_sdramWidth = 1;
281fa5e4d32SSunny Srivastava         l_sdramWidth = (l_sdramWidth << l_tmpValue) *
282fa5e4d32SSunny Srivastava                        constants::JEDEC_SDRAM_WIDTH_MULTIPLIER;
283fa5e4d32SSunny Srivastava 
284fa5e4d32SSunny Srivastava         /* Calculate Number of ranks */
285fa5e4d32SSunny Srivastava         l_tmpValue = i_iterator[constants::SPD_BYTE_12] &
286fa5e4d32SSunny Srivastava                      constants::JEDEC_NUM_RANKS_MASK;
287fa5e4d32SSunny Srivastava         l_tmpValue >>= constants::JEDEC_RESERVED_BITS;
288fa5e4d32SSunny Srivastava 
289fa5e4d32SSunny Srivastava         if (l_tmpValue > constants::JEDEC_RESERVED_BITS)
290fa5e4d32SSunny Srivastava         {
291fa5e4d32SSunny Srivastava             throw std::runtime_error(
292fa5e4d32SSunny Srivastava                 "Bad data in VPD byte 12, can't calculate number of ranks. Invalid data found.");
293fa5e4d32SSunny Srivastava         }
294fa5e4d32SSunny Srivastava 
295fa5e4d32SSunny Srivastava         uint8_t l_logicalRanksPerDimm = l_tmpValue + 1;
296fa5e4d32SSunny Srivastava 
297fa5e4d32SSunny Srivastava         // Determine is single load stack (3DS) or not
298fa5e4d32SSunny Srivastava         l_tmpValue = i_iterator[constants::SPD_BYTE_6] &
299fa5e4d32SSunny Srivastava                      constants::JEDEC_SIGNAL_LOADING_MASK;
300fa5e4d32SSunny Srivastava 
301fa5e4d32SSunny Srivastava         if (l_tmpValue == constants::JEDEC_SINGLE_LOAD_STACK)
302fa5e4d32SSunny Srivastava         {
303fa5e4d32SSunny Srivastava             // Fetch die count
304fa5e4d32SSunny Srivastava             l_tmpValue = i_iterator[constants::SPD_BYTE_6] &
305fa5e4d32SSunny Srivastava                          constants::JEDEC_DIE_COUNT_MASK;
306fa5e4d32SSunny Srivastava             l_tmpValue >>= constants::JEDEC_DIE_COUNT_RIGHT_SHIFT;
307fa5e4d32SSunny Srivastava 
308fa5e4d32SSunny Srivastava             uint8_t l_dieCount = l_tmpValue + 1;
309fa5e4d32SSunny Srivastava             l_logicalRanksPerDimm *= l_dieCount;
310fa5e4d32SSunny Srivastava         }
311fa5e4d32SSunny Srivastava 
312fa5e4d32SSunny Srivastava         l_dimmSize =
313fa5e4d32SSunny Srivastava             (l_sdramCapacity / constants::JEDEC_PRI_BUS_WIDTH_MULTIPLIER) *
314fa5e4d32SSunny Srivastava             (l_primaryBusWid / l_sdramWidth) * l_logicalRanksPerDimm;
315fa5e4d32SSunny Srivastava 
316fa5e4d32SSunny Srivastava         // Converting dimm size from MB to KB
317fa5e4d32SSunny Srivastava         l_dimmSize *= constants::CONVERT_MB_TO_KB;
318fa5e4d32SSunny Srivastava     }
319fa5e4d32SSunny Srivastava     catch (const std::exception& l_ex)
320fa5e4d32SSunny Srivastava     {
321fa5e4d32SSunny Srivastava         // TODO:: Need an error log here
322fa5e4d32SSunny Srivastava         logging::logMessage("DDR4 DDIMM calculation is failed, reason: " +
323fa5e4d32SSunny Srivastava                             std::string(l_ex.what()));
324fa5e4d32SSunny Srivastava     }
325fa5e4d32SSunny Srivastava     return l_dimmSize;
326fa5e4d32SSunny Srivastava }
327fa5e4d32SSunny Srivastava 
getDdimmSize(types::BinaryVector::const_iterator i_iterator)328*43fedabcSPatrick Williams size_t DdimmVpdParser::getDdimmSize(
329*43fedabcSPatrick Williams     types::BinaryVector::const_iterator i_iterator)
330fa5e4d32SSunny Srivastava {
331fa5e4d32SSunny Srivastava     size_t l_dimmSize = 0;
332fa5e4d32SSunny Srivastava     if (i_iterator[constants::SPD_BYTE_2] == constants::SPD_DRAM_TYPE_DDR5)
333fa5e4d32SSunny Srivastava     {
334fa5e4d32SSunny Srivastava         l_dimmSize = getDdr5BasedDdimmSize(i_iterator);
335fa5e4d32SSunny Srivastava     }
336fa5e4d32SSunny Srivastava     else if (i_iterator[constants::SPD_BYTE_2] == constants::SPD_DRAM_TYPE_DDR4)
337fa5e4d32SSunny Srivastava     {
338fa5e4d32SSunny Srivastava         l_dimmSize = getDdr4BasedDdimmSize(i_iterator);
339fa5e4d32SSunny Srivastava     }
340fa5e4d32SSunny Srivastava     else
341fa5e4d32SSunny Srivastava     {
342fa5e4d32SSunny Srivastava         logging::logMessage(
343fa5e4d32SSunny Srivastava             "Error: DDIMM is neither DDR4 nor DDR5. DDIMM Byte 2 value [" +
344fa5e4d32SSunny Srivastava             std::to_string(i_iterator[constants::SPD_BYTE_2]) + "]");
345fa5e4d32SSunny Srivastava     }
346fa5e4d32SSunny Srivastava     return l_dimmSize;
347fa5e4d32SSunny Srivastava }
348fa5e4d32SSunny Srivastava 
readKeywords(types::BinaryVector::const_iterator i_iterator)349*43fedabcSPatrick Williams void DdimmVpdParser::readKeywords(
350*43fedabcSPatrick Williams     types::BinaryVector::const_iterator i_iterator)
351fa5e4d32SSunny Srivastava {
352fa5e4d32SSunny Srivastava     // collect DDIMM size value
353fa5e4d32SSunny Srivastava     auto l_dimmSize = getDdimmSize(i_iterator);
354fa5e4d32SSunny Srivastava     if (!l_dimmSize)
355fa5e4d32SSunny Srivastava     {
356fa5e4d32SSunny Srivastava         throw(DataException("Error: Calculated dimm size is 0."));
357fa5e4d32SSunny Srivastava     }
358fa5e4d32SSunny Srivastava 
359fa5e4d32SSunny Srivastava     m_parsedVpdMap.emplace("MemorySizeInKB", l_dimmSize);
360fa5e4d32SSunny Srivastava     // point the i_iterator to DIMM data and skip "11S"
361fa5e4d32SSunny Srivastava     advance(i_iterator, constants::DDIMM_11S_BARCODE_START +
362fa5e4d32SSunny Srivastava                             constants::DDIMM_11S_FORMAT_LEN);
363fa5e4d32SSunny Srivastava     types::BinaryVector l_partNumber(i_iterator,
364fa5e4d32SSunny Srivastava                                      i_iterator + constants::PART_NUM_LEN);
365fa5e4d32SSunny Srivastava 
366fa5e4d32SSunny Srivastava     advance(i_iterator, constants::PART_NUM_LEN);
367fa5e4d32SSunny Srivastava     types::BinaryVector l_serialNumber(i_iterator,
368fa5e4d32SSunny Srivastava                                        i_iterator + constants::SERIAL_NUM_LEN);
369fa5e4d32SSunny Srivastava 
370fa5e4d32SSunny Srivastava     advance(i_iterator, constants::SERIAL_NUM_LEN);
371fa5e4d32SSunny Srivastava     types::BinaryVector l_ccin(i_iterator, i_iterator + constants::CCIN_LEN);
372fa5e4d32SSunny Srivastava 
373e606f061SPriyanga Ramasamy     types::BinaryVector l_mfgId(DRAM_MANUFACTURER_ID_LENGTH);
374e606f061SPriyanga Ramasamy     std::copy_n((m_vpdVector.cbegin() + DRAM_MANUFACTURER_ID_OFFSET),
375e606f061SPriyanga Ramasamy                 DRAM_MANUFACTURER_ID_LENGTH, l_mfgId.begin());
376e606f061SPriyanga Ramasamy 
377fa5e4d32SSunny Srivastava     m_parsedVpdMap.emplace("FN", l_partNumber);
378fa5e4d32SSunny Srivastava     m_parsedVpdMap.emplace("PN", move(l_partNumber));
379fa5e4d32SSunny Srivastava     m_parsedVpdMap.emplace("SN", move(l_serialNumber));
380fa5e4d32SSunny Srivastava     m_parsedVpdMap.emplace("CC", move(l_ccin));
381e606f061SPriyanga Ramasamy     m_parsedVpdMap.emplace("DI", move(l_mfgId));
382fa5e4d32SSunny Srivastava }
383fa5e4d32SSunny Srivastava 
parse()384fa5e4d32SSunny Srivastava types::VPDMapVariant DdimmVpdParser::parse()
385fa5e4d32SSunny Srivastava {
386fa5e4d32SSunny Srivastava     try
387fa5e4d32SSunny Srivastava     {
388fa5e4d32SSunny Srivastava         // Read the data and return the map
389fa5e4d32SSunny Srivastava         auto l_iterator = m_vpdVector.cbegin();
390fa5e4d32SSunny Srivastava         readKeywords(l_iterator);
391fa5e4d32SSunny Srivastava         return m_parsedVpdMap;
392fa5e4d32SSunny Srivastava     }
393fa5e4d32SSunny Srivastava     catch (const std::exception& exp)
394fa5e4d32SSunny Srivastava     {
395fa5e4d32SSunny Srivastava         logging::logMessage(exp.what());
396fa5e4d32SSunny Srivastava         throw exp;
397fa5e4d32SSunny Srivastava     }
398fa5e4d32SSunny Srivastava }
399fa5e4d32SSunny Srivastava 
400fa5e4d32SSunny Srivastava } // namespace vpd
401