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  *   -------------------P10 proc-----------------------
37  *   |        |  Byte 0   |  Byte 1  |  Byte 2    |    Byte 3   |
38  *   |----------------------------------------------------------|
39  *   | Word 0 | Magic Bytes : 0xFFDC | Length in words (N+4)    |
40  *   | Word 1 | [Sequence ID]        | Command-Class | Command  |
41  *   | Word 2 |           Return Code 0..31                     |
42  *   | Word 3 |           FFDC Data – Word 0                    |
43  *   |  ...                                                     |
44  *   | Word N+3 |  FFDC Data – Word N                           |
45  *    -----------------------------------------------------------
46  *
47  *   --------------POZ - PowerOdysseyZEE-----------------------
48  *   First FFDC packet structure
49  *   --------------------------------------------------------------
50  *   |          |  Byte 0   |  Byte 1  |  Byte 2    |    Byte 3   |
51  *   |------------------------------------------------------------|
52  *   | Word 0   | Magic Bytes : 0xFBAD | Length in words (N+4)    |
53  *   | Word 1   | [Sequence ID]        | Command-Class | Command  |
54  *   | Word 2   | SLID                 | Severity      | Chip ID  |
55  *   | Word 3   |           FAPI RC (HWP)                         |
56  *   | Word 4   | HWP FFDC Dump Fields (Local FFDC | HW Register) |
57  *   | Word 6   | Field ID 0(Local FFDC) | Field ID 0 Length      |
58  *   | Word 7   |          Filed Data 0(Size1, data2)             |
59  *   |  ...                                                       |
60  *   | Word N   |          Filed Data N(Size1, data2)             |
61  *   | Word N+1 | Field ID 1(HW Register) | Field ID 1 Length     |
62  *   | Word N+2 |              Filed Data 0)                      |
63  *   |  ...                                                       |
64  *   | Word Y   |              Filed Data M)                      |
65  *    -------------------------------------------------------------
66  *   Second FFDC packet structure
67  *   --------------------------------------------------------------
68  *   |          |  Byte 0   |  Byte 1  |  Byte 2    |    Byte 3   |
69  *   |------------------------------------------------------------|
70  *   | Word 0   | Magic Bytes : 0xFBAD | Length in words (N+4)    |
71  *   | Word 1   | [Sequence ID]        | Command-Class | Command  |
72  *   | Word 2   | SLID                 | Severity      | Chip ID  |
73  *   | Word 3   |       FAPI RC (PLAT ERR SEE DATA)               |
74  *   | Word 4   | Primary Status       | Secondary Status         |
75  *   | Word 5   |             FW commit ID                        |
76  *   | Word 5   | Reserve | DD Major   | DD Minor      | Thread ID|
77  *   | Word 4   |         SBE FFDC Dump Fields (Bitmaped)         |
78  *   | Word 6   | Field ID 0           | Field ID 0 Length        |
79  *   | Word 7   |              Filed Data 0                       |
80  *   |  ...                                                       |
81  *   | Word N   |              Filed Data N                       |
82  *   | Word N+1 | Field ID 1           | Field ID 1 Length        |
83  *   | Word N+2 |       Filed Data 0)                             |
84  *   |  ...                                                       |
85  *   | Word Y   |       Filed Data M)                             |
86  *   | Word Y+1 | 0xCODE               | 0xA8         | 0x1       |
87  *   | Word Y+2 | Primary Status       | Secondary Status         |
88  *   | Word Y+3 |          Distance to Header                     |
89  *    -------------------------------------------------------------
90  *
91  **/
92 
93 using LogSeverity = phosphor::logging::Entry::Level;
94 
95 /** @class SbeFFDC
96  *
97  * @brief This class provides higher level interface to process SBE ffdc
98  * for PEL based error logging infrastructure.
99  * Key Functionalities included here
100  *    - Process the SBE FFDC data with the help of FAPI infrastructure and
101  *      and create PEL required format Callout and user data for hardware
102  *      procedure failures specific reason code
103  *    - Add the user data section with SBE FFDC data to support SBE provided
104  *      parser tool usage.
105  *    - Any SBE FFDC processing will result additional log message in journal
106  *      and will continue to create Error log with available data. This is to
107  *      help user to analyse the failure.
108  */
109 class SbeFFDC
110 {
111   public:
112     SbeFFDC() = delete;
113     SbeFFDC(const SbeFFDC&) = delete;
114     SbeFFDC& operator=(const SbeFFDC&) = delete;
115     SbeFFDC(SbeFFDC&&) = delete;
116     SbeFFDC& operator=(SbeFFDC&&) = delete;
117 
118     /**
119      * @brief Constructor
120      *
121      * Create PEL required format data from SBE provided FFDC data.
122      *
123      * @param[in] data - The AdditionalData properties in this PEL event
124      * @param[in] files - FFDC files that go into UserData sections
125      */
126     SbeFFDC(const AdditionalData& data, const PelFFDC& files);
127 
128     /**
129      * @brief Destructor
130      *
131      * Deletes the temporary files
132      */
133     ~SbeFFDC()
134     {
135         try
136         {
137             for (const auto& [path, fd] : paths)
138             {
139                 if (!path.empty())
140                 {
141                     // Delete temporary file from file system
142                     std::error_code ec;
143                     std::filesystem::remove(path, ec);
144                 }
145 
146                 if (fd != -1)
147                 {
148                     close(fd);
149                 }
150             }
151             paths.clear();
152         }
153         catch (...)
154         {
155             // Destructors should not throw exceptions
156         }
157     }
158 
159     /**
160      * @brief Helper function to return FFDC files information, which
161      *        includes SBE FFDC specific callout information.
162      *
163      * return PelFFDC - pel formated FFDC files.
164      */
165     const PelFFDC& getSbeFFDC()
166     {
167         return ffdcFiles;
168     }
169 
170     /**
171      * @brief Helper function to get severity type
172      *
173      * @return severity type as informational for spare clock
174      *         failure type ffdc. Otherwise null string.
175      */
176     std::optional<LogSeverity> getSeverity();
177 
178   private:
179     /**
180      * @brief Helper function to parse SBE FFDC file.
181      *        parsing is based on the FFDC structure definition
182      *        define initially in this file.
183      *
184      * @param fd  SBE ffdc file descriptor
185      *
186      * Any failure during the process stops the function
187      * execution to support the raw SBE FFDC data based
188      * PEL creation.
189      */
190     void parse(int fd);
191 
192     /**
193      * @brief Helper function to process SBE FFDC packet.
194      * This function call libekb function to process the
195      * FFDC packet and convert in to known format for PEL
196      * specific file creation. This function also creates
197      * json callout file and text type file, which includes
198      * the addition debug data included in SBE FFDC packet.
199      *
200      * @param ffdcPkt  SBE FFDC packet
201      *
202      * Any failure during the process stops the function
203      * execution to support the raw SBE FFDC data based
204      * PEL creation.
205      */
206     void process(const sbeFfdcPacketType& ffdcPkt);
207 
208     /**
209      * @brief  Temporary files path and FD information created as part of FFDC
210      *         processing.
211      */
212     std::vector<std::pair<std::filesystem::path, int>> paths;
213 
214     /**
215      * @brief PEL FFDC files, which includes the user data sections and the
216      *        added callout details if any, found during SBE FFDC processing.
217      */
218     PelFFDC ffdcFiles;
219 
220     /**
221      * @brief Chip position associated to SBE FFDC
222      */
223     uint32_t chipPos;
224 
225     /**
226      * @brief Used to get type of ffdc
227      */
228     FFDC_TYPE ffdcType;
229 
230     /**
231      * @brief Chip type associated to SBE FFDC
232      */
233     uint32_t chipType;
234 };
235 
236 } // namespace sbe
237 } // namespace pels
238 } // namespace openpower
239