| #include "parser_factory.hpp" |
| |
| #include "constants.hpp" |
| #include "ddimm_parser.hpp" |
| #include "exceptions.hpp" |
| #include "ipz_parser.hpp" |
| #include "isdimm_parser.hpp" |
| #include "keyword_vpd_parser.hpp" |
| |
| namespace vpd |
| { |
| |
| /** |
| * @brief Type of VPD formats. |
| */ |
| enum vpdType |
| { |
| IPZ_VPD, /**< IPZ VPD type */ |
| KEYWORD_VPD, /**< Keyword VPD type */ |
| DDR4_DDIMM_MEMORY_VPD, /**< DDR4 DDIMM Memory VPD type */ |
| DDR5_DDIMM_MEMORY_VPD, /**< DDR5 DDIMM Memory VPD type */ |
| DDR4_ISDIMM_MEMORY_VPD, /**< DDR4 ISDIMM Memory VPD type */ |
| DDR5_ISDIMM_MEMORY_VPD, /**< DDR5 ISDIMM Memory VPD type */ |
| INVALID_VPD_FORMAT /**< Invalid VPD type */ |
| }; |
| |
| /** |
| * @brief API to get the type of VPD. |
| * |
| * @param[in] i_vpdVector - VPD file content |
| * |
| * @return Type of VPD data, "INVALID_VPD_FORMAT" in case of unknown type. |
| */ |
| static vpdType vpdTypeCheck(const types::BinaryVector& i_vpdVector) |
| { |
| if (i_vpdVector[constants::IPZ_DATA_START] == constants::IPZ_DATA_START_TAG) |
| { |
| return vpdType::IPZ_VPD; |
| } |
| else if (i_vpdVector[constants::KW_VPD_DATA_START] == |
| constants::KW_VPD_START_TAG) |
| { |
| return vpdType::KEYWORD_VPD; |
| } |
| else if (((i_vpdVector[constants::SPD_BYTE_3] & |
| constants::SPD_BYTE_BIT_0_3_MASK) == |
| constants::SPD_MODULE_TYPE_DDIMM)) |
| { |
| std::string l_is11SFormat; |
| if (i_vpdVector.size() > (constants::DDIMM_11S_BARCODE_START + |
| constants::DDIMM_11S_BARCODE_LEN)) |
| { |
| // Read first 3 Bytes to check the 11S bar code format |
| for (uint8_t l_index = 0; l_index < constants::DDIMM_11S_FORMAT_LEN; |
| l_index++) |
| { |
| l_is11SFormat += |
| i_vpdVector[constants::DDIMM_11S_BARCODE_START + l_index]; |
| } |
| } |
| |
| if (l_is11SFormat.compare(constants::DDIMM_11S_BARCODE_START_TAG) == 0) |
| { |
| // DDIMM memory VPD format |
| if ((i_vpdVector[constants::SPD_BYTE_2] & |
| constants::SPD_BYTE_MASK) == constants::SPD_DRAM_TYPE_DDR5) |
| { |
| return vpdType::DDR5_DDIMM_MEMORY_VPD; |
| } |
| |
| if ((i_vpdVector[constants::SPD_BYTE_2] & |
| constants::SPD_BYTE_MASK) == constants::SPD_DRAM_TYPE_DDR4) |
| { |
| return vpdType::DDR4_DDIMM_MEMORY_VPD; |
| } |
| } |
| |
| logging::logMessage("11S format is not found in the DDIMM VPD."); |
| return vpdType::INVALID_VPD_FORMAT; |
| } |
| else if ((i_vpdVector[constants::SPD_BYTE_2] & constants::SPD_BYTE_MASK) == |
| constants::SPD_DRAM_TYPE_DDR5) |
| { |
| // ISDIMM memory VPD format |
| return vpdType::DDR5_ISDIMM_MEMORY_VPD; |
| } |
| else if ((i_vpdVector[constants::SPD_BYTE_2] & constants::SPD_BYTE_MASK) == |
| constants::SPD_DRAM_TYPE_DDR4) |
| { |
| // ISDIMM memory VPD format |
| return vpdType::DDR4_ISDIMM_MEMORY_VPD; |
| } |
| |
| return vpdType::INVALID_VPD_FORMAT; |
| } |
| |
| std::shared_ptr<ParserInterface> ParserFactory::getParser( |
| const types::BinaryVector& i_vpdVector, const std::string& i_vpdFilePath, |
| size_t i_vpdStartOffset) |
| { |
| if (i_vpdVector.empty()) |
| { |
| throw std::runtime_error(std::string(__FUNCTION__) + |
| "Empty VPD vector passed to parser factory"); |
| } |
| |
| vpdType l_type = vpdTypeCheck(i_vpdVector); |
| |
| switch (l_type) |
| { |
| case vpdType::IPZ_VPD: |
| { |
| return std::make_shared<IpzVpdParser>(i_vpdVector, i_vpdFilePath, |
| i_vpdStartOffset); |
| } |
| |
| case vpdType::KEYWORD_VPD: |
| { |
| return std::make_shared<KeywordVpdParser>(i_vpdVector); |
| } |
| |
| case vpdType::DDR5_DDIMM_MEMORY_VPD: |
| case vpdType::DDR4_DDIMM_MEMORY_VPD: |
| { |
| return std::make_shared<DdimmVpdParser>(i_vpdVector); |
| } |
| |
| case vpdType::DDR4_ISDIMM_MEMORY_VPD: |
| case vpdType::DDR5_ISDIMM_MEMORY_VPD: |
| { |
| // return shared pointer to class object. |
| logging::logMessage( |
| "ISDIMM parser selected for VPD path: " + i_vpdFilePath); |
| return std::make_shared<JedecSpdParser>(i_vpdVector); |
| } |
| |
| default: |
| throw DataException( |
| std::string(__FUNCTION__) + "Unable to determine VPD format"); |
| } |
| } |
| } // namespace vpd |