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