1*99b78ec8SJason M. Bills /* 2*99b78ec8SJason M. Bills // Copyright (c) 2019 Intel Corporation 3*99b78ec8SJason M. Bills // 4*99b78ec8SJason M. Bills // Licensed under the Apache License, Version 2.0 (the "License"); 5*99b78ec8SJason M. Bills // you may not use this file except in compliance with the License. 6*99b78ec8SJason M. Bills // You may obtain a copy of the License at 7*99b78ec8SJason M. Bills // 8*99b78ec8SJason M. Bills // http://www.apache.org/licenses/LICENSE-2.0 9*99b78ec8SJason M. Bills // 10*99b78ec8SJason M. Bills // Unless required by applicable law or agreed to in writing, software 11*99b78ec8SJason M. Bills // distributed under the License is distributed on an "AS IS" BASIS, 12*99b78ec8SJason M. Bills // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*99b78ec8SJason M. Bills // See the License for the specific language governing permissions and 14*99b78ec8SJason M. Bills // limitations under the License. 15*99b78ec8SJason M. Bills */ 16*99b78ec8SJason M. Bills 17*99b78ec8SJason M. Bills #include <boost/algorithm/string/join.hpp> 18*99b78ec8SJason M. Bills #include <boost/beast/core/span.hpp> 19*99b78ec8SJason M. Bills #include <iomanip> 20*99b78ec8SJason M. Bills #include <ipmi_to_redfish_hooks.hpp> 21*99b78ec8SJason M. Bills #include <phosphor-logging/log.hpp> 22*99b78ec8SJason M. Bills #include <sstream> 23*99b78ec8SJason M. Bills #include <storagecommands.hpp> 24*99b78ec8SJason M. Bills #include <string_view> 25*99b78ec8SJason M. Bills 26*99b78ec8SJason M. Bills namespace intel_oem::ipmi::sel 27*99b78ec8SJason M. Bills { 28*99b78ec8SJason M. Bills 29*99b78ec8SJason M. Bills namespace redfish_hooks 30*99b78ec8SJason M. Bills { 31*99b78ec8SJason M. Bills static void toHexStr(const boost::beast::span<uint8_t> bytes, 32*99b78ec8SJason M. Bills std::string& hexStr) 33*99b78ec8SJason M. Bills { 34*99b78ec8SJason M. Bills std::stringstream stream; 35*99b78ec8SJason M. Bills stream << std::hex << std::uppercase << std::setfill('0'); 36*99b78ec8SJason M. Bills for (const uint8_t& byte : bytes) 37*99b78ec8SJason M. Bills { 38*99b78ec8SJason M. Bills stream << std::setw(2) << static_cast<int>(byte); 39*99b78ec8SJason M. Bills } 40*99b78ec8SJason M. Bills hexStr = stream.str(); 41*99b78ec8SJason M. Bills } 42*99b78ec8SJason M. Bills 43*99b78ec8SJason M. Bills // Record a BIOS message as a Redfish message instead of a SEL record 44*99b78ec8SJason M. Bills static bool biosMessageHook(const SELData& selData, const std::string& ipmiRaw) 45*99b78ec8SJason M. Bills { 46*99b78ec8SJason M. Bills // This is a BIOS message, so record it as a Redfish message instead 47*99b78ec8SJason M. Bills // of a SEL record 48*99b78ec8SJason M. Bills 49*99b78ec8SJason M. Bills // Walk through the SEL request record to build the appropriate Redfish 50*99b78ec8SJason M. Bills // message 51*99b78ec8SJason M. Bills static constexpr std::string_view openBMCMessageRegistryVersion = "0.1"; 52*99b78ec8SJason M. Bills std::string messageID = 53*99b78ec8SJason M. Bills "OpenBMC." + std::string(openBMCMessageRegistryVersion); 54*99b78ec8SJason M. Bills std::vector<std::string> messageArgs; 55*99b78ec8SJason M. Bills BIOSSensors sensor = static_cast<BIOSSensors>(selData.sensorNum); 56*99b78ec8SJason M. Bills BIOSEventTypes eventType = static_cast<BIOSEventTypes>(selData.eventType); 57*99b78ec8SJason M. Bills switch (sensor) 58*99b78ec8SJason M. Bills { 59*99b78ec8SJason M. Bills case BIOSSensors::memoryRASConfigStatus: 60*99b78ec8SJason M. Bills switch (eventType) 61*99b78ec8SJason M. Bills { 62*99b78ec8SJason M. Bills case BIOSEventTypes::digitalDiscrete: 63*99b78ec8SJason M. Bills { 64*99b78ec8SJason M. Bills switch (selData.offset) 65*99b78ec8SJason M. Bills { 66*99b78ec8SJason M. Bills case 0x00: 67*99b78ec8SJason M. Bills messageID += ".MemoryRASConfigurationDisabled"; 68*99b78ec8SJason M. Bills break; 69*99b78ec8SJason M. Bills case 0x01: 70*99b78ec8SJason M. Bills messageID += ".MemoryRASConfigurationEnabled"; 71*99b78ec8SJason M. Bills break; 72*99b78ec8SJason M. Bills default: 73*99b78ec8SJason M. Bills messageID += ".Unknown"; 74*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 75*99b78ec8SJason M. Bills break; 76*99b78ec8SJason M. Bills } 77*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 78*99b78ec8SJason M. Bills 79*99b78ec8SJason M. Bills // error = eventData2 bits [3:0] 80*99b78ec8SJason M. Bills int error = selData.eventData2 & 0x0F; 81*99b78ec8SJason M. Bills 82*99b78ec8SJason M. Bills // mode = eventData3 bits [3:0] 83*99b78ec8SJason M. Bills int mode = selData.eventData3 & 0x0F; 84*99b78ec8SJason M. Bills 85*99b78ec8SJason M. Bills // Save the messageArgs 86*99b78ec8SJason M. Bills switch (error) 87*99b78ec8SJason M. Bills { 88*99b78ec8SJason M. Bills case 0x00: 89*99b78ec8SJason M. Bills messageArgs.push_back("None"); 90*99b78ec8SJason M. Bills break; 91*99b78ec8SJason M. Bills case 0x03: 92*99b78ec8SJason M. Bills messageArgs.push_back("Invalid DIMM Config"); 93*99b78ec8SJason M. Bills break; 94*99b78ec8SJason M. Bills default: 95*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(error)); 96*99b78ec8SJason M. Bills break; 97*99b78ec8SJason M. Bills } 98*99b78ec8SJason M. Bills switch (mode) 99*99b78ec8SJason M. Bills { 100*99b78ec8SJason M. Bills case 0x00: 101*99b78ec8SJason M. Bills messageArgs.push_back("None"); 102*99b78ec8SJason M. Bills break; 103*99b78ec8SJason M. Bills case 0x01: 104*99b78ec8SJason M. Bills messageArgs.push_back("Mirroring"); 105*99b78ec8SJason M. Bills break; 106*99b78ec8SJason M. Bills case 0x02: 107*99b78ec8SJason M. Bills messageArgs.push_back("Lockstep"); 108*99b78ec8SJason M. Bills break; 109*99b78ec8SJason M. Bills case 0x04: 110*99b78ec8SJason M. Bills messageArgs.push_back("Rank Sparing"); 111*99b78ec8SJason M. Bills break; 112*99b78ec8SJason M. Bills default: 113*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(mode)); 114*99b78ec8SJason M. Bills break; 115*99b78ec8SJason M. Bills } 116*99b78ec8SJason M. Bills 117*99b78ec8SJason M. Bills break; 118*99b78ec8SJason M. Bills } 119*99b78ec8SJason M. Bills default: 120*99b78ec8SJason M. Bills messageID += ".Unknown"; 121*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 122*99b78ec8SJason M. Bills break; 123*99b78ec8SJason M. Bills } 124*99b78ec8SJason M. Bills break; 125*99b78ec8SJason M. Bills case BIOSSensors::biosPOSTError: 126*99b78ec8SJason M. Bills switch (eventType) 127*99b78ec8SJason M. Bills { 128*99b78ec8SJason M. Bills case BIOSEventTypes::sensorSpecificOffset: 129*99b78ec8SJason M. Bills { 130*99b78ec8SJason M. Bills switch (selData.offset) 131*99b78ec8SJason M. Bills { 132*99b78ec8SJason M. Bills case 0x00: 133*99b78ec8SJason M. Bills messageID += ".BIOSPOSTError"; 134*99b78ec8SJason M. Bills break; 135*99b78ec8SJason M. Bills default: 136*99b78ec8SJason M. Bills messageID += ".Unknown"; 137*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 138*99b78ec8SJason M. Bills break; 139*99b78ec8SJason M. Bills } 140*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 141*99b78ec8SJason M. Bills 142*99b78ec8SJason M. Bills std::array<uint8_t, 2> post; 143*99b78ec8SJason M. Bills // post LSB = eventData2 bits [7:0] 144*99b78ec8SJason M. Bills post[1] = selData.eventData2; 145*99b78ec8SJason M. Bills // post MSB = eventData3 bits [7:0] 146*99b78ec8SJason M. Bills post[0] = selData.eventData3; 147*99b78ec8SJason M. Bills 148*99b78ec8SJason M. Bills // Save the messageArgs 149*99b78ec8SJason M. Bills messageArgs.emplace_back(); 150*99b78ec8SJason M. Bills std::string& postStr = messageArgs.back(); 151*99b78ec8SJason M. Bills toHexStr(boost::beast::span<uint8_t>(post), postStr); 152*99b78ec8SJason M. Bills 153*99b78ec8SJason M. Bills break; 154*99b78ec8SJason M. Bills } 155*99b78ec8SJason M. Bills default: 156*99b78ec8SJason M. Bills messageID += ".Unknown"; 157*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 158*99b78ec8SJason M. Bills break; 159*99b78ec8SJason M. Bills } 160*99b78ec8SJason M. Bills break; 161*99b78ec8SJason M. Bills case BIOSSensors::intelUPILinkWidthReduced: 162*99b78ec8SJason M. Bills switch (eventType) 163*99b78ec8SJason M. Bills { 164*99b78ec8SJason M. Bills case BIOSEventTypes::oemDiscrete7: 165*99b78ec8SJason M. Bills { 166*99b78ec8SJason M. Bills switch (selData.offset) 167*99b78ec8SJason M. Bills { 168*99b78ec8SJason M. Bills case 0x01: 169*99b78ec8SJason M. Bills messageID += ".IntelUPILinkWidthReducedToHalf"; 170*99b78ec8SJason M. Bills break; 171*99b78ec8SJason M. Bills case 0x02: 172*99b78ec8SJason M. Bills messageID += ".IntelUPILinkWidthReducedToQuarter"; 173*99b78ec8SJason M. Bills break; 174*99b78ec8SJason M. Bills default: 175*99b78ec8SJason M. Bills messageID += ".Unknown"; 176*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 177*99b78ec8SJason M. Bills break; 178*99b78ec8SJason M. Bills } 179*99b78ec8SJason M. Bills // Get the message data from eventData2 180*99b78ec8SJason M. Bills 181*99b78ec8SJason M. Bills // Node ID = eventData2 bits [7:0] 182*99b78ec8SJason M. Bills int node = selData.eventData2; 183*99b78ec8SJason M. Bills 184*99b78ec8SJason M. Bills // Save the messageArgs 185*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(node + 1)); 186*99b78ec8SJason M. Bills 187*99b78ec8SJason M. Bills break; 188*99b78ec8SJason M. Bills } 189*99b78ec8SJason M. Bills default: 190*99b78ec8SJason M. Bills messageID += ".Unknown"; 191*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 192*99b78ec8SJason M. Bills break; 193*99b78ec8SJason M. Bills } 194*99b78ec8SJason M. Bills break; 195*99b78ec8SJason M. Bills case BIOSSensors::memoryRASModeSelect: 196*99b78ec8SJason M. Bills switch (eventType) 197*99b78ec8SJason M. Bills { 198*99b78ec8SJason M. Bills case BIOSEventTypes::digitalDiscrete: 199*99b78ec8SJason M. Bills { 200*99b78ec8SJason M. Bills switch (selData.offset) 201*99b78ec8SJason M. Bills { 202*99b78ec8SJason M. Bills case 0x00: 203*99b78ec8SJason M. Bills messageID += ".MemoryRASModeDisabled"; 204*99b78ec8SJason M. Bills break; 205*99b78ec8SJason M. Bills case 0x01: 206*99b78ec8SJason M. Bills messageID += ".MemoryRASModeEnabled"; 207*99b78ec8SJason M. Bills break; 208*99b78ec8SJason M. Bills default: 209*99b78ec8SJason M. Bills messageID += ".Unknown"; 210*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 211*99b78ec8SJason M. Bills break; 212*99b78ec8SJason M. Bills } 213*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 214*99b78ec8SJason M. Bills 215*99b78ec8SJason M. Bills // prior mode = eventData2 bits [3:0] 216*99b78ec8SJason M. Bills int priorMode = selData.eventData2 & 0x0F; 217*99b78ec8SJason M. Bills 218*99b78ec8SJason M. Bills // selected mode = eventData3 bits [3:0] 219*99b78ec8SJason M. Bills int selectedMode = selData.eventData3 & 0x0F; 220*99b78ec8SJason M. Bills 221*99b78ec8SJason M. Bills // Save the messageArgs 222*99b78ec8SJason M. Bills switch (priorMode) 223*99b78ec8SJason M. Bills { 224*99b78ec8SJason M. Bills case 0x00: 225*99b78ec8SJason M. Bills messageArgs.push_back("None"); 226*99b78ec8SJason M. Bills break; 227*99b78ec8SJason M. Bills case 0x01: 228*99b78ec8SJason M. Bills messageArgs.push_back("Mirroring"); 229*99b78ec8SJason M. Bills break; 230*99b78ec8SJason M. Bills case 0x02: 231*99b78ec8SJason M. Bills messageArgs.push_back("Lockstep"); 232*99b78ec8SJason M. Bills break; 233*99b78ec8SJason M. Bills case 0x04: 234*99b78ec8SJason M. Bills messageArgs.push_back("Rank Sparing"); 235*99b78ec8SJason M. Bills break; 236*99b78ec8SJason M. Bills default: 237*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(priorMode)); 238*99b78ec8SJason M. Bills break; 239*99b78ec8SJason M. Bills } 240*99b78ec8SJason M. Bills switch (selectedMode) 241*99b78ec8SJason M. Bills { 242*99b78ec8SJason M. Bills case 0x00: 243*99b78ec8SJason M. Bills messageArgs.push_back("None"); 244*99b78ec8SJason M. Bills break; 245*99b78ec8SJason M. Bills case 0x01: 246*99b78ec8SJason M. Bills messageArgs.push_back("Mirroring"); 247*99b78ec8SJason M. Bills break; 248*99b78ec8SJason M. Bills case 0x02: 249*99b78ec8SJason M. Bills messageArgs.push_back("Lockstep"); 250*99b78ec8SJason M. Bills break; 251*99b78ec8SJason M. Bills case 0x04: 252*99b78ec8SJason M. Bills messageArgs.push_back("Rank Sparing"); 253*99b78ec8SJason M. Bills break; 254*99b78ec8SJason M. Bills default: 255*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(selectedMode)); 256*99b78ec8SJason M. Bills break; 257*99b78ec8SJason M. Bills } 258*99b78ec8SJason M. Bills 259*99b78ec8SJason M. Bills break; 260*99b78ec8SJason M. Bills } 261*99b78ec8SJason M. Bills default: 262*99b78ec8SJason M. Bills messageID += ".Unknown"; 263*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 264*99b78ec8SJason M. Bills break; 265*99b78ec8SJason M. Bills } 266*99b78ec8SJason M. Bills break; 267*99b78ec8SJason M. Bills case BIOSSensors::bootEvent: 268*99b78ec8SJason M. Bills switch (eventType) 269*99b78ec8SJason M. Bills { 270*99b78ec8SJason M. Bills case BIOSEventTypes::sensorSpecificOffset: 271*99b78ec8SJason M. Bills { 272*99b78ec8SJason M. Bills switch (selData.offset) 273*99b78ec8SJason M. Bills { 274*99b78ec8SJason M. Bills case 0x01: 275*99b78ec8SJason M. Bills messageID += ".BIOSBoot"; 276*99b78ec8SJason M. Bills break; 277*99b78ec8SJason M. Bills default: 278*99b78ec8SJason M. Bills messageID += ".Unknown"; 279*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 280*99b78ec8SJason M. Bills break; 281*99b78ec8SJason M. Bills } 282*99b78ec8SJason M. Bills break; 283*99b78ec8SJason M. Bills } 284*99b78ec8SJason M. Bills default: 285*99b78ec8SJason M. Bills messageID += ".Unknown"; 286*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 287*99b78ec8SJason M. Bills break; 288*99b78ec8SJason M. Bills } 289*99b78ec8SJason M. Bills break; 290*99b78ec8SJason M. Bills default: 291*99b78ec8SJason M. Bills messageID += ".Unknown"; 292*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 293*99b78ec8SJason M. Bills break; 294*99b78ec8SJason M. Bills } 295*99b78ec8SJason M. Bills 296*99b78ec8SJason M. Bills // Log the Redfish message to the journal with the appropriate metadata 297*99b78ec8SJason M. Bills std::string journalMsg = "BIOS POST IPMI event: " + ipmiRaw; 298*99b78ec8SJason M. Bills if (messageArgs.empty()) 299*99b78ec8SJason M. Bills { 300*99b78ec8SJason M. Bills phosphor::logging::log<phosphor::logging::level::INFO>( 301*99b78ec8SJason M. Bills journalMsg.c_str(), 302*99b78ec8SJason M. Bills phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", 303*99b78ec8SJason M. Bills messageID.c_str())); 304*99b78ec8SJason M. Bills } 305*99b78ec8SJason M. Bills else 306*99b78ec8SJason M. Bills { 307*99b78ec8SJason M. Bills std::string messageArgsString = 308*99b78ec8SJason M. Bills boost::algorithm::join(messageArgs, ","); 309*99b78ec8SJason M. Bills phosphor::logging::log<phosphor::logging::level::INFO>( 310*99b78ec8SJason M. Bills journalMsg.c_str(), 311*99b78ec8SJason M. Bills phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", 312*99b78ec8SJason M. Bills messageID.c_str()), 313*99b78ec8SJason M. Bills phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s", 314*99b78ec8SJason M. Bills messageArgsString.c_str())); 315*99b78ec8SJason M. Bills } 316*99b78ec8SJason M. Bills 317*99b78ec8SJason M. Bills return true; 318*99b78ec8SJason M. Bills } 319*99b78ec8SJason M. Bills 320*99b78ec8SJason M. Bills // Record a BIOS SMI message as a Redfish message instead of a SEL record 321*99b78ec8SJason M. Bills static bool biosSMIMessageHook(const SELData& selData, 322*99b78ec8SJason M. Bills const std::string& ipmiRaw) 323*99b78ec8SJason M. Bills { 324*99b78ec8SJason M. Bills // This is a BIOS SMI message, so record it as a Redfish message instead 325*99b78ec8SJason M. Bills // of a SEL record 326*99b78ec8SJason M. Bills 327*99b78ec8SJason M. Bills // Walk through the SEL request record to build the appropriate Redfish 328*99b78ec8SJason M. Bills // message 329*99b78ec8SJason M. Bills static constexpr std::string_view openBMCMessageRegistryVersion = "0.1"; 330*99b78ec8SJason M. Bills std::string messageID = 331*99b78ec8SJason M. Bills "OpenBMC." + std::string(openBMCMessageRegistryVersion); 332*99b78ec8SJason M. Bills std::vector<std::string> messageArgs; 333*99b78ec8SJason M. Bills BIOSSMISensors sensor = static_cast<BIOSSMISensors>(selData.sensorNum); 334*99b78ec8SJason M. Bills BIOSEventTypes eventType = static_cast<BIOSEventTypes>(selData.eventType); 335*99b78ec8SJason M. Bills switch (sensor) 336*99b78ec8SJason M. Bills { 337*99b78ec8SJason M. Bills case BIOSSMISensors::mirroringRedundancyState: 338*99b78ec8SJason M. Bills switch (eventType) 339*99b78ec8SJason M. Bills { 340*99b78ec8SJason M. Bills case BIOSEventTypes::discreteRedundancyStates: 341*99b78ec8SJason M. Bills { 342*99b78ec8SJason M. Bills switch (selData.offset) 343*99b78ec8SJason M. Bills { 344*99b78ec8SJason M. Bills case 0x00: 345*99b78ec8SJason M. Bills messageID += ".MirroringRedundancyFull"; 346*99b78ec8SJason M. Bills break; 347*99b78ec8SJason M. Bills case 0x02: 348*99b78ec8SJason M. Bills messageID += ".MirroringRedundancyDegraded"; 349*99b78ec8SJason M. Bills break; 350*99b78ec8SJason M. Bills default: 351*99b78ec8SJason M. Bills messageID += ".Unknown"; 352*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 353*99b78ec8SJason M. Bills break; 354*99b78ec8SJason M. Bills } 355*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 356*99b78ec8SJason M. Bills 357*99b78ec8SJason M. Bills // pair = eventData2 bits [7:4] 358*99b78ec8SJason M. Bills int pair = selData.eventData2 >> 4 & 0x0F; 359*99b78ec8SJason M. Bills // rank = eventData2 bits [1:0] 360*99b78ec8SJason M. Bills int rank = selData.eventData2 & 0x03; 361*99b78ec8SJason M. Bills 362*99b78ec8SJason M. Bills // Socket ID = eventData3 bits [7:5] 363*99b78ec8SJason M. Bills int socket = selData.eventData3 >> 5 & 0x07; 364*99b78ec8SJason M. Bills // Channel = eventData3 bits [4:2] 365*99b78ec8SJason M. Bills int channel = selData.eventData3 >> 2 & 0x07; 366*99b78ec8SJason M. Bills char channelLetter[4] = {'A'}; 367*99b78ec8SJason M. Bills channelLetter[0] += channel; 368*99b78ec8SJason M. Bills // DIMM = eventData3 bits [1:0] 369*99b78ec8SJason M. Bills int dimm = selData.eventData3 & 0x03; 370*99b78ec8SJason M. Bills 371*99b78ec8SJason M. Bills // Save the messageArgs 372*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(socket + 1)); 373*99b78ec8SJason M. Bills messageArgs.push_back(std::string(channelLetter)); 374*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(dimm + 1)); 375*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(pair)); 376*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(rank)); 377*99b78ec8SJason M. Bills 378*99b78ec8SJason M. Bills break; 379*99b78ec8SJason M. Bills } 380*99b78ec8SJason M. Bills default: 381*99b78ec8SJason M. Bills messageID += ".Unknown"; 382*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 383*99b78ec8SJason M. Bills break; 384*99b78ec8SJason M. Bills } 385*99b78ec8SJason M. Bills break; 386*99b78ec8SJason M. Bills case BIOSSMISensors::memoryECCError: 387*99b78ec8SJason M. Bills switch (eventType) 388*99b78ec8SJason M. Bills { 389*99b78ec8SJason M. Bills case BIOSEventTypes::sensorSpecificOffset: 390*99b78ec8SJason M. Bills { 391*99b78ec8SJason M. Bills switch (selData.offset) 392*99b78ec8SJason M. Bills { 393*99b78ec8SJason M. Bills case 0x00: 394*99b78ec8SJason M. Bills messageID += ".MemoryECCCorrectable"; 395*99b78ec8SJason M. Bills break; 396*99b78ec8SJason M. Bills case 0x01: 397*99b78ec8SJason M. Bills messageID += ".MemoryECCUncorrectable"; 398*99b78ec8SJason M. Bills break; 399*99b78ec8SJason M. Bills default: 400*99b78ec8SJason M. Bills messageID += ".Unknown"; 401*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 402*99b78ec8SJason M. Bills break; 403*99b78ec8SJason M. Bills } 404*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 405*99b78ec8SJason M. Bills 406*99b78ec8SJason M. Bills // dimm = eventData2 bits [7:4] 407*99b78ec8SJason M. Bills int dimm = selData.eventData2 >> 4 & 0x0F; 408*99b78ec8SJason M. Bills // rank = eventData2 bits [3:0] 409*99b78ec8SJason M. Bills int rank = selData.eventData2 & 0x0F; 410*99b78ec8SJason M. Bills 411*99b78ec8SJason M. Bills // Socket ID = eventData3 bits [7:4] 412*99b78ec8SJason M. Bills int socket = selData.eventData3 >> 4 & 0x0F; 413*99b78ec8SJason M. Bills // Channel = eventData3 bits [3:0] 414*99b78ec8SJason M. Bills int channel = selData.eventData3 & 0x0F; 415*99b78ec8SJason M. Bills char channelLetter[4] = {'A'}; 416*99b78ec8SJason M. Bills channelLetter[0] += channel; 417*99b78ec8SJason M. Bills 418*99b78ec8SJason M. Bills // Save the messageArgs 419*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(socket + 1)); 420*99b78ec8SJason M. Bills messageArgs.push_back(std::string(channelLetter)); 421*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(dimm)); 422*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(rank)); 423*99b78ec8SJason M. Bills 424*99b78ec8SJason M. Bills break; 425*99b78ec8SJason M. Bills } 426*99b78ec8SJason M. Bills default: 427*99b78ec8SJason M. Bills messageID += ".Unknown"; 428*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 429*99b78ec8SJason M. Bills break; 430*99b78ec8SJason M. Bills } 431*99b78ec8SJason M. Bills break; 432*99b78ec8SJason M. Bills case BIOSSMISensors::legacyPCIError: 433*99b78ec8SJason M. Bills switch (eventType) 434*99b78ec8SJason M. Bills { 435*99b78ec8SJason M. Bills case BIOSEventTypes::sensorSpecificOffset: 436*99b78ec8SJason M. Bills { 437*99b78ec8SJason M. Bills switch (selData.offset) 438*99b78ec8SJason M. Bills { 439*99b78ec8SJason M. Bills case 0x04: 440*99b78ec8SJason M. Bills messageID += ".LegacyPCIPERR"; 441*99b78ec8SJason M. Bills break; 442*99b78ec8SJason M. Bills case 0x05: 443*99b78ec8SJason M. Bills messageID += ".LegacyPCISERR"; 444*99b78ec8SJason M. Bills break; 445*99b78ec8SJason M. Bills default: 446*99b78ec8SJason M. Bills messageID += ".Unknown"; 447*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 448*99b78ec8SJason M. Bills break; 449*99b78ec8SJason M. Bills } 450*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 451*99b78ec8SJason M. Bills 452*99b78ec8SJason M. Bills // Bus = eventData2 bits [7:0] 453*99b78ec8SJason M. Bills int bus = selData.eventData2; 454*99b78ec8SJason M. Bills // Device = eventData3 bits [7:3] 455*99b78ec8SJason M. Bills int device = selData.eventData3 >> 3 & 0x1F; 456*99b78ec8SJason M. Bills // Function = eventData3 bits [2:0] 457*99b78ec8SJason M. Bills int function = selData.eventData3 >> 0x07; 458*99b78ec8SJason M. Bills 459*99b78ec8SJason M. Bills // Save the messageArgs 460*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(bus)); 461*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(device)); 462*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(function)); 463*99b78ec8SJason M. Bills 464*99b78ec8SJason M. Bills break; 465*99b78ec8SJason M. Bills } 466*99b78ec8SJason M. Bills default: 467*99b78ec8SJason M. Bills messageID += ".Unknown"; 468*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 469*99b78ec8SJason M. Bills break; 470*99b78ec8SJason M. Bills } 471*99b78ec8SJason M. Bills break; 472*99b78ec8SJason M. Bills case BIOSSMISensors::pcieFatalError: 473*99b78ec8SJason M. Bills switch (eventType) 474*99b78ec8SJason M. Bills { 475*99b78ec8SJason M. Bills case BIOSEventTypes::oemDiscrete0: 476*99b78ec8SJason M. Bills { 477*99b78ec8SJason M. Bills switch (selData.offset) 478*99b78ec8SJason M. Bills { 479*99b78ec8SJason M. Bills case 0x00: 480*99b78ec8SJason M. Bills messageID += ".PCIeFatalDataLinkLayerProtocol"; 481*99b78ec8SJason M. Bills break; 482*99b78ec8SJason M. Bills case 0x01: 483*99b78ec8SJason M. Bills messageID += ".PCIeFatalSurpriseLinkDown"; 484*99b78ec8SJason M. Bills break; 485*99b78ec8SJason M. Bills case 0x02: 486*99b78ec8SJason M. Bills messageID += ".PCIeFatalCompleterAbort"; 487*99b78ec8SJason M. Bills break; 488*99b78ec8SJason M. Bills case 0x03: 489*99b78ec8SJason M. Bills messageID += ".PCIeFatalUnsupportedRequest"; 490*99b78ec8SJason M. Bills break; 491*99b78ec8SJason M. Bills case 0x04: 492*99b78ec8SJason M. Bills messageID += ".PCIeFatalPoisonedTLP"; 493*99b78ec8SJason M. Bills break; 494*99b78ec8SJason M. Bills case 0x05: 495*99b78ec8SJason M. Bills messageID += ".PCIeFatalFlowControlProtocol"; 496*99b78ec8SJason M. Bills break; 497*99b78ec8SJason M. Bills case 0x06: 498*99b78ec8SJason M. Bills messageID += ".PCIeFatalCompletionTimeout"; 499*99b78ec8SJason M. Bills break; 500*99b78ec8SJason M. Bills case 0x07: 501*99b78ec8SJason M. Bills messageID += ".PCIeFatalReceiverBufferOverflow"; 502*99b78ec8SJason M. Bills break; 503*99b78ec8SJason M. Bills case 0x08: 504*99b78ec8SJason M. Bills messageID += ".PCIeFatalACSViolation"; 505*99b78ec8SJason M. Bills break; 506*99b78ec8SJason M. Bills case 0x09: 507*99b78ec8SJason M. Bills messageID += ".PCIeFatalMalformedTLP"; 508*99b78ec8SJason M. Bills break; 509*99b78ec8SJason M. Bills case 0x0a: 510*99b78ec8SJason M. Bills messageID += ".PCIeFatalECRCError"; 511*99b78ec8SJason M. Bills break; 512*99b78ec8SJason M. Bills case 0x0b: 513*99b78ec8SJason M. Bills messageID += 514*99b78ec8SJason M. Bills ".PCIeFatalReceivedFatalMessageFromDownstream"; 515*99b78ec8SJason M. Bills break; 516*99b78ec8SJason M. Bills case 0x0c: 517*99b78ec8SJason M. Bills messageID += ".PCIeFatalUnexpectedCompletion"; 518*99b78ec8SJason M. Bills break; 519*99b78ec8SJason M. Bills case 0x0d: 520*99b78ec8SJason M. Bills messageID += 521*99b78ec8SJason M. Bills ".PCIeFatalReceivedERR_NONFATALMessage"; 522*99b78ec8SJason M. Bills break; 523*99b78ec8SJason M. Bills case 0x0e: 524*99b78ec8SJason M. Bills messageID += ".PCIeFatalUncorrectableInternal"; 525*99b78ec8SJason M. Bills break; 526*99b78ec8SJason M. Bills case 0x0f: 527*99b78ec8SJason M. Bills messageID += ".PCIeFatalMCBlockedTLP"; 528*99b78ec8SJason M. Bills break; 529*99b78ec8SJason M. Bills default: 530*99b78ec8SJason M. Bills messageID += ".Unknown"; 531*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 532*99b78ec8SJason M. Bills break; 533*99b78ec8SJason M. Bills } 534*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 535*99b78ec8SJason M. Bills 536*99b78ec8SJason M. Bills // Bus = eventData2 bits [7:0] 537*99b78ec8SJason M. Bills int bus = selData.eventData2; 538*99b78ec8SJason M. Bills // Device = eventData3 bits [7:3] 539*99b78ec8SJason M. Bills int device = selData.eventData3 >> 3 & 0x1F; 540*99b78ec8SJason M. Bills // Function = eventData3 bits [2:0] 541*99b78ec8SJason M. Bills int function = selData.eventData3 >> 0x07; 542*99b78ec8SJason M. Bills 543*99b78ec8SJason M. Bills // Save the messageArgs 544*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(bus)); 545*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(device)); 546*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(function)); 547*99b78ec8SJason M. Bills 548*99b78ec8SJason M. Bills break; 549*99b78ec8SJason M. Bills } 550*99b78ec8SJason M. Bills default: 551*99b78ec8SJason M. Bills messageID += ".Unknown"; 552*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 553*99b78ec8SJason M. Bills break; 554*99b78ec8SJason M. Bills } 555*99b78ec8SJason M. Bills break; 556*99b78ec8SJason M. Bills case BIOSSMISensors::pcieCorrectableError: 557*99b78ec8SJason M. Bills switch (eventType) 558*99b78ec8SJason M. Bills { 559*99b78ec8SJason M. Bills case BIOSEventTypes::oemDiscrete1: 560*99b78ec8SJason M. Bills { 561*99b78ec8SJason M. Bills switch (selData.offset) 562*99b78ec8SJason M. Bills { 563*99b78ec8SJason M. Bills case 0x00: 564*99b78ec8SJason M. Bills messageID += ".PCIeCorrectableReceiverError"; 565*99b78ec8SJason M. Bills break; 566*99b78ec8SJason M. Bills case 0x01: 567*99b78ec8SJason M. Bills messageID += ".PCIeCorrectableBadDLLP"; 568*99b78ec8SJason M. Bills break; 569*99b78ec8SJason M. Bills case 0x02: 570*99b78ec8SJason M. Bills messageID += ".PCIeCorrectableBadTLP"; 571*99b78ec8SJason M. Bills break; 572*99b78ec8SJason M. Bills case 0x03: 573*99b78ec8SJason M. Bills messageID += ".PCIeCorrectableReplayNumRollover"; 574*99b78ec8SJason M. Bills break; 575*99b78ec8SJason M. Bills case 0x04: 576*99b78ec8SJason M. Bills messageID += ".PCIeCorrectableReplayTimerTimeout"; 577*99b78ec8SJason M. Bills break; 578*99b78ec8SJason M. Bills case 0x05: 579*99b78ec8SJason M. Bills messageID += ".PCIeCorrectableAdvisoryNonFatal"; 580*99b78ec8SJason M. Bills break; 581*99b78ec8SJason M. Bills case 0x06: 582*99b78ec8SJason M. Bills messageID += ".PCIeCorrectableLinkBWChanged"; 583*99b78ec8SJason M. Bills break; 584*99b78ec8SJason M. Bills case 0x07: 585*99b78ec8SJason M. Bills messageID += ".PCIeCorrectableInternal"; 586*99b78ec8SJason M. Bills break; 587*99b78ec8SJason M. Bills case 0x08: 588*99b78ec8SJason M. Bills messageID += ".PCIeCorrectableHeaderLogOverflow"; 589*99b78ec8SJason M. Bills break; 590*99b78ec8SJason M. Bills case 0x0f: 591*99b78ec8SJason M. Bills messageID += ".PCIeCorrectableUnspecifiedAERError"; 592*99b78ec8SJason M. Bills break; 593*99b78ec8SJason M. Bills default: 594*99b78ec8SJason M. Bills messageID += ".Unknown"; 595*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 596*99b78ec8SJason M. Bills break; 597*99b78ec8SJason M. Bills } 598*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 599*99b78ec8SJason M. Bills 600*99b78ec8SJason M. Bills // Bus = eventData2 bits [7:0] 601*99b78ec8SJason M. Bills int bus = selData.eventData2; 602*99b78ec8SJason M. Bills // Device = eventData3 bits [7:3] 603*99b78ec8SJason M. Bills int device = selData.eventData3 >> 3 & 0x1F; 604*99b78ec8SJason M. Bills // Function = eventData3 bits [2:0] 605*99b78ec8SJason M. Bills int function = selData.eventData3 >> 0x07; 606*99b78ec8SJason M. Bills 607*99b78ec8SJason M. Bills // Save the messageArgs 608*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(bus)); 609*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(device)); 610*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(function)); 611*99b78ec8SJason M. Bills 612*99b78ec8SJason M. Bills break; 613*99b78ec8SJason M. Bills } 614*99b78ec8SJason M. Bills default: 615*99b78ec8SJason M. Bills messageID += ".Unknown"; 616*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 617*99b78ec8SJason M. Bills break; 618*99b78ec8SJason M. Bills } 619*99b78ec8SJason M. Bills break; 620*99b78ec8SJason M. Bills case BIOSSMISensors::sparingRedundancyState: 621*99b78ec8SJason M. Bills switch (eventType) 622*99b78ec8SJason M. Bills { 623*99b78ec8SJason M. Bills case BIOSEventTypes::discreteRedundancyStates: 624*99b78ec8SJason M. Bills { 625*99b78ec8SJason M. Bills switch (selData.offset) 626*99b78ec8SJason M. Bills { 627*99b78ec8SJason M. Bills case 0x00: 628*99b78ec8SJason M. Bills messageID += ".SparingRedundancyFull"; 629*99b78ec8SJason M. Bills break; 630*99b78ec8SJason M. Bills case 0x02: 631*99b78ec8SJason M. Bills messageID += ".SparingRedundancyDegraded"; 632*99b78ec8SJason M. Bills break; 633*99b78ec8SJason M. Bills default: 634*99b78ec8SJason M. Bills messageID += ".Unknown"; 635*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 636*99b78ec8SJason M. Bills break; 637*99b78ec8SJason M. Bills } 638*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 639*99b78ec8SJason M. Bills 640*99b78ec8SJason M. Bills // domain = eventData2 bits [7:4] 641*99b78ec8SJason M. Bills int domain = selData.eventData2 >> 4 & 0x0F; 642*99b78ec8SJason M. Bills char domainLetter[4] = {'A'}; 643*99b78ec8SJason M. Bills domainLetter[0] += domain; 644*99b78ec8SJason M. Bills // rank = eventData2 bits [1:0] 645*99b78ec8SJason M. Bills int rank = selData.eventData2 & 0x03; 646*99b78ec8SJason M. Bills 647*99b78ec8SJason M. Bills // Socket ID = eventData3 bits [7:5] 648*99b78ec8SJason M. Bills int socket = selData.eventData3 >> 5 & 0x07; 649*99b78ec8SJason M. Bills // Channel = eventData3 bits [4:2] 650*99b78ec8SJason M. Bills int channel = selData.eventData3 >> 2 & 0x07; 651*99b78ec8SJason M. Bills char channelLetter[4] = {'A'}; 652*99b78ec8SJason M. Bills channelLetter[0] += channel; 653*99b78ec8SJason M. Bills // DIMM = eventData3 bits [1:0] 654*99b78ec8SJason M. Bills int dimm = selData.eventData3 & 0x03; 655*99b78ec8SJason M. Bills 656*99b78ec8SJason M. Bills // Save the messageArgs 657*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(socket + 1)); 658*99b78ec8SJason M. Bills messageArgs.push_back(std::string(channelLetter)); 659*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(dimm + 1)); 660*99b78ec8SJason M. Bills messageArgs.push_back(std::string(domainLetter)); 661*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(rank)); 662*99b78ec8SJason M. Bills 663*99b78ec8SJason M. Bills break; 664*99b78ec8SJason M. Bills } 665*99b78ec8SJason M. Bills default: 666*99b78ec8SJason M. Bills messageID += ".Unknown"; 667*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 668*99b78ec8SJason M. Bills break; 669*99b78ec8SJason M. Bills } 670*99b78ec8SJason M. Bills break; 671*99b78ec8SJason M. Bills case BIOSSMISensors::memoryParityError: 672*99b78ec8SJason M. Bills switch (eventType) 673*99b78ec8SJason M. Bills { 674*99b78ec8SJason M. Bills case BIOSEventTypes::sensorSpecificOffset: 675*99b78ec8SJason M. Bills { 676*99b78ec8SJason M. Bills switch (selData.offset) 677*99b78ec8SJason M. Bills { 678*99b78ec8SJason M. Bills case 0x03: 679*99b78ec8SJason M. Bills { 680*99b78ec8SJason M. Bills // type = eventData2 bits [2:0] 681*99b78ec8SJason M. Bills int type = selData.eventData2 & 0x07; 682*99b78ec8SJason M. Bills switch (type) 683*99b78ec8SJason M. Bills { 684*99b78ec8SJason M. Bills case 0x00: 685*99b78ec8SJason M. Bills messageID += ".MemoryParityNotKnown"; 686*99b78ec8SJason M. Bills break; 687*99b78ec8SJason M. Bills case 0x03: 688*99b78ec8SJason M. Bills messageID += 689*99b78ec8SJason M. Bills ".MemoryParityCommandAndAddress"; 690*99b78ec8SJason M. Bills break; 691*99b78ec8SJason M. Bills default: 692*99b78ec8SJason M. Bills messageID += ".Unknown"; 693*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 694*99b78ec8SJason M. Bills break; 695*99b78ec8SJason M. Bills } 696*99b78ec8SJason M. Bills break; 697*99b78ec8SJason M. Bills } 698*99b78ec8SJason M. Bills default: 699*99b78ec8SJason M. Bills messageID += ".Unknown"; 700*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 701*99b78ec8SJason M. Bills break; 702*99b78ec8SJason M. Bills } 703*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 704*99b78ec8SJason M. Bills 705*99b78ec8SJason M. Bills // channelValid = eventData2 bit [4] 706*99b78ec8SJason M. Bills int channelValid = selData.eventData2 >> 4 & 0x01; 707*99b78ec8SJason M. Bills // dimmValid = eventData2 bit [3] 708*99b78ec8SJason M. Bills int dimmValid = selData.eventData2 >> 3 & 0x01; 709*99b78ec8SJason M. Bills 710*99b78ec8SJason M. Bills // Socket ID = eventData3 bits [7:5] 711*99b78ec8SJason M. Bills int socket = selData.eventData3 >> 5 & 0x07; 712*99b78ec8SJason M. Bills // Channel = eventData3 bits [4:2] 713*99b78ec8SJason M. Bills int channel = selData.eventData3 >> 2 & 0x07; 714*99b78ec8SJason M. Bills char channelLetter[4] = {'A'}; 715*99b78ec8SJason M. Bills channelLetter[0] += channel; 716*99b78ec8SJason M. Bills // DIMM = eventData3 bits [1:0] 717*99b78ec8SJason M. Bills int dimm = selData.eventData3 & 0x03; 718*99b78ec8SJason M. Bills 719*99b78ec8SJason M. Bills // Save the messageArgs 720*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(socket + 1)); 721*99b78ec8SJason M. Bills messageArgs.push_back(std::string(channelLetter)); 722*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(dimm + 1)); 723*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(channelValid)); 724*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(dimmValid)); 725*99b78ec8SJason M. Bills 726*99b78ec8SJason M. Bills break; 727*99b78ec8SJason M. Bills } 728*99b78ec8SJason M. Bills default: 729*99b78ec8SJason M. Bills messageID += ".Unknown"; 730*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 731*99b78ec8SJason M. Bills break; 732*99b78ec8SJason M. Bills } 733*99b78ec8SJason M. Bills break; 734*99b78ec8SJason M. Bills case BIOSSMISensors::pcieFatalError2: 735*99b78ec8SJason M. Bills switch (eventType) 736*99b78ec8SJason M. Bills { 737*99b78ec8SJason M. Bills case BIOSEventTypes::oemDiscrete6: 738*99b78ec8SJason M. Bills { 739*99b78ec8SJason M. Bills switch (selData.offset) 740*99b78ec8SJason M. Bills { 741*99b78ec8SJason M. Bills case 0x00: 742*99b78ec8SJason M. Bills messageID += ".PCIeFatalAtomicEgressBlocked"; 743*99b78ec8SJason M. Bills break; 744*99b78ec8SJason M. Bills case 0x01: 745*99b78ec8SJason M. Bills messageID += ".PCIeFatalTLPPrefixBlocked"; 746*99b78ec8SJason M. Bills break; 747*99b78ec8SJason M. Bills case 0x0f: 748*99b78ec8SJason M. Bills messageID += 749*99b78ec8SJason M. Bills ".PCIeFatalUnspecifiedNonAERFatalError"; 750*99b78ec8SJason M. Bills break; 751*99b78ec8SJason M. Bills default: 752*99b78ec8SJason M. Bills messageID += ".Unknown"; 753*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 754*99b78ec8SJason M. Bills break; 755*99b78ec8SJason M. Bills } 756*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 757*99b78ec8SJason M. Bills 758*99b78ec8SJason M. Bills // Bus = eventData2 bits [7:0] 759*99b78ec8SJason M. Bills int bus = selData.eventData2; 760*99b78ec8SJason M. Bills // Device = eventData3 bits [7:3] 761*99b78ec8SJason M. Bills int device = selData.eventData3 >> 3 & 0x1F; 762*99b78ec8SJason M. Bills // Function = eventData3 bits [2:0] 763*99b78ec8SJason M. Bills int function = selData.eventData3 >> 0x07; 764*99b78ec8SJason M. Bills 765*99b78ec8SJason M. Bills // Save the messageArgs 766*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(bus)); 767*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(device)); 768*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(function)); 769*99b78ec8SJason M. Bills 770*99b78ec8SJason M. Bills break; 771*99b78ec8SJason M. Bills } 772*99b78ec8SJason M. Bills default: 773*99b78ec8SJason M. Bills messageID += ".Unknown"; 774*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 775*99b78ec8SJason M. Bills break; 776*99b78ec8SJason M. Bills } 777*99b78ec8SJason M. Bills break; 778*99b78ec8SJason M. Bills case BIOSSMISensors::biosRecovery: 779*99b78ec8SJason M. Bills switch (eventType) 780*99b78ec8SJason M. Bills { 781*99b78ec8SJason M. Bills case BIOSEventTypes::oemDiscrete0: 782*99b78ec8SJason M. Bills { 783*99b78ec8SJason M. Bills switch (selData.offset) 784*99b78ec8SJason M. Bills { 785*99b78ec8SJason M. Bills case 0x01: 786*99b78ec8SJason M. Bills messageID += ".BIOSRecoveryStart"; 787*99b78ec8SJason M. Bills break; 788*99b78ec8SJason M. Bills default: 789*99b78ec8SJason M. Bills messageID += ".Unknown"; 790*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 791*99b78ec8SJason M. Bills break; 792*99b78ec8SJason M. Bills } 793*99b78ec8SJason M. Bills break; 794*99b78ec8SJason M. Bills } 795*99b78ec8SJason M. Bills case BIOSEventTypes::reservedF0: 796*99b78ec8SJason M. Bills { 797*99b78ec8SJason M. Bills switch (selData.offset) 798*99b78ec8SJason M. Bills { 799*99b78ec8SJason M. Bills case 0x01: 800*99b78ec8SJason M. Bills messageID += ".BIOSRecoveryComplete"; 801*99b78ec8SJason M. Bills break; 802*99b78ec8SJason M. Bills default: 803*99b78ec8SJason M. Bills messageID += ".Unknown"; 804*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 805*99b78ec8SJason M. Bills break; 806*99b78ec8SJason M. Bills } 807*99b78ec8SJason M. Bills break; 808*99b78ec8SJason M. Bills } 809*99b78ec8SJason M. Bills default: 810*99b78ec8SJason M. Bills messageID += ".Unknown"; 811*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 812*99b78ec8SJason M. Bills break; 813*99b78ec8SJason M. Bills } 814*99b78ec8SJason M. Bills break; 815*99b78ec8SJason M. Bills case BIOSSMISensors::adddcError: 816*99b78ec8SJason M. Bills switch (eventType) 817*99b78ec8SJason M. Bills { 818*99b78ec8SJason M. Bills case BIOSEventTypes::reservedA0: 819*99b78ec8SJason M. Bills { 820*99b78ec8SJason M. Bills messageID += ".ADDDCCorrectable"; 821*99b78ec8SJason M. Bills 822*99b78ec8SJason M. Bills // Get the message data from eventData2 and eventData3 823*99b78ec8SJason M. Bills 824*99b78ec8SJason M. Bills // dimm = eventData2 bits [7:4] 825*99b78ec8SJason M. Bills int dimm = selData.eventData2 >> 4 & 0x0F; 826*99b78ec8SJason M. Bills // rank = eventData2 bits [3:0] 827*99b78ec8SJason M. Bills int rank = selData.eventData2 & 0x0F; 828*99b78ec8SJason M. Bills 829*99b78ec8SJason M. Bills // Socket ID = eventData3 bits [7:4] 830*99b78ec8SJason M. Bills int socket = selData.eventData3 >> 4 & 0x0F; 831*99b78ec8SJason M. Bills // Channel = eventData3 bits [3:0] 832*99b78ec8SJason M. Bills int channel = selData.eventData3 & 0x0F; 833*99b78ec8SJason M. Bills char channelLetter[4] = {'A'}; 834*99b78ec8SJason M. Bills channelLetter[0] += channel; 835*99b78ec8SJason M. Bills 836*99b78ec8SJason M. Bills // Save the messageArgs 837*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(socket + 1)); 838*99b78ec8SJason M. Bills messageArgs.push_back(std::string(channelLetter)); 839*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(dimm)); 840*99b78ec8SJason M. Bills messageArgs.push_back(std::to_string(rank)); 841*99b78ec8SJason M. Bills 842*99b78ec8SJason M. Bills break; 843*99b78ec8SJason M. Bills } 844*99b78ec8SJason M. Bills default: 845*99b78ec8SJason M. Bills messageID += ".Unknown"; 846*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 847*99b78ec8SJason M. Bills break; 848*99b78ec8SJason M. Bills } 849*99b78ec8SJason M. Bills break; 850*99b78ec8SJason M. Bills default: 851*99b78ec8SJason M. Bills messageID += ".Unknown"; 852*99b78ec8SJason M. Bills messageArgs.push_back(ipmiRaw); 853*99b78ec8SJason M. Bills break; 854*99b78ec8SJason M. Bills } 855*99b78ec8SJason M. Bills 856*99b78ec8SJason M. Bills // Log the Redfish message to the journal with the appropriate metadata 857*99b78ec8SJason M. Bills std::string journalMsg = "BIOS SMI IPMI event: " + ipmiRaw; 858*99b78ec8SJason M. Bills std::string messageArgsString = boost::algorithm::join(messageArgs, ","); 859*99b78ec8SJason M. Bills phosphor::logging::log<phosphor::logging::level::INFO>( 860*99b78ec8SJason M. Bills journalMsg.c_str(), 861*99b78ec8SJason M. Bills phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageID.c_str()), 862*99b78ec8SJason M. Bills phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s", 863*99b78ec8SJason M. Bills messageArgsString.c_str())); 864*99b78ec8SJason M. Bills 865*99b78ec8SJason M. Bills return true; 866*99b78ec8SJason M. Bills } 867*99b78ec8SJason M. Bills 868*99b78ec8SJason M. Bills static bool startRedfishHook(const SELData& selData, const std::string& ipmiRaw) 869*99b78ec8SJason M. Bills { 870*99b78ec8SJason M. Bills switch (selData.generatorID) 871*99b78ec8SJason M. Bills { 872*99b78ec8SJason M. Bills case 0x01: // Check if this message is from the BIOS Generator ID 873*99b78ec8SJason M. Bills // Let the BIOS hook handle this request 874*99b78ec8SJason M. Bills return biosMessageHook(selData, ipmiRaw); 875*99b78ec8SJason M. Bills break; 876*99b78ec8SJason M. Bills 877*99b78ec8SJason M. Bills case 0x33: // Check if this message is from the BIOS SMI Generator ID 878*99b78ec8SJason M. Bills // Let the BIOS SMI hook handle this request 879*99b78ec8SJason M. Bills return biosSMIMessageHook(selData, ipmiRaw); 880*99b78ec8SJason M. Bills break; 881*99b78ec8SJason M. Bills } 882*99b78ec8SJason M. Bills 883*99b78ec8SJason M. Bills // No hooks handled the request, so let it go to the SEL 884*99b78ec8SJason M. Bills return false; 885*99b78ec8SJason M. Bills } 886*99b78ec8SJason M. Bills } // namespace redfish_hooks 887*99b78ec8SJason M. Bills 888*99b78ec8SJason M. Bills bool checkRedfishHooks(AddSELRequest* selRequest) 889*99b78ec8SJason M. Bills { 890*99b78ec8SJason M. Bills // First check that this is a system event record type since that 891*99b78ec8SJason M. Bills // determines the definition of the rest of the data 892*99b78ec8SJason M. Bills if (selRequest->recordType != ipmi::sel::systemEvent) 893*99b78ec8SJason M. Bills { 894*99b78ec8SJason M. Bills // OEM record type, so let it go to the SEL 895*99b78ec8SJason M. Bills return false; 896*99b78ec8SJason M. Bills } 897*99b78ec8SJason M. Bills 898*99b78ec8SJason M. Bills // Save the raw IPMI string of the request 899*99b78ec8SJason M. Bills std::string ipmiRaw; 900*99b78ec8SJason M. Bills const boost::beast::span<uint8_t> selBytes( 901*99b78ec8SJason M. Bills reinterpret_cast<uint8_t*>(selRequest), sizeof(AddSELRequest)); 902*99b78ec8SJason M. Bills redfish_hooks::toHexStr(selBytes, ipmiRaw); 903*99b78ec8SJason M. Bills 904*99b78ec8SJason M. Bills // Extract the SEL data for the hook 905*99b78ec8SJason M. Bills redfish_hooks::SELData selData = { 906*99b78ec8SJason M. Bills .generatorID = selRequest->record.system.generatorID, 907*99b78ec8SJason M. Bills .sensorNum = selRequest->record.system.sensorNum, 908*99b78ec8SJason M. Bills .eventType = selRequest->record.system.eventType, 909*99b78ec8SJason M. Bills .offset = selRequest->record.system.eventData[0] & 0x0F, 910*99b78ec8SJason M. Bills .eventData2 = selRequest->record.system.eventData[1], 911*99b78ec8SJason M. Bills .eventData3 = selRequest->record.system.eventData[2]}; 912*99b78ec8SJason M. Bills 913*99b78ec8SJason M. Bills return redfish_hooks::startRedfishHook(selData, ipmiRaw); 914*99b78ec8SJason M. Bills } 915*99b78ec8SJason M. Bills 916*99b78ec8SJason M. Bills bool checkRedfishHooks(uint8_t generatorID, uint8_t evmRev, uint8_t sensorType, 917*99b78ec8SJason M. Bills uint8_t sensorNum, uint8_t eventType, uint8_t eventData1, 918*99b78ec8SJason M. Bills uint8_t eventData2, uint8_t eventData3) 919*99b78ec8SJason M. Bills { 920*99b78ec8SJason M. Bills // Save the raw IPMI string of the selData 921*99b78ec8SJason M. Bills std::string ipmiRaw; 922*99b78ec8SJason M. Bills std::array selBytes = {generatorID, evmRev, sensorType, sensorNum, 923*99b78ec8SJason M. Bills eventType, eventData1, eventData2, eventData3}; 924*99b78ec8SJason M. Bills redfish_hooks::toHexStr(boost::beast::span<uint8_t>(selBytes), ipmiRaw); 925*99b78ec8SJason M. Bills 926*99b78ec8SJason M. Bills // Extract the SEL data for the hook 927*99b78ec8SJason M. Bills redfish_hooks::SELData selData = {.generatorID = generatorID, 928*99b78ec8SJason M. Bills .sensorNum = sensorNum, 929*99b78ec8SJason M. Bills .eventType = eventType, 930*99b78ec8SJason M. Bills .offset = eventData1 & 0x0F, 931*99b78ec8SJason M. Bills .eventData2 = eventData2, 932*99b78ec8SJason M. Bills .eventData3 = eventData3}; 933*99b78ec8SJason M. Bills 934*99b78ec8SJason M. Bills return redfish_hooks::startRedfishHook(selData, ipmiRaw); 935*99b78ec8SJason M. Bills } 936*99b78ec8SJason M. Bills 937*99b78ec8SJason M. Bills } // namespace intel_oem::ipmi::sel 938