xref: /openbmc/phosphor-logging/extensions/openpower-pels/extended_user_data.hpp (revision bf27da63180a019a59db528a94100be955872681)
1386a61e6SMatt Spinler #pragma once
2386a61e6SMatt Spinler 
3386a61e6SMatt Spinler #include "section.hpp"
4386a61e6SMatt Spinler #include "stream.hpp"
5386a61e6SMatt Spinler 
6386a61e6SMatt Spinler namespace openpower::pels
7386a61e6SMatt Spinler {
8386a61e6SMatt Spinler 
9386a61e6SMatt Spinler /**
10386a61e6SMatt Spinler  * @class ExtendedUserData
11386a61e6SMatt Spinler  *
12386a61e6SMatt Spinler  * This represents the Extended User Data section in a PEL.  It is free form
13386a61e6SMatt Spinler  * data that the creator knows the contents of.  The component ID, version, and
14386a61e6SMatt Spinler  * sub-type fields in the section header are used to identify the format.
15386a61e6SMatt Spinler  *
16386a61e6SMatt Spinler  *  This section is used for one subsystem to add FFDC data to a PEL created
17386a61e6SMatt Spinler  *  by another subsystem.  It is basically the same as a UserData section,
18386a61e6SMatt Spinler  *  except it has the creator ID of the section creator stored in the section.
19386a61e6SMatt Spinler  *
20386a61e6SMatt Spinler  * The Section base class handles the section header structure that every
21386a61e6SMatt Spinler  * PEL section has at offset zero.
22386a61e6SMatt Spinler  */
23386a61e6SMatt Spinler class ExtendedUserData : public Section
24386a61e6SMatt Spinler {
25386a61e6SMatt Spinler   public:
26386a61e6SMatt Spinler     ExtendedUserData() = delete;
27362f469cSMatt Spinler     ~ExtendedUserData() override = default;
28386a61e6SMatt Spinler     ExtendedUserData(const ExtendedUserData&) = default;
29386a61e6SMatt Spinler     ExtendedUserData& operator=(const ExtendedUserData&) = default;
30386a61e6SMatt Spinler     ExtendedUserData(ExtendedUserData&&) = default;
31386a61e6SMatt Spinler     ExtendedUserData& operator=(ExtendedUserData&&) = default;
32386a61e6SMatt Spinler 
33386a61e6SMatt Spinler     /**
34386a61e6SMatt Spinler      * @brief Constructor
35386a61e6SMatt Spinler      *
36386a61e6SMatt Spinler      * Fills in this class's data fields from the stream.
37386a61e6SMatt Spinler      *
38386a61e6SMatt Spinler      * @param[in] pel - the PEL data stream
39386a61e6SMatt Spinler      */
40386a61e6SMatt Spinler     explicit ExtendedUserData(Stream& pel);
41386a61e6SMatt Spinler 
42386a61e6SMatt Spinler     /**
43386a61e6SMatt Spinler      * @brief Constructor
44386a61e6SMatt Spinler      *
45386a61e6SMatt Spinler      * Create a valid ExtendedUserData object with the passed in data.
46386a61e6SMatt Spinler      *
47386a61e6SMatt Spinler      * The component ID, subtype, and version are used to identify
48386a61e6SMatt Spinler      * the data to know which parser to call.
49386a61e6SMatt Spinler      *
50386a61e6SMatt Spinler      * @param[in] componentID - Component ID of the creator
51386a61e6SMatt Spinler      * @param[in] subType - The type of user data
52386a61e6SMatt Spinler      * @param[in] version - The version of the data
53386a61e6SMatt Spinler      */
54386a61e6SMatt Spinler     ExtendedUserData(uint16_t componentID, uint8_t subType, uint8_t version,
55386a61e6SMatt Spinler                      uint8_t creatorID, const std::vector<uint8_t>& data);
56386a61e6SMatt Spinler 
57386a61e6SMatt Spinler     /**
58386a61e6SMatt Spinler      * @brief Flatten the section into the stream
59386a61e6SMatt Spinler      *
60386a61e6SMatt Spinler      * @param[in] stream - The stream to write to
61386a61e6SMatt Spinler      */
62386a61e6SMatt Spinler     void flatten(Stream& stream) const override;
63386a61e6SMatt Spinler 
64386a61e6SMatt Spinler     /**
65386a61e6SMatt Spinler      * @brief Returns the size of this section when flattened into a PEL
66386a61e6SMatt Spinler      *
67386a61e6SMatt Spinler      * @return size_t - the size of the section
68386a61e6SMatt Spinler      */
flattenedSize()69386a61e6SMatt Spinler     size_t flattenedSize()
70386a61e6SMatt Spinler     {
71e2eb14aeSMatt Spinler         return Section::headerSize() + sizeof(_creatorID) +
72386a61e6SMatt Spinler                sizeof(_reserved1B) + sizeof(_reserved2B) + _data.size();
73386a61e6SMatt Spinler     }
74386a61e6SMatt Spinler 
75386a61e6SMatt Spinler     /**
76386a61e6SMatt Spinler      * @brief Returns the section creator ID field.
77386a61e6SMatt Spinler      *
78386a61e6SMatt Spinler      * @return uint8_t - The creator ID
79386a61e6SMatt Spinler      */
creatorID() const80d26fa3e7SPatrick Williams     uint8_t creatorID() const
81386a61e6SMatt Spinler     {
82386a61e6SMatt Spinler         return _creatorID;
83386a61e6SMatt Spinler     }
84386a61e6SMatt Spinler 
85386a61e6SMatt Spinler     /**
86386a61e6SMatt Spinler      * @brief Returns the raw section data
87386a61e6SMatt Spinler      *
88386a61e6SMatt Spinler      * This doesn't include the creator ID.
89386a61e6SMatt Spinler      *
90386a61e6SMatt Spinler      * @return std::vector<uint8_t>&
91386a61e6SMatt Spinler      */
data() const92386a61e6SMatt Spinler     const std::vector<uint8_t>& data() const
93386a61e6SMatt Spinler     {
94386a61e6SMatt Spinler         return _data;
95386a61e6SMatt Spinler     }
96386a61e6SMatt Spinler 
97386a61e6SMatt Spinler     /**
983160a544SSumit Kumar      * @brief Returns the section data updated with new data
993160a544SSumit Kumar      *
1003160a544SSumit Kumar      * @param[in] subType - The type of user data
1013160a544SSumit Kumar      * @param[in] componentID - Component ID of the creator
1023160a544SSumit Kumar      * @param[in] newData - The new data
1033160a544SSumit Kumar      *
1043160a544SSumit Kumar      */
updateDataSection(const uint8_t subType,const uint16_t componentId,const std::vector<uint8_t> & newData)1053160a544SSumit Kumar     void updateDataSection(const uint8_t subType, const uint16_t componentId,
1063160a544SSumit Kumar                            const std::vector<uint8_t>& newData)
1073160a544SSumit Kumar     {
1083160a544SSumit Kumar         if (newData.size() >= 4)
1093160a544SSumit Kumar         {
11045796e82SMatt Spinler             size_t origDataSize{};
11145796e82SMatt Spinler 
1123160a544SSumit Kumar             // Update component Id & subtype in section header of ED
1133160a544SSumit Kumar             _header.componentID = static_cast<uint16_t>(componentId);
1143160a544SSumit Kumar             _header.subType = static_cast<uint8_t>(subType);
1153160a544SSumit Kumar 
1163160a544SSumit Kumar             if (newData.size() > _data.size())
1173160a544SSumit Kumar             {
1183160a544SSumit Kumar                 // Don't allow section to get bigger
1193160a544SSumit Kumar                 origDataSize = _data.size();
1203160a544SSumit Kumar                 _data = newData;
1213160a544SSumit Kumar                 _data.resize(origDataSize);
1223160a544SSumit Kumar             }
1233160a544SSumit Kumar             else
1243160a544SSumit Kumar             {
1253160a544SSumit Kumar                 // Use shrink to handle 4B alignment and update the header size
1263160a544SSumit Kumar                 auto status =
127e2eb14aeSMatt Spinler                     shrink(Section::headerSize() + 4 + newData.size());
1283160a544SSumit Kumar                 if (status)
1293160a544SSumit Kumar                 {
1303160a544SSumit Kumar                     origDataSize = _data.size();
1313160a544SSumit Kumar                     _data = newData;
1323160a544SSumit Kumar                     _data.resize(origDataSize);
1333160a544SSumit Kumar                 }
1343160a544SSumit Kumar             }
1353160a544SSumit Kumar         }
1363160a544SSumit Kumar     }
1373160a544SSumit Kumar 
1383160a544SSumit Kumar     /**
139386a61e6SMatt Spinler      * @brief Get the section contents in JSON
140386a61e6SMatt Spinler      *
141386a61e6SMatt Spinler      * @param[in] creatorID - Creator Subsystem ID - unused (see the .cpp)
142386a61e6SMatt Spinler      * @param[in] plugins - Vector of strings of plugins found in filesystem
143386a61e6SMatt Spinler      *
144386a61e6SMatt Spinler      * @return The JSON as a string if a parser was found,
145386a61e6SMatt Spinler      *         otherwise std::nullopt.
146386a61e6SMatt Spinler      */
14725291157SPatrick Williams     std::optional<std::string> getJSON(
14825291157SPatrick Williams         uint8_t creatorID,
149386a61e6SMatt Spinler         const std::vector<std::string>& plugins) const override;
150386a61e6SMatt Spinler 
151386a61e6SMatt Spinler     /**
152386a61e6SMatt Spinler      * @brief Shrink the section
153386a61e6SMatt Spinler      *
154386a61e6SMatt Spinler      * The new size must be between the current size and the minimum
155386a61e6SMatt Spinler      * size, which is 12 bytes.  If it isn't a 4 byte aligned value
156386a61e6SMatt Spinler      * the code will do the aligning before the resize takes place.
157386a61e6SMatt Spinler      *
158386a61e6SMatt Spinler      * @param[in] newSize - The new size in bytes
159386a61e6SMatt Spinler      *
160386a61e6SMatt Spinler      * @return bool - true if successful, false else.
161386a61e6SMatt Spinler      */
162386a61e6SMatt Spinler     bool shrink(size_t newSize) override;
163386a61e6SMatt Spinler 
164386a61e6SMatt Spinler   private:
165386a61e6SMatt Spinler     /**
166386a61e6SMatt Spinler      * @brief Fills in the object from the stream data
167386a61e6SMatt Spinler      *
168386a61e6SMatt Spinler      * @param[in] stream - The stream to read from
169386a61e6SMatt Spinler      */
170386a61e6SMatt Spinler     void unflatten(Stream& stream);
171386a61e6SMatt Spinler 
172386a61e6SMatt Spinler     /**
173386a61e6SMatt Spinler      * @brief Validates the section contents
174386a61e6SMatt Spinler      *
175386a61e6SMatt Spinler      * Updates _valid (in Section) with the results.
176386a61e6SMatt Spinler      */
177*bf27da63SMatt Spinler     void validate();
178386a61e6SMatt Spinler 
179386a61e6SMatt Spinler     /**
180386a61e6SMatt Spinler      * @brief The subsystem creator ID of the code that
181386a61e6SMatt Spinler      *        created this section.
182386a61e6SMatt Spinler      */
183386a61e6SMatt Spinler     uint8_t _creatorID;
184386a61e6SMatt Spinler 
185386a61e6SMatt Spinler     /**
186386a61e6SMatt Spinler      * @brief Reserved
187386a61e6SMatt Spinler      */
188386a61e6SMatt Spinler     uint8_t _reserved1B;
189386a61e6SMatt Spinler 
190386a61e6SMatt Spinler     /**
191386a61e6SMatt Spinler      * @brief Reserved
192386a61e6SMatt Spinler      */
193386a61e6SMatt Spinler     uint16_t _reserved2B;
194386a61e6SMatt Spinler 
195386a61e6SMatt Spinler     /**
196386a61e6SMatt Spinler      * @brief The section data
197386a61e6SMatt Spinler      */
198386a61e6SMatt Spinler     std::vector<uint8_t> _data;
199386a61e6SMatt Spinler };
200386a61e6SMatt Spinler 
201386a61e6SMatt Spinler } // namespace openpower::pels
202