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