blob: 365f12b54a7be54230198f6e4738fdafd82cbd50 [file] [log] [blame]
Matt Spinlerf9bae182019-10-09 13:37:38 -05001#pragma once
2
3#include "additional_data.hpp"
4#include "ascii_string.hpp"
5#include "callouts.hpp"
6#include "pel_types.hpp"
7#include "section.hpp"
8#include "stream.hpp"
9
10namespace openpower
11{
12namespace pels
13{
14
15constexpr size_t numSRCHexDataWords = 8;
16constexpr uint8_t srcSectionVersion = 0x02;
17
18/**
19 * @class SRC
20 *
21 * SRC stands for System Reference Code.
22 *
23 * This class represents the SRC sections in the PEL, of which there are 2:
24 * primary SRC and secondary SRC. These are the same structurally, the
25 * difference is that the primary SRC must be the 3rd section in the PEL if
26 * present and there is only one of them, and the secondary SRC sections are
27 * optional and there can be more than one (by definition, for there to be a
28 * secondary SRC, a primary SRC must also exist).
29 *
30 * This section consists of:
31 * - An 8B header (Has the version, flags, hexdata word count, and size fields)
32 * - 8 4B words of hex data
33 * - An ASCII character string
34 * - An optional subsection for Callouts
35 */
36class SRC : public Section
37{
38 public:
39 enum HeaderFlags
40 {
41 additionalSections = 0x01
42 };
43
44 SRC() = delete;
45 ~SRC() = default;
46 SRC(const SRC&) = delete;
47 SRC& operator=(const SRC&) = delete;
48 SRC(SRC&&) = delete;
49 SRC& operator=(SRC&&) = delete;
50
51 /**
52 * @brief Constructor
53 *
54 * Fills in this class's data fields from the stream.
55 *
56 * @param[in] pel - the PEL data stream
57 */
58 explicit SRC(Stream& pel);
59
60 /**
61 * @brief Flatten the section into the stream
62 *
63 * @param[in] stream - The stream to write to
64 */
65 void flatten(Stream& stream) override;
66
67 /**
68 * @brief Returns the SRC version, which is a different field
69 * than the version byte in the section header.
70 *
71 * @return uint8_t
72 */
73 uint8_t version() const
74 {
75 return _version;
76 }
77
78 /**
79 * @brief Returns the flags byte
80 *
81 * @return uint8_t
82 */
83 uint8_t flags() const
84 {
85 return _flags;
86 }
87
88 /**
89 * @brief Returns the hex data word count.
90 *
91 * Even though there always 8 words, this returns 9 due to previous
92 * SRC version formats.
93 *
94 * @return uint8_t
95 */
96 uint8_t hexWordCount() const
97 {
98 return _wordCount;
99 }
100
101 /**
102 * @brief Returns the size of the SRC section, not including the header.
103 *
104 * @return uint16_t
105 */
106 uint16_t size() const
107 {
108 return _size;
109 }
110
111 /**
112 * @brief Returns the 8 hex data words.
113 *
114 * @return const std::array<uint32_t, numSRCHexDataWords>&
115 */
116 const std::array<uint32_t, numSRCHexDataWords>& hexwordData() const
117 {
118 return _hexData;
119 }
120
121 /**
122 * @brief Returns the ASCII string
123 *
124 * @return std::string
125 */
126 std::string asciiString() const
127 {
128 return _asciiString->get();
129 }
130
131 /**
132 * @brief Returns the callouts subsection
133 *
134 * If no callouts, this unique_ptr will be empty
135 *
136 * @return const std::unique_ptr<src::Callouts>&
137 */
138 const std::unique_ptr<src::Callouts>& callouts() const
139 {
140 return _callouts;
141 }
142
143 private:
144 /**
145 * @brief Fills in the object from the stream data
146 *
147 * @param[in] stream - The stream to read from
148 */
149 void unflatten(Stream& stream);
150
151 /**
152 * @brief Says if this SRC has additional subsections in it
153 *
154 * Note: The callouts section is the only possible subsection.
155 *
156 * @return bool
157 */
158 inline bool hasAdditionalSections() const
159 {
160 return _flags & static_cast<uint8_t>(HeaderFlags::additionalSections);
161 }
162
163 /**
164 * @brief Validates the section contents
165 *
166 * Updates _valid (in Section) with the results.
167 */
168 void validate() override;
169
170 /**
171 * @brief The SRC version field
172 */
173 uint8_t _version;
174
175 /**
176 * @brief The SRC flags field
177 */
178 uint8_t _flags;
179
180 /**
181 * @brief A byte of reserved data after the flags field
182 */
183 uint8_t _reserved1B;
184
185 /**
186 * @brief The hex data word count.
187 *
188 * To be compatible with previous versions of SRCs, this is
189 * number of hex words (8) + 1 = 9.
190 */
191 uint8_t _wordCount;
192
193 /**
194 * @brief Two bytes of reserved data after the hex word count
195 */
196 uint16_t _reserved2B;
197
198 /**
199 * @brief The total size of the SRC section, not including the section
200 * header.
201 */
202 uint16_t _size;
203
204 /**
205 * @brief The SRC 'hex words'.
206 *
207 * In the spec these are referred to as SRC words 2 - 9 as words 0 and 1
208 * are filled by the 8 bytes of fields from above.
209 */
210 std::array<uint32_t, numSRCHexDataWords> _hexData;
211
212 /**
213 * @brief The 32 byte ASCII character string of the SRC
214 *
215 * It is padded with spaces to fill the 32 bytes.
216 * An example is:
217 * "BD8D1234 "
218 *
219 * That first word is what is commonly referred to as the refcode, and
220 * sometimes also called an SRC.
221 */
222 std::unique_ptr<src::AsciiString> _asciiString;
223
224 /**
225 * @brief The callouts subsection.
226 *
227 * Optional and only created if there are callouts.
228 */
229 std::unique_ptr<src::Callouts> _callouts;
230};
231
232} // namespace pels
233} // namespace openpower