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