blob: fac2731c7a4cd4a99cc3c928cde7062b2a1cdc05 [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>
20#include <string_view>
21
22namespace intel_oem::ipmi::sel::redfish_hooks::me
23{
24namespace health_event
25{
26namespace smbus_failure
27{
28
29static bool messageHook(const SELData& selData, std::string& eventId,
30 std::vector<std::string>& args)
31{
32 static const boost::container::flat_map<uint8_t, std::string> smlink = {
33 {0x01, "SmLink0/0B"},
34 {0x02, "SmLink1"},
35 {0x03, "SmLink2"},
36 {0x04, "SmLink3"},
37 {0x05, "SmLink4"}};
38
39 const auto errorDetails = selData.eventData3;
40 const auto faultySmlink = smlink.find(selData.eventData2);
41 if (faultySmlink == smlink.end())
42 {
43 return false;
44 }
45
46 eventId = "MeSmbusLinkFailure";
47
48 args.push_back(faultySmlink->second);
49 args.push_back(utils::toHex(errorDetails));
50
51 return true;
52}
53} // namespace smbus_failure
54
55namespace fw_status
56{
57static const boost::container::flat_map<uint8_t, std::string>
58 manufacturingError = {
59 {0x00, "Generic error"},
60 {0x01, "Wrong or missing VSCC table"},
61 {0x02, "Wrong sensor scanning period in PIA"},
62 {0x03, "Wrong device definition in PIA"},
63 {0x04, "Reserved (Wrong SMART/CLST configuration)"},
64 {0x05, "Intel ME FW configuration is inconsistent or out of range"},
65 {0x06, "Reserved"},
66 {0x07, "Intel ME FW configuration is corrupted"},
67 {0x08, "SMLink0/0B misconfiguration"}};
68
69static const boost::container::flat_map<uint8_t, std::string> peciOverDmiError =
70 {{0x01, "DRAM Init Done HECI message not received by Intel ME before EOP"},
71 {0x02, "System PCIe bus configuration not known or not valid on DID HECI "
72 "message arrival to Intel ME"},
73 {0x03, "PECI over DMI run-time failure"}};
74
75static const boost::container::flat_map<uint8_t, std::string>
76 mctpInterfaceError = {
77 {0x01, "No DID HECI message received before EOP"},
78 {0x02, "No MCTP_SET_BUS_OWNER HECI message received by Intel ME on EOP "
79 "arrival "
80 "to ME while MCTP stack is configured in Bus Owner Proxy mode"}};
81
82static const boost::container::flat_map<uint8_t, std::string>
83 unsupportedFeature = {{0x00, "Other Segment Defined Feature"},
84 {0x01, "Fast NM limiting"},
85 {0x02, "Volumetric Airflow and Outlet Temperature"},
86 {0x03, "CUPS"},
87 {0x04, "Thermal policies and Inlet Temperature"},
88 {0x05, "Platform limiting with MICs"},
89 {0x07, "Shared power supplies"},
90 {0x08, "MIC Proxy"},
91 {0x09, "Reset warning"},
92 {0x0A, "PMBus Proxy"},
93 {0x0B, "Always on"},
94 {0x0C, "IPMI Intel ME FW update"},
95 {0x0D, "MCTP bus owner"},
96 {0x0E, "MCTP bus owner proxy"},
97 {0x0F, "Dual BIOS"},
98 {0x10, "Battery less"}};
99
100static const boost::container::flat_map<uint8_t, std::string> umaError = {
101 {0x00, "UMA Read integrity error. Checksum of data read from UMA differs "
102 "from expected one."},
103 {0x01, "UMA Read/Write timeout. Timeout occurred during copying data "
104 "from/to UMA."},
105 {0x02,
106 "UMA not granted. BIOS did not grant any UMA or DRAM INIT done message "
107 "was not received from BIOS before EOP. Intel ME FW goes to recovery."},
108 {0x03, "UMA size granted by BIOS differs from requested. ME FW goes to "
109 "recovery."}};
110
111static const boost::container::flat_map<uint8_t, std::string> pttHealthEvent = {
112 {0x00, "Intel PTT disabled (PTT region is not present)."},
113 {0x01, "Intel PTT downgrade (PTT data should be not available)."},
114 {0x02, "Intel PTT disabled (battery less configuration)."}};
115
116static const boost::container::flat_map<uint8_t, std::string>
117 bootGuardHealthEvent = {
118 {0x00, "Boot Guard flow error (possible reasons: verification timeout; "
119 "verification error; BIOS Protection error)."}};
120
121static const boost::container::flat_map<uint8_t, std::string> restrictedMode = {
122 {0x01, "Firmware entered restricted mode – UMA is not available. "
123 "Restricted features set."},
124 {0x02, "Firmware exited restricted mode."}};
125
126static const boost::container::flat_map<uint8_t, std::string>
127 multiPchModeMisconfig = {
128 {0x01, "BIOS did not set reset synchronization in multiPCH mode"},
129 {0x02,
130 "PMC indicates different non/legacy mode for the PCH than BMC set "
131 "on the GPIO"},
132 {0x03,
133 "Misconfiguration MPCH support enabled due to BTG support enabled"}};
134
135static const boost::container::flat_map<uint8_t, std::string>
136 flashVerificationError = {
137 {0x00, "OEM Public Key verification error"},
138 {0x01, "Flash Descriptor Region Manifest verification error"},
139 {0x02, "Soft Straps verification error"}};
140
141namespace autoconfiguration
142{
143
144bool messageHook(const SELData& selData, std::string& eventId,
145 std::vector<std::string>& args)
146{
147 static const boost::container::flat_map<uint8_t, std::string> dcSource = {
148 {0b00, "BMC"}, {0b01, "PSU"}, {0b10, "On-board power sensor"}};
149
150 static const boost::container::flat_map<uint8_t, std::string>
151 chassisSource = {{0b00, "BMC"},
152 {0b01, "PSU"},
153 {0b10, "On-board power sensor"},
154 {0b11, "Not supported"}};
155
156 static const boost::container::flat_map<uint8_t, std::string>
157 efficiencySource = {
158 {0b00, "BMC"}, {0b01, "PSU"}, {0b11, "Not supported"}};
159
160 static const boost::container::flat_map<uint8_t, std::string>
161 unmanagedSource = {{0b00, "BMC"}, {0b01, "Estimated"}};
162
163 static const boost::container::flat_map<uint8_t, std::string>
164 failureReason = {{0b00, "BMC discovery failure"},
165 {0b01, "Insufficient factory configuration"},
166 {0b10, "Unknown sensor type"},
167 {0b11, "Other error encountered"}};
168
169 auto succeeded = selData.eventData3 >> 7 & 0b1;
170 if (succeeded)
171 {
172 eventId = "MeAutoConfigSuccess";
173
174 auto dc = dcSource.find(selData.eventData3 >> 5 & 0b11);
175 auto chassis = chassisSource.find(selData.eventData3 >> 3 & 0b11);
176 auto efficiency = efficiencySource.find(selData.eventData3 >> 1 & 0b11);
177 auto unmanaged = unmanagedSource.find(selData.eventData3 & 0b1);
178 if (dc == dcSource.end() || chassis == chassisSource.end() ||
179 efficiency == efficiencySource.end() ||
180 unmanaged == unmanagedSource.end())
181 {
182 return false;
183 }
184
185 args.push_back(dc->second);
186 args.push_back(chassis->second);
187 args.push_back(efficiency->second);
188 args.push_back(unmanaged->second);
189 }
190 else
191 {
192 eventId = "MeAutoConfigFailed";
193
194 const auto it = failureReason.find(selData.eventData3 >> 5 & 0b11);
195 if (it == failureReason.end())
196 {
197 return false;
198 }
199
200 args.push_back(it->second);
201 }
202
203 return true;
204}
205} // namespace autoconfiguration
206
207namespace factory_reset
208{
209bool messageHook(const SELData& selData, std::string& eventId,
210 std::vector<std::string>& args)
211{
212 static const boost::container::flat_map<uint8_t, std::string>
213 restoreToFactoryPreset = {
214 {0x00,
215 "Flash file system error detected. Automatic restore to factory "
216 "presets has been triggered."},
217 {0x01, "Automatic restore to factory presets has been completed."},
218 {0x02,
219 "Restore to factory presets triggered by “Force ME Recovery” "
220 "IPMI command has been completed."},
221 {0x03,
222 "Restore to factory presets triggered by AC power cycle with "
223 "Recovery jumper asserted has been completed."}};
224
225 auto param = restoreToFactoryPreset.find(selData.eventData3);
226 if (param == restoreToFactoryPreset.end())
227 {
228 return false;
229 }
230
231 if (selData.eventData3 == 0x00)
232 {
233 eventId = "MeFactoryResetError";
234 }
235 else
236 {
237 eventId = "MeFactoryRestore";
238 }
239
240 args.push_back(param->second);
241 return true;
242}
243} // namespace factory_reset
244
245namespace flash_state
246{
247bool messageHook(const SELData& selData, std::string& eventId,
248 std::vector<std::string>& args)
249{
250 static const boost::container::flat_map<uint8_t, std::string>
251 flashStateInformation = {
252 {0x00,
253 "Flash partition table, recovery image or factory presets image "
254 "corrupted"},
255 {0x01, "Flash erase limit has been reached"},
256 {0x02,
257 "Flash write limit has been reached. Writing to flash has been "
258 "disabled"},
259 {0x03, "Writing to the flash has been enabled"}};
260
261 auto param = flashStateInformation.find(selData.eventData3);
262 if (param == flashStateInformation.end())
263 {
264 return false;
265 }
266
267 if (selData.eventData3 == 0x03)
268 {
269 eventId = "MeFlashStateInformationWritingEnabled";
270 }
271 else
272 {
273 eventId = "MeFlashStateInformation";
274 }
275
276 args.push_back(param->second);
277 return true;
278}
279} // namespace flash_state
280
281static bool messageHook(const SELData& selData, std::string& eventId,
282 std::vector<std::string>& args)
283{
284 static const boost::container::flat_map<
285 uint8_t,
286 std::pair<std::string, std::optional<std::variant<utils::ParserFunc,
287 utils::MessageMap>>>>
288 eventMap = {
289 {0x00, {"MeRecoveryGpioForced", {}}},
290 {0x01, {"MeImageExecutionFailed", {}}},
291 {0x02, {"MeFlashEraseError", {}}},
292 {0x03, {{}, flash_state::messageHook}},
293 {0x04, {"MeInternalError", {}}},
294 {0x05, {"MeExceptionDuringShutdown", {}}},
295 {0x06, {"MeDirectFlashUpdateRequested", {}}},
296 {0x07, {"MeManufacturingError", manufacturingError}},
297 {0x08, {{}, factory_reset::messageHook}},
298 {0x09, {"MeFirmwareException", utils::logByteHex<2>}},
299 {0x0A, {"MeFlashWearOutWarning", utils::logByteDec<2>}},
300 {0x0D, {"MePeciOverDmiError", peciOverDmiError}},
301 {0x0E, {"MeMctpInterfaceError", mctpInterfaceError}},
302 {0x0F, {{}, autoconfiguration::messageHook}},
303 {0x10, {"MeUnsupportedFeature", unsupportedFeature}},
304 {0x12, {"MeCpuDebugCapabilityDisabled", {}}},
305 {0x13, {"MeUmaError", umaError}},
306 {0x16, {"MePttHealthEvent", pttHealthEvent}},
307 {0x17, {"MeBootGuardHealthEvent", bootGuardHealthEvent}},
308 {0x18, {"MeRestrictedMode", restrictedMode}},
309 {0x19, {"MeMultiPchModeMisconfig", multiPchModeMisconfig}},
310 {0x1A, {"MeFlashVerificationError", flashVerificationError}}};
311
312 return utils::genericMessageHook(eventMap, selData, eventId, args);
313}
314} // namespace fw_status
315
316static bool messageHook(const SELData& selData, std::string& eventId,
317 std::vector<std::string>& args)
318{
319 const HealthEventType healthEventType =
320 static_cast<HealthEventType>(selData.offset);
321
322 switch (healthEventType)
323 {
324 case HealthEventType::FirmwareStatus:
325 return fw_status::messageHook(selData, eventId, args);
326 break;
327
328 case HealthEventType::SmbusLinkFailure:
329 return smbus_failure::messageHook(selData, eventId, args);
330 break;
331 }
332
333 return false;
334}
335} // namespace health_event
336
337/**
338 * @brief Main entry point for parsing ME IPMI Platform Events
339 *
340 * @brief selData - IPMI Platform Event structure
341 * @brief ipmiRaw - the same event in raw binary form
342 *
343 * @returns true if event was successfully parsed and consumed
344 */
345bool messageHook(const SELData& selData, const std::string& ipmiRaw)
346{
347 const EventSensor meSensor = static_cast<EventSensor>(selData.sensorNum);
348 std::string eventId;
349 std::vector<std::string> args;
350
351 switch (meSensor)
352 {
353 case EventSensor::MeFirmwareHealth:
354 if (health_event::messageHook(selData, eventId, args))
355 {
356 utils::storeRedfishEvent(ipmiRaw, eventId, args);
357 return true;
358 }
359 break;
360 }
361
362 return defaultMessageHook(ipmiRaw);
363}
364} // namespace intel_oem::ipmi::sel::redfish_hooks::me