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
12int 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
49int 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 */
88