11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/arch/parisc/traps.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999, 2000 Philipp Rumpf <prumpf@tux.org> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 'Traps.c' handles hardware traps and faults after we have saved some 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * state in 'asm.s'. 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ptrace.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/timer.h> 1922fced881122f7fc6f5f259dca03ac6d5c601404Helge Deller#include <linux/delay.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/smp.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/spinlock.h> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/console.h> 276891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller#include <linux/bug.h> 28fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller#include <linux/ratelimit.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/assembly.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/traps.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/unaligned.h> 3660063497a95e716c9a689af3be2687d261f115b4Arun Sharma#include <linux/atomic.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/smp.h> 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/pdc.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/pdc_chassis.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/unwind.h> 41d6ce8626dbc7d277d29b62e31c24ce777c60546bRandolph Chung#include <asm/tlbflush.h> 42d6ce8626dbc7d277d29b62e31c24ce777c60546bRandolph Chung#include <asm/cacheflush.h> 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "../math-emu/math-emu.h" /* for handle_fpe() */ 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsDEFINE_SPINLOCK(pa_dbit_lock); 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 507a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Dellerstatic void parisc_show_stack(struct task_struct *task, unsigned long *sp, 51dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin struct pt_regs *regs); 52dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin 536891f8a1135b964f8ef30521d1473d5d137af0faHelge Dellerstatic int printbinary(char *buf, unsigned long x, int nbits) 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long mask = 1UL << (nbits - 1); 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (mask != 0) { 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *buf++ = (mask & x ? '1' : '0'); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask >>= 1; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *buf = '\0'; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return nbits; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 65a8f44e3889b686813926b288bd4e51a0cf17d2c7Helge Deller#ifdef CONFIG_64BIT 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RFMT "%016lx" 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RFMT "%08lx" 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 701c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin#define FFMT "%016llx" /* fpregs are 64-bit always */ 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 721c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin#define PRINTREGS(lvl,r,f,fmt,x) \ 731c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin printk("%s%s%02d-%02d " fmt " " fmt " " fmt " " fmt "\n", \ 741c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1], \ 751c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin (r)[(x)+2], (r)[(x)+3]) 761c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin 771c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartinstatic void print_gr(char *level, struct pt_regs *regs) 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 801c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin char buf[64]; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin printk("%s\n", level); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level); 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printbinary(buf, regs->gr[0], 32); 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%sPSW: %s %s\n", level, buf, print_tainted()); 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 871c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin for (i = 0; i < 32; i += 4) 881c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin PRINTREGS(level, regs->gr, "r", RFMT, i); 891c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin} 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartinstatic void print_fr(char *level, struct pt_regs *regs) 921c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin{ 931c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin int i; 941c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin char buf[64]; 951c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin struct { u32 sw[2]; } s; 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 97eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene /* FR are 64bit everywhere. Need to use asm to get the content 98eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene * of fpsr/fper1, and we assume that we won't have a FP Identify 99eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene * in our way, otherwise we're screwed. 100eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene * The fldd is used to restore the T-bit if there was one, as the 101eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene * store clears it anyway. 1021c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin * PA2.0 book says "thou shall not use fstw on FPSR/FPERs" - T-Bone */ 1031c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin asm volatile ("fstd %%fr0,0(%1) \n\t" 1041c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin "fldd 0(%1),%%fr0 \n\t" 1051c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin : "=m" (s) : "r" (&s) : "r0"); 106eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene 107eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene printk("%s\n", level); 108eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level); 109eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene printbinary(buf, s.sw[0], 32); 110eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene printk("%sFPSR: %s\n", level, buf); 111eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene printk("%sFPER1: %08x\n", level, s.sw[1]); 112eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene 113eba917273eb8579dd8ae36f6645518ca5579a2abThibaut Varene /* here we'll print fr0 again, tho it'll be meaningless */ 1141c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin for (i = 0; i < 32; i += 4) 1151c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin PRINTREGS(level, regs->fr, "fr", FFMT, i); 1161c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin} 1171c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin 1181c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartinvoid show_regs(struct pt_regs *regs) 1191c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin{ 1207a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller int i, user; 1211c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin char *level; 1221c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin unsigned long cr30, cr31; 1231c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin 1247a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller user = user_mode(regs); 1257a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller level = user ? KERN_DEBUG : KERN_CRIT; 1261c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin 127a43cb95d547a061ed5bf1acb28e0f5fd575e26c1Tejun Heo show_regs_print_info(level); 128a43cb95d547a061ed5bf1acb28e0f5fd575e26c1Tejun Heo 1291c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin print_gr(level, regs); 1301c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin 1311c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin for (i = 0; i < 8; i += 4) 1321c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin PRINTREGS(level, regs->sr, "sr", RFMT, i); 1331c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin 1347a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller if (user) 1351c63b4b8474700f3fb5e3442a78897766f153437Kyle McMartin print_fr(level, regs); 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cr30 = mfctl(30); 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cr31 = mfctl(31); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s\n", level); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%sIASQ: " RFMT " " RFMT " IAOQ: " RFMT " " RFMT "\n", 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds level, regs->iasq[0], regs->iasq[1], regs->iaoq[0], regs->iaoq[1]); 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s IIR: %08lx ISR: " RFMT " IOR: " RFMT "\n", 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds level, regs->iir, regs->isr, regs->ior); 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s CPU: %8d CR30: " RFMT " CR31: " RFMT "\n", 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds level, current_thread_info()->cpu, cr30, cr31); 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28); 1477a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller 1487a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller if (user) { 1497a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller printk("%s IAOQ[0]: " RFMT "\n", level, regs->iaoq[0]); 1507a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller printk("%s IAOQ[1]: " RFMT "\n", level, regs->iaoq[1]); 1517a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller printk("%s RP(r2): " RFMT "\n", level, regs->gr[2]); 1527a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller } else { 1537a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller printk("%s IAOQ[0]: %pS\n", level, (void *) regs->iaoq[0]); 1547a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]); 1557a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]); 1567a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller 1577a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller parisc_show_stack(current, NULL, regs); 1587a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller } 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 161fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Dellerstatic DEFINE_RATELIMIT_STATE(_hppa_rs, 162fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); 163fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller 164fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller#define parisc_printk_ratelimited(critical, regs, fmt, ...) { \ 165fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller if ((critical || show_unhandled_signals) && __ratelimit(&_hppa_rs)) { \ 166fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller printk(fmt, ##__VA_ARGS__); \ 167fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller show_regs(regs); \ 168fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller } \ 169fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller} 170fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller 171fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void do_show_stack(struct unwind_frame_info *info) 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 1; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 176bd83bcffb2a582ddac0b463153a4c1fda4335273Helge Deller printk(KERN_CRIT "Backtrace:\n"); 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (i <= 16) { 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (unwind_once(info) < 0 || info->ip == 0) 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (__kernel_text_address(info->ip)) { 1827a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller printk(KERN_CRIT " [<" RFMT ">] %pS\n", 1837a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller info->ip, (void *) info->ip); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i++; 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1877a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Deller printk(KERN_CRIT "\n"); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1907a3f5134a8f5bd7fa38b5645eef05e8a4eb62951Helge Dellerstatic void parisc_show_stack(struct task_struct *task, unsigned long *sp, 191dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin struct pt_regs *regs) 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct unwind_frame_info info; 194dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin struct task_struct *t; 195dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin 196dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin t = task ? task : current; 197dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin if (regs) { 198dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin unwind_frame_init(&info, t, regs); 199dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin goto show_stack; 200dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin } 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 202dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin if (t == current) { 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long sp; 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsHERE: 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds asm volatile ("copy %%r30, %0" : "=r"(sp)); 2079f15c82686251cd2b97ac6859de62959d3c4afe1Matthew Wilcox { 2089f15c82686251cd2b97ac6859de62959d3c4afe1Matthew Wilcox struct pt_regs r; 2099f15c82686251cd2b97ac6859de62959d3c4afe1Matthew Wilcox 2109f15c82686251cd2b97ac6859de62959d3c4afe1Matthew Wilcox memset(&r, 0, sizeof(struct pt_regs)); 2119f15c82686251cd2b97ac6859de62959d3c4afe1Matthew Wilcox r.iaoq[0] = (unsigned long)&&HERE; 2129f15c82686251cd2b97ac6859de62959d3c4afe1Matthew Wilcox r.gr[2] = (unsigned long)__builtin_return_address(0); 2139f15c82686251cd2b97ac6859de62959d3c4afe1Matthew Wilcox r.gr[30] = sp; 2149f15c82686251cd2b97ac6859de62959d3c4afe1Matthew Wilcox 2159f15c82686251cd2b97ac6859de62959d3c4afe1Matthew Wilcox unwind_frame_init(&info, current, &r); 2169f15c82686251cd2b97ac6859de62959d3c4afe1Matthew Wilcox } 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 218dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin unwind_frame_init_from_blocked_task(&info, t); 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartinshow_stack: 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do_show_stack(&info); 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 225dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartinvoid show_stack(struct task_struct *t, unsigned long *sp) 226dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin{ 227dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin return parisc_show_stack(t, sp, NULL); 228dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin} 229dc39455e7948ec9bc5f3f2dced5c2f5ac8a8dfd9Kyle McMartin 2306891f8a1135b964f8ef30521d1473d5d137af0faHelge Dellerint is_valid_bugaddr(unsigned long iaoq) 2316891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller{ 2326891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller return 1; 2336891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller} 2346891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid die_if_kernel(char *str, struct pt_regs *regs, long err) 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (user_mode(regs)) { 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err == 0) 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; /* STFU */ 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 241fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller parisc_printk_ratelimited(1, regs, 242fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n", 24319c5870c0eefd27c6d09d867465e0571262e05d0Alexey Dobriyan current->comm, task_pid_nr(current), str, err, regs->iaoq[0]); 244fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oops_in_progress = 1; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 250c48faf86b0d59cc43ff4eede59c4af7afbd7c0ffHelge Deller oops_enter(); 251c48faf86b0d59cc43ff4eede59c4af7afbd7c0ffHelge Deller 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Amuse the user in a SPARC fashion */ 253ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches if (err) printk(KERN_CRIT 254ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches " _______________________________ \n" 255ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches " < Your System ate a SPARC! Gah! >\n" 256ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches " ------------------------------- \n" 257ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches " \\ ^__^\n" 258ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches " (__)\\ )\\/\\\n" 259ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches " U ||----w |\n" 260ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches " || ||\n"); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* unlock the pdc lock if necessary */ 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdc_emergency_unlock(); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* maybe the kernel hasn't booted very far yet and hasn't been able 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to initialize the serial or STI console. In that case we should 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * re-enable the pdc console, so that the user will be able to 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * identify the problem. */ 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!console_drivers) 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdc_console_restart(); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2726891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller if (err) 2736891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n", 27419c5870c0eefd27c6d09d867465e0571262e05d0Alexey Dobriyan current->comm, task_pid_nr(current), str, err); 275bd83bcffb2a582ddac0b463153a4c1fda4335273Helge Deller 2760bbdac0897a48f415eb788bf3263c92bd5e97ffbHelge Deller /* Wot's wrong wif bein' racy? */ 2770bbdac0897a48f415eb788bf3263c92bd5e97ffbHelge Deller if (current->thread.flags & PARISC_KERNEL_DEATH) { 27891bae23ce185b74c9b6dda86b92bb204a1c951c3Harvey Harrison printk(KERN_CRIT "%s() recursion detected.\n", __func__); 2790bbdac0897a48f415eb788bf3263c92bd5e97ffbHelge Deller local_irq_enable(); 2800bbdac0897a48f415eb788bf3263c92bd5e97ffbHelge Deller while (1); 2810bbdac0897a48f415eb788bf3263c92bd5e97ffbHelge Deller } 2820bbdac0897a48f415eb788bf3263c92bd5e97ffbHelge Deller current->thread.flags |= PARISC_KERNEL_DEATH; 2830bbdac0897a48f415eb788bf3263c92bd5e97ffbHelge Deller 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_regs(regs); 2850bbdac0897a48f415eb788bf3263c92bd5e97ffbHelge Deller dump_stack(); 286373d4d099761cb1f637bed488ab3871945882273Rusty Russell add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28822fced881122f7fc6f5f259dca03ac6d5c601404Helge Deller if (in_interrupt()) 28922fced881122f7fc6f5f259dca03ac6d5c601404Helge Deller panic("Fatal exception in interrupt"); 29022fced881122f7fc6f5f259dca03ac6d5c601404Helge Deller 29122fced881122f7fc6f5f259dca03ac6d5c601404Helge Deller if (panic_on_oops) { 29222fced881122f7fc6f5f259dca03ac6d5c601404Helge Deller printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); 29322fced881122f7fc6f5f259dca03ac6d5c601404Helge Deller ssleep(5); 29422fced881122f7fc6f5f259dca03ac6d5c601404Helge Deller panic("Fatal exception"); 29522fced881122f7fc6f5f259dca03ac6d5c601404Helge Deller } 29622fced881122f7fc6f5f259dca03ac6d5c601404Helge Deller 297c48faf86b0d59cc43ff4eede59c4af7afbd7c0ffHelge Deller oops_exit(); 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do_exit(SIGSEGV); 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* gdb uses break 4,8 */ 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define GDB_BREAK_INSN 0x10004 3036891f8a1135b964f8ef30521d1473d5d137af0faHelge Dellerstatic void handle_gdb_break(struct pt_regs *regs, int wot) 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct siginfo si; 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_signo = SIGTRAP; 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_errno = 0; 3096891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller si.si_code = wot; 3106891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller si.si_addr = (void __user *) (regs->iaoq[0] & ~3); 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds force_sig_info(SIGTRAP, &si, current); 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3146891f8a1135b964f8ef30521d1473d5d137af0faHelge Dellerstatic void handle_break(struct pt_regs *regs) 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3166891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller unsigned iir = regs->iir; 3176891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller 3186891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller if (unlikely(iir == PARISC_BUG_BREAK_INSN && !user_mode(regs))) { 3196891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller /* check if a BUG() or WARN() trapped here. */ 3206891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller enum bug_trap_type tt; 321608e2619682e951f525b08e7a48669a3c0263b41Heiko Carstens tt = report_bug(regs->iaoq[0] & ~3, regs); 3226891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller if (tt == BUG_TRAP_TYPE_WARN) { 3236891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller regs->iaoq[0] += 4; 3246891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller regs->iaoq[1] += 4; 3256891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller return; /* return to next instruction when WARN_ON(). */ 3266891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller } 3276891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller die_if_kernel("Unknown kernel breakpoint", regs, 3286891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0); 3296891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller } 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller if (unlikely(iir != GDB_BREAK_INSN)) 332fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller parisc_printk_ratelimited(0, regs, 333fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller KERN_DEBUG "break %d,%d: pid=%d command='%s'\n", 334df47b4386a473eba87095e6dea8046762434817dHelge Deller iir & 31, (iir>>13) & ((1<<13)-1), 33519c5870c0eefd27c6d09d867465e0571262e05d0Alexey Dobriyan task_pid_nr(current), current->comm); 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3376891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller /* send standard GDB signal */ 3386891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller handle_gdb_break(regs, TRAP_BRKPT); 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void default_trap(int code, struct pt_regs *regs) 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "Trap %d on CPU %d\n", code, smp_processor_id()); 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_regs(regs); 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3476891f8a1135b964f8ef30521d1473d5d137af0faHelge Dellervoid (*cpu_lpmc) (int code, struct pt_regs *regs) __read_mostly = default_trap; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid transfer_pim_to_trap_frame(struct pt_regs *regs) 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register int i; 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds extern unsigned int hpmc_pim_data[]; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pdc_hpmc_pim_11 *pim_narrow; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pdc_hpmc_pim_20 *pim_wide; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (boot_cpu_data.cpu_type >= pcxu) { 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pim_wide = (struct pdc_hpmc_pim_20 *)hpmc_pim_data; 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: The following code will probably generate a 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bunch of truncation error warnings from the compiler. 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Could be handled with an ifdef, but perhaps there 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is a better way. 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->gr[0] = pim_wide->cr[22]; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 1; i < 32; i++) 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->gr[i] = pim_wide->gr[i]; 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 32; i++) 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->fr[i] = pim_wide->fr[i]; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 8; i++) 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->sr[i] = pim_wide->sr[i]; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iasq[0] = pim_wide->cr[17]; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iasq[1] = pim_wide->iasq_back; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iaoq[0] = pim_wide->cr[18]; 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iaoq[1] = pim_wide->iaoq_back; 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->sar = pim_wide->cr[11]; 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iir = pim_wide->cr[19]; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->isr = pim_wide->cr[20]; 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->ior = pim_wide->cr[21]; 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pim_narrow = (struct pdc_hpmc_pim_11 *)hpmc_pim_data; 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->gr[0] = pim_narrow->cr[22]; 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 1; i < 32; i++) 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->gr[i] = pim_narrow->gr[i]; 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 32; i++) 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->fr[i] = pim_narrow->fr[i]; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 8; i++) 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->sr[i] = pim_narrow->sr[i]; 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iasq[0] = pim_narrow->cr[17]; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iasq[1] = pim_narrow->iasq_back; 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iaoq[0] = pim_narrow->cr[18]; 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iaoq[1] = pim_narrow->iaoq_back; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->sar = pim_narrow->cr[11]; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iir = pim_narrow->cr[19]; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->isr = pim_narrow->cr[20]; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->ior = pim_narrow->cr[21]; 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The following fields only have meaning if we came through 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * another path. So just zero them here. 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->ksp = 0; 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->kpc = 0; 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->orig_r28 = 0; 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This routine is called as a last resort when everything else 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * has gone clearly wrong. We get called for faults in kernel space, 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and HPMC's. 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset) 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static DEFINE_SPINLOCK(terminate_lock); 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oops_in_progress = 1; 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_eiem(0); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_disable(); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock(&terminate_lock); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* unlock the pdc lock if necessary */ 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdc_emergency_unlock(); 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* restart pdc console if necessary */ 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!console_drivers) 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdc_console_restart(); 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Not all paths will gutter the processor... */ 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(code){ 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds transfer_pim_to_trap_frame(regs); 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Fall through */ 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* show_stack(NULL, (unsigned long *)regs->gr[30]); */ 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct unwind_frame_info info; 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unwind_frame_init(&info, current, regs); 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do_show_stack(&info); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("\n"); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_CRIT "%s: Code=%d regs=%p (Addr=" RFMT ")\n", 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg, code, regs, offset); 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_regs(regs); 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock(&terminate_lock); 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* put soft power button back under hardware control; 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if the user had pressed it once at any time, the 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * system will shut down immediately right here. */ 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdc_soft_power_button(0); 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Call kernel panic() so reboot timeouts work properly 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FIXME: This function should be on the list of 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * panic notifiers, and we should call panic 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * directly from the location that we wish. 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * e.g. We should not call panic from 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * parisc_terminate, but rather the oter way around. 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This hack works, prints the panic message twice, 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and it enables reboot timers! 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds panic(msg); 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491d75f054a2cf0614ff63d534ff21ca8eaab41e713Helge Dellervoid notrace handle_interruption(int code, struct pt_regs *regs) 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long fault_address = 0; 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long fault_space = 0; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct siginfo si; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (code == 1) 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdc_console_restart(); /* switch back to pdc if HPMC */ 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_enable(); 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Security check: 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the priority level is still user, and the 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * faulting space is not equal to the active space 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * then the user is attempting something in a space 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that does not belong to them. Kill the process. 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is normally the situation when the user 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * attempts to jump into the kernel space at the 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * wrong offset, be it at the gateway page or a 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * random location. 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We cannot normally signal the process because it 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * could *be* on the gateway page, and processes 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * executing on the gateway page can't have signals 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * delivered. 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We merely readjust the address into the users 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * space, at a destination address of zero, and 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * allow processing to continue. 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((unsigned long)regs->iaoq[0] & 3) && 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((unsigned long)regs->iasq[0] != (unsigned long)regs->sr[7])) { 524a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer /* Kill the user process later */ 525a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer regs->iaoq[0] = 0 | 3; 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iaoq[1] = regs->iaoq[0] + 4; 527a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer regs->iasq[0] = regs->iasq[1] = regs->sr[7]; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->gr[0] &= ~PSW_B; 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_CRIT "Interruption # %d\n", code); 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(code) { 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* High-priority machine check (HPMC) */ 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set up a new led state on systems shipped with a LED State panel */ 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC); 543a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer 544a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer parisc_terminate("High Priority Machine Check (HPMC)", 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs, code, 0); 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* NOT REACHED */ 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Power failure interrupt */ 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_CRIT "Power failure interrupt !\n"); 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Recovery counter trap */ 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->gr[0] &= ~PSW_R; 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (user_space(regs)) 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handle_gdb_break(regs, TRAP_TRACE); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* else this must be the start of a syscall - just let it run */ 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 5: 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Low-priority machine check */ 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC); 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 565d6ce8626dbc7d277d29b62e31c24ce777c60546bRandolph Chung flush_cache_all(); 566d6ce8626dbc7d277d29b62e31c24ce777c60546bRandolph Chung flush_tlb_all(); 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_lpmc(5, regs); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 6: 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Instruction TLB miss fault/Instruction page fault */ 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_address = regs->iaoq[0]; 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_space = regs->iasq[0]; 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 8: 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Illegal instruction trap */ 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds die_if_kernel("Illegal instruction", regs, code); 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_code = ILL_ILLOPC; 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto give_sigill; 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 9: 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Break instruction trap */ 5846891f8a1135b964f8ef30521d1473d5d137af0faHelge Deller handle_break(regs); 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 586a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 10: 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Privileged operation trap */ 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds die_if_kernel("Privileged operation", regs, code); 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_code = ILL_PRVOPC; 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto give_sigill; 592a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 11: 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Privileged register trap */ 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((regs->iir & 0xffdfffe0) == 0x034008a0) { 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This is a MFCTL cr26/cr27 to gr instruction. 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PCXS traps on this, so we need to emulate it. 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (regs->iir & 0x00200000) 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->gr[regs->iir & 0x1f] = mfctl(27); 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->gr[regs->iir & 0x1f] = mfctl(26); 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iaoq[0] = regs->iaoq[1]; 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iaoq[1] += 4; 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->iasq[0] = regs->iasq[1]; 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds die_if_kernel("Privileged register usage", regs, code); 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_code = ILL_PRVREG; 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds give_sigill: 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_signo = SIGILL; 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_errno = 0; 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_addr = (void __user *) regs->iaoq[0]; 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds force_sig_info(SIGILL, &si, current); 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 12: 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Overflow Trap, let the userland signal handler do the cleanup */ 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_signo = SIGFPE; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_code = FPE_INTOVF; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_addr = (void __user *) regs->iaoq[0]; 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds force_sig_info(SIGFPE, &si, current); 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 13: 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Conditional Trap 6317022672e4046fac4699aa5f8ff2a5213b7ec4ff9Simon Arlott The condition succeeds in an instruction which traps 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds on condition */ 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(user_mode(regs)){ 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_signo = SIGFPE; 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set to zero, and let the userspace app figure it out from 636a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer the insn pointed to by si_addr */ 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_code = 0; 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_addr = (void __user *) regs->iaoq[0]; 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds force_sig_info(SIGFPE, &si, current); 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* The kernel doesn't want to handle condition codes */ 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 14: 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Assist Exception Trap, i.e. floating point exception. */ 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds die_if_kernel("Floating point exception", regs, 0); /* quiet */ 648d0c3be806a3fe7f4abdb0f7e7287addb55e73f35Helge Deller __inc_irq_stat(irq_fpassist_count); 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handle_fpe(regs); 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 651a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 15: 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Data TLB miss fault/Data page fault */ 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Fall through */ 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 16: 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Non-access instruction TLB miss fault */ 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* The instruction TLB entry needed for the target address of the FIC 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds is absent, and hardware can't find it, so we get to cleanup */ 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Fall through */ 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 17: 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Non-access data TLB miss fault/Non-access data page fault */ 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FIXME: 663a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer Still need to add slow path emulation code here! 664a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer If the insn used a non-shadow register, then the tlb 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handlers could not have their side-effect (e.g. probe 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writing to a target register) emulated since rfir would 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds erase the changes to said register. Instead we have to 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setup everything, call this function we are in, and emulate 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds by hand. Technically we need to emulate: 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw 671a39e6beaa1455407af7b0bb6f501e9135987334bRolf Eike Beer */ 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_address = regs->ior; 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_space = regs->isr; 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 18: 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* PCXS only -- later cpu's split this into types 26,27 & 28 */ 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check for unaligned access */ 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (check_unaligned(regs)) { 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handle_unaligned(regs); 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Fall Through */ 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 26: 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* PCXL: Data memory access rights trap */ 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_address = regs->ior; 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_space = regs->isr; 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 19: 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Data memory break trap */ 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->gr[0] |= PSW_X; /* So we can single-step over the trap */ 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* fall thru */ 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 21: 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Page reference trap */ 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handle_gdb_break(regs, TRAP_HWBKPT); 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 25: 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Taken branch trap */ 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regs->gr[0] &= ~PSW_T; 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (user_space(regs)) 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handle_gdb_break(regs, TRAP_BRANCH); 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* else this must be the start of a syscall - just let it 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * run. 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 7: 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Instruction access rights */ 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* PCXL: Instruction memory protection trap */ 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This could be caused by either: 1) a process attempting 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to execute within a vma that does not have execute 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * permission, or 2) an access rights violation caused by a 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * flush only translation set up by ptep_get_and_clear(). 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * So we check the vma permissions to differentiate the two. 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the vma indicates we have execute permission, then 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the cause is the latter one. In this case, we need to 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * call do_page_fault() to fix the problem. 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (user_mode(regs)) { 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct vm_area_struct *vma; 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds down_read(¤t->mm->mmap_sem); 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vma = find_vma(current->mm,regs->iaoq[0]); 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vma && (regs->iaoq[0] >= vma->vm_start) 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && (vma->vm_flags & VM_EXEC)) { 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_address = regs->iaoq[0]; 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fault_space = regs->iasq[0]; 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds up_read(¤t->mm->mmap_sem); 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; /* call do_page_fault() */ 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds up_read(¤t->mm->mmap_sem); 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Fall Through */ 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 27: 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Data memory protection ID trap */ 743c61c25eb02757ecf697015ef4ae3675c5e114e2eKyle McMartin if (code == 27 && !user_mode(regs) && 744c61c25eb02757ecf697015ef4ae3675c5e114e2eKyle McMartin fixup_exception(regs)) 745c61c25eb02757ecf697015ef4ae3675c5e114e2eKyle McMartin return; 746c61c25eb02757ecf697015ef4ae3675c5e114e2eKyle McMartin 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds die_if_kernel("Protection id trap", regs, code); 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_code = SEGV_MAPERR; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_signo = SIGSEGV; 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_errno = 0; 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (code == 7) 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_addr = (void __user *) regs->iaoq[0]; 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_addr = (void __user *) regs->ior; 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds force_sig_info(SIGSEGV, &si, current); 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 28: 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Unaligned data reference trap */ 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handle_unaligned(regs); 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (user_mode(regs)) { 765fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller parisc_printk_ratelimited(0, regs, KERN_DEBUG 766fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller "handle_interruption() pid=%d command='%s'\n", 767fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller task_pid_nr(current), current->comm); 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* SIGBUS, for lack of a better one. */ 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_signo = SIGBUS; 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_code = BUS_OBJERR; 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_errno = 0; 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_addr = (void __user *) regs->ior; 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds force_sig_info(SIGBUS, &si, current); 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds parisc_terminate("Unexpected interruption", regs, code, 0); 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* NOT REACHED */ 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (user_mode(regs)) { 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) { 784fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller parisc_printk_ratelimited(0, regs, KERN_DEBUG 785fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller "User fault %d on space 0x%08lx, pid=%d command='%s'\n", 786fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller code, fault_space, 787fef47e2a2e1e75fe50a10f634a80f16808348cc6Helge Deller task_pid_nr(current), current->comm); 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_signo = SIGSEGV; 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_errno = 0; 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_code = SEGV_MAPERR; 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds si.si_addr = (void __user *) regs->ior; 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds force_sig_info(SIGSEGV, &si, current); 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 79959b33f148cc08fb33cbe823fca1e34f7f023765eHelge Deller * The kernel should never fault on its own address space, 80059b33f148cc08fb33cbe823fca1e34f7f023765eHelge Deller * unless pagefault_disable() was called before. 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 80359b33f148cc08fb33cbe823fca1e34f7f023765eHelge Deller if (fault_space == 0 && !in_atomic()) 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds parisc_terminate("Kernel Fault", regs, code, fault_address); 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do_page_fault(regs, code, fault_address); 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init check_ivt(void *iva) 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 816ae16489eb1175066c8f3008fc3c0396c525e1906Kyle McMartin extern u32 os_hpmc_size; 817c3d4ed4e3e5aa8d9e6b4b795f004a7028ce780e9Kyle McMartin extern const u32 os_hpmc[]; 818c3d4ed4e3e5aa8d9e6b4b795f004a7028ce780e9Kyle McMartin 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 check = 0; 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 *ivap; 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 *hpmcp; 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 length; 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (strcmp((char *)iva, "cows can fly")) 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ivap = (u32 *)iva; 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 8; i++) 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ivap++ = 0; 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Compute Checksum for HPMC handler */ 834ae16489eb1175066c8f3008fc3c0396c525e1906Kyle McMartin length = os_hpmc_size; 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ivap[7] = length; 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hpmcp = (u32 *)os_hpmc; 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=0; i<length/4; i++) 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check += *hpmcp++; 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=0; i<8; i++) 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds check += ivap[i]; 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ivap[5] = -check; 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 850a8f44e3889b686813926b288bd4e51a0cf17d2c7Helge Deller#ifndef CONFIG_64BIT 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern const void fault_vector_11; 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern const void fault_vector_20; 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init trap_init(void) 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *iva; 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (boot_cpu_data.cpu_type >= pcxu) 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iva = (void *) &fault_vector_20; 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 862a8f44e3889b686813926b288bd4e51a0cf17d2c7Helge Deller#ifdef CONFIG_64BIT 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds panic("Can't boot 64-bit OS on PA1.1 processor!"); 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iva = (void *) &fault_vector_11; 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (check_ivt(iva)) 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds panic("IVT invalid"); 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 871