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