blob: c964608bfad4d97e7fcaaaf0c3021f153f4fc57b [file] [log] [blame]
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +02001/*
2// Copyright (c) 2019 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16
17#include <boost/algorithm/string/join.hpp>
18#include <me_to_redfish_hooks.hpp>
19#include <phosphor-logging/log.hpp>
James Feistfcd2d3a2020-05-28 10:38:15 -070020
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +020021#include <string_view>
22
23namespace intel_oem::ipmi::sel::redfish_hooks::me
24{
25namespace health_event
26{
27namespace smbus_failure
28{
29
30static bool messageHook(const SELData& selData, std::string& eventId,
31 std::vector<std::string>& args)
32{
33 static const boost::container::flat_map<uint8_t, std::string> smlink = {
34 {0x01, "SmLink0/0B"},
35 {0x02, "SmLink1"},
36 {0x03, "SmLink2"},
37 {0x04, "SmLink3"},
38 {0x05, "SmLink4"}};
39
40 const auto errorDetails = selData.eventData3;
41 const auto faultySmlink = smlink.find(selData.eventData2);
42 if (faultySmlink == smlink.end())
43 {
44 return false;
45 }
46
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +020047 eventId = "MESmbusLinkFailure";
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +020048
49 args.push_back(faultySmlink->second);
50 args.push_back(utils::toHex(errorDetails));
51
52 return true;
53}
54} // namespace smbus_failure
55
56namespace fw_status
57{
58static const boost::container::flat_map<uint8_t, std::string>
59 manufacturingError = {
60 {0x00, "Generic error"},
61 {0x01, "Wrong or missing VSCC table"},
62 {0x02, "Wrong sensor scanning period in PIA"},
63 {0x03, "Wrong device definition in PIA"},
64 {0x04, "Reserved (Wrong SMART/CLST configuration)"},
65 {0x05, "Intel ME FW configuration is inconsistent or out of range"},
66 {0x06, "Reserved"},
67 {0x07, "Intel ME FW configuration is corrupted"},
68 {0x08, "SMLink0/0B misconfiguration"}};
69
70static const boost::container::flat_map<uint8_t, std::string> peciOverDmiError =
71 {{0x01, "DRAM Init Done HECI message not received by Intel ME before EOP"},
72 {0x02, "System PCIe bus configuration not known or not valid on DID HECI "
73 "message arrival to Intel ME"},
74 {0x03, "PECI over DMI run-time failure"}};
75
76static const boost::container::flat_map<uint8_t, std::string>
77 mctpInterfaceError = {
78 {0x01, "No DID HECI message received before EOP"},
79 {0x02, "No MCTP_SET_BUS_OWNER HECI message received by Intel ME on EOP "
80 "arrival "
81 "to ME while MCTP stack is configured in Bus Owner Proxy mode"}};
82
83static const boost::container::flat_map<uint8_t, std::string>
Patrick Williams1bcced02024-08-16 15:20:24 -040084 unsupportedFeature = {
85 {0x00, "Other Segment Defined Feature"},
86 {0x01, "Fast NM limiting"},
87 {0x02, "Volumetric Airflow and Outlet Temperature"},
88 {0x03, "CUPS"},
89 {0x04, "Thermal policies and Inlet Temperature"},
90 {0x05, "Platform limiting with MICs"},
91 {0x07, "Shared power supplies"},
92 {0x08, "MIC Proxy"},
93 {0x09, "Reset warning"},
94 {0x0A, "PMBus Proxy"},
95 {0x0B, "Always on"},
96 {0x0C, "IPMI Intel ME FW update"},
97 {0x0D, "MCTP bus owner"},
98 {0x0E, "MCTP bus owner proxy"},
99 {0x0F, "Dual BIOS"},
100 {0x10, "Battery less"}};
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200101
102static const boost::container::flat_map<uint8_t, std::string> umaError = {
103 {0x00, "UMA Read integrity error. Checksum of data read from UMA differs "
104 "from expected one."},
105 {0x01, "UMA Read/Write timeout. Timeout occurred during copying data "
106 "from/to UMA."},
107 {0x02,
108 "UMA not granted. BIOS did not grant any UMA or DRAM INIT done message "
109 "was not received from BIOS before EOP. Intel ME FW goes to recovery."},
110 {0x03, "UMA size granted by BIOS differs from requested. ME FW goes to "
111 "recovery."}};
112
113static const boost::container::flat_map<uint8_t, std::string> pttHealthEvent = {
114 {0x00, "Intel PTT disabled (PTT region is not present)."},
115 {0x01, "Intel PTT downgrade (PTT data should be not available)."},
116 {0x02, "Intel PTT disabled (battery less configuration)."}};
117
118static const boost::container::flat_map<uint8_t, std::string>
119 bootGuardHealthEvent = {
120 {0x00, "Boot Guard flow error (possible reasons: verification timeout; "
121 "verification error; BIOS Protection error)."}};
122
123static const boost::container::flat_map<uint8_t, std::string> restrictedMode = {
124 {0x01, "Firmware entered restricted mode – UMA is not available. "
125 "Restricted features set."},
126 {0x02, "Firmware exited restricted mode."}};
127
128static const boost::container::flat_map<uint8_t, std::string>
129 multiPchModeMisconfig = {
130 {0x01, "BIOS did not set reset synchronization in multiPCH mode"},
131 {0x02,
132 "PMC indicates different non/legacy mode for the PCH than BMC set "
133 "on the GPIO"},
134 {0x03,
135 "Misconfiguration MPCH support enabled due to BTG support enabled"}};
136
137static const boost::container::flat_map<uint8_t, std::string>
138 flashVerificationError = {
139 {0x00, "OEM Public Key verification error"},
140 {0x01, "Flash Descriptor Region Manifest verification error"},
141 {0x02, "Soft Straps verification error"}};
142
143namespace autoconfiguration
144{
145
146bool messageHook(const SELData& selData, std::string& eventId,
147 std::vector<std::string>& args)
148{
149 static const boost::container::flat_map<uint8_t, std::string> dcSource = {
150 {0b00, "BMC"}, {0b01, "PSU"}, {0b10, "On-board power sensor"}};
151
152 static const boost::container::flat_map<uint8_t, std::string>
153 chassisSource = {{0b00, "BMC"},
154 {0b01, "PSU"},
155 {0b10, "On-board power sensor"},
156 {0b11, "Not supported"}};
157
158 static const boost::container::flat_map<uint8_t, std::string>
159 efficiencySource = {
160 {0b00, "BMC"}, {0b01, "PSU"}, {0b11, "Not supported"}};
161
162 static const boost::container::flat_map<uint8_t, std::string>
163 unmanagedSource = {{0b00, "BMC"}, {0b01, "Estimated"}};
164
165 static const boost::container::flat_map<uint8_t, std::string>
166 failureReason = {{0b00, "BMC discovery failure"},
167 {0b01, "Insufficient factory configuration"},
168 {0b10, "Unknown sensor type"},
169 {0b11, "Other error encountered"}};
170
171 auto succeeded = selData.eventData3 >> 7 & 0b1;
172 if (succeeded)
173 {
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200174 eventId = "MEAutoConfigSuccess";
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200175
176 auto dc = dcSource.find(selData.eventData3 >> 5 & 0b11);
177 auto chassis = chassisSource.find(selData.eventData3 >> 3 & 0b11);
178 auto efficiency = efficiencySource.find(selData.eventData3 >> 1 & 0b11);
179 auto unmanaged = unmanagedSource.find(selData.eventData3 & 0b1);
180 if (dc == dcSource.end() || chassis == chassisSource.end() ||
181 efficiency == efficiencySource.end() ||
182 unmanaged == unmanagedSource.end())
183 {
184 return false;
185 }
186
187 args.push_back(dc->second);
188 args.push_back(chassis->second);
189 args.push_back(efficiency->second);
190 args.push_back(unmanaged->second);
191 }
192 else
193 {
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200194 eventId = "MEAutoConfigFailed";
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200195
196 const auto it = failureReason.find(selData.eventData3 >> 5 & 0b11);
197 if (it == failureReason.end())
198 {
199 return false;
200 }
201
202 args.push_back(it->second);
203 }
204
205 return true;
206}
207} // namespace autoconfiguration
208
209namespace factory_reset
210{
211bool messageHook(const SELData& selData, std::string& eventId,
212 std::vector<std::string>& args)
213{
214 static const boost::container::flat_map<uint8_t, std::string>
215 restoreToFactoryPreset = {
216 {0x00,
217 "Flash file system error detected. Automatic restore to factory "
218 "presets has been triggered."},
219 {0x01, "Automatic restore to factory presets has been completed."},
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200220 {0x02, "Restore to factory presets triggered by Force ME Recovery "
221 "IPMI command has been completed."},
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200222 {0x03,
223 "Restore to factory presets triggered by AC power cycle with "
224 "Recovery jumper asserted has been completed."}};
225
226 auto param = restoreToFactoryPreset.find(selData.eventData3);
227 if (param == restoreToFactoryPreset.end())
228 {
229 return false;
230 }
231
232 if (selData.eventData3 == 0x00)
233 {
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200234 eventId = "MEFactoryResetError";
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200235 }
236 else
237 {
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200238 eventId = "MEFactoryRestore";
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200239 }
240
241 args.push_back(param->second);
242 return true;
243}
244} // namespace factory_reset
245
246namespace flash_state
247{
248bool messageHook(const SELData& selData, std::string& eventId,
249 std::vector<std::string>& args)
250{
251 static const boost::container::flat_map<uint8_t, std::string>
252 flashStateInformation = {
253 {0x00,
254 "Flash partition table, recovery image or factory presets image "
255 "corrupted"},
256 {0x01, "Flash erase limit has been reached"},
257 {0x02,
258 "Flash write limit has been reached. Writing to flash has been "
259 "disabled"},
260 {0x03, "Writing to the flash has been enabled"}};
261
262 auto param = flashStateInformation.find(selData.eventData3);
263 if (param == flashStateInformation.end())
264 {
265 return false;
266 }
267
268 if (selData.eventData3 == 0x03)
269 {
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200270 eventId = "MEFlashStateInformationWritingEnabled";
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200271 }
272 else
273 {
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200274 eventId = "MEFlashStateInformation";
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200275 }
276
277 args.push_back(param->second);
278 return true;
279}
280} // namespace flash_state
281
282static bool messageHook(const SELData& selData, std::string& eventId,
283 std::vector<std::string>& args)
284{
285 static const boost::container::flat_map<
286 uint8_t,
287 std::pair<std::string, std::optional<std::variant<utils::ParserFunc,
288 utils::MessageMap>>>>
289 eventMap = {
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200290 {0x00, {"MERecoveryGpioForced", {}}},
291 {0x01, {"MEImageExecutionFailed", {}}},
292 {0x02, {"MEFlashEraseError", {}}},
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200293 {0x03, {{}, flash_state::messageHook}},
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200294 {0x04, {"MEInternalError", {}}},
295 {0x05, {"MEExceptionDuringShutdown", {}}},
296 {0x06, {"MEDirectFlashUpdateRequested", {}}},
297 {0x07, {"MEManufacturingError", manufacturingError}},
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200298 {0x08, {{}, factory_reset::messageHook}},
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200299 {0x09, {"MEFirmwareException", utils::logByteHex<2>}},
300 {0x0A, {"MEFlashWearOutWarning", utils::logByteDec<2>}},
301 {0x0D, {"MEPeciOverDmiError", peciOverDmiError}},
302 {0x0E, {"MEMctpInterfaceError", mctpInterfaceError}},
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200303 {0x0F, {{}, autoconfiguration::messageHook}},
Agnieszka Szlendakff28aa52020-05-28 12:15:31 +0200304 {0x10, {"MEUnsupportedFeature", unsupportedFeature}},
305 {0x12, {"MECpuDebugCapabilityDisabled", {}}},
306 {0x13, {"MEUmaError", umaError}},
307 {0x16, {"MEPttHealthEvent", pttHealthEvent}},
308 {0x17, {"MEBootGuardHealthEvent", bootGuardHealthEvent}},
309 {0x18, {"MERestrictedMode", restrictedMode}},
310 {0x19, {"MEMultiPchModeMisconfig", multiPchModeMisconfig}},
311 {0x1A, {"MEFlashVerificationError", flashVerificationError}}};
Agnieszka Szlendakd2220cc2020-04-17 15:00:12 +0200312
313 return utils::genericMessageHook(eventMap, selData, eventId, args);
314}
315} // namespace fw_status
316
317static bool messageHook(const SELData& selData, std::string& eventId,
318 std::vector<std::string>& args)
319{
320 const HealthEventType healthEventType =
321 static_cast<HealthEventType>(selData.offset);
322
323 switch (healthEventType)
324 {
325 case HealthEventType::FirmwareStatus:
326 return fw_status::messageHook(selData, eventId, args);
327 break;
328
329 case HealthEventType::SmbusLinkFailure:
330 return smbus_failure::messageHook(selData, eventId, args);
331 break;
332 }
333
334 return false;
335}
336} // namespace health_event
337
338/**
339 * @brief Main entry point for parsing ME IPMI Platform Events
340 *
341 * @brief selData - IPMI Platform Event structure
342 * @brief ipmiRaw - the same event in raw binary form
343 *
344 * @returns true if event was successfully parsed and consumed
345 */
346bool messageHook(const SELData& selData, const std::string& ipmiRaw)
347{
348 const EventSensor meSensor = static_cast<EventSensor>(selData.sensorNum);
349 std::string eventId;
350 std::vector<std::string> args;
351
352 switch (meSensor)
353 {
354 case EventSensor::MeFirmwareHealth:
355 if (health_event::messageHook(selData, eventId, args))
356 {
357 utils::storeRedfishEvent(ipmiRaw, eventId, args);
358 return true;
359 }
360 break;
361 }
362
363 return defaultMessageHook(ipmiRaw);
364}
Patrick Williamsb37abfb2023-05-10 07:50:33 -0500365} // namespace intel_oem::ipmi::sel::redfish_hooks::me