xref: /OK3568_Linux_fs/kernel/drivers/edac/mce_amd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun #include <linux/module.h>
3*4882a593Smuzhiyun #include <linux/slab.h>
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <asm/cpu.h>
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include "mce_amd.h"
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun static struct amd_decoder_ops fam_ops;
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun static u8 xec_mask	 = 0xf;
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun static void (*decode_dram_ecc)(int node_id, struct mce *m);
14*4882a593Smuzhiyun 
amd_register_ecc_decoder(void (* f)(int,struct mce *))15*4882a593Smuzhiyun void amd_register_ecc_decoder(void (*f)(int, struct mce *))
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun 	decode_dram_ecc = f;
18*4882a593Smuzhiyun }
19*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
20*4882a593Smuzhiyun 
amd_unregister_ecc_decoder(void (* f)(int,struct mce *))21*4882a593Smuzhiyun void amd_unregister_ecc_decoder(void (*f)(int, struct mce *))
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun 	if (decode_dram_ecc) {
24*4882a593Smuzhiyun 		WARN_ON(decode_dram_ecc != f);
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun 		decode_dram_ecc = NULL;
27*4882a593Smuzhiyun 	}
28*4882a593Smuzhiyun }
29*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(amd_unregister_ecc_decoder);
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun /*
32*4882a593Smuzhiyun  * string representation for the different MCA reported error types, see F3x48
33*4882a593Smuzhiyun  * or MSR0000_0411.
34*4882a593Smuzhiyun  */
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun /* transaction type */
37*4882a593Smuzhiyun static const char * const tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" };
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /* cache level */
40*4882a593Smuzhiyun static const char * const ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" };
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /* memory transaction type */
43*4882a593Smuzhiyun static const char * const rrrr_msgs[] = {
44*4882a593Smuzhiyun        "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP"
45*4882a593Smuzhiyun };
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun /* participating processor */
48*4882a593Smuzhiyun const char * const pp_msgs[] = { "SRC", "RES", "OBS", "GEN" };
49*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pp_msgs);
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun /* request timeout */
52*4882a593Smuzhiyun static const char * const to_msgs[] = { "no timeout", "timed out" };
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /* memory or i/o */
55*4882a593Smuzhiyun static const char * const ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /* internal error type */
58*4882a593Smuzhiyun static const char * const uu_msgs[] = { "RESV", "RESV", "HWA", "RESV" };
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun static const char * const f15h_mc1_mce_desc[] = {
61*4882a593Smuzhiyun 	"UC during a demand linefill from L2",
62*4882a593Smuzhiyun 	"Parity error during data load from IC",
63*4882a593Smuzhiyun 	"Parity error for IC valid bit",
64*4882a593Smuzhiyun 	"Main tag parity error",
65*4882a593Smuzhiyun 	"Parity error in prediction queue",
66*4882a593Smuzhiyun 	"PFB data/address parity error",
67*4882a593Smuzhiyun 	"Parity error in the branch status reg",
68*4882a593Smuzhiyun 	"PFB promotion address error",
69*4882a593Smuzhiyun 	"Tag error during probe/victimization",
70*4882a593Smuzhiyun 	"Parity error for IC probe tag valid bit",
71*4882a593Smuzhiyun 	"PFB non-cacheable bit parity error",
72*4882a593Smuzhiyun 	"PFB valid bit parity error",			/* xec = 0xd */
73*4882a593Smuzhiyun 	"Microcode Patch Buffer",			/* xec = 010 */
74*4882a593Smuzhiyun 	"uop queue",
75*4882a593Smuzhiyun 	"insn buffer",
76*4882a593Smuzhiyun 	"predecode buffer",
77*4882a593Smuzhiyun 	"fetch address FIFO",
78*4882a593Smuzhiyun 	"dispatch uop queue"
79*4882a593Smuzhiyun };
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun static const char * const f15h_mc2_mce_desc[] = {
82*4882a593Smuzhiyun 	"Fill ECC error on data fills",			/* xec = 0x4 */
83*4882a593Smuzhiyun 	"Fill parity error on insn fills",
84*4882a593Smuzhiyun 	"Prefetcher request FIFO parity error",
85*4882a593Smuzhiyun 	"PRQ address parity error",
86*4882a593Smuzhiyun 	"PRQ data parity error",
87*4882a593Smuzhiyun 	"WCC Tag ECC error",
88*4882a593Smuzhiyun 	"WCC Data ECC error",
89*4882a593Smuzhiyun 	"WCB Data parity error",
90*4882a593Smuzhiyun 	"VB Data ECC or parity error",
91*4882a593Smuzhiyun 	"L2 Tag ECC error",				/* xec = 0x10 */
92*4882a593Smuzhiyun 	"Hard L2 Tag ECC error",
93*4882a593Smuzhiyun 	"Multiple hits on L2 tag",
94*4882a593Smuzhiyun 	"XAB parity error",
95*4882a593Smuzhiyun 	"PRB address parity error"
96*4882a593Smuzhiyun };
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun static const char * const mc4_mce_desc[] = {
99*4882a593Smuzhiyun 	"DRAM ECC error detected on the NB",
100*4882a593Smuzhiyun 	"CRC error detected on HT link",
101*4882a593Smuzhiyun 	"Link-defined sync error packets detected on HT link",
102*4882a593Smuzhiyun 	"HT Master abort",
103*4882a593Smuzhiyun 	"HT Target abort",
104*4882a593Smuzhiyun 	"Invalid GART PTE entry during GART table walk",
105*4882a593Smuzhiyun 	"Unsupported atomic RMW received from an IO link",
106*4882a593Smuzhiyun 	"Watchdog timeout due to lack of progress",
107*4882a593Smuzhiyun 	"DRAM ECC error detected on the NB",
108*4882a593Smuzhiyun 	"SVM DMA Exclusion Vector error",
109*4882a593Smuzhiyun 	"HT data error detected on link",
110*4882a593Smuzhiyun 	"Protocol error (link, L3, probe filter)",
111*4882a593Smuzhiyun 	"NB internal arrays parity error",
112*4882a593Smuzhiyun 	"DRAM addr/ctl signals parity error",
113*4882a593Smuzhiyun 	"IO link transmission error",
114*4882a593Smuzhiyun 	"L3 data cache ECC error",			/* xec = 0x1c */
115*4882a593Smuzhiyun 	"L3 cache tag error",
116*4882a593Smuzhiyun 	"L3 LRU parity bits error",
117*4882a593Smuzhiyun 	"ECC Error in the Probe Filter directory"
118*4882a593Smuzhiyun };
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun static const char * const mc5_mce_desc[] = {
121*4882a593Smuzhiyun 	"CPU Watchdog timer expire",
122*4882a593Smuzhiyun 	"Wakeup array dest tag",
123*4882a593Smuzhiyun 	"AG payload array",
124*4882a593Smuzhiyun 	"EX payload array",
125*4882a593Smuzhiyun 	"IDRF array",
126*4882a593Smuzhiyun 	"Retire dispatch queue",
127*4882a593Smuzhiyun 	"Mapper checkpoint array",
128*4882a593Smuzhiyun 	"Physical register file EX0 port",
129*4882a593Smuzhiyun 	"Physical register file EX1 port",
130*4882a593Smuzhiyun 	"Physical register file AG0 port",
131*4882a593Smuzhiyun 	"Physical register file AG1 port",
132*4882a593Smuzhiyun 	"Flag register file",
133*4882a593Smuzhiyun 	"DE error occurred",
134*4882a593Smuzhiyun 	"Retire status queue"
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun static const char * const mc6_mce_desc[] = {
138*4882a593Smuzhiyun 	"Hardware Assertion",
139*4882a593Smuzhiyun 	"Free List",
140*4882a593Smuzhiyun 	"Physical Register File",
141*4882a593Smuzhiyun 	"Retire Queue",
142*4882a593Smuzhiyun 	"Scheduler table",
143*4882a593Smuzhiyun 	"Status Register File",
144*4882a593Smuzhiyun };
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun /* Scalable MCA error strings */
147*4882a593Smuzhiyun static const char * const smca_ls_mce_desc[] = {
148*4882a593Smuzhiyun 	"Load queue parity error",
149*4882a593Smuzhiyun 	"Store queue parity error",
150*4882a593Smuzhiyun 	"Miss address buffer payload parity error",
151*4882a593Smuzhiyun 	"Level 1 TLB parity error",
152*4882a593Smuzhiyun 	"DC Tag error type 5",
153*4882a593Smuzhiyun 	"DC Tag error type 6",
154*4882a593Smuzhiyun 	"DC Tag error type 1",
155*4882a593Smuzhiyun 	"Internal error type 1",
156*4882a593Smuzhiyun 	"Internal error type 2",
157*4882a593Smuzhiyun 	"System Read Data Error Thread 0",
158*4882a593Smuzhiyun 	"System Read Data Error Thread 1",
159*4882a593Smuzhiyun 	"DC Tag error type 2",
160*4882a593Smuzhiyun 	"DC Data error type 1 and poison consumption",
161*4882a593Smuzhiyun 	"DC Data error type 2",
162*4882a593Smuzhiyun 	"DC Data error type 3",
163*4882a593Smuzhiyun 	"DC Tag error type 4",
164*4882a593Smuzhiyun 	"Level 2 TLB parity error",
165*4882a593Smuzhiyun 	"PDC parity error",
166*4882a593Smuzhiyun 	"DC Tag error type 3",
167*4882a593Smuzhiyun 	"DC Tag error type 5",
168*4882a593Smuzhiyun 	"L2 Fill Data error",
169*4882a593Smuzhiyun };
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun static const char * const smca_ls2_mce_desc[] = {
172*4882a593Smuzhiyun 	"An ECC error was detected on a data cache read by a probe or victimization",
173*4882a593Smuzhiyun 	"An ECC error or L2 poison was detected on a data cache read by a load",
174*4882a593Smuzhiyun 	"An ECC error was detected on a data cache read-modify-write by a store",
175*4882a593Smuzhiyun 	"An ECC error or poison bit mismatch was detected on a tag read by a probe or victimization",
176*4882a593Smuzhiyun 	"An ECC error or poison bit mismatch was detected on a tag read by a load",
177*4882a593Smuzhiyun 	"An ECC error or poison bit mismatch was detected on a tag read by a store",
178*4882a593Smuzhiyun 	"An ECC error was detected on an EMEM read by a load",
179*4882a593Smuzhiyun 	"An ECC error was detected on an EMEM read-modify-write by a store",
180*4882a593Smuzhiyun 	"A parity error was detected in an L1 TLB entry by any access",
181*4882a593Smuzhiyun 	"A parity error was detected in an L2 TLB entry by any access",
182*4882a593Smuzhiyun 	"A parity error was detected in a PWC entry by any access",
183*4882a593Smuzhiyun 	"A parity error was detected in an STQ entry by any access",
184*4882a593Smuzhiyun 	"A parity error was detected in an LDQ entry by any access",
185*4882a593Smuzhiyun 	"A parity error was detected in a MAB entry by any access",
186*4882a593Smuzhiyun 	"A parity error was detected in an SCB entry state field by any access",
187*4882a593Smuzhiyun 	"A parity error was detected in an SCB entry address field by any access",
188*4882a593Smuzhiyun 	"A parity error was detected in an SCB entry data field by any access",
189*4882a593Smuzhiyun 	"A parity error was detected in a WCB entry by any access",
190*4882a593Smuzhiyun 	"A poisoned line was detected in an SCB entry by any access",
191*4882a593Smuzhiyun 	"A SystemReadDataError error was reported on read data returned from L2 for a load",
192*4882a593Smuzhiyun 	"A SystemReadDataError error was reported on read data returned from L2 for an SCB store",
193*4882a593Smuzhiyun 	"A SystemReadDataError error was reported on read data returned from L2 for a WCB store",
194*4882a593Smuzhiyun 	"A hardware assertion error was reported",
195*4882a593Smuzhiyun 	"A parity error was detected in an STLF, SCB EMEM entry or SRB store data by any access",
196*4882a593Smuzhiyun };
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun static const char * const smca_if_mce_desc[] = {
199*4882a593Smuzhiyun 	"Op Cache Microtag Probe Port Parity Error",
200*4882a593Smuzhiyun 	"IC Microtag or Full Tag Multi-hit Error",
201*4882a593Smuzhiyun 	"IC Full Tag Parity Error",
202*4882a593Smuzhiyun 	"IC Data Array Parity Error",
203*4882a593Smuzhiyun 	"Decoupling Queue PhysAddr Parity Error",
204*4882a593Smuzhiyun 	"L0 ITLB Parity Error",
205*4882a593Smuzhiyun 	"L1 ITLB Parity Error",
206*4882a593Smuzhiyun 	"L2 ITLB Parity Error",
207*4882a593Smuzhiyun 	"BPQ Thread 0 Snoop Parity Error",
208*4882a593Smuzhiyun 	"BPQ Thread 1 Snoop Parity Error",
209*4882a593Smuzhiyun 	"L1 BTB Multi-Match Error",
210*4882a593Smuzhiyun 	"L2 BTB Multi-Match Error",
211*4882a593Smuzhiyun 	"L2 Cache Response Poison Error",
212*4882a593Smuzhiyun 	"System Read Data Error",
213*4882a593Smuzhiyun 	"Hardware Assertion Error",
214*4882a593Smuzhiyun 	"L1-TLB Multi-Hit",
215*4882a593Smuzhiyun 	"L2-TLB Multi-Hit",
216*4882a593Smuzhiyun 	"BSR Parity Error",
217*4882a593Smuzhiyun 	"CT MCE",
218*4882a593Smuzhiyun };
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun static const char * const smca_l2_mce_desc[] = {
221*4882a593Smuzhiyun 	"L2M Tag Multiple-Way-Hit error",
222*4882a593Smuzhiyun 	"L2M Tag or State Array ECC Error",
223*4882a593Smuzhiyun 	"L2M Data Array ECC Error",
224*4882a593Smuzhiyun 	"Hardware Assert Error",
225*4882a593Smuzhiyun };
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun static const char * const smca_de_mce_desc[] = {
228*4882a593Smuzhiyun 	"Micro-op cache tag parity error",
229*4882a593Smuzhiyun 	"Micro-op cache data parity error",
230*4882a593Smuzhiyun 	"Instruction buffer parity error",
231*4882a593Smuzhiyun 	"Micro-op queue parity error",
232*4882a593Smuzhiyun 	"Instruction dispatch queue parity error",
233*4882a593Smuzhiyun 	"Fetch address FIFO parity error",
234*4882a593Smuzhiyun 	"Patch RAM data parity error",
235*4882a593Smuzhiyun 	"Patch RAM sequencer parity error",
236*4882a593Smuzhiyun 	"Micro-op buffer parity error",
237*4882a593Smuzhiyun 	"Hardware Assertion MCA Error",
238*4882a593Smuzhiyun };
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun static const char * const smca_ex_mce_desc[] = {
241*4882a593Smuzhiyun 	"Watchdog Timeout error",
242*4882a593Smuzhiyun 	"Physical register file parity error",
243*4882a593Smuzhiyun 	"Flag register file parity error",
244*4882a593Smuzhiyun 	"Immediate displacement register file parity error",
245*4882a593Smuzhiyun 	"Address generator payload parity error",
246*4882a593Smuzhiyun 	"EX payload parity error",
247*4882a593Smuzhiyun 	"Checkpoint queue parity error",
248*4882a593Smuzhiyun 	"Retire dispatch queue parity error",
249*4882a593Smuzhiyun 	"Retire status queue parity error",
250*4882a593Smuzhiyun 	"Scheduling queue parity error",
251*4882a593Smuzhiyun 	"Branch buffer queue parity error",
252*4882a593Smuzhiyun 	"Hardware Assertion error",
253*4882a593Smuzhiyun 	"Spec Map parity error",
254*4882a593Smuzhiyun 	"Retire Map parity error",
255*4882a593Smuzhiyun };
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun static const char * const smca_fp_mce_desc[] = {
258*4882a593Smuzhiyun 	"Physical register file (PRF) parity error",
259*4882a593Smuzhiyun 	"Freelist (FL) parity error",
260*4882a593Smuzhiyun 	"Schedule queue parity error",
261*4882a593Smuzhiyun 	"NSQ parity error",
262*4882a593Smuzhiyun 	"Retire queue (RQ) parity error",
263*4882a593Smuzhiyun 	"Status register file (SRF) parity error",
264*4882a593Smuzhiyun 	"Hardware assertion",
265*4882a593Smuzhiyun };
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun static const char * const smca_l3_mce_desc[] = {
268*4882a593Smuzhiyun 	"Shadow Tag Macro ECC Error",
269*4882a593Smuzhiyun 	"Shadow Tag Macro Multi-way-hit Error",
270*4882a593Smuzhiyun 	"L3M Tag ECC Error",
271*4882a593Smuzhiyun 	"L3M Tag Multi-way-hit Error",
272*4882a593Smuzhiyun 	"L3M Data ECC Error",
273*4882a593Smuzhiyun 	"SDP Parity Error or SystemReadDataError from XI",
274*4882a593Smuzhiyun 	"L3 Victim Queue Parity Error",
275*4882a593Smuzhiyun 	"L3 Hardware Assertion",
276*4882a593Smuzhiyun };
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun static const char * const smca_cs_mce_desc[] = {
279*4882a593Smuzhiyun 	"Illegal Request",
280*4882a593Smuzhiyun 	"Address Violation",
281*4882a593Smuzhiyun 	"Security Violation",
282*4882a593Smuzhiyun 	"Illegal Response",
283*4882a593Smuzhiyun 	"Unexpected Response",
284*4882a593Smuzhiyun 	"Request or Probe Parity Error",
285*4882a593Smuzhiyun 	"Read Response Parity Error",
286*4882a593Smuzhiyun 	"Atomic Request Parity Error",
287*4882a593Smuzhiyun 	"Probe Filter ECC Error",
288*4882a593Smuzhiyun };
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun static const char * const smca_cs2_mce_desc[] = {
291*4882a593Smuzhiyun 	"Illegal Request",
292*4882a593Smuzhiyun 	"Address Violation",
293*4882a593Smuzhiyun 	"Security Violation",
294*4882a593Smuzhiyun 	"Illegal Response",
295*4882a593Smuzhiyun 	"Unexpected Response",
296*4882a593Smuzhiyun 	"Request or Probe Parity Error",
297*4882a593Smuzhiyun 	"Read Response Parity Error",
298*4882a593Smuzhiyun 	"Atomic Request Parity Error",
299*4882a593Smuzhiyun 	"SDP read response had no match in the CS queue",
300*4882a593Smuzhiyun 	"Probe Filter Protocol Error",
301*4882a593Smuzhiyun 	"Probe Filter ECC Error",
302*4882a593Smuzhiyun 	"SDP read response had an unexpected RETRY error",
303*4882a593Smuzhiyun 	"Counter overflow error",
304*4882a593Smuzhiyun 	"Counter underflow error",
305*4882a593Smuzhiyun };
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun static const char * const smca_pie_mce_desc[] = {
308*4882a593Smuzhiyun 	"Hardware Assert",
309*4882a593Smuzhiyun 	"Register security violation",
310*4882a593Smuzhiyun 	"Link Error",
311*4882a593Smuzhiyun 	"Poison data consumption",
312*4882a593Smuzhiyun 	"A deferred error was detected in the DF"
313*4882a593Smuzhiyun };
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun static const char * const smca_umc_mce_desc[] = {
316*4882a593Smuzhiyun 	"DRAM ECC error",
317*4882a593Smuzhiyun 	"Data poison error",
318*4882a593Smuzhiyun 	"SDP parity error",
319*4882a593Smuzhiyun 	"Advanced peripheral bus error",
320*4882a593Smuzhiyun 	"Address/Command parity error",
321*4882a593Smuzhiyun 	"Write data CRC error",
322*4882a593Smuzhiyun 	"DCQ SRAM ECC error",
323*4882a593Smuzhiyun 	"AES SRAM ECC error",
324*4882a593Smuzhiyun };
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun static const char * const smca_pb_mce_desc[] = {
327*4882a593Smuzhiyun 	"An ECC error in the Parameter Block RAM array",
328*4882a593Smuzhiyun };
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun static const char * const smca_psp_mce_desc[] = {
331*4882a593Smuzhiyun 	"An ECC or parity error in a PSP RAM instance",
332*4882a593Smuzhiyun };
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun static const char * const smca_psp2_mce_desc[] = {
335*4882a593Smuzhiyun 	"High SRAM ECC or parity error",
336*4882a593Smuzhiyun 	"Low SRAM ECC or parity error",
337*4882a593Smuzhiyun 	"Instruction Cache Bank 0 ECC or parity error",
338*4882a593Smuzhiyun 	"Instruction Cache Bank 1 ECC or parity error",
339*4882a593Smuzhiyun 	"Instruction Tag Ram 0 parity error",
340*4882a593Smuzhiyun 	"Instruction Tag Ram 1 parity error",
341*4882a593Smuzhiyun 	"Data Cache Bank 0 ECC or parity error",
342*4882a593Smuzhiyun 	"Data Cache Bank 1 ECC or parity error",
343*4882a593Smuzhiyun 	"Data Cache Bank 2 ECC or parity error",
344*4882a593Smuzhiyun 	"Data Cache Bank 3 ECC or parity error",
345*4882a593Smuzhiyun 	"Data Tag Bank 0 parity error",
346*4882a593Smuzhiyun 	"Data Tag Bank 1 parity error",
347*4882a593Smuzhiyun 	"Data Tag Bank 2 parity error",
348*4882a593Smuzhiyun 	"Data Tag Bank 3 parity error",
349*4882a593Smuzhiyun 	"Dirty Data Ram parity error",
350*4882a593Smuzhiyun 	"TLB Bank 0 parity error",
351*4882a593Smuzhiyun 	"TLB Bank 1 parity error",
352*4882a593Smuzhiyun 	"System Hub Read Buffer ECC or parity error",
353*4882a593Smuzhiyun };
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun static const char * const smca_smu_mce_desc[] = {
356*4882a593Smuzhiyun 	"An ECC or parity error in an SMU RAM instance",
357*4882a593Smuzhiyun };
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun static const char * const smca_smu2_mce_desc[] = {
360*4882a593Smuzhiyun 	"High SRAM ECC or parity error",
361*4882a593Smuzhiyun 	"Low SRAM ECC or parity error",
362*4882a593Smuzhiyun 	"Data Cache Bank A ECC or parity error",
363*4882a593Smuzhiyun 	"Data Cache Bank B ECC or parity error",
364*4882a593Smuzhiyun 	"Data Tag Cache Bank A ECC or parity error",
365*4882a593Smuzhiyun 	"Data Tag Cache Bank B ECC or parity error",
366*4882a593Smuzhiyun 	"Instruction Cache Bank A ECC or parity error",
367*4882a593Smuzhiyun 	"Instruction Cache Bank B ECC or parity error",
368*4882a593Smuzhiyun 	"Instruction Tag Cache Bank A ECC or parity error",
369*4882a593Smuzhiyun 	"Instruction Tag Cache Bank B ECC or parity error",
370*4882a593Smuzhiyun 	"System Hub Read Buffer ECC or parity error",
371*4882a593Smuzhiyun 	"PHY RAM ECC error",
372*4882a593Smuzhiyun };
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun static const char * const smca_mp5_mce_desc[] = {
375*4882a593Smuzhiyun 	"High SRAM ECC or parity error",
376*4882a593Smuzhiyun 	"Low SRAM ECC or parity error",
377*4882a593Smuzhiyun 	"Data Cache Bank A ECC or parity error",
378*4882a593Smuzhiyun 	"Data Cache Bank B ECC or parity error",
379*4882a593Smuzhiyun 	"Data Tag Cache Bank A ECC or parity error",
380*4882a593Smuzhiyun 	"Data Tag Cache Bank B ECC or parity error",
381*4882a593Smuzhiyun 	"Instruction Cache Bank A ECC or parity error",
382*4882a593Smuzhiyun 	"Instruction Cache Bank B ECC or parity error",
383*4882a593Smuzhiyun 	"Instruction Tag Cache Bank A ECC or parity error",
384*4882a593Smuzhiyun 	"Instruction Tag Cache Bank B ECC or parity error",
385*4882a593Smuzhiyun };
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun static const char * const smca_nbio_mce_desc[] = {
388*4882a593Smuzhiyun 	"ECC or Parity error",
389*4882a593Smuzhiyun 	"PCIE error",
390*4882a593Smuzhiyun 	"SDP ErrEvent error",
391*4882a593Smuzhiyun 	"SDP Egress Poison Error",
392*4882a593Smuzhiyun 	"IOHC Internal Poison Error",
393*4882a593Smuzhiyun };
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun static const char * const smca_pcie_mce_desc[] = {
396*4882a593Smuzhiyun 	"CCIX PER Message logging",
397*4882a593Smuzhiyun 	"CCIX Read Response with Status: Non-Data Error",
398*4882a593Smuzhiyun 	"CCIX Write Response with Status: Non-Data Error",
399*4882a593Smuzhiyun 	"CCIX Read Response with Status: Data Error",
400*4882a593Smuzhiyun 	"CCIX Non-okay write response with data error",
401*4882a593Smuzhiyun };
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun struct smca_mce_desc {
404*4882a593Smuzhiyun 	const char * const *descs;
405*4882a593Smuzhiyun 	unsigned int num_descs;
406*4882a593Smuzhiyun };
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun static struct smca_mce_desc smca_mce_descs[] = {
409*4882a593Smuzhiyun 	[SMCA_LS]	= { smca_ls_mce_desc,	ARRAY_SIZE(smca_ls_mce_desc)	},
410*4882a593Smuzhiyun 	[SMCA_LS_V2]	= { smca_ls2_mce_desc,	ARRAY_SIZE(smca_ls2_mce_desc)	},
411*4882a593Smuzhiyun 	[SMCA_IF]	= { smca_if_mce_desc,	ARRAY_SIZE(smca_if_mce_desc)	},
412*4882a593Smuzhiyun 	[SMCA_L2_CACHE]	= { smca_l2_mce_desc,	ARRAY_SIZE(smca_l2_mce_desc)	},
413*4882a593Smuzhiyun 	[SMCA_DE]	= { smca_de_mce_desc,	ARRAY_SIZE(smca_de_mce_desc)	},
414*4882a593Smuzhiyun 	[SMCA_EX]	= { smca_ex_mce_desc,	ARRAY_SIZE(smca_ex_mce_desc)	},
415*4882a593Smuzhiyun 	[SMCA_FP]	= { smca_fp_mce_desc,	ARRAY_SIZE(smca_fp_mce_desc)	},
416*4882a593Smuzhiyun 	[SMCA_L3_CACHE]	= { smca_l3_mce_desc,	ARRAY_SIZE(smca_l3_mce_desc)	},
417*4882a593Smuzhiyun 	[SMCA_CS]	= { smca_cs_mce_desc,	ARRAY_SIZE(smca_cs_mce_desc)	},
418*4882a593Smuzhiyun 	[SMCA_CS_V2]	= { smca_cs2_mce_desc,	ARRAY_SIZE(smca_cs2_mce_desc)	},
419*4882a593Smuzhiyun 	[SMCA_PIE]	= { smca_pie_mce_desc,	ARRAY_SIZE(smca_pie_mce_desc)	},
420*4882a593Smuzhiyun 	[SMCA_UMC]	= { smca_umc_mce_desc,	ARRAY_SIZE(smca_umc_mce_desc)	},
421*4882a593Smuzhiyun 	[SMCA_PB]	= { smca_pb_mce_desc,	ARRAY_SIZE(smca_pb_mce_desc)	},
422*4882a593Smuzhiyun 	[SMCA_PSP]	= { smca_psp_mce_desc,	ARRAY_SIZE(smca_psp_mce_desc)	},
423*4882a593Smuzhiyun 	[SMCA_PSP_V2]	= { smca_psp2_mce_desc,	ARRAY_SIZE(smca_psp2_mce_desc)	},
424*4882a593Smuzhiyun 	[SMCA_SMU]	= { smca_smu_mce_desc,	ARRAY_SIZE(smca_smu_mce_desc)	},
425*4882a593Smuzhiyun 	[SMCA_SMU_V2]	= { smca_smu2_mce_desc,	ARRAY_SIZE(smca_smu2_mce_desc)	},
426*4882a593Smuzhiyun 	[SMCA_MP5]	= { smca_mp5_mce_desc,	ARRAY_SIZE(smca_mp5_mce_desc)	},
427*4882a593Smuzhiyun 	[SMCA_NBIO]	= { smca_nbio_mce_desc,	ARRAY_SIZE(smca_nbio_mce_desc)	},
428*4882a593Smuzhiyun 	[SMCA_PCIE]	= { smca_pcie_mce_desc,	ARRAY_SIZE(smca_pcie_mce_desc)	},
429*4882a593Smuzhiyun };
430*4882a593Smuzhiyun 
f12h_mc0_mce(u16 ec,u8 xec)431*4882a593Smuzhiyun static bool f12h_mc0_mce(u16 ec, u8 xec)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun 	bool ret = false;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	if (MEM_ERROR(ec)) {
436*4882a593Smuzhiyun 		u8 ll = LL(ec);
437*4882a593Smuzhiyun 		ret = true;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 		if (ll == LL_L2)
440*4882a593Smuzhiyun 			pr_cont("during L1 linefill from L2.\n");
441*4882a593Smuzhiyun 		else if (ll == LL_L1)
442*4882a593Smuzhiyun 			pr_cont("Data/Tag %s error.\n", R4_MSG(ec));
443*4882a593Smuzhiyun 		else
444*4882a593Smuzhiyun 			ret = false;
445*4882a593Smuzhiyun 	}
446*4882a593Smuzhiyun 	return ret;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun 
f10h_mc0_mce(u16 ec,u8 xec)449*4882a593Smuzhiyun static bool f10h_mc0_mce(u16 ec, u8 xec)
450*4882a593Smuzhiyun {
451*4882a593Smuzhiyun 	if (R4(ec) == R4_GEN && LL(ec) == LL_L1) {
452*4882a593Smuzhiyun 		pr_cont("during data scrub.\n");
453*4882a593Smuzhiyun 		return true;
454*4882a593Smuzhiyun 	}
455*4882a593Smuzhiyun 	return f12h_mc0_mce(ec, xec);
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun 
k8_mc0_mce(u16 ec,u8 xec)458*4882a593Smuzhiyun static bool k8_mc0_mce(u16 ec, u8 xec)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun 	if (BUS_ERROR(ec)) {
461*4882a593Smuzhiyun 		pr_cont("during system linefill.\n");
462*4882a593Smuzhiyun 		return true;
463*4882a593Smuzhiyun 	}
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	return f10h_mc0_mce(ec, xec);
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun 
cat_mc0_mce(u16 ec,u8 xec)468*4882a593Smuzhiyun static bool cat_mc0_mce(u16 ec, u8 xec)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun 	u8 r4	 = R4(ec);
471*4882a593Smuzhiyun 	bool ret = true;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	if (MEM_ERROR(ec)) {
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 		if (TT(ec) != TT_DATA || LL(ec) != LL_L1)
476*4882a593Smuzhiyun 			return false;
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 		switch (r4) {
479*4882a593Smuzhiyun 		case R4_DRD:
480*4882a593Smuzhiyun 		case R4_DWR:
481*4882a593Smuzhiyun 			pr_cont("Data/Tag parity error due to %s.\n",
482*4882a593Smuzhiyun 				(r4 == R4_DRD ? "load/hw prf" : "store"));
483*4882a593Smuzhiyun 			break;
484*4882a593Smuzhiyun 		case R4_EVICT:
485*4882a593Smuzhiyun 			pr_cont("Copyback parity error on a tag miss.\n");
486*4882a593Smuzhiyun 			break;
487*4882a593Smuzhiyun 		case R4_SNOOP:
488*4882a593Smuzhiyun 			pr_cont("Tag parity error during snoop.\n");
489*4882a593Smuzhiyun 			break;
490*4882a593Smuzhiyun 		default:
491*4882a593Smuzhiyun 			ret = false;
492*4882a593Smuzhiyun 		}
493*4882a593Smuzhiyun 	} else if (BUS_ERROR(ec)) {
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 		if ((II(ec) != II_MEM && II(ec) != II_IO) || LL(ec) != LL_LG)
496*4882a593Smuzhiyun 			return false;
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 		pr_cont("System read data error on a ");
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 		switch (r4) {
501*4882a593Smuzhiyun 		case R4_RD:
502*4882a593Smuzhiyun 			pr_cont("TLB reload.\n");
503*4882a593Smuzhiyun 			break;
504*4882a593Smuzhiyun 		case R4_DWR:
505*4882a593Smuzhiyun 			pr_cont("store.\n");
506*4882a593Smuzhiyun 			break;
507*4882a593Smuzhiyun 		case R4_DRD:
508*4882a593Smuzhiyun 			pr_cont("load.\n");
509*4882a593Smuzhiyun 			break;
510*4882a593Smuzhiyun 		default:
511*4882a593Smuzhiyun 			ret = false;
512*4882a593Smuzhiyun 		}
513*4882a593Smuzhiyun 	} else {
514*4882a593Smuzhiyun 		ret = false;
515*4882a593Smuzhiyun 	}
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	return ret;
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun 
f15h_mc0_mce(u16 ec,u8 xec)520*4882a593Smuzhiyun static bool f15h_mc0_mce(u16 ec, u8 xec)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun 	bool ret = true;
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	if (MEM_ERROR(ec)) {
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 		switch (xec) {
527*4882a593Smuzhiyun 		case 0x0:
528*4882a593Smuzhiyun 			pr_cont("Data Array access error.\n");
529*4882a593Smuzhiyun 			break;
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 		case 0x1:
532*4882a593Smuzhiyun 			pr_cont("UC error during a linefill from L2/NB.\n");
533*4882a593Smuzhiyun 			break;
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 		case 0x2:
536*4882a593Smuzhiyun 		case 0x11:
537*4882a593Smuzhiyun 			pr_cont("STQ access error.\n");
538*4882a593Smuzhiyun 			break;
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 		case 0x3:
541*4882a593Smuzhiyun 			pr_cont("SCB access error.\n");
542*4882a593Smuzhiyun 			break;
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 		case 0x10:
545*4882a593Smuzhiyun 			pr_cont("Tag error.\n");
546*4882a593Smuzhiyun 			break;
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 		case 0x12:
549*4882a593Smuzhiyun 			pr_cont("LDQ access error.\n");
550*4882a593Smuzhiyun 			break;
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 		default:
553*4882a593Smuzhiyun 			ret = false;
554*4882a593Smuzhiyun 		}
555*4882a593Smuzhiyun 	} else if (BUS_ERROR(ec)) {
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun 		if (!xec)
558*4882a593Smuzhiyun 			pr_cont("System Read Data Error.\n");
559*4882a593Smuzhiyun 		else
560*4882a593Smuzhiyun 			pr_cont(" Internal error condition type %d.\n", xec);
561*4882a593Smuzhiyun 	} else if (INT_ERROR(ec)) {
562*4882a593Smuzhiyun 		if (xec <= 0x1f)
563*4882a593Smuzhiyun 			pr_cont("Hardware Assert.\n");
564*4882a593Smuzhiyun 		else
565*4882a593Smuzhiyun 			ret = false;
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun 	} else
568*4882a593Smuzhiyun 		ret = false;
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	return ret;
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun 
decode_mc0_mce(struct mce * m)573*4882a593Smuzhiyun static void decode_mc0_mce(struct mce *m)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun 	u16 ec = EC(m->status);
576*4882a593Smuzhiyun 	u8 xec = XEC(m->status, xec_mask);
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	pr_emerg(HW_ERR "MC0 Error: ");
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	/* TLB error signatures are the same across families */
581*4882a593Smuzhiyun 	if (TLB_ERROR(ec)) {
582*4882a593Smuzhiyun 		if (TT(ec) == TT_DATA) {
583*4882a593Smuzhiyun 			pr_cont("%s TLB %s.\n", LL_MSG(ec),
584*4882a593Smuzhiyun 				((xec == 2) ? "locked miss"
585*4882a593Smuzhiyun 					    : (xec ? "multimatch" : "parity")));
586*4882a593Smuzhiyun 			return;
587*4882a593Smuzhiyun 		}
588*4882a593Smuzhiyun 	} else if (fam_ops.mc0_mce(ec, xec))
589*4882a593Smuzhiyun 		;
590*4882a593Smuzhiyun 	else
591*4882a593Smuzhiyun 		pr_emerg(HW_ERR "Corrupted MC0 MCE info?\n");
592*4882a593Smuzhiyun }
593*4882a593Smuzhiyun 
k8_mc1_mce(u16 ec,u8 xec)594*4882a593Smuzhiyun static bool k8_mc1_mce(u16 ec, u8 xec)
595*4882a593Smuzhiyun {
596*4882a593Smuzhiyun 	u8 ll	 = LL(ec);
597*4882a593Smuzhiyun 	bool ret = true;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	if (!MEM_ERROR(ec))
600*4882a593Smuzhiyun 		return false;
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 	if (ll == 0x2)
603*4882a593Smuzhiyun 		pr_cont("during a linefill from L2.\n");
604*4882a593Smuzhiyun 	else if (ll == 0x1) {
605*4882a593Smuzhiyun 		switch (R4(ec)) {
606*4882a593Smuzhiyun 		case R4_IRD:
607*4882a593Smuzhiyun 			pr_cont("Parity error during data load.\n");
608*4882a593Smuzhiyun 			break;
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 		case R4_EVICT:
611*4882a593Smuzhiyun 			pr_cont("Copyback Parity/Victim error.\n");
612*4882a593Smuzhiyun 			break;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 		case R4_SNOOP:
615*4882a593Smuzhiyun 			pr_cont("Tag Snoop error.\n");
616*4882a593Smuzhiyun 			break;
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 		default:
619*4882a593Smuzhiyun 			ret = false;
620*4882a593Smuzhiyun 			break;
621*4882a593Smuzhiyun 		}
622*4882a593Smuzhiyun 	} else
623*4882a593Smuzhiyun 		ret = false;
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	return ret;
626*4882a593Smuzhiyun }
627*4882a593Smuzhiyun 
cat_mc1_mce(u16 ec,u8 xec)628*4882a593Smuzhiyun static bool cat_mc1_mce(u16 ec, u8 xec)
629*4882a593Smuzhiyun {
630*4882a593Smuzhiyun 	u8 r4    = R4(ec);
631*4882a593Smuzhiyun 	bool ret = true;
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun 	if (!MEM_ERROR(ec))
634*4882a593Smuzhiyun 		return false;
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 	if (TT(ec) != TT_INSTR)
637*4882a593Smuzhiyun 		return false;
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun 	if (r4 == R4_IRD)
640*4882a593Smuzhiyun 		pr_cont("Data/tag array parity error for a tag hit.\n");
641*4882a593Smuzhiyun 	else if (r4 == R4_SNOOP)
642*4882a593Smuzhiyun 		pr_cont("Tag error during snoop/victimization.\n");
643*4882a593Smuzhiyun 	else if (xec == 0x0)
644*4882a593Smuzhiyun 		pr_cont("Tag parity error from victim castout.\n");
645*4882a593Smuzhiyun 	else if (xec == 0x2)
646*4882a593Smuzhiyun 		pr_cont("Microcode patch RAM parity error.\n");
647*4882a593Smuzhiyun 	else
648*4882a593Smuzhiyun 		ret = false;
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun 	return ret;
651*4882a593Smuzhiyun }
652*4882a593Smuzhiyun 
f15h_mc1_mce(u16 ec,u8 xec)653*4882a593Smuzhiyun static bool f15h_mc1_mce(u16 ec, u8 xec)
654*4882a593Smuzhiyun {
655*4882a593Smuzhiyun 	bool ret = true;
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	if (!MEM_ERROR(ec))
658*4882a593Smuzhiyun 		return false;
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun 	switch (xec) {
661*4882a593Smuzhiyun 	case 0x0 ... 0xa:
662*4882a593Smuzhiyun 		pr_cont("%s.\n", f15h_mc1_mce_desc[xec]);
663*4882a593Smuzhiyun 		break;
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun 	case 0xd:
666*4882a593Smuzhiyun 		pr_cont("%s.\n", f15h_mc1_mce_desc[xec-2]);
667*4882a593Smuzhiyun 		break;
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun 	case 0x10:
670*4882a593Smuzhiyun 		pr_cont("%s.\n", f15h_mc1_mce_desc[xec-4]);
671*4882a593Smuzhiyun 		break;
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun 	case 0x11 ... 0x15:
674*4882a593Smuzhiyun 		pr_cont("Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]);
675*4882a593Smuzhiyun 		break;
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	default:
678*4882a593Smuzhiyun 		ret = false;
679*4882a593Smuzhiyun 	}
680*4882a593Smuzhiyun 	return ret;
681*4882a593Smuzhiyun }
682*4882a593Smuzhiyun 
decode_mc1_mce(struct mce * m)683*4882a593Smuzhiyun static void decode_mc1_mce(struct mce *m)
684*4882a593Smuzhiyun {
685*4882a593Smuzhiyun 	u16 ec = EC(m->status);
686*4882a593Smuzhiyun 	u8 xec = XEC(m->status, xec_mask);
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	pr_emerg(HW_ERR "MC1 Error: ");
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	if (TLB_ERROR(ec))
691*4882a593Smuzhiyun 		pr_cont("%s TLB %s.\n", LL_MSG(ec),
692*4882a593Smuzhiyun 			(xec ? "multimatch" : "parity error"));
693*4882a593Smuzhiyun 	else if (BUS_ERROR(ec)) {
694*4882a593Smuzhiyun 		bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 		pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
697*4882a593Smuzhiyun 	} else if (INT_ERROR(ec)) {
698*4882a593Smuzhiyun 		if (xec <= 0x3f)
699*4882a593Smuzhiyun 			pr_cont("Hardware Assert.\n");
700*4882a593Smuzhiyun 		else
701*4882a593Smuzhiyun 			goto wrong_mc1_mce;
702*4882a593Smuzhiyun 	} else if (fam_ops.mc1_mce(ec, xec))
703*4882a593Smuzhiyun 		;
704*4882a593Smuzhiyun 	else
705*4882a593Smuzhiyun 		goto wrong_mc1_mce;
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun 	return;
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun wrong_mc1_mce:
710*4882a593Smuzhiyun 	pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n");
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun 
k8_mc2_mce(u16 ec,u8 xec)713*4882a593Smuzhiyun static bool k8_mc2_mce(u16 ec, u8 xec)
714*4882a593Smuzhiyun {
715*4882a593Smuzhiyun 	bool ret = true;
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	if (xec == 0x1)
718*4882a593Smuzhiyun 		pr_cont(" in the write data buffers.\n");
719*4882a593Smuzhiyun 	else if (xec == 0x3)
720*4882a593Smuzhiyun 		pr_cont(" in the victim data buffers.\n");
721*4882a593Smuzhiyun 	else if (xec == 0x2 && MEM_ERROR(ec))
722*4882a593Smuzhiyun 		pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec));
723*4882a593Smuzhiyun 	else if (xec == 0x0) {
724*4882a593Smuzhiyun 		if (TLB_ERROR(ec))
725*4882a593Smuzhiyun 			pr_cont("%s error in a Page Descriptor Cache or Guest TLB.\n",
726*4882a593Smuzhiyun 				TT_MSG(ec));
727*4882a593Smuzhiyun 		else if (BUS_ERROR(ec))
728*4882a593Smuzhiyun 			pr_cont(": %s/ECC error in data read from NB: %s.\n",
729*4882a593Smuzhiyun 				R4_MSG(ec), PP_MSG(ec));
730*4882a593Smuzhiyun 		else if (MEM_ERROR(ec)) {
731*4882a593Smuzhiyun 			u8 r4 = R4(ec);
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 			if (r4 >= 0x7)
734*4882a593Smuzhiyun 				pr_cont(": %s error during data copyback.\n",
735*4882a593Smuzhiyun 					R4_MSG(ec));
736*4882a593Smuzhiyun 			else if (r4 <= 0x1)
737*4882a593Smuzhiyun 				pr_cont(": %s parity/ECC error during data "
738*4882a593Smuzhiyun 					"access from L2.\n", R4_MSG(ec));
739*4882a593Smuzhiyun 			else
740*4882a593Smuzhiyun 				ret = false;
741*4882a593Smuzhiyun 		} else
742*4882a593Smuzhiyun 			ret = false;
743*4882a593Smuzhiyun 	} else
744*4882a593Smuzhiyun 		ret = false;
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun 	return ret;
747*4882a593Smuzhiyun }
748*4882a593Smuzhiyun 
f15h_mc2_mce(u16 ec,u8 xec)749*4882a593Smuzhiyun static bool f15h_mc2_mce(u16 ec, u8 xec)
750*4882a593Smuzhiyun {
751*4882a593Smuzhiyun 	bool ret = true;
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 	if (TLB_ERROR(ec)) {
754*4882a593Smuzhiyun 		if (xec == 0x0)
755*4882a593Smuzhiyun 			pr_cont("Data parity TLB read error.\n");
756*4882a593Smuzhiyun 		else if (xec == 0x1)
757*4882a593Smuzhiyun 			pr_cont("Poison data provided for TLB fill.\n");
758*4882a593Smuzhiyun 		else
759*4882a593Smuzhiyun 			ret = false;
760*4882a593Smuzhiyun 	} else if (BUS_ERROR(ec)) {
761*4882a593Smuzhiyun 		if (xec > 2)
762*4882a593Smuzhiyun 			ret = false;
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun 		pr_cont("Error during attempted NB data read.\n");
765*4882a593Smuzhiyun 	} else if (MEM_ERROR(ec)) {
766*4882a593Smuzhiyun 		switch (xec) {
767*4882a593Smuzhiyun 		case 0x4 ... 0xc:
768*4882a593Smuzhiyun 			pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x4]);
769*4882a593Smuzhiyun 			break;
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun 		case 0x10 ... 0x14:
772*4882a593Smuzhiyun 			pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x7]);
773*4882a593Smuzhiyun 			break;
774*4882a593Smuzhiyun 
775*4882a593Smuzhiyun 		default:
776*4882a593Smuzhiyun 			ret = false;
777*4882a593Smuzhiyun 		}
778*4882a593Smuzhiyun 	} else if (INT_ERROR(ec)) {
779*4882a593Smuzhiyun 		if (xec <= 0x3f)
780*4882a593Smuzhiyun 			pr_cont("Hardware Assert.\n");
781*4882a593Smuzhiyun 		else
782*4882a593Smuzhiyun 			ret = false;
783*4882a593Smuzhiyun 	}
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	return ret;
786*4882a593Smuzhiyun }
787*4882a593Smuzhiyun 
f16h_mc2_mce(u16 ec,u8 xec)788*4882a593Smuzhiyun static bool f16h_mc2_mce(u16 ec, u8 xec)
789*4882a593Smuzhiyun {
790*4882a593Smuzhiyun 	u8 r4 = R4(ec);
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 	if (!MEM_ERROR(ec))
793*4882a593Smuzhiyun 		return false;
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun 	switch (xec) {
796*4882a593Smuzhiyun 	case 0x04 ... 0x05:
797*4882a593Smuzhiyun 		pr_cont("%cBUFF parity error.\n", (r4 == R4_RD) ? 'I' : 'O');
798*4882a593Smuzhiyun 		break;
799*4882a593Smuzhiyun 
800*4882a593Smuzhiyun 	case 0x09 ... 0x0b:
801*4882a593Smuzhiyun 	case 0x0d ... 0x0f:
802*4882a593Smuzhiyun 		pr_cont("ECC error in L2 tag (%s).\n",
803*4882a593Smuzhiyun 			((r4 == R4_GEN)   ? "BankReq" :
804*4882a593Smuzhiyun 			((r4 == R4_SNOOP) ? "Prb"     : "Fill")));
805*4882a593Smuzhiyun 		break;
806*4882a593Smuzhiyun 
807*4882a593Smuzhiyun 	case 0x10 ... 0x19:
808*4882a593Smuzhiyun 	case 0x1b:
809*4882a593Smuzhiyun 		pr_cont("ECC error in L2 data array (%s).\n",
810*4882a593Smuzhiyun 			(((r4 == R4_RD) && !(xec & 0x3)) ? "Hit"  :
811*4882a593Smuzhiyun 			((r4 == R4_GEN)   ? "Attr" :
812*4882a593Smuzhiyun 			((r4 == R4_EVICT) ? "Vict" : "Fill"))));
813*4882a593Smuzhiyun 		break;
814*4882a593Smuzhiyun 
815*4882a593Smuzhiyun 	case 0x1c ... 0x1d:
816*4882a593Smuzhiyun 	case 0x1f:
817*4882a593Smuzhiyun 		pr_cont("Parity error in L2 attribute bits (%s).\n",
818*4882a593Smuzhiyun 			((r4 == R4_RD)  ? "Hit"  :
819*4882a593Smuzhiyun 			((r4 == R4_GEN) ? "Attr" : "Fill")));
820*4882a593Smuzhiyun 		break;
821*4882a593Smuzhiyun 
822*4882a593Smuzhiyun 	default:
823*4882a593Smuzhiyun 		return false;
824*4882a593Smuzhiyun 	}
825*4882a593Smuzhiyun 
826*4882a593Smuzhiyun 	return true;
827*4882a593Smuzhiyun }
828*4882a593Smuzhiyun 
decode_mc2_mce(struct mce * m)829*4882a593Smuzhiyun static void decode_mc2_mce(struct mce *m)
830*4882a593Smuzhiyun {
831*4882a593Smuzhiyun 	u16 ec = EC(m->status);
832*4882a593Smuzhiyun 	u8 xec = XEC(m->status, xec_mask);
833*4882a593Smuzhiyun 
834*4882a593Smuzhiyun 	pr_emerg(HW_ERR "MC2 Error: ");
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun 	if (!fam_ops.mc2_mce(ec, xec))
837*4882a593Smuzhiyun 		pr_cont(HW_ERR "Corrupted MC2 MCE info?\n");
838*4882a593Smuzhiyun }
839*4882a593Smuzhiyun 
decode_mc3_mce(struct mce * m)840*4882a593Smuzhiyun static void decode_mc3_mce(struct mce *m)
841*4882a593Smuzhiyun {
842*4882a593Smuzhiyun 	u16 ec = EC(m->status);
843*4882a593Smuzhiyun 	u8 xec = XEC(m->status, xec_mask);
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun 	if (boot_cpu_data.x86 >= 0x14) {
846*4882a593Smuzhiyun 		pr_emerg("You shouldn't be seeing MC3 MCE on this cpu family,"
847*4882a593Smuzhiyun 			 " please report on LKML.\n");
848*4882a593Smuzhiyun 		return;
849*4882a593Smuzhiyun 	}
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun 	pr_emerg(HW_ERR "MC3 Error");
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 	if (xec == 0x0) {
854*4882a593Smuzhiyun 		u8 r4 = R4(ec);
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 		if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
857*4882a593Smuzhiyun 			goto wrong_mc3_mce;
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun 		pr_cont(" during %s.\n", R4_MSG(ec));
860*4882a593Smuzhiyun 	} else
861*4882a593Smuzhiyun 		goto wrong_mc3_mce;
862*4882a593Smuzhiyun 
863*4882a593Smuzhiyun 	return;
864*4882a593Smuzhiyun 
865*4882a593Smuzhiyun  wrong_mc3_mce:
866*4882a593Smuzhiyun 	pr_emerg(HW_ERR "Corrupted MC3 MCE info?\n");
867*4882a593Smuzhiyun }
868*4882a593Smuzhiyun 
decode_mc4_mce(struct mce * m)869*4882a593Smuzhiyun static void decode_mc4_mce(struct mce *m)
870*4882a593Smuzhiyun {
871*4882a593Smuzhiyun 	unsigned int fam = x86_family(m->cpuid);
872*4882a593Smuzhiyun 	int node_id = amd_get_nb_id(m->extcpu);
873*4882a593Smuzhiyun 	u16 ec = EC(m->status);
874*4882a593Smuzhiyun 	u8 xec = XEC(m->status, 0x1f);
875*4882a593Smuzhiyun 	u8 offset = 0;
876*4882a593Smuzhiyun 
877*4882a593Smuzhiyun 	pr_emerg(HW_ERR "MC4 Error (node %d): ", node_id);
878*4882a593Smuzhiyun 
879*4882a593Smuzhiyun 	switch (xec) {
880*4882a593Smuzhiyun 	case 0x0 ... 0xe:
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun 		/* special handling for DRAM ECCs */
883*4882a593Smuzhiyun 		if (xec == 0x0 || xec == 0x8) {
884*4882a593Smuzhiyun 			/* no ECCs on F11h */
885*4882a593Smuzhiyun 			if (fam == 0x11)
886*4882a593Smuzhiyun 				goto wrong_mc4_mce;
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun 			pr_cont("%s.\n", mc4_mce_desc[xec]);
889*4882a593Smuzhiyun 
890*4882a593Smuzhiyun 			if (decode_dram_ecc)
891*4882a593Smuzhiyun 				decode_dram_ecc(node_id, m);
892*4882a593Smuzhiyun 			return;
893*4882a593Smuzhiyun 		}
894*4882a593Smuzhiyun 		break;
895*4882a593Smuzhiyun 
896*4882a593Smuzhiyun 	case 0xf:
897*4882a593Smuzhiyun 		if (TLB_ERROR(ec))
898*4882a593Smuzhiyun 			pr_cont("GART Table Walk data error.\n");
899*4882a593Smuzhiyun 		else if (BUS_ERROR(ec))
900*4882a593Smuzhiyun 			pr_cont("DMA Exclusion Vector Table Walk error.\n");
901*4882a593Smuzhiyun 		else
902*4882a593Smuzhiyun 			goto wrong_mc4_mce;
903*4882a593Smuzhiyun 		return;
904*4882a593Smuzhiyun 
905*4882a593Smuzhiyun 	case 0x19:
906*4882a593Smuzhiyun 		if (fam == 0x15 || fam == 0x16)
907*4882a593Smuzhiyun 			pr_cont("Compute Unit Data Error.\n");
908*4882a593Smuzhiyun 		else
909*4882a593Smuzhiyun 			goto wrong_mc4_mce;
910*4882a593Smuzhiyun 		return;
911*4882a593Smuzhiyun 
912*4882a593Smuzhiyun 	case 0x1c ... 0x1f:
913*4882a593Smuzhiyun 		offset = 13;
914*4882a593Smuzhiyun 		break;
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun 	default:
917*4882a593Smuzhiyun 		goto wrong_mc4_mce;
918*4882a593Smuzhiyun 	}
919*4882a593Smuzhiyun 
920*4882a593Smuzhiyun 	pr_cont("%s.\n", mc4_mce_desc[xec - offset]);
921*4882a593Smuzhiyun 	return;
922*4882a593Smuzhiyun 
923*4882a593Smuzhiyun  wrong_mc4_mce:
924*4882a593Smuzhiyun 	pr_emerg(HW_ERR "Corrupted MC4 MCE info?\n");
925*4882a593Smuzhiyun }
926*4882a593Smuzhiyun 
decode_mc5_mce(struct mce * m)927*4882a593Smuzhiyun static void decode_mc5_mce(struct mce *m)
928*4882a593Smuzhiyun {
929*4882a593Smuzhiyun 	unsigned int fam = x86_family(m->cpuid);
930*4882a593Smuzhiyun 	u16 ec = EC(m->status);
931*4882a593Smuzhiyun 	u8 xec = XEC(m->status, xec_mask);
932*4882a593Smuzhiyun 
933*4882a593Smuzhiyun 	if (fam == 0xf || fam == 0x11)
934*4882a593Smuzhiyun 		goto wrong_mc5_mce;
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun 	pr_emerg(HW_ERR "MC5 Error: ");
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun 	if (INT_ERROR(ec)) {
939*4882a593Smuzhiyun 		if (xec <= 0x1f) {
940*4882a593Smuzhiyun 			pr_cont("Hardware Assert.\n");
941*4882a593Smuzhiyun 			return;
942*4882a593Smuzhiyun 		} else
943*4882a593Smuzhiyun 			goto wrong_mc5_mce;
944*4882a593Smuzhiyun 	}
945*4882a593Smuzhiyun 
946*4882a593Smuzhiyun 	if (xec == 0x0 || xec == 0xc)
947*4882a593Smuzhiyun 		pr_cont("%s.\n", mc5_mce_desc[xec]);
948*4882a593Smuzhiyun 	else if (xec <= 0xd)
949*4882a593Smuzhiyun 		pr_cont("%s parity error.\n", mc5_mce_desc[xec]);
950*4882a593Smuzhiyun 	else
951*4882a593Smuzhiyun 		goto wrong_mc5_mce;
952*4882a593Smuzhiyun 
953*4882a593Smuzhiyun 	return;
954*4882a593Smuzhiyun 
955*4882a593Smuzhiyun  wrong_mc5_mce:
956*4882a593Smuzhiyun 	pr_emerg(HW_ERR "Corrupted MC5 MCE info?\n");
957*4882a593Smuzhiyun }
958*4882a593Smuzhiyun 
decode_mc6_mce(struct mce * m)959*4882a593Smuzhiyun static void decode_mc6_mce(struct mce *m)
960*4882a593Smuzhiyun {
961*4882a593Smuzhiyun 	u8 xec = XEC(m->status, xec_mask);
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun 	pr_emerg(HW_ERR "MC6 Error: ");
964*4882a593Smuzhiyun 
965*4882a593Smuzhiyun 	if (xec > 0x5)
966*4882a593Smuzhiyun 		goto wrong_mc6_mce;
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun 	pr_cont("%s parity error.\n", mc6_mce_desc[xec]);
969*4882a593Smuzhiyun 	return;
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun  wrong_mc6_mce:
972*4882a593Smuzhiyun 	pr_emerg(HW_ERR "Corrupted MC6 MCE info?\n");
973*4882a593Smuzhiyun }
974*4882a593Smuzhiyun 
975*4882a593Smuzhiyun /* Decode errors according to Scalable MCA specification */
decode_smca_error(struct mce * m)976*4882a593Smuzhiyun static void decode_smca_error(struct mce *m)
977*4882a593Smuzhiyun {
978*4882a593Smuzhiyun 	struct smca_hwid *hwid;
979*4882a593Smuzhiyun 	enum smca_bank_types bank_type;
980*4882a593Smuzhiyun 	const char *ip_name;
981*4882a593Smuzhiyun 	u8 xec = XEC(m->status, xec_mask);
982*4882a593Smuzhiyun 
983*4882a593Smuzhiyun 	if (m->bank >= ARRAY_SIZE(smca_banks))
984*4882a593Smuzhiyun 		return;
985*4882a593Smuzhiyun 
986*4882a593Smuzhiyun 	hwid = smca_banks[m->bank].hwid;
987*4882a593Smuzhiyun 	if (!hwid)
988*4882a593Smuzhiyun 		return;
989*4882a593Smuzhiyun 
990*4882a593Smuzhiyun 	bank_type = hwid->bank_type;
991*4882a593Smuzhiyun 
992*4882a593Smuzhiyun 	if (bank_type == SMCA_RESERVED) {
993*4882a593Smuzhiyun 		pr_emerg(HW_ERR "Bank %d is reserved.\n", m->bank);
994*4882a593Smuzhiyun 		return;
995*4882a593Smuzhiyun 	}
996*4882a593Smuzhiyun 
997*4882a593Smuzhiyun 	ip_name = smca_get_long_name(bank_type);
998*4882a593Smuzhiyun 
999*4882a593Smuzhiyun 	pr_emerg(HW_ERR "%s Ext. Error Code: %d", ip_name, xec);
1000*4882a593Smuzhiyun 
1001*4882a593Smuzhiyun 	/* Only print the decode of valid error codes */
1002*4882a593Smuzhiyun 	if (xec < smca_mce_descs[bank_type].num_descs)
1003*4882a593Smuzhiyun 		pr_cont(", %s.\n", smca_mce_descs[bank_type].descs[xec]);
1004*4882a593Smuzhiyun 
1005*4882a593Smuzhiyun 	if (bank_type == SMCA_UMC && xec == 0 && decode_dram_ecc)
1006*4882a593Smuzhiyun 		decode_dram_ecc(topology_die_id(m->extcpu), m);
1007*4882a593Smuzhiyun }
1008*4882a593Smuzhiyun 
amd_decode_err_code(u16 ec)1009*4882a593Smuzhiyun static inline void amd_decode_err_code(u16 ec)
1010*4882a593Smuzhiyun {
1011*4882a593Smuzhiyun 	if (INT_ERROR(ec)) {
1012*4882a593Smuzhiyun 		pr_emerg(HW_ERR "internal: %s\n", UU_MSG(ec));
1013*4882a593Smuzhiyun 		return;
1014*4882a593Smuzhiyun 	}
1015*4882a593Smuzhiyun 
1016*4882a593Smuzhiyun 	pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec));
1017*4882a593Smuzhiyun 
1018*4882a593Smuzhiyun 	if (BUS_ERROR(ec))
1019*4882a593Smuzhiyun 		pr_cont(", mem/io: %s", II_MSG(ec));
1020*4882a593Smuzhiyun 	else
1021*4882a593Smuzhiyun 		pr_cont(", tx: %s", TT_MSG(ec));
1022*4882a593Smuzhiyun 
1023*4882a593Smuzhiyun 	if (MEM_ERROR(ec) || BUS_ERROR(ec)) {
1024*4882a593Smuzhiyun 		pr_cont(", mem-tx: %s", R4_MSG(ec));
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 		if (BUS_ERROR(ec))
1027*4882a593Smuzhiyun 			pr_cont(", part-proc: %s (%s)", PP_MSG(ec), TO_MSG(ec));
1028*4882a593Smuzhiyun 	}
1029*4882a593Smuzhiyun 
1030*4882a593Smuzhiyun 	pr_cont("\n");
1031*4882a593Smuzhiyun }
1032*4882a593Smuzhiyun 
decode_error_status(struct mce * m)1033*4882a593Smuzhiyun static const char *decode_error_status(struct mce *m)
1034*4882a593Smuzhiyun {
1035*4882a593Smuzhiyun 	if (m->status & MCI_STATUS_UC) {
1036*4882a593Smuzhiyun 		if (m->status & MCI_STATUS_PCC)
1037*4882a593Smuzhiyun 			return "System Fatal error.";
1038*4882a593Smuzhiyun 		if (m->mcgstatus & MCG_STATUS_RIPV)
1039*4882a593Smuzhiyun 			return "Uncorrected, software restartable error.";
1040*4882a593Smuzhiyun 		return "Uncorrected, software containable error.";
1041*4882a593Smuzhiyun 	}
1042*4882a593Smuzhiyun 
1043*4882a593Smuzhiyun 	if (m->status & MCI_STATUS_DEFERRED)
1044*4882a593Smuzhiyun 		return "Deferred error, no action required.";
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun 	return "Corrected error, no action required.";
1047*4882a593Smuzhiyun }
1048*4882a593Smuzhiyun 
1049*4882a593Smuzhiyun static int
amd_decode_mce(struct notifier_block * nb,unsigned long val,void * data)1050*4882a593Smuzhiyun amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
1051*4882a593Smuzhiyun {
1052*4882a593Smuzhiyun 	struct mce *m = (struct mce *)data;
1053*4882a593Smuzhiyun 	unsigned int fam = x86_family(m->cpuid);
1054*4882a593Smuzhiyun 	int ecc;
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun 	if (m->kflags & MCE_HANDLED_CEC)
1057*4882a593Smuzhiyun 		return NOTIFY_DONE;
1058*4882a593Smuzhiyun 
1059*4882a593Smuzhiyun 	pr_emerg(HW_ERR "%s\n", decode_error_status(m));
1060*4882a593Smuzhiyun 
1061*4882a593Smuzhiyun 	pr_emerg(HW_ERR "CPU:%d (%x:%x:%x) MC%d_STATUS[%s|%s|%s|%s|%s",
1062*4882a593Smuzhiyun 		m->extcpu,
1063*4882a593Smuzhiyun 		fam, x86_model(m->cpuid), x86_stepping(m->cpuid),
1064*4882a593Smuzhiyun 		m->bank,
1065*4882a593Smuzhiyun 		((m->status & MCI_STATUS_OVER)	? "Over"  : "-"),
1066*4882a593Smuzhiyun 		((m->status & MCI_STATUS_UC)	? "UE"	  :
1067*4882a593Smuzhiyun 		 (m->status & MCI_STATUS_DEFERRED) ? "-"  : "CE"),
1068*4882a593Smuzhiyun 		((m->status & MCI_STATUS_MISCV)	? "MiscV" : "-"),
1069*4882a593Smuzhiyun 		((m->status & MCI_STATUS_ADDRV)	? "AddrV" : "-"),
1070*4882a593Smuzhiyun 		((m->status & MCI_STATUS_PCC)	? "PCC"	  : "-"));
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	if (boot_cpu_has(X86_FEATURE_SMCA)) {
1073*4882a593Smuzhiyun 		u32 low, high;
1074*4882a593Smuzhiyun 		u32 addr = MSR_AMD64_SMCA_MCx_CONFIG(m->bank);
1075*4882a593Smuzhiyun 
1076*4882a593Smuzhiyun 		if (!rdmsr_safe(addr, &low, &high) &&
1077*4882a593Smuzhiyun 		    (low & MCI_CONFIG_MCAX))
1078*4882a593Smuzhiyun 			pr_cont("|%s", ((m->status & MCI_STATUS_TCC) ? "TCC" : "-"));
1079*4882a593Smuzhiyun 
1080*4882a593Smuzhiyun 		pr_cont("|%s", ((m->status & MCI_STATUS_SYNDV) ? "SyndV" : "-"));
1081*4882a593Smuzhiyun 	}
1082*4882a593Smuzhiyun 
1083*4882a593Smuzhiyun 	/* do the two bits[14:13] together */
1084*4882a593Smuzhiyun 	ecc = (m->status >> 45) & 0x3;
1085*4882a593Smuzhiyun 	if (ecc)
1086*4882a593Smuzhiyun 		pr_cont("|%sECC", ((ecc == 2) ? "C" : "U"));
1087*4882a593Smuzhiyun 
1088*4882a593Smuzhiyun 	if (fam >= 0x15) {
1089*4882a593Smuzhiyun 		pr_cont("|%s", (m->status & MCI_STATUS_DEFERRED ? "Deferred" : "-"));
1090*4882a593Smuzhiyun 
1091*4882a593Smuzhiyun 		/* F15h, bank4, bit 43 is part of McaStatSubCache. */
1092*4882a593Smuzhiyun 		if (fam != 0x15 || m->bank != 4)
1093*4882a593Smuzhiyun 			pr_cont("|%s", (m->status & MCI_STATUS_POISON ? "Poison" : "-"));
1094*4882a593Smuzhiyun 	}
1095*4882a593Smuzhiyun 
1096*4882a593Smuzhiyun 	if (fam >= 0x17)
1097*4882a593Smuzhiyun 		pr_cont("|%s", (m->status & MCI_STATUS_SCRUB ? "Scrub" : "-"));
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun 	pr_cont("]: 0x%016llx\n", m->status);
1100*4882a593Smuzhiyun 
1101*4882a593Smuzhiyun 	if (m->status & MCI_STATUS_ADDRV)
1102*4882a593Smuzhiyun 		pr_emerg(HW_ERR "Error Addr: 0x%016llx\n", m->addr);
1103*4882a593Smuzhiyun 
1104*4882a593Smuzhiyun 	if (m->ppin)
1105*4882a593Smuzhiyun 		pr_emerg(HW_ERR "PPIN: 0x%016llx\n", m->ppin);
1106*4882a593Smuzhiyun 
1107*4882a593Smuzhiyun 	if (boot_cpu_has(X86_FEATURE_SMCA)) {
1108*4882a593Smuzhiyun 		pr_emerg(HW_ERR "IPID: 0x%016llx", m->ipid);
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun 		if (m->status & MCI_STATUS_SYNDV)
1111*4882a593Smuzhiyun 			pr_cont(", Syndrome: 0x%016llx", m->synd);
1112*4882a593Smuzhiyun 
1113*4882a593Smuzhiyun 		pr_cont("\n");
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 		decode_smca_error(m);
1116*4882a593Smuzhiyun 		goto err_code;
1117*4882a593Smuzhiyun 	}
1118*4882a593Smuzhiyun 
1119*4882a593Smuzhiyun 	if (m->tsc)
1120*4882a593Smuzhiyun 		pr_emerg(HW_ERR "TSC: %llu\n", m->tsc);
1121*4882a593Smuzhiyun 
1122*4882a593Smuzhiyun 	/* Doesn't matter which member to test. */
1123*4882a593Smuzhiyun 	if (!fam_ops.mc0_mce)
1124*4882a593Smuzhiyun 		goto err_code;
1125*4882a593Smuzhiyun 
1126*4882a593Smuzhiyun 	switch (m->bank) {
1127*4882a593Smuzhiyun 	case 0:
1128*4882a593Smuzhiyun 		decode_mc0_mce(m);
1129*4882a593Smuzhiyun 		break;
1130*4882a593Smuzhiyun 
1131*4882a593Smuzhiyun 	case 1:
1132*4882a593Smuzhiyun 		decode_mc1_mce(m);
1133*4882a593Smuzhiyun 		break;
1134*4882a593Smuzhiyun 
1135*4882a593Smuzhiyun 	case 2:
1136*4882a593Smuzhiyun 		decode_mc2_mce(m);
1137*4882a593Smuzhiyun 		break;
1138*4882a593Smuzhiyun 
1139*4882a593Smuzhiyun 	case 3:
1140*4882a593Smuzhiyun 		decode_mc3_mce(m);
1141*4882a593Smuzhiyun 		break;
1142*4882a593Smuzhiyun 
1143*4882a593Smuzhiyun 	case 4:
1144*4882a593Smuzhiyun 		decode_mc4_mce(m);
1145*4882a593Smuzhiyun 		break;
1146*4882a593Smuzhiyun 
1147*4882a593Smuzhiyun 	case 5:
1148*4882a593Smuzhiyun 		decode_mc5_mce(m);
1149*4882a593Smuzhiyun 		break;
1150*4882a593Smuzhiyun 
1151*4882a593Smuzhiyun 	case 6:
1152*4882a593Smuzhiyun 		decode_mc6_mce(m);
1153*4882a593Smuzhiyun 		break;
1154*4882a593Smuzhiyun 
1155*4882a593Smuzhiyun 	default:
1156*4882a593Smuzhiyun 		break;
1157*4882a593Smuzhiyun 	}
1158*4882a593Smuzhiyun 
1159*4882a593Smuzhiyun  err_code:
1160*4882a593Smuzhiyun 	amd_decode_err_code(m->status & 0xffff);
1161*4882a593Smuzhiyun 
1162*4882a593Smuzhiyun 	m->kflags |= MCE_HANDLED_EDAC;
1163*4882a593Smuzhiyun 	return NOTIFY_OK;
1164*4882a593Smuzhiyun }
1165*4882a593Smuzhiyun 
1166*4882a593Smuzhiyun static struct notifier_block amd_mce_dec_nb = {
1167*4882a593Smuzhiyun 	.notifier_call	= amd_decode_mce,
1168*4882a593Smuzhiyun 	.priority	= MCE_PRIO_EDAC,
1169*4882a593Smuzhiyun };
1170*4882a593Smuzhiyun 
mce_amd_init(void)1171*4882a593Smuzhiyun static int __init mce_amd_init(void)
1172*4882a593Smuzhiyun {
1173*4882a593Smuzhiyun 	struct cpuinfo_x86 *c = &boot_cpu_data;
1174*4882a593Smuzhiyun 
1175*4882a593Smuzhiyun 	if (c->x86_vendor != X86_VENDOR_AMD &&
1176*4882a593Smuzhiyun 	    c->x86_vendor != X86_VENDOR_HYGON)
1177*4882a593Smuzhiyun 		return -ENODEV;
1178*4882a593Smuzhiyun 
1179*4882a593Smuzhiyun 	if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
1180*4882a593Smuzhiyun 		return -ENODEV;
1181*4882a593Smuzhiyun 
1182*4882a593Smuzhiyun 	if (boot_cpu_has(X86_FEATURE_SMCA)) {
1183*4882a593Smuzhiyun 		xec_mask = 0x3f;
1184*4882a593Smuzhiyun 		goto out;
1185*4882a593Smuzhiyun 	}
1186*4882a593Smuzhiyun 
1187*4882a593Smuzhiyun 	switch (c->x86) {
1188*4882a593Smuzhiyun 	case 0xf:
1189*4882a593Smuzhiyun 		fam_ops.mc0_mce = k8_mc0_mce;
1190*4882a593Smuzhiyun 		fam_ops.mc1_mce = k8_mc1_mce;
1191*4882a593Smuzhiyun 		fam_ops.mc2_mce = k8_mc2_mce;
1192*4882a593Smuzhiyun 		break;
1193*4882a593Smuzhiyun 
1194*4882a593Smuzhiyun 	case 0x10:
1195*4882a593Smuzhiyun 		fam_ops.mc0_mce = f10h_mc0_mce;
1196*4882a593Smuzhiyun 		fam_ops.mc1_mce = k8_mc1_mce;
1197*4882a593Smuzhiyun 		fam_ops.mc2_mce = k8_mc2_mce;
1198*4882a593Smuzhiyun 		break;
1199*4882a593Smuzhiyun 
1200*4882a593Smuzhiyun 	case 0x11:
1201*4882a593Smuzhiyun 		fam_ops.mc0_mce = k8_mc0_mce;
1202*4882a593Smuzhiyun 		fam_ops.mc1_mce = k8_mc1_mce;
1203*4882a593Smuzhiyun 		fam_ops.mc2_mce = k8_mc2_mce;
1204*4882a593Smuzhiyun 		break;
1205*4882a593Smuzhiyun 
1206*4882a593Smuzhiyun 	case 0x12:
1207*4882a593Smuzhiyun 		fam_ops.mc0_mce = f12h_mc0_mce;
1208*4882a593Smuzhiyun 		fam_ops.mc1_mce = k8_mc1_mce;
1209*4882a593Smuzhiyun 		fam_ops.mc2_mce = k8_mc2_mce;
1210*4882a593Smuzhiyun 		break;
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun 	case 0x14:
1213*4882a593Smuzhiyun 		fam_ops.mc0_mce = cat_mc0_mce;
1214*4882a593Smuzhiyun 		fam_ops.mc1_mce = cat_mc1_mce;
1215*4882a593Smuzhiyun 		fam_ops.mc2_mce = k8_mc2_mce;
1216*4882a593Smuzhiyun 		break;
1217*4882a593Smuzhiyun 
1218*4882a593Smuzhiyun 	case 0x15:
1219*4882a593Smuzhiyun 		xec_mask = c->x86_model == 0x60 ? 0x3f : 0x1f;
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun 		fam_ops.mc0_mce = f15h_mc0_mce;
1222*4882a593Smuzhiyun 		fam_ops.mc1_mce = f15h_mc1_mce;
1223*4882a593Smuzhiyun 		fam_ops.mc2_mce = f15h_mc2_mce;
1224*4882a593Smuzhiyun 		break;
1225*4882a593Smuzhiyun 
1226*4882a593Smuzhiyun 	case 0x16:
1227*4882a593Smuzhiyun 		xec_mask = 0x1f;
1228*4882a593Smuzhiyun 		fam_ops.mc0_mce = cat_mc0_mce;
1229*4882a593Smuzhiyun 		fam_ops.mc1_mce = cat_mc1_mce;
1230*4882a593Smuzhiyun 		fam_ops.mc2_mce = f16h_mc2_mce;
1231*4882a593Smuzhiyun 		break;
1232*4882a593Smuzhiyun 
1233*4882a593Smuzhiyun 	case 0x17:
1234*4882a593Smuzhiyun 	case 0x18:
1235*4882a593Smuzhiyun 		pr_warn_once("Decoding supported only on Scalable MCA processors.\n");
1236*4882a593Smuzhiyun 		return -EINVAL;
1237*4882a593Smuzhiyun 
1238*4882a593Smuzhiyun 	default:
1239*4882a593Smuzhiyun 		printk(KERN_WARNING "Huh? What family is it: 0x%x?!\n", c->x86);
1240*4882a593Smuzhiyun 		return -EINVAL;
1241*4882a593Smuzhiyun 	}
1242*4882a593Smuzhiyun 
1243*4882a593Smuzhiyun out:
1244*4882a593Smuzhiyun 	pr_info("MCE: In-kernel MCE decoding enabled.\n");
1245*4882a593Smuzhiyun 
1246*4882a593Smuzhiyun 	mce_register_decode_chain(&amd_mce_dec_nb);
1247*4882a593Smuzhiyun 
1248*4882a593Smuzhiyun 	return 0;
1249*4882a593Smuzhiyun }
1250*4882a593Smuzhiyun early_initcall(mce_amd_init);
1251*4882a593Smuzhiyun 
1252*4882a593Smuzhiyun #ifdef MODULE
mce_amd_exit(void)1253*4882a593Smuzhiyun static void __exit mce_amd_exit(void)
1254*4882a593Smuzhiyun {
1255*4882a593Smuzhiyun 	mce_unregister_decode_chain(&amd_mce_dec_nb);
1256*4882a593Smuzhiyun }
1257*4882a593Smuzhiyun 
1258*4882a593Smuzhiyun MODULE_DESCRIPTION("AMD MCE decoder");
1259*4882a593Smuzhiyun MODULE_ALIAS("edac-mce-amd");
1260*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1261*4882a593Smuzhiyun module_exit(mce_amd_exit);
1262*4882a593Smuzhiyun #endif
1263