ia64/xen-unstable

view xen/arch/ia64/linux-xen/mca.c @ 10888:5379548bfc79

[NET] Enable TCPv4 segmentation offload in front/back drivers.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Aug 01 11:54:45 2006 +0100 (2006-08-01)
parents efdfbb40db3f
children d42e9a6f5378
line source
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>
68 #include <asm/delay.h>
69 #include <asm/machvec.h>
70 #include <asm/meminit.h>
71 #include <asm/page.h>
72 #include <asm/ptrace.h>
73 #include <asm/system.h>
74 #include <asm/sal.h>
75 #include <asm/mca.h>
77 #include <asm/irq.h>
78 #include <asm/hw_irq.h>
80 #ifdef XEN
81 #include <xen/symbols.h>
82 #endif
84 #if defined(IA64_MCA_DEBUG_INFO)
85 # define IA64_MCA_DEBUG(fmt...) printk(fmt)
86 #else
87 # define IA64_MCA_DEBUG(fmt...)
88 #endif
90 /* Used by mca_asm.S */
91 #ifndef XEN
92 ia64_mca_sal_to_os_state_t ia64_sal_to_os_handoff_state;
93 #else
94 ia64_mca_sal_to_os_state_t ia64_sal_to_os_handoff_state[NR_CPUS];
95 DEFINE_PER_CPU(u64, ia64_sal_to_os_handoff_state_addr);
96 #endif
97 ia64_mca_os_to_sal_state_t ia64_os_to_sal_handoff_state;
98 u64 ia64_mca_serialize;
99 DEFINE_PER_CPU(u64, ia64_mca_data); /* == __per_cpu_mca[smp_processor_id()] */
100 DEFINE_PER_CPU(u64, ia64_mca_per_cpu_pte); /* PTE to map per-CPU area */
101 DEFINE_PER_CPU(u64, ia64_mca_pal_pte); /* PTE to map PAL code */
102 DEFINE_PER_CPU(u64, ia64_mca_pal_base); /* vaddr PAL code granule */
104 unsigned long __per_cpu_mca[NR_CPUS];
106 /* In mca_asm.S */
107 extern void ia64_monarch_init_handler (void);
108 extern void ia64_slave_init_handler (void);
110 static ia64_mc_info_t ia64_mc_info;
112 #ifndef XEN
113 #define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */
114 #define MIN_CPE_POLL_INTERVAL (2*60*HZ) /* 2 minutes */
115 #define CMC_POLL_INTERVAL (1*60*HZ) /* 1 minute */
116 #define CPE_HISTORY_LENGTH 5
117 #define CMC_HISTORY_LENGTH 5
119 static struct timer_list cpe_poll_timer;
120 static struct timer_list cmc_poll_timer;
121 /*
122 * This variable tells whether we are currently in polling mode.
123 * Start with this in the wrong state so we won't play w/ timers
124 * before the system is ready.
125 */
126 static int cmc_polling_enabled = 1;
128 /*
129 * Clearing this variable prevents CPE polling from getting activated
130 * in mca_late_init. Use it if your system doesn't provide a CPEI,
131 * but encounters problems retrieving CPE logs. This should only be
132 * necessary for debugging.
133 */
134 static int cpe_poll_enabled = 1;
136 extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
137 #endif /* !XEN */
139 static int mca_init;
141 #ifndef XEN
142 /*
143 * IA64_MCA log support
144 */
145 #define IA64_MAX_LOGS 2 /* Double-buffering for nested MCAs */
146 #define IA64_MAX_LOG_TYPES 4 /* MCA, INIT, CMC, CPE */
148 typedef struct ia64_state_log_s
149 {
150 spinlock_t isl_lock;
151 int isl_index;
152 unsigned long isl_count;
153 ia64_err_rec_t *isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */
154 } ia64_state_log_t;
156 static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES];
158 #define IA64_LOG_ALLOCATE(it, size) \
159 {ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)] = \
160 (ia64_err_rec_t *)alloc_bootmem(size); \
161 ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)] = \
162 (ia64_err_rec_t *)alloc_bootmem(size);}
163 #define IA64_LOG_LOCK_INIT(it) spin_lock_init(&ia64_state_log[it].isl_lock)
164 #define IA64_LOG_LOCK(it) spin_lock_irqsave(&ia64_state_log[it].isl_lock, s)
165 #define IA64_LOG_UNLOCK(it) spin_unlock_irqrestore(&ia64_state_log[it].isl_lock,s)
166 #define IA64_LOG_NEXT_INDEX(it) ia64_state_log[it].isl_index
167 #define IA64_LOG_CURR_INDEX(it) 1 - ia64_state_log[it].isl_index
168 #define IA64_LOG_INDEX_INC(it) \
169 {ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index; \
170 ia64_state_log[it].isl_count++;}
171 #define IA64_LOG_INDEX_DEC(it) \
172 ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index
173 #define IA64_LOG_NEXT_BUFFER(it) (void *)((ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)]))
174 #define IA64_LOG_CURR_BUFFER(it) (void *)((ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)]))
175 #define IA64_LOG_COUNT(it) ia64_state_log[it].isl_count
177 /*
178 * ia64_log_init
179 * Reset the OS ia64 log buffer
180 * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE})
181 * Outputs : None
182 */
183 static void
184 ia64_log_init(int sal_info_type)
185 {
186 u64 max_size = 0;
188 IA64_LOG_NEXT_INDEX(sal_info_type) = 0;
189 IA64_LOG_LOCK_INIT(sal_info_type);
191 // SAL will tell us the maximum size of any error record of this type
192 max_size = ia64_sal_get_state_info_size(sal_info_type);
193 if (!max_size)
194 /* alloc_bootmem() doesn't like zero-sized allocations! */
195 return;
197 // set up OS data structures to hold error info
198 IA64_LOG_ALLOCATE(sal_info_type, max_size);
199 memset(IA64_LOG_CURR_BUFFER(sal_info_type), 0, max_size);
200 memset(IA64_LOG_NEXT_BUFFER(sal_info_type), 0, max_size);
201 }
203 /*
204 * ia64_log_get
205 *
206 * Get the current MCA log from SAL and copy it into the OS log buffer.
207 *
208 * Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE})
209 * irq_safe whether you can use printk at this point
210 * Outputs : size (total record length)
211 * *buffer (ptr to error record)
212 *
213 */
214 static u64
215 ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe)
216 {
217 sal_log_record_header_t *log_buffer;
218 u64 total_len = 0;
219 int s;
221 IA64_LOG_LOCK(sal_info_type);
223 /* Get the process state information */
224 log_buffer = IA64_LOG_NEXT_BUFFER(sal_info_type);
226 total_len = ia64_sal_get_state_info(sal_info_type, (u64 *)log_buffer);
228 if (total_len) {
229 IA64_LOG_INDEX_INC(sal_info_type);
230 IA64_LOG_UNLOCK(sal_info_type);
231 if (irq_safe) {
232 IA64_MCA_DEBUG("%s: SAL error record type %d retrieved. "
233 "Record length = %ld\n", __FUNCTION__, sal_info_type, total_len);
234 }
235 *buffer = (u8 *) log_buffer;
236 return total_len;
237 } else {
238 IA64_LOG_UNLOCK(sal_info_type);
239 return 0;
240 }
241 }
243 /*
244 * ia64_mca_log_sal_error_record
245 *
246 * This function retrieves a specified error record type from SAL
247 * and wakes up any processes waiting for error records.
248 *
249 * Inputs : sal_info_type (Type of error record MCA/CMC/CPE/INIT)
250 */
251 static void
252 ia64_mca_log_sal_error_record(int sal_info_type)
253 {
254 u8 *buffer;
255 sal_log_record_header_t *rh;
256 u64 size;
257 int irq_safe = sal_info_type != SAL_INFO_TYPE_MCA && sal_info_type != SAL_INFO_TYPE_INIT;
258 #ifdef IA64_MCA_DEBUG_INFO
259 static const char * const rec_name[] = { "MCA", "INIT", "CMC", "CPE" };
260 #endif
262 size = ia64_log_get(sal_info_type, &buffer, irq_safe);
263 if (!size)
264 return;
266 salinfo_log_wakeup(sal_info_type, buffer, size, irq_safe);
268 if (irq_safe)
269 IA64_MCA_DEBUG("CPU %d: SAL log contains %s error record\n",
270 smp_processor_id(),
271 sal_info_type < ARRAY_SIZE(rec_name) ? rec_name[sal_info_type] : "UNKNOWN");
273 /* Clear logs from corrected errors in case there's no user-level logger */
274 rh = (sal_log_record_header_t *)buffer;
275 if (rh->severity == sal_log_severity_corrected)
276 ia64_sal_clear_state_info(sal_info_type);
277 }
279 /*
280 * platform dependent error handling
281 */
282 #endif /* !XEN */
283 #ifndef PLATFORM_MCA_HANDLERS
284 #ifndef XEN
286 #ifdef CONFIG_ACPI
288 int cpe_vector = -1;
290 static irqreturn_t
291 ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
292 {
293 static unsigned long cpe_history[CPE_HISTORY_LENGTH];
294 static int index;
295 static DEFINE_SPINLOCK(cpe_history_lock);
297 IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n",
298 __FUNCTION__, cpe_irq, smp_processor_id());
300 /* SAL spec states this should run w/ interrupts enabled */
301 local_irq_enable();
303 /* Get the CPE error record and log it */
304 ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE);
306 spin_lock(&cpe_history_lock);
307 if (!cpe_poll_enabled && cpe_vector >= 0) {
309 int i, count = 1; /* we know 1 happened now */
310 unsigned long now = jiffies;
312 for (i = 0; i < CPE_HISTORY_LENGTH; i++) {
313 if (now - cpe_history[i] <= HZ)
314 count++;
315 }
317 IA64_MCA_DEBUG(KERN_INFO "CPE threshold %d/%d\n", count, CPE_HISTORY_LENGTH);
318 if (count >= CPE_HISTORY_LENGTH) {
320 cpe_poll_enabled = 1;
321 spin_unlock(&cpe_history_lock);
322 disable_irq_nosync(local_vector_to_irq(IA64_CPE_VECTOR));
324 /*
325 * Corrected errors will still be corrected, but
326 * make sure there's a log somewhere that indicates
327 * something is generating more than we can handle.
328 */
329 printk(KERN_WARNING "WARNING: Switching to polling CPE handler; error records may be lost\n");
331 mod_timer(&cpe_poll_timer, jiffies + MIN_CPE_POLL_INTERVAL);
333 /* lock already released, get out now */
334 return IRQ_HANDLED;
335 } else {
336 cpe_history[index++] = now;
337 if (index == CPE_HISTORY_LENGTH)
338 index = 0;
339 }
340 }
341 spin_unlock(&cpe_history_lock);
342 return IRQ_HANDLED;
343 }
345 #endif /* CONFIG_ACPI */
346 #endif /* !XEN */
348 static void
349 show_min_state (pal_min_state_area_t *minstate)
350 {
351 u64 iip = minstate->pmsa_iip + ((struct ia64_psr *)(&minstate->pmsa_ipsr))->ri;
352 u64 xip = minstate->pmsa_xip + ((struct ia64_psr *)(&minstate->pmsa_xpsr))->ri;
354 printk("NaT bits\t%016lx\n", minstate->pmsa_nat_bits);
355 printk("pr\t\t%016lx\n", minstate->pmsa_pr);
356 printk("b0\t\t%016lx ", minstate->pmsa_br0); print_symbol("%s\n", minstate->pmsa_br0);
357 printk("ar.rsc\t\t%016lx\n", minstate->pmsa_rsc);
358 printk("cr.iip\t\t%016lx ", iip); print_symbol("%s\n", iip);
359 printk("cr.ipsr\t\t%016lx\n", minstate->pmsa_ipsr);
360 printk("cr.ifs\t\t%016lx\n", minstate->pmsa_ifs);
361 printk("xip\t\t%016lx ", xip); print_symbol("%s\n", xip);
362 printk("xpsr\t\t%016lx\n", minstate->pmsa_xpsr);
363 printk("xfs\t\t%016lx\n", minstate->pmsa_xfs);
364 printk("b1\t\t%016lx ", minstate->pmsa_br1);
365 print_symbol("%s\n", minstate->pmsa_br1);
367 printk("\nstatic registers r0-r15:\n");
368 printk(" r0- 3 %016lx %016lx %016lx %016lx\n",
369 0UL, minstate->pmsa_gr[0], minstate->pmsa_gr[1], minstate->pmsa_gr[2]);
370 printk(" r4- 7 %016lx %016lx %016lx %016lx\n",
371 minstate->pmsa_gr[3], minstate->pmsa_gr[4],
372 minstate->pmsa_gr[5], minstate->pmsa_gr[6]);
373 printk(" r8-11 %016lx %016lx %016lx %016lx\n",
374 minstate->pmsa_gr[7], minstate->pmsa_gr[8],
375 minstate->pmsa_gr[9], minstate->pmsa_gr[10]);
376 printk("r12-15 %016lx %016lx %016lx %016lx\n",
377 minstate->pmsa_gr[11], minstate->pmsa_gr[12],
378 minstate->pmsa_gr[13], minstate->pmsa_gr[14]);
380 printk("\nbank 0:\n");
381 printk("r16-19 %016lx %016lx %016lx %016lx\n",
382 minstate->pmsa_bank0_gr[0], minstate->pmsa_bank0_gr[1],
383 minstate->pmsa_bank0_gr[2], minstate->pmsa_bank0_gr[3]);
384 printk("r20-23 %016lx %016lx %016lx %016lx\n",
385 minstate->pmsa_bank0_gr[4], minstate->pmsa_bank0_gr[5],
386 minstate->pmsa_bank0_gr[6], minstate->pmsa_bank0_gr[7]);
387 printk("r24-27 %016lx %016lx %016lx %016lx\n",
388 minstate->pmsa_bank0_gr[8], minstate->pmsa_bank0_gr[9],
389 minstate->pmsa_bank0_gr[10], minstate->pmsa_bank0_gr[11]);
390 printk("r28-31 %016lx %016lx %016lx %016lx\n",
391 minstate->pmsa_bank0_gr[12], minstate->pmsa_bank0_gr[13],
392 minstate->pmsa_bank0_gr[14], minstate->pmsa_bank0_gr[15]);
394 printk("\nbank 1:\n");
395 printk("r16-19 %016lx %016lx %016lx %016lx\n",
396 minstate->pmsa_bank1_gr[0], minstate->pmsa_bank1_gr[1],
397 minstate->pmsa_bank1_gr[2], minstate->pmsa_bank1_gr[3]);
398 printk("r20-23 %016lx %016lx %016lx %016lx\n",
399 minstate->pmsa_bank1_gr[4], minstate->pmsa_bank1_gr[5],
400 minstate->pmsa_bank1_gr[6], minstate->pmsa_bank1_gr[7]);
401 printk("r24-27 %016lx %016lx %016lx %016lx\n",
402 minstate->pmsa_bank1_gr[8], minstate->pmsa_bank1_gr[9],
403 minstate->pmsa_bank1_gr[10], minstate->pmsa_bank1_gr[11]);
404 printk("r28-31 %016lx %016lx %016lx %016lx\n",
405 minstate->pmsa_bank1_gr[12], minstate->pmsa_bank1_gr[13],
406 minstate->pmsa_bank1_gr[14], minstate->pmsa_bank1_gr[15]);
407 }
409 static void
410 fetch_min_state (pal_min_state_area_t *ms, struct pt_regs *pt, struct switch_stack *sw)
411 {
412 u64 *dst_banked, *src_banked, bit, shift, nat_bits;
413 int i;
415 /*
416 * First, update the pt-regs and switch-stack structures with the contents stored
417 * in the min-state area:
418 */
419 if (((struct ia64_psr *) &ms->pmsa_ipsr)->ic == 0) {
420 pt->cr_ipsr = ms->pmsa_xpsr;
421 pt->cr_iip = ms->pmsa_xip;
422 pt->cr_ifs = ms->pmsa_xfs;
423 } else {
424 pt->cr_ipsr = ms->pmsa_ipsr;
425 pt->cr_iip = ms->pmsa_iip;
426 pt->cr_ifs = ms->pmsa_ifs;
427 }
428 pt->ar_rsc = ms->pmsa_rsc;
429 pt->pr = ms->pmsa_pr;
430 pt->r1 = ms->pmsa_gr[0];
431 pt->r2 = ms->pmsa_gr[1];
432 pt->r3 = ms->pmsa_gr[2];
433 sw->r4 = ms->pmsa_gr[3];
434 sw->r5 = ms->pmsa_gr[4];
435 sw->r6 = ms->pmsa_gr[5];
436 sw->r7 = ms->pmsa_gr[6];
437 pt->r8 = ms->pmsa_gr[7];
438 pt->r9 = ms->pmsa_gr[8];
439 pt->r10 = ms->pmsa_gr[9];
440 pt->r11 = ms->pmsa_gr[10];
441 pt->r12 = ms->pmsa_gr[11];
442 pt->r13 = ms->pmsa_gr[12];
443 pt->r14 = ms->pmsa_gr[13];
444 pt->r15 = ms->pmsa_gr[14];
445 dst_banked = &pt->r16; /* r16-r31 are contiguous in struct pt_regs */
446 src_banked = ms->pmsa_bank1_gr;
447 for (i = 0; i < 16; ++i)
448 dst_banked[i] = src_banked[i];
449 pt->b0 = ms->pmsa_br0;
450 sw->b1 = ms->pmsa_br1;
452 /* construct the NaT bits for the pt-regs structure: */
453 # define PUT_NAT_BIT(dst, addr) \
454 do { \
455 bit = nat_bits & 1; nat_bits >>= 1; \
456 shift = ((unsigned long) addr >> 3) & 0x3f; \
457 dst = ((dst) & ~(1UL << shift)) | (bit << shift); \
458 } while (0)
460 /* Rotate the saved NaT bits such that bit 0 corresponds to pmsa_gr[0]: */
461 shift = ((unsigned long) &ms->pmsa_gr[0] >> 3) & 0x3f;
462 nat_bits = (ms->pmsa_nat_bits >> shift) | (ms->pmsa_nat_bits << (64 - shift));
464 PUT_NAT_BIT(sw->caller_unat, &pt->r1);
465 PUT_NAT_BIT(sw->caller_unat, &pt->r2);
466 PUT_NAT_BIT(sw->caller_unat, &pt->r3);
467 PUT_NAT_BIT(sw->ar_unat, &sw->r4);
468 PUT_NAT_BIT(sw->ar_unat, &sw->r5);
469 PUT_NAT_BIT(sw->ar_unat, &sw->r6);
470 PUT_NAT_BIT(sw->ar_unat, &sw->r7);
471 PUT_NAT_BIT(sw->caller_unat, &pt->r8); PUT_NAT_BIT(sw->caller_unat, &pt->r9);
472 PUT_NAT_BIT(sw->caller_unat, &pt->r10); PUT_NAT_BIT(sw->caller_unat, &pt->r11);
473 PUT_NAT_BIT(sw->caller_unat, &pt->r12); PUT_NAT_BIT(sw->caller_unat, &pt->r13);
474 PUT_NAT_BIT(sw->caller_unat, &pt->r14); PUT_NAT_BIT(sw->caller_unat, &pt->r15);
475 nat_bits >>= 16; /* skip over bank0 NaT bits */
476 PUT_NAT_BIT(sw->caller_unat, &pt->r16); PUT_NAT_BIT(sw->caller_unat, &pt->r17);
477 PUT_NAT_BIT(sw->caller_unat, &pt->r18); PUT_NAT_BIT(sw->caller_unat, &pt->r19);
478 PUT_NAT_BIT(sw->caller_unat, &pt->r20); PUT_NAT_BIT(sw->caller_unat, &pt->r21);
479 PUT_NAT_BIT(sw->caller_unat, &pt->r22); PUT_NAT_BIT(sw->caller_unat, &pt->r23);
480 PUT_NAT_BIT(sw->caller_unat, &pt->r24); PUT_NAT_BIT(sw->caller_unat, &pt->r25);
481 PUT_NAT_BIT(sw->caller_unat, &pt->r26); PUT_NAT_BIT(sw->caller_unat, &pt->r27);
482 PUT_NAT_BIT(sw->caller_unat, &pt->r28); PUT_NAT_BIT(sw->caller_unat, &pt->r29);
483 PUT_NAT_BIT(sw->caller_unat, &pt->r30); PUT_NAT_BIT(sw->caller_unat, &pt->r31);
484 }
486 #ifdef XEN
487 static spinlock_t init_dump_lock = SPIN_LOCK_UNLOCKED;
488 static spinlock_t show_stack_lock = SPIN_LOCK_UNLOCKED;
490 static void
491 save_ksp (struct unw_frame_info *info, void *arg)
492 {
493 current->arch._thread.ksp = (__u64)(info->sw) - 16;
494 wmb();
495 }
497 /* FIXME */
498 int try_crashdump(struct pt_regs *a) { return 0; }
500 #define CPU_FLUSH_RETRY_MAX 5
501 static void
502 init_cache_flush (void)
503 {
504 unsigned long flags;
505 int i;
506 s64 rval = 0;
507 u64 vector, progress = 0;
509 for (i = 0; i < CPU_FLUSH_RETRY_MAX; i++) {
510 local_irq_save(flags);
511 rval = ia64_pal_cache_flush(PAL_CACHE_TYPE_INSTRUCTION_DATA,
512 0, &progress, &vector);
513 local_irq_restore(flags);
514 if (rval == 0){
515 printk("\nPAL cache flush success\n");
516 return;
517 }
518 }
519 printk("\nPAL cache flush failed. status=%ld\n",rval);
520 }
521 #endif /* XEN */
523 static void
524 init_handler_platform (pal_min_state_area_t *ms,
525 struct pt_regs *pt, struct switch_stack *sw)
526 {
527 struct unw_frame_info info;
529 /* if a kernel debugger is available call it here else just dump the registers */
531 /*
532 * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
533 * generated via the BMC's command-line interface, but since the console is on the
534 * same serial line, the user will need some time to switch out of the BMC before
535 * the dump begins.
536 */
537 printk("Delaying for 5 seconds...\n");
538 udelay(5*1000000);
539 #ifdef XEN
540 fetch_min_state(ms, pt, sw);
541 spin_lock(&show_stack_lock);
542 #endif
543 show_min_state(ms);
545 #ifdef XEN
546 printk("Backtrace of current vcpu (vcpu_id %d)\n", current->vcpu_id);
547 #else
548 printk("Backtrace of current task (pid %d, %s)\n", current->pid, current->comm);
549 fetch_min_state(ms, pt, sw);
550 #endif
551 unw_init_from_interruption(&info, current, pt, sw);
552 ia64_do_show_stack(&info, NULL);
553 #ifdef XEN
554 unw_init_running(save_ksp, NULL);
555 spin_unlock(&show_stack_lock);
556 wmb();
557 init_cache_flush();
559 if (spin_trylock(&init_dump_lock)) {
560 #ifdef CONFIG_SMP
561 udelay(5*1000000);
562 #endif
563 if (try_crashdump(pt) == 0)
564 printk("\nINIT dump complete. Please reboot now.\n");
565 }
566 printk("%s: CPU%d init handler done\n",
567 __FUNCTION__, smp_processor_id());
568 #else /* XEN */
569 #ifdef CONFIG_SMP
570 /* read_trylock() would be handy... */
571 if (!tasklist_lock.write_lock)
572 read_lock(&tasklist_lock);
573 #endif
574 {
575 struct task_struct *g, *t;
576 do_each_thread (g, t) {
577 if (t == current)
578 continue;
580 printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
581 show_stack(t, NULL);
582 } while_each_thread (g, t);
583 }
584 #ifdef CONFIG_SMP
585 if (!tasklist_lock.write_lock)
586 read_unlock(&tasklist_lock);
587 #endif
589 printk("\nINIT dump complete. Please reboot now.\n");
590 #endif /* XEN */
591 while (1); /* hang city if no debugger */
592 }
594 #ifndef XEN
595 #ifdef CONFIG_ACPI
596 /*
597 * ia64_mca_register_cpev
598 *
599 * Register the corrected platform error vector with SAL.
600 *
601 * Inputs
602 * cpev Corrected Platform Error Vector number
603 *
604 * Outputs
605 * None
606 */
607 static void
608 ia64_mca_register_cpev (int cpev)
609 {
610 /* Register the CPE interrupt vector with SAL */
611 struct ia64_sal_retval isrv;
613 isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0);
614 if (isrv.status) {
615 printk(KERN_ERR "Failed to register Corrected Platform "
616 "Error interrupt vector with SAL (status %ld)\n", isrv.status);
617 return;
618 }
620 IA64_MCA_DEBUG("%s: corrected platform error "
621 "vector %#x registered\n", __FUNCTION__, cpev);
622 }
623 #endif /* CONFIG_ACPI */
625 #endif /* !XEN */
626 #endif /* PLATFORM_MCA_HANDLERS */
627 #ifndef XEN
629 /*
630 * ia64_mca_cmc_vector_setup
631 *
632 * Setup the corrected machine check vector register in the processor.
633 * (The interrupt is masked on boot. ia64_mca_late_init unmask this.)
634 * This function is invoked on a per-processor basis.
635 *
636 * Inputs
637 * None
638 *
639 * Outputs
640 * None
641 */
642 void
643 ia64_mca_cmc_vector_setup (void)
644 {
645 cmcv_reg_t cmcv;
647 cmcv.cmcv_regval = 0;
648 cmcv.cmcv_mask = 1; /* Mask/disable interrupt at first */
649 cmcv.cmcv_vector = IA64_CMC_VECTOR;
650 ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval);
652 IA64_MCA_DEBUG("%s: CPU %d corrected "
653 "machine check vector %#x registered.\n",
654 __FUNCTION__, smp_processor_id(), IA64_CMC_VECTOR);
656 IA64_MCA_DEBUG("%s: CPU %d CMCV = %#016lx\n",
657 __FUNCTION__, smp_processor_id(), ia64_getreg(_IA64_REG_CR_CMCV));
658 }
660 /*
661 * ia64_mca_cmc_vector_disable
662 *
663 * Mask the corrected machine check vector register in the processor.
664 * This function is invoked on a per-processor basis.
665 *
666 * Inputs
667 * dummy(unused)
668 *
669 * Outputs
670 * None
671 */
672 static void
673 ia64_mca_cmc_vector_disable (void *dummy)
674 {
675 cmcv_reg_t cmcv;
677 cmcv.cmcv_regval = ia64_getreg(_IA64_REG_CR_CMCV);
679 cmcv.cmcv_mask = 1; /* Mask/disable interrupt */
680 ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval);
682 IA64_MCA_DEBUG("%s: CPU %d corrected "
683 "machine check vector %#x disabled.\n",
684 __FUNCTION__, smp_processor_id(), cmcv.cmcv_vector);
685 }
687 /*
688 * ia64_mca_cmc_vector_enable
689 *
690 * Unmask the corrected machine check vector register in the processor.
691 * This function is invoked on a per-processor basis.
692 *
693 * Inputs
694 * dummy(unused)
695 *
696 * Outputs
697 * None
698 */
699 static void
700 ia64_mca_cmc_vector_enable (void *dummy)
701 {
702 cmcv_reg_t cmcv;
704 cmcv.cmcv_regval = ia64_getreg(_IA64_REG_CR_CMCV);
706 cmcv.cmcv_mask = 0; /* Unmask/enable interrupt */
707 ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval);
709 IA64_MCA_DEBUG("%s: CPU %d corrected "
710 "machine check vector %#x enabled.\n",
711 __FUNCTION__, smp_processor_id(), cmcv.cmcv_vector);
712 }
714 /*
715 * ia64_mca_cmc_vector_disable_keventd
716 *
717 * Called via keventd (smp_call_function() is not safe in interrupt context) to
718 * disable the cmc interrupt vector.
719 */
720 static void
721 ia64_mca_cmc_vector_disable_keventd(void *unused)
722 {
723 on_each_cpu(ia64_mca_cmc_vector_disable, NULL, 1, 0);
724 }
726 /*
727 * ia64_mca_cmc_vector_enable_keventd
728 *
729 * Called via keventd (smp_call_function() is not safe in interrupt context) to
730 * enable the cmc interrupt vector.
731 */
732 static void
733 ia64_mca_cmc_vector_enable_keventd(void *unused)
734 {
735 on_each_cpu(ia64_mca_cmc_vector_enable, NULL, 1, 0);
736 }
738 /*
739 * ia64_mca_wakeup_ipi_wait
740 *
741 * Wait for the inter-cpu interrupt to be sent by the
742 * monarch processor once it is done with handling the
743 * MCA.
744 *
745 * Inputs : None
746 * Outputs : None
747 */
748 static void
749 ia64_mca_wakeup_ipi_wait(void)
750 {
751 int irr_num = (IA64_MCA_WAKEUP_VECTOR >> 6);
752 int irr_bit = (IA64_MCA_WAKEUP_VECTOR & 0x3f);
753 u64 irr = 0;
755 do {
756 switch(irr_num) {
757 case 0:
758 irr = ia64_getreg(_IA64_REG_CR_IRR0);
759 break;
760 case 1:
761 irr = ia64_getreg(_IA64_REG_CR_IRR1);
762 break;
763 case 2:
764 irr = ia64_getreg(_IA64_REG_CR_IRR2);
765 break;
766 case 3:
767 irr = ia64_getreg(_IA64_REG_CR_IRR3);
768 break;
769 }
770 cpu_relax();
771 } while (!(irr & (1UL << irr_bit))) ;
772 }
774 /*
775 * ia64_mca_wakeup
776 *
777 * Send an inter-cpu interrupt to wake-up a particular cpu
778 * and mark that cpu to be out of rendez.
779 *
780 * Inputs : cpuid
781 * Outputs : None
782 */
783 static void
784 ia64_mca_wakeup(int cpu)
785 {
786 platform_send_ipi(cpu, IA64_MCA_WAKEUP_VECTOR, IA64_IPI_DM_INT, 0);
787 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
789 }
791 /*
792 * ia64_mca_wakeup_all
793 *
794 * Wakeup all the cpus which have rendez'ed previously.
795 *
796 * Inputs : None
797 * Outputs : None
798 */
799 static void
800 ia64_mca_wakeup_all(void)
801 {
802 int cpu;
804 /* Clear the Rendez checkin flag for all cpus */
805 for(cpu = 0; cpu < NR_CPUS; cpu++) {
806 if (!cpu_online(cpu))
807 continue;
808 if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE)
809 ia64_mca_wakeup(cpu);
810 }
812 }
814 /*
815 * ia64_mca_rendez_interrupt_handler
816 *
817 * This is handler used to put slave processors into spinloop
818 * while the monarch processor does the mca handling and later
819 * wake each slave up once the monarch is done.
820 *
821 * Inputs : None
822 * Outputs : None
823 */
824 static irqreturn_t
825 ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
826 {
827 unsigned long flags;
828 int cpu = smp_processor_id();
830 /* Mask all interrupts */
831 local_irq_save(flags);
833 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
834 /* Register with the SAL monarch that the slave has
835 * reached SAL
836 */
837 ia64_sal_mc_rendez();
839 /* Wait for the wakeup IPI from the monarch
840 * This waiting is done by polling on the wakeup-interrupt
841 * vector bit in the processor's IRRs
842 */
843 ia64_mca_wakeup_ipi_wait();
845 /* Enable all interrupts */
846 local_irq_restore(flags);
847 return IRQ_HANDLED;
848 }
850 /*
851 * ia64_mca_wakeup_int_handler
852 *
853 * The interrupt handler for processing the inter-cpu interrupt to the
854 * slave cpu which was spinning in the rendez loop.
855 * Since this spinning is done by turning off the interrupts and
856 * polling on the wakeup-interrupt bit in the IRR, there is
857 * nothing useful to be done in the handler.
858 *
859 * Inputs : wakeup_irq (Wakeup-interrupt bit)
860 * arg (Interrupt handler specific argument)
861 * ptregs (Exception frame at the time of the interrupt)
862 * Outputs : None
863 *
864 */
865 static irqreturn_t
866 ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg, struct pt_regs *ptregs)
867 {
868 return IRQ_HANDLED;
869 }
871 /*
872 * ia64_return_to_sal_check
873 *
874 * This is function called before going back from the OS_MCA handler
875 * to the OS_MCA dispatch code which finally takes the control back
876 * to the SAL.
877 * The main purpose of this routine is to setup the OS_MCA to SAL
878 * return state which can be used by the OS_MCA dispatch code
879 * just before going back to SAL.
880 *
881 * Inputs : None
882 * Outputs : None
883 */
885 static void
886 ia64_return_to_sal_check(int recover)
887 {
889 /* Copy over some relevant stuff from the sal_to_os_mca_handoff
890 * so that it can be used at the time of os_mca_to_sal_handoff
891 */
892 ia64_os_to_sal_handoff_state.imots_sal_gp =
893 ia64_sal_to_os_handoff_state.imsto_sal_gp;
895 ia64_os_to_sal_handoff_state.imots_sal_check_ra =
896 ia64_sal_to_os_handoff_state.imsto_sal_check_ra;
898 if (recover)
899 ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_CORRECTED;
900 else
901 ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_COLD_BOOT;
903 /* Default = tell SAL to return to same context */
904 ia64_os_to_sal_handoff_state.imots_context = IA64_MCA_SAME_CONTEXT;
906 ia64_os_to_sal_handoff_state.imots_new_min_state =
907 (u64 *)ia64_sal_to_os_handoff_state.pal_min_state;
909 }
911 /* Function pointer for extra MCA recovery */
912 int (*ia64_mca_ucmc_extension)
913 (void*,ia64_mca_sal_to_os_state_t*,ia64_mca_os_to_sal_state_t*)
914 = NULL;
916 int
917 ia64_reg_MCA_extension(void *fn)
918 {
919 if (ia64_mca_ucmc_extension)
920 return 1;
922 ia64_mca_ucmc_extension = fn;
923 return 0;
924 }
926 void
927 ia64_unreg_MCA_extension(void)
928 {
929 if (ia64_mca_ucmc_extension)
930 ia64_mca_ucmc_extension = NULL;
931 }
933 EXPORT_SYMBOL(ia64_reg_MCA_extension);
934 EXPORT_SYMBOL(ia64_unreg_MCA_extension);
936 /*
937 * ia64_mca_ucmc_handler
938 *
939 * This is uncorrectable machine check handler called from OS_MCA
940 * dispatch code which is in turn called from SAL_CHECK().
941 * This is the place where the core of OS MCA handling is done.
942 * Right now the logs are extracted and displayed in a well-defined
943 * format. This handler code is supposed to be run only on the
944 * monarch processor. Once the monarch is done with MCA handling
945 * further MCA logging is enabled by clearing logs.
946 * Monarch also has the duty of sending wakeup-IPIs to pull the
947 * slave processors out of rendezvous spinloop.
948 *
949 * Inputs : None
950 * Outputs : None
951 */
952 void
953 ia64_mca_ucmc_handler(void)
954 {
955 pal_processor_state_info_t *psp = (pal_processor_state_info_t *)
956 &ia64_sal_to_os_handoff_state.proc_state_param;
957 int recover;
959 /* Get the MCA error record and log it */
960 ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
962 /* TLB error is only exist in this SAL error record */
963 recover = (psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc))
964 /* other error recovery */
965 || (ia64_mca_ucmc_extension
966 && ia64_mca_ucmc_extension(
967 IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_MCA),
968 &ia64_sal_to_os_handoff_state,
969 &ia64_os_to_sal_handoff_state));
971 if (recover) {
972 sal_log_record_header_t *rh = IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_MCA);
973 rh->severity = sal_log_severity_corrected;
974 ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
975 }
976 /*
977 * Wakeup all the processors which are spinning in the rendezvous
978 * loop.
979 */
980 ia64_mca_wakeup_all();
982 /* Return to SAL */
983 ia64_return_to_sal_check(recover);
984 }
986 static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd, NULL);
987 static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd, NULL);
989 /*
990 * ia64_mca_cmc_int_handler
991 *
992 * This is corrected machine check interrupt handler.
993 * Right now the logs are extracted and displayed in a well-defined
994 * format.
995 *
996 * Inputs
997 * interrupt number
998 * client data arg ptr
999 * saved registers ptr
1001 * Outputs
1002 * None
1003 */
1004 static irqreturn_t
1005 ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
1007 static unsigned long cmc_history[CMC_HISTORY_LENGTH];
1008 static int index;
1009 static DEFINE_SPINLOCK(cmc_history_lock);
1011 IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n",
1012 __FUNCTION__, cmc_irq, smp_processor_id());
1014 /* SAL spec states this should run w/ interrupts enabled */
1015 local_irq_enable();
1017 /* Get the CMC error record and log it */
1018 ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC);
1020 spin_lock(&cmc_history_lock);
1021 if (!cmc_polling_enabled) {
1022 int i, count = 1; /* we know 1 happened now */
1023 unsigned long now = jiffies;
1025 for (i = 0; i < CMC_HISTORY_LENGTH; i++) {
1026 if (now - cmc_history[i] <= HZ)
1027 count++;
1030 IA64_MCA_DEBUG(KERN_INFO "CMC threshold %d/%d\n", count, CMC_HISTORY_LENGTH);
1031 if (count >= CMC_HISTORY_LENGTH) {
1033 cmc_polling_enabled = 1;
1034 spin_unlock(&cmc_history_lock);
1035 schedule_work(&cmc_disable_work);
1037 /*
1038 * Corrected errors will still be corrected, but
1039 * make sure there's a log somewhere that indicates
1040 * something is generating more than we can handle.
1041 */
1042 printk(KERN_WARNING "WARNING: Switching to polling CMC handler; error records may be lost\n");
1044 mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
1046 /* lock already released, get out now */
1047 return IRQ_HANDLED;
1048 } else {
1049 cmc_history[index++] = now;
1050 if (index == CMC_HISTORY_LENGTH)
1051 index = 0;
1054 spin_unlock(&cmc_history_lock);
1055 return IRQ_HANDLED;
1058 /*
1059 * ia64_mca_cmc_int_caller
1061 * Triggered by sw interrupt from CMC polling routine. Calls
1062 * real interrupt handler and either triggers a sw interrupt
1063 * on the next cpu or does cleanup at the end.
1065 * Inputs
1066 * interrupt number
1067 * client data arg ptr
1068 * saved registers ptr
1069 * Outputs
1070 * handled
1071 */
1072 static irqreturn_t
1073 ia64_mca_cmc_int_caller(int cmc_irq, void *arg, struct pt_regs *ptregs)
1075 static int start_count = -1;
1076 unsigned int cpuid;
1078 cpuid = smp_processor_id();
1080 /* If first cpu, update count */
1081 if (start_count == -1)
1082 start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC);
1084 ia64_mca_cmc_int_handler(cmc_irq, arg, ptregs);
1086 for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
1088 if (cpuid < NR_CPUS) {
1089 platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
1090 } else {
1091 /* If no log record, switch out of polling mode */
1092 if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) {
1094 printk(KERN_WARNING "Returning to interrupt driven CMC handler\n");
1095 schedule_work(&cmc_enable_work);
1096 cmc_polling_enabled = 0;
1098 } else {
1100 mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
1103 start_count = -1;
1106 return IRQ_HANDLED;
1109 /*
1110 * ia64_mca_cmc_poll
1112 * Poll for Corrected Machine Checks (CMCs)
1114 * Inputs : dummy(unused)
1115 * Outputs : None
1117 */
1118 static void
1119 ia64_mca_cmc_poll (unsigned long dummy)
1121 /* Trigger a CMC interrupt cascade */
1122 platform_send_ipi(first_cpu(cpu_online_map), IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
1125 /*
1126 * ia64_mca_cpe_int_caller
1128 * Triggered by sw interrupt from CPE polling routine. Calls
1129 * real interrupt handler and either triggers a sw interrupt
1130 * on the next cpu or does cleanup at the end.
1132 * Inputs
1133 * interrupt number
1134 * client data arg ptr
1135 * saved registers ptr
1136 * Outputs
1137 * handled
1138 */
1139 #ifdef CONFIG_ACPI
1141 static irqreturn_t
1142 ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
1144 static int start_count = -1;
1145 static int poll_time = MIN_CPE_POLL_INTERVAL;
1146 unsigned int cpuid;
1148 cpuid = smp_processor_id();
1150 /* If first cpu, update count */
1151 if (start_count == -1)
1152 start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE);
1154 ia64_mca_cpe_int_handler(cpe_irq, arg, ptregs);
1156 for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
1158 if (cpuid < NR_CPUS) {
1159 platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
1160 } else {
1161 /*
1162 * If a log was recorded, increase our polling frequency,
1163 * otherwise, backoff or return to interrupt mode.
1164 */
1165 if (start_count != IA64_LOG_COUNT(SAL_INFO_TYPE_CPE)) {
1166 poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time / 2);
1167 } else if (cpe_vector < 0) {
1168 poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2);
1169 } else {
1170 poll_time = MIN_CPE_POLL_INTERVAL;
1172 printk(KERN_WARNING "Returning to interrupt driven CPE handler\n");
1173 enable_irq(local_vector_to_irq(IA64_CPE_VECTOR));
1174 cpe_poll_enabled = 0;
1177 if (cpe_poll_enabled)
1178 mod_timer(&cpe_poll_timer, jiffies + poll_time);
1179 start_count = -1;
1182 return IRQ_HANDLED;
1185 /*
1186 * ia64_mca_cpe_poll
1188 * Poll for Corrected Platform Errors (CPEs), trigger interrupt
1189 * on first cpu, from there it will trickle through all the cpus.
1191 * Inputs : dummy(unused)
1192 * Outputs : None
1194 */
1195 static void
1196 ia64_mca_cpe_poll (unsigned long dummy)
1198 /* Trigger a CPE interrupt cascade */
1199 platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
1202 #endif /* CONFIG_ACPI */
1203 #endif /* !XEN */
1205 /*
1206 * C portion of the OS INIT handler
1208 * Called from ia64_monarch_init_handler
1210 * Inputs: pointer to pt_regs where processor info was saved.
1212 * Returns:
1213 * 0 if SAL must warm boot the System
1214 * 1 if SAL must return to interrupted context using PAL_MC_RESUME
1216 */
1217 void
1218 ia64_init_handler (struct pt_regs *pt, struct switch_stack *sw)
1220 pal_min_state_area_t *ms;
1221 #ifdef XEN
1222 int cpu = smp_processor_id();
1224 printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n",
1225 ia64_sal_to_os_handoff_state[cpu].proc_state_param);
1226 #endif
1228 #ifndef XEN
1229 oops_in_progress = 1; /* avoid deadlock in printk, but it makes recovery dodgy */
1230 console_loglevel = 15; /* make sure printks make it to console */
1232 printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n",
1233 ia64_sal_to_os_handoff_state.proc_state_param);
1235 /*
1236 * Address of minstate area provided by PAL is physical,
1237 * uncacheable (bit 63 set). Convert to Linux virtual
1238 * address in region 6.
1239 */
1240 ms = (pal_min_state_area_t *)(ia64_sal_to_os_handoff_state.pal_min_state | (6ul<<61));
1241 #else
1242 /* Xen virtual address in region 7. */
1243 ms = __va((pal_min_state_area_t *)(ia64_sal_to_os_handoff_state[cpu].pal_min_state));
1244 #endif
1246 init_handler_platform(ms, pt, sw); /* call platform specific routines */
1249 #ifndef XEN
1250 static int __init
1251 ia64_mca_disable_cpe_polling(char *str)
1253 cpe_poll_enabled = 0;
1254 return 1;
1257 __setup("disable_cpe_poll", ia64_mca_disable_cpe_polling);
1259 static struct irqaction cmci_irqaction = {
1260 .handler = ia64_mca_cmc_int_handler,
1261 .flags = SA_INTERRUPT,
1262 .name = "cmc_hndlr"
1263 };
1265 static struct irqaction cmcp_irqaction = {
1266 .handler = ia64_mca_cmc_int_caller,
1267 .flags = SA_INTERRUPT,
1268 .name = "cmc_poll"
1269 };
1271 static struct irqaction mca_rdzv_irqaction = {
1272 .handler = ia64_mca_rendez_int_handler,
1273 .flags = SA_INTERRUPT,
1274 .name = "mca_rdzv"
1275 };
1277 static struct irqaction mca_wkup_irqaction = {
1278 .handler = ia64_mca_wakeup_int_handler,
1279 .flags = SA_INTERRUPT,
1280 .name = "mca_wkup"
1281 };
1283 #ifdef CONFIG_ACPI
1284 static struct irqaction mca_cpe_irqaction = {
1285 .handler = ia64_mca_cpe_int_handler,
1286 .flags = SA_INTERRUPT,
1287 .name = "cpe_hndlr"
1288 };
1290 static struct irqaction mca_cpep_irqaction = {
1291 .handler = ia64_mca_cpe_int_caller,
1292 .flags = SA_INTERRUPT,
1293 .name = "cpe_poll"
1294 };
1295 #endif /* CONFIG_ACPI */
1296 #endif /* !XEN */
1298 /* Do per-CPU MCA-related initialization. */
1300 void __devinit
1301 ia64_mca_cpu_init(void *cpu_data)
1303 void *pal_vaddr;
1305 if (smp_processor_id() == 0) {
1306 void *mca_data;
1307 int cpu;
1309 #ifdef XEN
1310 unsigned int pageorder;
1311 pageorder = get_order_from_bytes(sizeof(struct ia64_mca_cpu));
1312 #else
1313 mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu)
1314 * NR_CPUS);
1315 #endif
1316 for (cpu = 0; cpu < NR_CPUS; cpu++) {
1317 #ifdef XEN
1318 mca_data = alloc_xenheap_pages(pageorder);
1319 __per_cpu_mca[cpu] = __pa(mca_data);
1320 IA64_MCA_DEBUG("%s: __per_cpu_mca[%d]=%lx"
1321 "(mca_data[%d]=%lx)\n",
1322 __FUNCTION__, cpu, __per_cpu_mca[cpu],
1323 cpu, (u64)mca_data);
1324 #else
1325 __per_cpu_mca[cpu] = __pa(mca_data);
1326 mca_data += sizeof(struct ia64_mca_cpu);
1327 #endif
1331 /*
1332 * The MCA info structure was allocated earlier and its
1333 * physical address saved in __per_cpu_mca[cpu]. Copy that
1334 * address * to ia64_mca_data so we can access it as a per-CPU
1335 * variable.
1336 */
1337 __get_cpu_var(ia64_mca_data) = __per_cpu_mca[smp_processor_id()];
1338 #ifdef XEN
1339 IA64_MCA_DEBUG("%s: CPU#%d, ia64_mca_data=%lx\n", __FUNCTION__,
1340 smp_processor_id(), __get_cpu_var(ia64_mca_data));
1342 /* sal_to_os_handoff for smp support */
1343 __get_cpu_var(ia64_sal_to_os_handoff_state_addr) =
1344 __pa(&ia64_sal_to_os_handoff_state[smp_processor_id()]);
1345 IA64_MCA_DEBUG("%s: CPU#%d, ia64_sal_to_os=%lx\n", __FUNCTION__,
1346 smp_processor_id(),
1347 __get_cpu_var(ia64_sal_to_os_handoff_state_addr));
1348 #endif
1350 /*
1351 * Stash away a copy of the PTE needed to map the per-CPU page.
1352 * We may need it during MCA recovery.
1353 */
1354 __get_cpu_var(ia64_mca_per_cpu_pte) =
1355 pte_val(mk_pte_phys(__pa(cpu_data), PAGE_KERNEL));
1357 /*
1358 * Also, stash away a copy of the PAL address and the PTE
1359 * needed to map it.
1360 */
1361 pal_vaddr = efi_get_pal_addr();
1362 if (!pal_vaddr)
1363 return;
1364 __get_cpu_var(ia64_mca_pal_base) =
1365 GRANULEROUNDDOWN((unsigned long) pal_vaddr);
1366 __get_cpu_var(ia64_mca_pal_pte) = pte_val(mk_pte_phys(__pa(pal_vaddr),
1367 PAGE_KERNEL));
1370 /*
1371 * ia64_mca_init
1373 * Do all the system level mca specific initialization.
1375 * 1. Register spinloop and wakeup request interrupt vectors
1377 * 2. Register OS_MCA handler entry point
1379 * 3. Register OS_INIT handler entry point
1381 * 4. Initialize MCA/CMC/INIT related log buffers maintained by the OS.
1383 * Note that this initialization is done very early before some kernel
1384 * services are available.
1386 * Inputs : None
1388 * Outputs : None
1389 */
1390 void __init
1391 ia64_mca_init(void)
1393 ia64_fptr_t *mon_init_ptr = (ia64_fptr_t *)ia64_monarch_init_handler;
1394 ia64_fptr_t *slave_init_ptr = (ia64_fptr_t *)ia64_slave_init_handler;
1395 ia64_fptr_t *mca_hldlr_ptr = (ia64_fptr_t *)ia64_os_mca_dispatch;
1396 #ifdef XEN
1397 s64 rc;
1399 slave_init_ptr = (ia64_fptr_t *)ia64_monarch_init_handler;
1401 IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
1402 #else
1403 int i;
1404 s64 rc;
1405 struct ia64_sal_retval isrv;
1406 u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */
1408 IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
1410 /* Clear the Rendez checkin flag for all cpus */
1411 for(i = 0 ; i < NR_CPUS; i++)
1412 ia64_mc_info.imi_rendez_checkin[i] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
1414 /*
1415 * Register the rendezvous spinloop and wakeup mechanism with SAL
1416 */
1418 /* Register the rendezvous interrupt vector with SAL */
1419 while (1) {
1420 isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_INT,
1421 SAL_MC_PARAM_MECHANISM_INT,
1422 IA64_MCA_RENDEZ_VECTOR,
1423 timeout,
1424 SAL_MC_PARAM_RZ_ALWAYS);
1425 rc = isrv.status;
1426 if (rc == 0)
1427 break;
1428 if (rc == -2) {
1429 printk(KERN_INFO "Increasing MCA rendezvous timeout from "
1430 "%ld to %ld milliseconds\n", timeout, isrv.v0);
1431 timeout = isrv.v0;
1432 continue;
1434 printk(KERN_ERR "Failed to register rendezvous interrupt "
1435 "with SAL (status %ld)\n", rc);
1436 return;
1439 /* Register the wakeup interrupt vector with SAL */
1440 isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_WAKEUP,
1441 SAL_MC_PARAM_MECHANISM_INT,
1442 IA64_MCA_WAKEUP_VECTOR,
1443 0, 0);
1444 rc = isrv.status;
1445 if (rc) {
1446 printk(KERN_ERR "Failed to register wakeup interrupt with SAL "
1447 "(status %ld)\n", rc);
1448 return;
1451 IA64_MCA_DEBUG("%s: registered MCA rendezvous spinloop and wakeup mech.\n", __FUNCTION__);
1452 #endif /* !XEN */
1454 ia64_mc_info.imi_mca_handler = ia64_tpa(mca_hldlr_ptr->fp);
1455 /*
1456 * XXX - disable SAL checksum by setting size to 0; should be
1457 * ia64_tpa(ia64_os_mca_dispatch_end) - ia64_tpa(ia64_os_mca_dispatch);
1458 */
1459 ia64_mc_info.imi_mca_handler_size = 0;
1461 /* Register the os mca handler with SAL */
1462 if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_MCA,
1463 ia64_mc_info.imi_mca_handler,
1464 ia64_tpa(mca_hldlr_ptr->gp),
1465 ia64_mc_info.imi_mca_handler_size,
1466 0, 0, 0)))
1468 printk(KERN_ERR "Failed to register OS MCA handler with SAL "
1469 "(status %ld)\n", rc);
1470 return;
1473 IA64_MCA_DEBUG("%s: registered OS MCA handler with SAL at 0x%lx, gp = 0x%lx\n", __FUNCTION__,
1474 ia64_mc_info.imi_mca_handler, ia64_tpa(mca_hldlr_ptr->gp));
1476 /*
1477 * XXX - disable SAL checksum by setting size to 0, should be
1478 * size of the actual init handler in mca_asm.S.
1479 */
1480 ia64_mc_info.imi_monarch_init_handler = ia64_tpa(mon_init_ptr->fp);
1481 ia64_mc_info.imi_monarch_init_handler_size = 0;
1482 ia64_mc_info.imi_slave_init_handler = ia64_tpa(slave_init_ptr->fp);
1483 ia64_mc_info.imi_slave_init_handler_size = 0;
1485 IA64_MCA_DEBUG("%s: OS INIT handler at %lx\n", __FUNCTION__,
1486 ia64_mc_info.imi_monarch_init_handler);
1488 /* Register the os init handler with SAL */
1489 if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_INIT,
1490 ia64_mc_info.imi_monarch_init_handler,
1491 ia64_tpa(ia64_getreg(_IA64_REG_GP)),
1492 ia64_mc_info.imi_monarch_init_handler_size,
1493 ia64_mc_info.imi_slave_init_handler,
1494 ia64_tpa(ia64_getreg(_IA64_REG_GP)),
1495 ia64_mc_info.imi_slave_init_handler_size)))
1497 printk(KERN_ERR "Failed to register m/s INIT handlers with SAL "
1498 "(status %ld)\n", rc);
1499 return;
1502 IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__);
1504 #ifndef XEN
1505 /*
1506 * Configure the CMCI/P vector and handler. Interrupts for CMC are
1507 * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c).
1508 */
1509 register_percpu_irq(IA64_CMC_VECTOR, &cmci_irqaction);
1510 register_percpu_irq(IA64_CMCP_VECTOR, &cmcp_irqaction);
1511 ia64_mca_cmc_vector_setup(); /* Setup vector on BSP */
1513 /* Setup the MCA rendezvous interrupt vector */
1514 register_percpu_irq(IA64_MCA_RENDEZ_VECTOR, &mca_rdzv_irqaction);
1516 /* Setup the MCA wakeup interrupt vector */
1517 register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
1519 #ifdef CONFIG_ACPI
1520 /* Setup the CPEI/P handler */
1521 register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
1522 #endif
1524 /* Initialize the areas set aside by the OS to buffer the
1525 * platform/processor error states for MCA/INIT/CMC
1526 * handling.
1527 */
1528 ia64_log_init(SAL_INFO_TYPE_MCA);
1529 ia64_log_init(SAL_INFO_TYPE_INIT);
1530 ia64_log_init(SAL_INFO_TYPE_CMC);
1531 ia64_log_init(SAL_INFO_TYPE_CPE);
1532 #endif /* !XEN */
1534 mca_init = 1;
1535 printk(KERN_INFO "MCA related initialization done\n");
1538 #ifndef XEN
1539 /*
1540 * ia64_mca_late_init
1542 * Opportunity to setup things that require initialization later
1543 * than ia64_mca_init. Setup a timer to poll for CPEs if the
1544 * platform doesn't support an interrupt driven mechanism.
1546 * Inputs : None
1547 * Outputs : Status
1548 */
1549 static int __init
1550 ia64_mca_late_init(void)
1552 if (!mca_init)
1553 return 0;
1555 /* Setup the CMCI/P vector and handler */
1556 init_timer(&cmc_poll_timer);
1557 cmc_poll_timer.function = ia64_mca_cmc_poll;
1559 /* Unmask/enable the vector */
1560 cmc_polling_enabled = 0;
1561 schedule_work(&cmc_enable_work);
1563 IA64_MCA_DEBUG("%s: CMCI/P setup and enabled.\n", __FUNCTION__);
1565 #ifdef CONFIG_ACPI
1566 /* Setup the CPEI/P vector and handler */
1567 cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
1568 init_timer(&cpe_poll_timer);
1569 cpe_poll_timer.function = ia64_mca_cpe_poll;
1572 irq_desc_t *desc;
1573 unsigned int irq;
1575 if (cpe_vector >= 0) {
1576 /* If platform supports CPEI, enable the irq. */
1577 cpe_poll_enabled = 0;
1578 for (irq = 0; irq < NR_IRQS; ++irq)
1579 if (irq_to_vector(irq) == cpe_vector) {
1580 desc = irq_descp(irq);
1581 desc->status |= IRQ_PER_CPU;
1582 setup_irq(irq, &mca_cpe_irqaction);
1584 ia64_mca_register_cpev(cpe_vector);
1585 IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__);
1586 } else {
1587 /* If platform doesn't support CPEI, get the timer going. */
1588 if (cpe_poll_enabled) {
1589 ia64_mca_cpe_poll(0UL);
1590 IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __FUNCTION__);
1594 #endif
1596 return 0;
1599 device_initcall(ia64_mca_late_init);
1600 #endif /* !XEN */