| Sunny Srivastava | fa5e4d3 | 2023-03-12 11:59:49 -0500 | [diff] [blame] | 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 | { | 
| Sunny Srivastava | 4c509c2 | 2025-03-25 12:43:40 +0530 | [diff] [blame] | 103 | throw std::runtime_error(std::string(__FUNCTION__) + | 
|  | 104 | "Empty VPD vector passed to parser factory"); | 
| Sunny Srivastava | fa5e4d3 | 2023-03-12 11:59:49 -0500 | [diff] [blame] | 105 | } | 
|  | 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 Srivastava | 4c509c2 | 2025-03-25 12:43:40 +0530 | [diff] [blame] | 138 | throw DataException( | 
|  | 139 | std::string(__FUNCTION__) + "Unable to determine VPD format"); | 
| Sunny Srivastava | fa5e4d3 | 2023-03-12 11:59:49 -0500 | [diff] [blame] | 140 | } | 
|  | 141 | } | 
|  | 142 | } // namespace vpd |