1 /*
2 * Copyright (C) 2003-2015 FreeIPMI Core Team
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif /* HAVE_CONFIG_H */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #if STDC_HEADERS
26 #include <string.h>
27 #include <stdarg.h>
28 #endif /* STDC_HEADERS */
29 #include <assert.h>
30 #include <errno.h>
31
32 #include "freeipmi/sel/ipmi-sel.h"
33
34 #include "freeipmi/record-format/ipmi-sel-record-format.h"
35 #include "freeipmi/record-format/oem/ipmi-sel-oem-intel-record-format.h"
36 #include "freeipmi/spec/ipmi-event-reading-type-code-spec.h"
37 #include "freeipmi/spec/ipmi-iana-enterprise-numbers-spec.h"
38 #include "freeipmi/spec/ipmi-product-id-spec.h"
39 #include "freeipmi/spec/ipmi-sensor-and-event-code-tables-spec.h"
40 #include "freeipmi/spec/ipmi-sensor-types-spec.h"
41 #include "freeipmi/spec/oem/ipmi-event-reading-type-code-oem-intel-spec.h"
42 #include "freeipmi/spec/oem/ipmi-sensor-and-event-code-tables-oem-intel-spec.h"
43 #include "freeipmi/spec/oem/ipmi-sensor-numbers-oem-intel-spec.h"
44 #include "freeipmi/spec/oem/ipmi-sensor-types-oem-intel-spec.h"
45
46 #include "ipmi-sel-common.h"
47 #include "ipmi-sel-defs.h"
48 #include "ipmi-sel-string.h"
49 #include "ipmi-sel-string-intel-node-manager.h"
50 #include "ipmi-sel-trace.h"
51 #include "ipmi-sel-util.h"
52
53 #include "freeipmi-portability.h"
54
55 #define INTEL_EVENT_BUFFER_LENGTH 4096
56
57 /* return (0) - no OEM match
58 * return (1) - OEM match
59 * return (-1) - error, cleanup and return error
60 */
61 int
sel_string_output_intel_windmill_event_data1_class_sensor_specific_discrete(ipmi_sel_ctx_t ctx,struct ipmi_sel_entry * sel_entry,uint8_t sel_record_type,char * tmpbuf,unsigned int tmpbuflen,unsigned int flags,unsigned int * wlen,struct ipmi_sel_system_event_record_data * system_event_record_data)62 sel_string_output_intel_windmill_event_data1_class_sensor_specific_discrete (ipmi_sel_ctx_t ctx,
63 struct ipmi_sel_entry *sel_entry,
64 uint8_t sel_record_type,
65 char *tmpbuf,
66 unsigned int tmpbuflen,
67 unsigned int flags,
68 unsigned int *wlen,
69 struct ipmi_sel_system_event_record_data *system_event_record_data)
70 {
71 assert (ctx);
72 assert (ctx->magic == IPMI_SEL_CTX_MAGIC);
73 assert (ctx->manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL);
74 assert (sel_entry);
75 assert (tmpbuf);
76 assert (tmpbuflen);
77 assert (!(flags & ~IPMI_SEL_STRING_FLAGS_MASK));
78 assert (flags & IPMI_SEL_STRING_FLAGS_INTERPRET_OEM_DATA);
79 assert (wlen);
80 assert (system_event_record_data);
81 assert (system_event_record_data->event_type_code == IPMI_EVENT_READING_TYPE_CODE_SENSOR_SPECIFIC);
82 assert (ctx->product_id == IPMI_INTEL_PRODUCT_ID_WINDMILL);
83
84 /*
85 * Intel Windmill
86 * (Quanta Winterfell)
87 * (Wiwynn Windmill)
88 */
89 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_OEM_INTEL_WINDMILL_GENERIC
90 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_CPU_SEL_STATUS)
91 {
92 uint8_t sel_clear;
93 uint8_t sel_rollover;
94
95 sel_clear = (system_event_record_data->event_data1 & IPMI_SENSOR_TYPE_OEM_INTEL_SEL_CLEAR_BITMASK);
96 sel_clear >>= IPMI_SENSOR_TYPE_OEM_INTEL_SEL_CLEAR_SHIFT;
97
98 sel_rollover = (system_event_record_data->event_data1 & IPMI_SENSOR_TYPE_OEM_INTEL_SEL_ROLLOVER_BITMASK);
99 sel_rollover >>= IPMI_SENSOR_TYPE_OEM_INTEL_SEL_ROLLOVER_SHIFT;
100
101 if (sel_clear)
102 {
103 snprintf (tmpbuf,
104 tmpbuflen,
105 "SEL Clear");
106
107 return (1);
108 }
109
110 if (sel_rollover)
111 {
112 snprintf (tmpbuf,
113 tmpbuflen,
114 "SEL Rollover");
115
116 return (1);
117 }
118 }
119
120 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_OEM_INTEL_WINDMILL_GENERIC
121 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_CHASSIS_POWER_STATUS)
122 {
123 char *chassis_power_status_str;
124
125 switch (system_event_record_data->event_data1)
126 {
127 case IPMI_SENSOR_TYPE_OEM_INTEL_WINDMILL_CHASSIS_POWER_STATUS_POWER_DOWN:
128 chassis_power_status_str = "Power Down";
129 break;
130 case IPMI_SENSOR_TYPE_OEM_INTEL_WINDMILL_CHASSIS_POWER_STATUS_POWER_CYCLE_RESET:
131 chassis_power_status_str = "Power Cycle/Reset";
132 break;
133 case IPMI_SENSOR_TYPE_OEM_INTEL_WINDMILL_CHASSIS_POWER_STATUS_POWER_ON:
134 chassis_power_status_str = "Power On";
135 break;
136 case IPMI_SENSOR_TYPE_OEM_INTEL_WINDMILL_CHASSIS_POWER_STATUS_AC_LOST:
137 chassis_power_status_str = "AC Lost";
138 break;
139 default:
140 chassis_power_status_str = "Unknown";
141 break;
142 }
143
144 snprintf (tmpbuf,
145 tmpbuflen,
146 "Power Status = %s",
147 chassis_power_status_str);
148
149 return (1);
150 }
151
152 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_OEM_INTEL_WINDMILL_GENERIC
153 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_HOT_SWAP_CONTROLLER_0_STATUS_LOW)
154 {
155 char *hsc_str;
156
157 switch (system_event_record_data->event_data1)
158 {
159 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_LOW_NONE_OF_THE_ABOVE:
160 hsc_str = "Active status bits are waiting to be read by one or more status commands.";
161 break;
162 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_LOW_CML_ERROR:
163 hsc_str = "An error was detected on the I2C/PMBus interface.";
164 break;
165 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_LOW_VIN_UV_FAULT:
166 hsc_str = "An undervoltage input fault was detected on the UV pin.";
167 break;
168 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_LOW_IOUT_OC_FAULT:
169 hsc_str = "The hot swap controller detected an overcurrent condition.";
170 break;
171 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_LOW_HOTSWAP_OFF:
172 hsc_str = "The hot swap gate driver output is disabled.";
173 break;
174 default:
175 hsc_str = "Unknown";
176 break;
177 }
178
179 snprintf (tmpbuf,
180 tmpbuflen,
181 "Status = %s",
182 hsc_str);
183
184 return (1);
185 }
186
187 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_OEM_INTEL_WINDMILL_GENERIC
188 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_HOT_SWAP_CONTROLLER_0_STATUS_HIGH)
189 {
190 char *hsc_str;
191
192 switch (system_event_record_data->event_data1)
193 {
194 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_HIGH_POWER_GOOD:
195 hsc_str = "The voltage on the FLB pin is below the required threshold.";
196 break;
197 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_HIGH_MFR_STATUS:
198 hsc_str = "There are one or more active status bits to be read by STATUS_MFR_SPECIFIC.";
199 break;
200 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_HIGH_INPUT_STATUS:
201 hsc_str = "There are one or more active status bits to be read by STATUS_INPUT.";
202 break;
203 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_HIGH_IOUT_STATUS:
204 hsc_str = "There are one or more active status bits to be read by STATUS_IOUT.";
205 break;
206 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_HIGH_VOUT_STATUS:
207 hsc_str = "There are one or more active status bits to be read by STATUS_VOUT.";
208 break;
209 default:
210 hsc_str = "Unknown";
211 break;
212 }
213
214 snprintf (tmpbuf,
215 tmpbuflen,
216 "Status = %s",
217 hsc_str);
218
219 return (1);
220 }
221
222 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_OEM_INTEL_WINDMILL_GENERIC
223 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_HOT_SWAP_CONTROLLER_0_STATUS_MFR_SPECIFIC)
224 {
225 char *hsc_str;
226
227 switch (system_event_record_data->event_data1)
228 {
229 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_MFR_SPECIFIC_IOUT_WARN2:
230 hsc_str = "An undercurrent or overcurrent condition on the output supply detected.";
231 break;
232 /* achu: HS_SHUTDOWN_CAUSE1 & HS_SHUTDOWN_CAUSE2 list 4 error messages
233 * with <00>, <01>, <10>, & <11> listed next to them. I have no idea
234 * where these other bits come from.
235 *
236 * So all user gets is a generic "hotswap shutdown"
237 */
238 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_MFR_SPECIFIC_HS_SHUTDOWN_CAUSE1:
239 hsc_str = "Hotswap shutdown";
240 break;
241 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_MFR_SPECIFIC_HS_SHUTDOWN_CAUSE2:
242 hsc_str = "Hotswap shutdown";
243 break;
244 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_MFR_SPECIFIC_HS_INLIM:
245 hsc_str = "The ADM1276 has actively limited current into the load.";
246 break;
247 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_MFR_SPECIFIC_OV_CMP_OUT:
248 hsc_str = "Input Voltage to OV pin is above threshold.";
249 break;
250 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_MFR_SPECIFIC_UV_CMP_OUT:
251 hsc_str = "Input voltage to UV pin is below threshold.";
252 break;
253 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_MFR_SPECIFIC_FET_HEALTH_BAD:
254 hsc_str = "FET behavior suggests that the FET may be shorted.";
255 break;
256 default:
257 hsc_str = "Unknown";
258 break;
259 }
260
261 snprintf (tmpbuf,
262 tmpbuflen,
263 "Status = %s",
264 hsc_str);
265
266 return (1);
267 }
268
269 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_OEM_INTEL_WINDMILL_GENERIC
270 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_HOT_SWAP_CONTROLLER_0_STATUS_INPUT)
271 {
272 char *hsc_str;
273
274 switch (system_event_record_data->event_data1)
275 {
276 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_INPUT_PIN_OP_WARN:
277 hsc_str = "An overpower condition on the input supply was detected by power monitor.";
278 break;
279 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_INPUT_VIN_UV_FAULT:
280 hsc_str = "An undervoltage was detected on the UV pin.";
281 break;
282 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_INPUT_VIN_UV_WARN:
283 hsc_str = "An undervoltage condition on the input supply was detected by the power monitor.";
284 break;
285 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_INPUT_VIN_OV_WARN:
286 hsc_str = "An overvoltage condition on the input supply was detected by hte power monitor.";
287 break;
288 case IPMI_SENSOR_TYPE_OEM_INTEL_HOT_SWAP_CONTROLLER_0_STATUS_INPUT_VIN_OV_FAULT:
289 hsc_str = "An overvoltage was detected on the OV pin.";
290 break;
291 default:
292 hsc_str = "Unknown";
293 break;
294 }
295
296 snprintf (tmpbuf,
297 tmpbuflen,
298 "Status = %s",
299 hsc_str);
300
301 return (1);
302 }
303
304 return (0);
305 }
306
307 static const char *
_sel_string_output_intel_windmill_native_vs_external_throttling(uint8_t event_data)308 _sel_string_output_intel_windmill_native_vs_external_throttling (uint8_t event_data)
309 {
310 uint8_t noe;
311 char *noe_str;
312
313 noe = (event_data & IPMI_OEM_INTEL_WINDMILL_EVENT_DATA2_THROTTLING_BITMASK);
314 noe >>= IPMI_OEM_INTEL_WINDMILL_EVENT_DATA2_THROTTLING_SHIFT;
315
316 switch (noe)
317 {
318 case IPMI_OEM_INTEL_WINDMILL_EVENT_DATA2_NATIVE_THROTTLING:
319 noe_str = "Native";
320 break;
321 case IPMI_OEM_INTEL_WINDMILL_EVENT_DATA2_EXTERNAL_THROTTLING:
322 noe_str = "External";
323 break;
324 default:
325 noe_str = "Unknown";
326 break;
327 }
328
329 return (noe_str);
330 }
331
332 /* return (0) - no OEM match
333 * return (1) - OEM match
334 * return (-1) - error, cleanup and return error
335 */
336 int
sel_string_output_intel_windmill_event_data2_discrete_oem(ipmi_sel_ctx_t ctx,struct ipmi_sel_entry * sel_entry,uint8_t sel_record_type,char * tmpbuf,unsigned int tmpbuflen,unsigned int flags,unsigned int * wlen,struct ipmi_sel_system_event_record_data * system_event_record_data)337 sel_string_output_intel_windmill_event_data2_discrete_oem (ipmi_sel_ctx_t ctx,
338 struct ipmi_sel_entry *sel_entry,
339 uint8_t sel_record_type,
340 char *tmpbuf,
341 unsigned int tmpbuflen,
342 unsigned int flags,
343 unsigned int *wlen,
344 struct ipmi_sel_system_event_record_data *system_event_record_data)
345 {
346 assert (ctx);
347 assert (ctx->magic == IPMI_SEL_CTX_MAGIC);
348 assert (ctx->manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL);
349 assert (sel_entry);
350 assert (tmpbuf);
351 assert (tmpbuflen);
352 assert (!(flags & ~IPMI_SEL_STRING_FLAGS_MASK));
353 assert (flags & IPMI_SEL_STRING_FLAGS_INTERPRET_OEM_DATA);
354 assert (wlen);
355 assert (system_event_record_data);
356 assert (system_event_record_data->event_data2_flag == IPMI_SEL_EVENT_DATA_OEM_CODE);
357 assert (ctx->product_id == IPMI_INTEL_PRODUCT_ID_WINDMILL);
358
359 /*
360 * Intel Windmill
361 * (Quanta Winterfell)
362 * (Wiwynn Windmill)
363 */
364 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_PROCESSOR
365 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_PROC_HOT_EXTENDED_SENSOR
366 && system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_PROCESSOR_PROCESSOR_AUTOMATICALLY_THROTTLED)
367 {
368 const char *noe_str;
369
370 noe_str = _sel_string_output_intel_windmill_native_vs_external_throttling (system_event_record_data->event_data2);
371
372 snprintf (tmpbuf,
373 tmpbuflen,
374 "Throttling = %s",
375 noe_str);
376
377 return (1);
378 }
379
380 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_MEMORY
381 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_MEM_HOT_EXTENDED_SENSOR
382 && system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_MEMORY_MEMORY_AUTOMATICALLY_THROTTLED)
383 {
384 const char *noe_str;
385
386 noe_str = _sel_string_output_intel_windmill_native_vs_external_throttling (system_event_record_data->event_data2);
387
388 snprintf (tmpbuf,
389 tmpbuflen,
390 "Throttling = %s",
391 noe_str);
392
393 return (1);
394 }
395
396 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_PROCESSOR
397 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_SENSOR
398 && (system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_PROCESSOR_MACHINE_CHECK_EXCEPTION
399 || system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_PROCESSOR_CORRECTABLE_MACHINE_CHECK_ERROR))
400 {
401 snprintf (tmpbuf,
402 tmpbuflen,
403 "Error Code Number = %u",
404 system_event_record_data->event_data2);
405
406 return (1);
407 }
408
409 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT
410 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_PCIE_ERROR_SENSOR
411 && (system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_BUS_CORRECTABLE_ERROR
412 || system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_BUS_UNCORRECTABLE_ERROR
413 || system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_BUS_FATAL_ERROR))
414 {
415 uint8_t device;
416 uint8_t function;
417
418 device = (system_event_record_data->event_data2 & IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA2_OEM_INTEL_DEVICE_NUMBER_BITMASK);
419 device >>= IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA2_OEM_INTEL_DEVICE_NUMBER_SHIFT;
420
421 function = (system_event_record_data->event_data2 & IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA2_OEM_INTEL_FUNCTION_NUMBER_BITMASK);
422 function >>= IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA2_OEM_INTEL_FUNCTION_NUMBER_SHIFT;
423
424 snprintf (tmpbuf,
425 tmpbuflen,
426 "Device %u, Function %u",
427 device,
428 function);
429
430 return (1);
431 }
432
433 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_MEMORY
434 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_MEMORY_ECC_ERROR
435 && (system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_MEMORY_CORRECTABLE_MEMORY_ERROR
436 || system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_MEMORY_UNCORRECTABLE_MEMORY_ERROR))
437 {
438 uint8_t logical_rank;
439
440 logical_rank = (system_event_record_data->event_data2 & IPMI_SENSOR_TYPE_MEMORY_EVENT_DATA2_OEM_INTEL_WINDMILL_LOGICAL_RANK_BITMASK);
441 logical_rank >>= IPMI_SENSOR_TYPE_MEMORY_EVENT_DATA2_OEM_INTEL_WINDMILL_LOGICAL_RANK_SHIFT;
442
443 snprintf (tmpbuf,
444 tmpbuflen,
445 "Logical Rank = %u",
446 logical_rank);
447
448 return (1);
449 }
450
451 return (0);
452 }
453
454 /* return (0) - no OEM match
455 * return (1) - OEM match
456 * return (-1) - error, cleanup and return error
457 */
458 int
sel_string_output_intel_windmill_event_data2_class_oem(ipmi_sel_ctx_t ctx,struct ipmi_sel_entry * sel_entry,uint8_t sel_record_type,char * tmpbuf,unsigned int tmpbuflen,unsigned int flags,unsigned int * wlen,struct ipmi_sel_system_event_record_data * system_event_record_data)459 sel_string_output_intel_windmill_event_data2_class_oem (ipmi_sel_ctx_t ctx,
460 struct ipmi_sel_entry *sel_entry,
461 uint8_t sel_record_type,
462 char *tmpbuf,
463 unsigned int tmpbuflen,
464 unsigned int flags,
465 unsigned int *wlen,
466 struct ipmi_sel_system_event_record_data *system_event_record_data)
467 {
468 assert (ctx);
469 assert (ctx->magic == IPMI_SEL_CTX_MAGIC);
470 assert (ctx->manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL);
471 assert (sel_entry);
472 assert (tmpbuf);
473 assert (tmpbuflen);
474 assert (!(flags & ~IPMI_SEL_STRING_FLAGS_MASK));
475 assert (flags & IPMI_SEL_STRING_FLAGS_INTERPRET_OEM_DATA);
476 assert (wlen);
477 assert (system_event_record_data);
478 assert (ctx->product_id == IPMI_INTEL_PRODUCT_ID_WINDMILL);
479
480 /*
481 * Intel Windmill
482 * (Quanta Winterfell)
483 * (Wiwynn Windmill)
484 */
485 if (system_event_record_data->event_type_code == IPMI_EVENT_READING_TYPE_CODE_OEM_INTEL_WINDMILL_ME_FW_HEALTH_SENSOR
486 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_ME_FW_HEALTH_SENSOR
487 && system_event_record_data->offset_from_event_reading_type_code == IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_FIRMWARE_STATUS)
488 {
489 uint8_t health_event;
490 char *health_event_str;
491
492 health_event = system_event_record_data->event_data2;
493
494 switch (health_event)
495 {
496 case IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_EVENT_DATA2_RECOVERY_GPIO_FORCED:
497 health_event_str = "Recovery GPIO forced";
498 break;
499 case IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_EVENT_DATA2_IMAGE_EXECUTION_FAILED:
500 health_event_str = "Image execution failed";
501 break;
502 case IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_EVENT_DATA2_FLASH_ERASE_ERROR:
503 health_event_str = "Flash erase error";
504 break;
505 case IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_EVENT_DATA2_FLASH_STATE_INFORMATION:
506 health_event_str = "Flash state information";
507 break;
508 case IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_EVENT_DATA2_INTERNAL_ERROR:
509 health_event_str = "Internal error";
510 break;
511 case IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_EVENT_DATA2_BMC_COLD_RESET_ERROR:
512 health_event_str = "BMC did not respond to cold reset";
513 break;
514 case IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_EVENT_DATA2_DIRECT_FLASH_UPDATE:
515 health_event_str = "Direct flash update requested by the BIOS";
516 break;
517 case IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_EVENT_DATA2_MANUFACTURING_ERROR:
518 health_event_str = "Manufacturing error";
519 break;
520 case IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_EVENT_DATA2_PERSISTENT_STORAGE_INTEGRITY_ERROR:
521 health_event_str = "Persistent storage integrity error";
522 break;
523 default:
524 health_event_str = "Unknown";
525 }
526
527 snprintf (tmpbuf,
528 tmpbuflen,
529 "Health Event = %s",
530 health_event_str);
531
532 return (1);
533 }
534
535 if (system_event_record_data->event_type_code == IPMI_EVENT_READING_TYPE_CODE_OEM_INTEL_WINDMILL_OTHER_IIO_ERROR_SENSOR
536 && system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT
537 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_OTHER_IIO_ERROR_SENSOR
538 && system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_FRONT_PANEL_NMI_DIAGNOSTIC_INTERRUPT)
539 {
540 snprintf (tmpbuf,
541 tmpbuflen,
542 "Error ID = 0x%02X",
543 system_event_record_data->event_data2);
544
545 return (1);
546 }
547
548 return (0);
549 }
550
551 /* return (0) - no OEM match
552 * return (1) - OEM match
553 * return (-1) - error, cleanup and return error
554 */
555 int
sel_string_output_intel_windmill_event_data3_discrete_oem(ipmi_sel_ctx_t ctx,struct ipmi_sel_entry * sel_entry,uint8_t sel_record_type,char * tmpbuf,unsigned int tmpbuflen,unsigned int flags,unsigned int * wlen,struct ipmi_sel_system_event_record_data * system_event_record_data)556 sel_string_output_intel_windmill_event_data3_discrete_oem (ipmi_sel_ctx_t ctx,
557 struct ipmi_sel_entry *sel_entry,
558 uint8_t sel_record_type,
559 char *tmpbuf,
560 unsigned int tmpbuflen,
561 unsigned int flags,
562 unsigned int *wlen,
563 struct ipmi_sel_system_event_record_data *system_event_record_data)
564 {
565 assert (ctx);
566 assert (ctx->magic == IPMI_SEL_CTX_MAGIC);
567 assert (ctx->manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL);
568 assert (sel_entry);
569 assert (tmpbuf);
570 assert (tmpbuflen);
571 assert (!(flags & ~IPMI_SEL_STRING_FLAGS_MASK));
572 assert (flags & IPMI_SEL_STRING_FLAGS_INTERPRET_OEM_DATA);
573 assert (wlen);
574 assert (system_event_record_data);
575 assert (system_event_record_data->event_data3_flag == IPMI_SEL_EVENT_DATA_OEM_CODE);
576 assert (ctx->product_id == IPMI_INTEL_PRODUCT_ID_WINDMILL);
577
578 /*
579 * Intel Windmill
580 * (Quanta Winterfell)
581 * (Wiwynn Windmill)
582 */
583 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_PROCESSOR
584 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_PROC_HOT_EXTENDED_SENSOR
585 && system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_PROCESSOR_PROCESSOR_AUTOMATICALLY_THROTTLED)
586 {
587 uint8_t cpu_vr;
588
589 cpu_vr = (system_event_record_data->event_data3 & IPMI_OEM_INTEL_WINDMILL_EVENT_DATA3_THROTTLING_CPU_VR_BITMASK);
590 cpu_vr >>= IPMI_OEM_INTEL_WINDMILL_EVENT_DATA3_THROTTLING_CPU_VR_SHIFT;
591
592 snprintf (tmpbuf,
593 tmpbuflen,
594 "CPU/VR = %u",
595 cpu_vr);
596
597 return (1);
598 }
599
600 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_MEMORY
601 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_MEM_HOT_EXTENDED_SENSOR
602 && system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_MEMORY_MEMORY_AUTOMATICALLY_THROTTLED)
603 {
604 uint8_t cpu_vr;
605 uint8_t channel_number;
606 uint8_t dimm;
607
608 cpu_vr = (system_event_record_data->event_data3 & IPMI_OEM_INTEL_WINDMILL_EVENT_DATA3_THROTTLING_CPU_VR_BITMASK);
609 cpu_vr >>= IPMI_OEM_INTEL_WINDMILL_EVENT_DATA3_THROTTLING_CPU_VR_SHIFT;
610
611 channel_number = (system_event_record_data->event_data3 & IPMI_OEM_INTEL_WINDMILL_EVENT_DATA3_THROTTLING_CHANNEL_NUMBER_BITMASK);
612 channel_number >>= IPMI_OEM_INTEL_WINDMILL_EVENT_DATA3_THROTTLING_CHANNEL_NUMBER_SHIFT;
613
614 dimm = (system_event_record_data->event_data3 & IPMI_OEM_INTEL_WINDMILL_EVENT_DATA3_THROTTLING_DIMM_BITMASK);
615 dimm >>= IPMI_OEM_INTEL_WINDMILL_EVENT_DATA3_THROTTLING_DIMM_SHIFT;
616
617 snprintf (tmpbuf,
618 tmpbuflen,
619 "CPU/VR = %u, Channel Number = %u, Dimm = %u",
620 cpu_vr,
621 channel_number,
622 dimm);
623
624 return (1);
625 }
626
627 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_PROCESSOR
628 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_SENSOR
629 && (system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_PROCESSOR_MACHINE_CHECK_EXCEPTION
630 || system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_PROCESSOR_CORRECTABLE_MACHINE_CHECK_ERROR))
631 {
632 uint8_t cpu_number;
633 uint8_t source;
634 uint8_t source_extra;
635
636 cpu_number = (system_event_record_data->event_data3 & IPMI_SENSOR_TYPE_PROCESSOR_EVENT_DATA2_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_CPU_NUMBER_BITMASK);
637 cpu_number >>= IPMI_SENSOR_TYPE_PROCESSOR_EVENT_DATA2_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_CPU_NUMBER_SHIFT;
638
639 source = (system_event_record_data->event_data3 & IPMI_SENSOR_TYPE_PROCESSOR_EVENT_DATA2_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_SOURCE_BITMASK);
640 source >>= IPMI_SENSOR_TYPE_PROCESSOR_EVENT_DATA2_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_SOURCE_SHIFT;
641
642 source_extra = (system_event_record_data->event_data3 & IPMI_SENSOR_TYPE_PROCESSOR_EVENT_DATA2_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_SOURCE_EXTRA_BITMASK);
643 source_extra >>= IPMI_SENSOR_TYPE_PROCESSOR_EVENT_DATA2_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_SOURCE_EXTRA_SHIFT;
644
645 if (source == IPMI_SENSOR_TYPE_PROCESSOR_EVENT_DATA2_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_SOURCE_QPI)
646 {
647 char *qpi_str;
648
649 switch (source_extra)
650 {
651 case IPMI_SENSOR_TYPE_PROCESSOR_EVENT_DATA2_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_SOURCE_EXTRA_QPI0:
652 qpi_str = "QPI0";
653 break;
654 case IPMI_SENSOR_TYPE_PROCESSOR_EVENT_DATA2_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_SOURCE_EXTRA_QPI1:
655 qpi_str = "QPI1";
656 break;
657 default:
658 qpi_str = "Unknown QPI";
659 break;
660 }
661
662 snprintf (tmpbuf,
663 tmpbuflen,
664 "CPU = %u, Source = %s",
665 cpu_number,
666 qpi_str);
667 }
668 else if (source == IPMI_SENSOR_TYPE_PROCESSOR_EVENT_DATA2_OEM_INTEL_WINDMILL_MACHINE_CHECK_ERROR_SOURCE_LLC)
669 {
670 snprintf (tmpbuf,
671 tmpbuflen,
672 "CPU = %u, Core = %u",
673 cpu_number,
674 source_extra);
675 }
676 else
677 {
678 snprintf (tmpbuf,
679 tmpbuflen,
680 "CPU = %u, Source = %s",
681 cpu_number,
682 "Unknown");
683 }
684
685 return (1);
686 }
687
688 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT
689 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_PCIE_ERROR_SENSOR
690 && (system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_BUS_CORRECTABLE_ERROR
691 || system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_BUS_UNCORRECTABLE_ERROR
692 || system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_BUS_FATAL_ERROR))
693 {
694 snprintf (tmpbuf,
695 tmpbuflen,
696 "Bus Number = %u",
697 system_event_record_data->event_data3);
698
699 return (1);
700 }
701
702 if (system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_MEMORY
703 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_MEMORY_ECC_ERROR
704 && (system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_MEMORY_CORRECTABLE_MEMORY_ERROR
705 || system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_MEMORY_UNCORRECTABLE_MEMORY_ERROR))
706 {
707 uint8_t cpu_number;
708 uint8_t channel_number;
709 uint8_t dimm;
710
711 cpu_number = (system_event_record_data->event_data3 & IPMI_SENSOR_TYPE_MEMORY_EVENT_DATA3_OEM_INTEL_WINDMILL_CPU_NUMBER_BITMASK);
712 cpu_number >>= IPMI_SENSOR_TYPE_MEMORY_EVENT_DATA3_OEM_INTEL_WINDMILL_CPU_NUMBER_SHIFT;
713
714 channel_number = (system_event_record_data->event_data3 & IPMI_SENSOR_TYPE_MEMORY_EVENT_DATA3_OEM_INTEL_WINDMILL_CHANNEL_NUMBER_BITMASK);
715 channel_number >>= IPMI_SENSOR_TYPE_MEMORY_EVENT_DATA3_OEM_INTEL_WINDMILL_CHANNEL_NUMBER_SHIFT;
716
717 dimm = (system_event_record_data->event_data3 & IPMI_SENSOR_TYPE_MEMORY_EVENT_DATA3_OEM_INTEL_WINDMILL_DIMM_BITMASK);
718 dimm >>= IPMI_SENSOR_TYPE_MEMORY_EVENT_DATA3_OEM_INTEL_WINDMILL_DIMM_SHIFT;
719
720 snprintf (tmpbuf,
721 tmpbuflen,
722 "CPU Number = %u, Channel Number = %u, Dimm = %u",
723 cpu_number,
724 channel_number,
725 dimm);
726
727 return (1);
728 }
729
730 return (0);
731 }
732
733 /* return (0) - no OEM match
734 * return (1) - OEM match
735 * return (-1) - error, cleanup and return error
736 */
737 int
sel_string_output_intel_windmill_event_data3_class_oem(ipmi_sel_ctx_t ctx,struct ipmi_sel_entry * sel_entry,uint8_t sel_record_type,char * tmpbuf,unsigned int tmpbuflen,unsigned int flags,unsigned int * wlen,struct ipmi_sel_system_event_record_data * system_event_record_data)738 sel_string_output_intel_windmill_event_data3_class_oem (ipmi_sel_ctx_t ctx,
739 struct ipmi_sel_entry *sel_entry,
740 uint8_t sel_record_type,
741 char *tmpbuf,
742 unsigned int tmpbuflen,
743 unsigned int flags,
744 unsigned int *wlen,
745 struct ipmi_sel_system_event_record_data *system_event_record_data)
746 {
747 assert (ctx);
748 assert (ctx->magic == IPMI_SEL_CTX_MAGIC);
749 assert (ctx->manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL);
750 assert (sel_entry);
751 assert (tmpbuf);
752 assert (tmpbuflen);
753 assert (!(flags & ~IPMI_SEL_STRING_FLAGS_MASK));
754 assert (flags & IPMI_SEL_STRING_FLAGS_INTERPRET_OEM_DATA);
755 assert (wlen);
756 assert (system_event_record_data);
757 assert (ctx->product_id == IPMI_INTEL_PRODUCT_ID_WINDMILL);
758
759 /*
760 * Intel Windmill
761 * (Quanta Winterfell)
762 * (Wiwynn Windmill)
763 */
764 if (system_event_record_data->event_type_code == IPMI_EVENT_READING_TYPE_CODE_OEM_INTEL_WINDMILL_ME_FW_HEALTH_SENSOR
765 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_ME_FW_HEALTH_SENSOR
766 && system_event_record_data->offset_from_event_reading_type_code == IPMI_OEM_INTEL_WINDMILL_ME_FIRMWARE_HEALTH_EVENT_FIRMWARE_STATUS)
767 {
768 snprintf (tmpbuf,
769 tmpbuflen,
770 "Extended Error Info = %02X",
771 system_event_record_data->event_data3);
772
773 }
774
775 if (system_event_record_data->event_type_code == IPMI_EVENT_READING_TYPE_CODE_OEM_INTEL_WINDMILL_OTHER_IIO_ERROR_SENSOR
776 && system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT
777 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_OTHER_IIO_ERROR_SENSOR
778 && system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_FRONT_PANEL_NMI_DIAGNOSTIC_INTERRUPT)
779 {
780 uint8_t cpu_number;
781 uint8_t source;
782 char *source_str;
783
784 cpu_number = (system_event_record_data->event_data3 & IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA3_OEM_INTEL_WINDMILL_CPU_NUMBER_BITMASK);
785 cpu_number >>= IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA3_OEM_INTEL_WINDMILL_CPU_NUMBER_SHIFT;
786
787 source = (system_event_record_data->event_data3 & IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA3_OEM_INTEL_WINDMILL_SOURCE_BITMASK);
788 source >>= IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA3_OEM_INTEL_WINDMILL_SOURCE_SHIFT;
789
790 switch (source)
791 {
792 case IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA3_OEM_INTEL_WINDMILL_SOURCE_IRP0:
793 source_str = "IRP0";
794 break;
795 case IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA3_OEM_INTEL_WINDMILL_SOURCE_IRP1:
796 source_str = "IRP1";
797 break;
798 case IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA3_OEM_INTEL_WINDMILL_SOURCE_IIO_CORE:
799 source_str = "IIO-Core";
800 break;
801 case IPMI_SENSOR_TYPE_CRITICAL_INTERRUPT_EVENT_DATA3_OEM_INTEL_WINDMILL_SOURCE_VT_D:
802 source_str = "VT-d";
803 break;
804 default:
805 source_str = "Unknown";
806 break;
807 }
808
809 snprintf (tmpbuf,
810 tmpbuflen,
811 "CPU Number = %u, Source = %s",
812 cpu_number, source_str);
813
814 return (1);
815 }
816
817 return (0);
818 }
819
820 /* return (0) - no OEM match
821 * return (1) - OEM match
822 * return (-1) - error, cleanup and return error
823 *
824 * in oem_rv, return
825 * 0 - continue on
826 * 1 - buffer full, return full buffer to user
827 */
828 int
sel_string_output_intel_windmill_event_data2_event_data3(ipmi_sel_ctx_t ctx,struct ipmi_sel_entry * sel_entry,uint8_t sel_record_type,char * buf,unsigned int buflen,unsigned int flags,unsigned int * wlen,struct ipmi_sel_system_event_record_data * system_event_record_data,int * oem_rv)829 sel_string_output_intel_windmill_event_data2_event_data3 (ipmi_sel_ctx_t ctx,
830 struct ipmi_sel_entry *sel_entry,
831 uint8_t sel_record_type,
832 char *buf,
833 unsigned int buflen,
834 unsigned int flags,
835 unsigned int *wlen,
836 struct ipmi_sel_system_event_record_data *system_event_record_data,
837 int *oem_rv)
838 {
839 assert (ctx);
840 assert (ctx->magic == IPMI_SEL_CTX_MAGIC);
841 assert (ctx->manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL);
842 assert (sel_entry);
843 assert (buf);
844 assert (buflen);
845 assert (!(flags & ~IPMI_SEL_STRING_FLAGS_MASK));
846 assert (flags & IPMI_SEL_STRING_FLAGS_INTERPRET_OEM_DATA);
847 assert (wlen);
848 assert (system_event_record_data);
849 assert (oem_rv);
850 assert (ctx->product_id == IPMI_INTEL_PRODUCT_ID_WINDMILL);
851
852 /*
853 * Intel Windmill
854 * (Quanta Winterfell)
855 * (Wiwynn Windmill)
856 */
857
858 if (system_event_record_data->event_type_code == IPMI_EVENT_READING_TYPE_CODE_SENSOR_SPECIFIC
859 && system_event_record_data->sensor_type == IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS
860 && system_event_record_data->sensor_number == IPMI_SENSOR_NUMBER_OEM_INTEL_WINDMILL_POST_ERROR_SENSOR
861 && system_event_record_data->offset_from_event_reading_type_code == IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_SYSTEM_FIRMWARE_ERROR
862 && system_event_record_data->event_data2_flag == IPMI_SEL_EVENT_DATA_OEM_CODE
863 && system_event_record_data->event_data3_flag == IPMI_SEL_EVENT_DATA_OEM_CODE)
864 {
865 uint16_t error_code;
866 char *error_code_str = NULL;
867
868 error_code = system_event_record_data->event_data2;
869 error_code |= (system_event_record_data->event_data3 << 8);
870
871 switch (error_code)
872 {
873 /* These are from WiWynn doc */
874 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_CPU_MISMATCH:
875 error_code_str = "PEI CPU Mismatch";
876 break;
877 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_CPU_SELF_TEST_FAILED:
878 error_code_str = "PEI CPU Self Test Failed";
879 break;
880 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_CPU_CACHE_ERROR:
881 error_code_str = "PEI CPU Cache Error ";
882 break;
883 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_CPU_MICROCODE_UPDATE_FAILED:
884 error_code_str = "PEI CPU Microcode Update Failed";
885 break;
886 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_CPU_NO_MICROCODE:
887 error_code_str = "PEI CPU No Microcode";
888 break;
889 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_CPU_INTERNAL_ERROR:
890 error_code_str = "PEI CPU Internal Error";
891 break;
892 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_RESET_NOT_AVAILABLE1:
893 error_code_str = "PEI Reset Not Available";
894 break;
895 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_RESET_NOT_AVAILABLE2:
896 error_code_str = "PEI Reset Not Available";
897 break;
898 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_RECOVERY_NO_CAPSULE:
899 error_code_str = "PEI Recovery No Capsule";
900 break;
901 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_SB_PWR_FLR:
902 error_code_str = "PEI SB PWR FLR";
903 break;
904 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_PEI_SB_SYSPWR_FLR:
905 error_code_str = "PEI SB SYSPWR FLR";
906 break;
907 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_DXE_CLEAR_CMOS:
908 error_code_str = "DXE Clear CMOS ";
909 break;
910 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_DXE_NB_ERROR:
911 error_code_str = "DXE NB Error";
912 break;
913 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_DXE_ARCH_PROTOCOL_NOT_AVAILABLE:
914 error_code_str = "DXE Arch Protocol Not Available";
915 break;
916 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_DXE_PCI_BUS_OUT_OF_RESOURCES:
917 error_code_str = "DXE PCI Bus Out of Resources";
918 break;
919 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_DXE_LEGACY_OPROM_NO_SPACE:
920 error_code_str = "DXE Legacy OPROM No Space";
921 break;
922 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_DXE_NO_CON_OUT:
923 error_code_str = "DXE No Con Out";
924 break;
925 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_DXE_NO_CON_IN:
926 error_code_str = "DXE No Con In";
927 break;
928 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_DXE_FLASH_UPDATE_FAILED:
929 error_code_str = "DXE Flash Update Failed";
930 break;
931 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_DXE_RESET_NOT_AVAILABLE:
932 error_code_str = "DXE Reset Not Available";
933 break;
934 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_ME_RECOVERED_VIA_GR:
935 error_code_str = "ME Recovered via GR";
936 break;
937 /* These are from a Quanta doc */
938 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_CMOS_CLEAR:
939 error_code_str = "CMOS Clear";
940 break;
941 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_THERMAL_TRIP:
942 error_code_str = "Thermal Trip";
943 break;
944 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_SYS_PWROK_DROPS_UNEXPECTEDLY:
945 error_code_str = "SYS_PWROK Drops Unexpectedly";
946 break;
947 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_AC_LOST:
948 error_code_str = "AC Lost";
949 break;
950 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_RECOVER_ME_FROM_ABNORMAL_MODE:
951 error_code_str = "Recover ME from Abnormal Mode Successfully";
952 break;
953 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_BACKUP_IMAGE_LOADED_DIRECT_FW_UPDATE_NEEDED:
954 error_code_str = "Backup Image Loaded and a direct FW updated is needed";
955 break;
956 case IPMI_SENSOR_TYPE_SYSTEM_FIRMWARE_PROGRESS_OEM_INTEL_WINDMILL_POST_ERROR_CODE_ROCVER_HECI_FROM_ABNORMAL_MODE:
957 error_code_str = "Recover HECI from Abnormal Mode Successfully";
958 break;
959 default:
960 error_code_str = "Undefined Post Error";
961 }
962
963 if (sel_string_snprintf (buf,
964 buflen,
965 wlen,
966 "%s",
967 error_code_str))
968 (*oem_rv) = 1;
969 else
970 (*oem_rv) = 0;
971
972 return (1);
973 }
974
975 return (0);
976 }
977
978 /* return (0) - no OEM match
979 * return (1) - OEM match
980 * return (-1) - error, cleanup and return error
981 *
982 * in oem_rv, return
983 * 0 - continue on
984 * 1 - buffer full, return full buffer to user
985 */
986 int
sel_string_output_intel_windmill_oem_record_data(ipmi_sel_ctx_t ctx,struct ipmi_sel_entry * sel_entry,uint8_t sel_record_type,char * buf,unsigned int buflen,unsigned int flags,unsigned int * wlen,int * oem_rv)987 sel_string_output_intel_windmill_oem_record_data (ipmi_sel_ctx_t ctx,
988 struct ipmi_sel_entry *sel_entry,
989 uint8_t sel_record_type,
990 char *buf,
991 unsigned int buflen,
992 unsigned int flags,
993 unsigned int *wlen,
994 int *oem_rv)
995 {
996 assert (ctx);
997 assert (ctx->magic == IPMI_SEL_CTX_MAGIC);
998 assert (ctx->manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL);
999 assert (ipmi_sel_record_type_class (sel_record_type) == IPMI_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD
1000 || ipmi_sel_record_type_class (sel_record_type) == IPMI_SEL_RECORD_TYPE_CLASS_NON_TIMESTAMPED_OEM_RECORD);
1001 assert (sel_entry);
1002 assert (buf);
1003 assert (buflen);
1004 assert (!(flags & ~IPMI_SEL_STRING_FLAGS_MASK));
1005 assert (flags & IPMI_SEL_STRING_FLAGS_INTERPRET_OEM_DATA);
1006 assert (wlen);
1007 assert (oem_rv);
1008 assert (ctx->product_id == IPMI_INTEL_PRODUCT_ID_WINDMILL);
1009
1010 /* Intel Windmill
1011 * (Quanta Winterfell)
1012 * (Wiwynn Windmill)
1013 */
1014
1015 if (ipmi_sel_record_type_class (sel_record_type) == IPMI_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD)
1016 {
1017 /* Bytes 11-12 - Device ID
1018 * Bytes 13-14 - Device Identification Number
1019 * Bytes 15-16 - Error Code
1020 *
1021 * I'm assuming little endian, hopefully I'm right.
1022 */
1023 uint16_t device_id;
1024 uint16_t device_identification_number;
1025 char *device_identification_number_str;
1026 uint16_t error_code;
1027 char *error_code_str;
1028
1029 device_id = sel_entry->sel_event_record[IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_INDEX_LSB_INDEX];
1030 device_id |= (sel_entry->sel_event_record[IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_INDEX_MSB_INDEX] << 8);
1031
1032 device_identification_number = sel_entry->sel_event_record[IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_INDEX_LSB_INDEX];
1033 device_identification_number |= (sel_entry->sel_event_record[IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_INDEX_MSB_INDEX] << 8);
1034
1035 error_code = sel_entry->sel_event_record[IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_INDEX_LSB_INDEX];
1036 error_code |= (sel_entry->sel_event_record[IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_INDEX_MSB_INDEX] << 8);
1037
1038 switch (device_identification_number)
1039 {
1040 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_DEVICE_0_IN_DMI_MODE:
1041 device_identification_number_str = "Device 0 in DMI Mode ";
1042 break;
1043 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_DMI_PORT_IN_PCIE_MODE:
1044 device_identification_number_str = "DMI Port in PCIe Mode ";
1045 break;
1046 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_PORT_1A:
1047 device_identification_number_str = "Port 1A";
1048 break;
1049 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_PORT_1B:
1050 device_identification_number_str = "Port 1B";
1051 break;
1052 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_PORT_2A:
1053 device_identification_number_str = "Port 2A";
1054 break;
1055 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_PORT_2B:
1056 device_identification_number_str = "Port 2B";
1057 break;
1058 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_PORT_2C:
1059 device_identification_number_str = "Port 2C";
1060 break;
1061 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_PORT_2D:
1062 device_identification_number_str = "Port 2D";
1063 break;
1064 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_PORT_3A_IN_PCIE_MODE:
1065 device_identification_number_str = "Port 3A in PCIe Mode";
1066 break;
1067 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_PORT_3B:
1068 device_identification_number_str = "Port 3B";
1069 break;
1070 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_PORT_3C:
1071 device_identification_number_str = "Port 3C";
1072 break;
1073 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_PORT_3D:
1074 device_identification_number_str = "Port 3D";
1075 break;
1076 case IPMI_SEL_OEM_INTEL_WINDMILL_DEVICE_IDENTIFICATION_NUMBER_IIO_NTB_SECONDARY_ENDPOINT:
1077 device_identification_number_str = "IIO NTB Secondary Endpoint";
1078 break;
1079 default:
1080 device_identification_number_str = "Unknown";
1081 break;
1082 }
1083
1084 switch (error_code)
1085 {
1086 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_RECEIVER_ERROR:
1087 error_code_str = "Receiver Error";
1088 break;
1089 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_BAD_TLP:
1090 error_code_str = "Bad TLP";
1091 break;
1092 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_BAD_DLLP:
1093 error_code_str = "Bad DLPP";
1094 break;
1095 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_REPLAY_TIMEOUT:
1096 error_code_str = "Replay Time-out";
1097 break;
1098 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_REPLAY_NUMBER_ROLLOVER:
1099 error_code_str = "Replay Number Rollover";
1100 break;
1101 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_ADVISORY_NON_FATAL_ERROR:
1102 error_code_str = "Advisory Non-fatal Error";
1103 break;
1104 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_RECEIVED_ERR_COR_MESSAGE_FROM_DOWNSTREAM_DEVICE:
1105 error_code_str = "Received ERR_COR message from downstream device";
1106 break;
1107 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_PCI_EXPRESS_LINK_BANDWIDTH_CHANGED:
1108 error_code_str = "PCI Express Link Bandwidth changed";
1109 break;
1110 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_RECEIVED_UNSUPPORTED_REQUEST_COMPLETION_STATUS_FROM_DOWNSTREAM_DEVICE:
1111 error_code_str = "Received \"Unsupported Request\" completion status from downstream device.";
1112 break;
1113 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_SENT_A_PCI_EXPRESS_UNSUPPORTED_REQUEST_RESPOND_ON_INBOUND_REQUEST:
1114 error_code_str = "Sent a PCI Express \"Unsupported Request\" respond on inbound request for address decode, request type, or other reason.";
1115 break;
1116 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_RECEIVED_COMPLETER_ABORT_COMPLETION_STATUS_FROM_DOWNSTREAM_DEVICE:
1117 error_code_str = "Received \"Completer Abort\" completion status from downstream device.";
1118 break;
1119 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_SENT_A_PCI_EXPRESS_COMPLETER_ABORT_CONDITION_ON_INBOUND_REQUEST:
1120 error_code_str = "Sent a PCI Express \"Completer Abort\" condition on inbound request for address decode, request type, or other reason.";
1121 break;
1122 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_COMPLETION_TIMEOUT_ON_NP_TRANSACTION_OUTSTANDING_ON_PCI_EXPRESS_DMI:
1123 error_code_str = "Completion timeout on NP transaction outstanding on PCI Express/DMI.";
1124 break;
1125 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_RECEIVED_PCI_EXPRESS_POISONED_TLP:
1126 error_code_str = "Received PCI Express Poisoned TLP.";
1127 break;
1128 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_RECEIVED_PCI_EXPRESS_UNEXPECTED_COMPLETION:
1129 error_code_str = "Received PCI Express unexpected Completion.";
1130 break;
1131 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_PCI_EXPRESS_FLOW_CONTROL_PROTOCOL_ERROR:
1132 error_code_str = "PCI Express Flow Control Protocol Error.";
1133 break;
1134 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_RECEIVED_ERR_NONFATAL_MESSAGE_FROM_DOWNSTREAM_DEVICE:
1135 error_code_str = "Received ERR_NONFATAL Message from downstream device.";
1136 break;
1137 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_RECEIVED_A_REQUEST_FROM_A_DOWNSTREAM_COMPONENT_THAT_IS_UNSUPPORTED:
1138 error_code_str = "Received a Request from a downstream component that is unsupported.";
1139 break;
1140 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_RECEIVED_A_REQUEST_FROM_A_DOWNSTREAM_COMPONENT_THAT_IS_TO_BE_COMPLETER_ABORTED:
1141 error_code_str = "Received a Request from a downstream component that is to be completer aborted.";
1142 break;
1143 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_ACS_VIOLATION:
1144 error_code_str = "ACS Violation";
1145 break;
1146 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_PCI_EXPRESS_MALFORMED_TLP:
1147 error_code_str = "PCI Express Malformed TLP";
1148 break;
1149 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_PCI_EXPRESS_DATA_LINK_PROTOCOL_ERROR:
1150 error_code_str = "PCI Express Data Link Protocol Error";
1151 break;
1152 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_PCI_EXPRESS_RECEIVER_OVERFLOW:
1153 error_code_str = "PCI Express Receiver Overflow";
1154 break;
1155 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_SURPRISE_DOWN:
1156 error_code_str = "Surprise Down";
1157 break;
1158 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_RECEIVED_ERR_FATAL_MESSAGE_FROM_DOWNSTREAM_DEVICE:
1159 error_code_str = "Received ERR_FATAL message from downstream device.";
1160 break;
1161 case IPMI_SEL_OEM_INTEL_WINDMILL_ERROR_CODE_OUTBOUND_SWITCH_HEADER_QUEUE_PARITY_ERROR:
1162 error_code_str = "Outbound switch header queue partiy error";
1163 break;
1164 default:
1165 error_code_str = "Unknown";
1166 break;
1167 }
1168
1169 if (sel_string_snprintf (buf,
1170 buflen,
1171 wlen,
1172 "Devie ID = %u, Device Identification Number = %s, Error = %s",
1173 device_id,
1174 device_identification_number_str,
1175 error_code_str))
1176 (*oem_rv) = 1;
1177 else
1178 (*oem_rv) = 0;
1179
1180 return (1);
1181 }
1182
1183 return (0);
1184 }
1185
1186 struct sel_string_oem sel_string_oem_intel_windmill =
1187 {
1188 NULL,
1189 sel_string_output_intel_windmill_event_data1_class_sensor_specific_discrete,
1190 NULL,
1191 NULL,
1192 sel_string_output_intel_windmill_event_data2_discrete_oem,
1193 sel_string_output_intel_windmill_event_data2_class_oem,
1194 NULL,
1195 sel_string_output_intel_windmill_event_data3_discrete_oem,
1196 sel_string_output_intel_windmill_event_data3_class_oem,
1197 sel_string_output_intel_windmill_event_data2_event_data3,
1198 sel_string_output_intel_windmill_oem_record_data,
1199 NULL,
1200 };
1201