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] dataIface - The DataInterface object
48      */
49     UserHeader(const message::Entry& entry,
50                phosphor::logging::Entry::Level severity,
51                const DataInterfaceBase& dataIface);
52 
53     /**
54      * @brief Constructor
55      *
56      * 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     /**
63      * @brief Flatten the section into the stream
64      *
65      * @param[in] stream - The stream to write to
66      */
67     void flatten(Stream& stream) const override;
68 
69     /**
70      * @brief Returns the subsystem field.
71      *
72      * @return uint8_t - the subsystem
73      */
74     uint8_t subsystem() const
75     {
76         return _eventSubsystem;
77     }
78 
79     /**
80      * @brief Returns the event scope field.
81      *
82      * @return uint8_t - the event scope
83      */
84     uint8_t scope() const
85     {
86         return _eventScope;
87     }
88 
89     /**
90      * @brief Returns the severity field.
91      *
92      * @return uint8_t - the severity
93      */
94     uint8_t severity() const
95     {
96         return _eventSeverity;
97     }
98 
99     /**
100      * @brief Returns the event type field.
101      *
102      * @return uint8_t - the event type
103      */
104     uint8_t eventType() const
105     {
106         return _eventType;
107     }
108 
109     /**
110      * @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     /**
120      * @brief Returns the problem domain field.
121      *
122      * @return uint8_t - the problem domain
123      */
124     uint8_t problemDomain() const
125     {
126         return _problemDomain;
127     }
128 
129     /**
130      * @brief Returns the problem vector field.
131      *
132      * @return uint8_t - the problem vector
133      */
134     uint8_t problemVector() const
135     {
136         return _problemVector;
137     }
138 
139     /**
140      * @brief Returns the action flags field.
141      *
142      * @return uint16_t - the action flags
143      */
144     uint16_t actionFlags() const
145     {
146         return _actionFlags;
147     }
148 
149     /**
150      * @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     /**
160      * @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     /**
205      * @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) +
215                sizeof(_actionFlags) + sizeof(_states);
216     }
217 
218     /**
219      * @brief Get section in JSON.
220      * @return std::optional<std::string> -User header section's JSON
221      */
222     std::optional<std::string> getJSON() const override;
223 
224   private:
225     /**
226      * @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     /**
233      * @brief Validates the section contents
234      *
235      * Updates _valid (in Section) with the results.
236      */
237     void validate() override;
238 
239     /**
240      * @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.
248      * @param[in] dataIface - The DataInterface object
249      */
250     std::optional<uint8_t>
251         getSeverity(const std::vector<message::RegistrySeverity>& severities,
252                     const DataInterfaceBase& dataIface) const;
253 
254     /**
255      * @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     /**
295      * @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
302      */
303     uint32_t _states;
304 };
305 
306 } // namespace pels
307 } // namespace openpower
308