1 #pragma once 2 3 #include "data_interface.hpp" 4 #include "elog_entry.hpp" 5 #include "registry.hpp" 6 #include "section.hpp" 7 #include "stream.hpp" 8 9 namespace openpower 10 { 11 namespace pels 12 { 13 14 static constexpr uint8_t userHeaderVersion = 0x01; 15 static constexpr uint16_t actionFlagsDefault = 0xFFFF; 16 17 /** 18 * @class UserHeader 19 * 20 * This represents the User Header section in a PEL. It is required, 21 * and it is always the second section. 22 * 23 * The Section base class handles the section header structure that every 24 * PEL section has at offset zero. 25 * 26 * The fields in this class directly correspond to the order and sizes of 27 * the fields in the section. 28 */ 29 class UserHeader : public Section 30 { 31 public: 32 UserHeader() = delete; 33 ~UserHeader() override = default; 34 UserHeader(const UserHeader&) = default; 35 UserHeader& operator=(const UserHeader&) = default; 36 UserHeader(UserHeader&&) = default; 37 UserHeader& operator=(UserHeader&&) = default; 38 39 /** 40 * @brief Constructor 41 * 42 * Creates a valid UserHeader with the passed in data. 43 * 44 * @param[in] entry - The message registry entry for this error 45 * @param[in] severity - The OpenBMC event log severity for this error 46 * @param[in] additionalData - The AdditionalData properties in this 47 * error log 48 * @param[in] dataIface - The DataInterface object 49 */ 50 UserHeader(const message::Entry& entry, 51 phosphor::logging::Entry::Level severity, 52 const AdditionalData& additionalData, 53 const DataInterfaceBase& dataIface); 54 55 /** 56 * @brief Constructor 57 * 58 * Fills in this class's data fields from the stream. 59 * 60 * @param[in] pel - the PEL data stream 61 */ 62 explicit UserHeader(Stream& pel); 63 64 /** 65 * @brief Flatten the section into the stream 66 * 67 * @param[in] stream - The stream to write to 68 */ 69 void flatten(Stream& stream) const override; 70 71 /** 72 * @brief Returns the subsystem field. 73 * 74 * @return uint8_t - the subsystem 75 */ subsystem() const76 uint8_t subsystem() const 77 { 78 return _eventSubsystem; 79 } 80 81 /** 82 * @brief Returns the event scope field. 83 * 84 * @return uint8_t - the event scope 85 */ scope() const86 uint8_t scope() const 87 { 88 return _eventScope; 89 } 90 91 /** 92 * @brief Returns the severity field. 93 * 94 * @return uint8_t - the severity 95 */ severity() const96 uint8_t severity() const 97 { 98 return _eventSeverity; 99 } 100 101 /** 102 * @brief Returns the event type field. 103 * 104 * @return uint8_t - the event type 105 */ eventType() const106 uint8_t eventType() const 107 { 108 return _eventType; 109 } 110 111 /** 112 * @brief Set the event type field 113 * 114 * @param[in] type - the new event type 115 */ setEventType(uint8_t type)116 void setEventType(uint8_t type) 117 { 118 _eventType = type; 119 } 120 121 /** 122 * @brief Returns the problem domain field. 123 * 124 * @return uint8_t - the problem domain 125 */ problemDomain() const126 uint8_t problemDomain() const 127 { 128 return _problemDomain; 129 } 130 131 /** 132 * @brief Returns the problem vector field. 133 * 134 * @return uint8_t - the problem vector 135 */ problemVector() const136 uint8_t problemVector() const 137 { 138 return _problemVector; 139 } 140 141 /** 142 * @brief Returns the action flags field. 143 * 144 * @return uint16_t - the action flags 145 */ actionFlags() const146 uint16_t actionFlags() const 147 { 148 return _actionFlags; 149 } 150 151 /** 152 * @brief Sets the action flags field 153 * 154 * @param[in] flags - the new action flags 155 */ setActionFlags(uint16_t flags)156 void setActionFlags(uint16_t flags) 157 { 158 _actionFlags = flags; 159 } 160 161 /** 162 * @brief Returns the host transmission state 163 * 164 * @return uint8_t - the host transmission state 165 */ hostTransmissionState() const166 uint8_t hostTransmissionState() const 167 { 168 return _states & 0xFF; 169 } 170 171 /** 172 * @brief Sets the host transmission state 173 * 174 * @param[in] state - the new state 175 */ setHostTransmissionState(uint8_t state)176 void setHostTransmissionState(uint8_t state) 177 { 178 _states &= 0xFFFFFF00; 179 _states |= state; 180 } 181 182 /** 183 * @brief Returns the HMC transmission state 184 * 185 * (HMC = Hardware Management Console) 186 * 187 * @return uint8_t - the HMC transmission state 188 */ hmcTransmissionState() const189 uint8_t hmcTransmissionState() const 190 { 191 return (_states & 0x0000FF00) >> 8; 192 } 193 194 /** 195 * @brief Sets the HMC transmission state 196 * 197 * @param[in] state - the new state 198 */ setHMCTransmissionState(uint8_t state)199 void setHMCTransmissionState(uint8_t state) 200 { 201 uint32_t newState = state << 8; 202 _states &= 0xFFFF00FF; 203 _states |= newState; 204 } 205 206 /** 207 * @brief Returns the size of this section when flattened into a PEL 208 * 209 * @return size_t - the size of the section 210 */ flattenedSize()211 static constexpr size_t flattenedSize() 212 { 213 return Section::headerSize() + sizeof(_eventSubsystem) + 214 sizeof(_eventScope) + sizeof(_eventSeverity) + 215 sizeof(_eventType) + sizeof(_reserved4Byte1) + 216 sizeof(_problemDomain) + sizeof(_problemVector) + 217 sizeof(_actionFlags) + sizeof(_states); 218 } 219 220 /** 221 * @brief Get section in JSON. 222 * 223 * @param[in] creatorID - The creator ID for the PEL 224 * 225 * @return std::optional<std::string> -User header section's JSON 226 */ 227 std::optional<std::string> getJSON(uint8_t creatorID) const override; 228 229 private: 230 /** 231 * @brief Fills in the object from the stream data 232 * 233 * @param[in] stream - The stream to read from 234 */ 235 void unflatten(Stream& stream); 236 237 /** 238 * @brief Validates the section contents 239 * 240 * Updates _valid (in Section) with the results. 241 */ 242 void validate(); 243 244 /** 245 * @brief Returns the severity value to use from the list 246 * of them passed in based on the system type. 247 * 248 * If there isn't an entry found for the current system 249 * type then std::nullopt will be returned. 250 * 251 * @param[in] severities - The array of {systype, severity} 252 * structures to find an entry in. 253 * @param[in] dataIface - The DataInterface object 254 */ 255 std::optional<uint8_t> getSeverity( 256 const std::vector<message::RegistrySeverity>& severities, 257 const DataInterfaceBase& dataIface) const; 258 259 /** 260 * @brief The subsystem associated with the event. 261 */ 262 uint8_t _eventSubsystem; 263 264 /** 265 * @brief The event scope field. 266 */ 267 uint8_t _eventScope; 268 269 /** 270 * @brief The event severity. 271 */ 272 uint8_t _eventSeverity; 273 274 /** 275 * @brief The event type. 276 */ 277 uint8_t _eventType; 278 279 /** 280 * @brief A reserved word placeholder 281 */ 282 uint32_t _reserved4Byte1; 283 284 /** 285 * @brief The problem domain field. 286 */ 287 uint8_t _problemDomain; 288 289 /** 290 * @brief The problem vector field. 291 */ 292 uint8_t _problemVector; 293 294 /** 295 * @brief The action flags field. 296 */ 297 uint16_t _actionFlags; 298 299 /** 300 * @brief The second reserved word that we are 301 * using for storing state information. 302 * 303 * 0x0000AABB 304 * Where: 305 * 0xAA = HMC transmission state 306 * 0xBB = Host transmission state 307 */ 308 uint32_t _states; 309 }; 310 311 } // namespace pels 312 } // namespace openpower 313