xref: /OK3568_Linux_fs/kernel/arch/powerpc/platforms/44x/machine_check.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  */
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/kernel.h>
6*4882a593Smuzhiyun #include <linux/printk.h>
7*4882a593Smuzhiyun #include <linux/ptrace.h>
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <asm/reg.h>
10*4882a593Smuzhiyun #include <asm/cacheflush.h>
11*4882a593Smuzhiyun 
machine_check_440A(struct pt_regs * regs)12*4882a593Smuzhiyun int machine_check_440A(struct pt_regs *regs)
13*4882a593Smuzhiyun {
14*4882a593Smuzhiyun 	unsigned long reason = regs->dsisr;
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun 	printk("Machine check in kernel mode.\n");
17*4882a593Smuzhiyun 	if (reason & ESR_IMCP){
18*4882a593Smuzhiyun 		printk("Instruction Synchronous Machine Check exception\n");
19*4882a593Smuzhiyun 		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
20*4882a593Smuzhiyun 	}
21*4882a593Smuzhiyun 	else {
22*4882a593Smuzhiyun 		u32 mcsr = mfspr(SPRN_MCSR);
23*4882a593Smuzhiyun 		if (mcsr & MCSR_IB)
24*4882a593Smuzhiyun 			printk("Instruction Read PLB Error\n");
25*4882a593Smuzhiyun 		if (mcsr & MCSR_DRB)
26*4882a593Smuzhiyun 			printk("Data Read PLB Error\n");
27*4882a593Smuzhiyun 		if (mcsr & MCSR_DWB)
28*4882a593Smuzhiyun 			printk("Data Write PLB Error\n");
29*4882a593Smuzhiyun 		if (mcsr & MCSR_TLBP)
30*4882a593Smuzhiyun 			printk("TLB Parity Error\n");
31*4882a593Smuzhiyun 		if (mcsr & MCSR_ICP){
32*4882a593Smuzhiyun 			flush_instruction_cache();
33*4882a593Smuzhiyun 			printk("I-Cache Parity Error\n");
34*4882a593Smuzhiyun 		}
35*4882a593Smuzhiyun 		if (mcsr & MCSR_DCSP)
36*4882a593Smuzhiyun 			printk("D-Cache Search Parity Error\n");
37*4882a593Smuzhiyun 		if (mcsr & MCSR_DCFP)
38*4882a593Smuzhiyun 			printk("D-Cache Flush Parity Error\n");
39*4882a593Smuzhiyun 		if (mcsr & MCSR_IMPE)
40*4882a593Smuzhiyun 			printk("Machine Check exception is imprecise\n");
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 		/* Clear MCSR */
43*4882a593Smuzhiyun 		mtspr(SPRN_MCSR, mcsr);
44*4882a593Smuzhiyun 	}
45*4882a593Smuzhiyun 	return 0;
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #ifdef CONFIG_PPC_47x
machine_check_47x(struct pt_regs * regs)49*4882a593Smuzhiyun int machine_check_47x(struct pt_regs *regs)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun 	unsigned long reason = regs->dsisr;
52*4882a593Smuzhiyun 	u32 mcsr;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	printk(KERN_ERR "Machine check in kernel mode.\n");
55*4882a593Smuzhiyun 	if (reason & ESR_IMCP) {
56*4882a593Smuzhiyun 		printk(KERN_ERR "Instruction Synchronous Machine Check exception\n");
57*4882a593Smuzhiyun 		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
58*4882a593Smuzhiyun 		return 0;
59*4882a593Smuzhiyun 	}
60*4882a593Smuzhiyun 	mcsr = mfspr(SPRN_MCSR);
61*4882a593Smuzhiyun 	if (mcsr & MCSR_IB)
62*4882a593Smuzhiyun 		printk(KERN_ERR "Instruction Read PLB Error\n");
63*4882a593Smuzhiyun 	if (mcsr & MCSR_DRB)
64*4882a593Smuzhiyun 		printk(KERN_ERR "Data Read PLB Error\n");
65*4882a593Smuzhiyun 	if (mcsr & MCSR_DWB)
66*4882a593Smuzhiyun 		printk(KERN_ERR "Data Write PLB Error\n");
67*4882a593Smuzhiyun 	if (mcsr & MCSR_TLBP)
68*4882a593Smuzhiyun 		printk(KERN_ERR "TLB Parity Error\n");
69*4882a593Smuzhiyun 	if (mcsr & MCSR_ICP) {
70*4882a593Smuzhiyun 		flush_instruction_cache();
71*4882a593Smuzhiyun 		printk(KERN_ERR "I-Cache Parity Error\n");
72*4882a593Smuzhiyun 	}
73*4882a593Smuzhiyun 	if (mcsr & MCSR_DCSP)
74*4882a593Smuzhiyun 		printk(KERN_ERR "D-Cache Search Parity Error\n");
75*4882a593Smuzhiyun 	if (mcsr & PPC47x_MCSR_GPR)
76*4882a593Smuzhiyun 		printk(KERN_ERR "GPR Parity Error\n");
77*4882a593Smuzhiyun 	if (mcsr & PPC47x_MCSR_FPR)
78*4882a593Smuzhiyun 		printk(KERN_ERR "FPR Parity Error\n");
79*4882a593Smuzhiyun 	if (mcsr & PPC47x_MCSR_IPR)
80*4882a593Smuzhiyun 		printk(KERN_ERR "Machine Check exception is imprecise\n");
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	/* Clear MCSR */
83*4882a593Smuzhiyun 	mtspr(SPRN_MCSR, mcsr);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	return 0;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun #endif /* CONFIG_PPC_47x */
88