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