blob: 908fe2047f85132b9c9a9192ccf91cff6f8ba822 [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
Patrick Williams2544b412022-10-04 08:41:06 -050033#include <new>
34
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050035namespace openpower
36{
37namespace pels
38{
39namespace sbe
40{
41
devenraob5693742024-02-16 18:33:32 +053042constexpr uint32_t sbeMaxFfdcPackets = 20;
devenraoda876612024-02-16 18:48:27 +053043constexpr uint16_t p10FfdcMagicCode = 0xFFDC;
44constexpr uint16_t pozFfdcMagicCode = 0xFBAD;
45constexpr uint16_t p10FfdcSkipWords = 2;
46constexpr uint16_t pozFfdcSkipWords = 3;
devenraob5693742024-02-16 18:33:32 +053047
devenraoda876612024-02-16 18:48:27 +053048struct p10FfdcHeader
devenraob5693742024-02-16 18:33:32 +053049{
50 uint32_t magic_bytes:16;
51 uint32_t lengthinWords:16;
52 uint32_t seqId:16;
53 uint32_t cmdClass:8;
54 uint32_t cmd:8;
55 uint32_t fapiRc;
devenraoda876612024-02-16 18:48:27 +053056} __attribute__((packed));
57
58struct pozFfdcHeader
59{
60 uint32_t magicByte:16;
61 uint32_t lengthinWords:16;
62 uint32_t seqId:16;
63 uint32_t cmdClass:8;
64 uint32_t cmd:8;
65 uint32_t slid:16;
66 uint32_t severity:8;
67 uint32_t chipId:8;
68 uint32_t fapiRc;
69} __attribute__((packed));
70
71using namespace phosphor::logging;
devenraob5693742024-02-16 18:33:32 +053072
Jayanth Othayoth742b00b2022-06-30 05:16:57 -050073SbeFFDC::SbeFFDC(const AdditionalData& aData, const PelFFDC& files) :
devenraoda876612024-02-16 18:48:27 +053074 ffdcType(FFDC_TYPE_NONE), chipType(fapi2::TARGET_TYPE_PROC_CHIP)
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050075{
Arya K Padman5bc26532024-04-10 06:19:25 -050076 lg2::info("SBE FFDC processing requested");
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050077
78 // SRC6 field in the additional data contains Processor position
79 // associated to the SBE FFDC
80 //"[0:15] chip position"
81 auto src6 = aData.getValue("SRC6");
82 if (src6 == std::nullopt)
83 {
Arya K Padman5bc26532024-04-10 06:19:25 -050084 lg2::error("Fail to extract SRC6 data: failing to get proc index");
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050085 return;
86 }
87 try
88 {
devenraoda876612024-02-16 18:48:27 +053089 chipPos = (std::stoi(src6.value()) & 0xFFFF0000) >> 16;
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050090 }
Patrick Williams66491c62021-10-06 12:23:37 -050091 catch (const std::exception& err)
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050092 {
Arya K Padman5bc26532024-04-10 06:19:25 -050093 lg2::error("Conversion failure errormsg({ERR})", "ERR", err);
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -050094 return;
95 }
devenraoda876612024-02-16 18:48:27 +053096 auto type = aData.getValue("CHIP_TYPE");
97 if (type != std::nullopt)
98 {
99 try
100 {
101 chipType = std::stoi(type.value());
102 }
103 catch (const std::exception& err)
104 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500105 lg2::error("Conversion failure errormsg({ERR})", "ERR", err);
devenraoda876612024-02-16 18:48:27 +0530106 return;
107 }
108 }
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -0500109
110 if (files.empty())
111 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500112 lg2::info("SbeFFDC : No files found, skipping ffdc processing");
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -0500113 return;
114 }
115
116 for (const auto& file : files)
117 {
118 if ((file.format == UserDataFormat::custom) &&
119 (file.subType == sbeFFDCSubType))
120 {
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500121 // Process SBE file.
122 parse(file.fd);
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -0500123 }
124 }
125}
126
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500127void SbeFFDC::parse(int fd)
128{
Arya K Padman5bc26532024-04-10 06:19:25 -0500129 lg2::info("SBE FFDC file fd:({FD}), parsing started", "FD", fd);
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500130
131 uint32_t ffdcBufOffset = 0;
132 uint32_t pktCount = 0;
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500133
134 // get SBE FFDC data.
135 auto ffdcData = util::readFD(fd);
136 if (ffdcData.empty())
137 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500138 lg2::error("Empty SBE FFDC file fd:({FD}), skipping", "FD", fd);
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500139 return;
140 }
141
142 while ((ffdcBufOffset < ffdcData.size()) && (sbeMaxFfdcPackets != pktCount))
143 {
devenraoc1a0ff82024-02-16 18:36:20 +0530144 sbeFfdcPacketType ffdcPkt;
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500145 // Next un-extracted FFDC Packet
devenraoda876612024-02-16 18:48:27 +0530146 uint16_t magicBytes =
147 *(reinterpret_cast<uint16_t*>(ffdcData.data() + ffdcBufOffset));
148 magicBytes = ntohs(magicBytes);
149 uint32_t pktLenWords = 0;
150 uint16_t lenWords = 0;
151 if (magicBytes == p10FfdcMagicCode)
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500152 {
devenraoda876612024-02-16 18:48:27 +0530153 p10FfdcHeader* ffdc = reinterpret_cast<p10FfdcHeader*>(
154 ffdcData.data() + ffdcBufOffset);
155 lenWords = ntohs(ffdc->lengthinWords);
156 auto fapiRc = ntohl(ffdc->fapiRc);
157
Arya K Padman5bc26532024-04-10 06:19:25 -0500158 lg2::info(
159 "P10 FFDC magic: {MAGIC_BYTES} length in words:{LEN_WORDS} "
160 "Fapirc:{FAPI_RC}",
161 "MAGIC_BYTES", magicBytes, "LEN_WORDS", lenWords, "FAPI_RC",
162 fapiRc);
devenraoda876612024-02-16 18:48:27 +0530163
164 ffdcPkt.fapiRc = fapiRc;
165 // Not interested in the first 2 words (these are not ffdc)
166 pktLenWords = lenWords - p10FfdcSkipWords;
167 ffdcPkt.ffdcLengthInWords = pktLenWords;
168 if (pktLenWords)
169 {
170 ffdcPkt.ffdcData = new uint32_t[pktLenWords];
171 memcpy(ffdcPkt.ffdcData,
172 ((reinterpret_cast<uint32_t*>(ffdc)) + p10FfdcSkipWords),
173 (pktLenWords * sizeof(uint32_t)));
174 }
175 else
176 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500177 lg2::error("FFDC packet size is zero skipping");
devenraoda876612024-02-16 18:48:27 +0530178 return;
179 }
devenrao4fdb31a2024-02-16 18:51:17 +0530180 pktCount++;
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500181 }
devenraoda876612024-02-16 18:48:27 +0530182 else if (magicBytes == pozFfdcMagicCode)
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500183 {
devenraoda876612024-02-16 18:48:27 +0530184 pozFfdcHeader* ffdc = reinterpret_cast<pozFfdcHeader*>(
185 ffdcData.data() + ffdcBufOffset);
186 lenWords = ntohs(ffdc->lengthinWords);
187 auto fapiRc = ntohl(ffdc->fapiRc);
188
Arya K Padman5bc26532024-04-10 06:19:25 -0500189 lg2::info(
190 "P0Z FFDC magic: {MAGIC_BYTES} length in words:{LEN_WORDS} "
191 "Fapirc:{FAPI_RC}",
192 "MAGIC_BYTES", magicBytes, "LEN_WORDS", lenWords, "FAPI_RC",
193 fapiRc);
devenraoda876612024-02-16 18:48:27 +0530194
195 ffdcPkt.fapiRc = fapiRc;
196 // Not interested in the first 3 words (these are not ffdc)
197 pktLenWords = lenWords - pozFfdcSkipWords;
198 ffdcPkt.ffdcLengthInWords = pktLenWords;
199 if (pktLenWords)
200 {
201 ffdcPkt.ffdcData = new uint32_t[pktLenWords];
202 memcpy(ffdcPkt.ffdcData,
203 ((reinterpret_cast<uint32_t*>(ffdc)) + pozFfdcSkipWords),
204 (pktLenWords * sizeof(uint32_t)));
205 }
206 else
207 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500208 lg2::error("FFDC packet size is zero skipping");
devenraoda876612024-02-16 18:48:27 +0530209 return;
210 }
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500211 }
212 else
213 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500214 lg2::error("Invalid FFDC magic code in Header: Skipping ");
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500215 return;
216 }
217
218 // SBE FFDC processing is not required for SBE Plat errors RCs.
219 // Plat errors processing is driven by SBE provided user data
220 // plugins, which need to link with PEL tool infrastructure.
221 if (ffdcPkt.fapiRc != fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA)
222 {
223 process(ffdcPkt);
224 }
Jayanth Othayothfb9b8112021-10-07 04:10:18 -0500225 else
226 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500227 lg2::info("SBE FFDC: Internal FFDC packet");
Jayanth Othayothfb9b8112021-10-07 04:10:18 -0500228 }
229
230 // Update Buffer offset in Bytes
231 ffdcBufOffset += lenWords * sizeof(uint32_t);
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500232 }
233 if (pktCount == sbeMaxFfdcPackets)
234 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500235 lg2::error("Received more than the limit of ({SBEMAXFFDCPACKETS}) FFDC "
236 "packets, processing only ({PKTCOUNT})",
237 "SBEMAXFFDCPACKETS", sbeMaxFfdcPackets, "PKTCOUNT",
238 pktCount);
Jayanth Othayoth0866c3f2021-06-07 07:06:20 -0500239 }
240}
241
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500242void SbeFFDC::process(const sbeFfdcPacketType& ffdcPkt)
243{
244 using json = nlohmann::json;
245
246 // formated FFDC data structure after FFDC packet processing
247 FFDC ffdc;
248
249 try
250 {
251 // libekb provided wrapper function to convert SBE FFDC
252 // in to known ffdc structure.
devenraoda876612024-02-16 18:48:27 +0530253 libekb_get_sbe_ffdc(ffdc, ffdcPkt, chipPos, chipType);
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500254 }
255 catch (...)
256 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500257 lg2::error("libekb_get_sbe_ffdc failed, skipping ffdc processing");
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500258 return;
259 }
260
Jayanth Othayoth742b00b2022-06-30 05:16:57 -0500261 // update FFDC type class membeir for hwp specific packet
262 // Assumption SBE FFDC contains only one hwp FFDC packet.
263 ffdcType = ffdc.ffdc_type;
264
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500265 // To store callouts details in json format as per pel expectation.
266 json pelJSONFmtCalloutDataList;
267 pelJSONFmtCalloutDataList = json::array();
268
269 // To store other user data from FFDC.
270 openpower::pels::phal::FFDCData ffdcUserData;
271
272 // Get FFDC and required info to include in PEL
273 openpower::pels::phal::convertFAPItoPELformat(
274 ffdc, pelJSONFmtCalloutDataList, ffdcUserData);
275
276 // Get callout information and sore in to file.
277 auto calloutData = pelJSONFmtCalloutDataList.dump();
278 util::TemporaryFile ffdcFile(calloutData.c_str(), calloutData.size());
279
280 // Create json callout type pel FFDC file structre.
281 PelFFDCfile pf;
282 pf.format = openpower::pels::UserDataFormat::json;
283 pf.subType = openpower::pels::jsonCalloutSubtype;
284 pf.version = 0x01;
285 pf.fd = ffdcFile.getFd();
286 ffdcFiles.push_back(pf);
287
288 // save the file path to delete the file after usage.
Matt Spinler8c7bb862023-08-31 14:32:22 -0500289 paths.emplace_back(ffdcFile.getPath(), pf.fd);
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500290
291 // Format ffdc user data and create new file.
292 std::string data;
293 for (auto& d : ffdcUserData)
294 {
295 data += d.first + " = " + d.second + "\n";
296 }
297 util::TemporaryFile pelDataFile(data.c_str(), data.size());
298 PelFFDCfile pdf;
299 pdf.format = openpower::pels::UserDataFormat::text;
300 pdf.version = 0x01;
301 pdf.fd = pelDataFile.getFd();
Matt Spinlerbe952d22022-07-01 11:30:11 -0500302 pdf.subType = 0;
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500303 ffdcFiles.push_back(pdf);
304
Matt Spinler8c7bb862023-08-31 14:32:22 -0500305 paths.emplace_back(pelDataFile.getPath(), pdf.fd);
Jayanth Othayothc74c2202021-06-04 06:42:43 -0500306}
307
Jayanth Othayoth742b00b2022-06-30 05:16:57 -0500308std::optional<LogSeverity> SbeFFDC::getSeverity()
309{
310 if (ffdcType == FFDC_TYPE_SPARE_CLOCK_INFO)
311 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500312 lg2::info(
Jayanth Othayoth742b00b2022-06-30 05:16:57 -0500313 "Found spare clock error, changing severity to informational");
314 return LogSeverity::Informational;
315 }
316 return std::nullopt;
317}
318
Jayanth Othayothe8bdeea2021-06-03 03:01:16 -0500319} // namespace sbe
320} // namespace pels
321} // namespace openpower