1 /* $Id: traps.c,v 1.68 2000/11/22 06:50:37 davem Exp $
2 * arch/sparc64/kernel/traps.c
4 * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com)
9 * I like traps on v9, :))))
12 #include <linux/config.h>
13 #include <linux/sched.h> /* for jiffies */
14 #include <linux/kernel.h>
15 #include <linux/signal.h>
16 #include <linux/smp.h>
17 #include <linux/smp_lock.h>
19 #include <asm/delay.h>
20 #include <asm/system.h>
21 #include <asm/ptrace.h>
22 #include <asm/oplib.h>
24 #include <asm/pgtable.h>
25 #include <asm/unistd.h>
26 #include <asm/uaccess.h>
27 #include <asm/fpumacro.h>
29 #include <asm/psrcompat.h>
31 #include <linux/kmod.h>
34 /* #define SYSCALL_TRACING */
35 /* #define VERBOSE_SYSCALL_TRACING */
36 /* #define DEBUG_FPU */
38 #ifdef SYSCALL_TRACING
39 #ifdef VERBOSE_SYSCALL_TRACING
44 char arg_is_string
[6];
47 { 1, "exit", 1, { 0, } },
49 { 3, "read", 3, { 0, 0, 0, } },
50 { 4, "write", 3, { 0, 0, 0, } },
51 { 5, "open", 3, { 1, 0, 0, } },
52 { 6, "close", 1, { 0, } },
53 { 7, "wait4", 4, { 0, 0, 0, 0, } },
54 { 8, "creat", 2, { 1, 0, } },
55 { 9, "link", 2, { 1, 1, } },
56 { 10, "unlink", 1, { 1, } },
57 { 11, "execv", 2, { 1, 0, } },
58 { 12, "chdir", 1, { 1, } },
59 { 15, "chmod", 2, { 1, 0, } },
60 { 16, "chown", 3, { 1, 0, 0, } },
61 { 17, "brk", 1, { 0, } },
62 { 19, "lseek", 3, { 0, 0, 0, } },
63 { 27, "alarm", 1, { 0, } },
65 { 33, "access", 2, { 1, 0, } },
67 { 37, "kill", 2, { 0, 0, } },
68 { 38, "stat", 2, { 1, 0, } },
69 { 40, "lstat", 2, { 1, 0, } },
70 { 41, "dup", 1, { 0, } },
72 { 54, "ioctl", 3, { 0, 0, 0, } },
73 { 57, "symlink", 2, { 1, 1, } },
74 { 58, "readlink", 3, { 1, 0, 0, } },
75 { 59, "execve", 3, { 1, 0, 0, } },
76 { 60, "umask", 1, { 0, } },
77 { 62, "fstat", 2, { 0, 0, } },
78 { 64, "getpagesize", 0, },
79 { 71, "mmap", 6, { 0, 0, 0, 0, 0, 0, } },
80 { 73, "munmap", 2, { 0, 0, } },
81 { 74, "mprotect", 3, { 0, 0, 0, } },
82 { 83, "setitimer", 3, { 0, 0, 0, } },
83 { 90, "dup2", 2, { 0, 0, } },
84 { 92, "fcntl", 3, { 0, 0, 0, } },
85 { 93, "select", 5, { 0, 0, 0, 0, 0, } },
86 { 97, "socket", 3, { 0, 0, 0, } },
87 { 98, "connect", 3, { 0, 0, 0, } },
88 { 99, "accept", 3, { 0, 0, 0, } },
89 { 101, "send", 4, { 0, 0, 0, 0, } },
90 { 102, "recv", 4, { 0, 0, 0, 0, } },
91 { 104, "bind", 3, { 0, 0, 0, } },
92 { 105, "setsockopt", 5, { 0, 0, 0, 0, 0, } },
93 { 106, "listen", 2, { 0, 0, } },
94 { 120, "readv", 3, { 0, 0, 0, } },
95 { 121, "writev", 3, { 0, 0, 0, } },
96 { 123, "fchown", 3, { 0, 0, 0, } },
97 { 124, "fchmod", 2, { 0, 0, } },
98 { 128, "rename", 2, { 1, 1, } },
99 { 129, "truncate", 2, { 1, 0, } },
100 { 130, "ftruncate", 2, { 0, 0, } },
101 { 131, "flock", 2, { 0, 0, } },
102 { 136, "mkdir", 2, { 1, 0, } },
103 { 137, "rmdir", 1, { 1, } },
104 { 146, "killpg", 1, { 0, } },
105 { 157, "statfs", 2, { 1, 0, } },
106 { 158, "fstatfs", 2, { 0, 0, } },
107 { 159, "umount", 1, { 1, } },
108 { 167, "mount", 5, { 1, 1, 1, 0, 0, } },
109 { 174, "getdents", 3, { 0, 0, 0, } },
110 { 176, "fchdir", 2, { 0, 0, } },
111 { 198, "sigaction", 3, { 0, 0, 0, } },
112 { 201, "sigsuspend", 1, { 0, } },
113 { 206, "socketcall", 2, { 0, 0, } },
114 { 216, "sigreturn", 0, },
115 { 230, "newselect", 5, { 0, 0, 0, 0, 0, } },
116 { 236, "llseek", 5, { 0, 0, 0, 0, 0, } },
117 { 251, "sysctl", 1, { 0, } },
119 #define NUM_SDESC_ENTRIES (sizeof(sdesc_entries) / sizeof(sdesc_entries[0]))
122 #ifdef VERBOSE_SYSCALL_TRACING
123 static char scall_strbuf
[512];
126 void syscall_trace_entry(unsigned long g1
, struct pt_regs
*regs
)
128 #ifdef VERBOSE_SYSCALL_TRACING
134 if (!current
->pid
) return;
136 printk("SYS[%s:%d]: PC(%016lx) <%3d> ",
137 current
->comm
, current
->pid
, regs
->tpc
, (int)g1
);
138 #ifdef VERBOSE_SYSCALL_TRACING
140 for(i
= 0; i
< NUM_SDESC_ENTRIES
; i
++)
141 if(sdesc_entries
[i
].scall_num
== g1
) {
142 sdp
= &sdesc_entries
[i
];
146 printk("%s(", sdp
->name
);
147 for(i
= 0; i
< sdp
->num_args
; i
++) {
150 if(!sdp
->arg_is_string
[i
]) {
151 if (current
->thread
.flags
& SPARC_FLAG_32BIT
)
152 printk("%08x", (unsigned int)regs
->u_regs
[UREG_I0
+ i
]);
154 printk("%016lx", regs
->u_regs
[UREG_I0
+ i
]);
156 if (current
->thread
.flags
& SPARC_FLAG_32BIT
)
157 strncpy_from_user(scall_strbuf
,
158 (char *)(regs
->u_regs
[UREG_I0
+ i
] & 0xffffffff),
161 strncpy_from_user(scall_strbuf
,
162 (char *)regs
->u_regs
[UREG_I0
+ i
],
164 printk("%s", scall_strbuf
);
172 unsigned long syscall_trace_exit(unsigned long retval
, struct pt_regs
*regs
)
177 printk("ret[%016lx]\n", retval
);
180 #endif /* SYSCALL_TRACING */
183 void rtrap_check(struct pt_regs
*regs
)
185 register unsigned long pgd_phys
asm("o1");
186 register unsigned long pgd_cache
asm("o2");
187 register unsigned long g1_or_g3
asm("o3");
188 register unsigned long g2
asm("o4");
194 __asm__
__volatile__("rdpr %%pstate, %0"
196 if((test
& PSTATE_MG
) != 0 ||
197 (test
& PSTATE_IE
) == 0) {
198 printk("rtrap_check: Bogus pstate[%016lx]\n", test
);
204 __asm__
__volatile__("
206 wrpr %%o5, %4, %%pstate
212 wrpr %%o5, 0x0, %%pstate"
213 : "=r" (pgd_phys
), "=r" (pgd_cache
),
214 "=r" (g1_or_g3
), "=r" (g2
)
215 : "i" (PSTATE_IE
| PSTATE_MG
), "i" (TSB_REG
),
219 ctx
= spitfire_get_secondary_context();
221 if((pgd_phys
!= __pa(current
->mm
->pgd
)) ||
223 (pgd_cache
!= pgd_val(current
->mm
->pgd
[0])<<11UL)) ||
224 (g1_or_g3
!= (0xfffffffe00000000UL
| 0x0000000000000018UL
)) ||
225 #define KERN_HIGHBITS ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000)
226 #define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
227 (g2
!= (KERN_HIGHBITS
| KERN_LOWBITS
)) ||
230 ((ctx
!= (current
->mm
->context
& 0x3ff)) ||
232 (CTX_HWBITS(current
->mm
->context
) != ctx
))) {
233 printk("SHIT[%s:%d]: "
234 "(PP[%016lx] CACH[%016lx] CTX[%lx] g1g3[%016lx] g2[%016lx]) ",
235 current
->comm
, current
->pid
,
236 pgd_phys
, pgd_cache
, ctx
, g1_or_g3
, g2
);
237 printk("SHIT[%s:%d]: "
238 "[PP[%016lx] CACH[%016lx] CTX[%lx]] PC[%016lx:%016lx]\n",
239 current
->comm
, current
->pid
,
240 __pa(current
->mm
->pgd
),
241 pgd_val(current
->mm
->pgd
[0]),
242 current
->mm
->context
& 0x3ff,
243 regs
->tpc
, regs
->tnpc
);
254 void bad_trap (struct pt_regs
*regs
, long lvl
)
261 sprintf (buffer
, "Bad hw trap %lx at tl0\n", lvl
);
262 die_if_kernel (buffer
, regs
);
264 if (regs
->tstate
& TSTATE_PRIV
)
265 die_if_kernel ("Kernel bad trap", regs
);
266 info
.si_signo
= SIGILL
;
268 info
.si_code
= ILL_ILLTRP
;
269 info
.si_addr
= (void *)regs
->tpc
;
270 info
.si_trapno
= lvl
- 0x100;
271 force_sig_info(SIGILL
, &info
, current
);
274 void bad_trap_tl1 (struct pt_regs
*regs
, long lvl
)
278 sprintf (buffer
, "Bad trap %lx at tl>0", lvl
);
279 die_if_kernel (buffer
, regs
);
282 void instruction_access_exception (struct pt_regs
*regs
,
283 unsigned long sfsr
, unsigned long sfar
)
287 if (regs
->tstate
& TSTATE_PRIV
) {
289 printk("instruction_access_exception: Shit SFSR[%016lx] SFAR[%016lx], going.\n",
292 die_if_kernel("Iax", regs
);
294 info
.si_signo
= SIGSEGV
;
296 info
.si_code
= SEGV_MAPERR
;
297 info
.si_addr
= (void *)regs
->tpc
;
299 force_sig_info(SIGSEGV
, &info
, current
);
302 void data_access_exception (struct pt_regs
*regs
,
303 unsigned long sfsr
, unsigned long sfar
)
307 if (regs
->tstate
& TSTATE_PRIV
) {
308 /* Test if this comes from uaccess places. */
309 unsigned long fixup
, g2
;
311 g2
= regs
->u_regs
[UREG_G2
];
312 if ((fixup
= search_exception_table (regs
->tpc
, &g2
))) {
313 /* Ouch, somebody is trying ugly VM hole tricks on us... */
314 #ifdef DEBUG_EXCEPTIONS
315 printk("Exception: PC<%016lx> faddr<UNKNOWN>\n", regs
->tpc
);
316 printk("EX_TABLE: insn<%016lx> fixup<%016lx> "
317 "g2<%016lx>\n", regs
->tpc
, fixup
, g2
);
320 regs
->tnpc
= regs
->tpc
+ 4;
321 regs
->u_regs
[UREG_G2
] = g2
;
326 printk("data_access_exception: Shit SFSR[%016lx] SFAR[%016lx], going.\n",
329 die_if_kernel("Dax", regs
);
335 info
.si_signo
= SIGSEGV
;
337 info
.si_code
= SEGV_MAPERR
;
338 info
.si_addr
= (void *)sfar
;
340 force_sig_info(SIGSEGV
, &info
, current
);
344 /* This is really pathetic... */
345 /* #define DEBUG_PCI_POKES */
346 extern volatile int pci_poke_in_progress
;
347 extern volatile int pci_poke_faulted
;
350 /* When access exceptions happen, we must do this. */
351 static __inline__
void clean_and_reenable_l1_caches(void)
356 for(va
= 0; va
< (PAGE_SIZE
<< 1); va
+= 32) {
357 spitfire_put_icache_tag(va
, 0x0);
358 spitfire_put_dcache_tag(va
, 0x0);
362 __asm__
__volatile__("flush %%g6\n\t"
364 "stxa %0, [%%g0] %1\n\t"
367 : "r" (LSU_CONTROL_IC
| LSU_CONTROL_DC
|
368 LSU_CONTROL_IM
| LSU_CONTROL_DM
),
369 "i" (ASI_LSU_CONTROL
)
373 void do_iae(struct pt_regs
*regs
)
377 clean_and_reenable_l1_caches();
379 info
.si_signo
= SIGBUS
;
381 info
.si_code
= BUS_OBJERR
;
382 info
.si_addr
= (void *)0;
384 force_sig_info(SIGBUS
, &info
, current
);
387 void do_dae(struct pt_regs
*regs
)
390 if(pci_poke_in_progress
) {
391 #ifdef DEBUG_PCI_POKES
392 prom_printf(" (POKE tpc[%016lx] tnpc[%016lx] ",
393 regs
->tpc
, regs
->tnpc
);
395 pci_poke_faulted
= 1;
396 regs
->tnpc
= regs
->tpc
+ 4;
399 #ifdef DEBUG_PCI_POKES
400 prom_printf("PCI) ");
403 clean_and_reenable_l1_caches();
410 static char ecc_syndrome_table
[] = {
411 0x4c, 0x40, 0x41, 0x48, 0x42, 0x48, 0x48, 0x49,
412 0x43, 0x48, 0x48, 0x49, 0x48, 0x49, 0x49, 0x4a,
413 0x44, 0x48, 0x48, 0x20, 0x48, 0x39, 0x4b, 0x48,
414 0x48, 0x25, 0x31, 0x48, 0x28, 0x48, 0x48, 0x2c,
415 0x45, 0x48, 0x48, 0x21, 0x48, 0x3d, 0x04, 0x48,
416 0x48, 0x4b, 0x35, 0x48, 0x2d, 0x48, 0x48, 0x29,
417 0x48, 0x00, 0x01, 0x48, 0x0a, 0x48, 0x48, 0x4b,
418 0x0f, 0x48, 0x48, 0x4b, 0x48, 0x49, 0x49, 0x48,
419 0x46, 0x48, 0x48, 0x2a, 0x48, 0x3b, 0x27, 0x48,
420 0x48, 0x4b, 0x33, 0x48, 0x22, 0x48, 0x48, 0x2e,
421 0x48, 0x19, 0x1d, 0x48, 0x1b, 0x4a, 0x48, 0x4b,
422 0x1f, 0x48, 0x4a, 0x4b, 0x48, 0x4b, 0x4b, 0x48,
423 0x48, 0x4b, 0x24, 0x48, 0x07, 0x48, 0x48, 0x36,
424 0x4b, 0x48, 0x48, 0x3e, 0x48, 0x30, 0x38, 0x48,
425 0x49, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x16, 0x48,
426 0x48, 0x12, 0x4b, 0x48, 0x49, 0x48, 0x48, 0x4b,
427 0x47, 0x48, 0x48, 0x2f, 0x48, 0x3f, 0x4b, 0x48,
428 0x48, 0x06, 0x37, 0x48, 0x23, 0x48, 0x48, 0x2b,
429 0x48, 0x05, 0x4b, 0x48, 0x4b, 0x48, 0x48, 0x32,
430 0x26, 0x48, 0x48, 0x3a, 0x48, 0x34, 0x3c, 0x48,
431 0x48, 0x11, 0x15, 0x48, 0x13, 0x4a, 0x48, 0x4b,
432 0x17, 0x48, 0x4a, 0x4b, 0x48, 0x4b, 0x4b, 0x48,
433 0x49, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x1e, 0x48,
434 0x48, 0x1a, 0x4b, 0x48, 0x49, 0x48, 0x48, 0x4b,
435 0x48, 0x08, 0x0d, 0x48, 0x02, 0x48, 0x48, 0x49,
436 0x03, 0x48, 0x48, 0x49, 0x48, 0x4b, 0x4b, 0x48,
437 0x49, 0x48, 0x48, 0x49, 0x48, 0x4b, 0x10, 0x48,
438 0x48, 0x14, 0x4b, 0x48, 0x4b, 0x48, 0x48, 0x4b,
439 0x49, 0x48, 0x48, 0x49, 0x48, 0x4b, 0x18, 0x48,
440 0x48, 0x1c, 0x4b, 0x48, 0x4b, 0x48, 0x48, 0x4b,
441 0x4a, 0x0c, 0x09, 0x48, 0x0e, 0x48, 0x48, 0x4b,
442 0x0b, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x4b, 0x4a
445 /* cee_trap in entry.S encodes AFSR/UDBH/UDBL error status
446 * in the following format. The AFAR is left as is, with
447 * reserved bits cleared, and is a raw 40-bit physical
450 #define CE_STATUS_UDBH_UE (1UL << (43 + 9))
451 #define CE_STATUS_UDBH_CE (1UL << (43 + 8))
452 #define CE_STATUS_UDBH_ESYNDR (0xffUL << 43)
453 #define CE_STATUS_UDBH_SHIFT 43
454 #define CE_STATUS_UDBL_UE (1UL << (33 + 9))
455 #define CE_STATUS_UDBL_CE (1UL << (33 + 8))
456 #define CE_STATUS_UDBL_ESYNDR (0xffUL << 33)
457 #define CE_STATUS_UDBL_SHIFT 33
458 #define CE_STATUS_AFSR_MASK (0x1ffffffffUL)
459 #define CE_STATUS_AFSR_ME (1UL << 32)
460 #define CE_STATUS_AFSR_PRIV (1UL << 31)
461 #define CE_STATUS_AFSR_ISAP (1UL << 30)
462 #define CE_STATUS_AFSR_ETP (1UL << 29)
463 #define CE_STATUS_AFSR_IVUE (1UL << 28)
464 #define CE_STATUS_AFSR_TO (1UL << 27)
465 #define CE_STATUS_AFSR_BERR (1UL << 26)
466 #define CE_STATUS_AFSR_LDP (1UL << 25)
467 #define CE_STATUS_AFSR_CP (1UL << 24)
468 #define CE_STATUS_AFSR_WP (1UL << 23)
469 #define CE_STATUS_AFSR_EDP (1UL << 22)
470 #define CE_STATUS_AFSR_UE (1UL << 21)
471 #define CE_STATUS_AFSR_CE (1UL << 20)
472 #define CE_STATUS_AFSR_ETS (0xfUL << 16)
473 #define CE_STATUS_AFSR_ETS_SHIFT 16
474 #define CE_STATUS_AFSR_PSYND (0xffffUL << 0)
475 #define CE_STATUS_AFSR_PSYND_SHIFT 0
477 /* Layout of Ecache TAG Parity Syndrome of AFSR */
478 #define AFSR_ETSYNDROME_7_0 0x1UL /* E$-tag bus bits <7:0> */
479 #define AFSR_ETSYNDROME_15_8 0x2UL /* E$-tag bus bits <15:8> */
480 #define AFSR_ETSYNDROME_21_16 0x4UL /* E$-tag bus bits <21:16> */
481 #define AFSR_ETSYNDROME_24_22 0x8UL /* E$-tag bus bits <24:22> */
483 static char *syndrome_unknown
= "<Unknown>";
485 asmlinkage
void cee_log(unsigned long ce_status
,
487 struct pt_regs
*regs
)
491 unsigned short scode
, udb_reg
;
493 printk(KERN_WARNING
"CPU[%d]: Correctable ECC Error "
494 "AFSR[%lx] AFAR[%016lx] UDBL[%lx] UDBH[%lx]\n",
496 (ce_status
& CE_STATUS_AFSR_MASK
),
498 ((ce_status
>> CE_STATUS_UDBL_SHIFT
) & 0x3ffUL
),
499 ((ce_status
>> CE_STATUS_UDBH_SHIFT
) & 0x3ffUL
));
501 udb_reg
= ((ce_status
>> CE_STATUS_UDBL_SHIFT
) & 0x3ffUL
);
502 if (udb_reg
& (1 << 8)) {
503 scode
= ecc_syndrome_table
[udb_reg
& 0xff];
504 if (prom_getunumber(scode
, afar
,
505 memmod_str
, sizeof(memmod_str
)) == -1)
506 p
= syndrome_unknown
;
509 printk(KERN_WARNING
"CPU[%d]: UDBL Syndrome[%x] "
510 "Memory Module \"%s\"\n",
511 smp_processor_id(), scode
, p
);
514 udb_reg
= ((ce_status
>> CE_STATUS_UDBH_SHIFT
) & 0x3ffUL
);
515 if (udb_reg
& (1 << 8)) {
516 scode
= ecc_syndrome_table
[udb_reg
& 0xff];
517 if (prom_getunumber(scode
, afar
,
518 memmod_str
, sizeof(memmod_str
)) == -1)
519 p
= syndrome_unknown
;
522 printk(KERN_WARNING
"CPU[%d]: UDBH Syndrome[%x] "
523 "Memory Module \"%s\"\n",
524 smp_processor_id(), scode
, p
);
528 void do_fpe_common(struct pt_regs
*regs
)
530 if(regs
->tstate
& TSTATE_PRIV
) {
531 regs
->tpc
= regs
->tnpc
;
534 unsigned long fsr
= current
->thread
.xfsr
[0];
537 info
.si_signo
= SIGFPE
;
539 info
.si_addr
= (void *)regs
->tpc
;
541 info
.si_code
= __SI_FAULT
;
542 if ((fsr
& 0x1c000) == (1 << 14)) {
544 info
.si_code
= FPE_FLTINV
;
546 info
.si_code
= FPE_FLTOVF
;
548 info
.si_code
= FPE_FLTUND
;
550 info
.si_code
= FPE_FLTDIV
;
552 info
.si_code
= FPE_FLTRES
;
554 force_sig_info(SIGFPE
, &info
, current
);
558 void do_fpieee(struct pt_regs
*regs
)
561 printk("fpieee %016lx\n", current
->thread
.xfsr
[0]);
566 extern int do_mathemu(struct pt_regs
*, struct fpustate
*);
568 void do_fpother(struct pt_regs
*regs
)
570 struct fpustate
*f
= FPUSTATE
;
573 switch ((current
->thread
.xfsr
[0] & 0x1c000)) {
574 case (2 << 14): /* unfinished_FPop */
575 case (3 << 14): /* unimplemented_FPop */
576 ret
= do_mathemu(regs
, f
);
581 printk("fpother %016lx\n", current
->thread
.xfsr
[0]);
586 void do_tof(struct pt_regs
*regs
)
590 if(regs
->tstate
& TSTATE_PRIV
)
591 die_if_kernel("Penguin overflow trap from kernel mode", regs
);
592 info
.si_signo
= SIGEMT
;
594 info
.si_code
= EMT_TAGOVF
;
595 info
.si_addr
= (void *)regs
->tpc
;
597 force_sig_info(SIGEMT
, &info
, current
);
600 void do_div0(struct pt_regs
*regs
)
604 info
.si_signo
= SIGFPE
;
606 info
.si_code
= FPE_INTDIV
;
607 info
.si_addr
= (void *)regs
->tpc
;
609 force_sig_info(SIGFPE
, &info
, current
);
612 void instruction_dump (unsigned int *pc
)
616 if((((unsigned long) pc
) & 3))
619 printk("Instruction DUMP:");
620 for(i
= -3; i
< 6; i
++)
621 printk("%c%08x%c",i
?' ':'<',pc
[i
],i
?' ':'>');
625 void user_instruction_dump (unsigned int *pc
)
630 if((((unsigned long) pc
) & 3))
633 if(copy_from_user(buf
, pc
- 3, sizeof(buf
)))
636 printk("Instruction DUMP:");
637 for(i
= 0; i
< 9; i
++)
638 printk("%c%08x%c",i
==3?' ':'<',buf
[i
],i
==3?' ':'>');
642 void die_if_kernel(char *str
, struct pt_regs
*regs
)
644 extern void __show_regs(struct pt_regs
* regs
);
645 extern void smp_report_regs(void);
647 struct reg_window
*lastrw
;
649 /* Amuse the user. */
656 printk("%s(%d): %s\n", current
->comm
, current
->pid
, str
);
657 __asm__
__volatile__("flushw");
659 if(regs
->tstate
& TSTATE_PRIV
) {
660 struct reg_window
*rw
= (struct reg_window
*)
661 (regs
->u_regs
[UREG_FP
] + STACK_BIAS
);
663 /* Stop the back trace when we hit userland or we
664 * find some badly aligned kernel stack.
666 lastrw
= (struct reg_window
*)current
;
670 (char *) rw
< ((char *) current
)
671 + sizeof (union task_union
) &&
672 !(((unsigned long) rw
) & 0x7)) {
673 printk("Caller[%016lx]\n", rw
->ins
[7]);
675 rw
= (struct reg_window
*)
676 (rw
->ins
[6] + STACK_BIAS
);
678 instruction_dump ((unsigned int *) regs
->tpc
);
680 user_instruction_dump ((unsigned int *) regs
->tpc
);
685 if(regs
->tstate
& TSTATE_PRIV
)
690 extern int handle_popc(u32 insn
, struct pt_regs
*regs
);
691 extern int handle_ldf_stq(u32 insn
, struct pt_regs
*regs
);
693 void do_illegal_instruction(struct pt_regs
*regs
)
695 unsigned long pc
= regs
->tpc
;
696 unsigned long tstate
= regs
->tstate
;
700 if(tstate
& TSTATE_PRIV
)
701 die_if_kernel("Kernel illegal instruction", regs
);
702 if(current
->thread
.flags
& SPARC_FLAG_32BIT
)
704 if (get_user(insn
, (u32
*)pc
) != -EFAULT
) {
705 if ((insn
& 0xc1ffc000) == 0x81700000) /* POPC */ {
706 if (handle_popc(insn
, regs
))
708 } else if ((insn
& 0xc1580000) == 0xc1100000) /* LDQ/STQ */ {
709 if (handle_ldf_stq(insn
, regs
))
713 info
.si_signo
= SIGILL
;
715 info
.si_code
= ILL_ILLOPC
;
716 info
.si_addr
= (void *)pc
;
718 force_sig_info(SIGILL
, &info
, current
);
721 void mem_address_unaligned(struct pt_regs
*regs
, unsigned long sfar
, unsigned long sfsr
)
725 if(regs
->tstate
& TSTATE_PRIV
) {
726 extern void kernel_unaligned_trap(struct pt_regs
*regs
,
728 unsigned long sfar
, unsigned long sfsr
);
730 return kernel_unaligned_trap(regs
, *((unsigned int *)regs
->tpc
), sfar
, sfsr
);
732 info
.si_signo
= SIGBUS
;
734 info
.si_code
= BUS_ADRALN
;
735 info
.si_addr
= (void *)sfar
;
737 force_sig_info(SIGBUS
, &info
, current
);
740 void do_privop(struct pt_regs
*regs
)
744 info
.si_signo
= SIGILL
;
746 info
.si_code
= ILL_PRVOPC
;
747 info
.si_addr
= (void *)regs
->tpc
;
749 force_sig_info(SIGILL
, &info
, current
);
752 void do_privact(struct pt_regs
*regs
)
757 /* Trap level 1 stuff or other traps we should never see... */
758 void do_cee(struct pt_regs
*regs
)
760 die_if_kernel("TL0: Cache Error Exception", regs
);
763 void do_cee_tl1(struct pt_regs
*regs
)
765 die_if_kernel("TL1: Cache Error Exception", regs
);
768 void do_dae_tl1(struct pt_regs
*regs
)
770 die_if_kernel("TL1: Data Access Exception", regs
);
773 void do_iae_tl1(struct pt_regs
*regs
)
775 die_if_kernel("TL1: Instruction Access Exception", regs
);
778 void do_div0_tl1(struct pt_regs
*regs
)
780 die_if_kernel("TL1: DIV0 Exception", regs
);
783 void do_fpdis_tl1(struct pt_regs
*regs
)
785 die_if_kernel("TL1: FPU Disabled", regs
);
788 void do_fpieee_tl1(struct pt_regs
*regs
)
790 die_if_kernel("TL1: FPU IEEE Exception", regs
);
793 void do_fpother_tl1(struct pt_regs
*regs
)
795 die_if_kernel("TL1: FPU Other Exception", regs
);
798 void do_ill_tl1(struct pt_regs
*regs
)
800 die_if_kernel("TL1: Illegal Instruction Exception", regs
);
803 void do_irq_tl1(struct pt_regs
*regs
)
805 die_if_kernel("TL1: IRQ Exception", regs
);
808 void do_lddfmna_tl1(struct pt_regs
*regs
)
810 die_if_kernel("TL1: LDDF Exception", regs
);
813 void do_stdfmna_tl1(struct pt_regs
*regs
)
815 die_if_kernel("TL1: STDF Exception", regs
);
818 void do_paw(struct pt_regs
*regs
)
820 die_if_kernel("TL0: Phys Watchpoint Exception", regs
);
823 void do_paw_tl1(struct pt_regs
*regs
)
825 die_if_kernel("TL1: Phys Watchpoint Exception", regs
);
828 void do_vaw(struct pt_regs
*regs
)
830 die_if_kernel("TL0: Virt Watchpoint Exception", regs
);
833 void do_vaw_tl1(struct pt_regs
*regs
)
835 die_if_kernel("TL1: Virt Watchpoint Exception", regs
);
838 void do_tof_tl1(struct pt_regs
*regs
)
840 die_if_kernel("TL1: Tag Overflow Exception", regs
);
843 #ifdef CONFIG_EC_FLUSH_TRAP
844 void cache_flush_trap(struct pt_regs
*regs
)
847 unsigned node
= linux_cpus
[get_cpuid()].prom_node
;
849 #error cache_flush_trap not supported on sparc64/SMP yet
854 int size
= prom_getintdefault(node
, "ecache-size", 512*1024);
857 struct page
*page
, *end
;
859 regs
->tpc
= regs
->tnpc
;
860 regs
->tnpc
= regs
->tnpc
+ 4;
861 if (!capable(CAP_SYS_ADMIN
)) return;
863 addr
= PAGE_OFFSET
- PAGE_SIZE
;
865 end
= mem_map
+ max_mapnr
;
866 for (i
= 0; i
< size
; i
++) {
872 } while (!PageReserved(page
));
873 /* E-Cache line size is 64B. Let us pollute it :)) */
874 for (j
= 0; j
< PAGE_SIZE
; j
+= 64)
875 __asm__
__volatile__ ("ldx [%0 + %1], %%g1" : : "r" (j
), "r" (addr
) : "g1");
881 void do_getpsr(struct pt_regs
*regs
)
883 regs
->u_regs
[UREG_I0
] = tstate_to_psr(regs
->tstate
);
884 regs
->tpc
= regs
->tnpc
;
890 /* Attach to the address space of init_task. */
891 atomic_inc(&init_mm
.mm_count
);
892 current
->active_mm
= &init_mm
;
894 /* NOTE: Other cpus have this done as they are started