xref: /openbmc/openpower-vpd-parser/impl.hpp (revision 26a74af7)
1 #pragma once
2 
3 #include "store.hpp"
4 
5 #include <cstddef>
6 
7 namespace openpower
8 {
9 namespace vpd
10 {
11 namespace parser
12 {
13 namespace keyword
14 {
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(Binary&& vpdBuffer) : vpd(std::move(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   private:
82     /** @brief Process the table of contents record, VHDR
83      *
84      *  @returns List of offsets to records in VPD
85      */
86     internal::OffsetList readTOC() const;
87 
88     /** @brief Read the PT keyword contained in the VHDR record,
89      *         to obtain offsets to other records in the VPD.
90      *
91      *  @param[in] iterator - iterator to buffer containing VPD
92      *  @param[in] ptLength - Length of PT keyword data
93      *
94      *  @returns List of offsets to records in VPD
95      */
96     internal::OffsetList readPT(Binary::const_iterator iterator,
97                                 std::size_t ptLen) const;
98 
99     /** @brief Read VPD information contained within a record
100      *
101      *  @param[in] recordOffset - offset to a record location
102      *      within the binary VPD
103      */
104     void processRecord(std::size_t recordOffset);
105 
106     /** @brief Read keyword data
107      *
108      *  @param[in] keyword - VPD keyword
109      *  @param[in] dataLength - Length of data to be read
110      *  @param[in] iterator - iterator pointing to a Keyword's data in
111      *      the VPD
112      *
113      *  @returns keyword data as a string
114      */
115     std::string readKwData(const internal::KeywordInfo& keyword,
116                            std::size_t dataLength,
117                            Binary::const_iterator iterator);
118 
119     /** @brief While we're pointing at the keyword section of
120      *     a record in the VPD, this will read all contained
121      *     keywords and their values.
122      *
123      *  @param[in] iterator - iterator pointing to a Keyword in the VPD
124      *
125      *  @returns map of keyword:data
126      */
127     internal::KeywordMap readKeywords(Binary::const_iterator iterator);
128 
129     /** @brief Checks if the VHDR record is present in the VPD */
130     void checkHeader() const;
131 
132     /** @brief VPD in binary format */
133     Binary vpd;
134 
135     /** @brief parser output */
136     Parsed out;
137 };
138 
139 } // namespace parser
140 } // namespace vpd
141 } // namespace openpower
142