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