#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 ParserFactory::getParser( const types::BinaryVector& i_vpdVector, const std::string& i_vpdFilePath, size_t i_vpdStartOffset) { if (i_vpdVector.empty()) { throw std::runtime_error("Empty VPD vector passed to parser factory"); } vpdType l_type = vpdTypeCheck(i_vpdVector); switch (l_type) { case vpdType::IPZ_VPD: { return std::make_shared(i_vpdVector, i_vpdFilePath, i_vpdStartOffset); } case vpdType::KEYWORD_VPD: { return std::make_shared(i_vpdVector); } case vpdType::DDR5_DDIMM_MEMORY_VPD: case vpdType::DDR4_DDIMM_MEMORY_VPD: { return std::make_shared(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(i_vpdVector); } default: throw DataException("Unable to determine VPD format"); } } } // namespace vpd