Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 1 | #include "create_pel.hpp" |
| 2 | |
Jayanth Othayoth | e5ba5fd | 2022-01-27 09:29:01 -0600 | [diff] [blame] | 3 | #include "attributes_info.H" |
| 4 | |
Jayanth Othayoth | c483181 | 2021-06-08 01:33:40 -0500 | [diff] [blame] | 5 | #include "util.hpp" |
| 6 | |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 7 | #include <fcntl.h> |
| 8 | #include <fmt/format.h> |
| 9 | #include <libekb.H> |
Jayanth Othayoth | e5ba5fd | 2022-01-27 09:29:01 -0600 | [diff] [blame] | 10 | #include <libphal.H> |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 11 | #include <unistd.h> |
| 12 | |
Brad Bishop | 5e5d445 | 2020-10-27 19:46:13 -0400 | [diff] [blame] | 13 | #include <phosphor-logging/elog.hpp> |
| 14 | #include <xyz/openbmc_project/Logging/Create/server.hpp> |
| 15 | #include <xyz/openbmc_project/Logging/Entry/server.hpp> |
| 16 | |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 17 | #include <cerrno> |
| 18 | #include <cstdio> |
| 19 | #include <cstdlib> |
| 20 | #include <cstring> |
| 21 | #include <map> |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 22 | #include <stdexcept> |
| 23 | #include <string> |
| 24 | #include <tuple> |
| 25 | #include <vector> |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 26 | |
| 27 | namespace openpower |
| 28 | { |
| 29 | using namespace phosphor::logging; |
| 30 | |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 31 | namespace pel |
| 32 | { |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 33 | |
| 34 | constexpr auto loggingObjectPath = "/xyz/openbmc_project/logging"; |
| 35 | constexpr auto loggingInterface = "xyz.openbmc_project.Logging.Create"; |
Jayanth Othayoth | fe37aea | 2021-10-07 04:41:26 -0500 | [diff] [blame] | 36 | constexpr auto opLoggingInterface = "org.open_power.Logging.PEL"; |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 37 | |
Jayanth Othayoth | e5ba5fd | 2022-01-27 09:29:01 -0600 | [diff] [blame] | 38 | /** |
| 39 | * @brief get SBE special callout information |
| 40 | * |
| 41 | * This function add the special sbe callout in the user provided |
| 42 | * json callout list. includes BMC0002 procedure callout with |
| 43 | * high priority and processor callout with medium priority. |
| 44 | * |
| 45 | * @param[in] procTarget - pdbg processor target |
| 46 | * @param[out] jsonCalloutDataList - reference to json callout list |
| 47 | */ |
| 48 | static void getSBECallout(struct pdbg_target* procTarget, |
| 49 | json& jsonCalloutDataList) |
| 50 | { |
| 51 | using namespace openpower::phal::pdbg; |
| 52 | |
| 53 | json jsonProcedCallout; |
| 54 | |
| 55 | // Add procedure callout |
| 56 | jsonProcedCallout["Procedure"] = "BMC0002"; |
| 57 | jsonProcedCallout["Priority"] = "H"; |
| 58 | jsonCalloutDataList.emplace_back(std::move(jsonProcedCallout)); |
| 59 | try |
| 60 | { |
| 61 | ATTR_LOCATION_CODE_Type locationCode; |
| 62 | // Initialize with default data. |
| 63 | memset(&locationCode, '\0', sizeof(locationCode)); |
| 64 | // Get location code information |
| 65 | openpower::phal::pdbg::getLocationCode(procTarget, locationCode); |
| 66 | json jsonProcCallout; |
| 67 | jsonProcCallout["LocationCode"] = locationCode; |
| 68 | jsonProcCallout["Deconfigured"] = false; |
| 69 | jsonProcCallout["Guarded"] = false; |
| 70 | jsonProcCallout["Priority"] = "M"; |
| 71 | jsonCalloutDataList.emplace_back(std::move(jsonProcCallout)); |
| 72 | } |
| 73 | catch (const std::exception& e) |
| 74 | { |
| 75 | log<level::ERR>(fmt::format("getLocationCode({}): Exception({})", |
| 76 | pdbg_target_path(procTarget), e.what()) |
| 77 | .c_str()); |
| 78 | } |
| 79 | } |
| 80 | |
Jayanth Othayoth | 8fe9ff9 | 2021-11-14 09:15:59 -0600 | [diff] [blame] | 81 | void createErrorPEL(const std::string& event, const json& calloutData, |
Marri Devender Rao | 4d5b5bf | 2022-05-23 09:23:31 -0500 | [diff] [blame] | 82 | const FFDCData& ffdcData, const Severity severity) |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 83 | { |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 84 | std::map<std::string, std::string> additionalData; |
| 85 | auto bus = sdbusplus::bus::new_default(); |
| 86 | additionalData.emplace("_PID", std::to_string(getpid())); |
| 87 | for (auto& data : ffdcData) |
| 88 | { |
| 89 | additionalData.emplace(data); |
| 90 | } |
| 91 | |
| 92 | try |
| 93 | { |
| 94 | FFDCFile ffdcFile(calloutData); |
| 95 | |
| 96 | std::vector<std::tuple<sdbusplus::xyz::openbmc_project::Logging:: |
| 97 | server::Create::FFDCFormat, |
| 98 | uint8_t, uint8_t, sdbusplus::message::unix_fd>> |
| 99 | pelCalloutInfo; |
| 100 | |
| 101 | pelCalloutInfo.push_back( |
| 102 | std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server:: |
| 103 | Create::FFDCFormat::JSON, |
| 104 | static_cast<uint8_t>(0xCA), |
| 105 | static_cast<uint8_t>(0x01), ffdcFile.getFileFD())); |
| 106 | |
Patrick Williams | 00dd33e | 2023-05-10 07:50:37 -0500 | [diff] [blame^] | 107 | std::string service = util::getService(bus, loggingObjectPath, |
| 108 | loggingInterface); |
| 109 | auto method = bus.new_method_call(service.c_str(), loggingObjectPath, |
| 110 | loggingInterface, |
| 111 | "CreateWithFFDCFiles"); |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 112 | auto level = |
| 113 | sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage( |
Marri Devender Rao | 4d5b5bf | 2022-05-23 09:23:31 -0500 | [diff] [blame] | 114 | severity); |
Jayanth Othayoth | 8fe9ff9 | 2021-11-14 09:15:59 -0600 | [diff] [blame] | 115 | method.append(event, level, additionalData, pelCalloutInfo); |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 116 | auto resp = bus.call(method); |
| 117 | } |
Patrick Williams | aaea686 | 2022-07-22 19:26:54 -0500 | [diff] [blame] | 118 | catch (const sdbusplus::exception_t& e) |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 119 | { |
Jayanth Othayoth | 8fe9ff9 | 2021-11-14 09:15:59 -0600 | [diff] [blame] | 120 | log<level::ERR>( |
| 121 | fmt::format("D-Bus call exception", |
| 122 | "OBJPATH={}, INTERFACE={}, event={}, EXCEPTION={}", |
| 123 | loggingObjectPath, loggingInterface, event, e.what()) |
| 124 | .c_str()); |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 125 | throw std::runtime_error( |
| 126 | "Error in invoking D-Bus logging create interface"); |
| 127 | } |
Patrick Williams | 1a9a5a6 | 2021-10-06 13:05:06 -0500 | [diff] [blame] | 128 | catch (const std::exception& e) |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 129 | { |
| 130 | throw e; |
| 131 | } |
| 132 | } |
| 133 | |
Jayanth Othayoth | fe37aea | 2021-10-07 04:41:26 -0500 | [diff] [blame] | 134 | uint32_t createSbeErrorPEL(const std::string& event, const sbeError_t& sbeError, |
Jayanth Othayoth | e5ba5fd | 2022-01-27 09:29:01 -0600 | [diff] [blame] | 135 | const FFDCData& ffdcData, |
| 136 | struct pdbg_target* procTarget, |
| 137 | const Severity severity) |
Jayanth Othayoth | 2eb31ad | 2021-09-20 07:13:28 -0500 | [diff] [blame] | 138 | { |
Jayanth Othayoth | fe37aea | 2021-10-07 04:41:26 -0500 | [diff] [blame] | 139 | uint32_t plid = 0; |
Jayanth Othayoth | 2eb31ad | 2021-09-20 07:13:28 -0500 | [diff] [blame] | 140 | std::map<std::string, std::string> additionalData; |
| 141 | auto bus = sdbusplus::bus::new_default(); |
| 142 | |
| 143 | additionalData.emplace("_PID", std::to_string(getpid())); |
| 144 | additionalData.emplace("SBE_ERR_MSG", sbeError.what()); |
| 145 | |
| 146 | for (auto& data : ffdcData) |
| 147 | { |
| 148 | additionalData.emplace(data); |
| 149 | } |
| 150 | |
| 151 | std::vector<std::tuple< |
| 152 | sdbusplus::xyz::openbmc_project::Logging::server::Create::FFDCFormat, |
| 153 | uint8_t, uint8_t, sdbusplus::message::unix_fd>> |
| 154 | pelFFDCInfo; |
| 155 | |
Jayanth Othayoth | fe37aea | 2021-10-07 04:41:26 -0500 | [diff] [blame] | 156 | // get SBE ffdc file descriptor |
| 157 | auto fd = sbeError.getFd(); |
| 158 | |
| 159 | // Negative fd value indicates error case or invalid file |
| 160 | // No need of special processing , just log error with additional ffdc. |
| 161 | if (fd > 0) |
| 162 | { |
| 163 | // Refer phosphor-logging/extensions/openpower-pels/README.md section |
| 164 | // "Self Boot Engine(SBE) First Failure Data Capture(FFDC) Support" |
| 165 | // for details of related to createPEL with SBE FFDC information |
| 166 | // usin g CreateWithFFDCFiles api. |
| 167 | pelFFDCInfo.push_back( |
| 168 | std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server:: |
| 169 | Create::FFDCFormat::Custom, |
| 170 | static_cast<uint8_t>(0xCB), |
| 171 | static_cast<uint8_t>(0x01), sbeError.getFd())); |
| 172 | } |
Jayanth Othayoth | e5ba5fd | 2022-01-27 09:29:01 -0600 | [diff] [blame] | 173 | |
| 174 | // Workaround : currently sbe_extract_rc hwp procedure based callout |
| 175 | // handling is not available. openbmc issue #2917 |
| 176 | // As per discussion with RAS team adding additional callout for |
| 177 | // SBE timeout error case, till this hwp based error handling in place. |
| 178 | // Note: PEL needs ffdcFile file till pel creation. This is forced to |
| 179 | // define ffdcFile function level scope. |
| 180 | std::unique_ptr<FFDCFile> FFDCFilePtr; |
| 181 | try |
| 182 | { |
Jayanth Othayoth | 8e93c1c | 2022-06-02 08:59:08 -0500 | [diff] [blame] | 183 | if ((event == "org.open_power.Processor.Error.SbeBootTimeout") && |
Jayanth Othayoth | e5ba5fd | 2022-01-27 09:29:01 -0600 | [diff] [blame] | 184 | (severity == Severity::Error)) |
| 185 | { |
| 186 | json jsonCalloutDataList; |
| 187 | jsonCalloutDataList = json::array(); |
| 188 | getSBECallout(procTarget, jsonCalloutDataList); |
| 189 | FFDCFilePtr = std::make_unique<FFDCFile>(jsonCalloutDataList); |
| 190 | pelFFDCInfo.push_back(std::make_tuple( |
| 191 | sdbusplus::xyz::openbmc_project::Logging::server::Create:: |
| 192 | FFDCFormat::JSON, |
| 193 | static_cast<uint8_t>(0xCA), static_cast<uint8_t>(0x01), |
| 194 | FFDCFilePtr->getFileFD())); |
| 195 | } |
| 196 | } |
| 197 | catch (const std::exception& e) |
| 198 | { |
| 199 | log<level::ERR>( |
| 200 | fmt::format("Skipping SBE special callout due to Exception({})", |
| 201 | e.what()) |
| 202 | .c_str()); |
| 203 | } |
| 204 | |
Jayanth Othayoth | 2eb31ad | 2021-09-20 07:13:28 -0500 | [diff] [blame] | 205 | try |
| 206 | { |
Patrick Williams | 00dd33e | 2023-05-10 07:50:37 -0500 | [diff] [blame^] | 207 | std::string service = util::getService(bus, loggingObjectPath, |
| 208 | opLoggingInterface); |
| 209 | auto method = bus.new_method_call(service.c_str(), loggingObjectPath, |
| 210 | opLoggingInterface, |
| 211 | "CreatePELWithFFDCFiles"); |
Jayanth Othayoth | 2eb31ad | 2021-09-20 07:13:28 -0500 | [diff] [blame] | 212 | auto level = |
| 213 | sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage( |
Marri Devender Rao | 2b30dea | 2021-12-17 02:38:30 -0600 | [diff] [blame] | 214 | severity); |
Jayanth Othayoth | 2eb31ad | 2021-09-20 07:13:28 -0500 | [diff] [blame] | 215 | method.append(event, level, additionalData, pelFFDCInfo); |
Jayanth Othayoth | fe37aea | 2021-10-07 04:41:26 -0500 | [diff] [blame] | 216 | auto response = bus.call(method); |
| 217 | |
| 218 | // reply will be tuple containing bmc log id, platform log id |
| 219 | std::tuple<uint32_t, uint32_t> reply = {0, 0}; |
| 220 | |
| 221 | // parse dbus response into reply |
| 222 | response.read(reply); |
| 223 | plid = std::get<1>(reply); // platform log id is tuple "second" |
Jayanth Othayoth | 2eb31ad | 2021-09-20 07:13:28 -0500 | [diff] [blame] | 224 | } |
Patrick Williams | aaea686 | 2022-07-22 19:26:54 -0500 | [diff] [blame] | 225 | catch (const sdbusplus::exception_t& e) |
Jayanth Othayoth | 2eb31ad | 2021-09-20 07:13:28 -0500 | [diff] [blame] | 226 | { |
| 227 | log<level::ERR>(fmt::format("D-Bus call exception", |
| 228 | "OBJPATH={}, INTERFACE={}, EXCEPTION={}", |
| 229 | loggingObjectPath, loggingInterface, |
| 230 | e.what()) |
| 231 | .c_str()); |
| 232 | throw std::runtime_error( |
| 233 | "Error in invoking D-Bus logging create interface"); |
| 234 | } |
Patrick Williams | 1a9a5a6 | 2021-10-06 13:05:06 -0500 | [diff] [blame] | 235 | catch (const std::exception& e) |
Jayanth Othayoth | 2eb31ad | 2021-09-20 07:13:28 -0500 | [diff] [blame] | 236 | { |
| 237 | throw e; |
| 238 | } |
Jayanth Othayoth | fe37aea | 2021-10-07 04:41:26 -0500 | [diff] [blame] | 239 | return plid; |
Jayanth Othayoth | 2eb31ad | 2021-09-20 07:13:28 -0500 | [diff] [blame] | 240 | } |
| 241 | |
Matt Spinler | be14ec2 | 2023-03-24 15:59:48 -0500 | [diff] [blame] | 242 | void createPEL(const std::string& event, const FFDCData& ffdcData, |
| 243 | const Severity severity) |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 244 | { |
| 245 | std::map<std::string, std::string> additionalData; |
| 246 | auto bus = sdbusplus::bus::new_default(); |
Jayanth Othayoth | a8d2f71 | 2021-09-20 07:02:51 -0500 | [diff] [blame] | 247 | |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 248 | additionalData.emplace("_PID", std::to_string(getpid())); |
Jayanth Othayoth | a8d2f71 | 2021-09-20 07:02:51 -0500 | [diff] [blame] | 249 | for (auto& data : ffdcData) |
| 250 | { |
| 251 | additionalData.emplace(data); |
| 252 | } |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 253 | |
| 254 | try |
| 255 | { |
Patrick Williams | 00dd33e | 2023-05-10 07:50:37 -0500 | [diff] [blame^] | 256 | std::string service = util::getService(bus, loggingObjectPath, |
| 257 | loggingInterface); |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 258 | auto method = bus.new_method_call(service.c_str(), loggingObjectPath, |
| 259 | loggingInterface, "Create"); |
| 260 | auto level = |
| 261 | sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage( |
Matt Spinler | be14ec2 | 2023-03-24 15:59:48 -0500 | [diff] [blame] | 262 | severity); |
Jayanth Othayoth | ac95c56 | 2021-07-16 05:56:04 -0500 | [diff] [blame] | 263 | method.append(event, level, additionalData); |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 264 | auto resp = bus.call(method); |
| 265 | } |
Patrick Williams | aaea686 | 2022-07-22 19:26:54 -0500 | [diff] [blame] | 266 | catch (const sdbusplus::exception_t& e) |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 267 | { |
Jayanth Othayoth | ac95c56 | 2021-07-16 05:56:04 -0500 | [diff] [blame] | 268 | log<level::ERR>(fmt::format("sdbusplus D-Bus call exception", |
| 269 | "OBJPATH={}, INTERFACE={}, EXCEPTION={}", |
| 270 | loggingObjectPath, loggingInterface, |
| 271 | e.what()) |
| 272 | .c_str()); |
| 273 | ; |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 274 | |
| 275 | throw std::runtime_error( |
| 276 | "Error in invoking D-Bus logging create interface"); |
| 277 | } |
Patrick Williams | 1a9a5a6 | 2021-10-06 13:05:06 -0500 | [diff] [blame] | 278 | catch (const std::exception& e) |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 279 | { |
Jayanth Othayoth | ac95c56 | 2021-07-16 05:56:04 -0500 | [diff] [blame] | 280 | log<level::ERR>( |
| 281 | fmt::format("D-bus call exception", "EXCEPTION={}", e.what()) |
| 282 | .c_str()); |
Andrew Geissler | 61febf0 | 2021-06-22 17:19:32 -0500 | [diff] [blame] | 283 | throw e; |
| 284 | } |
| 285 | } |
| 286 | |
Brad Bishop | f6783cd | 2020-10-27 19:25:09 -0400 | [diff] [blame] | 287 | FFDCFile::FFDCFile(const json& pHALCalloutData) : |
| 288 | calloutData(pHALCalloutData.dump()), |
| 289 | calloutFile("/tmp/phalPELCalloutsJson.XXXXXX"), fileFD(-1) |
| 290 | { |
| 291 | prepareFFDCFile(); |
| 292 | } |
| 293 | |
| 294 | FFDCFile::~FFDCFile() |
| 295 | { |
| 296 | removeCalloutFile(); |
| 297 | } |
| 298 | |
| 299 | int FFDCFile::getFileFD() const |
| 300 | { |
| 301 | return fileFD; |
| 302 | } |
| 303 | |
| 304 | void FFDCFile::prepareFFDCFile() |
| 305 | { |
| 306 | createCalloutFile(); |
| 307 | writeCalloutData(); |
| 308 | setCalloutFileSeekPos(); |
| 309 | } |
| 310 | |
| 311 | void FFDCFile::createCalloutFile() |
| 312 | { |
| 313 | fileFD = mkostemp(const_cast<char*>(calloutFile.c_str()), O_RDWR); |
| 314 | |
| 315 | if (fileFD == -1) |
| 316 | { |
| 317 | log<level::ERR>(fmt::format("Failed to create phalPELCallouts " |
| 318 | "file({}), errorno({}) and errormsg({})", |
| 319 | calloutFile, errno, strerror(errno)) |
| 320 | .c_str()); |
| 321 | throw std::runtime_error("Failed to create phalPELCallouts file"); |
| 322 | } |
| 323 | } |
| 324 | |
| 325 | void FFDCFile::writeCalloutData() |
| 326 | { |
| 327 | ssize_t rc = write(fileFD, calloutData.c_str(), calloutData.size()); |
| 328 | |
| 329 | if (rc == -1) |
| 330 | { |
| 331 | log<level::ERR>(fmt::format("Failed to write phaPELCallout info " |
| 332 | "in file({}), errorno({}), errormsg({})", |
| 333 | calloutFile, errno, strerror(errno)) |
| 334 | .c_str()); |
| 335 | throw std::runtime_error("Failed to write phalPELCallouts info"); |
| 336 | } |
| 337 | else if (rc != static_cast<ssize_t>(calloutData.size())) |
| 338 | { |
| 339 | log<level::WARNING>(fmt::format("Could not write all phal callout " |
| 340 | "info in file({}), written byte({}) " |
| 341 | "and total byte({})", |
| 342 | calloutFile, rc, calloutData.size()) |
| 343 | .c_str()); |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | void FFDCFile::setCalloutFileSeekPos() |
| 348 | { |
| 349 | int rc = lseek(fileFD, 0, SEEK_SET); |
| 350 | |
| 351 | if (rc == -1) |
| 352 | { |
| 353 | log<level::ERR>(fmt::format("Failed to set SEEK_SET for " |
| 354 | "phalPELCallouts in file({}), errorno({}) " |
| 355 | "and errormsg({})", |
| 356 | calloutFile, errno, strerror(errno)) |
| 357 | .c_str()); |
| 358 | throw std::runtime_error( |
| 359 | "Failed to set SEEK_SET for phalPELCallouts file"); |
| 360 | } |
| 361 | } |
| 362 | |
| 363 | void FFDCFile::removeCalloutFile() |
| 364 | { |
| 365 | close(fileFD); |
| 366 | std::remove(calloutFile.c_str()); |
| 367 | } |
| 368 | |
| 369 | } // namespace pel |
| 370 | } // namespace openpower |