blob: b47c8ceefc4f4c0e2070b5ace28478754761ddda [file] [log] [blame]
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05001#include "parser_factory.hpp"
2
3#include "constants.hpp"
4#include "ddimm_parser.hpp"
5#include "exceptions.hpp"
6#include "ipz_parser.hpp"
7#include "isdimm_parser.hpp"
8#include "keyword_vpd_parser.hpp"
9
10namespace vpd
11{
12
13/**
14 * @brief Type of VPD formats.
15 */
16enum vpdType
17{
18 IPZ_VPD, /**< IPZ VPD type */
19 KEYWORD_VPD, /**< Keyword VPD type */
20 DDR4_DDIMM_MEMORY_VPD, /**< DDR4 DDIMM Memory VPD type */
21 DDR5_DDIMM_MEMORY_VPD, /**< DDR5 DDIMM Memory VPD type */
22 DDR4_ISDIMM_MEMORY_VPD, /**< DDR4 ISDIMM Memory VPD type */
23 DDR5_ISDIMM_MEMORY_VPD, /**< DDR5 ISDIMM Memory VPD type */
24 INVALID_VPD_FORMAT /**< Invalid VPD type */
25};
26
27/**
28 * @brief API to get the type of VPD.
29 *
30 * @param[in] i_vpdVector - VPD file content
31 *
32 * @return Type of VPD data, "INVALID_VPD_FORMAT" in case of unknown type.
33 */
34static vpdType vpdTypeCheck(const types::BinaryVector& i_vpdVector)
35{
36 if (i_vpdVector[constants::IPZ_DATA_START] == constants::IPZ_DATA_START_TAG)
37 {
38 return vpdType::IPZ_VPD;
39 }
40 else if (i_vpdVector[constants::KW_VPD_DATA_START] ==
41 constants::KW_VPD_START_TAG)
42 {
43 return vpdType::KEYWORD_VPD;
44 }
45 else if (((i_vpdVector[constants::SPD_BYTE_3] &
46 constants::SPD_BYTE_BIT_0_3_MASK) ==
47 constants::SPD_MODULE_TYPE_DDIMM))
48 {
49 std::string l_is11SFormat;
50 if (i_vpdVector.size() > (constants::DDIMM_11S_BARCODE_START +
51 constants::DDIMM_11S_BARCODE_LEN))
52 {
53 // Read first 3 Bytes to check the 11S bar code format
54 for (uint8_t l_index = 0; l_index < constants::DDIMM_11S_FORMAT_LEN;
55 l_index++)
56 {
57 l_is11SFormat +=
58 i_vpdVector[constants::DDIMM_11S_BARCODE_START + l_index];
59 }
60 }
61
62 if (l_is11SFormat.compare(constants::DDIMM_11S_BARCODE_START_TAG) == 0)
63 {
64 // DDIMM memory VPD format
65 if ((i_vpdVector[constants::SPD_BYTE_2] &
66 constants::SPD_BYTE_MASK) == constants::SPD_DRAM_TYPE_DDR5)
67 {
68 return vpdType::DDR5_DDIMM_MEMORY_VPD;
69 }
70
71 if ((i_vpdVector[constants::SPD_BYTE_2] &
72 constants::SPD_BYTE_MASK) == constants::SPD_DRAM_TYPE_DDR4)
73 {
74 return vpdType::DDR4_DDIMM_MEMORY_VPD;
75 }
76 }
77
78 logging::logMessage("11S format is not found in the DDIMM VPD.");
79 return vpdType::INVALID_VPD_FORMAT;
80 }
81 else if ((i_vpdVector[constants::SPD_BYTE_2] & constants::SPD_BYTE_MASK) ==
82 constants::SPD_DRAM_TYPE_DDR5)
83 {
84 // ISDIMM memory VPD format
85 return vpdType::DDR5_ISDIMM_MEMORY_VPD;
86 }
87 else if ((i_vpdVector[constants::SPD_BYTE_2] & constants::SPD_BYTE_MASK) ==
88 constants::SPD_DRAM_TYPE_DDR4)
89 {
90 // ISDIMM memory VPD format
91 return vpdType::DDR4_ISDIMM_MEMORY_VPD;
92 }
93
94 return vpdType::INVALID_VPD_FORMAT;
95}
96
97std::shared_ptr<ParserInterface> ParserFactory::getParser(
98 const types::BinaryVector& i_vpdVector, const std::string& i_vpdFilePath,
99 size_t i_vpdStartOffset)
100{
101 if (i_vpdVector.empty())
102 {
Sunny Srivastava4c509c22025-03-25 12:43:40 +0530103 throw std::runtime_error(std::string(__FUNCTION__) +
104 "Empty VPD vector passed to parser factory");
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500105 }
106
107 vpdType l_type = vpdTypeCheck(i_vpdVector);
108
109 switch (l_type)
110 {
111 case vpdType::IPZ_VPD:
112 {
113 return std::make_shared<IpzVpdParser>(i_vpdVector, i_vpdFilePath,
114 i_vpdStartOffset);
115 }
116
117 case vpdType::KEYWORD_VPD:
118 {
119 return std::make_shared<KeywordVpdParser>(i_vpdVector);
120 }
121
122 case vpdType::DDR5_DDIMM_MEMORY_VPD:
123 case vpdType::DDR4_DDIMM_MEMORY_VPD:
124 {
125 return std::make_shared<DdimmVpdParser>(i_vpdVector);
126 }
127
128 case vpdType::DDR4_ISDIMM_MEMORY_VPD:
129 case vpdType::DDR5_ISDIMM_MEMORY_VPD:
130 {
131 // return shared pointer to class object.
132 logging::logMessage(
133 "ISDIMM parser selected for VPD path: " + i_vpdFilePath);
134 return std::make_shared<JedecSpdParser>(i_vpdVector);
135 }
136
137 default:
Sunny Srivastava4c509c22025-03-25 12:43:40 +0530138 throw DataException(
139 std::string(__FUNCTION__) + "Unable to determine VPD format");
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500140 }
141}
142} // namespace vpd