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      * @return std::optional<std::string> -User header section's JSON
224      */
225     std::optional<std::string> getJSON() const override;
226 
227   private:
228     /**
229      * @brief Fills in the object from the stream data
230      *
231      * @param[in] stream - The stream to read from
232      */
233     void unflatten(Stream& stream);
234 
235     /**
236      * @brief Validates the section contents
237      *
238      * Updates _valid (in Section) with the results.
239      */
240     void validate() override;
241 
242     /**
243      * @brief Returns the severity value to use from the list
244      *        of them passed in based on the system type.
245      *
246      * If there isn't an entry found for the current system
247      * type then std::nullopt will be returned.
248      *
249      * @param[in] severities - The array of {systype, severity}
250      *                         structures to find an entry in.
251      * @param[in] dataIface - The DataInterface object
252      */
253     std::optional<uint8_t>
254         getSeverity(const std::vector<message::RegistrySeverity>& severities,
255                     const DataInterfaceBase& dataIface) const;
256 
257     /**
258      * @brief The subsystem associated with the event.
259      */
260     uint8_t _eventSubsystem;
261 
262     /**
263      * @brief The event scope field.
264      */
265     uint8_t _eventScope;
266 
267     /**
268      * @brief The event severity.
269      */
270     uint8_t _eventSeverity;
271 
272     /**
273      * @brief The event type.
274      */
275     uint8_t _eventType;
276 
277     /**
278      * @brief A reserved word placeholder
279      */
280     uint32_t _reserved4Byte1;
281 
282     /**
283      * @brief The problem domain field.
284      */
285     uint8_t _problemDomain;
286 
287     /**
288      * @brief The problem vector field.
289      */
290     uint8_t _problemVector;
291 
292     /**
293      * @brief The action flags field.
294      */
295     uint16_t _actionFlags;
296 
297     /**
298      * @brief The second reserved word that we are
299      *        using for storing state information.
300      *
301      * 0x0000AABB
302      *   Where:
303      *      0xAA = HMC transmission state
304      *      0xBB = Host transmission state
305      */
306     uint32_t _states;
307 };
308 
309 } // namespace pels
310 } // namespace openpower
311