blob: 0984c70716953fd8a5a577cbc3d63efcccb555f3 [file] [log] [blame]
Benjamin Herrenschmidtacf7d762006-06-19 20:33:16 +02001#define DEBUG
2
Benjamin Herrenschmidtacf7d762006-06-19 20:33:16 +02003#include <linux/types.h>
4#include <linux/kernel.h>
5#include <linux/smp.h>
6
7#include <asm/reg.h>
8#include <asm/io.h>
9#include <asm/prom.h>
10#include <asm/machdep.h>
11
12#include "ras.h"
13#include "cbe_regs.h"
14
15
16static void dump_fir(int cpu)
17{
18 struct cbe_pmd_regs __iomem *pregs = cbe_get_cpu_pmd_regs(cpu);
19 struct cbe_iic_regs __iomem *iregs = cbe_get_cpu_iic_regs(cpu);
20
21 if (pregs == NULL)
22 return;
23
24 /* Todo: do some nicer parsing of bits and based on them go down
25 * to other sub-units FIRs and not only IIC
26 */
27 printk(KERN_ERR "Global Checkstop FIR : 0x%016lx\n",
28 in_be64(&pregs->checkstop_fir));
29 printk(KERN_ERR "Global Recoverable FIR : 0x%016lx\n",
30 in_be64(&pregs->checkstop_fir));
31 printk(KERN_ERR "Global MachineCheck FIR : 0x%016lx\n",
32 in_be64(&pregs->spec_att_mchk_fir));
33
34 if (iregs == NULL)
35 return;
36 printk(KERN_ERR "IOC FIR : 0x%016lx\n",
37 in_be64(&iregs->ioc_fir));
38
39}
40
41void cbe_system_error_exception(struct pt_regs *regs)
42{
43 int cpu = smp_processor_id();
44
45 printk(KERN_ERR "System Error Interrupt on CPU %d !\n", cpu);
46 dump_fir(cpu);
47 dump_stack();
48}
49
50void cbe_maintenance_exception(struct pt_regs *regs)
51{
52 int cpu = smp_processor_id();
53
54 /*
55 * Nothing implemented for the maintenance interrupt at this point
56 */
57
58 printk(KERN_ERR "Unhandled Maintenance interrupt on CPU %d !\n", cpu);
59 dump_stack();
60}
61
62void cbe_thermal_exception(struct pt_regs *regs)
63{
64 int cpu = smp_processor_id();
65
66 /*
67 * Nothing implemented for the thermal interrupt at this point
68 */
69
70 printk(KERN_ERR "Unhandled Thermal interrupt on CPU %d !\n", cpu);
71 dump_stack();
72}
73
74static int cbe_machine_check_handler(struct pt_regs *regs)
75{
76 int cpu = smp_processor_id();
77
78 printk(KERN_ERR "Machine Check Interrupt on CPU %d !\n", cpu);
79 dump_fir(cpu);
80
81 /* No recovery from this code now, lets continue */
82 return 0;
83}
84
85void __init cbe_ras_init(void)
86{
87 unsigned long hid0;
88
89 /*
90 * Enable System Error & thermal interrupts and wakeup conditions
91 */
92
93 hid0 = mfspr(SPRN_HID0);
94 hid0 |= HID0_CBE_THERM_INT_EN | HID0_CBE_THERM_WAKEUP |
95 HID0_CBE_SYSERR_INT_EN | HID0_CBE_SYSERR_WAKEUP;
96 mtspr(SPRN_HID0, hid0);
97 mb();
98
99 /*
100 * Install machine check handler. Leave setting of precise mode to
101 * what the firmware did for now
102 */
103 ppc_md.machine_check_exception = cbe_machine_check_handler;
104 mb();
105
106 /*
107 * For now, we assume that IOC_FIR is already set to forward some
108 * error conditions to the System Error handler. If that is not true
109 * then it will have to be fixed up here.
110 */
111}