1cb6b059eSMatt Spinler #pragma once 2cb6b059eSMatt Spinler 3b832363dSMatt Spinler #include "additional_data.hpp" 4aa659477SMatt Spinler #include "data_interface.hpp" 5cb6b059eSMatt Spinler #include "private_header.hpp" 6b832363dSMatt Spinler #include "registry.hpp" 7bd716f00SMatt Spinler #include "src.hpp" 8afa857c7SMatt Spinler #include "user_data.hpp" 9cb6b059eSMatt Spinler #include "user_header.hpp" 10cb6b059eSMatt Spinler 11cb6b059eSMatt Spinler #include <memory> 12cb6b059eSMatt Spinler #include <vector> 13cb6b059eSMatt Spinler 14cb6b059eSMatt Spinler namespace openpower 15cb6b059eSMatt Spinler { 16cb6b059eSMatt Spinler namespace pels 17cb6b059eSMatt Spinler { 18cb6b059eSMatt Spinler 19cb6b059eSMatt Spinler /** @class PEL 20cb6b059eSMatt Spinler * 21cb6b059eSMatt Spinler * @brief This class represents a specific event log format referred to as a 22cb6b059eSMatt Spinler * Platform Event Log. 23cb6b059eSMatt Spinler * 24cb6b059eSMatt Spinler * Every field in a PEL are in structures call sections, of which there are 25cb6b059eSMatt Spinler * several types. Some sections are required, and some are optional. In some 26cb6b059eSMatt Spinler * cases there may be more than one instance of a section type. 27cb6b059eSMatt Spinler * 28cb6b059eSMatt Spinler * The only two required sections for every type of PEL are the Private Header 29cb6b059eSMatt Spinler * section and User Header section, which must be in the first and second 30cb6b059eSMatt Spinler * positions, respectively. 31cb6b059eSMatt Spinler * 32cb6b059eSMatt Spinler * Every section starts with an 8 byte section header, which has the section 33cb6b059eSMatt Spinler * size and type, among other things. 34cb6b059eSMatt Spinler * 35cb6b059eSMatt Spinler * This class represents all sections with objects. 36cb6b059eSMatt Spinler * 37bd716f00SMatt Spinler * The class can be constructed: 38bd716f00SMatt Spinler * - From a full formed flattened PEL. 39bd716f00SMatt Spinler * - From scratch based on an OpenBMC event and its corresponding PEL message 40bd716f00SMatt Spinler * registry entry. 41b832363dSMatt Spinler * 42cb6b059eSMatt Spinler * The data() method allows one to retrieve the PEL as a vector<uint8_t>. This 43cb6b059eSMatt Spinler * is the format in which it is stored and transmitted. 44cb6b059eSMatt Spinler */ 45cb6b059eSMatt Spinler class PEL 46cb6b059eSMatt Spinler { 47cb6b059eSMatt Spinler public: 48cb6b059eSMatt Spinler PEL() = delete; 49cb6b059eSMatt Spinler ~PEL() = default; 50cb6b059eSMatt Spinler PEL(const PEL&) = delete; 51cb6b059eSMatt Spinler PEL& operator=(const PEL&) = delete; 52cb6b059eSMatt Spinler PEL(PEL&&) = delete; 53cb6b059eSMatt Spinler PEL& operator=(PEL&&) = delete; 54cb6b059eSMatt Spinler 55cb6b059eSMatt Spinler /** 56cb6b059eSMatt Spinler * @brief Constructor 57cb6b059eSMatt Spinler * 58cb6b059eSMatt Spinler * Build a PEL from raw data. 59cb6b059eSMatt Spinler * 6007eefc54SMatt Spinler * Note: Neither this nor the following constructor can take a const vector& 6107eefc54SMatt Spinler * because the Stream class that is used to read from the vector cannot take 6207eefc54SMatt Spinler * a const. The alternative is to make a copy of the data, but as PELs can 6307eefc54SMatt Spinler * be up to 16KB that is undesireable. 6407eefc54SMatt Spinler * 65cb6b059eSMatt Spinler * @param[in] data - The PEL data 66cb6b059eSMatt Spinler */ 6707eefc54SMatt Spinler PEL(std::vector<uint8_t>& data); 68cb6b059eSMatt Spinler 69cb6b059eSMatt Spinler /** 70cb6b059eSMatt Spinler * @brief Constructor 71cb6b059eSMatt Spinler * 72cb6b059eSMatt Spinler * Build a PEL from the raw data. 73cb6b059eSMatt Spinler * 74cb6b059eSMatt Spinler * @param[in] data - the PEL data 75cb6b059eSMatt Spinler * @param[in] obmcLogID - the corresponding OpenBMC event log ID 76cb6b059eSMatt Spinler */ 7707eefc54SMatt Spinler PEL(std::vector<uint8_t>& data, uint32_t obmcLogID); 78cb6b059eSMatt Spinler 79cb6b059eSMatt Spinler /** 80b832363dSMatt Spinler * @brief Constructor 81b832363dSMatt Spinler * 82b832363dSMatt Spinler * Creates a PEL from an OpenBMC event log and its message 83b832363dSMatt Spinler * registry entry. 84b832363dSMatt Spinler * 85b832363dSMatt Spinler * @param[in] entry - The message registry entry for this error 86b832363dSMatt Spinler * @param[in] obmcLogID - ID of corresponding OpenBMC event log 87b832363dSMatt Spinler * @param[in] timestamp - Timestamp from the event log 88b832363dSMatt Spinler * @param[in] severity - Severity from the event log 89bd716f00SMatt Spinler * @param[in] additionalData - The AdditionalData contents 90aa659477SMatt Spinler * @param[in] dataIface - The data interface object 91b832363dSMatt Spinler */ 92b832363dSMatt Spinler PEL(const openpower::pels::message::Entry& entry, uint32_t obmcLogID, 93bd716f00SMatt Spinler uint64_t timestamp, phosphor::logging::Entry::Level severity, 94aa659477SMatt Spinler const AdditionalData& additionalData, 95aa659477SMatt Spinler const DataInterfaceBase& dataIface); 96b832363dSMatt Spinler 97b832363dSMatt Spinler /** 98cb6b059eSMatt Spinler * @brief Convenience function to return the log ID field from the 99cb6b059eSMatt Spinler * Private Header section. 100cb6b059eSMatt Spinler * 101cb6b059eSMatt Spinler * @return uint32_t - the ID 102cb6b059eSMatt Spinler */ 103cb6b059eSMatt Spinler uint32_t id() const 104cb6b059eSMatt Spinler { 105cb6b059eSMatt Spinler return _ph->id(); 106cb6b059eSMatt Spinler } 107cb6b059eSMatt Spinler 108cb6b059eSMatt Spinler /** 109cb6b059eSMatt Spinler * @brief Convenience function to return the PLID field from the 110cb6b059eSMatt Spinler * Private Header section. 111cb6b059eSMatt Spinler * 112cb6b059eSMatt Spinler * @return uint32_t - the PLID 113cb6b059eSMatt Spinler */ 114cb6b059eSMatt Spinler uint32_t plid() const 115cb6b059eSMatt Spinler { 116cb6b059eSMatt Spinler return _ph->plid(); 117cb6b059eSMatt Spinler } 118cb6b059eSMatt Spinler 119cb6b059eSMatt Spinler /** 120cb6b059eSMatt Spinler * @brief Convenience function to return the OpenBMC event log ID field 121cb6b059eSMatt Spinler * from the Private Header section. 122cb6b059eSMatt Spinler * 123cb6b059eSMatt Spinler * @return uint32_t - the OpenBMC event log ID 124cb6b059eSMatt Spinler */ 125cb6b059eSMatt Spinler uint32_t obmcLogID() const 126cb6b059eSMatt Spinler { 127cb6b059eSMatt Spinler return _ph->obmcLogID(); 128cb6b059eSMatt Spinler } 129cb6b059eSMatt Spinler 130cb6b059eSMatt Spinler /** 131cb6b059eSMatt Spinler * @brief Convenience function to return the commit time field from 132cb6b059eSMatt Spinler * the Private Header section. 133cb6b059eSMatt Spinler * 134cb6b059eSMatt Spinler * @return BCDTime - the timestamp 135cb6b059eSMatt Spinler */ 136cb6b059eSMatt Spinler BCDTime commitTime() const 137cb6b059eSMatt Spinler { 138cb6b059eSMatt Spinler return _ph->commitTimestamp(); 139cb6b059eSMatt Spinler } 140cb6b059eSMatt Spinler 141cb6b059eSMatt Spinler /** 142cb6b059eSMatt Spinler * @brief Convenience function to return the create time field from 143cb6b059eSMatt Spinler * the Private Header section. 144cb6b059eSMatt Spinler * 145cb6b059eSMatt Spinler * @return BCDTime - the timestamp 146cb6b059eSMatt Spinler */ 147cb6b059eSMatt Spinler BCDTime createTime() const 148cb6b059eSMatt Spinler { 149cb6b059eSMatt Spinler return _ph->createTimestamp(); 150cb6b059eSMatt Spinler } 151cb6b059eSMatt Spinler 152cb6b059eSMatt Spinler /** 153cb6b059eSMatt Spinler * @brief Gives access to the Private Header section class 154cb6b059eSMatt Spinler * 15597d19b48SMatt Spinler * @return const PrivateHeader& - the private header 156cb6b059eSMatt Spinler */ 15797d19b48SMatt Spinler const PrivateHeader& privateHeader() const 158cb6b059eSMatt Spinler { 15997d19b48SMatt Spinler return *_ph; 160cb6b059eSMatt Spinler } 161cb6b059eSMatt Spinler 162cb6b059eSMatt Spinler /** 163cb6b059eSMatt Spinler * @brief Gives access to the User Header section class 164cb6b059eSMatt Spinler * 16597d19b48SMatt Spinler * @return const UserHeader& - the user header 166cb6b059eSMatt Spinler */ 16797d19b48SMatt Spinler const UserHeader& userHeader() const 168cb6b059eSMatt Spinler { 16997d19b48SMatt Spinler return *_uh; 170cb6b059eSMatt Spinler } 171cb6b059eSMatt Spinler 172cb6b059eSMatt Spinler /** 173bd716f00SMatt Spinler * @brief Gives access to the primary SRC's section class 174bd716f00SMatt Spinler * 175bd716f00SMatt Spinler * This is technically an optional section, so the return 176bd716f00SMatt Spinler * value is an std::optional<SRC*>. 177bd716f00SMatt Spinler * 178bd716f00SMatt Spinler * @return std::optional<SRC*> - the SRC section object 179bd716f00SMatt Spinler */ 180bd716f00SMatt Spinler std::optional<SRC*> primarySRC() const; 181bd716f00SMatt Spinler 182bd716f00SMatt Spinler /** 183131870c7SMatt Spinler * @brief Returns the optional sections, which is everything but 184131870c7SMatt Spinler * the Private and User Headers. 185131870c7SMatt Spinler * 186131870c7SMatt Spinler * @return const std::vector<std::unique_ptr<Section>>& 187131870c7SMatt Spinler */ 188131870c7SMatt Spinler const std::vector<std::unique_ptr<Section>>& optionalSections() const 189131870c7SMatt Spinler { 190131870c7SMatt Spinler return _optionalSections; 191131870c7SMatt Spinler } 192131870c7SMatt Spinler 193131870c7SMatt Spinler /** 194cb6b059eSMatt Spinler * @brief Returns the PEL data. 195cb6b059eSMatt Spinler * 196cb6b059eSMatt Spinler * @return std::vector<uint8_t> - the raw PEL data 197cb6b059eSMatt Spinler */ 1980688545bSMatt Spinler std::vector<uint8_t> data() const; 199cb6b059eSMatt Spinler 200cb6b059eSMatt Spinler /** 201cb6b059eSMatt Spinler * @brief Says if the PEL is valid (the sections are all valid) 202cb6b059eSMatt Spinler * 203cb6b059eSMatt Spinler * @return bool - if the PEL is valid 204cb6b059eSMatt Spinler */ 205cb6b059eSMatt Spinler bool valid() const; 206cb6b059eSMatt Spinler 207cb6b059eSMatt Spinler /** 208cb6b059eSMatt Spinler * @brief Sets the commit timestamp to the current time 209cb6b059eSMatt Spinler */ 210cb6b059eSMatt Spinler void setCommitTime(); 211cb6b059eSMatt Spinler 212cb6b059eSMatt Spinler /** 213cb6b059eSMatt Spinler * @brief Sets the error log ID field to a unique ID. 214cb6b059eSMatt Spinler */ 215cb6b059eSMatt Spinler void assignID(); 216cb6b059eSMatt Spinler 217186ce8c9SAatir /** 218186ce8c9SAatir * @brief Output a PEL in JSON. 219186ce8c9SAatir */ 2200688545bSMatt Spinler void toJSON() const; 221186ce8c9SAatir 222f38ce984SMatt Spinler /** 223f38ce984SMatt Spinler * @brief Sets the host transmission state in the User Header 224f38ce984SMatt Spinler * 225f38ce984SMatt Spinler * @param[in] state - The state value 226f38ce984SMatt Spinler */ 227f38ce984SMatt Spinler void setHostTransmissionState(TransmissionState state) 228f38ce984SMatt Spinler { 229f38ce984SMatt Spinler _uh->setHostTransmissionState(static_cast<uint8_t>(state)); 230f38ce984SMatt Spinler } 231f38ce984SMatt Spinler 232f38ce984SMatt Spinler /** 233f38ce984SMatt Spinler * @brief Returns the host transmission state 234f38ce984SMatt Spinler * 235f38ce984SMatt Spinler * @return HostTransmissionState - The state 236f38ce984SMatt Spinler */ 237f38ce984SMatt Spinler TransmissionState hostTransmissionState() const 238f38ce984SMatt Spinler { 239f38ce984SMatt Spinler return static_cast<TransmissionState>(_uh->hostTransmissionState()); 240f38ce984SMatt Spinler } 241f38ce984SMatt Spinler 242f38ce984SMatt Spinler /** 243f38ce984SMatt Spinler * @brief Sets the HMC transmission state in the User Header 244f38ce984SMatt Spinler * 245f38ce984SMatt Spinler * @param[in] state - The state value 246f38ce984SMatt Spinler */ 247f38ce984SMatt Spinler void setHMCTransmissionState(TransmissionState state) 248f38ce984SMatt Spinler { 249f38ce984SMatt Spinler _uh->setHMCTransmissionState(static_cast<uint8_t>(state)); 250f38ce984SMatt Spinler } 251f38ce984SMatt Spinler 252f38ce984SMatt Spinler /** 253f38ce984SMatt Spinler * @brief Returns the HMC transmission state 254f38ce984SMatt Spinler * 255f38ce984SMatt Spinler * @return HMCTransmissionState - The state 256f38ce984SMatt Spinler */ 257f38ce984SMatt Spinler TransmissionState hmcTransmissionState() const 258f38ce984SMatt Spinler { 259f38ce984SMatt Spinler return static_cast<TransmissionState>(_uh->hmcTransmissionState()); 260f38ce984SMatt Spinler } 261f38ce984SMatt Spinler 262cb6b059eSMatt Spinler private: 263cb6b059eSMatt Spinler /** 264cb6b059eSMatt Spinler * @brief Builds the section objects from a PEL data buffer 265cb6b059eSMatt Spinler * 26607eefc54SMatt Spinler * Note: The data parameter cannot be const for the same reasons 26707eefc54SMatt Spinler * as listed in the constructor. 26807eefc54SMatt Spinler * 26907eefc54SMatt Spinler * @param[in] data - The PEL data 270cb6b059eSMatt Spinler * @param[in] obmcLogID - The OpenBMC event log ID to use for that 271cb6b059eSMatt Spinler * field in the Private Header. 272cb6b059eSMatt Spinler */ 27307eefc54SMatt Spinler void populateFromRawData(std::vector<uint8_t>& data, uint32_t obmcLogID); 274cb6b059eSMatt Spinler 275cb6b059eSMatt Spinler /** 276cb6b059eSMatt Spinler * @brief Flattens the PEL objects into the buffer 277cb6b059eSMatt Spinler * 278cb6b059eSMatt Spinler * @param[out] pelBuffer - What the data will be written to 279cb6b059eSMatt Spinler */ 2800688545bSMatt Spinler void flatten(std::vector<uint8_t>& pelBuffer) const; 281cb6b059eSMatt Spinler 282cb6b059eSMatt Spinler /** 283f1e85e20SMatt Spinler * @brief Check that the PEL fields that need to be in agreement 284f1e85e20SMatt Spinler * with each other are, and fix them up if necessary. 285f1e85e20SMatt Spinler */ 286f1e85e20SMatt Spinler void checkRulesAndFix(); 287f1e85e20SMatt Spinler 288f1e85e20SMatt Spinler /** 289*acb7c106SMatt Spinler * @brief Returns a map of the section IDs that appear more than once 290*acb7c106SMatt Spinler * in the PEL. The data value for each entry will be set to 0. 291*acb7c106SMatt Spinler * 292*acb7c106SMatt Spinler * @return std::map<uint16_t, size_t> 293*acb7c106SMatt Spinler */ 294*acb7c106SMatt Spinler std::map<uint16_t, size_t> getPluralSections() const; 295*acb7c106SMatt Spinler 296*acb7c106SMatt Spinler /** 297cb6b059eSMatt Spinler * @brief The PEL Private Header section 298cb6b059eSMatt Spinler */ 299cb6b059eSMatt Spinler std::unique_ptr<PrivateHeader> _ph; 300cb6b059eSMatt Spinler 301cb6b059eSMatt Spinler /** 302cb6b059eSMatt Spinler * @brief The PEL User Header section 303cb6b059eSMatt Spinler */ 304cb6b059eSMatt Spinler std::unique_ptr<UserHeader> _uh; 305cb6b059eSMatt Spinler 306cb6b059eSMatt Spinler /** 307131870c7SMatt Spinler * @brief Holds all sections by the PH and UH. 308131870c7SMatt Spinler */ 309131870c7SMatt Spinler std::vector<std::unique_ptr<Section>> _optionalSections; 310186ce8c9SAatir 311186ce8c9SAatir /** 312186ce8c9SAatir * @brief helper function for printing PELs. 313186ce8c9SAatir * @param[in] Section& - section object reference 314186ce8c9SAatir * @param[in] std::string - PEL string 315*acb7c106SMatt Spinler * @param[in|out] pluralSections - Map used to track sections counts for 316*acb7c106SMatt Spinler * when there is more than 1. 317186ce8c9SAatir */ 318*acb7c106SMatt Spinler void printSectionInJSON(const Section& section, std::string& buf, 319*acb7c106SMatt Spinler std::map<uint16_t, size_t>& pluralSections) const; 320cb6b059eSMatt Spinler }; 321cb6b059eSMatt Spinler 322afa857c7SMatt Spinler namespace util 323afa857c7SMatt Spinler { 324afa857c7SMatt Spinler 325afa857c7SMatt Spinler /** 326afa857c7SMatt Spinler * @brief Create a UserData section containing the AdditionalData 327afa857c7SMatt Spinler * contents as a JSON string. 328afa857c7SMatt Spinler * 329afa857c7SMatt Spinler * @param[in] ad - The AdditionalData contents 330afa857c7SMatt Spinler * 331afa857c7SMatt Spinler * @return std::unique_ptr<UserData> - The section 332afa857c7SMatt Spinler */ 333afa857c7SMatt Spinler std::unique_ptr<UserData> makeADUserDataSection(const AdditionalData& ad); 334afa857c7SMatt Spinler 335afa857c7SMatt Spinler } // namespace util 336afa857c7SMatt Spinler 337cb6b059eSMatt Spinler } // namespace pels 338cb6b059eSMatt Spinler } // namespace openpower 339