blob: da9be6cee2adc68b47f7d5c5e16f864419c02c0d [file] [log] [blame]
Matt Spinler03c1d912019-07-10 14:12:15 -05001#pragma once
2
Matt Spinleraadccc82020-04-10 14:33:42 -05003#include "data_interface.hpp"
Matt Spinlerfdb6a202019-09-20 14:09:20 -05004#include "elog_entry.hpp"
Aatir Manzurad0e0472019-10-07 13:18:37 -05005#include "pel_values.hpp"
Matt Spinlerfdb6a202019-09-20 14:09:20 -05006#include "registry.hpp"
Matt Spinler03c1d912019-07-10 14:12:15 -05007#include "section.hpp"
8#include "stream.hpp"
9
10namespace openpower
11{
12namespace pels
13{
14
Matt Spinler1a94cc32019-09-11 13:32:12 -050015static constexpr uint8_t userHeaderVersion = 0x01;
Matt Spinler1f93c592020-09-10 10:43:08 -050016static constexpr uint16_t actionFlagsDefault = 0xFFFF;
Matt Spinler03c1d912019-07-10 14:12:15 -050017
18/**
19 * @class UserHeader
20 *
21 * This represents the User Header section in a PEL. It is required,
22 * and it is always the second section.
23 *
24 * The Section base class handles the section header structure that every
25 * PEL section has at offset zero.
26 *
27 * The fields in this class directly correspond to the order and sizes of
28 * the fields in the section.
29 */
30class UserHeader : public Section
31{
32 public:
33 UserHeader() = delete;
34 ~UserHeader() = default;
35 UserHeader(const UserHeader&) = default;
36 UserHeader& operator=(const UserHeader&) = default;
37 UserHeader(UserHeader&&) = default;
38 UserHeader& operator=(UserHeader&&) = default;
39
40 /**
41 * @brief Constructor
42 *
Matt Spinlerfdb6a202019-09-20 14:09:20 -050043 * Creates a valid UserHeader with the passed in data.
44 *
45 * @param[in] entry - The message registry entry for this error
46 * @param[in] severity - The OpenBMC event log severity for this error
Matt Spinleraadccc82020-04-10 14:33:42 -050047 * @param[in] dataIface - The DataInterface object
Matt Spinlerfdb6a202019-09-20 14:09:20 -050048 */
49 UserHeader(const message::Entry& entry,
Matt Spinleraadccc82020-04-10 14:33:42 -050050 phosphor::logging::Entry::Level severity,
51 const DataInterfaceBase& dataIface);
Matt Spinlerfdb6a202019-09-20 14:09:20 -050052
53 /**
54 * @brief Constructor
55 *
Matt Spinler03c1d912019-07-10 14:12:15 -050056 * Fills in this class's data fields from the stream.
57 *
58 * @param[in] pel - the PEL data stream
59 */
60 explicit UserHeader(Stream& pel);
61
62 /**
Matt Spinlercf5a8d02019-09-05 12:58:53 -050063 * @brief Flatten the section into the stream
64 *
65 * @param[in] stream - The stream to write to
66 */
Matt Spinler06885452019-11-06 10:35:42 -060067 void flatten(Stream& stream) const override;
Matt Spinlercf5a8d02019-09-05 12:58:53 -050068
69 /**
Matt Spinler03c1d912019-07-10 14:12:15 -050070 * @brief Returns the subsystem field.
71 *
Matt Spinler97d19b42019-10-29 11:34:03 -050072 * @return uint8_t - the subsystem
Matt Spinler03c1d912019-07-10 14:12:15 -050073 */
Matt Spinler97d19b42019-10-29 11:34:03 -050074 uint8_t subsystem() const
Matt Spinler03c1d912019-07-10 14:12:15 -050075 {
76 return _eventSubsystem;
77 }
78
79 /**
80 * @brief Returns the event scope field.
81 *
Matt Spinler97d19b42019-10-29 11:34:03 -050082 * @return uint8_t - the event scope
Matt Spinler03c1d912019-07-10 14:12:15 -050083 */
Matt Spinler97d19b42019-10-29 11:34:03 -050084 uint8_t scope() const
Matt Spinler03c1d912019-07-10 14:12:15 -050085 {
86 return _eventScope;
87 }
88
89 /**
90 * @brief Returns the severity field.
91 *
Matt Spinler97d19b42019-10-29 11:34:03 -050092 * @return uint8_t - the severity
Matt Spinler03c1d912019-07-10 14:12:15 -050093 */
Matt Spinler97d19b42019-10-29 11:34:03 -050094 uint8_t severity() const
Matt Spinler03c1d912019-07-10 14:12:15 -050095 {
96 return _eventSeverity;
97 }
98
99 /**
100 * @brief Returns the event type field.
101 *
Matt Spinler97d19b42019-10-29 11:34:03 -0500102 * @return uint8_t - the event type
Matt Spinler03c1d912019-07-10 14:12:15 -0500103 */
Matt Spinler97d19b42019-10-29 11:34:03 -0500104 uint8_t eventType() const
Matt Spinler03c1d912019-07-10 14:12:15 -0500105 {
106 return _eventType;
107 }
108
109 /**
Matt Spinlerf1e85e22019-11-01 11:31:31 -0500110 * @brief Set the event type field
111 *
112 * @param[in] type - the new event type
113 */
114 void setEventType(uint8_t type)
115 {
116 _eventType = type;
117 }
118
119 /**
Matt Spinler03c1d912019-07-10 14:12:15 -0500120 * @brief Returns the problem domain field.
121 *
Matt Spinler97d19b42019-10-29 11:34:03 -0500122 * @return uint8_t - the problem domain
Matt Spinler03c1d912019-07-10 14:12:15 -0500123 */
Matt Spinler97d19b42019-10-29 11:34:03 -0500124 uint8_t problemDomain() const
Matt Spinler03c1d912019-07-10 14:12:15 -0500125 {
126 return _problemDomain;
127 }
128
129 /**
130 * @brief Returns the problem vector field.
131 *
Matt Spinler97d19b42019-10-29 11:34:03 -0500132 * @return uint8_t - the problem vector
Matt Spinler03c1d912019-07-10 14:12:15 -0500133 */
Matt Spinler97d19b42019-10-29 11:34:03 -0500134 uint8_t problemVector() const
Matt Spinler03c1d912019-07-10 14:12:15 -0500135 {
136 return _problemVector;
137 }
138
139 /**
140 * @brief Returns the action flags field.
141 *
Matt Spinler97d19b42019-10-29 11:34:03 -0500142 * @return uint16_t - the action flags
Matt Spinler03c1d912019-07-10 14:12:15 -0500143 */
Matt Spinler97d19b42019-10-29 11:34:03 -0500144 uint16_t actionFlags() const
Matt Spinler03c1d912019-07-10 14:12:15 -0500145 {
146 return _actionFlags;
147 }
148
149 /**
Matt Spinlerf1e85e22019-11-01 11:31:31 -0500150 * @brief Sets the action flags field
151 *
152 * @param[in] flags - the new action flags
153 */
154 void setActionFlags(uint16_t flags)
155 {
156 _actionFlags = flags;
157 }
158
159 /**
Matt Spinlereb111442019-11-07 13:05:36 -0600160 * @brief Returns the host transmission state
161 *
162 * @return uint8_t - the host transmission state
163 */
164 uint8_t hostTransmissionState() const
165 {
166 return _states & 0xFF;
167 }
168
169 /**
170 * @brief Sets the host transmission state
171 *
172 * @param[in] state - the new state
173 */
174 void setHostTransmissionState(uint8_t state)
175 {
176 _states &= 0xFFFFFF00;
177 _states |= state;
178 }
179
180 /**
181 * @brief Returns the HMC transmission state
182 *
183 * (HMC = Hardware Management Console)
184 *
185 * @return uint8_t - the HMC transmission state
186 */
187 uint8_t hmcTransmissionState() const
188 {
189 return (_states & 0x0000FF00) >> 8;
190 }
191
192 /**
193 * @brief Sets the HMC transmission state
194 *
195 * @param[in] state - the new state
196 */
197 void setHMCTransmissionState(uint8_t state)
198 {
199 uint32_t newState = state << 8;
200 _states &= 0xFFFF00FF;
201 _states |= newState;
202 }
203
204 /**
Matt Spinler03c1d912019-07-10 14:12:15 -0500205 * @brief Returns the size of this section when flattened into a PEL
206 *
207 * @return size_t - the size of the section
208 */
209 static constexpr size_t flattenedSize()
210 {
211 return Section::flattenedSize() + sizeof(_eventSubsystem) +
212 sizeof(_eventScope) + sizeof(_eventSeverity) +
213 sizeof(_eventType) + sizeof(_reserved4Byte1) +
214 sizeof(_problemDomain) + sizeof(_problemVector) +
Matt Spinlereb111442019-11-07 13:05:36 -0600215 sizeof(_actionFlags) + sizeof(_states);
Matt Spinler03c1d912019-07-10 14:12:15 -0500216 }
217
Aatir Manzurad0e0472019-10-07 13:18:37 -0500218 /**
219 * @brief Get section in JSON.
Aatirc1489352019-12-09 13:13:20 -0600220 * @return std::optional<std::string> -User header section's JSON
Aatir Manzurad0e0472019-10-07 13:18:37 -0500221 */
222 std::optional<std::string> getJSON() const override;
223
Matt Spinler03c1d912019-07-10 14:12:15 -0500224 private:
225 /**
Matt Spinlercf5a8d02019-09-05 12:58:53 -0500226 * @brief Fills in the object from the stream data
227 *
228 * @param[in] stream - The stream to read from
229 */
230 void unflatten(Stream& stream);
231
232 /**
Matt Spinler03c1d912019-07-10 14:12:15 -0500233 * @brief Validates the section contents
234 *
235 * Updates _valid (in Section) with the results.
236 */
237 void validate() override;
238
239 /**
Matt Spinleraadccc82020-04-10 14:33:42 -0500240 * @brief Returns the severity value to use from the list
241 * of them passed in based on the system type.
242 *
243 * If there isn't an entry found for the current system
244 * type then std::nullopt will be returned.
245 *
246 * @param[in] severities - The array of {systype, severity}
247 * structures to find an entry in.
Matt Spinler1ab66962020-10-29 13:21:44 -0500248 * @param[in] dataIface - The DataInterface object
Matt Spinleraadccc82020-04-10 14:33:42 -0500249 */
250 std::optional<uint8_t>
251 getSeverity(const std::vector<message::RegistrySeverity>& severities,
Matt Spinler1ab66962020-10-29 13:21:44 -0500252 const DataInterfaceBase& dataIface) const;
253
Matt Spinleraadccc82020-04-10 14:33:42 -0500254 /**
Matt Spinler03c1d912019-07-10 14:12:15 -0500255 * @brief The subsystem associated with the event.
256 */
257 uint8_t _eventSubsystem;
258
259 /**
260 * @brief The event scope field.
261 */
262 uint8_t _eventScope;
263
264 /**
265 * @brief The event severity.
266 */
267 uint8_t _eventSeverity;
268
269 /**
270 * @brief The event type.
271 */
272 uint8_t _eventType;
273
274 /**
275 * @brief A reserved word placeholder
276 */
277 uint32_t _reserved4Byte1;
278
279 /**
280 * @brief The problem domain field.
281 */
282 uint8_t _problemDomain;
283
284 /**
285 * @brief The problem vector field.
286 */
287 uint8_t _problemVector;
288
289 /**
290 * @brief The action flags field.
291 */
292 uint16_t _actionFlags;
293
294 /**
Matt Spinlereb111442019-11-07 13:05:36 -0600295 * @brief The second reserved word that we are
296 * using for storing state information.
297 *
298 * 0x0000AABB
299 * Where:
300 * 0xAA = HMC transmission state
301 * 0xBB = Host transmission state
Matt Spinler03c1d912019-07-10 14:12:15 -0500302 */
Matt Spinlereb111442019-11-07 13:05:36 -0600303 uint32_t _states;
Matt Spinler03c1d912019-07-10 14:12:15 -0500304};
305
Matt Spinler03c1d912019-07-10 14:12:15 -0500306} // namespace pels
307} // namespace openpower