ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / ia64 / kernel / mca.c
1 /*
2  * File:        mca.c
3  * Purpose:     Generic MCA handling layer
4  *
5  * Updated for latest kernel
6  * Copyright (C) 2003 Hewlett-Packard Co
7  *      David Mosberger-Tang <davidm@hpl.hp.com>
8  *
9  * Copyright (C) 2002 Dell Inc.
10  * Copyright (C) Matt Domsch (Matt_Domsch@dell.com)
11  *
12  * Copyright (C) 2002 Intel
13  * Copyright (C) Jenna Hall (jenna.s.hall@intel.com)
14  *
15  * Copyright (C) 2001 Intel
16  * Copyright (C) Fred Lewis (frederick.v.lewis@intel.com)
17  *
18  * Copyright (C) 2000 Intel
19  * Copyright (C) Chuck Fleckenstein (cfleck@co.intel.com)
20  *
21  * Copyright (C) 1999, 2004 Silicon Graphics, Inc.
22  * Copyright (C) Vijay Chander(vijay@engr.sgi.com)
23  *
24  * 03/04/15 D. Mosberger Added INIT backtrace support.
25  * 02/03/25 M. Domsch   GUID cleanups
26  *
27  * 02/01/04 J. Hall     Aligned MCA stack to 16 bytes, added platform vs. CPU
28  *                      error flag, set SAL default return values, changed
29  *                      error record structure to linked list, added init call
30  *                      to sal_get_state_info_size().
31  *
32  * 01/01/03 F. Lewis    Added setup of CMCI and CPEI IRQs, logging of corrected
33  *                      platform errors, completed code for logging of
34  *                      corrected & uncorrected machine check errors, and
35  *                      updated for conformance with Nov. 2000 revision of the
36  *                      SAL 3.0 spec.
37  * 00/03/29 C. Fleckenstein  Fixed PAL/SAL update issues, began MCA bug fixes, logging issues,
38  *                           added min save state dump, added INIT handler.
39  *
40  * 2003-12-08 Keith Owens <kaos@sgi.com>
41  *            smp_call_function() must not be called from interrupt context (can
42  *            deadlock on tasklist_lock).  Use keventd to call smp_call_function().
43  *
44  * 2004-02-01 Keith Owens <kaos@sgi.com>
45  *            Avoid deadlock when using printk() for MCA and INIT records.
46  *            Delete all record printing code, moved to salinfo_decode in user space.
47  *            Mark variables and functions static where possible.
48  *            Delete dead variables and functions.
49  *            Reorder to remove the need for forward declarations and to consolidate
50  *            related code.
51  */
52 #include <linux/config.h>
53 #include <linux/types.h>
54 #include <linux/init.h>
55 #include <linux/sched.h>
56 #include <linux/interrupt.h>
57 #include <linux/irq.h>
58 #include <linux/kallsyms.h>
59 #include <linux/smp_lock.h>
60 #include <linux/bootmem.h>
61 #include <linux/acpi.h>
62 #include <linux/timer.h>
63 #include <linux/module.h>
64 #include <linux/kernel.h>
65 #include <linux/smp.h>
66 #include <linux/workqueue.h>
67
68 #include <asm/delay.h>
69 #include <asm/machvec.h>
70 #include <asm/page.h>
71 #include <asm/ptrace.h>
72 #include <asm/system.h>
73 #include <asm/sal.h>
74 #include <asm/mca.h>
75
76 #include <asm/irq.h>
77 #include <asm/hw_irq.h>
78
79 #if defined(IA64_MCA_DEBUG_INFO)
80 # define IA64_MCA_DEBUG(fmt...) printk(fmt)
81 #else
82 # define IA64_MCA_DEBUG(fmt...)
83 #endif
84
85 typedef struct ia64_fptr {
86         unsigned long fp;
87         unsigned long gp;
88 } ia64_fptr_t;
89
90 /* Used by mca_asm.S */
91 ia64_mca_sal_to_os_state_t      ia64_sal_to_os_handoff_state;
92 ia64_mca_os_to_sal_state_t      ia64_os_to_sal_handoff_state;
93 u64                             ia64_mca_proc_state_dump[512];
94 u64                             ia64_mca_stack[1024] __attribute__((aligned(16)));
95 u64                             ia64_mca_stackframe[32];
96 u64                             ia64_mca_bspstore[1024];
97 u64                             ia64_init_stack[KERNEL_STACK_SIZE/8] __attribute__((aligned(16)));
98 u64                             ia64_mca_serialize;
99
100 /* In mca_asm.S */
101 extern void                     ia64_monarch_init_handler (void);
102 extern void                     ia64_slave_init_handler (void);
103
104 static ia64_mc_info_t           ia64_mc_info;
105
106 struct ia64_mca_tlb_info ia64_mca_tlb_list[NR_CPUS];
107
108 #define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */
109 #define MIN_CPE_POLL_INTERVAL (2*60*HZ)  /* 2 minutes */
110 #define CMC_POLL_INTERVAL     (1*60*HZ)  /* 1 minute */
111 #define CMC_HISTORY_LENGTH    5
112
113 static struct timer_list cpe_poll_timer;
114 static struct timer_list cmc_poll_timer;
115 /*
116  * This variable tells whether we are currently in polling mode.
117  * Start with this in the wrong state so we won't play w/ timers
118  * before the system is ready.
119  */
120 static int cmc_polling_enabled = 1;
121
122 /*
123  * Clearing this variable prevents CPE polling from getting activated
124  * in mca_late_init.  Use it if your system doesn't provide a CPEI,
125  * but encounters problems retrieving CPE logs.  This should only be
126  * necessary for debugging.
127  */
128 static int cpe_poll_enabled = 1;
129
130 extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
131
132 /*
133  * IA64_MCA log support
134  */
135 #define IA64_MAX_LOGS           2       /* Double-buffering for nested MCAs */
136 #define IA64_MAX_LOG_TYPES      4   /* MCA, INIT, CMC, CPE */
137
138 typedef struct ia64_state_log_s
139 {
140         spinlock_t      isl_lock;
141         int             isl_index;
142         unsigned long   isl_count;
143         ia64_err_rec_t  *isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */
144 } ia64_state_log_t;
145
146 static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES];
147
148 #define IA64_LOG_ALLOCATE(it, size) \
149         {ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)] = \
150                 (ia64_err_rec_t *)alloc_bootmem(size); \
151         ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)] = \
152                 (ia64_err_rec_t *)alloc_bootmem(size);}
153 #define IA64_LOG_LOCK_INIT(it) spin_lock_init(&ia64_state_log[it].isl_lock)
154 #define IA64_LOG_LOCK(it)      spin_lock_irqsave(&ia64_state_log[it].isl_lock, s)
155 #define IA64_LOG_UNLOCK(it)    spin_unlock_irqrestore(&ia64_state_log[it].isl_lock,s)
156 #define IA64_LOG_NEXT_INDEX(it)    ia64_state_log[it].isl_index
157 #define IA64_LOG_CURR_INDEX(it)    1 - ia64_state_log[it].isl_index
158 #define IA64_LOG_INDEX_INC(it) \
159     {ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index; \
160     ia64_state_log[it].isl_count++;}
161 #define IA64_LOG_INDEX_DEC(it) \
162     ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index
163 #define IA64_LOG_NEXT_BUFFER(it)   (void *)((ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)]))
164 #define IA64_LOG_CURR_BUFFER(it)   (void *)((ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)]))
165 #define IA64_LOG_COUNT(it)         ia64_state_log[it].isl_count
166
167 /*
168  * ia64_log_init
169  *      Reset the OS ia64 log buffer
170  * Inputs   :   info_type   (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE})
171  * Outputs      :       None
172  */
173 static void
174 ia64_log_init(int sal_info_type)
175 {
176         u64     max_size = 0;
177
178         IA64_LOG_NEXT_INDEX(sal_info_type) = 0;
179         IA64_LOG_LOCK_INIT(sal_info_type);
180
181         // SAL will tell us the maximum size of any error record of this type
182         max_size = ia64_sal_get_state_info_size(sal_info_type);
183         if (!max_size)
184                 /* alloc_bootmem() doesn't like zero-sized allocations! */
185                 return;
186
187         // set up OS data structures to hold error info
188         IA64_LOG_ALLOCATE(sal_info_type, max_size);
189         memset(IA64_LOG_CURR_BUFFER(sal_info_type), 0, max_size);
190         memset(IA64_LOG_NEXT_BUFFER(sal_info_type), 0, max_size);
191 }
192
193 /*
194  * ia64_log_get
195  *
196  *      Get the current MCA log from SAL and copy it into the OS log buffer.
197  *
198  *  Inputs  :   info_type   (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE})
199  *              irq_safe    whether you can use printk at this point
200  *  Outputs :   size        (total record length)
201  *              *buffer     (ptr to error record)
202  *
203  */
204 static u64
205 ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe)
206 {
207         sal_log_record_header_t     *log_buffer;
208         u64                         total_len = 0;
209         int                         s;
210
211         IA64_LOG_LOCK(sal_info_type);
212
213         /* Get the process state information */
214         log_buffer = IA64_LOG_NEXT_BUFFER(sal_info_type);
215
216         total_len = ia64_sal_get_state_info(sal_info_type, (u64 *)log_buffer);
217
218         if (total_len) {
219                 IA64_LOG_INDEX_INC(sal_info_type);
220                 IA64_LOG_UNLOCK(sal_info_type);
221                 if (irq_safe) {
222                         IA64_MCA_DEBUG("%s: SAL error record type %d retrieved. "
223                                        "Record length = %ld\n", __FUNCTION__, sal_info_type, total_len);
224                 }
225                 *buffer = (u8 *) log_buffer;
226                 return total_len;
227         } else {
228                 IA64_LOG_UNLOCK(sal_info_type);
229                 return 0;
230         }
231 }
232
233 /*
234  *  ia64_mca_log_sal_error_record
235  *
236  *  This function retrieves a specified error record type from SAL
237  *  and wakes up any processes waiting for error records.
238  *
239  *  Inputs  :   sal_info_type   (Type of error record MCA/CMC/CPE/INIT)
240  */
241 static void
242 ia64_mca_log_sal_error_record(int sal_info_type)
243 {
244         u8 *buffer;
245         u64 size;
246         int irq_safe = sal_info_type != SAL_INFO_TYPE_MCA && sal_info_type != SAL_INFO_TYPE_INIT;
247         static const char * const rec_name[] = { "MCA", "INIT", "CMC", "CPE" };
248
249         size = ia64_log_get(sal_info_type, &buffer, irq_safe);
250         if (!size)
251                 return;
252
253         salinfo_log_wakeup(sal_info_type, buffer, size, irq_safe);
254
255         if (irq_safe)
256                 printk(KERN_INFO "CPU %d: SAL log contains %s error record\n",
257                         smp_processor_id(),
258                         sal_info_type < ARRAY_SIZE(rec_name) ? rec_name[sal_info_type] : "UNKNOWN");
259
260         /* Clear logs from corrected errors in case there's no user-level logger */
261         if (sal_info_type == SAL_INFO_TYPE_CPE || sal_info_type == SAL_INFO_TYPE_CMC)
262                 ia64_sal_clear_state_info(sal_info_type);
263 }
264
265 /*
266  * platform dependent error handling
267  */
268 #ifndef PLATFORM_MCA_HANDLERS
269
270 static irqreturn_t
271 ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
272 {
273         IA64_MCA_DEBUG("%s: received interrupt. CPU:%d vector = %#x\n",
274                        __FUNCTION__, smp_processor_id(), cpe_irq);
275
276         /* SAL spec states this should run w/ interrupts enabled */
277         local_irq_enable();
278
279         /* Get the CMC error record and log it */
280         ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE);
281         return IRQ_HANDLED;
282 }
283
284 static void
285 show_min_state (pal_min_state_area_t *minstate)
286 {
287         u64 iip = minstate->pmsa_iip + ((struct ia64_psr *)(&minstate->pmsa_ipsr))->ri;
288         u64 xip = minstate->pmsa_xip + ((struct ia64_psr *)(&minstate->pmsa_xpsr))->ri;
289
290         printk("NaT bits\t%016lx\n", minstate->pmsa_nat_bits);
291         printk("pr\t\t%016lx\n", minstate->pmsa_pr);
292         printk("b0\t\t%016lx ", minstate->pmsa_br0); print_symbol("%s\n", minstate->pmsa_br0);
293         printk("ar.rsc\t\t%016lx\n", minstate->pmsa_rsc);
294         printk("cr.iip\t\t%016lx ", iip); print_symbol("%s\n", iip);
295         printk("cr.ipsr\t\t%016lx\n", minstate->pmsa_ipsr);
296         printk("cr.ifs\t\t%016lx\n", minstate->pmsa_ifs);
297         printk("xip\t\t%016lx ", xip); print_symbol("%s\n", xip);
298         printk("xpsr\t\t%016lx\n", minstate->pmsa_xpsr);
299         printk("xfs\t\t%016lx\n", minstate->pmsa_xfs);
300         printk("b1\t\t%016lx ", minstate->pmsa_br1);
301         print_symbol("%s\n", minstate->pmsa_br1);
302
303         printk("\nstatic registers r0-r15:\n");
304         printk(" r0- 3 %016lx %016lx %016lx %016lx\n",
305                0UL, minstate->pmsa_gr[0], minstate->pmsa_gr[1], minstate->pmsa_gr[2]);
306         printk(" r4- 7 %016lx %016lx %016lx %016lx\n",
307                minstate->pmsa_gr[3], minstate->pmsa_gr[4],
308                minstate->pmsa_gr[5], minstate->pmsa_gr[6]);
309         printk(" r8-11 %016lx %016lx %016lx %016lx\n",
310                minstate->pmsa_gr[7], minstate->pmsa_gr[8],
311                minstate->pmsa_gr[9], minstate->pmsa_gr[10]);
312         printk("r12-15 %016lx %016lx %016lx %016lx\n",
313                minstate->pmsa_gr[11], minstate->pmsa_gr[12],
314                minstate->pmsa_gr[13], minstate->pmsa_gr[14]);
315
316         printk("\nbank 0:\n");
317         printk("r16-19 %016lx %016lx %016lx %016lx\n",
318                minstate->pmsa_bank0_gr[0], minstate->pmsa_bank0_gr[1],
319                minstate->pmsa_bank0_gr[2], minstate->pmsa_bank0_gr[3]);
320         printk("r20-23 %016lx %016lx %016lx %016lx\n",
321                minstate->pmsa_bank0_gr[4], minstate->pmsa_bank0_gr[5],
322                minstate->pmsa_bank0_gr[6], minstate->pmsa_bank0_gr[7]);
323         printk("r24-27 %016lx %016lx %016lx %016lx\n",
324                minstate->pmsa_bank0_gr[8], minstate->pmsa_bank0_gr[9],
325                minstate->pmsa_bank0_gr[10], minstate->pmsa_bank0_gr[11]);
326         printk("r28-31 %016lx %016lx %016lx %016lx\n",
327                minstate->pmsa_bank0_gr[12], minstate->pmsa_bank0_gr[13],
328                minstate->pmsa_bank0_gr[14], minstate->pmsa_bank0_gr[15]);
329
330         printk("\nbank 1:\n");
331         printk("r16-19 %016lx %016lx %016lx %016lx\n",
332                minstate->pmsa_bank1_gr[0], minstate->pmsa_bank1_gr[1],
333                minstate->pmsa_bank1_gr[2], minstate->pmsa_bank1_gr[3]);
334         printk("r20-23 %016lx %016lx %016lx %016lx\n",
335                minstate->pmsa_bank1_gr[4], minstate->pmsa_bank1_gr[5],
336                minstate->pmsa_bank1_gr[6], minstate->pmsa_bank1_gr[7]);
337         printk("r24-27 %016lx %016lx %016lx %016lx\n",
338                minstate->pmsa_bank1_gr[8], minstate->pmsa_bank1_gr[9],
339                minstate->pmsa_bank1_gr[10], minstate->pmsa_bank1_gr[11]);
340         printk("r28-31 %016lx %016lx %016lx %016lx\n",
341                minstate->pmsa_bank1_gr[12], minstate->pmsa_bank1_gr[13],
342                minstate->pmsa_bank1_gr[14], minstate->pmsa_bank1_gr[15]);
343 }
344
345 static void
346 fetch_min_state (pal_min_state_area_t *ms, struct pt_regs *pt, struct switch_stack *sw)
347 {
348         u64 *dst_banked, *src_banked, bit, shift, nat_bits;
349         int i;
350
351         /*
352          * First, update the pt-regs and switch-stack structures with the contents stored
353          * in the min-state area:
354          */
355         if (((struct ia64_psr *) &ms->pmsa_ipsr)->ic == 0) {
356                 pt->cr_ipsr = ms->pmsa_xpsr;
357                 pt->cr_iip = ms->pmsa_xip;
358                 pt->cr_ifs = ms->pmsa_xfs;
359         } else {
360                 pt->cr_ipsr = ms->pmsa_ipsr;
361                 pt->cr_iip = ms->pmsa_iip;
362                 pt->cr_ifs = ms->pmsa_ifs;
363         }
364         pt->ar_rsc = ms->pmsa_rsc;
365         pt->pr = ms->pmsa_pr;
366         pt->r1 = ms->pmsa_gr[0];
367         pt->r2 = ms->pmsa_gr[1];
368         pt->r3 = ms->pmsa_gr[2];
369         sw->r4 = ms->pmsa_gr[3];
370         sw->r5 = ms->pmsa_gr[4];
371         sw->r6 = ms->pmsa_gr[5];
372         sw->r7 = ms->pmsa_gr[6];
373         pt->r8 = ms->pmsa_gr[7];
374         pt->r9 = ms->pmsa_gr[8];
375         pt->r10 = ms->pmsa_gr[9];
376         pt->r11 = ms->pmsa_gr[10];
377         pt->r12 = ms->pmsa_gr[11];
378         pt->r13 = ms->pmsa_gr[12];
379         pt->r14 = ms->pmsa_gr[13];
380         pt->r15 = ms->pmsa_gr[14];
381         dst_banked = &pt->r16;          /* r16-r31 are contiguous in struct pt_regs */
382         src_banked = ms->pmsa_bank1_gr;
383         for (i = 0; i < 16; ++i)
384                 dst_banked[i] = src_banked[i];
385         pt->b0 = ms->pmsa_br0;
386         sw->b1 = ms->pmsa_br1;
387
388         /* construct the NaT bits for the pt-regs structure: */
389 #       define PUT_NAT_BIT(dst, addr)                                   \
390         do {                                                            \
391                 bit = nat_bits & 1; nat_bits >>= 1;                     \
392                 shift = ((unsigned long) addr >> 3) & 0x3f;             \
393                 dst = ((dst) & ~(1UL << shift)) | (bit << shift);       \
394         } while (0)
395
396         /* Rotate the saved NaT bits such that bit 0 corresponds to pmsa_gr[0]: */
397         shift = ((unsigned long) &ms->pmsa_gr[0] >> 3) & 0x3f;
398         nat_bits = (ms->pmsa_nat_bits >> shift) | (ms->pmsa_nat_bits << (64 - shift));
399
400         PUT_NAT_BIT(sw->caller_unat, &pt->r1);
401         PUT_NAT_BIT(sw->caller_unat, &pt->r2);
402         PUT_NAT_BIT(sw->caller_unat, &pt->r3);
403         PUT_NAT_BIT(sw->ar_unat, &sw->r4);
404         PUT_NAT_BIT(sw->ar_unat, &sw->r5);
405         PUT_NAT_BIT(sw->ar_unat, &sw->r6);
406         PUT_NAT_BIT(sw->ar_unat, &sw->r7);
407         PUT_NAT_BIT(sw->caller_unat, &pt->r8);  PUT_NAT_BIT(sw->caller_unat, &pt->r9);
408         PUT_NAT_BIT(sw->caller_unat, &pt->r10); PUT_NAT_BIT(sw->caller_unat, &pt->r11);
409         PUT_NAT_BIT(sw->caller_unat, &pt->r12); PUT_NAT_BIT(sw->caller_unat, &pt->r13);
410         PUT_NAT_BIT(sw->caller_unat, &pt->r14); PUT_NAT_BIT(sw->caller_unat, &pt->r15);
411         nat_bits >>= 16;        /* skip over bank0 NaT bits */
412         PUT_NAT_BIT(sw->caller_unat, &pt->r16); PUT_NAT_BIT(sw->caller_unat, &pt->r17);
413         PUT_NAT_BIT(sw->caller_unat, &pt->r18); PUT_NAT_BIT(sw->caller_unat, &pt->r19);
414         PUT_NAT_BIT(sw->caller_unat, &pt->r20); PUT_NAT_BIT(sw->caller_unat, &pt->r21);
415         PUT_NAT_BIT(sw->caller_unat, &pt->r22); PUT_NAT_BIT(sw->caller_unat, &pt->r23);
416         PUT_NAT_BIT(sw->caller_unat, &pt->r24); PUT_NAT_BIT(sw->caller_unat, &pt->r25);
417         PUT_NAT_BIT(sw->caller_unat, &pt->r26); PUT_NAT_BIT(sw->caller_unat, &pt->r27);
418         PUT_NAT_BIT(sw->caller_unat, &pt->r28); PUT_NAT_BIT(sw->caller_unat, &pt->r29);
419         PUT_NAT_BIT(sw->caller_unat, &pt->r30); PUT_NAT_BIT(sw->caller_unat, &pt->r31);
420 }
421
422 static void
423 init_handler_platform (pal_min_state_area_t *ms,
424                        struct pt_regs *pt, struct switch_stack *sw)
425 {
426         struct unw_frame_info info;
427
428         /* if a kernel debugger is available call it here else just dump the registers */
429
430         /*
431          * Wait for a bit.  On some machines (e.g., HP's zx2000 and zx6000, INIT can be
432          * generated via the BMC's command-line interface, but since the console is on the
433          * same serial line, the user will need some time to switch out of the BMC before
434          * the dump begins.
435          */
436         printk("Delaying for 5 seconds...\n");
437         udelay(5*1000000);
438         show_min_state(ms);
439
440         printk("Backtrace of current task (pid %d, %s)\n", current->pid, current->comm);
441         fetch_min_state(ms, pt, sw);
442         unw_init_from_interruption(&info, current, pt, sw);
443         ia64_do_show_stack(&info, NULL);
444
445 #ifdef CONFIG_SMP
446         /* read_trylock() would be handy... */
447         if (!tasklist_lock.write_lock)
448                 read_lock(&tasklist_lock);
449 #endif
450         {
451                 struct task_struct *g, *t;
452                 do_each_thread (g, t) {
453                         if (t == current)
454                                 continue;
455
456                         printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
457                         show_stack(t, NULL);
458                 } while_each_thread (g, t);
459         }
460 #ifdef CONFIG_SMP
461         if (!tasklist_lock.write_lock)
462                 read_unlock(&tasklist_lock);
463 #endif
464
465         printk("\nINIT dump complete.  Please reboot now.\n");
466         while (1);                      /* hang city if no debugger */
467 }
468
469 #ifdef CONFIG_ACPI
470 /*
471  * ia64_mca_register_cpev
472  *
473  *  Register the corrected platform error vector with SAL.
474  *
475  *  Inputs
476  *      cpev        Corrected Platform Error Vector number
477  *
478  *  Outputs
479  *      None
480  */
481 static void
482 ia64_mca_register_cpev (int cpev)
483 {
484         /* Register the CPE interrupt vector with SAL */
485         struct ia64_sal_retval isrv;
486
487         isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0);
488         if (isrv.status) {
489                 printk(KERN_ERR "Failed to register Corrected Platform "
490                        "Error interrupt vector with SAL (status %ld)\n", isrv.status);
491                 return;
492         }
493
494         IA64_MCA_DEBUG("%s: corrected platform error "
495                        "vector %#x setup and enabled\n", __FUNCTION__, cpev);
496 }
497 #endif /* CONFIG_ACPI */
498
499 #endif /* PLATFORM_MCA_HANDLERS */
500
501 /*
502  * ia64_mca_cmc_vector_setup
503  *
504  *  Setup the corrected machine check vector register in the processor and
505  *  unmask interrupt.  This function is invoked on a per-processor basis.
506  *
507  * Inputs
508  *      None
509  *
510  * Outputs
511  *      None
512  */
513 void
514 ia64_mca_cmc_vector_setup (void)
515 {
516         cmcv_reg_t      cmcv;
517
518         cmcv.cmcv_regval        = 0;
519         cmcv.cmcv_mask          = 0;        /* Unmask/enable interrupt */
520         cmcv.cmcv_vector        = IA64_CMC_VECTOR;
521         ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval);
522
523         IA64_MCA_DEBUG("%s: CPU %d corrected "
524                        "machine check vector %#x setup and enabled.\n",
525                        __FUNCTION__, smp_processor_id(), IA64_CMC_VECTOR);
526
527         IA64_MCA_DEBUG("%s: CPU %d CMCV = %#016lx\n",
528                        __FUNCTION__, smp_processor_id(), ia64_getreg(_IA64_REG_CR_CMCV));
529 }
530
531 /*
532  * ia64_mca_cmc_vector_disable
533  *
534  *  Mask the corrected machine check vector register in the processor.
535  *  This function is invoked on a per-processor basis.
536  *
537  * Inputs
538  *      dummy(unused)
539  *
540  * Outputs
541  *      None
542  */
543 static void
544 ia64_mca_cmc_vector_disable (void *dummy)
545 {
546         cmcv_reg_t      cmcv;
547
548         cmcv = (cmcv_reg_t)ia64_getreg(_IA64_REG_CR_CMCV);
549
550         cmcv.cmcv_mask = 1; /* Mask/disable interrupt */
551         ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval)
552
553         IA64_MCA_DEBUG("%s: CPU %d corrected "
554                        "machine check vector %#x disabled.\n",
555                        __FUNCTION__, smp_processor_id(), cmcv.cmcv_vector);
556 }
557
558 /*
559  * ia64_mca_cmc_vector_enable
560  *
561  *  Unmask the corrected machine check vector register in the processor.
562  *  This function is invoked on a per-processor basis.
563  *
564  * Inputs
565  *      dummy(unused)
566  *
567  * Outputs
568  *      None
569  */
570 static void
571 ia64_mca_cmc_vector_enable (void *dummy)
572 {
573         cmcv_reg_t      cmcv;
574
575         cmcv = (cmcv_reg_t)ia64_getreg(_IA64_REG_CR_CMCV);
576
577         cmcv.cmcv_mask = 0; /* Unmask/enable interrupt */
578         ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval)
579
580         IA64_MCA_DEBUG("%s: CPU %d corrected "
581                        "machine check vector %#x enabled.\n",
582                        __FUNCTION__, smp_processor_id(), cmcv.cmcv_vector);
583 }
584
585 /*
586  * ia64_mca_cmc_vector_disable_keventd
587  *
588  * Called via keventd (smp_call_function() is not safe in interrupt context) to
589  * disable the cmc interrupt vector.
590  */
591 static void
592 ia64_mca_cmc_vector_disable_keventd(void *unused)
593 {
594         on_each_cpu(ia64_mca_cmc_vector_disable, NULL, 1, 0);
595 }
596
597 /*
598  * ia64_mca_cmc_vector_enable_keventd
599  *
600  * Called via keventd (smp_call_function() is not safe in interrupt context) to
601  * enable the cmc interrupt vector.
602  */
603 static void
604 ia64_mca_cmc_vector_enable_keventd(void *unused)
605 {
606         on_each_cpu(ia64_mca_cmc_vector_enable, NULL, 1, 0);
607 }
608
609 /*
610  * ia64_mca_wakeup_ipi_wait
611  *
612  *      Wait for the inter-cpu interrupt to be sent by the
613  *      monarch processor once it is done with handling the
614  *      MCA.
615  *
616  *  Inputs  :   None
617  *  Outputs :   None
618  */
619 static void
620 ia64_mca_wakeup_ipi_wait(void)
621 {
622         int     irr_num = (IA64_MCA_WAKEUP_VECTOR >> 6);
623         int     irr_bit = (IA64_MCA_WAKEUP_VECTOR & 0x3f);
624         u64     irr = 0;
625
626         do {
627                 switch(irr_num) {
628                       case 0:
629                         irr = ia64_getreg(_IA64_REG_CR_IRR0);
630                         break;
631                       case 1:
632                         irr = ia64_getreg(_IA64_REG_CR_IRR1);
633                         break;
634                       case 2:
635                         irr = ia64_getreg(_IA64_REG_CR_IRR2);
636                         break;
637                       case 3:
638                         irr = ia64_getreg(_IA64_REG_CR_IRR3);
639                         break;
640                 }
641         } while (!(irr & (1UL << irr_bit))) ;
642 }
643
644 /*
645  * ia64_mca_wakeup
646  *
647  *      Send an inter-cpu interrupt to wake-up a particular cpu
648  *      and mark that cpu to be out of rendez.
649  *
650  *  Inputs  :   cpuid
651  *  Outputs :   None
652  */
653 static void
654 ia64_mca_wakeup(int cpu)
655 {
656         platform_send_ipi(cpu, IA64_MCA_WAKEUP_VECTOR, IA64_IPI_DM_INT, 0);
657         ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
658
659 }
660
661 /*
662  * ia64_mca_wakeup_all
663  *
664  *      Wakeup all the cpus which have rendez'ed previously.
665  *
666  *  Inputs  :   None
667  *  Outputs :   None
668  */
669 static void
670 ia64_mca_wakeup_all(void)
671 {
672         int cpu;
673
674         /* Clear the Rendez checkin flag for all cpus */
675         for(cpu = 0; cpu < NR_CPUS; cpu++) {
676                 if (!cpu_online(cpu))
677                         continue;
678                 if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE)
679                         ia64_mca_wakeup(cpu);
680         }
681
682 }
683
684 /*
685  * ia64_mca_rendez_interrupt_handler
686  *
687  *      This is handler used to put slave processors into spinloop
688  *      while the monarch processor does the mca handling and later
689  *      wake each slave up once the monarch is done.
690  *
691  *  Inputs  :   None
692  *  Outputs :   None
693  */
694 static irqreturn_t
695 ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
696 {
697         unsigned long flags;
698         int cpu = smp_processor_id();
699
700         /* Mask all interrupts */
701         local_irq_save(flags);
702
703         ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
704         /* Register with the SAL monarch that the slave has
705          * reached SAL
706          */
707         ia64_sal_mc_rendez();
708
709         /* Wait for the wakeup IPI from the monarch
710          * This waiting is done by polling on the wakeup-interrupt
711          * vector bit in the processor's IRRs
712          */
713         ia64_mca_wakeup_ipi_wait();
714
715         /* Enable all interrupts */
716         local_irq_restore(flags);
717         return IRQ_HANDLED;
718 }
719
720 /*
721  * ia64_mca_wakeup_int_handler
722  *
723  *      The interrupt handler for processing the inter-cpu interrupt to the
724  *      slave cpu which was spinning in the rendez loop.
725  *      Since this spinning is done by turning off the interrupts and
726  *      polling on the wakeup-interrupt bit in the IRR, there is
727  *      nothing useful to be done in the handler.
728  *
729  *  Inputs  :   wakeup_irq  (Wakeup-interrupt bit)
730  *      arg             (Interrupt handler specific argument)
731  *      ptregs          (Exception frame at the time of the interrupt)
732  *  Outputs :   None
733  *
734  */
735 static irqreturn_t
736 ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg, struct pt_regs *ptregs)
737 {
738         return IRQ_HANDLED;
739 }
740
741 /*
742  * ia64_return_to_sal_check
743  *
744  *      This is function called before going back from the OS_MCA handler
745  *      to the OS_MCA dispatch code which finally takes the control back
746  *      to the SAL.
747  *      The main purpose of this routine is to setup the OS_MCA to SAL
748  *      return state which can be used by the OS_MCA dispatch code
749  *      just before going back to SAL.
750  *
751  *  Inputs  :   None
752  *  Outputs :   None
753  */
754
755 static void
756 ia64_return_to_sal_check(int recover)
757 {
758
759         /* Copy over some relevant stuff from the sal_to_os_mca_handoff
760          * so that it can be used at the time of os_mca_to_sal_handoff
761          */
762         ia64_os_to_sal_handoff_state.imots_sal_gp =
763                 ia64_sal_to_os_handoff_state.imsto_sal_gp;
764
765         ia64_os_to_sal_handoff_state.imots_sal_check_ra =
766                 ia64_sal_to_os_handoff_state.imsto_sal_check_ra;
767
768         if (recover)
769                 ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_CORRECTED;
770         else
771                 ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_COLD_BOOT;
772
773         /* Default = tell SAL to return to same context */
774         ia64_os_to_sal_handoff_state.imots_context = IA64_MCA_SAME_CONTEXT;
775
776         ia64_os_to_sal_handoff_state.imots_new_min_state =
777                 (u64 *)ia64_sal_to_os_handoff_state.pal_min_state;
778
779 }
780
781 /*
782  * ia64_mca_ucmc_handler
783  *
784  *      This is uncorrectable machine check handler called from OS_MCA
785  *      dispatch code which is in turn called from SAL_CHECK().
786  *      This is the place where the core of OS MCA handling is done.
787  *      Right now the logs are extracted and displayed in a well-defined
788  *      format. This handler code is supposed to be run only on the
789  *      monarch processor. Once the monarch is done with MCA handling
790  *      further MCA logging is enabled by clearing logs.
791  *      Monarch also has the duty of sending wakeup-IPIs to pull the
792  *      slave processors out of rendezvous spinloop.
793  *
794  *  Inputs  :   None
795  *  Outputs :   None
796  */
797 void
798 ia64_mca_ucmc_handler(void)
799 {
800         pal_processor_state_info_t *psp = (pal_processor_state_info_t *)
801                 &ia64_sal_to_os_handoff_state.proc_state_param;
802         int recover = psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc);
803
804         /* Get the MCA error record and log it */
805         ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
806
807         /*
808          *  Wakeup all the processors which are spinning in the rendezvous
809          *  loop.
810          */
811         ia64_mca_wakeup_all();
812
813         /* Return to SAL */
814         ia64_return_to_sal_check(recover);
815 }
816
817 static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd, NULL);
818 static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd, NULL);
819
820 /*
821  * ia64_mca_cmc_int_handler
822  *
823  *  This is corrected machine check interrupt handler.
824  *      Right now the logs are extracted and displayed in a well-defined
825  *      format.
826  *
827  * Inputs
828  *      interrupt number
829  *      client data arg ptr
830  *      saved registers ptr
831  *
832  * Outputs
833  *      None
834  */
835 static irqreturn_t
836 ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
837 {
838         static unsigned long    cmc_history[CMC_HISTORY_LENGTH];
839         static int              index;
840         static spinlock_t       cmc_history_lock = SPIN_LOCK_UNLOCKED;
841
842         IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n",
843                        __FUNCTION__, cmc_irq, smp_processor_id());
844
845         /* SAL spec states this should run w/ interrupts enabled */
846         local_irq_enable();
847
848         /* Get the CMC error record and log it */
849         ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC);
850
851         spin_lock(&cmc_history_lock);
852         if (!cmc_polling_enabled) {
853                 int i, count = 1; /* we know 1 happened now */
854                 unsigned long now = jiffies;
855
856                 for (i = 0; i < CMC_HISTORY_LENGTH; i++) {
857                         if (now - cmc_history[i] <= HZ)
858                                 count++;
859                 }
860
861                 IA64_MCA_DEBUG(KERN_INFO "CMC threshold %d/%d\n", count, CMC_HISTORY_LENGTH);
862                 if (count >= CMC_HISTORY_LENGTH) {
863
864                         cmc_polling_enabled = 1;
865                         spin_unlock(&cmc_history_lock);
866                         schedule_work(&cmc_disable_work);
867
868                         /*
869                          * Corrected errors will still be corrected, but
870                          * make sure there's a log somewhere that indicates
871                          * something is generating more than we can handle.
872                          */
873                         printk(KERN_WARNING "WARNING: Switching to polling CMC handler; error records may be lost\n");
874
875                         mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
876
877                         /* lock already released, get out now */
878                         return IRQ_HANDLED;
879                 } else {
880                         cmc_history[index++] = now;
881                         if (index == CMC_HISTORY_LENGTH)
882                                 index = 0;
883                 }
884         }
885         spin_unlock(&cmc_history_lock);
886         return IRQ_HANDLED;
887 }
888
889 /*
890  *  ia64_mca_cmc_int_caller
891  *
892  *      Triggered by sw interrupt from CMC polling routine.  Calls
893  *      real interrupt handler and either triggers a sw interrupt
894  *      on the next cpu or does cleanup at the end.
895  *
896  * Inputs
897  *      interrupt number
898  *      client data arg ptr
899  *      saved registers ptr
900  * Outputs
901  *      handled
902  */
903 static irqreturn_t
904 ia64_mca_cmc_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
905 {
906         static int start_count = -1;
907         unsigned int cpuid;
908
909         cpuid = smp_processor_id();
910
911         /* If first cpu, update count */
912         if (start_count == -1)
913                 start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC);
914
915         ia64_mca_cmc_int_handler(cpe_irq, arg, ptregs);
916
917         for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
918
919         if (cpuid < NR_CPUS) {
920                 platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
921         } else {
922                 /* If no log record, switch out of polling mode */
923                 if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) {
924
925                         printk(KERN_WARNING "Returning to interrupt driven CMC handler\n");
926                         schedule_work(&cmc_enable_work);
927                         cmc_polling_enabled = 0;
928
929                 } else {
930
931                         mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
932                 }
933
934                 start_count = -1;
935         }
936
937         return IRQ_HANDLED;
938 }
939
940 /*
941  *  ia64_mca_cmc_poll
942  *
943  *      Poll for Corrected Machine Checks (CMCs)
944  *
945  * Inputs   :   dummy(unused)
946  * Outputs  :   None
947  *
948  */
949 static void
950 ia64_mca_cmc_poll (unsigned long dummy)
951 {
952         /* Trigger a CMC interrupt cascade  */
953         platform_send_ipi(first_cpu(cpu_online_map), IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
954 }
955
956 /*
957  *  ia64_mca_cpe_int_caller
958  *
959  *      Triggered by sw interrupt from CPE polling routine.  Calls
960  *      real interrupt handler and either triggers a sw interrupt
961  *      on the next cpu or does cleanup at the end.
962  *
963  * Inputs
964  *      interrupt number
965  *      client data arg ptr
966  *      saved registers ptr
967  * Outputs
968  *      handled
969  */
970 static irqreturn_t
971 ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
972 {
973         static int start_count = -1;
974         static int poll_time = MAX_CPE_POLL_INTERVAL;
975         unsigned int cpuid;
976
977         cpuid = smp_processor_id();
978
979         /* If first cpu, update count */
980         if (start_count == -1)
981                 start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE);
982
983         ia64_mca_cpe_int_handler(cpe_irq, arg, ptregs);
984
985         for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
986
987         if (cpuid < NR_CPUS) {
988                 platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
989         } else {
990                 /*
991                  * If a log was recorded, increase our polling frequency,
992                  * otherwise, backoff.
993                  */
994                 if (start_count != IA64_LOG_COUNT(SAL_INFO_TYPE_CPE)) {
995                         poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time / 2);
996                 } else {
997                         poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2);
998                 }
999                 start_count = -1;
1000                 mod_timer(&cpe_poll_timer, jiffies + poll_time);
1001         }
1002
1003         return IRQ_HANDLED;
1004 }
1005
1006 /*
1007  *  ia64_mca_cpe_poll
1008  *
1009  *      Poll for Corrected Platform Errors (CPEs), trigger interrupt
1010  *      on first cpu, from there it will trickle through all the cpus.
1011  *
1012  * Inputs   :   dummy(unused)
1013  * Outputs  :   None
1014  *
1015  */
1016 static void
1017 ia64_mca_cpe_poll (unsigned long dummy)
1018 {
1019         /* Trigger a CPE interrupt cascade  */
1020         platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
1021 }
1022
1023 /*
1024  * C portion of the OS INIT handler
1025  *
1026  * Called from ia64_monarch_init_handler
1027  *
1028  * Inputs: pointer to pt_regs where processor info was saved.
1029  *
1030  * Returns:
1031  *   0 if SAL must warm boot the System
1032  *   1 if SAL must return to interrupted context using PAL_MC_RESUME
1033  *
1034  */
1035 void
1036 ia64_init_handler (struct pt_regs *pt, struct switch_stack *sw)
1037 {
1038         pal_min_state_area_t *ms;
1039
1040         oops_in_progress = 1;   /* avoid deadlock in printk, but it makes recovery dodgy */
1041
1042         printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n",
1043                 ia64_sal_to_os_handoff_state.proc_state_param);
1044
1045         /*
1046          * Address of minstate area provided by PAL is physical,
1047          * uncacheable (bit 63 set). Convert to Linux virtual
1048          * address in region 6.
1049          */
1050         ms = (pal_min_state_area_t *)(ia64_sal_to_os_handoff_state.pal_min_state | (6ul<<61));
1051
1052         init_handler_platform(ms, pt, sw);      /* call platform specific routines */
1053 }
1054
1055 static int __init
1056 ia64_mca_disable_cpe_polling(char *str)
1057 {
1058         cpe_poll_enabled = 0;
1059         return 1;
1060 }
1061
1062 __setup("disable_cpe_poll", ia64_mca_disable_cpe_polling);
1063
1064 static struct irqaction cmci_irqaction = {
1065         .handler =      ia64_mca_cmc_int_handler,
1066         .flags =        SA_INTERRUPT,
1067         .name =         "cmc_hndlr"
1068 };
1069
1070 static struct irqaction cmcp_irqaction = {
1071         .handler =      ia64_mca_cmc_int_caller,
1072         .flags =        SA_INTERRUPT,
1073         .name =         "cmc_poll"
1074 };
1075
1076 static struct irqaction mca_rdzv_irqaction = {
1077         .handler =      ia64_mca_rendez_int_handler,
1078         .flags =        SA_INTERRUPT,
1079         .name =         "mca_rdzv"
1080 };
1081
1082 static struct irqaction mca_wkup_irqaction = {
1083         .handler =      ia64_mca_wakeup_int_handler,
1084         .flags =        SA_INTERRUPT,
1085         .name =         "mca_wkup"
1086 };
1087
1088 #ifdef CONFIG_ACPI
1089 static struct irqaction mca_cpe_irqaction = {
1090         .handler =      ia64_mca_cpe_int_handler,
1091         .flags =        SA_INTERRUPT,
1092         .name =         "cpe_hndlr"
1093 };
1094
1095 static struct irqaction mca_cpep_irqaction = {
1096         .handler =      ia64_mca_cpe_int_caller,
1097         .flags =        SA_INTERRUPT,
1098         .name =         "cpe_poll"
1099 };
1100 #endif /* CONFIG_ACPI */
1101
1102 /*
1103  * ia64_mca_init
1104  *
1105  *  Do all the system level mca specific initialization.
1106  *
1107  *      1. Register spinloop and wakeup request interrupt vectors
1108  *
1109  *      2. Register OS_MCA handler entry point
1110  *
1111  *      3. Register OS_INIT handler entry point
1112  *
1113  *  4. Initialize MCA/CMC/INIT related log buffers maintained by the OS.
1114  *
1115  *  Note that this initialization is done very early before some kernel
1116  *  services are available.
1117  *
1118  *  Inputs  :   None
1119  *
1120  *  Outputs :   None
1121  */
1122 void __init
1123 ia64_mca_init(void)
1124 {
1125         ia64_fptr_t *mon_init_ptr = (ia64_fptr_t *)ia64_monarch_init_handler;
1126         ia64_fptr_t *slave_init_ptr = (ia64_fptr_t *)ia64_slave_init_handler;
1127         ia64_fptr_t *mca_hldlr_ptr = (ia64_fptr_t *)ia64_os_mca_dispatch;
1128         int i;
1129         s64 rc;
1130         struct ia64_sal_retval isrv;
1131         u64 timeout = IA64_MCA_RENDEZ_TIMEOUT;  /* platform specific */
1132
1133         IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
1134
1135         /* Clear the Rendez checkin flag for all cpus */
1136         for(i = 0 ; i < NR_CPUS; i++)
1137                 ia64_mc_info.imi_rendez_checkin[i] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
1138
1139         /*
1140          * Register the rendezvous spinloop and wakeup mechanism with SAL
1141          */
1142
1143         /* Register the rendezvous interrupt vector with SAL */
1144         while (1) {
1145                 isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_INT,
1146                                               SAL_MC_PARAM_MECHANISM_INT,
1147                                               IA64_MCA_RENDEZ_VECTOR,
1148                                               timeout,
1149                                               SAL_MC_PARAM_RZ_ALWAYS);
1150                 rc = isrv.status;
1151                 if (rc == 0)
1152                         break;
1153                 if (rc == -2) {
1154                         printk(KERN_INFO "Increasing MCA rendezvous timeout from "
1155                                 "%ld to %ld milliseconds\n", timeout, isrv.v0);
1156                         timeout = isrv.v0;
1157                         continue;
1158                 }
1159                 printk(KERN_ERR "Failed to register rendezvous interrupt "
1160                        "with SAL (status %ld)\n", rc);
1161                 return;
1162         }
1163
1164         /* Register the wakeup interrupt vector with SAL */
1165         isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_WAKEUP,
1166                                       SAL_MC_PARAM_MECHANISM_INT,
1167                                       IA64_MCA_WAKEUP_VECTOR,
1168                                       0, 0);
1169         rc = isrv.status;
1170         if (rc) {
1171                 printk(KERN_ERR "Failed to register wakeup interrupt with SAL "
1172                        "(status %ld)\n", rc);
1173                 return;
1174         }
1175
1176         IA64_MCA_DEBUG("%s: registered MCA rendezvous spinloop and wakeup mech.\n", __FUNCTION__);
1177
1178         ia64_mc_info.imi_mca_handler        = ia64_tpa(mca_hldlr_ptr->fp);
1179         /*
1180          * XXX - disable SAL checksum by setting size to 0; should be
1181          *      ia64_tpa(ia64_os_mca_dispatch_end) - ia64_tpa(ia64_os_mca_dispatch);
1182          */
1183         ia64_mc_info.imi_mca_handler_size       = 0;
1184
1185         /* Register the os mca handler with SAL */
1186         if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_MCA,
1187                                        ia64_mc_info.imi_mca_handler,
1188                                        ia64_tpa(mca_hldlr_ptr->gp),
1189                                        ia64_mc_info.imi_mca_handler_size,
1190                                        0, 0, 0)))
1191         {
1192                 printk(KERN_ERR "Failed to register OS MCA handler with SAL "
1193                        "(status %ld)\n", rc);
1194                 return;
1195         }
1196
1197         IA64_MCA_DEBUG("%s: registered OS MCA handler with SAL at 0x%lx, gp = 0x%lx\n", __FUNCTION__,
1198                        ia64_mc_info.imi_mca_handler, ia64_tpa(mca_hldlr_ptr->gp));
1199
1200         /*
1201          * XXX - disable SAL checksum by setting size to 0, should be
1202          * size of the actual init handler in mca_asm.S.
1203          */
1204         ia64_mc_info.imi_monarch_init_handler           = ia64_tpa(mon_init_ptr->fp);
1205         ia64_mc_info.imi_monarch_init_handler_size      = 0;
1206         ia64_mc_info.imi_slave_init_handler             = ia64_tpa(slave_init_ptr->fp);
1207         ia64_mc_info.imi_slave_init_handler_size        = 0;
1208
1209         IA64_MCA_DEBUG("%s: OS INIT handler at %lx\n", __FUNCTION__,
1210                        ia64_mc_info.imi_monarch_init_handler);
1211
1212         /* Register the os init handler with SAL */
1213         if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_INIT,
1214                                        ia64_mc_info.imi_monarch_init_handler,
1215                                        ia64_tpa(ia64_getreg(_IA64_REG_GP)),
1216                                        ia64_mc_info.imi_monarch_init_handler_size,
1217                                        ia64_mc_info.imi_slave_init_handler,
1218                                        ia64_tpa(ia64_getreg(_IA64_REG_GP)),
1219                                        ia64_mc_info.imi_slave_init_handler_size)))
1220         {
1221                 printk(KERN_ERR "Failed to register m/s INIT handlers with SAL "
1222                        "(status %ld)\n", rc);
1223                 return;
1224         }
1225
1226         IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__);
1227
1228         /*
1229          *  Configure the CMCI/P vector and handler. Interrupts for CMC are
1230          *  per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c).
1231          */
1232         register_percpu_irq(IA64_CMC_VECTOR, &cmci_irqaction);
1233         register_percpu_irq(IA64_CMCP_VECTOR, &cmcp_irqaction);
1234         ia64_mca_cmc_vector_setup();       /* Setup vector on BSP & enable */
1235
1236         /* Setup the MCA rendezvous interrupt vector */
1237         register_percpu_irq(IA64_MCA_RENDEZ_VECTOR, &mca_rdzv_irqaction);
1238
1239         /* Setup the MCA wakeup interrupt vector */
1240         register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
1241
1242 #ifdef CONFIG_ACPI
1243         /* Setup the CPE interrupt vector */
1244         {
1245                 irq_desc_t *desc;
1246                 unsigned int irq;
1247                 int cpev = acpi_request_vector(ACPI_INTERRUPT_CPEI);
1248
1249                 if (cpev >= 0) {
1250                         for (irq = 0; irq < NR_IRQS; ++irq)
1251                                 if (irq_to_vector(irq) == cpev) {
1252                                         desc = irq_descp(irq);
1253                                         desc->status |= IRQ_PER_CPU;
1254                                         setup_irq(irq, &mca_cpe_irqaction);
1255                                 }
1256                         ia64_mca_register_cpev(cpev);
1257                 }
1258         }
1259 #endif
1260
1261         /* Initialize the areas set aside by the OS to buffer the
1262          * platform/processor error states for MCA/INIT/CMC
1263          * handling.
1264          */
1265         ia64_log_init(SAL_INFO_TYPE_MCA);
1266         ia64_log_init(SAL_INFO_TYPE_INIT);
1267         ia64_log_init(SAL_INFO_TYPE_CMC);
1268         ia64_log_init(SAL_INFO_TYPE_CPE);
1269
1270         printk(KERN_INFO "MCA related initialization done\n");
1271 }
1272
1273 /*
1274  * ia64_mca_late_init
1275  *
1276  *      Opportunity to setup things that require initialization later
1277  *      than ia64_mca_init.  Setup a timer to poll for CPEs if the
1278  *      platform doesn't support an interrupt driven mechanism.
1279  *
1280  *  Inputs  :   None
1281  *  Outputs :   Status
1282  */
1283 static int __init
1284 ia64_mca_late_init(void)
1285 {
1286         init_timer(&cmc_poll_timer);
1287         cmc_poll_timer.function = ia64_mca_cmc_poll;
1288
1289         /* Reset to the correct state */
1290         cmc_polling_enabled = 0;
1291
1292         init_timer(&cpe_poll_timer);
1293         cpe_poll_timer.function = ia64_mca_cpe_poll;
1294
1295 #ifdef CONFIG_ACPI
1296         /* If platform doesn't support CPEI, get the timer going. */
1297         if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0 && cpe_poll_enabled) {
1298                 register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
1299                 ia64_mca_cpe_poll(0UL);
1300         }
1301 #endif
1302
1303         return 0;
1304 }
1305
1306 device_initcall(ia64_mca_late_init);