1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #include <soc/soc_util.h>
5 #include <drivers/ipmi/ocp/ipmi_ocp.h>
8 static void ipmi_send_sel_ewl_type3_err(EWL_ENTRY_HEADER
*header
,
9 EWL_ENTRY_MEMORY_LOCATION memory_location
)
11 struct ipmi_sel_mem_err sel
;
13 EWL_ENTRY_TYPE3
*basic_warning
;
14 basic_warning
= (EWL_ENTRY_TYPE3
*)header
;
16 /* Ignore invalid EWL DIMM location before sending SEL */
17 if (memory_location
.Channel
== 0xff || memory_location
.Dimm
== 0xff)
19 memset(&sel
, 0, sizeof(struct ipmi_sel_mem_err
));
20 sel
.record_id
= 0x0000;
21 sel
.record_type
= 0xfb;
22 sel
.general_info
= SEL_INTEL_MEMORY_ERROR
;
24 socketid
= get_blade_id() - 1;
25 sel
.socket
= socketid
<<= 4;
26 sel
.channel
= memory_location
.Channel
;
27 sel
.dimm_slot
= memory_location
.Dimm
;
29 sel
.dimm_failure_type
= MEM_TRAINING_ERR
;
30 sel
.major_code
= basic_warning
->Context
.MajorWarningCode
;
31 sel
.minor_code
= basic_warning
->Context
.MinorWarningCode
;
33 ipmi_send_to_bmc((unsigned char *)&sel
, sizeof(sel
));
34 printk(BIOS_DEBUG
, "ipmi send memory training error\n");
37 static void process_ewl_type3(EWL_ENTRY_HEADER
*header
, EWL_ENTRY_MEMORY_LOCATION memory_location
)
39 /* Treat warning as type 3, collect basic information and print to serial log */
40 EWL_ENTRY_TYPE3
*basic_warning
;
41 basic_warning
= (EWL_ENTRY_TYPE3
*)header
;
42 printk(BIOS_ERR
, "Major Warning Code = 0x%02x, Minor Warning Code = 0x%02x,\n",
43 basic_warning
->Context
.MajorWarningCode
,
44 basic_warning
->Context
.MinorWarningCode
);
45 printk(BIOS_ERR
, "Major Checkpoint: 0x%02x\n", basic_warning
->Context
.MajorCheckpoint
);
46 printk(BIOS_ERR
, "Minor Checkpoint: 0x%02x\n", basic_warning
->Context
.MinorCheckpoint
);
48 if (memory_location
.Socket
!= 0xff)
49 printk(BIOS_ERR
, "Socket %d\n", memory_location
.Socket
);
50 if (memory_location
.Channel
!= 0xff)
51 printk(BIOS_ERR
, "Channel %d\n", memory_location
.Channel
);
52 if (memory_location
.Dimm
!= 0xff)
53 printk(BIOS_ERR
, "Dimm %d\n", memory_location
.Dimm
);
54 if (memory_location
.Rank
!= 0xff)
55 printk(BIOS_ERR
, "Rank %d\n", memory_location
.Rank
);
60 const EWL_PRIVATE_DATA
*hob
= get_ewl_hob();
63 EWL_ENTRY_HEADER
*warning_header
;
64 printk(BIOS_DEBUG
, "Number of EWL entries %d\n", hob
->numEntries
);
65 while (offset
< hob
->status
.Header
.FreeOffset
) {
66 warning_header
= (EWL_ENTRY_HEADER
*) &(hob
->status
.Buffer
[offset
]);
67 if (warning_header
->Type
== EwlType3
) {
68 printk(BIOS_ERR
, "EWL type: %d size:%d severity level:%d\n",
71 warning_header
->Severity
);
72 if (warning_header
->Size
!= sizeof(EWL_ENTRY_TYPE3
)) {
73 printk(BIOS_ERR
, "EWL type3 size mismatch!\n");
76 EWL_ENTRY_TYPE3
*type3
;
77 type3
= (EWL_ENTRY_TYPE3
*)warning_header
;
78 process_ewl_type3(warning_header
, type3
->MemoryLocation
);
80 ipmi_send_sel_ewl_type3_err(warning_header
, type3
->MemoryLocation
);
82 printk(BIOS_DEBUG
, "EWL type: %d size:%d severity level:%d\n",
85 warning_header
->Severity
);
86 hexdump(&(hob
->status
.Buffer
[offset
]), warning_header
->Size
);
88 offset
+= warning_header
->Size
;
91 /* If Fastboot is enabled, the next boot will skip MRC and won't detect
92 MRC error via EWL and still can boot up, so enforce MRC after reboot. */
93 soc_set_mrc_cold_boot_flag(true);
94 die("Memory Training Error!\n");