Merge rsync://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[deliverable/linux.git] / arch / parisc / kernel / traps.c
1 /*
2 * linux/arch/parisc/traps.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 1999, 2000 Philipp Rumpf <prumpf@tux.org>
6 */
7
8 /*
9 * 'Traps.c' handles hardware traps and faults after we have saved some
10 * state in 'asm.s'.
11 */
12
13 #include <linux/sched.h>
14 #include <linux/kernel.h>
15 #include <linux/string.h>
16 #include <linux/errno.h>
17 #include <linux/ptrace.h>
18 #include <linux/timer.h>
19 #include <linux/mm.h>
20 #include <linux/module.h>
21 #include <linux/smp.h>
22 #include <linux/smp_lock.h>
23 #include <linux/spinlock.h>
24 #include <linux/init.h>
25 #include <linux/interrupt.h>
26 #include <linux/console.h>
27 #include <linux/kallsyms.h>
28
29 #include <asm/assembly.h>
30 #include <asm/system.h>
31 #include <asm/uaccess.h>
32 #include <asm/io.h>
33 #include <asm/irq.h>
34 #include <asm/traps.h>
35 #include <asm/unaligned.h>
36 #include <asm/atomic.h>
37 #include <asm/smp.h>
38 #include <asm/pdc.h>
39 #include <asm/pdc_chassis.h>
40 #include <asm/unwind.h>
41
42 #include "../math-emu/math-emu.h" /* for handle_fpe() */
43
44 #define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */
45 /* dumped to the console via printk) */
46
47 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
48 DEFINE_SPINLOCK(pa_dbit_lock);
49 #endif
50
51 int printbinary(char *buf, unsigned long x, int nbits)
52 {
53 unsigned long mask = 1UL << (nbits - 1);
54 while (mask != 0) {
55 *buf++ = (mask & x ? '1' : '0');
56 mask >>= 1;
57 }
58 *buf = '\0';
59
60 return nbits;
61 }
62
63 #ifdef __LP64__
64 #define RFMT "%016lx"
65 #else
66 #define RFMT "%08lx"
67 #endif
68 #define FFMT "%016llx" /* fpregs are 64-bit always */
69
70 #define PRINTREGS(lvl,r,f,fmt,x) \
71 printk("%s%s%02d-%02d " fmt " " fmt " " fmt " " fmt "\n", \
72 lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1], \
73 (r)[(x)+2], (r)[(x)+3])
74
75 static void print_gr(char *level, struct pt_regs *regs)
76 {
77 int i;
78 char buf[64];
79
80 printk("%s\n", level);
81 printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level);
82 printbinary(buf, regs->gr[0], 32);
83 printk("%sPSW: %s %s\n", level, buf, print_tainted());
84
85 for (i = 0; i < 32; i += 4)
86 PRINTREGS(level, regs->gr, "r", RFMT, i);
87 }
88
89 static void print_fr(char *level, struct pt_regs *regs)
90 {
91 int i;
92 char buf[64];
93 struct { u32 sw[2]; } s;
94
95 /* FR are 64bit everywhere. Need to use asm to get the content
96 * of fpsr/fper1, and we assume that we won't have a FP Identify
97 * in our way, otherwise we're screwed.
98 * The fldd is used to restore the T-bit if there was one, as the
99 * store clears it anyway.
100 * PA2.0 book says "thou shall not use fstw on FPSR/FPERs" - T-Bone */
101 asm volatile ("fstd %%fr0,0(%1) \n\t"
102 "fldd 0(%1),%%fr0 \n\t"
103 : "=m" (s) : "r" (&s) : "r0");
104
105 printk("%s\n", level);
106 printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level);
107 printbinary(buf, s.sw[0], 32);
108 printk("%sFPSR: %s\n", level, buf);
109 printk("%sFPER1: %08x\n", level, s.sw[1]);
110
111 /* here we'll print fr0 again, tho it'll be meaningless */
112 for (i = 0; i < 32; i += 4)
113 PRINTREGS(level, regs->fr, "fr", FFMT, i);
114 }
115
116 void show_regs(struct pt_regs *regs)
117 {
118 int i;
119 char *level;
120 unsigned long cr30, cr31;
121
122 level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT;
123
124 print_gr(level, regs);
125
126 for (i = 0; i < 8; i += 4)
127 PRINTREGS(level, regs->sr, "sr", RFMT, i);
128
129 if (user_mode(regs))
130 print_fr(level, regs);
131
132 cr30 = mfctl(30);
133 cr31 = mfctl(31);
134 printk("%s\n", level);
135 printk("%sIASQ: " RFMT " " RFMT " IAOQ: " RFMT " " RFMT "\n",
136 level, regs->iasq[0], regs->iasq[1], regs->iaoq[0], regs->iaoq[1]);
137 printk("%s IIR: %08lx ISR: " RFMT " IOR: " RFMT "\n",
138 level, regs->iir, regs->isr, regs->ior);
139 printk("%s CPU: %8d CR30: " RFMT " CR31: " RFMT "\n",
140 level, current_thread_info()->cpu, cr30, cr31);
141 printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);
142 printk(level);
143 print_symbol(" IAOQ[0]: %s\n", regs->iaoq[0]);
144 printk(level);
145 print_symbol(" IAOQ[1]: %s\n", regs->iaoq[1]);
146 printk(level);
147 print_symbol(" RP(r2): %s\n", regs->gr[2]);
148 }
149
150
151 void dump_stack(void)
152 {
153 show_stack(NULL, NULL);
154 }
155
156 EXPORT_SYMBOL(dump_stack);
157
158 static void do_show_stack(struct unwind_frame_info *info)
159 {
160 int i = 1;
161
162 printk("Backtrace:\n");
163 while (i <= 16) {
164 if (unwind_once(info) < 0 || info->ip == 0)
165 break;
166
167 if (__kernel_text_address(info->ip)) {
168 printk(" [<" RFMT ">] ", info->ip);
169 #ifdef CONFIG_KALLSYMS
170 print_symbol("%s\n", info->ip);
171 #else
172 if ((i & 0x03) == 0)
173 printk("\n");
174 #endif
175 i++;
176 }
177 }
178 printk("\n");
179 }
180
181 void show_stack(struct task_struct *task, unsigned long *s)
182 {
183 struct unwind_frame_info info;
184
185 if (!task) {
186 unsigned long sp;
187 struct pt_regs *r;
188
189 HERE:
190 asm volatile ("copy %%r30, %0" : "=r"(sp));
191 r = kzalloc(sizeof(struct pt_regs), GFP_KERNEL);
192 if (!r)
193 return;
194 r->iaoq[0] = (unsigned long)&&HERE;
195 r->gr[2] = (unsigned long)__builtin_return_address(0);
196 r->gr[30] = sp;
197 unwind_frame_init(&info, current, r);
198 kfree(r);
199 } else {
200 unwind_frame_init_from_blocked_task(&info, task);
201 }
202
203 do_show_stack(&info);
204 }
205
206 void die_if_kernel(char *str, struct pt_regs *regs, long err)
207 {
208 if (user_mode(regs)) {
209 if (err == 0)
210 return; /* STFU */
211
212 printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
213 current->comm, current->pid, str, err, regs->iaoq[0]);
214 #ifdef PRINT_USER_FAULTS
215 /* XXX for debugging only */
216 show_regs(regs);
217 #endif
218 return;
219 }
220
221 oops_in_progress = 1;
222
223 /* Amuse the user in a SPARC fashion */
224 printk(
225 " _______________________________ \n"
226 " < Your System ate a SPARC! Gah! >\n"
227 " ------------------------------- \n"
228 " \\ ^__^\n"
229 " \\ (xx)\\_______\n"
230 " (__)\\ )\\/\\\n"
231 " U ||----w |\n"
232 " || ||\n");
233
234 /* unlock the pdc lock if necessary */
235 pdc_emergency_unlock();
236
237 /* maybe the kernel hasn't booted very far yet and hasn't been able
238 * to initialize the serial or STI console. In that case we should
239 * re-enable the pdc console, so that the user will be able to
240 * identify the problem. */
241 if (!console_drivers)
242 pdc_console_restart();
243
244 printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
245 current->comm, current->pid, str, err);
246 show_regs(regs);
247
248 /* Wot's wrong wif bein' racy? */
249 if (current->thread.flags & PARISC_KERNEL_DEATH) {
250 printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__);
251 local_irq_enable();
252 while (1);
253 }
254
255 current->thread.flags |= PARISC_KERNEL_DEATH;
256 do_exit(SIGSEGV);
257 }
258
259 int syscall_ipi(int (*syscall) (struct pt_regs *), struct pt_regs *regs)
260 {
261 return syscall(regs);
262 }
263
264 /* gdb uses break 4,8 */
265 #define GDB_BREAK_INSN 0x10004
266 void handle_gdb_break(struct pt_regs *regs, int wot)
267 {
268 struct siginfo si;
269
270 si.si_code = wot;
271 si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
272 si.si_signo = SIGTRAP;
273 si.si_errno = 0;
274 force_sig_info(SIGTRAP, &si, current);
275 }
276
277 void handle_break(unsigned iir, struct pt_regs *regs)
278 {
279 struct siginfo si;
280
281 switch(iir) {
282 case 0x00:
283 #ifdef PRINT_USER_FAULTS
284 printk(KERN_DEBUG "break 0,0: pid=%d command='%s'\n",
285 current->pid, current->comm);
286 #endif
287 die_if_kernel("Breakpoint", regs, 0);
288 #ifdef PRINT_USER_FAULTS
289 show_regs(regs);
290 #endif
291 si.si_code = TRAP_BRKPT;
292 si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
293 si.si_signo = SIGTRAP;
294 force_sig_info(SIGTRAP, &si, current);
295 break;
296
297 case GDB_BREAK_INSN:
298 die_if_kernel("Breakpoint", regs, 0);
299 handle_gdb_break(regs, TRAP_BRKPT);
300 break;
301
302 default:
303 #ifdef PRINT_USER_FAULTS
304 printk(KERN_DEBUG "break %#08x: pid=%d command='%s'\n",
305 iir, current->pid, current->comm);
306 show_regs(regs);
307 #endif
308 si.si_signo = SIGTRAP;
309 si.si_code = TRAP_BRKPT;
310 si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
311 force_sig_info(SIGTRAP, &si, current);
312 return;
313 }
314 }
315
316
317 int handle_toc(void)
318 {
319 printk(KERN_CRIT "TOC call.\n");
320 return 0;
321 }
322
323 static void default_trap(int code, struct pt_regs *regs)
324 {
325 printk(KERN_ERR "Trap %d on CPU %d\n", code, smp_processor_id());
326 show_regs(regs);
327 }
328
329 void (*cpu_lpmc) (int code, struct pt_regs *regs) = default_trap;
330
331
332 void transfer_pim_to_trap_frame(struct pt_regs *regs)
333 {
334 register int i;
335 extern unsigned int hpmc_pim_data[];
336 struct pdc_hpmc_pim_11 *pim_narrow;
337 struct pdc_hpmc_pim_20 *pim_wide;
338
339 if (boot_cpu_data.cpu_type >= pcxu) {
340
341 pim_wide = (struct pdc_hpmc_pim_20 *)hpmc_pim_data;
342
343 /*
344 * Note: The following code will probably generate a
345 * bunch of truncation error warnings from the compiler.
346 * Could be handled with an ifdef, but perhaps there
347 * is a better way.
348 */
349
350 regs->gr[0] = pim_wide->cr[22];
351
352 for (i = 1; i < 32; i++)
353 regs->gr[i] = pim_wide->gr[i];
354
355 for (i = 0; i < 32; i++)
356 regs->fr[i] = pim_wide->fr[i];
357
358 for (i = 0; i < 8; i++)
359 regs->sr[i] = pim_wide->sr[i];
360
361 regs->iasq[0] = pim_wide->cr[17];
362 regs->iasq[1] = pim_wide->iasq_back;
363 regs->iaoq[0] = pim_wide->cr[18];
364 regs->iaoq[1] = pim_wide->iaoq_back;
365
366 regs->sar = pim_wide->cr[11];
367 regs->iir = pim_wide->cr[19];
368 regs->isr = pim_wide->cr[20];
369 regs->ior = pim_wide->cr[21];
370 }
371 else {
372 pim_narrow = (struct pdc_hpmc_pim_11 *)hpmc_pim_data;
373
374 regs->gr[0] = pim_narrow->cr[22];
375
376 for (i = 1; i < 32; i++)
377 regs->gr[i] = pim_narrow->gr[i];
378
379 for (i = 0; i < 32; i++)
380 regs->fr[i] = pim_narrow->fr[i];
381
382 for (i = 0; i < 8; i++)
383 regs->sr[i] = pim_narrow->sr[i];
384
385 regs->iasq[0] = pim_narrow->cr[17];
386 regs->iasq[1] = pim_narrow->iasq_back;
387 regs->iaoq[0] = pim_narrow->cr[18];
388 regs->iaoq[1] = pim_narrow->iaoq_back;
389
390 regs->sar = pim_narrow->cr[11];
391 regs->iir = pim_narrow->cr[19];
392 regs->isr = pim_narrow->cr[20];
393 regs->ior = pim_narrow->cr[21];
394 }
395
396 /*
397 * The following fields only have meaning if we came through
398 * another path. So just zero them here.
399 */
400
401 regs->ksp = 0;
402 regs->kpc = 0;
403 regs->orig_r28 = 0;
404 }
405
406
407 /*
408 * This routine is called as a last resort when everything else
409 * has gone clearly wrong. We get called for faults in kernel space,
410 * and HPMC's.
411 */
412 void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset)
413 {
414 static DEFINE_SPINLOCK(terminate_lock);
415
416 oops_in_progress = 1;
417
418 set_eiem(0);
419 local_irq_disable();
420 spin_lock(&terminate_lock);
421
422 /* unlock the pdc lock if necessary */
423 pdc_emergency_unlock();
424
425 /* restart pdc console if necessary */
426 if (!console_drivers)
427 pdc_console_restart();
428
429 /* Not all paths will gutter the processor... */
430 switch(code){
431
432 case 1:
433 transfer_pim_to_trap_frame(regs);
434 break;
435
436 default:
437 /* Fall through */
438 break;
439
440 }
441
442 {
443 /* show_stack(NULL, (unsigned long *)regs->gr[30]); */
444 struct unwind_frame_info info;
445 unwind_frame_init(&info, current, regs);
446 do_show_stack(&info);
447 }
448
449 printk("\n");
450 printk(KERN_CRIT "%s: Code=%d regs=%p (Addr=" RFMT ")\n",
451 msg, code, regs, offset);
452 show_regs(regs);
453
454 spin_unlock(&terminate_lock);
455
456 /* put soft power button back under hardware control;
457 * if the user had pressed it once at any time, the
458 * system will shut down immediately right here. */
459 pdc_soft_power_button(0);
460
461 /* Call kernel panic() so reboot timeouts work properly
462 * FIXME: This function should be on the list of
463 * panic notifiers, and we should call panic
464 * directly from the location that we wish.
465 * e.g. We should not call panic from
466 * parisc_terminate, but rather the oter way around.
467 * This hack works, prints the panic message twice,
468 * and it enables reboot timers!
469 */
470 panic(msg);
471 }
472
473 void handle_interruption(int code, struct pt_regs *regs)
474 {
475 unsigned long fault_address = 0;
476 unsigned long fault_space = 0;
477 struct siginfo si;
478
479 if (code == 1)
480 pdc_console_restart(); /* switch back to pdc if HPMC */
481 else
482 local_irq_enable();
483
484 /* Security check:
485 * If the priority level is still user, and the
486 * faulting space is not equal to the active space
487 * then the user is attempting something in a space
488 * that does not belong to them. Kill the process.
489 *
490 * This is normally the situation when the user
491 * attempts to jump into the kernel space at the
492 * wrong offset, be it at the gateway page or a
493 * random location.
494 *
495 * We cannot normally signal the process because it
496 * could *be* on the gateway page, and processes
497 * executing on the gateway page can't have signals
498 * delivered.
499 *
500 * We merely readjust the address into the users
501 * space, at a destination address of zero, and
502 * allow processing to continue.
503 */
504 if (((unsigned long)regs->iaoq[0] & 3) &&
505 ((unsigned long)regs->iasq[0] != (unsigned long)regs->sr[7])) {
506 /* Kill the user process later */
507 regs->iaoq[0] = 0 | 3;
508 regs->iaoq[1] = regs->iaoq[0] + 4;
509 regs->iasq[0] = regs->iasq[0] = regs->sr[7];
510 regs->gr[0] &= ~PSW_B;
511 return;
512 }
513
514 #if 0
515 printk(KERN_CRIT "Interruption # %d\n", code);
516 #endif
517
518 switch(code) {
519
520 case 1:
521 /* High-priority machine check (HPMC) */
522
523 /* set up a new led state on systems shipped with a LED State panel */
524 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC);
525
526 parisc_terminate("High Priority Machine Check (HPMC)",
527 regs, code, 0);
528 /* NOT REACHED */
529
530 case 2:
531 /* Power failure interrupt */
532 printk(KERN_CRIT "Power failure interrupt !\n");
533 return;
534
535 case 3:
536 /* Recovery counter trap */
537 regs->gr[0] &= ~PSW_R;
538 if (user_space(regs))
539 handle_gdb_break(regs, TRAP_TRACE);
540 /* else this must be the start of a syscall - just let it run */
541 return;
542
543 case 5:
544 /* Low-priority machine check */
545 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC);
546
547 flush_all_caches();
548 cpu_lpmc(5, regs);
549 return;
550
551 case 6:
552 /* Instruction TLB miss fault/Instruction page fault */
553 fault_address = regs->iaoq[0];
554 fault_space = regs->iasq[0];
555 break;
556
557 case 8:
558 /* Illegal instruction trap */
559 die_if_kernel("Illegal instruction", regs, code);
560 si.si_code = ILL_ILLOPC;
561 goto give_sigill;
562
563 case 9:
564 /* Break instruction trap */
565 handle_break(regs->iir,regs);
566 return;
567
568 case 10:
569 /* Privileged operation trap */
570 die_if_kernel("Privileged operation", regs, code);
571 si.si_code = ILL_PRVOPC;
572 goto give_sigill;
573
574 case 11:
575 /* Privileged register trap */
576 if ((regs->iir & 0xffdfffe0) == 0x034008a0) {
577
578 /* This is a MFCTL cr26/cr27 to gr instruction.
579 * PCXS traps on this, so we need to emulate it.
580 */
581
582 if (regs->iir & 0x00200000)
583 regs->gr[regs->iir & 0x1f] = mfctl(27);
584 else
585 regs->gr[regs->iir & 0x1f] = mfctl(26);
586
587 regs->iaoq[0] = regs->iaoq[1];
588 regs->iaoq[1] += 4;
589 regs->iasq[0] = regs->iasq[1];
590 return;
591 }
592
593 die_if_kernel("Privileged register usage", regs, code);
594 si.si_code = ILL_PRVREG;
595 give_sigill:
596 si.si_signo = SIGILL;
597 si.si_errno = 0;
598 si.si_addr = (void __user *) regs->iaoq[0];
599 force_sig_info(SIGILL, &si, current);
600 return;
601
602 case 12:
603 /* Overflow Trap, let the userland signal handler do the cleanup */
604 si.si_signo = SIGFPE;
605 si.si_code = FPE_INTOVF;
606 si.si_addr = (void __user *) regs->iaoq[0];
607 force_sig_info(SIGFPE, &si, current);
608 return;
609
610 case 13:
611 /* Conditional Trap
612 The condition succees in an instruction which traps
613 on condition */
614 if(user_mode(regs)){
615 si.si_signo = SIGFPE;
616 /* Set to zero, and let the userspace app figure it out from
617 the insn pointed to by si_addr */
618 si.si_code = 0;
619 si.si_addr = (void __user *) regs->iaoq[0];
620 force_sig_info(SIGFPE, &si, current);
621 return;
622 }
623 /* The kernel doesn't want to handle condition codes */
624 break;
625
626 case 14:
627 /* Assist Exception Trap, i.e. floating point exception. */
628 die_if_kernel("Floating point exception", regs, 0); /* quiet */
629 handle_fpe(regs);
630 return;
631
632 case 15:
633 /* Data TLB miss fault/Data page fault */
634 /* Fall through */
635 case 16:
636 /* Non-access instruction TLB miss fault */
637 /* The instruction TLB entry needed for the target address of the FIC
638 is absent, and hardware can't find it, so we get to cleanup */
639 /* Fall through */
640 case 17:
641 /* Non-access data TLB miss fault/Non-access data page fault */
642 /* FIXME:
643 Still need to add slow path emulation code here!
644 If the insn used a non-shadow register, then the tlb
645 handlers could not have their side-effect (e.g. probe
646 writing to a target register) emulated since rfir would
647 erase the changes to said register. Instead we have to
648 setup everything, call this function we are in, and emulate
649 by hand. Technically we need to emulate:
650 fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw
651 */
652 fault_address = regs->ior;
653 fault_space = regs->isr;
654 break;
655
656 case 18:
657 /* PCXS only -- later cpu's split this into types 26,27 & 28 */
658 /* Check for unaligned access */
659 if (check_unaligned(regs)) {
660 handle_unaligned(regs);
661 return;
662 }
663 /* Fall Through */
664 case 26:
665 /* PCXL: Data memory access rights trap */
666 fault_address = regs->ior;
667 fault_space = regs->isr;
668 break;
669
670 case 19:
671 /* Data memory break trap */
672 regs->gr[0] |= PSW_X; /* So we can single-step over the trap */
673 /* fall thru */
674 case 21:
675 /* Page reference trap */
676 handle_gdb_break(regs, TRAP_HWBKPT);
677 return;
678
679 case 25:
680 /* Taken branch trap */
681 regs->gr[0] &= ~PSW_T;
682 if (user_space(regs))
683 handle_gdb_break(regs, TRAP_BRANCH);
684 /* else this must be the start of a syscall - just let it
685 * run.
686 */
687 return;
688
689 case 7:
690 /* Instruction access rights */
691 /* PCXL: Instruction memory protection trap */
692
693 /*
694 * This could be caused by either: 1) a process attempting
695 * to execute within a vma that does not have execute
696 * permission, or 2) an access rights violation caused by a
697 * flush only translation set up by ptep_get_and_clear().
698 * So we check the vma permissions to differentiate the two.
699 * If the vma indicates we have execute permission, then
700 * the cause is the latter one. In this case, we need to
701 * call do_page_fault() to fix the problem.
702 */
703
704 if (user_mode(regs)) {
705 struct vm_area_struct *vma;
706
707 down_read(&current->mm->mmap_sem);
708 vma = find_vma(current->mm,regs->iaoq[0]);
709 if (vma && (regs->iaoq[0] >= vma->vm_start)
710 && (vma->vm_flags & VM_EXEC)) {
711
712 fault_address = regs->iaoq[0];
713 fault_space = regs->iasq[0];
714
715 up_read(&current->mm->mmap_sem);
716 break; /* call do_page_fault() */
717 }
718 up_read(&current->mm->mmap_sem);
719 }
720 /* Fall Through */
721 case 27:
722 /* Data memory protection ID trap */
723 die_if_kernel("Protection id trap", regs, code);
724 si.si_code = SEGV_MAPERR;
725 si.si_signo = SIGSEGV;
726 si.si_errno = 0;
727 if (code == 7)
728 si.si_addr = (void __user *) regs->iaoq[0];
729 else
730 si.si_addr = (void __user *) regs->ior;
731 force_sig_info(SIGSEGV, &si, current);
732 return;
733
734 case 28:
735 /* Unaligned data reference trap */
736 handle_unaligned(regs);
737 return;
738
739 default:
740 if (user_mode(regs)) {
741 #ifdef PRINT_USER_FAULTS
742 printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n",
743 current->pid, current->comm);
744 show_regs(regs);
745 #endif
746 /* SIGBUS, for lack of a better one. */
747 si.si_signo = SIGBUS;
748 si.si_code = BUS_OBJERR;
749 si.si_errno = 0;
750 si.si_addr = (void __user *) regs->ior;
751 force_sig_info(SIGBUS, &si, current);
752 return;
753 }
754 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
755
756 parisc_terminate("Unexpected interruption", regs, code, 0);
757 /* NOT REACHED */
758 }
759
760 if (user_mode(regs)) {
761 if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) {
762 #ifdef PRINT_USER_FAULTS
763 if (fault_space == 0)
764 printk(KERN_DEBUG "User Fault on Kernel Space ");
765 else
766 printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ",
767 code);
768 printk("pid=%d command='%s'\n", current->pid, current->comm);
769 show_regs(regs);
770 #endif
771 si.si_signo = SIGSEGV;
772 si.si_errno = 0;
773 si.si_code = SEGV_MAPERR;
774 si.si_addr = (void __user *) regs->ior;
775 force_sig_info(SIGSEGV, &si, current);
776 return;
777 }
778 }
779 else {
780
781 /*
782 * The kernel should never fault on its own address space.
783 */
784
785 if (fault_space == 0)
786 {
787 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
788 parisc_terminate("Kernel Fault", regs, code, fault_address);
789
790 }
791 }
792
793 do_page_fault(regs, code, fault_address);
794 }
795
796
797 int __init check_ivt(void *iva)
798 {
799 int i;
800 u32 check = 0;
801 u32 *ivap;
802 u32 *hpmcp;
803 u32 length;
804 extern void os_hpmc(void);
805 extern void os_hpmc_end(void);
806
807 if (strcmp((char *)iva, "cows can fly"))
808 return -1;
809
810 ivap = (u32 *)iva;
811
812 for (i = 0; i < 8; i++)
813 *ivap++ = 0;
814
815 /* Compute Checksum for HPMC handler */
816
817 length = (u32)((unsigned long)os_hpmc_end - (unsigned long)os_hpmc);
818 ivap[7] = length;
819
820 hpmcp = (u32 *)os_hpmc;
821
822 for (i=0; i<length/4; i++)
823 check += *hpmcp++;
824
825 for (i=0; i<8; i++)
826 check += ivap[i];
827
828 ivap[5] = -check;
829
830 return 0;
831 }
832
833 #ifndef __LP64__
834 extern const void fault_vector_11;
835 #endif
836 extern const void fault_vector_20;
837
838 void __init trap_init(void)
839 {
840 void *iva;
841
842 if (boot_cpu_data.cpu_type >= pcxu)
843 iva = (void *) &fault_vector_20;
844 else
845 #ifdef __LP64__
846 panic("Can't boot 64-bit OS on PA1.1 processor!");
847 #else
848 iva = (void *) &fault_vector_11;
849 #endif
850
851 if (check_ivt(iva))
852 panic("IVT invalid");
853 }
This page took 0.049855 seconds and 6 git commands to generate.