xref: /openbmc/phosphor-logging/extensions/openpower-pels/src.hpp (revision 7b92372da378fa751c6596e5ea93936f61e61022)
1f9bae185SMatt Spinler #pragma once
2f9bae185SMatt Spinler 
3f9bae185SMatt Spinler #include "additional_data.hpp"
4f9bae185SMatt Spinler #include "ascii_string.hpp"
5f9bae185SMatt Spinler #include "callouts.hpp"
6075e5bafSMatt Spinler #include "data_interface.hpp"
7f9bae185SMatt Spinler #include "pel_types.hpp"
8bd716f00SMatt Spinler #include "registry.hpp"
9f9bae185SMatt Spinler #include "section.hpp"
10f9bae185SMatt Spinler #include "stream.hpp"
11f9bae185SMatt Spinler 
12f9bae185SMatt Spinler namespace openpower
13f9bae185SMatt Spinler {
14f9bae185SMatt Spinler namespace pels
15f9bae185SMatt Spinler {
16f9bae185SMatt Spinler 
17bd716f00SMatt Spinler constexpr uint8_t srcSectionVersion = 0x01;
18bd716f00SMatt Spinler constexpr uint8_t srcSectionSubtype = 0x01;
19f9bae185SMatt Spinler constexpr size_t numSRCHexDataWords = 8;
20bd716f00SMatt Spinler constexpr uint8_t srcVersion = 0x02;
21bd716f00SMatt Spinler constexpr uint8_t bmcSRCFormat = 0x55;
22bd716f00SMatt Spinler constexpr uint8_t primaryBMCPosition = 0x10;
23bd716f00SMatt Spinler constexpr size_t baseSRCSize = 72;
24f9bae185SMatt Spinler 
250f717e10SHarisuddin Mohamed Isa enum class DetailLevel
260f717e10SHarisuddin Mohamed Isa {
270f717e10SHarisuddin Mohamed Isa     message = 0x01,
280f717e10SHarisuddin Mohamed Isa     json = 0x02
290f717e10SHarisuddin Mohamed Isa };
30f9bae185SMatt Spinler /**
31f9bae185SMatt Spinler  * @class SRC
32f9bae185SMatt Spinler  *
33f9bae185SMatt Spinler  * SRC stands for System Reference Code.
34f9bae185SMatt Spinler  *
35f9bae185SMatt Spinler  * This class represents the SRC sections in the PEL, of which there are 2:
36f9bae185SMatt Spinler  * primary SRC and secondary SRC.  These are the same structurally, the
37f9bae185SMatt Spinler  * difference is that the primary SRC must be the 3rd section in the PEL if
38f9bae185SMatt Spinler  * present and there is only one of them, and the secondary SRC sections are
39f9bae185SMatt Spinler  * optional and there can be more than one (by definition, for there to be a
40f9bae185SMatt Spinler  * secondary SRC, a primary SRC must also exist).
41f9bae185SMatt Spinler  *
42f9bae185SMatt Spinler  * This section consists of:
43f9bae185SMatt Spinler  * - An 8B header (Has the version, flags, hexdata word count, and size fields)
44f9bae185SMatt Spinler  * - 8 4B words of hex data
45f9bae185SMatt Spinler  * - An ASCII character string
46f9bae185SMatt Spinler  * - An optional subsection for Callouts
47f9bae185SMatt Spinler  */
48f9bae185SMatt Spinler class SRC : public Section
49f9bae185SMatt Spinler {
50f9bae185SMatt Spinler   public:
51f9bae185SMatt Spinler     enum HeaderFlags
52f9bae185SMatt Spinler     {
53bd716f00SMatt Spinler         additionalSections = 0x01,
540f717e10SHarisuddin Mohamed Isa         powerFaultEvent = 0x02,
550f717e10SHarisuddin Mohamed Isa         hypDumpInit = 0x04,
563e274432SSumit Kumar         postOPPanel = 0x08,
570f717e10SHarisuddin Mohamed Isa         i5OSServiceEventBit = 0x10,
580f717e10SHarisuddin Mohamed Isa         virtualProgressSRC = 0x80
59f9bae185SMatt Spinler     };
60f9bae185SMatt Spinler 
61afa2c799SMatt Spinler     /**
62afa2c799SMatt Spinler      * @brief Enums for the error status bits in hex word 5
63afa2c799SMatt Spinler      *        of BMC SRCs.
64afa2c799SMatt Spinler      */
65da5b76b2SMatt Spinler     enum class ErrorStatusFlags : uint32_t
66afa2c799SMatt Spinler     {
67da5b76b2SMatt Spinler         hwCheckstop = 0x80000000,
683e274432SSumit Kumar         terminateFwErr = 0x20000000,
69afa2c799SMatt Spinler         deconfigured = 0x02000000,
70afa2c799SMatt Spinler         guarded = 0x01000000
71afa2c799SMatt Spinler     };
72afa2c799SMatt Spinler 
73f9bae185SMatt Spinler     SRC() = delete;
74f9bae185SMatt Spinler     ~SRC() = default;
75f9bae185SMatt Spinler     SRC(const SRC&) = delete;
76f9bae185SMatt Spinler     SRC& operator=(const SRC&) = delete;
77f9bae185SMatt Spinler     SRC(SRC&&) = delete;
78f9bae185SMatt Spinler     SRC& operator=(SRC&&) = delete;
79f9bae185SMatt Spinler 
80f9bae185SMatt Spinler     /**
81f9bae185SMatt Spinler      * @brief Constructor
82f9bae185SMatt Spinler      *
83f9bae185SMatt Spinler      * Fills in this class's data fields from the stream.
84f9bae185SMatt Spinler      *
85f9bae185SMatt Spinler      * @param[in] pel - the PEL data stream
86f9bae185SMatt Spinler      */
87f9bae185SMatt Spinler     explicit SRC(Stream& pel);
88f9bae185SMatt Spinler 
89f9bae185SMatt Spinler     /**
90bd716f00SMatt Spinler      * @brief Constructor
91bd716f00SMatt Spinler      *
92bd716f00SMatt Spinler      * Creates the section with data from the PEL message registry entry for
93bd716f00SMatt Spinler      * this error, along with the AdditionalData property contents from the
94bd716f00SMatt Spinler      * corresponding event log.
95bd716f00SMatt Spinler      *
96bd716f00SMatt Spinler      * @param[in] regEntry - The message registry entry for this event log
97bd716f00SMatt Spinler      * @param[in] additionalData - The AdditionalData properties in this event
98bd716f00SMatt Spinler      *                             log
99075e5bafSMatt Spinler      * @param[in] dataIface - The DataInterface object
100bd716f00SMatt Spinler      */
SRC(const message::Entry & regEntry,const AdditionalData & additionalData,const DataInterfaceBase & dataIface)101075e5bafSMatt Spinler     SRC(const message::Entry& regEntry, const AdditionalData& additionalData,
1025a90a95bSMatt Spinler         const DataInterfaceBase& dataIface) :
1035a90a95bSMatt Spinler         SRC(regEntry, additionalData, nlohmann::json{}, dataIface)
1042544b419SPatrick Williams     {}
1055a90a95bSMatt Spinler 
1065a90a95bSMatt Spinler     /**
1075a90a95bSMatt Spinler      * @brief Constructor
1085a90a95bSMatt Spinler      *
1095a90a95bSMatt Spinler      * Creates the section with data from the PEL message registry entry for
1105a90a95bSMatt Spinler      * this error, along with the AdditionalData property contents from the
1115a90a95bSMatt Spinler      * corresponding event log, and a JSON array of callouts to add.
1125a90a95bSMatt Spinler      *
1135a90a95bSMatt Spinler      * @param[in] regEntry - The message registry entry for this event log
1145a90a95bSMatt Spinler      * @param[in] additionalData - The AdditionalData properties in this event
1155a90a95bSMatt Spinler      *                             log
1165a90a95bSMatt Spinler      * @param[in] jsonCallouts - The array of JSON callouts, or an empty object.
1175a90a95bSMatt Spinler      * @param[in] dataIface - The DataInterface object
1185a90a95bSMatt Spinler      */
1195a90a95bSMatt Spinler     SRC(const message::Entry& regEntry, const AdditionalData& additionalData,
1205a90a95bSMatt Spinler         const nlohmann::json& jsonCallouts, const DataInterfaceBase& dataIface);
121bd716f00SMatt Spinler 
122bd716f00SMatt Spinler     /**
123f9bae185SMatt Spinler      * @brief Flatten the section into the stream
124f9bae185SMatt Spinler      *
125f9bae185SMatt Spinler      * @param[in] stream - The stream to write to
126f9bae185SMatt Spinler      */
1270688545bSMatt Spinler     void flatten(Stream& stream) const override;
128f9bae185SMatt Spinler 
129f9bae185SMatt Spinler     /**
130f9bae185SMatt Spinler      * @brief Returns the SRC version, which is a different field
131f9bae185SMatt Spinler      *        than the version byte in the section header.
132f9bae185SMatt Spinler      *
133f9bae185SMatt Spinler      * @return uint8_t
134f9bae185SMatt Spinler      */
version() const135f9bae185SMatt Spinler     uint8_t version() const
136f9bae185SMatt Spinler     {
137f9bae185SMatt Spinler         return _version;
138f9bae185SMatt Spinler     }
139f9bae185SMatt Spinler 
140f9bae185SMatt Spinler     /**
141f9bae185SMatt Spinler      * @brief Returns the flags byte
142f9bae185SMatt Spinler      *
143f9bae185SMatt Spinler      * @return uint8_t
144f9bae185SMatt Spinler      */
flags() const145f9bae185SMatt Spinler     uint8_t flags() const
146f9bae185SMatt Spinler     {
147f9bae185SMatt Spinler         return _flags;
148f9bae185SMatt Spinler     }
149f9bae185SMatt Spinler 
150f9bae185SMatt Spinler     /**
151f9bae185SMatt Spinler      * @brief Returns the hex data word count.
152f9bae185SMatt Spinler      *
153f9bae185SMatt Spinler      * Even though there always 8 words, this returns 9 due to previous
154f9bae185SMatt Spinler      * SRC version formats.
155f9bae185SMatt Spinler      *
156f9bae185SMatt Spinler      * @return uint8_t
157f9bae185SMatt Spinler      */
hexWordCount() const158f9bae185SMatt Spinler     uint8_t hexWordCount() const
159f9bae185SMatt Spinler     {
160f9bae185SMatt Spinler         return _wordCount;
161f9bae185SMatt Spinler     }
162f9bae185SMatt Spinler 
163f9bae185SMatt Spinler     /**
164f9bae185SMatt Spinler      * @brief Returns the size of the SRC section, not including the header.
165f9bae185SMatt Spinler      *
166f9bae185SMatt Spinler      * @return uint16_t
167f9bae185SMatt Spinler      */
size() const168f9bae185SMatt Spinler     uint16_t size() const
169f9bae185SMatt Spinler     {
170f9bae185SMatt Spinler         return _size;
171f9bae185SMatt Spinler     }
172f9bae185SMatt Spinler 
173f9bae185SMatt Spinler     /**
174f9bae185SMatt Spinler      * @brief Returns the 8 hex data words.
175f9bae185SMatt Spinler      *
176f9bae185SMatt Spinler      * @return const std::array<uint32_t, numSRCHexDataWords>&
177f9bae185SMatt Spinler      */
hexwordData() const178f9bae185SMatt Spinler     const std::array<uint32_t, numSRCHexDataWords>& hexwordData() const
179f9bae185SMatt Spinler     {
180f9bae185SMatt Spinler         return _hexData;
181f9bae185SMatt Spinler     }
182f9bae185SMatt Spinler 
183f9bae185SMatt Spinler     /**
184f9bae185SMatt Spinler      * @brief Returns the ASCII string
185f9bae185SMatt Spinler      *
186f9bae185SMatt Spinler      * @return std::string
187f9bae185SMatt Spinler      */
asciiString() const188f9bae185SMatt Spinler     std::string asciiString() const
189f9bae185SMatt Spinler     {
190f9bae185SMatt Spinler         return _asciiString->get();
191f9bae185SMatt Spinler     }
192f9bae185SMatt Spinler 
193f9bae185SMatt Spinler     /**
194f9bae185SMatt Spinler      * @brief Returns the callouts subsection
195f9bae185SMatt Spinler      *
196f9bae185SMatt Spinler      * If no callouts, this unique_ptr will be empty
197f9bae185SMatt Spinler      *
198f9bae185SMatt Spinler      * @return  const std::unique_ptr<src::Callouts>&
199f9bae185SMatt Spinler      */
callouts() const200f9bae185SMatt Spinler     const std::unique_ptr<src::Callouts>& callouts() const
201f9bae185SMatt Spinler     {
202f9bae185SMatt Spinler         return _callouts;
203f9bae185SMatt Spinler     }
204f9bae185SMatt Spinler 
205f9bae185SMatt Spinler     /**
206bd716f00SMatt Spinler      * @brief Returns the size of this section when flattened into a PEL
207f9bae185SMatt Spinler      *
208bd716f00SMatt Spinler      * @return size_t - the size of the section
209f9bae185SMatt Spinler      */
flattenedSize() const210bd716f00SMatt Spinler     size_t flattenedSize() const
211bd716f00SMatt Spinler     {
212bd716f00SMatt Spinler         return _header.size;
213bd716f00SMatt Spinler     }
214f9bae185SMatt Spinler 
215f9bae185SMatt Spinler     /**
216f9bae185SMatt Spinler      * @brief Says if this SRC has additional subsections in it
217f9bae185SMatt Spinler      *
218f9bae185SMatt Spinler      * Note: The callouts section is the only possible subsection.
219f9bae185SMatt Spinler      *
220f9bae185SMatt Spinler      * @return bool
221f9bae185SMatt Spinler      */
hasAdditionalSections() const222f9bae185SMatt Spinler     inline bool hasAdditionalSections() const
223f9bae185SMatt Spinler     {
224bd716f00SMatt Spinler         return _flags & additionalSections;
225bd716f00SMatt Spinler     }
226bd716f00SMatt Spinler 
227bd716f00SMatt Spinler     /**
228bd716f00SMatt Spinler      * @brief Indicates if this event log is for a power fault.
229bd716f00SMatt Spinler      *
230bd716f00SMatt Spinler      * This comes from a field in the message registry for BMC
231bd716f00SMatt Spinler      * generated PELs.
232bd716f00SMatt Spinler      *
233bd716f00SMatt Spinler      * @return bool
234bd716f00SMatt Spinler      */
isPowerFaultEvent() const235bd716f00SMatt Spinler     inline bool isPowerFaultEvent() const
236bd716f00SMatt Spinler     {
237bd716f00SMatt Spinler         return _flags & powerFaultEvent;
238bd716f00SMatt Spinler     }
239bd716f00SMatt Spinler 
240c63e2e82SMatt Spinler     /**
241c63e2e82SMatt Spinler      * @brief Get the _hexData[] index to use based on the corresponding
242c63e2e82SMatt Spinler      *        SRC word number.
243c63e2e82SMatt Spinler      *
244c63e2e82SMatt Spinler      * Converts the specification nomenclature to this data structure.
245c63e2e82SMatt Spinler      * See the _hexData documentation below for more information.
246c63e2e82SMatt Spinler      *
247c63e2e82SMatt Spinler      * @param[in] wordNum - The SRC word number, as defined by the spec.
248c63e2e82SMatt Spinler      *
249c63e2e82SMatt Spinler      * @return size_t The corresponding index into _hexData.
250c63e2e82SMatt Spinler      */
getWordIndexFromWordNum(size_t wordNum) const251c63e2e82SMatt Spinler     inline size_t getWordIndexFromWordNum(size_t wordNum) const
252c63e2e82SMatt Spinler     {
253c63e2e82SMatt Spinler         assert(wordNum >= 2 && wordNum <= 9);
254c63e2e82SMatt Spinler         return wordNum - 2;
255c63e2e82SMatt Spinler     }
256c63e2e82SMatt Spinler 
2570f717e10SHarisuddin Mohamed Isa     /**
2580f717e10SHarisuddin Mohamed Isa      * @brief Get section in JSON.
259a214ed30SHarisuddin Mohamed Isa      * @param[in] registry - Registry object reference
260c8d6cc61SHarisuddin Mohamed Isa      * @param[in] plugins - Vector of strings of plugins found in filesystem
261c8d6cc61SHarisuddin Mohamed Isa      * @param[in] creatorID - Creator Subsystem ID from Private Header
2620f717e10SHarisuddin Mohamed Isa      * @return std::optional<std::string> - SRC section's JSON
2630f717e10SHarisuddin Mohamed Isa      */
264c8d6cc61SHarisuddin Mohamed Isa     std::optional<std::string> getJSON(message::Registry& registry,
265c8d6cc61SHarisuddin Mohamed Isa                                        const std::vector<std::string>& plugins,
266c8d6cc61SHarisuddin Mohamed Isa                                        uint8_t creatorID) const override;
2670f717e10SHarisuddin Mohamed Isa 
2680f717e10SHarisuddin Mohamed Isa     /**
2690f717e10SHarisuddin Mohamed Isa      * @brief Get error details based on refcode and hexwords
2700f717e10SHarisuddin Mohamed Isa      * @param[in] registry - Registry object
2710f717e10SHarisuddin Mohamed Isa      * @param[in] type - detail level enum value : single message or full json
2720f717e10SHarisuddin Mohamed Isa      * @param[in] toCache - boolean to cache registry in memory, default=false
2730f717e10SHarisuddin Mohamed Isa      * @return std::optional<std::string> - Error details
2740f717e10SHarisuddin Mohamed Isa      */
27525291157SPatrick Williams     std::optional<std::string> getErrorDetails(message::Registry& registry,
27625291157SPatrick Williams                                                DetailLevel type,
2770f717e10SHarisuddin Mohamed Isa                                                bool toCache = false) const;
2780f717e10SHarisuddin Mohamed Isa 
279075e5bafSMatt Spinler     /**
280075e5bafSMatt Spinler      * @brief Says if this SRC was created by the BMC (i.e. this code).
281075e5bafSMatt Spinler      *
282075e5bafSMatt Spinler      * @return bool - If created by the BMC or not
283075e5bafSMatt Spinler      */
284075e5bafSMatt Spinler     bool isBMCSRC() const;
285075e5bafSMatt Spinler 
2863e274432SSumit Kumar     /**
2874deed972SMatt Spinler      * @brief Says if this SRC was created by Hostboot
2884deed972SMatt Spinler      *
2894deed972SMatt Spinler      * @return bool - If created by Hostboot or not
2904deed972SMatt Spinler      */
2914deed972SMatt Spinler     bool isHostbootSRC() const;
2924deed972SMatt Spinler 
2934deed972SMatt Spinler     /**
2943e274432SSumit Kumar      * @brief Set the terminate bit in hex data word 3.
2953e274432SSumit Kumar      */
setTerminateBit()2963e274432SSumit Kumar     void setTerminateBit()
2973e274432SSumit Kumar     {
2983e274432SSumit Kumar         setErrorStatusFlag(ErrorStatusFlags::terminateFwErr);
2993e274432SSumit Kumar     }
3003e274432SSumit Kumar 
3013e274432SSumit Kumar     /**
3023e274432SSumit Kumar      * @brief Get the SRC structure to pass on to the boot progress dbus
3033e274432SSumit Kumar      * interface.
3043e274432SSumit Kumar      *
3053e274432SSumit Kumar      * @return std::vector<uint8_t> - SRC struct data
3063e274432SSumit Kumar      */
3073e274432SSumit Kumar     std::vector<uint8_t> getSrcStruct();
3083e274432SSumit Kumar 
309875b6c7bSVijay Lobo     /**
310875b6c7bSVijay Lobo      * @brief Extracts the first 8 characters of the ASCII String field
311875b6c7bSVijay Lobo      *        from the raw progress SRC and converts it to a uint32_t.
312875b6c7bSVijay Lobo      *
313875b6c7bSVijay Lobo      * @param[in] rawProgressSRC - The progress SRC bytes
314875b6c7bSVijay Lobo      *
315875b6c7bSVijay Lobo      * @return uint32_t - The code, like 0xCC0099EE from "CC0099EE"
316875b6c7bSVijay Lobo      */
317875b6c7bSVijay Lobo     static uint32_t getProgressCode(std::vector<uint8_t>& rawProgressSRC);
318875b6c7bSVijay Lobo 
3198e65f4eaSMatt Spinler     /**
3208e65f4eaSMatt Spinler      * @brief Return the value of the passed in error status flag.
3218e65f4eaSMatt Spinler      *
3228e65f4eaSMatt Spinler      * @param[in] flag - The flag
3238e65f4eaSMatt Spinler      *
3248e65f4eaSMatt Spinler      * @return bool - If the flag is set.
3258e65f4eaSMatt Spinler      */
getErrorStatusFlag(ErrorStatusFlags flag) const3268e65f4eaSMatt Spinler     bool getErrorStatusFlag(ErrorStatusFlags flag) const
3278e65f4eaSMatt Spinler     {
3288e65f4eaSMatt Spinler         return _hexData[3] & static_cast<uint32_t>(flag);
3298e65f4eaSMatt Spinler     }
3308e65f4eaSMatt Spinler 
3310dd22c83SMatt Spinler     /**
3320dd22c83SMatt Spinler      * @brief Clears an error status flag in the SRC.
3330dd22c83SMatt Spinler      *
3340dd22c83SMatt Spinler      * @param[in] flag - The flag to set
3350dd22c83SMatt Spinler      */
clearErrorStatusFlag(ErrorStatusFlags flag)3360dd22c83SMatt Spinler     void clearErrorStatusFlag(ErrorStatusFlags flag)
3370dd22c83SMatt Spinler     {
3380dd22c83SMatt Spinler         _hexData[3] &= ~static_cast<uint32_t>(flag);
3390dd22c83SMatt Spinler     }
3400dd22c83SMatt Spinler 
341bd716f00SMatt Spinler   private:
342bd716f00SMatt Spinler     /**
343bd716f00SMatt Spinler      * @brief Fills in the user defined hex words from the
344bd716f00SMatt Spinler      *        AdditionalData fields.
345bd716f00SMatt Spinler      *
346bd716f00SMatt Spinler      * When creating this section from a message registry entry,
347bd716f00SMatt Spinler      * that entry has a field that says which AdditionalData property
348bd716f00SMatt Spinler      * fields to use to fill in the user defined hex data words 6-9
349bd716f00SMatt Spinler      * (which correspond to hexData words 4-7).
350bd716f00SMatt Spinler      *
351bd716f00SMatt Spinler      * For example, given that AdditionalData is a map of string keys
352bd716f00SMatt Spinler      * to string values, find the AdditionalData value for AdditionalData
353bd716f00SMatt Spinler      * key X, convert it to a uint32_t, and save it in user data word Y.
354bd716f00SMatt Spinler      *
355bd716f00SMatt Spinler      * @param[in] regEntry - The message registry entry for the error
356bd716f00SMatt Spinler      * @param[in] additionalData - The AdditionalData map
357bd716f00SMatt Spinler      */
358bd716f00SMatt Spinler     void setUserDefinedHexWords(const message::Entry& regEntry,
359bd716f00SMatt Spinler                                 const AdditionalData& additionalData);
360bd716f00SMatt Spinler     /**
361bd716f00SMatt Spinler      * @brief Fills in the object from the stream data
362bd716f00SMatt Spinler      *
363bd716f00SMatt Spinler      * @param[in] stream - The stream to read from
364bd716f00SMatt Spinler      */
365bd716f00SMatt Spinler     void unflatten(Stream& stream);
366bd716f00SMatt Spinler 
367bd716f00SMatt Spinler     /**
368bd716f00SMatt Spinler      * @brief Says if the word number is in the range of user defined words.
369bd716f00SMatt Spinler      *
370bd716f00SMatt Spinler      * This is only used for BMC generated SRCs, where words 6 - 9 are the
371bd716f00SMatt Spinler      * user defined ones, meaning that setUserDefinedHexWords() will be
372bd716f00SMatt Spinler      * used to fill them in based on the contents of the OpenBMC event log.
373bd716f00SMatt Spinler      *
374bd716f00SMatt Spinler      * @param[in] wordNum - The SRC word number, as defined by the spec.
375bd716f00SMatt Spinler      *
376bd716f00SMatt Spinler      * @return bool - If this word number can be filled in by the creator.
377bd716f00SMatt Spinler      */
isUserDefinedWord(size_t wordNum) const378bd716f00SMatt Spinler     inline bool isUserDefinedWord(size_t wordNum) const
379bd716f00SMatt Spinler     {
380bd716f00SMatt Spinler         return (wordNum >= 6) && (wordNum <= 9);
381bd716f00SMatt Spinler     }
382bd716f00SMatt Spinler 
383bd716f00SMatt Spinler     /**
384bd716f00SMatt Spinler      * @brief Sets the SRC format byte in the hex word data.
385bd716f00SMatt Spinler      */
setBMCFormat()386bd716f00SMatt Spinler     inline void setBMCFormat()
387bd716f00SMatt Spinler     {
388bd716f00SMatt Spinler         _hexData[0] |= bmcSRCFormat;
389bd716f00SMatt Spinler     }
390bd716f00SMatt Spinler 
391bd716f00SMatt Spinler     /**
392bd716f00SMatt Spinler      * @brief Sets the hex word field that specifies which BMC
393bd716f00SMatt Spinler      *        (primary vs backup) created the error.
394bd716f00SMatt Spinler      *
395bd716f00SMatt Spinler      * Can be hardcoded until there are systems with redundant BMCs.
396bd716f00SMatt Spinler      */
setBMCPosition()397bd716f00SMatt Spinler     inline void setBMCPosition()
398bd716f00SMatt Spinler     {
399bd716f00SMatt Spinler         _hexData[1] |= primaryBMCPosition;
400f9bae185SMatt Spinler     }
401f9bae185SMatt Spinler 
402f9bae185SMatt Spinler     /**
403075e5bafSMatt Spinler      * @brief Sets the motherboard CCIN hex word field
404075e5bafSMatt Spinler      *
405075e5bafSMatt Spinler      * @param[in] dataIface - The DataInterface object
406075e5bafSMatt Spinler      */
407075e5bafSMatt Spinler     void setMotherboardCCIN(const DataInterfaceBase& dataIface);
408075e5bafSMatt Spinler 
409075e5bafSMatt Spinler     /**
410875b6c7bSVijay Lobo      * @brief Sets the progress code hex word field
411875b6c7bSVijay Lobo      *
412875b6c7bSVijay Lobo      * @param[in] dataIface - The DataInterface object
413875b6c7bSVijay Lobo      */
414875b6c7bSVijay Lobo     void setProgressCode(const DataInterfaceBase& dataIface);
415875b6c7bSVijay Lobo 
416875b6c7bSVijay Lobo     /**
417afa2c799SMatt Spinler      * @brief Sets an error status bit in the SRC.
418afa2c799SMatt Spinler      *
419afa2c799SMatt Spinler      * @param[in] flag - The flag to set
420afa2c799SMatt Spinler      */
setErrorStatusFlag(ErrorStatusFlags flag)421afa2c799SMatt Spinler     void setErrorStatusFlag(ErrorStatusFlags flag)
422afa2c799SMatt Spinler     {
423afa2c799SMatt Spinler         _hexData[3] |= static_cast<uint32_t>(flag);
424afa2c799SMatt Spinler     }
425afa2c799SMatt Spinler 
426afa2c799SMatt Spinler     /**
427f9bae185SMatt Spinler      * @brief Validates the section contents
428f9bae185SMatt Spinler      *
429f9bae185SMatt Spinler      * Updates _valid (in Section) with the results.
430f9bae185SMatt Spinler      */
431f9bae185SMatt Spinler     void validate() override;
432f9bae185SMatt Spinler 
433f9bae185SMatt Spinler     /**
4340f717e10SHarisuddin Mohamed Isa      * @brief Get error description from message registry
4350f717e10SHarisuddin Mohamed Isa      * @param[in] regEntry - The message registry entry for the error
4360f717e10SHarisuddin Mohamed Isa      * @return std::optional<std::string> - Error message
4370f717e10SHarisuddin Mohamed Isa      */
43825291157SPatrick Williams     std::optional<std::string> getErrorMessage(
43925291157SPatrick Williams         const message::Entry& regEntry) const;
4400f717e10SHarisuddin Mohamed Isa 
4410f717e10SHarisuddin Mohamed Isa     /**
4420f717e10SHarisuddin Mohamed Isa      * @brief Get Callout info in JSON
4430f717e10SHarisuddin Mohamed Isa      * @return std::optional<std::string> - Callout details
4440f717e10SHarisuddin Mohamed Isa      */
4450f717e10SHarisuddin Mohamed Isa     std::optional<std::string> getCallouts() const;
4460f717e10SHarisuddin Mohamed Isa 
4470f717e10SHarisuddin Mohamed Isa     /**
448ed046856SMatt Spinler      * @brief Checks the AdditionalData property and the message registry
449ed046856SMatt Spinler      *        JSON and adds any necessary callouts.
450ed046856SMatt Spinler      *
451ed046856SMatt Spinler      * The callout sources are the AdditionalData event log property
452ed046856SMatt Spinler      * and the message registry JSON.
453ed046856SMatt Spinler      *
4540398458dSMatt Spinler      * @param[in] regEntry - The message registry entry for the error
4550398458dSMatt Spinler      * @param[in] additionalData - The AdditionalData values
4565a90a95bSMatt Spinler      * @param[in] jsonCallouts - The array of JSON callouts, or an empty object
457ed046856SMatt Spinler      * @param[in] dataIface - The DataInterface object
458ed046856SMatt Spinler      */
4590398458dSMatt Spinler     void addCallouts(const message::Entry& regEntry,
4600398458dSMatt Spinler                      const AdditionalData& additionalData,
4615a90a95bSMatt Spinler                      const nlohmann::json& jsonCallouts,
462ed046856SMatt Spinler                      const DataInterfaceBase& dataIface);
463ed046856SMatt Spinler 
464ed046856SMatt Spinler     /**
465ed046856SMatt Spinler      * @brief Adds a FRU callout based on an inventory path
466ed046856SMatt Spinler      *
467ed046856SMatt Spinler      * @param[in] inventoryPath - The inventory item to call out
468af191c7aSMatt Spinler      * @param[in] priority - An optional priority (uses high if nullopt)
469af191c7aSMatt Spinler      * @param[in] locationCode - The expanded location code (or look it up)
470ed046856SMatt Spinler      * @param[in] dataIface - The DataInterface object
471b8cb60feSMatt Spinler      * @param[in] mrus - The MRUs to add to the callout
472ed046856SMatt Spinler      */
473075c7923SPatrick Williams     void addInventoryCallout(
474075c7923SPatrick Williams         const std::string& inventoryPath,
475af191c7aSMatt Spinler         const std::optional<CalloutPriority>& priority,
476af191c7aSMatt Spinler         const std::optional<std::string>& locationCode,
477b8cb60feSMatt Spinler         const DataInterfaceBase& dataIface,
478b8cb60feSMatt Spinler         const std::vector<src::MRU::MRUCallout>& mrus = {});
479ed046856SMatt Spinler 
480ed046856SMatt Spinler     /**
481f00f9d0fSMatt Spinler      * @brief Returns the callouts to use from the registry entry.
482f00f9d0fSMatt Spinler      *
4830398458dSMatt Spinler      * @param[in] regEntry - The message registry entry for the error
484f00f9d0fSMatt Spinler      * @param[in] additionalData - The AdditionalData property
4850398458dSMatt Spinler      * @param[in] dataIface - The DataInterface object
4860398458dSMatt Spinler      */
487075c7923SPatrick Williams     std::vector<message::RegistryCallout> getRegistryCallouts(
488075c7923SPatrick Williams         const message::Entry& regEntry, const AdditionalData& additionalData,
4890398458dSMatt Spinler         const DataInterfaceBase& dataIface);
4900398458dSMatt Spinler 
4910398458dSMatt Spinler     /**
492f00f9d0fSMatt Spinler      * @brief Adds the FRU callouts from the list of registry callouts
493f00f9d0fSMatt Spinler      *        passed in to the SRC.
494f00f9d0fSMatt Spinler      *
495f00f9d0fSMatt Spinler      * The last parameter is used only in a special case when the first
496f00f9d0fSMatt Spinler      * callout is a symbolic FRU with a trusted location code.  See the
497f00f9d0fSMatt Spinler      * addRegistryCallout documentation.
498f00f9d0fSMatt Spinler      *
499f00f9d0fSMatt Spinler      * @param[in] callouts - The message registry callouts to add
500f00f9d0fSMatt Spinler      * @param[in] dataIface - The DataInterface object
501f00f9d0fSMatt Spinler      * @param[in] trustedSymbolicFRUInvPath - The optional inventory path used
502f00f9d0fSMatt Spinler      *                                        in the symbolic FRU case.
503f00f9d0fSMatt Spinler      */
504f00f9d0fSMatt Spinler     void addRegistryCallouts(
505f00f9d0fSMatt Spinler         const std::vector<message::RegistryCallout>& callouts,
506f00f9d0fSMatt Spinler         const DataInterfaceBase& dataIface,
507f00f9d0fSMatt Spinler         std::optional<std::string> trustedSymbolicFRUInvPath);
508f00f9d0fSMatt Spinler 
509f00f9d0fSMatt Spinler     /**
5100398458dSMatt Spinler      * @brief Adds a single FRU callout from the message registry.
5110398458dSMatt Spinler      *
512f00f9d0fSMatt Spinler      * If the last parameter is filled in, and the registry callout is a
513f00f9d0fSMatt Spinler      * symbolic FRU callout with a trusted location code, and it has the
514f00f9d0fSMatt Spinler      * 'useInventoryLocCode' member set to true, then the location code of
515f00f9d0fSMatt Spinler      * that inventory item will be what is used for that trusted location code.
516f00f9d0fSMatt Spinler      *
5170398458dSMatt Spinler      * @param[in] callout - The registry callout structure
5180398458dSMatt Spinler      * @param[in] dataIface - The DataInterface object
519f00f9d0fSMatt Spinler      * @param[in] trustedSymbolicFRUInvPath - The optional inventory path used
520f00f9d0fSMatt Spinler      *                                        in the symbolic FRU case.
5210398458dSMatt Spinler      */
522f00f9d0fSMatt Spinler     void addRegistryCallout(
523f00f9d0fSMatt Spinler         const message::RegistryCallout& callout,
524f00f9d0fSMatt Spinler         const DataInterfaceBase& dataIface,
525f00f9d0fSMatt Spinler         const std::optional<std::string>& trustedSymbolicFRUInvPath);
5260398458dSMatt Spinler 
5270398458dSMatt Spinler     /**
528ed046856SMatt Spinler      * @brief Creates the Callouts object _callouts
529ed046856SMatt Spinler      *        so that callouts can be added to it.
530ed046856SMatt Spinler      */
createCalloutsObject()531ed046856SMatt Spinler     void createCalloutsObject()
532ed046856SMatt Spinler     {
533ed046856SMatt Spinler         if (!_callouts)
534ed046856SMatt Spinler         {
535ed046856SMatt Spinler             _callouts = std::make_unique<src::Callouts>();
536ed046856SMatt Spinler             _flags |= additionalSections;
537ed046856SMatt Spinler         }
538ed046856SMatt Spinler     }
539ed046856SMatt Spinler 
540ed046856SMatt Spinler     /**
541717de428SMatt Spinler      * @brief Adds any FRU callouts based on a device path in the
542717de428SMatt Spinler      *        AdditionalData parameter.
543717de428SMatt Spinler      *
544717de428SMatt Spinler      * @param[in] additionalData - The AdditionalData values
545717de428SMatt Spinler      * @param[in] dataIface - The DataInterface object
546717de428SMatt Spinler      */
547717de428SMatt Spinler     void addDevicePathCallouts(const AdditionalData& additionalData,
548717de428SMatt Spinler                                const DataInterfaceBase& dataIface);
549717de428SMatt Spinler 
550717de428SMatt Spinler     /**
5515a90a95bSMatt Spinler      * @brief Adds any FRU callouts specified in the incoming JSON.
5525a90a95bSMatt Spinler      *
5535a90a95bSMatt Spinler      * @param[in] jsonCallouts - The JSON array of callouts
5545a90a95bSMatt Spinler      * @param[in] dataIface - The DataInterface object
5555a90a95bSMatt Spinler      */
5565a90a95bSMatt Spinler     void addJSONCallouts(const nlohmann::json& jsonCallouts,
5575a90a95bSMatt Spinler                          const DataInterfaceBase& dataIface);
5585a90a95bSMatt Spinler 
5595a90a95bSMatt Spinler     /**
5605a90a95bSMatt Spinler      * @brief Adds a single callout based on the JSON
5615a90a95bSMatt Spinler      *
5625a90a95bSMatt Spinler      * @param[in] jsonCallouts - A single callout entry
5635a90a95bSMatt Spinler      * @param[in] dataIface - The DataInterface object
5645a90a95bSMatt Spinler      */
5655a90a95bSMatt Spinler     void addJSONCallout(const nlohmann::json& jsonCallout,
5665a90a95bSMatt Spinler                         const DataInterfaceBase& dataIface);
5673bdd0110SMatt Spinler 
5683bdd0110SMatt Spinler     /**
569*7b92372dSMatt Spinler      * @brief Adds a FRU callout with only the location code
570*7b92372dSMatt Spinler      *
571*7b92372dSMatt Spinler      * Used when it's known not all of the data is available,
572*7b92372dSMatt Spinler      * including possibly the expanded location code.
573*7b92372dSMatt Spinler      *
574*7b92372dSMatt Spinler      * @param[in] locationCode - The location code
575*7b92372dSMatt Spinler      * @param[in] priority - The callout priority
576*7b92372dSMatt Spinler      */
577*7b92372dSMatt Spinler     void addLocationCodeOnlyCallout(const std::string& locationCode,
578*7b92372dSMatt Spinler                                     const CalloutPriority priority);
579*7b92372dSMatt Spinler 
580*7b92372dSMatt Spinler     /**
5813bdd0110SMatt Spinler      * @brief Extracts a CalloutPriority value from the json
5823bdd0110SMatt Spinler      *        using the 'Priority' key.
5833bdd0110SMatt Spinler      *
5843bdd0110SMatt Spinler      * @param[in] json - A JSON object that contains the priority key
5853bdd0110SMatt Spinler      *
5863bdd0110SMatt Spinler      * @return CalloutPriority - The priority value
5873bdd0110SMatt Spinler      */
5883bdd0110SMatt Spinler     CalloutPriority getPriorityFromJSON(const nlohmann::json& json);
5893bdd0110SMatt Spinler 
5905a90a95bSMatt Spinler     /**
591b8cb60feSMatt Spinler      * @brief Exracts MRU values and their priorities from the
592b8cb60feSMatt Spinler      *        input JSON array.
593b8cb60feSMatt Spinler      *
594b8cb60feSMatt Spinler      * @param[in] mruJSON - The JSON array
595b8cb60feSMatt Spinler      */
59625291157SPatrick Williams     std::vector<src::MRU::MRUCallout> getMRUsFromJSON(
59725291157SPatrick Williams         const nlohmann::json& mruJSON);
598b8cb60feSMatt Spinler 
599b8cb60feSMatt Spinler     /**
600f9bae185SMatt Spinler      * @brief The SRC version field
601f9bae185SMatt Spinler      */
602f9bae185SMatt Spinler     uint8_t _version;
603f9bae185SMatt Spinler 
604f9bae185SMatt Spinler     /**
605f9bae185SMatt Spinler      * @brief The SRC flags field
606f9bae185SMatt Spinler      */
607f9bae185SMatt Spinler     uint8_t _flags;
608f9bae185SMatt Spinler 
609f9bae185SMatt Spinler     /**
610f9bae185SMatt Spinler      * @brief A byte of reserved data after the flags field
611f9bae185SMatt Spinler      */
612f9bae185SMatt Spinler     uint8_t _reserved1B;
613f9bae185SMatt Spinler 
614f9bae185SMatt Spinler     /**
615f9bae185SMatt Spinler      * @brief The hex data word count.
616f9bae185SMatt Spinler      *
617f9bae185SMatt Spinler      * To be compatible with previous versions of SRCs, this is
618f9bae185SMatt Spinler      * number of hex words (8) + 1 = 9.
619f9bae185SMatt Spinler      */
620f9bae185SMatt Spinler     uint8_t _wordCount;
621f9bae185SMatt Spinler 
622f9bae185SMatt Spinler     /**
623f9bae185SMatt Spinler      * @brief Two bytes of reserved data after the hex word count
624f9bae185SMatt Spinler      */
625f9bae185SMatt Spinler     uint16_t _reserved2B;
626f9bae185SMatt Spinler 
627f9bae185SMatt Spinler     /**
628f9bae185SMatt Spinler      * @brief The total size of the SRC section, not including the section
629f9bae185SMatt Spinler      *        header.
630f9bae185SMatt Spinler      */
631f9bae185SMatt Spinler     uint16_t _size;
632f9bae185SMatt Spinler 
633f9bae185SMatt Spinler     /**
634f9bae185SMatt Spinler      * @brief The SRC 'hex words'.
635f9bae185SMatt Spinler      *
636f9bae185SMatt Spinler      * In the spec these are referred to as SRC words 2 - 9 as words 0 and 1
637f9bae185SMatt Spinler      * are filled by the 8 bytes of fields from above.
638f9bae185SMatt Spinler      */
639f9bae185SMatt Spinler     std::array<uint32_t, numSRCHexDataWords> _hexData;
640f9bae185SMatt Spinler 
641f9bae185SMatt Spinler     /**
642f9bae185SMatt Spinler      * @brief The 32 byte ASCII character string of the SRC
643f9bae185SMatt Spinler      *
644f9bae185SMatt Spinler      * It is padded with spaces to fill the 32 bytes.
645f9bae185SMatt Spinler      * An example is:
646f9bae185SMatt Spinler      * "BD8D1234                        "
647f9bae185SMatt Spinler      *
648f9bae185SMatt Spinler      * That first word is what is commonly referred to as the refcode, and
649f9bae185SMatt Spinler      * sometimes also called an SRC.
650f9bae185SMatt Spinler      */
651f9bae185SMatt Spinler     std::unique_ptr<src::AsciiString> _asciiString;
652f9bae185SMatt Spinler 
653f9bae185SMatt Spinler     /**
654f9bae185SMatt Spinler      * @brief The callouts subsection.
655f9bae185SMatt Spinler      *
656f9bae185SMatt Spinler      * Optional and only created if there are callouts.
657f9bae185SMatt Spinler      */
658f9bae185SMatt Spinler     std::unique_ptr<src::Callouts> _callouts;
659f9bae185SMatt Spinler };
660f9bae185SMatt Spinler 
661f9bae185SMatt Spinler } // namespace pels
662f9bae185SMatt Spinler } // namespace openpower
663