blob: 36198a16cbac5d602e5998bb02377a5df873e037 [file] [log] [blame]
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -05001/**
2 * Copyright © 2021 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Patrick Williams2544b412022-10-04 08:41:06 -050017extern "C"
18{
Jayanth Othayoth66e186d2021-06-15 22:44:35 -050019#include <libpdbg.h>
20}
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050021
Jayanth Othayothc74c2202021-06-04 06:42:43 -050022#include "fapi_data_process.hpp"
23#include "pel.hpp"
Jayanth Othayoth66e186d2021-06-15 22:44:35 -050024#include "sbe_ffdc_handler.hpp"
Jayanth Othayothc74c2202021-06-04 06:42:43 -050025#include "temporary_file.hpp"
26
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -050027#include <ekb/hwpf/fapi2/include/return_code_defs.H>
devenraoda876612024-02-16 18:48:27 +053028#include <ekb/hwpf/fapi2/include/target_types.H>
Jayanth Othayotheff307e2021-07-15 03:27:01 -050029#include <libekb.H>
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050030
Arya K Padman5bc26532024-04-10 06:19:25 -050031#include <phosphor-logging/lg2.hpp>
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050032
Jayanth Othayoth1aa90d42023-09-13 04:25:45 -050033#include <format>
Patrick Williams2544b412022-10-04 08:41:06 -050034#include <new>
35
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050036namespace openpower
37{
38namespace pels
39{
40namespace sbe
41{
42
devenraob5693742024-02-16 18:33:32 +053043constexpr uint32_t sbeMaxFfdcPackets = 20;
devenraoda876612024-02-16 18:48:27 +053044constexpr uint16_t p10FfdcMagicCode = 0xFFDC;
45constexpr uint16_t pozFfdcMagicCode = 0xFBAD;
46constexpr uint16_t p10FfdcSkipWords = 2;
47constexpr uint16_t pozFfdcSkipWords = 3;
devenraob5693742024-02-16 18:33:32 +053048
devenraoda876612024-02-16 18:48:27 +053049struct p10FfdcHeader
devenraob5693742024-02-16 18:33:32 +053050{
51 uint32_t magic_bytes:16;
52 uint32_t lengthinWords:16;
53 uint32_t seqId:16;
54 uint32_t cmdClass:8;
55 uint32_t cmd:8;
56 uint32_t fapiRc;
devenraoda876612024-02-16 18:48:27 +053057} __attribute__((packed));
58
59struct pozFfdcHeader
60{
61 uint32_t magicByte:16;
62 uint32_t lengthinWords:16;
63 uint32_t seqId:16;
64 uint32_t cmdClass:8;
65 uint32_t cmd:8;
66 uint32_t slid:16;
67 uint32_t severity:8;
68 uint32_t chipId:8;
69 uint32_t fapiRc;
70} __attribute__((packed));
71
72using namespace phosphor::logging;
devenraob5693742024-02-16 18:33:32 +053073
Jayanth Othayoth742b00b2022-06-30 05:16:57 -050074SbeFFDC::SbeFFDC(const AdditionalData& aData, const PelFFDC& files) :
devenraoda876612024-02-16 18:48:27 +053075 ffdcType(FFDC_TYPE_NONE), chipType(fapi2::TARGET_TYPE_PROC_CHIP)
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050076{
Arya K Padman5bc26532024-04-10 06:19:25 -050077 lg2::info("SBE FFDC processing requested");
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050078
79 // SRC6 field in the additional data contains Processor position
80 // associated to the SBE FFDC
81 //"[0:15] chip position"
82 auto src6 = aData.getValue("SRC6");
83 if (src6 == std::nullopt)
84 {
Arya K Padman5bc26532024-04-10 06:19:25 -050085 lg2::error("Fail to extract SRC6 data: failing to get proc index");
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050086 return;
87 }
88 try
89 {
devenraoda876612024-02-16 18:48:27 +053090 chipPos = (std::stoi(src6.value()) & 0xFFFF0000) >> 16;
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050091 }
Patrick Williams66491c62021-10-06 12:23:37 -050092 catch (const std::exception& err)
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050093 {
Arya K Padman5bc26532024-04-10 06:19:25 -050094 lg2::error("Conversion failure errormsg({ERR})", "ERR", err);
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050095 return;
96 }
devenraoda876612024-02-16 18:48:27 +053097 auto type = aData.getValue("CHIP_TYPE");
98 if (type != std::nullopt)
99 {
100 try
101 {
102 chipType = std::stoi(type.value());
103 }
104 catch (const std::exception& err)
105 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500106 lg2::error("Conversion failure errormsg({ERR})", "ERR", err);
devenraoda876612024-02-16 18:48:27 +0530107 return;
108 }
109 }
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -0500110
111 if (files.empty())
112 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500113 lg2::info("SbeFFDC : No files found, skipping ffdc processing");
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -0500114 return;
115 }
116
117 for (const auto& file : files)
118 {
119 if ((file.format == UserDataFormat::custom) &&
120 (file.subType == sbeFFDCSubType))
121 {
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500122 // Process SBE file.
123 parse(file.fd);
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -0500124 }
125 }
126}
127
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500128void SbeFFDC::parse(int fd)
129{
Arya K Padman5bc26532024-04-10 06:19:25 -0500130 lg2::info("SBE FFDC file fd:({FD}), parsing started", "FD", fd);
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500131
132 uint32_t ffdcBufOffset = 0;
133 uint32_t pktCount = 0;
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500134
135 // get SBE FFDC data.
136 auto ffdcData = util::readFD(fd);
137 if (ffdcData.empty())
138 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500139 lg2::error("Empty SBE FFDC file fd:({FD}), skipping", "FD", fd);
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500140 return;
141 }
142
143 while ((ffdcBufOffset < ffdcData.size()) && (sbeMaxFfdcPackets != pktCount))
144 {
devenraoc1a0ff82024-02-16 18:36:20 +0530145 sbeFfdcPacketType ffdcPkt;
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500146 // Next un-extracted FFDC Packet
devenraoda876612024-02-16 18:48:27 +0530147 uint16_t magicBytes =
148 *(reinterpret_cast<uint16_t*>(ffdcData.data() + ffdcBufOffset));
149 magicBytes = ntohs(magicBytes);
150 uint32_t pktLenWords = 0;
151 uint16_t lenWords = 0;
152 if (magicBytes == p10FfdcMagicCode)
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500153 {
devenraoda876612024-02-16 18:48:27 +0530154 p10FfdcHeader* ffdc = reinterpret_cast<p10FfdcHeader*>(
155 ffdcData.data() + ffdcBufOffset);
156 lenWords = ntohs(ffdc->lengthinWords);
157 auto fapiRc = ntohl(ffdc->fapiRc);
158
Arya K Padman5bc26532024-04-10 06:19:25 -0500159 lg2::info(
160 "P10 FFDC magic: {MAGIC_BYTES} length in words:{LEN_WORDS} "
161 "Fapirc:{FAPI_RC}",
162 "MAGIC_BYTES", magicBytes, "LEN_WORDS", lenWords, "FAPI_RC",
163 fapiRc);
devenraoda876612024-02-16 18:48:27 +0530164
165 ffdcPkt.fapiRc = fapiRc;
166 // Not interested in the first 2 words (these are not ffdc)
167 pktLenWords = lenWords - p10FfdcSkipWords;
168 ffdcPkt.ffdcLengthInWords = pktLenWords;
169 if (pktLenWords)
170 {
171 ffdcPkt.ffdcData = new uint32_t[pktLenWords];
172 memcpy(ffdcPkt.ffdcData,
173 ((reinterpret_cast<uint32_t*>(ffdc)) + p10FfdcSkipWords),
174 (pktLenWords * sizeof(uint32_t)));
175 }
176 else
177 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500178 lg2::error("FFDC packet size is zero skipping");
devenraoda876612024-02-16 18:48:27 +0530179 return;
180 }
devenrao4fdb31a2024-02-16 18:51:17 +0530181 pktCount++;
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500182 }
devenraoda876612024-02-16 18:48:27 +0530183 else if (magicBytes == pozFfdcMagicCode)
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500184 {
devenraoda876612024-02-16 18:48:27 +0530185 pozFfdcHeader* ffdc = reinterpret_cast<pozFfdcHeader*>(
186 ffdcData.data() + ffdcBufOffset);
187 lenWords = ntohs(ffdc->lengthinWords);
188 auto fapiRc = ntohl(ffdc->fapiRc);
189
Arya K Padman5bc26532024-04-10 06:19:25 -0500190 lg2::info(
191 "P0Z FFDC magic: {MAGIC_BYTES} length in words:{LEN_WORDS} "
192 "Fapirc:{FAPI_RC}",
193 "MAGIC_BYTES", magicBytes, "LEN_WORDS", lenWords, "FAPI_RC",
194 fapiRc);
devenraoda876612024-02-16 18:48:27 +0530195
196 ffdcPkt.fapiRc = fapiRc;
197 // Not interested in the first 3 words (these are not ffdc)
198 pktLenWords = lenWords - pozFfdcSkipWords;
199 ffdcPkt.ffdcLengthInWords = pktLenWords;
200 if (pktLenWords)
201 {
202 ffdcPkt.ffdcData = new uint32_t[pktLenWords];
203 memcpy(ffdcPkt.ffdcData,
204 ((reinterpret_cast<uint32_t*>(ffdc)) + pozFfdcSkipWords),
205 (pktLenWords * sizeof(uint32_t)));
206 }
207 else
208 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500209 lg2::error("FFDC packet size is zero skipping");
devenraoda876612024-02-16 18:48:27 +0530210 return;
211 }
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500212 }
213 else
214 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500215 lg2::error("Invalid FFDC magic code in Header: Skipping ");
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500216 return;
217 }
218
219 // SBE FFDC processing is not required for SBE Plat errors RCs.
220 // Plat errors processing is driven by SBE provided user data
221 // plugins, which need to link with PEL tool infrastructure.
222 if (ffdcPkt.fapiRc != fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA)
223 {
224 process(ffdcPkt);
225 }
Jayanth Othayothfb9b8112021-10-07 04:10:18 -0500226 else
227 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500228 lg2::info("SBE FFDC: Internal FFDC packet");
Jayanth Othayothfb9b8112021-10-07 04:10:18 -0500229 }
230
231 // Update Buffer offset in Bytes
232 ffdcBufOffset += lenWords * sizeof(uint32_t);
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500233 }
234 if (pktCount == sbeMaxFfdcPackets)
235 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500236 lg2::error("Received more than the limit of ({SBEMAXFFDCPACKETS}) FFDC "
237 "packets, processing only ({PKTCOUNT})",
238 "SBEMAXFFDCPACKETS", sbeMaxFfdcPackets, "PKTCOUNT",
239 pktCount);
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500240 }
241}
242
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500243void SbeFFDC::process(const sbeFfdcPacketType& ffdcPkt)
244{
245 using json = nlohmann::json;
246
247 // formated FFDC data structure after FFDC packet processing
248 FFDC ffdc;
249
Jayanth Othayoth66e186d2021-06-15 22:44:35 -0500250 if (!pdbg_targets_init(NULL))
251 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500252 lg2::error("pdbg_targets_init failed, skipping ffdc processing");
Jayanth Othayoth66e186d2021-06-15 22:44:35 -0500253 return;
254 }
255
Jayanth Othayotheff307e2021-07-15 03:27:01 -0500256 if (libekb_init())
257 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500258 lg2::error("libekb_init failed, skipping ffdc processing");
Jayanth Othayotheff307e2021-07-15 03:27:01 -0500259 return;
260 }
261
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500262 try
263 {
264 // libekb provided wrapper function to convert SBE FFDC
265 // in to known ffdc structure.
devenraoda876612024-02-16 18:48:27 +0530266 libekb_get_sbe_ffdc(ffdc, ffdcPkt, chipPos, chipType);
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500267 }
268 catch (...)
269 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500270 lg2::error("libekb_get_sbe_ffdc failed, skipping ffdc processing");
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500271 return;
272 }
273
Jayanth Othayoth742b00b2022-06-30 05:16:57 -0500274 // update FFDC type class membeir for hwp specific packet
275 // Assumption SBE FFDC contains only one hwp FFDC packet.
276 ffdcType = ffdc.ffdc_type;
277
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500278 // To store callouts details in json format as per pel expectation.
279 json pelJSONFmtCalloutDataList;
280 pelJSONFmtCalloutDataList = json::array();
281
282 // To store other user data from FFDC.
283 openpower::pels::phal::FFDCData ffdcUserData;
284
285 // Get FFDC and required info to include in PEL
286 openpower::pels::phal::convertFAPItoPELformat(
287 ffdc, pelJSONFmtCalloutDataList, ffdcUserData);
288
289 // Get callout information and sore in to file.
290 auto calloutData = pelJSONFmtCalloutDataList.dump();
291 util::TemporaryFile ffdcFile(calloutData.c_str(), calloutData.size());
292
293 // Create json callout type pel FFDC file structre.
294 PelFFDCfile pf;
295 pf.format = openpower::pels::UserDataFormat::json;
296 pf.subType = openpower::pels::jsonCalloutSubtype;
297 pf.version = 0x01;
298 pf.fd = ffdcFile.getFd();
299 ffdcFiles.push_back(pf);
300
301 // save the file path to delete the file after usage.
Matt Spinler8c7bb862023-08-31 14:32:22 -0500302 paths.emplace_back(ffdcFile.getPath(), pf.fd);
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500303
304 // Format ffdc user data and create new file.
305 std::string data;
306 for (auto& d : ffdcUserData)
307 {
308 data += d.first + " = " + d.second + "\n";
309 }
310 util::TemporaryFile pelDataFile(data.c_str(), data.size());
311 PelFFDCfile pdf;
312 pdf.format = openpower::pels::UserDataFormat::text;
313 pdf.version = 0x01;
314 pdf.fd = pelDataFile.getFd();
Matt Spinlerbe952d22022-07-01 11:30:11 -0500315 pdf.subType = 0;
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500316 ffdcFiles.push_back(pdf);
317
Matt Spinler8c7bb862023-08-31 14:32:22 -0500318 paths.emplace_back(pelDataFile.getPath(), pdf.fd);
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500319}
320
Jayanth Othayoth742b00b2022-06-30 05:16:57 -0500321std::optional<LogSeverity> SbeFFDC::getSeverity()
322{
323 if (ffdcType == FFDC_TYPE_SPARE_CLOCK_INFO)
324 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500325 lg2::info(
Jayanth Othayoth742b00b2022-06-30 05:16:57 -0500326 "Found spare clock error, changing severity to informational");
327 return LogSeverity::Informational;
328 }
329 return std::nullopt;
330}
331
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -0500332} // namespace sbe
333} // namespace pels
334} // namespace openpower