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