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