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 */ 71 explicit Impl(const Binary& vpdBuffer) : vpd(vpdBuffer), out{} 72 { 73 } 74 75 /** @brief Run the parser on binary VPD 76 * 77 * @returns openpower::vpd::Store object 78 */ 79 Store run(); 80 81 /** @brief check if VPD header is valid 82 */ 83 void checkVPDHeader(); 84 85 /** @brief Read a specific VPD keyword from hardware. 86 * This api is to read a specific VPD keyword directly from hardware. 87 * @param[in] record - record name. 88 * @param[in] keyword - keyword name. 89 * @return keyword value. 90 */ 91 std::string readKwFromHw(const std::string& record, 92 const std::string& keyword); 93 94 private: 95 /** @brief Process the table of contents record 96 * 97 * @param[in] iterator - iterator to buffer containing VPD 98 * @returns Size of the PT keyword in VTOC 99 */ 100 std::size_t readTOC(Binary::const_iterator& iterator) const; 101 102 /** @brief Read the PT keyword contained in the VHDR record, 103 * to obtain offsets to other records in the VPD. 104 * 105 * @param[in] iterator - iterator to buffer containing VPD 106 * @param[in] ptLength - Length of PT keyword data 107 * 108 * @returns List of offsets to records in VPD 109 */ 110 internal::OffsetList readPT(Binary::const_iterator iterator, 111 std::size_t ptLen) const; 112 113 /** @brief Read VPD information contained within a record 114 * 115 * @param[in] recordOffset - offset to a record location 116 * within the binary VPD 117 */ 118 void processRecord(std::size_t recordOffset); 119 120 /** @brief Read keyword data 121 * 122 * @param[in] keyword - VPD keyword 123 * @param[in] dataLength - Length of data to be read 124 * @param[in] iterator - iterator pointing to a Keyword's data in 125 * the VPD 126 * 127 * @returns keyword data as a string 128 */ 129 std::string readKwData(const internal::KeywordInfo& keyword, 130 std::size_t dataLength, 131 Binary::const_iterator iterator); 132 133 /** @brief While we're pointing at the keyword section of 134 * a record in the VPD, this will read all contained 135 * keywords and their values. 136 * 137 * @param[in] iterator - iterator pointing to a Keyword in the VPD 138 * 139 * @returns map of keyword:data 140 */ 141 internal::KeywordMap readKeywords(Binary::const_iterator iterator); 142 143 /** @brief Checks if the VHDR record is present in the VPD */ 144 void checkHeader() const; 145 146 /** @brief Checks the ECC for VHDR Record. 147 * @returns Success(0) OR corrupted data(-1) 148 */ 149 int vhdrEccCheck() const; 150 151 /** @brief Checks the ECC for VTOC Record. 152 * @returns Success(0) OR corrupted data(-1) 153 */ 154 int vtocEccCheck() const; 155 156 /** @brief Checks the ECC for the given record. 157 * 158 * @param[in] iterator - iterator pointing to a record in the VPD 159 * @returns Success(0) OR corrupted data(-1) 160 */ 161 int recordEccCheck(Binary::const_iterator iterator) const; 162 163 /** @brief This interface collects Offset of VTOC 164 * @returns VTOC Offset 165 */ 166 openpower::vpd::constants::RecordOffset getVtocOffset() const; 167 168 /** @brief VPD in binary format */ 169 const Binary& vpd; 170 171 /** @brief parser output */ 172 Parsed out; 173 }; 174 175 } // namespace parser 176 } // namespace vpd 177 } // namespace openpower