1 #pragma once
2 
3 #include "data_interface.hpp"
4 #include "elog_entry.hpp"
5 #include "pel_values.hpp"
6 #include "registry.hpp"
7 #include "section.hpp"
8 #include "stream.hpp"
9 
10 namespace openpower
11 {
12 namespace pels
13 {
14 
15 static constexpr uint8_t userHeaderVersion = 0x01;
16 static constexpr uint16_t actionFlagsDefault = 0xFFFF;
17 
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  */
30 class 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      *
43      * 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
47      * @param[in] additionalData - The AdditionalData properties in this
48      *                             error log
49      * @param[in] dataIface - The DataInterface object
50      */
51     UserHeader(const message::Entry& entry,
52                phosphor::logging::Entry::Level severity,
53                const AdditionalData& additionalData,
54                const DataInterfaceBase& dataIface);
55 
56     /**
57      * @brief Constructor
58      *
59      * Fills in this class's data fields from the stream.
60      *
61      * @param[in] pel - the PEL data stream
62      */
63     explicit UserHeader(Stream& pel);
64 
65     /**
66      * @brief Flatten the section into the stream
67      *
68      * @param[in] stream - The stream to write to
69      */
70     void flatten(Stream& stream) const override;
71 
72     /**
73      * @brief Returns the subsystem field.
74      *
75      * @return uint8_t - the subsystem
76      */
77     uint8_t subsystem() const
78     {
79         return _eventSubsystem;
80     }
81 
82     /**
83      * @brief Returns the event scope field.
84      *
85      * @return uint8_t - the event scope
86      */
87     uint8_t scope() const
88     {
89         return _eventScope;
90     }
91 
92     /**
93      * @brief Returns the severity field.
94      *
95      * @return uint8_t - the severity
96      */
97     uint8_t severity() const
98     {
99         return _eventSeverity;
100     }
101 
102     /**
103      * @brief Returns the event type field.
104      *
105      * @return uint8_t - the event type
106      */
107     uint8_t eventType() const
108     {
109         return _eventType;
110     }
111 
112     /**
113      * @brief Set the event type field
114      *
115      * @param[in] type - the new event type
116      */
117     void setEventType(uint8_t type)
118     {
119         _eventType = type;
120     }
121 
122     /**
123      * @brief Returns the problem domain field.
124      *
125      * @return uint8_t - the problem domain
126      */
127     uint8_t problemDomain() const
128     {
129         return _problemDomain;
130     }
131 
132     /**
133      * @brief Returns the problem vector field.
134      *
135      * @return uint8_t - the problem vector
136      */
137     uint8_t problemVector() const
138     {
139         return _problemVector;
140     }
141 
142     /**
143      * @brief Returns the action flags field.
144      *
145      * @return uint16_t - the action flags
146      */
147     uint16_t actionFlags() const
148     {
149         return _actionFlags;
150     }
151 
152     /**
153      * @brief Sets the action flags field
154      *
155      * @param[in] flags - the new action flags
156      */
157     void setActionFlags(uint16_t flags)
158     {
159         _actionFlags = flags;
160     }
161 
162     /**
163      * @brief Returns the host transmission state
164      *
165      * @return uint8_t - the host transmission state
166      */
167     uint8_t hostTransmissionState() const
168     {
169         return _states & 0xFF;
170     }
171 
172     /**
173      * @brief Sets the host transmission state
174      *
175      * @param[in] state - the new state
176      */
177     void setHostTransmissionState(uint8_t state)
178     {
179         _states &= 0xFFFFFF00;
180         _states |= state;
181     }
182 
183     /**
184      * @brief Returns the HMC transmission state
185      *
186      * (HMC = Hardware Management Console)
187      *
188      * @return uint8_t - the HMC transmission state
189      */
190     uint8_t hmcTransmissionState() const
191     {
192         return (_states & 0x0000FF00) >> 8;
193     }
194 
195     /**
196      * @brief Sets the HMC transmission state
197      *
198      * @param[in] state - the new state
199      */
200     void setHMCTransmissionState(uint8_t state)
201     {
202         uint32_t newState = state << 8;
203         _states &= 0xFFFF00FF;
204         _states |= newState;
205     }
206 
207     /**
208      * @brief Returns the size of this section when flattened into a PEL
209      *
210      * @return size_t - the size of the section
211      */
212     static constexpr size_t flattenedSize()
213     {
214         return Section::flattenedSize() + sizeof(_eventSubsystem) +
215                sizeof(_eventScope) + sizeof(_eventSeverity) +
216                sizeof(_eventType) + sizeof(_reserved4Byte1) +
217                sizeof(_problemDomain) + sizeof(_problemVector) +
218                sizeof(_actionFlags) + sizeof(_states);
219     }
220 
221     /**
222      * @brief Get section in JSON.
223      *
224      * @param[in] creatorID - The creator ID for the PEL
225      *
226      * @return std::optional<std::string> -User header section's JSON
227      */
228     std::optional<std::string> getJSON(uint8_t creatorID) const override;
229 
230   private:
231     /**
232      * @brief Fills in the object from the stream data
233      *
234      * @param[in] stream - The stream to read from
235      */
236     void unflatten(Stream& stream);
237 
238     /**
239      * @brief Validates the section contents
240      *
241      * Updates _valid (in Section) with the results.
242      */
243     void validate() override;
244 
245     /**
246      * @brief Returns the severity value to use from the list
247      *        of them passed in based on the system type.
248      *
249      * If there isn't an entry found for the current system
250      * type then std::nullopt will be returned.
251      *
252      * @param[in] severities - The array of {systype, severity}
253      *                         structures to find an entry in.
254      * @param[in] dataIface - The DataInterface object
255      */
256     std::optional<uint8_t>
257         getSeverity(const std::vector<message::RegistrySeverity>& severities,
258                     const DataInterfaceBase& dataIface) const;
259 
260     /**
261      * @brief The subsystem associated with the event.
262      */
263     uint8_t _eventSubsystem;
264 
265     /**
266      * @brief The event scope field.
267      */
268     uint8_t _eventScope;
269 
270     /**
271      * @brief The event severity.
272      */
273     uint8_t _eventSeverity;
274 
275     /**
276      * @brief The event type.
277      */
278     uint8_t _eventType;
279 
280     /**
281      * @brief A reserved word placeholder
282      */
283     uint32_t _reserved4Byte1;
284 
285     /**
286      * @brief The problem domain field.
287      */
288     uint8_t _problemDomain;
289 
290     /**
291      * @brief The problem vector field.
292      */
293     uint8_t _problemVector;
294 
295     /**
296      * @brief The action flags field.
297      */
298     uint16_t _actionFlags;
299 
300     /**
301      * @brief The second reserved word that we are
302      *        using for storing state information.
303      *
304      * 0x0000AABB
305      *   Where:
306      *      0xAA = HMC transmission state
307      *      0xBB = Host transmission state
308      */
309     uint32_t _states;
310 };
311 
312 } // namespace pels
313 } // namespace openpower
314