1 #pragma once
2 
3 #include "additional_data.hpp"
4 #include "pel.hpp"
5 
6 #include <libekb.H>
7 
8 #include <filesystem>
9 
10 namespace openpower
11 {
12 namespace pels
13 {
14 namespace sbe
15 {
16 
17 // SBE FFDC sub type.
18 constexpr uint8_t sbeFFDCSubType = 0xCB;
19 
20 /**
21  *   @brief FFDC Package structure and definitions based on SBE chip-op spec.
22  *
23  *   SBE FFDC Starts with a header word (Word 0) that has an unique magic
24  *   identifier code of 0xFFDC followed by the length of the FFDC package
25  *   including the header itself. Word 1 contains a sequence id ,
26  *   command-class and command fields.
27  *   The sequence id field is ignored on the BMC side.
28  *   Word 2 contains a 32 bit Return Code which acts like the key to the
29  *   contents of subsequent FFDC Data Words (0-N).
30  *
31  *   A FFDC package can typically contain debug data from either:
32  *    1. A failed hardware procedure (e.g. local variable values
33  *       at point of failure) or
34  *    2. SBE firmware (e.g. traces, attributes and other information).
35  *    ___________________________________________________________
36  *   |        |  Byte 0   |  Byte 1  |  Byte 2    |    Byte 3   |
37  *   |----------------------------------------------------------|
38  *   | Word 0 | Magic Bytes : 0xFFDC | Length in words (N+4)    |
39  *   | Word 1 | [Sequence ID]        | Command-Class | Command  |
40  *   | Word 2 |           Return Code 0..31                     |
41  *   | Word 3 |           FFDC Data – Word 0                    |
42  *   |  ...                                                     |
43  *   | Word N+3 |  FFDC Data – Word N                           |
44  *    -----------------------------------------------------------
45  **/
46 
47 constexpr uint32_t sbeMaxFfdcPackets = 20;
48 constexpr uint32_t ffdcPkgOneWord = 1;
49 const uint16_t ffdcMagicCode = 0xFFDC;
50 
51 typedef struct
52 {
53     uint32_t magic_bytes:16;
54     uint32_t lengthinWords:16;
55     uint32_t seqId:16;
56     uint32_t cmdClass:8;
57     uint32_t cmd:8;
58     uint32_t fapiRc;
59 } __attribute__((packed)) fapiFfdcBufType;
60 
61 using LogSeverity = phosphor::logging::Entry::Level;
62 
63 /** @class SbeFFDC
64  *
65  * @brief This class provides higher level interface to process SBE ffdc
66  * for PEL based error logging infrastructure.
67  * Key Functionalities included here
68  *    - Process the SBE FFDC data with the help of FAPI infrastructure and
69  *      and create PEL required format Callout and user data for hardware
70  *      procedure failures specific reason code
71  *    - Add the user data section with SBE FFDC data to support SBE provided
72  *      parser tool usage.
73  *    - Any SBE FFDC processing will result additional log message in journal
74  *      and will continue to create Error log with available data. This is to
75  *      help user to analyse the failure.
76  */
77 class SbeFFDC
78 {
79   public:
80     SbeFFDC() = delete;
81     SbeFFDC(const SbeFFDC&) = delete;
82     SbeFFDC& operator=(const SbeFFDC&) = delete;
83     SbeFFDC(SbeFFDC&&) = delete;
84     SbeFFDC& operator=(SbeFFDC&&) = delete;
85 
86     /**
87      * @brief Constructor
88      *
89      * Create PEL required format data from SBE provided FFDC data.
90      *
91      * @param[in] data - The AdditionalData properties in this PEL event
92      * @param[in] files - FFDC files that go into UserData sections
93      */
94     SbeFFDC(const AdditionalData& data, const PelFFDC& files);
95 
96     /**
97      * @brief Destructor
98      *
99      * Deletes the temporary files
100      */
101     ~SbeFFDC()
102     {
103         try
104         {
105             for (const auto& [path, fd] : paths)
106             {
107                 if (!path.empty())
108                 {
109                     // Delete temporary file from file system
110                     std::error_code ec;
111                     std::filesystem::remove(path, ec);
112                 }
113 
114                 if (fd != -1)
115                 {
116                     close(fd);
117                 }
118             }
119             paths.clear();
120         }
121         catch (...)
122         {
123             // Destructors should not throw exceptions
124         }
125     }
126 
127     /**
128      * @brief Helper function to return FFDC files information, which
129      *        includes SBE FFDC specific callout information.
130      *
131      * return PelFFDC - pel formated FFDC files.
132      */
133     const PelFFDC& getSbeFFDC()
134     {
135         return ffdcFiles;
136     }
137 
138     /**
139      * @brief Helper function to get severity type
140      *
141      * @return severity type as informational for spare clock
142      *         failure type ffdc. Otherwise null string.
143      */
144     std::optional<LogSeverity> getSeverity();
145 
146   private:
147     /**
148      * @brief Helper function to parse SBE FFDC file.
149      *        parsing is based on the FFDC structure definition
150      *        define initially in this file.
151      *
152      * @param fd  SBE ffdc file descriptor
153      *
154      * Any failure during the process stops the function
155      * execution to support the raw SBE FFDC data based
156      * PEL creation.
157      */
158     void parse(int fd);
159 
160     /**
161      * @brief Helper function to process SBE FFDC packet.
162      * This function call libekb function to process the
163      * FFDC packet and convert in to known format for PEL
164      * specific file creation. This function also creates
165      * json callout file and text type file, which includes
166      * the addition debug data included in SBE FFDC packet.
167      *
168      * @param ffdcPkt  SBE FFDC packet
169      *
170      * Any failure during the process stops the function
171      * execution to support the raw SBE FFDC data based
172      * PEL creation.
173      */
174     void process(const sbeFfdcPacketType& ffdcPkt);
175 
176     /**
177      * @brief  Temporary files path and FD information created as part of FFDC
178      *         processing.
179      */
180     std::vector<std::pair<std::filesystem::path, int>> paths;
181 
182     /**
183      * @brief PEL FFDC files, which includes the user data sections and the
184      *        added callout details if any, found during SBE FFDC processing.
185      */
186     PelFFDC ffdcFiles;
187 
188     /**
189      * @brief Processor position associated to SBE FFDC
190      */
191     uint32_t procPos;
192 
193     /**
194      * @brief Used to get type of ffdc
195      */
196     FFDC_TYPE ffdcType;
197 };
198 
199 } // namespace sbe
200 } // namespace pels
201 } // namespace openpower
202