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 */ 77 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 */ 87 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 */ 97 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 */ 107 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 */ 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 */ 127 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 */ 137 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 */ 147 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 */ 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 */ 167 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 */ 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 */ 190 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 */ 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 */ 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 * @return std::optional<std::string> -User header section's JSON 224 */ 225 std::optional<std::string> getJSON() const override; 226 227 private: 228 /** 229 * @brief Fills in the object from the stream data 230 * 231 * @param[in] stream - The stream to read from 232 */ 233 void unflatten(Stream& stream); 234 235 /** 236 * @brief Validates the section contents 237 * 238 * Updates _valid (in Section) with the results. 239 */ 240 void validate() override; 241 242 /** 243 * @brief Returns the severity value to use from the list 244 * of them passed in based on the system type. 245 * 246 * If there isn't an entry found for the current system 247 * type then std::nullopt will be returned. 248 * 249 * @param[in] severities - The array of {systype, severity} 250 * structures to find an entry in. 251 * @param[in] dataIface - The DataInterface object 252 */ 253 std::optional<uint8_t> 254 getSeverity(const std::vector<message::RegistrySeverity>& severities, 255 const DataInterfaceBase& dataIface) const; 256 257 /** 258 * @brief The subsystem associated with the event. 259 */ 260 uint8_t _eventSubsystem; 261 262 /** 263 * @brief The event scope field. 264 */ 265 uint8_t _eventScope; 266 267 /** 268 * @brief The event severity. 269 */ 270 uint8_t _eventSeverity; 271 272 /** 273 * @brief The event type. 274 */ 275 uint8_t _eventType; 276 277 /** 278 * @brief A reserved word placeholder 279 */ 280 uint32_t _reserved4Byte1; 281 282 /** 283 * @brief The problem domain field. 284 */ 285 uint8_t _problemDomain; 286 287 /** 288 * @brief The problem vector field. 289 */ 290 uint8_t _problemVector; 291 292 /** 293 * @brief The action flags field. 294 */ 295 uint16_t _actionFlags; 296 297 /** 298 * @brief The second reserved word that we are 299 * using for storing state information. 300 * 301 * 0x0000AABB 302 * Where: 303 * 0xAA = HMC transmission state 304 * 0xBB = Host transmission state 305 */ 306 uint32_t _states; 307 }; 308 309 } // namespace pels 310 } // namespace openpower 311