103c1d915SMatt Spinler #pragma once
203c1d915SMatt Spinler 
3fdb6a202SMatt Spinler #include "elog_entry.hpp"
4ad0e0476SAatir Manzur #include "pel_values.hpp"
5fdb6a202SMatt Spinler #include "registry.hpp"
603c1d915SMatt Spinler #include "section.hpp"
703c1d915SMatt Spinler #include "stream.hpp"
803c1d915SMatt Spinler 
903c1d915SMatt Spinler namespace openpower
1003c1d915SMatt Spinler {
1103c1d915SMatt Spinler namespace pels
1203c1d915SMatt Spinler {
1303c1d915SMatt Spinler 
141a94cc38SMatt Spinler static constexpr uint8_t userHeaderVersion = 0x01;
1503c1d915SMatt Spinler 
1603c1d915SMatt Spinler /**
1703c1d915SMatt Spinler  * @class UserHeader
1803c1d915SMatt Spinler  *
1903c1d915SMatt Spinler  * This represents the User Header section in a PEL.  It is required,
2003c1d915SMatt Spinler  * and it is always the second section.
2103c1d915SMatt Spinler  *
2203c1d915SMatt Spinler  * The Section base class handles the section header structure that every
2303c1d915SMatt Spinler  * PEL section has at offset zero.
2403c1d915SMatt Spinler  *
2503c1d915SMatt Spinler  * The fields in this class directly correspond to the order and sizes of
2603c1d915SMatt Spinler  * the fields in the section.
2703c1d915SMatt Spinler  */
2803c1d915SMatt Spinler class UserHeader : public Section
2903c1d915SMatt Spinler {
3003c1d915SMatt Spinler   public:
3103c1d915SMatt Spinler     UserHeader() = delete;
3203c1d915SMatt Spinler     ~UserHeader() = default;
3303c1d915SMatt Spinler     UserHeader(const UserHeader&) = default;
3403c1d915SMatt Spinler     UserHeader& operator=(const UserHeader&) = default;
3503c1d915SMatt Spinler     UserHeader(UserHeader&&) = default;
3603c1d915SMatt Spinler     UserHeader& operator=(UserHeader&&) = default;
3703c1d915SMatt Spinler 
3803c1d915SMatt Spinler     /**
3903c1d915SMatt Spinler      * @brief Constructor
4003c1d915SMatt Spinler      *
41fdb6a202SMatt Spinler      * Creates a valid UserHeader with the passed in data.
42fdb6a202SMatt Spinler      *
43fdb6a202SMatt Spinler      * @param[in] entry - The message registry entry for this error
44fdb6a202SMatt Spinler      * @param[in] severity - The OpenBMC event log severity for this error
45fdb6a202SMatt Spinler      */
46fdb6a202SMatt Spinler     UserHeader(const message::Entry& entry,
47fdb6a202SMatt Spinler                phosphor::logging::Entry::Level severity);
48fdb6a202SMatt Spinler 
49fdb6a202SMatt Spinler     /**
50fdb6a202SMatt Spinler      * @brief Constructor
51fdb6a202SMatt Spinler      *
5203c1d915SMatt Spinler      * Fills in this class's data fields from the stream.
5303c1d915SMatt Spinler      *
5403c1d915SMatt Spinler      * @param[in] pel - the PEL data stream
5503c1d915SMatt Spinler      */
5603c1d915SMatt Spinler     explicit UserHeader(Stream& pel);
5703c1d915SMatt Spinler 
5803c1d915SMatt Spinler     /**
59cf5a8d0fSMatt Spinler      * @brief Flatten the section into the stream
60cf5a8d0fSMatt Spinler      *
61cf5a8d0fSMatt Spinler      * @param[in] stream - The stream to write to
62cf5a8d0fSMatt Spinler      */
630688545bSMatt Spinler     void flatten(Stream& stream) const override;
64cf5a8d0fSMatt Spinler 
65cf5a8d0fSMatt Spinler     /**
6603c1d915SMatt Spinler      * @brief Returns the subsystem field.
6703c1d915SMatt Spinler      *
6897d19b48SMatt Spinler      * @return uint8_t - the subsystem
6903c1d915SMatt Spinler      */
7097d19b48SMatt Spinler     uint8_t subsystem() const
7103c1d915SMatt Spinler     {
7203c1d915SMatt Spinler         return _eventSubsystem;
7303c1d915SMatt Spinler     }
7403c1d915SMatt Spinler 
7503c1d915SMatt Spinler     /**
7603c1d915SMatt Spinler      * @brief Returns the event scope field.
7703c1d915SMatt Spinler      *
7897d19b48SMatt Spinler      * @return uint8_t - the event scope
7903c1d915SMatt Spinler      */
8097d19b48SMatt Spinler     uint8_t scope() const
8103c1d915SMatt Spinler     {
8203c1d915SMatt Spinler         return _eventScope;
8303c1d915SMatt Spinler     }
8403c1d915SMatt Spinler 
8503c1d915SMatt Spinler     /**
8603c1d915SMatt Spinler      * @brief Returns the severity field.
8703c1d915SMatt Spinler      *
8897d19b48SMatt Spinler      * @return uint8_t - the severity
8903c1d915SMatt Spinler      */
9097d19b48SMatt Spinler     uint8_t severity() const
9103c1d915SMatt Spinler     {
9203c1d915SMatt Spinler         return _eventSeverity;
9303c1d915SMatt Spinler     }
9403c1d915SMatt Spinler 
9503c1d915SMatt Spinler     /**
9603c1d915SMatt Spinler      * @brief Returns the event type field.
9703c1d915SMatt Spinler      *
9897d19b48SMatt Spinler      * @return uint8_t - the event type
9903c1d915SMatt Spinler      */
10097d19b48SMatt Spinler     uint8_t eventType() const
10103c1d915SMatt Spinler     {
10203c1d915SMatt Spinler         return _eventType;
10303c1d915SMatt Spinler     }
10403c1d915SMatt Spinler 
10503c1d915SMatt Spinler     /**
106f1e85e20SMatt Spinler      * @brief Set the event type field
107f1e85e20SMatt Spinler      *
108f1e85e20SMatt Spinler      * @param[in] type - the new event type
109f1e85e20SMatt Spinler      */
110f1e85e20SMatt Spinler     void setEventType(uint8_t type)
111f1e85e20SMatt Spinler     {
112f1e85e20SMatt Spinler         _eventType = type;
113f1e85e20SMatt Spinler     }
114f1e85e20SMatt Spinler 
115f1e85e20SMatt Spinler     /**
11603c1d915SMatt Spinler      * @brief Returns the problem domain field.
11703c1d915SMatt Spinler      *
11897d19b48SMatt Spinler      * @return uint8_t - the problem domain
11903c1d915SMatt Spinler      */
12097d19b48SMatt Spinler     uint8_t problemDomain() const
12103c1d915SMatt Spinler     {
12203c1d915SMatt Spinler         return _problemDomain;
12303c1d915SMatt Spinler     }
12403c1d915SMatt Spinler 
12503c1d915SMatt Spinler     /**
12603c1d915SMatt Spinler      * @brief Returns the problem vector field.
12703c1d915SMatt Spinler      *
12897d19b48SMatt Spinler      * @return uint8_t - the problem vector
12903c1d915SMatt Spinler      */
13097d19b48SMatt Spinler     uint8_t problemVector() const
13103c1d915SMatt Spinler     {
13203c1d915SMatt Spinler         return _problemVector;
13303c1d915SMatt Spinler     }
13403c1d915SMatt Spinler 
13503c1d915SMatt Spinler     /**
13603c1d915SMatt Spinler      * @brief Returns the action flags field.
13703c1d915SMatt Spinler      *
13897d19b48SMatt Spinler      * @return uint16_t - the action flags
13903c1d915SMatt Spinler      */
14097d19b48SMatt Spinler     uint16_t actionFlags() const
14103c1d915SMatt Spinler     {
14203c1d915SMatt Spinler         return _actionFlags;
14303c1d915SMatt Spinler     }
14403c1d915SMatt Spinler 
14503c1d915SMatt Spinler     /**
146f1e85e20SMatt Spinler      * @brief Sets the action flags field
147f1e85e20SMatt Spinler      *
148f1e85e20SMatt Spinler      * @param[in] flags - the new action flags
149f1e85e20SMatt Spinler      */
150f1e85e20SMatt Spinler     void setActionFlags(uint16_t flags)
151f1e85e20SMatt Spinler     {
152f1e85e20SMatt Spinler         _actionFlags = flags;
153f1e85e20SMatt Spinler     }
154f1e85e20SMatt Spinler 
155f1e85e20SMatt Spinler     /**
156*eb111447SMatt Spinler      * @brief Returns the host transmission state
157*eb111447SMatt Spinler      *
158*eb111447SMatt Spinler      * @return uint8_t - the host transmission state
159*eb111447SMatt Spinler      */
160*eb111447SMatt Spinler     uint8_t hostTransmissionState() const
161*eb111447SMatt Spinler     {
162*eb111447SMatt Spinler         return _states & 0xFF;
163*eb111447SMatt Spinler     }
164*eb111447SMatt Spinler 
165*eb111447SMatt Spinler     /**
166*eb111447SMatt Spinler      * @brief Sets the host transmission state
167*eb111447SMatt Spinler      *
168*eb111447SMatt Spinler      * @param[in] state - the new state
169*eb111447SMatt Spinler      */
170*eb111447SMatt Spinler     void setHostTransmissionState(uint8_t state)
171*eb111447SMatt Spinler     {
172*eb111447SMatt Spinler         _states &= 0xFFFFFF00;
173*eb111447SMatt Spinler         _states |= state;
174*eb111447SMatt Spinler     }
175*eb111447SMatt Spinler 
176*eb111447SMatt Spinler     /**
177*eb111447SMatt Spinler      * @brief Returns the HMC transmission state
178*eb111447SMatt Spinler      *
179*eb111447SMatt Spinler      * (HMC = Hardware Management Console)
180*eb111447SMatt Spinler      *
181*eb111447SMatt Spinler      * @return uint8_t - the HMC transmission state
182*eb111447SMatt Spinler      */
183*eb111447SMatt Spinler     uint8_t hmcTransmissionState() const
184*eb111447SMatt Spinler     {
185*eb111447SMatt Spinler         return (_states & 0x0000FF00) >> 8;
186*eb111447SMatt Spinler     }
187*eb111447SMatt Spinler 
188*eb111447SMatt Spinler     /**
189*eb111447SMatt Spinler      * @brief Sets the HMC transmission state
190*eb111447SMatt Spinler      *
191*eb111447SMatt Spinler      * @param[in] state - the new state
192*eb111447SMatt Spinler      */
193*eb111447SMatt Spinler     void setHMCTransmissionState(uint8_t state)
194*eb111447SMatt Spinler     {
195*eb111447SMatt Spinler         uint32_t newState = state << 8;
196*eb111447SMatt Spinler         _states &= 0xFFFF00FF;
197*eb111447SMatt Spinler         _states |= newState;
198*eb111447SMatt Spinler     }
199*eb111447SMatt Spinler 
200*eb111447SMatt Spinler     /**
20103c1d915SMatt Spinler      * @brief Returns the size of this section when flattened into a PEL
20203c1d915SMatt Spinler      *
20303c1d915SMatt Spinler      * @return size_t - the size of the section
20403c1d915SMatt Spinler      */
20503c1d915SMatt Spinler     static constexpr size_t flattenedSize()
20603c1d915SMatt Spinler     {
20703c1d915SMatt Spinler         return Section::flattenedSize() + sizeof(_eventSubsystem) +
20803c1d915SMatt Spinler                sizeof(_eventScope) + sizeof(_eventSeverity) +
20903c1d915SMatt Spinler                sizeof(_eventType) + sizeof(_reserved4Byte1) +
21003c1d915SMatt Spinler                sizeof(_problemDomain) + sizeof(_problemVector) +
211*eb111447SMatt Spinler                sizeof(_actionFlags) + sizeof(_states);
21203c1d915SMatt Spinler     }
21303c1d915SMatt Spinler 
214ad0e0476SAatir Manzur     /**
215ad0e0476SAatir Manzur      * @brief Get section in JSON.
216c1489351SAatir      * @return std::optional<std::string> -User header section's JSON
217ad0e0476SAatir Manzur      */
218ad0e0476SAatir Manzur     std::optional<std::string> getJSON() const override;
219ad0e0476SAatir Manzur 
22003c1d915SMatt Spinler   private:
22103c1d915SMatt Spinler     /**
222cf5a8d0fSMatt Spinler      * @brief Fills in the object from the stream data
223cf5a8d0fSMatt Spinler      *
224cf5a8d0fSMatt Spinler      * @param[in] stream - The stream to read from
225cf5a8d0fSMatt Spinler      */
226cf5a8d0fSMatt Spinler     void unflatten(Stream& stream);
227cf5a8d0fSMatt Spinler 
228cf5a8d0fSMatt Spinler     /**
22903c1d915SMatt Spinler      * @brief Validates the section contents
23003c1d915SMatt Spinler      *
23103c1d915SMatt Spinler      * Updates _valid (in Section) with the results.
23203c1d915SMatt Spinler      */
23303c1d915SMatt Spinler     void validate() override;
23403c1d915SMatt Spinler 
23503c1d915SMatt Spinler     /**
23603c1d915SMatt Spinler      * @brief The subsystem associated with the event.
23703c1d915SMatt Spinler      */
23803c1d915SMatt Spinler     uint8_t _eventSubsystem;
23903c1d915SMatt Spinler 
24003c1d915SMatt Spinler     /**
24103c1d915SMatt Spinler      * @brief The event scope field.
24203c1d915SMatt Spinler      */
24303c1d915SMatt Spinler     uint8_t _eventScope;
24403c1d915SMatt Spinler 
24503c1d915SMatt Spinler     /**
24603c1d915SMatt Spinler      * @brief The event severity.
24703c1d915SMatt Spinler      */
24803c1d915SMatt Spinler     uint8_t _eventSeverity;
24903c1d915SMatt Spinler 
25003c1d915SMatt Spinler     /**
25103c1d915SMatt Spinler      * @brief The event type.
25203c1d915SMatt Spinler      */
25303c1d915SMatt Spinler     uint8_t _eventType;
25403c1d915SMatt Spinler 
25503c1d915SMatt Spinler     /**
25603c1d915SMatt Spinler      * @brief A reserved word placeholder
25703c1d915SMatt Spinler      */
25803c1d915SMatt Spinler     uint32_t _reserved4Byte1;
25903c1d915SMatt Spinler 
26003c1d915SMatt Spinler     /**
26103c1d915SMatt Spinler      * @brief The problem domain field.
26203c1d915SMatt Spinler      */
26303c1d915SMatt Spinler     uint8_t _problemDomain;
26403c1d915SMatt Spinler 
26503c1d915SMatt Spinler     /**
26603c1d915SMatt Spinler      * @brief The problem vector field.
26703c1d915SMatt Spinler      */
26803c1d915SMatt Spinler     uint8_t _problemVector;
26903c1d915SMatt Spinler 
27003c1d915SMatt Spinler     /**
27103c1d915SMatt Spinler      * @brief The action flags field.
27203c1d915SMatt Spinler      */
27303c1d915SMatt Spinler     uint16_t _actionFlags;
27403c1d915SMatt Spinler 
27503c1d915SMatt Spinler     /**
276*eb111447SMatt Spinler      * @brief The second reserved word that we are
277*eb111447SMatt Spinler      *        using for storing state information.
278*eb111447SMatt Spinler      *
279*eb111447SMatt Spinler      * 0x0000AABB
280*eb111447SMatt Spinler      *   Where:
281*eb111447SMatt Spinler      *      0xAA = HMC transmission state
282*eb111447SMatt Spinler      *      0xBB = Host transmission state
28303c1d915SMatt Spinler      */
284*eb111447SMatt Spinler     uint32_t _states;
28503c1d915SMatt Spinler };
28603c1d915SMatt Spinler 
28703c1d915SMatt Spinler } // namespace pels
28803c1d915SMatt Spinler } // namespace openpower
289