1 #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 10 namespace vpd 11 { 12 13 /** 14 * @brief Type of VPD formats. 15 */ 16 enum 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 */ 34 static 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 97 std::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 { 103 throw std::runtime_error("Empty VPD vector passed to parser factory"); 104 } 105 106 vpdType l_type = vpdTypeCheck(i_vpdVector); 107 108 switch (l_type) 109 { 110 case vpdType::IPZ_VPD: 111 { 112 return std::make_shared<IpzVpdParser>(i_vpdVector, i_vpdFilePath, 113 i_vpdStartOffset); 114 } 115 116 case vpdType::KEYWORD_VPD: 117 { 118 return std::make_shared<KeywordVpdParser>(i_vpdVector); 119 } 120 121 case vpdType::DDR5_DDIMM_MEMORY_VPD: 122 case vpdType::DDR4_DDIMM_MEMORY_VPD: 123 { 124 return std::make_shared<DdimmVpdParser>(i_vpdVector); 125 } 126 127 case vpdType::DDR4_ISDIMM_MEMORY_VPD: 128 case vpdType::DDR5_ISDIMM_MEMORY_VPD: 129 { 130 // return shared pointer to class object. 131 logging::logMessage( 132 "ISDIMM parser selected for VPD path: " + i_vpdFilePath); 133 return std::make_shared<JedecSpdParser>(i_vpdVector); 134 } 135 136 default: 137 throw DataException("Unable to determine VPD format"); 138 } 139 } 140 } // namespace vpd 141