1 #pragma once 2 3 #include "bcd_time.hpp" 4 #include "data_interface.hpp" 5 #include "mtms.hpp" 6 #include "registry.hpp" 7 #include "section.hpp" 8 #include "src.hpp" 9 #include "stream.hpp" 10 11 namespace openpower 12 { 13 namespace pels 14 { 15 16 constexpr uint8_t extendedUserHeaderVersion = 0x01; 17 constexpr size_t firmwareVersionSize = 16; 18 19 /** 20 * @class ExtendedUserHeader 21 * 22 * This represents the Extended User Header section in a PEL. It is a required 23 * section. It contains code versions, an MTMS subsection, and a string called 24 * a symptom ID. 25 * 26 * The Section base class handles the section header structure that every 27 * PEL section has at offset zero. 28 */ 29 class ExtendedUserHeader : public Section 30 { 31 public: 32 ExtendedUserHeader() = delete; 33 ~ExtendedUserHeader() override = default; 34 ExtendedUserHeader(const ExtendedUserHeader&) = default; 35 ExtendedUserHeader& operator=(const ExtendedUserHeader&) = default; 36 ExtendedUserHeader(ExtendedUserHeader&&) = default; 37 ExtendedUserHeader& operator=(ExtendedUserHeader&&) = default; 38 39 /** 40 * @brief Constructor 41 * 42 * Fills in this class's data fields from the stream. 43 * 44 * @param[in] pel - the PEL data stream 45 */ 46 explicit ExtendedUserHeader(Stream& pel); 47 48 /** 49 * @brief Constructor 50 * 51 * @param[in] dataIface - The DataInterface object 52 * @param[in] regEntry - The message registry entry for this event 53 * @param[in] src - The SRC section object for this event 54 */ 55 ExtendedUserHeader(const DataInterfaceBase& dataIface, 56 const message::Entry& regEntry, const SRC& src); 57 58 /** 59 * @brief Flatten the section into the stream 60 * 61 * @param[in] stream - The stream to write to 62 */ 63 void flatten(Stream& stream) const override; 64 65 /** 66 * @brief Returns the size of this section when flattened into a PEL 67 * 68 * @return size_t - the size of the section 69 */ flattenedSize()70 size_t flattenedSize() 71 { 72 return Section::headerSize() + _mtms.flattenedSize() + 73 _serverFWVersion.size() + _subsystemFWVersion.size() + 74 sizeof(_reserved4B) + sizeof(_refTime) + sizeof(_reserved1B1) + 75 sizeof(_reserved1B2) + sizeof(_reserved1B3) + 76 sizeof(_symptomIDSize) + _symptomIDSize; 77 } 78 79 /** 80 * @brief Returns the server firmware version 81 * 82 * @return std::string - The version 83 */ serverFWVersion() const84 std::string serverFWVersion() const 85 { 86 std::string version; 87 for (size_t i = 0; 88 i < _serverFWVersion.size() && _serverFWVersion[i] != '\0'; i++) 89 { 90 version.push_back(_serverFWVersion[i]); 91 } 92 return version; 93 } 94 95 /** 96 * @brief Returns the subsystem firmware version 97 * 98 * @return std::string - The version 99 */ subsystemFWVersion() const100 std::string subsystemFWVersion() const 101 { 102 std::string version; 103 for (size_t i = 0; 104 i < _subsystemFWVersion.size() && _subsystemFWVersion[i] != '\0'; 105 i++) 106 { 107 version.push_back(_subsystemFWVersion[i]); 108 } 109 return version; 110 } 111 112 /** 113 * @brief Returns the machine type+model 114 * 115 * @return std::string - The MTM 116 */ machineTypeModel() const117 std::string machineTypeModel() const 118 { 119 return _mtms.machineTypeAndModel(); 120 } 121 122 /** 123 * @brief Returns the machine serial number 124 * 125 * @return std::string - The serial number 126 */ machineSerialNumber() const127 std::string machineSerialNumber() const 128 { 129 return _mtms.machineSerialNumber(); 130 } 131 132 /** 133 * @brief Returns the Event Common Reference Time field 134 * 135 * @return BCDTime - The time value 136 */ refTime() const137 const BCDTime& refTime() const 138 { 139 return _refTime; 140 } 141 142 /** 143 * @brief Returns the symptom ID 144 * 145 * @return std::string - The symptom ID 146 */ symptomID() const147 std::string symptomID() const 148 { 149 std::string symptom; 150 for (size_t i = 0; i < _symptomID.size() && _symptomID[i] != '\0'; i++) 151 { 152 symptom.push_back(_symptomID[i]); 153 } 154 return symptom; 155 } 156 157 /** 158 * @brief Get section in JSON. 159 * 160 * @param[in] creatorID - The creator ID for the PEL 161 * 162 * @return std::optional<std::string> - ExtendedUserHeader section's JSON 163 */ 164 std::optional<std::string> getJSON(uint8_t creatorID) const override; 165 166 private: 167 /** 168 * @brief Fills in the object from the stream data 169 * 170 * @param[in] stream - The stream to read from 171 */ 172 void unflatten(Stream& stream); 173 174 /** 175 * @brief Validates the section contents 176 * 177 * Updates _valid (in Section) with the results. 178 */ 179 void validate(); 180 181 /** 182 * @brief Builds the symptom ID 183 * 184 * Uses the message registry to say which SRC fields to add 185 * to the SRC's ASCII string to make the ID, and uses a smart 186 * default if not specified in the registry. 187 * 188 * @param[in] regEntry - The message registry entry for this event 189 * @param[in] src - The SRC section object for this event 190 */ 191 void createSymptomID(const message::Entry& regEntry, const SRC& src); 192 193 /** 194 * @brief The structure that holds the machine TM and SN fields. 195 */ 196 MTMS _mtms; 197 198 /** 199 * @brief The server firmware version 200 * 201 * NULL terminated. 202 * 203 * The release version of the full firmware image. 204 */ 205 std::array<uint8_t, firmwareVersionSize> _serverFWVersion; 206 207 /** 208 * @brief The subsystem firmware version 209 * 210 * NULL terminated. 211 * 212 * On PELs created on the BMC, this will be the BMC code version. 213 */ 214 std::array<uint8_t, firmwareVersionSize> _subsystemFWVersion; 215 216 /** 217 * @brief Reserved 218 */ 219 uint32_t _reserved4B = 0; 220 221 /** 222 * @brief Event Common Reference Time 223 * 224 * This is not used by PELs created on the BMC. 225 */ 226 BCDTime _refTime; 227 228 /** 229 * @brief Reserved 230 */ 231 uint8_t _reserved1B1 = 0; 232 233 /** 234 * @brief Reserved 235 */ 236 uint8_t _reserved1B2 = 0; 237 238 /** 239 * @brief Reserved 240 */ 241 uint8_t _reserved1B3 = 0; 242 243 /** 244 * @brief The size of the symptom ID field 245 */ 246 uint8_t _symptomIDSize; 247 248 /** 249 * @brief The symptom ID field 250 * 251 * Describes a unique event signature for the log. 252 * Required for serviceable events, otherwise optional. 253 * When present, must start with the first 8 characters 254 * of the ASCII string field from the SRC. 255 * 256 * NULL terminated. 257 */ 258 std::vector<uint8_t> _symptomID; 259 }; 260 261 } // namespace pels 262 } // namespace openpower 263