1 #pragma once 2 3 #include "const.hpp" 4 #include "store.hpp" 5 6 #include <cstddef> 7 8 namespace openpower 9 { 10 namespace vpd 11 { 12 namespace parser 13 { 14 namespace keyword 15 { 16 /** @brief Encoding scheme of a VPD keyword's data */ 17 enum class Encoding 18 { 19 ASCII, /**< data encoded in ascii */ 20 RAW, /**< raw data */ 21 // Keywords needing custom decoding 22 B1, /**< The keyword B1 needs to be decoded specially */ 23 MB, /**< Special decoding of MB meant for Build Date */ 24 UD /**< Special decoding of UD meant for UUID */ 25 }; 26 27 } // namespace keyword 28 29 namespace internal 30 { 31 32 using KeywordInfo = std::tuple<record::Keyword, keyword::Encoding>; 33 using OffsetList = std::vector<uint32_t>; 34 using KeywordMap = Parsed::mapped_type; 35 36 } // namespace internal 37 38 /** @class Impl 39 * @brief Implements parser for VPD 40 * 41 * An Impl object must be constructed by passing in VPD in 42 * binary format. To parse the VPD, call the run() method. The run() 43 * method returns an openpower::vpd::Store object, which contains 44 * parsed VPD, and provides access methods for the VPD. 45 * 46 * Following is the algorithm used to parse IPZ/OpenPower VPD: 47 * 1) Validate that the first record is VHDR, the header record. 48 * 2) From the VHDR record, get the offset of the VTOC record, 49 * which is the table of contents record. 50 * 3) Process the VTOC record - note offsets of supported records. 51 * 4) For each supported record : 52 * 4.1) Jump to record via offset. Add record name to parser output. 53 * 4.2) Process record - for each contained and supported keyword: 54 * 4.2.1) Note keyword name and value, associate this information to 55 * to the record noted in step 4.1). 56 */ 57 class Impl 58 { 59 public: 60 Impl() = delete; 61 Impl(const Impl&) = delete; 62 Impl& operator=(const Impl&) = delete; 63 Impl(Impl&&) = delete; 64 Impl& operator=(Impl&&) = delete; 65 ~Impl() = default; 66 67 /** @brief Construct an Impl 68 * 69 * @param[in] vpdBuffer - Binary VPD 70 * @param[in] path - To call out FRU in case of any PEL. 71 */ 72 Impl(const Binary& vpdBuffer, const std::string& path) : 73 vpd(vpdBuffer), inventoryPath(path), out{} 74 { 75 } 76 77 /** @brief Run the parser on binary VPD 78 * 79 * @returns openpower::vpd::Store object 80 */ 81 Store run(); 82 83 /** @brief check if VPD header is valid 84 */ 85 void checkVPDHeader(); 86 87 /** @brief Read a specific VPD keyword from hardware. 88 * This api is to read a specific VPD keyword directly from hardware. 89 * @param[in] record - record name. 90 * @param[in] keyword - keyword name. 91 * @return keyword value. 92 */ 93 std::string readKwFromHw(const std::string& record, 94 const std::string& keyword); 95 96 private: 97 /** @brief Process the table of contents record 98 * 99 * @param[in] iterator - iterator to buffer containing VPD 100 * @returns Size of the PT keyword in VTOC 101 */ 102 std::size_t readTOC(Binary::const_iterator& iterator) const; 103 104 /** @brief Read the PT keyword contained in the VHDR record, 105 * to obtain offsets to other records in the VPD. 106 * 107 * @param[in] iterator - iterator to buffer containing VPD 108 * @param[in] ptLength - Length of PT keyword data 109 * 110 * @returns List of offsets to records in VPD 111 */ 112 internal::OffsetList readPT(Binary::const_iterator iterator, 113 std::size_t ptLen) const; 114 115 /** @brief Read VPD information contained within a record 116 * 117 * @param[in] recordOffset - offset to a record location 118 * within the binary VPD 119 */ 120 void processRecord(std::size_t recordOffset); 121 122 /** @brief Read keyword data 123 * 124 * @param[in] keyword - VPD keyword 125 * @param[in] dataLength - Length of data to be read 126 * @param[in] iterator - iterator pointing to a Keyword's data in 127 * the VPD 128 * 129 * @returns keyword data as a string 130 */ 131 std::string readKwData(const internal::KeywordInfo& keyword, 132 std::size_t dataLength, 133 Binary::const_iterator iterator); 134 135 /** @brief While we're pointing at the keyword section of 136 * a record in the VPD, this will read all contained 137 * keywords and their values. 138 * 139 * @param[in] iterator - iterator pointing to a Keyword in the VPD 140 * 141 * @returns map of keyword:data 142 */ 143 internal::KeywordMap readKeywords(Binary::const_iterator iterator); 144 145 /** @brief Checks if the VHDR record is present in the VPD */ 146 void checkHeader() const; 147 148 /** @brief Checks the ECC for VHDR Record. 149 * @returns Success(0) OR corrupted data(-1) 150 */ 151 int vhdrEccCheck() const; 152 153 /** @brief Checks the ECC for VTOC Record. 154 * @returns Success(0) OR corrupted data(-1) 155 */ 156 int vtocEccCheck() const; 157 158 /** @brief Checks the ECC for the given record. 159 * 160 * @param[in] iterator - iterator pointing to a record in the VPD 161 * @returns Success(0) OR corrupted data(-1) 162 */ 163 int recordEccCheck(Binary::const_iterator iterator) const; 164 165 /** @brief This interface collects Offset of VTOC 166 * @returns VTOC Offset 167 */ 168 openpower::vpd::constants::RecordOffset getVtocOffset() const; 169 170 /** @brief VPD in binary format */ 171 const Binary& vpd; 172 173 /** Inventory path to call out FRU if required */ 174 const std::string inventoryPath; 175 176 /** @brief parser output */ 177 Parsed out; 178 }; 179 180 } // namespace parser 181 } // namespace vpd 182 } // namespace openpower