xref: /openbmc/openpower-vpd-parser/impl.hpp (revision f31a91bc)
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