aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/ras.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-06-19 14:33:16 -0400
committerPaul Mackerras <paulus@samba.org>2006-06-21 01:01:29 -0400
commitacf7d76827a577059636e949079021e6af6dd702 (patch)
tree283e94488c79e75dd3df9a376e1e8a27a69e26ec /arch/powerpc/platforms/cell/ras.c
parentef82a306b46dbedaecbb154b24d05dfab937df35 (diff)
[POWERPC] cell: add RAS support
This is a first version of support for the Cell BE "Reliability, Availability and Serviceability" features. It doesn't yet handle some of the RAS interrupts (the ones described in iic_is/iic_irr), I'm still working on a proper way to expose these. They are essentially a cascaded controller by themselves (sic !) though I may just handle them locally to the iic driver. I need also to sync with David Erb on the way he hooked in the performance monitor interrupt. So that's all for 2.6.17 and I'll do more work on that with my rework of the powerpc interrupt layer that I'm hacking on at the moment. Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/ras.c')
-rw-r--r--arch/powerpc/platforms/cell/ras.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c
new file mode 100644
index 00000000000..033ad6e2827
--- /dev/null
+++ b/arch/powerpc/platforms/cell/ras.c
@@ -0,0 +1,112 @@
1#define DEBUG
2
3#include <linux/config.h>
4#include <linux/types.h>
5#include <linux/kernel.h>
6#include <linux/smp.h>
7
8#include <asm/reg.h>
9#include <asm/io.h>
10#include <asm/prom.h>
11#include <asm/machdep.h>
12
13#include "ras.h"
14#include "cbe_regs.h"
15
16
17static void dump_fir(int cpu)
18{
19 struct cbe_pmd_regs __iomem *pregs = cbe_get_cpu_pmd_regs(cpu);
20 struct cbe_iic_regs __iomem *iregs = cbe_get_cpu_iic_regs(cpu);
21
22 if (pregs == NULL)
23 return;
24
25 /* Todo: do some nicer parsing of bits and based on them go down
26 * to other sub-units FIRs and not only IIC
27 */
28 printk(KERN_ERR "Global Checkstop FIR : 0x%016lx\n",
29 in_be64(&pregs->checkstop_fir));
30 printk(KERN_ERR "Global Recoverable FIR : 0x%016lx\n",
31 in_be64(&pregs->checkstop_fir));
32 printk(KERN_ERR "Global MachineCheck FIR : 0x%016lx\n",
33 in_be64(&pregs->spec_att_mchk_fir));
34
35 if (iregs == NULL)
36 return;
37 printk(KERN_ERR "IOC FIR : 0x%016lx\n",
38 in_be64(&iregs->ioc_fir));
39
40}
41
42void cbe_system_error_exception(struct pt_regs *regs)
43{
44 int cpu = smp_processor_id();
45
46 printk(KERN_ERR "System Error Interrupt on CPU %d !\n", cpu);
47 dump_fir(cpu);
48 dump_stack();
49}
50
51void cbe_maintenance_exception(struct pt_regs *regs)
52{
53 int cpu = smp_processor_id();
54
55 /*
56 * Nothing implemented for the maintenance interrupt at this point
57 */
58
59 printk(KERN_ERR "Unhandled Maintenance interrupt on CPU %d !\n", cpu);
60 dump_stack();
61}
62
63void cbe_thermal_exception(struct pt_regs *regs)
64{
65 int cpu = smp_processor_id();
66
67 /*
68 * Nothing implemented for the thermal interrupt at this point
69 */
70
71 printk(KERN_ERR "Unhandled Thermal interrupt on CPU %d !\n", cpu);
72 dump_stack();
73}
74
75static int cbe_machine_check_handler(struct pt_regs *regs)
76{
77 int cpu = smp_processor_id();
78
79 printk(KERN_ERR "Machine Check Interrupt on CPU %d !\n", cpu);
80 dump_fir(cpu);
81
82 /* No recovery from this code now, lets continue */
83 return 0;
84}
85
86void __init cbe_ras_init(void)
87{
88 unsigned long hid0;
89
90 /*
91 * Enable System Error & thermal interrupts and wakeup conditions
92 */
93
94 hid0 = mfspr(SPRN_HID0);
95 hid0 |= HID0_CBE_THERM_INT_EN | HID0_CBE_THERM_WAKEUP |
96 HID0_CBE_SYSERR_INT_EN | HID0_CBE_SYSERR_WAKEUP;
97 mtspr(SPRN_HID0, hid0);
98 mb();
99
100 /*
101 * Install machine check handler. Leave setting of precise mode to
102 * what the firmware did for now
103 */
104 ppc_md.machine_check_exception = cbe_machine_check_handler;
105 mb();
106
107 /*
108 * For now, we assume that IOC_FIR is already set to forward some
109 * error conditions to the System Error handler. If that is not true
110 * then it will have to be fixed up here.
111 */
112}