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