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