xref: /openbmc/phosphor-logging/extensions/openpower-pels/extended_user_header.hpp (revision bf27da63180a019a59db528a94100be955872681)
1 #pragma once
2 
3 #include "bcd_time.hpp"
4 #include "data_interface.hpp"
5 #include "mtms.hpp"
6 #include "registry.hpp"
7 #include "section.hpp"
8 #include "src.hpp"
9 #include "stream.hpp"
10 
11 namespace openpower
12 {
13 namespace pels
14 {
15 
16 constexpr uint8_t extendedUserHeaderVersion = 0x01;
17 constexpr size_t firmwareVersionSize = 16;
18 
19 /**
20  * @class ExtendedUserHeader
21  *
22  * This represents the Extended User Header section in a PEL.  It is  a required
23  * section.  It contains code versions, an MTMS subsection, and a string called
24  * a symptom ID.
25  *
26  * The Section base class handles the section header structure that every
27  * PEL section has at offset zero.
28  */
29 class ExtendedUserHeader : public Section
30 {
31   public:
32     ExtendedUserHeader() = delete;
33     ~ExtendedUserHeader() override = default;
34     ExtendedUserHeader(const ExtendedUserHeader&) = default;
35     ExtendedUserHeader& operator=(const ExtendedUserHeader&) = default;
36     ExtendedUserHeader(ExtendedUserHeader&&) = default;
37     ExtendedUserHeader& operator=(ExtendedUserHeader&&) = default;
38 
39     /**
40      * @brief Constructor
41      *
42      * Fills in this class's data fields from the stream.
43      *
44      * @param[in] pel - the PEL data stream
45      */
46     explicit ExtendedUserHeader(Stream& pel);
47 
48     /**
49      * @brief Constructor
50      *
51      * @param[in] dataIface - The DataInterface object
52      * @param[in] regEntry - The message registry entry for this event
53      * @param[in] src - The SRC section object for this event
54      */
55     ExtendedUserHeader(const DataInterfaceBase& dataIface,
56                        const message::Entry& regEntry, const SRC& src);
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 size of this section when flattened into a PEL
67      *
68      * @return size_t - the size of the section
69      */
flattenedSize()70     size_t flattenedSize()
71     {
72         return Section::headerSize() + _mtms.flattenedSize() +
73                _serverFWVersion.size() + _subsystemFWVersion.size() +
74                sizeof(_reserved4B) + sizeof(_refTime) + sizeof(_reserved1B1) +
75                sizeof(_reserved1B2) + sizeof(_reserved1B3) +
76                sizeof(_symptomIDSize) + _symptomIDSize;
77     }
78 
79     /**
80      * @brief Returns the server firmware version
81      *
82      * @return std::string - The version
83      */
serverFWVersion() const84     std::string serverFWVersion() const
85     {
86         std::string version;
87         for (size_t i = 0;
88              i < _serverFWVersion.size() && _serverFWVersion[i] != '\0'; i++)
89         {
90             version.push_back(_serverFWVersion[i]);
91         }
92         return version;
93     }
94 
95     /**
96      * @brief Returns the subsystem firmware version
97      *
98      * @return std::string - The version
99      */
subsystemFWVersion() const100     std::string subsystemFWVersion() const
101     {
102         std::string version;
103         for (size_t i = 0;
104              i < _subsystemFWVersion.size() && _subsystemFWVersion[i] != '\0';
105              i++)
106         {
107             version.push_back(_subsystemFWVersion[i]);
108         }
109         return version;
110     }
111 
112     /**
113      * @brief Returns the machine type+model
114      *
115      * @return std::string - The MTM
116      */
machineTypeModel() const117     std::string machineTypeModel() const
118     {
119         return _mtms.machineTypeAndModel();
120     }
121 
122     /**
123      * @brief Returns the machine serial number
124      *
125      * @return std::string - The serial number
126      */
machineSerialNumber() const127     std::string machineSerialNumber() const
128     {
129         return _mtms.machineSerialNumber();
130     }
131 
132     /**
133      * @brief Returns the Event Common Reference Time field
134      *
135      * @return BCDTime - The time value
136      */
refTime() const137     const BCDTime& refTime() const
138     {
139         return _refTime;
140     }
141 
142     /**
143      * @brief Returns the symptom ID
144      *
145      * @return std::string - The symptom ID
146      */
symptomID() const147     std::string symptomID() const
148     {
149         std::string symptom;
150         for (size_t i = 0; i < _symptomID.size() && _symptomID[i] != '\0'; i++)
151         {
152             symptom.push_back(_symptomID[i]);
153         }
154         return symptom;
155     }
156 
157     /**
158      * @brief Get section in JSON.
159      *
160      * @param[in] creatorID - The creator ID for the PEL
161      *
162      * @return std::optional<std::string> - ExtendedUserHeader section's JSON
163      */
164     std::optional<std::string> getJSON(uint8_t creatorID) const override;
165 
166   private:
167     /**
168      * @brief Fills in the object from the stream data
169      *
170      * @param[in] stream - The stream to read from
171      */
172     void unflatten(Stream& stream);
173 
174     /**
175      * @brief Validates the section contents
176      *
177      * Updates _valid (in Section) with the results.
178      */
179     void validate();
180 
181     /**
182      * @brief Builds the symptom ID
183      *
184      * Uses the message registry to say which SRC fields to add
185      * to the SRC's ASCII string to make the ID, and uses a smart
186      * default if not specified in the registry.
187      *
188      * @param[in] regEntry - The message registry entry for this event
189      * @param[in] src - The SRC section object for this event
190      */
191     void createSymptomID(const message::Entry& regEntry, const SRC& src);
192 
193     /**
194      * @brief The structure that holds the machine TM and SN fields.
195      */
196     MTMS _mtms;
197 
198     /**
199      * @brief The server firmware version
200      *
201      * NULL terminated.
202      *
203      * The release version of the full firmware image.
204      */
205     std::array<uint8_t, firmwareVersionSize> _serverFWVersion;
206 
207     /**
208      * @brief The subsystem firmware version
209      *
210      * NULL terminated.
211      *
212      * On PELs created on the BMC, this will be the BMC code version.
213      */
214     std::array<uint8_t, firmwareVersionSize> _subsystemFWVersion;
215 
216     /**
217      * @brief Reserved
218      */
219     uint32_t _reserved4B = 0;
220 
221     /**
222      * @brief Event Common Reference Time
223      *
224      * This is not used by PELs created on the BMC.
225      */
226     BCDTime _refTime;
227 
228     /**
229      * @brief Reserved
230      */
231     uint8_t _reserved1B1 = 0;
232 
233     /**
234      * @brief Reserved
235      */
236     uint8_t _reserved1B2 = 0;
237 
238     /**
239      * @brief Reserved
240      */
241     uint8_t _reserved1B3 = 0;
242 
243     /**
244      * @brief The size of the symptom ID field
245      */
246     uint8_t _symptomIDSize;
247 
248     /**
249      * @brief The symptom ID field
250      *
251      * Describes a unique event signature for the log.
252      * Required for serviceable events, otherwise optional.
253      * When present, must start with the first 8 characters
254      * of the ASCII string field from the SRC.
255      *
256      * NULL terminated.
257      */
258     std::vector<uint8_t> _symptomID;
259 };
260 
261 } // namespace pels
262 } // namespace openpower
263