103c1d915SMatt Spinler #pragma once
203c1d915SMatt Spinler 
3aadccc85SMatt Spinler #include "data_interface.hpp"
4fdb6a202SMatt Spinler #include "elog_entry.hpp"
5ad0e0476SAatir Manzur #include "pel_values.hpp"
6fdb6a202SMatt Spinler #include "registry.hpp"
703c1d915SMatt Spinler #include "section.hpp"
803c1d915SMatt Spinler #include "stream.hpp"
903c1d915SMatt Spinler 
1003c1d915SMatt Spinler namespace openpower
1103c1d915SMatt Spinler {
1203c1d915SMatt Spinler namespace pels
1303c1d915SMatt Spinler {
1403c1d915SMatt Spinler 
151a94cc38SMatt Spinler static constexpr uint8_t userHeaderVersion = 0x01;
161f93c590SMatt Spinler static constexpr uint16_t actionFlagsDefault = 0xFFFF;
1703c1d915SMatt Spinler 
1803c1d915SMatt Spinler /**
1903c1d915SMatt Spinler  * @class UserHeader
2003c1d915SMatt Spinler  *
2103c1d915SMatt Spinler  * This represents the User Header section in a PEL.  It is required,
2203c1d915SMatt Spinler  * and it is always the second section.
2303c1d915SMatt Spinler  *
2403c1d915SMatt Spinler  * The Section base class handles the section header structure that every
2503c1d915SMatt Spinler  * PEL section has at offset zero.
2603c1d915SMatt Spinler  *
2703c1d915SMatt Spinler  * The fields in this class directly correspond to the order and sizes of
2803c1d915SMatt Spinler  * the fields in the section.
2903c1d915SMatt Spinler  */
3003c1d915SMatt Spinler class UserHeader : public Section
3103c1d915SMatt Spinler {
3203c1d915SMatt Spinler   public:
3303c1d915SMatt Spinler     UserHeader() = delete;
3403c1d915SMatt Spinler     ~UserHeader() = default;
3503c1d915SMatt Spinler     UserHeader(const UserHeader&) = default;
3603c1d915SMatt Spinler     UserHeader& operator=(const UserHeader&) = default;
3703c1d915SMatt Spinler     UserHeader(UserHeader&&) = default;
3803c1d915SMatt Spinler     UserHeader& operator=(UserHeader&&) = default;
3903c1d915SMatt Spinler 
4003c1d915SMatt Spinler     /**
4103c1d915SMatt Spinler      * @brief Constructor
4203c1d915SMatt Spinler      *
43fdb6a202SMatt Spinler      * Creates a valid UserHeader with the passed in data.
44fdb6a202SMatt Spinler      *
45fdb6a202SMatt Spinler      * @param[in] entry - The message registry entry for this error
46fdb6a202SMatt Spinler      * @param[in] severity - The OpenBMC event log severity for this error
476b3f345bSVijay Lobo      * @param[in] additionalData - The AdditionalData properties in this
486b3f345bSVijay Lobo      *                             error log
49aadccc85SMatt Spinler      * @param[in] dataIface - The DataInterface object
50fdb6a202SMatt Spinler      */
51fdb6a202SMatt Spinler     UserHeader(const message::Entry& entry,
52aadccc85SMatt Spinler                phosphor::logging::Entry::Level severity,
536b3f345bSVijay Lobo                const AdditionalData& additionalData,
54aadccc85SMatt Spinler                const DataInterfaceBase& dataIface);
55fdb6a202SMatt Spinler 
56fdb6a202SMatt Spinler     /**
57fdb6a202SMatt Spinler      * @brief Constructor
58fdb6a202SMatt Spinler      *
5903c1d915SMatt Spinler      * Fills in this class's data fields from the stream.
6003c1d915SMatt Spinler      *
6103c1d915SMatt Spinler      * @param[in] pel - the PEL data stream
6203c1d915SMatt Spinler      */
6303c1d915SMatt Spinler     explicit UserHeader(Stream& pel);
6403c1d915SMatt Spinler 
6503c1d915SMatt Spinler     /**
66cf5a8d0fSMatt Spinler      * @brief Flatten the section into the stream
67cf5a8d0fSMatt Spinler      *
68cf5a8d0fSMatt Spinler      * @param[in] stream - The stream to write to
69cf5a8d0fSMatt Spinler      */
700688545bSMatt Spinler     void flatten(Stream& stream) const override;
71cf5a8d0fSMatt Spinler 
72cf5a8d0fSMatt Spinler     /**
7303c1d915SMatt Spinler      * @brief Returns the subsystem field.
7403c1d915SMatt Spinler      *
7597d19b48SMatt Spinler      * @return uint8_t - the subsystem
7603c1d915SMatt Spinler      */
subsystem() const7797d19b48SMatt Spinler     uint8_t subsystem() const
7803c1d915SMatt Spinler     {
7903c1d915SMatt Spinler         return _eventSubsystem;
8003c1d915SMatt Spinler     }
8103c1d915SMatt Spinler 
8203c1d915SMatt Spinler     /**
8303c1d915SMatt Spinler      * @brief Returns the event scope field.
8403c1d915SMatt Spinler      *
8597d19b48SMatt Spinler      * @return uint8_t - the event scope
8603c1d915SMatt Spinler      */
scope() const8797d19b48SMatt Spinler     uint8_t scope() const
8803c1d915SMatt Spinler     {
8903c1d915SMatt Spinler         return _eventScope;
9003c1d915SMatt Spinler     }
9103c1d915SMatt Spinler 
9203c1d915SMatt Spinler     /**
9303c1d915SMatt Spinler      * @brief Returns the severity field.
9403c1d915SMatt Spinler      *
9597d19b48SMatt Spinler      * @return uint8_t - the severity
9603c1d915SMatt Spinler      */
severity() const9797d19b48SMatt Spinler     uint8_t severity() const
9803c1d915SMatt Spinler     {
9903c1d915SMatt Spinler         return _eventSeverity;
10003c1d915SMatt Spinler     }
10103c1d915SMatt Spinler 
10203c1d915SMatt Spinler     /**
10303c1d915SMatt Spinler      * @brief Returns the event type field.
10403c1d915SMatt Spinler      *
10597d19b48SMatt Spinler      * @return uint8_t - the event type
10603c1d915SMatt Spinler      */
eventType() const10797d19b48SMatt Spinler     uint8_t eventType() const
10803c1d915SMatt Spinler     {
10903c1d915SMatt Spinler         return _eventType;
11003c1d915SMatt Spinler     }
11103c1d915SMatt Spinler 
11203c1d915SMatt Spinler     /**
113f1e85e20SMatt Spinler      * @brief Set the event type field
114f1e85e20SMatt Spinler      *
115f1e85e20SMatt Spinler      * @param[in] type - the new event type
116f1e85e20SMatt Spinler      */
setEventType(uint8_t type)117f1e85e20SMatt Spinler     void setEventType(uint8_t type)
118f1e85e20SMatt Spinler     {
119f1e85e20SMatt Spinler         _eventType = type;
120f1e85e20SMatt Spinler     }
121f1e85e20SMatt Spinler 
122f1e85e20SMatt Spinler     /**
12303c1d915SMatt Spinler      * @brief Returns the problem domain field.
12403c1d915SMatt Spinler      *
12597d19b48SMatt Spinler      * @return uint8_t - the problem domain
12603c1d915SMatt Spinler      */
problemDomain() const12797d19b48SMatt Spinler     uint8_t problemDomain() const
12803c1d915SMatt Spinler     {
12903c1d915SMatt Spinler         return _problemDomain;
13003c1d915SMatt Spinler     }
13103c1d915SMatt Spinler 
13203c1d915SMatt Spinler     /**
13303c1d915SMatt Spinler      * @brief Returns the problem vector field.
13403c1d915SMatt Spinler      *
13597d19b48SMatt Spinler      * @return uint8_t - the problem vector
13603c1d915SMatt Spinler      */
problemVector() const13797d19b48SMatt Spinler     uint8_t problemVector() const
13803c1d915SMatt Spinler     {
13903c1d915SMatt Spinler         return _problemVector;
14003c1d915SMatt Spinler     }
14103c1d915SMatt Spinler 
14203c1d915SMatt Spinler     /**
14303c1d915SMatt Spinler      * @brief Returns the action flags field.
14403c1d915SMatt Spinler      *
14597d19b48SMatt Spinler      * @return uint16_t - the action flags
14603c1d915SMatt Spinler      */
actionFlags() const14797d19b48SMatt Spinler     uint16_t actionFlags() const
14803c1d915SMatt Spinler     {
14903c1d915SMatt Spinler         return _actionFlags;
15003c1d915SMatt Spinler     }
15103c1d915SMatt Spinler 
15203c1d915SMatt Spinler     /**
153f1e85e20SMatt Spinler      * @brief Sets the action flags field
154f1e85e20SMatt Spinler      *
155f1e85e20SMatt Spinler      * @param[in] flags - the new action flags
156f1e85e20SMatt Spinler      */
setActionFlags(uint16_t flags)157f1e85e20SMatt Spinler     void setActionFlags(uint16_t flags)
158f1e85e20SMatt Spinler     {
159f1e85e20SMatt Spinler         _actionFlags = flags;
160f1e85e20SMatt Spinler     }
161f1e85e20SMatt Spinler 
162f1e85e20SMatt Spinler     /**
163eb111447SMatt Spinler      * @brief Returns the host transmission state
164eb111447SMatt Spinler      *
165eb111447SMatt Spinler      * @return uint8_t - the host transmission state
166eb111447SMatt Spinler      */
hostTransmissionState() const167eb111447SMatt Spinler     uint8_t hostTransmissionState() const
168eb111447SMatt Spinler     {
169eb111447SMatt Spinler         return _states & 0xFF;
170eb111447SMatt Spinler     }
171eb111447SMatt Spinler 
172eb111447SMatt Spinler     /**
173eb111447SMatt Spinler      * @brief Sets the host transmission state
174eb111447SMatt Spinler      *
175eb111447SMatt Spinler      * @param[in] state - the new state
176eb111447SMatt Spinler      */
setHostTransmissionState(uint8_t state)177eb111447SMatt Spinler     void setHostTransmissionState(uint8_t state)
178eb111447SMatt Spinler     {
179eb111447SMatt Spinler         _states &= 0xFFFFFF00;
180eb111447SMatt Spinler         _states |= state;
181eb111447SMatt Spinler     }
182eb111447SMatt Spinler 
183eb111447SMatt Spinler     /**
184eb111447SMatt Spinler      * @brief Returns the HMC transmission state
185eb111447SMatt Spinler      *
186eb111447SMatt Spinler      * (HMC = Hardware Management Console)
187eb111447SMatt Spinler      *
188eb111447SMatt Spinler      * @return uint8_t - the HMC transmission state
189eb111447SMatt Spinler      */
hmcTransmissionState() const190eb111447SMatt Spinler     uint8_t hmcTransmissionState() const
191eb111447SMatt Spinler     {
192eb111447SMatt Spinler         return (_states & 0x0000FF00) >> 8;
193eb111447SMatt Spinler     }
194eb111447SMatt Spinler 
195eb111447SMatt Spinler     /**
196eb111447SMatt Spinler      * @brief Sets the HMC transmission state
197eb111447SMatt Spinler      *
198eb111447SMatt Spinler      * @param[in] state - the new state
199eb111447SMatt Spinler      */
setHMCTransmissionState(uint8_t state)200eb111447SMatt Spinler     void setHMCTransmissionState(uint8_t state)
201eb111447SMatt Spinler     {
202eb111447SMatt Spinler         uint32_t newState = state << 8;
203eb111447SMatt Spinler         _states &= 0xFFFF00FF;
204eb111447SMatt Spinler         _states |= newState;
205eb111447SMatt Spinler     }
206eb111447SMatt Spinler 
207eb111447SMatt Spinler     /**
20803c1d915SMatt Spinler      * @brief Returns the size of this section when flattened into a PEL
20903c1d915SMatt Spinler      *
21003c1d915SMatt Spinler      * @return size_t - the size of the section
21103c1d915SMatt Spinler      */
flattenedSize()21203c1d915SMatt Spinler     static constexpr size_t flattenedSize()
21303c1d915SMatt Spinler     {
21403c1d915SMatt Spinler         return Section::flattenedSize() + sizeof(_eventSubsystem) +
21503c1d915SMatt Spinler                sizeof(_eventScope) + sizeof(_eventSeverity) +
21603c1d915SMatt Spinler                sizeof(_eventType) + sizeof(_reserved4Byte1) +
21703c1d915SMatt Spinler                sizeof(_problemDomain) + sizeof(_problemVector) +
218eb111447SMatt Spinler                sizeof(_actionFlags) + sizeof(_states);
21903c1d915SMatt Spinler     }
22003c1d915SMatt Spinler 
221ad0e0476SAatir Manzur     /**
222ad0e0476SAatir Manzur      * @brief Get section in JSON.
223*b832aa5eSMatt Spinler      *
224*b832aa5eSMatt Spinler      * @param[in] creatorID - The creator ID for the PEL
225*b832aa5eSMatt Spinler      *
226c1489351SAatir      * @return std::optional<std::string> -User header section's JSON
227ad0e0476SAatir Manzur      */
228*b832aa5eSMatt Spinler     std::optional<std::string> getJSON(uint8_t creatorID) const override;
229ad0e0476SAatir Manzur 
23003c1d915SMatt Spinler   private:
23103c1d915SMatt Spinler     /**
232cf5a8d0fSMatt Spinler      * @brief Fills in the object from the stream data
233cf5a8d0fSMatt Spinler      *
234cf5a8d0fSMatt Spinler      * @param[in] stream - The stream to read from
235cf5a8d0fSMatt Spinler      */
236cf5a8d0fSMatt Spinler     void unflatten(Stream& stream);
237cf5a8d0fSMatt Spinler 
238cf5a8d0fSMatt Spinler     /**
23903c1d915SMatt Spinler      * @brief Validates the section contents
24003c1d915SMatt Spinler      *
24103c1d915SMatt Spinler      * Updates _valid (in Section) with the results.
24203c1d915SMatt Spinler      */
24303c1d915SMatt Spinler     void validate() override;
24403c1d915SMatt Spinler 
24503c1d915SMatt Spinler     /**
246aadccc85SMatt Spinler      * @brief Returns the severity value to use from the list
247aadccc85SMatt Spinler      *        of them passed in based on the system type.
248aadccc85SMatt Spinler      *
249aadccc85SMatt Spinler      * If there isn't an entry found for the current system
250aadccc85SMatt Spinler      * type then std::nullopt will be returned.
251aadccc85SMatt Spinler      *
252aadccc85SMatt Spinler      * @param[in] severities - The array of {systype, severity}
253aadccc85SMatt Spinler      *                         structures to find an entry in.
2541ab6696fSMatt Spinler      * @param[in] dataIface - The DataInterface object
255aadccc85SMatt Spinler      */
256aadccc85SMatt Spinler     std::optional<uint8_t>
257aadccc85SMatt Spinler         getSeverity(const std::vector<message::RegistrySeverity>& severities,
2581ab6696fSMatt Spinler                     const DataInterfaceBase& dataIface) const;
2591ab6696fSMatt Spinler 
260aadccc85SMatt Spinler     /**
26103c1d915SMatt Spinler      * @brief The subsystem associated with the event.
26203c1d915SMatt Spinler      */
26303c1d915SMatt Spinler     uint8_t _eventSubsystem;
26403c1d915SMatt Spinler 
26503c1d915SMatt Spinler     /**
26603c1d915SMatt Spinler      * @brief The event scope field.
26703c1d915SMatt Spinler      */
26803c1d915SMatt Spinler     uint8_t _eventScope;
26903c1d915SMatt Spinler 
27003c1d915SMatt Spinler     /**
27103c1d915SMatt Spinler      * @brief The event severity.
27203c1d915SMatt Spinler      */
27303c1d915SMatt Spinler     uint8_t _eventSeverity;
27403c1d915SMatt Spinler 
27503c1d915SMatt Spinler     /**
27603c1d915SMatt Spinler      * @brief The event type.
27703c1d915SMatt Spinler      */
27803c1d915SMatt Spinler     uint8_t _eventType;
27903c1d915SMatt Spinler 
28003c1d915SMatt Spinler     /**
28103c1d915SMatt Spinler      * @brief A reserved word placeholder
28203c1d915SMatt Spinler      */
28303c1d915SMatt Spinler     uint32_t _reserved4Byte1;
28403c1d915SMatt Spinler 
28503c1d915SMatt Spinler     /**
28603c1d915SMatt Spinler      * @brief The problem domain field.
28703c1d915SMatt Spinler      */
28803c1d915SMatt Spinler     uint8_t _problemDomain;
28903c1d915SMatt Spinler 
29003c1d915SMatt Spinler     /**
29103c1d915SMatt Spinler      * @brief The problem vector field.
29203c1d915SMatt Spinler      */
29303c1d915SMatt Spinler     uint8_t _problemVector;
29403c1d915SMatt Spinler 
29503c1d915SMatt Spinler     /**
29603c1d915SMatt Spinler      * @brief The action flags field.
29703c1d915SMatt Spinler      */
29803c1d915SMatt Spinler     uint16_t _actionFlags;
29903c1d915SMatt Spinler 
30003c1d915SMatt Spinler     /**
301eb111447SMatt Spinler      * @brief The second reserved word that we are
302eb111447SMatt Spinler      *        using for storing state information.
303eb111447SMatt Spinler      *
304eb111447SMatt Spinler      * 0x0000AABB
305eb111447SMatt Spinler      *   Where:
306eb111447SMatt Spinler      *      0xAA = HMC transmission state
307eb111447SMatt Spinler      *      0xBB = Host transmission state
30803c1d915SMatt Spinler      */
309eb111447SMatt Spinler     uint32_t _states;
31003c1d915SMatt Spinler };
31103c1d915SMatt Spinler 
31203c1d915SMatt Spinler } // namespace pels
31303c1d915SMatt Spinler } // namespace openpower
314