1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version
5  * 2 of the License, or (at your option) any later version.
6  */
7 
8 #include <linux/kernel.h>
9 #include <linux/printk.h>
10 #include <linux/ptrace.h>
11 
12 #include <asm/reg.h>
13 
14 int machine_check_440A(struct pt_regs *regs)
15 {
16 	unsigned long reason = regs->dsisr;
17 
18 	printk("Machine check in kernel mode.\n");
19 	if (reason & ESR_IMCP){
20 		printk("Instruction Synchronous Machine Check exception\n");
21 		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
22 	}
23 	else {
24 		u32 mcsr = mfspr(SPRN_MCSR);
25 		if (mcsr & MCSR_IB)
26 			printk("Instruction Read PLB Error\n");
27 		if (mcsr & MCSR_DRB)
28 			printk("Data Read PLB Error\n");
29 		if (mcsr & MCSR_DWB)
30 			printk("Data Write PLB Error\n");
31 		if (mcsr & MCSR_TLBP)
32 			printk("TLB Parity Error\n");
33 		if (mcsr & MCSR_ICP){
34 			flush_instruction_cache();
35 			printk("I-Cache Parity Error\n");
36 		}
37 		if (mcsr & MCSR_DCSP)
38 			printk("D-Cache Search Parity Error\n");
39 		if (mcsr & MCSR_DCFP)
40 			printk("D-Cache Flush Parity Error\n");
41 		if (mcsr & MCSR_IMPE)
42 			printk("Machine Check exception is imprecise\n");
43 
44 		/* Clear MCSR */
45 		mtspr(SPRN_MCSR, mcsr);
46 	}
47 	return 0;
48 }
49 
50 #ifdef CONFIG_PPC_47x
51 int machine_check_47x(struct pt_regs *regs)
52 {
53 	unsigned long reason = regs->dsisr;
54 	u32 mcsr;
55 
56 	printk(KERN_ERR "Machine check in kernel mode.\n");
57 	if (reason & ESR_IMCP) {
58 		printk(KERN_ERR "Instruction Synchronous Machine Check exception\n");
59 		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
60 		return 0;
61 	}
62 	mcsr = mfspr(SPRN_MCSR);
63 	if (mcsr & MCSR_IB)
64 		printk(KERN_ERR "Instruction Read PLB Error\n");
65 	if (mcsr & MCSR_DRB)
66 		printk(KERN_ERR "Data Read PLB Error\n");
67 	if (mcsr & MCSR_DWB)
68 		printk(KERN_ERR "Data Write PLB Error\n");
69 	if (mcsr & MCSR_TLBP)
70 		printk(KERN_ERR "TLB Parity Error\n");
71 	if (mcsr & MCSR_ICP) {
72 		flush_instruction_cache();
73 		printk(KERN_ERR "I-Cache Parity Error\n");
74 	}
75 	if (mcsr & MCSR_DCSP)
76 		printk(KERN_ERR "D-Cache Search Parity Error\n");
77 	if (mcsr & PPC47x_MCSR_GPR)
78 		printk(KERN_ERR "GPR Parity Error\n");
79 	if (mcsr & PPC47x_MCSR_FPR)
80 		printk(KERN_ERR "FPR Parity Error\n");
81 	if (mcsr & PPC47x_MCSR_IPR)
82 		printk(KERN_ERR "Machine Check exception is imprecise\n");
83 
84 	/* Clear MCSR */
85 	mtspr(SPRN_MCSR, mcsr);
86 
87 	return 0;
88 }
89 #endif /* CONFIG_PPC_47x */
90