1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/sched.h>
22#include <linux/signal.h>
23#include <linux/kernel.h>
24#include <linux/mm.h>
25#include <linux/module.h>
26#include <linux/user.h>
27#include <linux/string.h>
28#include <linux/linkage.h>
29#include <linux/init.h>
30#include <linux/ptrace.h>
31#include <linux/kallsyms.h>
32
33#include <asm/setup.h>
34#include <asm/fpu.h>
35#include <asm/uaccess.h>
36#include <asm/traps.h>
37#include <asm/pgalloc.h>
38#include <asm/machdep.h>
39#include <asm/siginfo.h>
40
41
42static const char *vec_names[] = {
43 [VEC_RESETSP] = "RESET SP",
44 [VEC_RESETPC] = "RESET PC",
45 [VEC_BUSERR] = "BUS ERROR",
46 [VEC_ADDRERR] = "ADDRESS ERROR",
47 [VEC_ILLEGAL] = "ILLEGAL INSTRUCTION",
48 [VEC_ZERODIV] = "ZERO DIVIDE",
49 [VEC_CHK] = "CHK",
50 [VEC_TRAP] = "TRAPcc",
51 [VEC_PRIV] = "PRIVILEGE VIOLATION",
52 [VEC_TRACE] = "TRACE",
53 [VEC_LINE10] = "LINE 1010",
54 [VEC_LINE11] = "LINE 1111",
55 [VEC_RESV12] = "UNASSIGNED RESERVED 12",
56 [VEC_COPROC] = "COPROCESSOR PROTOCOL VIOLATION",
57 [VEC_FORMAT] = "FORMAT ERROR",
58 [VEC_UNINT] = "UNINITIALIZED INTERRUPT",
59 [VEC_RESV16] = "UNASSIGNED RESERVED 16",
60 [VEC_RESV17] = "UNASSIGNED RESERVED 17",
61 [VEC_RESV18] = "UNASSIGNED RESERVED 18",
62 [VEC_RESV19] = "UNASSIGNED RESERVED 19",
63 [VEC_RESV20] = "UNASSIGNED RESERVED 20",
64 [VEC_RESV21] = "UNASSIGNED RESERVED 21",
65 [VEC_RESV22] = "UNASSIGNED RESERVED 22",
66 [VEC_RESV23] = "UNASSIGNED RESERVED 23",
67 [VEC_SPUR] = "SPURIOUS INTERRUPT",
68 [VEC_INT1] = "LEVEL 1 INT",
69 [VEC_INT2] = "LEVEL 2 INT",
70 [VEC_INT3] = "LEVEL 3 INT",
71 [VEC_INT4] = "LEVEL 4 INT",
72 [VEC_INT5] = "LEVEL 5 INT",
73 [VEC_INT6] = "LEVEL 6 INT",
74 [VEC_INT7] = "LEVEL 7 INT",
75 [VEC_SYS] = "SYSCALL",
76 [VEC_TRAP1] = "TRAP #1",
77 [VEC_TRAP2] = "TRAP #2",
78 [VEC_TRAP3] = "TRAP #3",
79 [VEC_TRAP4] = "TRAP #4",
80 [VEC_TRAP5] = "TRAP #5",
81 [VEC_TRAP6] = "TRAP #6",
82 [VEC_TRAP7] = "TRAP #7",
83 [VEC_TRAP8] = "TRAP #8",
84 [VEC_TRAP9] = "TRAP #9",
85 [VEC_TRAP10] = "TRAP #10",
86 [VEC_TRAP11] = "TRAP #11",
87 [VEC_TRAP12] = "TRAP #12",
88 [VEC_TRAP13] = "TRAP #13",
89 [VEC_TRAP14] = "TRAP #14",
90 [VEC_TRAP15] = "TRAP #15",
91 [VEC_FPBRUC] = "FPCP BSUN",
92 [VEC_FPIR] = "FPCP INEXACT",
93 [VEC_FPDIVZ] = "FPCP DIV BY 0",
94 [VEC_FPUNDER] = "FPCP UNDERFLOW",
95 [VEC_FPOE] = "FPCP OPERAND ERROR",
96 [VEC_FPOVER] = "FPCP OVERFLOW",
97 [VEC_FPNAN] = "FPCP SNAN",
98 [VEC_FPUNSUP] = "FPCP UNSUPPORTED OPERATION",
99 [VEC_MMUCFG] = "MMU CONFIGURATION ERROR",
100 [VEC_MMUILL] = "MMU ILLEGAL OPERATION ERROR",
101 [VEC_MMUACC] = "MMU ACCESS LEVEL VIOLATION ERROR",
102 [VEC_RESV59] = "UNASSIGNED RESERVED 59",
103 [VEC_UNIMPEA] = "UNASSIGNED RESERVED 60",
104 [VEC_UNIMPII] = "UNASSIGNED RESERVED 61",
105 [VEC_RESV62] = "UNASSIGNED RESERVED 62",
106 [VEC_RESV63] = "UNASSIGNED RESERVED 63",
107};
108
109static const char *space_names[] = {
110 [0] = "Space 0",
111 [USER_DATA] = "User Data",
112 [USER_PROGRAM] = "User Program",
113#ifndef CONFIG_SUN3
114 [3] = "Space 3",
115#else
116 [FC_CONTROL] = "Control",
117#endif
118 [4] = "Space 4",
119 [SUPER_DATA] = "Super Data",
120 [SUPER_PROGRAM] = "Super Program",
121 [CPU_SPACE] = "CPU"
122};
123
124void die_if_kernel(char *,struct pt_regs *,int);
125asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
126 unsigned long error_code);
127int send_fault_sig(struct pt_regs *regs);
128
129asmlinkage void trap_c(struct frame *fp);
130
131#if defined (CONFIG_M68060)
132static inline void access_error060 (struct frame *fp)
133{
134 unsigned long fslw = fp->un.fmt4.pc;
135
136#ifdef DEBUG
137 printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);
138#endif
139
140 if (fslw & MMU060_BPE) {
141
142 __asm__ __volatile__ ("movec %/cacr,%/d0\n\t"
143 "orl #0x00400000,%/d0\n\t"
144 "movec %/d0,%/cacr"
145 : : : "d0" );
146
147 if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE))
148 return;
149 }
150
151 if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) {
152 unsigned long errorcode;
153 unsigned long addr = fp->un.fmt4.effaddr;
154
155 if (fslw & MMU060_MA)
156 addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;
157
158 errorcode = 1;
159 if (fslw & MMU060_DESC_ERR) {
160 __flush_tlb040_one(addr);
161 errorcode = 0;
162 }
163 if (fslw & MMU060_W)
164 errorcode |= 2;
165#ifdef DEBUG
166 printk("errorcode = %d\n", errorcode );
167#endif
168 do_page_fault(&fp->ptregs, addr, errorcode);
169 } else if (fslw & (MMU060_SEE)){
170
171
172
173 send_fault_sig(&fp->ptregs);
174 } else if (!(fslw & (MMU060_RE|MMU060_WE)) ||
175 send_fault_sig(&fp->ptregs) > 0) {
176 printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr);
177 printk( "68060 access error, fslw=%lx\n", fslw );
178 trap_c( fp );
179 }
180}
181#endif
182
183#if defined (CONFIG_M68040)
184static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)
185{
186 unsigned long mmusr;
187 mm_segment_t old_fs = get_fs();
188
189 set_fs(MAKE_MM_SEG(wbs));
190
191 if (iswrite)
192 asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));
193 else
194 asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));
195
196 asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));
197
198 set_fs(old_fs);
199
200 return mmusr;
201}
202
203static inline int do_040writeback1(unsigned short wbs, unsigned long wba,
204 unsigned long wbd)
205{
206 int res = 0;
207 mm_segment_t old_fs = get_fs();
208
209
210 set_fs(MAKE_MM_SEG(wbs));
211
212 switch (wbs & WBSIZ_040) {
213 case BA_SIZE_BYTE:
214 res = put_user(wbd & 0xff, (char __user *)wba);
215 break;
216 case BA_SIZE_WORD:
217 res = put_user(wbd & 0xffff, (short __user *)wba);
218 break;
219 case BA_SIZE_LONG:
220 res = put_user(wbd, (int __user *)wba);
221 break;
222 }
223
224
225 set_fs(old_fs);
226
227
228#ifdef DEBUG
229 printk("do_040writeback1, res=%d\n",res);
230#endif
231
232 return res;
233}
234
235
236
237
238
239static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs)
240{
241 fp->un.fmt7.faddr = wba;
242 fp->un.fmt7.ssw = wbs & 0xff;
243 if (wba != current->thread.faddr)
244 fp->un.fmt7.ssw |= MA_040;
245}
246
247static inline void do_040writebacks(struct frame *fp)
248{
249 int res = 0;
250#if 0
251 if (fp->un.fmt7.wb1s & WBV_040)
252 printk("access_error040: cannot handle 1st writeback. oops.\n");
253#endif
254
255 if ((fp->un.fmt7.wb2s & WBV_040) &&
256 !(fp->un.fmt7.wb2s & WBTT_040)) {
257 res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,
258 fp->un.fmt7.wb2d);
259 if (res)
260 fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s);
261 else
262 fp->un.fmt7.wb2s = 0;
263 }
264
265
266 if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) {
267 res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,
268 fp->un.fmt7.wb3d);
269 if (res)
270 {
271 fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s);
272
273 fp->un.fmt7.wb2s = fp->un.fmt7.wb3s;
274 fp->un.fmt7.wb3s &= (~WBV_040);
275 fp->un.fmt7.wb2a = fp->un.fmt7.wb3a;
276 fp->un.fmt7.wb2d = fp->un.fmt7.wb3d;
277 }
278 else
279 fp->un.fmt7.wb3s = 0;
280 }
281
282 if (res)
283 send_fault_sig(&fp->ptregs);
284}
285
286
287
288
289
290
291
292asmlinkage void berr_040cleanup(struct frame *fp)
293{
294 fp->un.fmt7.wb2s &= ~4;
295 fp->un.fmt7.wb3s &= ~4;
296
297 do_040writebacks(fp);
298}
299
300static inline void access_error040(struct frame *fp)
301{
302 unsigned short ssw = fp->un.fmt7.ssw;
303 unsigned long mmusr;
304
305#ifdef DEBUG
306 printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);
307 printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,
308 fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);
309 printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",
310 fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,
311 fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);
312#endif
313
314 if (ssw & ATC_040) {
315 unsigned long addr = fp->un.fmt7.faddr;
316 unsigned long errorcode;
317
318
319
320
321
322 if (ssw & MA_040)
323 addr = (addr + 7) & -8;
324
325
326 mmusr = probe040(!(ssw & RW_040), addr, ssw);
327#ifdef DEBUG
328 printk("mmusr = %lx\n", mmusr);
329#endif
330 errorcode = 1;
331 if (!(mmusr & MMU_R_040)) {
332
333 __flush_tlb040_one(addr);
334 errorcode = 0;
335 }
336
337
338
339 if (!(ssw & RW_040) || (ssw & LK_040))
340 errorcode |= 2;
341
342 if (do_page_fault(&fp->ptregs, addr, errorcode)) {
343#ifdef DEBUG
344 printk("do_page_fault() !=0\n");
345#endif
346 if (user_mode(&fp->ptregs)){
347
348#ifdef DEBUG
349 printk(".. was usermode - return\n");
350#endif
351 return;
352 }
353
354
355
356
357disable_wb:
358#ifdef DEBUG
359 printk(".. disabling wb2\n");
360#endif
361 if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)
362 fp->un.fmt7.wb2s &= ~WBV_040;
363 if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)
364 fp->un.fmt7.wb3s &= ~WBV_040;
365 }
366 } else {
367
368
369
370
371 current->thread.signo = SIGBUS;
372 current->thread.faddr = fp->un.fmt7.faddr;
373 if (send_fault_sig(&fp->ptregs) >= 0)
374 printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
375 fp->un.fmt7.faddr);
376 goto disable_wb;
377 }
378
379 do_040writebacks(fp);
380}
381#endif
382
383#if defined(CONFIG_SUN3)
384#include <asm/sun3mmu.h>
385
386extern int mmu_emu_handle_fault (unsigned long, int, int);
387
388
389
390static inline void bus_error030 (struct frame *fp)
391{
392 unsigned char buserr_type = sun3_get_buserr ();
393 unsigned long addr, errorcode;
394 unsigned short ssw = fp->un.fmtb.ssw;
395 extern unsigned long _sun3_map_test_start, _sun3_map_test_end;
396
397#ifdef DEBUG
398 if (ssw & (FC | FB))
399 printk ("Instruction fault at %#010lx\n",
400 ssw & FC ?
401 fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
402 :
403 fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
404 if (ssw & DF)
405 printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
406 ssw & RW ? "read" : "write",
407 fp->un.fmtb.daddr,
408 space_names[ssw & DFC], fp->ptregs.pc);
409#endif
410
411
412
413
414
415
416
417 if ((ssw & DF)
418 && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) {
419 if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0))
420 return;
421 }
422
423
424 if (fp->ptregs.sr & PS_S) {
425
426 if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {
427
428 if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1))
429 return;
430
431 if (ssw & (FC | FB))
432 printk ("Instruction fault at %#010lx\n",
433 fp->ptregs.pc);
434 if (ssw & DF) {
435
436 if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) &&
437 (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) {
438 send_fault_sig(&fp->ptregs);
439 return;
440 }
441
442 printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
443 ssw & RW ? "read" : "write",
444 fp->un.fmtb.daddr,
445 space_names[ssw & DFC], fp->ptregs.pc);
446 }
447 printk ("BAD KERNEL BUSERR\n");
448
449 die_if_kernel("Oops", &fp->ptregs,0);
450 force_sig(SIGKILL, current);
451 return;
452 }
453 } else {
454
455 if (!(ssw & (FC | FB)) && !(ssw & DF))
456
457 panic ("USER BUSERR w/o instruction or data fault");
458 }
459
460
461
462 if (ssw & DF) {
463 addr = fp->un.fmtb.daddr;
464
465
466
467
468
469
470
471 if (buserr_type & SUN3_BUSERR_PROTERR)
472 errorcode = 0x01;
473 else if (buserr_type & SUN3_BUSERR_INVALID)
474 errorcode = 0x00;
475 else {
476#ifdef DEBUG
477 printk ("*** unexpected busfault type=%#04x\n", buserr_type);
478 printk ("invalid %s access at %#lx from pc %#lx\n",
479 !(ssw & RW) ? "write" : "read", addr,
480 fp->ptregs.pc);
481#endif
482 die_if_kernel ("Oops", &fp->ptregs, buserr_type);
483 force_sig (SIGBUS, current);
484 return;
485 }
486
487
488 if (!(ssw & RW) || ssw & RM)
489 errorcode |= 0x02;
490
491
492 do_page_fault (&fp->ptregs, addr, errorcode);
493
494
495 return;
496 }
497
498
499
500
501 if (fp->ptregs.format == 0xA)
502 addr = fp->ptregs.pc + 4;
503 else
504 addr = fp->un.fmtb.baddr;
505 if (ssw & FC)
506 addr -= 2;
507
508 if (buserr_type & SUN3_BUSERR_INVALID) {
509 if (!mmu_emu_handle_fault(addr, 1, 0))
510 do_page_fault (&fp->ptregs, addr, 0);
511 } else {
512#ifdef DEBUG
513 printk ("protection fault on insn access (segv).\n");
514#endif
515 force_sig (SIGSEGV, current);
516 }
517}
518#else
519#if defined(CPU_M68020_OR_M68030)
520static inline void bus_error030 (struct frame *fp)
521{
522 volatile unsigned short temp;
523 unsigned short mmusr;
524 unsigned long addr, errorcode;
525 unsigned short ssw = fp->un.fmtb.ssw;
526#ifdef DEBUG
527 unsigned long desc;
528
529 printk ("pid = %x ", current->pid);
530 printk ("SSW=%#06x ", ssw);
531
532 if (ssw & (FC | FB))
533 printk ("Instruction fault at %#010lx\n",
534 ssw & FC ?
535 fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
536 :
537 fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
538 if (ssw & DF)
539 printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
540 ssw & RW ? "read" : "write",
541 fp->un.fmtb.daddr,
542 space_names[ssw & DFC], fp->ptregs.pc);
543#endif
544
545
546
547
548
549 if (ssw & DF) {
550 addr = fp->un.fmtb.daddr;
551
552#ifdef DEBUG
553 asm volatile ("ptestr %3,%2@,#7,%0\n\t"
554 "pmove %%psr,%1"
555 : "=a&" (desc), "=m" (temp)
556 : "a" (addr), "d" (ssw));
557#else
558 asm volatile ("ptestr %2,%1@,#7\n\t"
559 "pmove %%psr,%0"
560 : "=m" (temp) : "a" (addr), "d" (ssw));
561#endif
562 mmusr = temp;
563
564#ifdef DEBUG
565 printk("mmusr is %#x for addr %#lx in task %p\n",
566 mmusr, addr, current);
567 printk("descriptor address is %#lx, contents %#lx\n",
568 __va(desc), *(unsigned long *)__va(desc));
569#endif
570
571 errorcode = (mmusr & MMU_I) ? 0 : 1;
572 if (!(ssw & RW) || (ssw & RM))
573 errorcode |= 2;
574
575 if (mmusr & (MMU_I | MMU_WP)) {
576 if (ssw & 4) {
577 printk("Data %s fault at %#010lx in %s (pc=%#lx)\n",
578 ssw & RW ? "read" : "write",
579 fp->un.fmtb.daddr,
580 space_names[ssw & DFC], fp->ptregs.pc);
581 goto buserr;
582 }
583
584
585 if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)
586 return;
587 } else if (!(mmusr & MMU_I)) {
588
589 if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0)
590 printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr);
591 } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
592 printk("invalid %s access at %#lx from pc %#lx\n",
593 !(ssw & RW) ? "write" : "read", addr,
594 fp->ptregs.pc);
595 die_if_kernel("Oops",&fp->ptregs,mmusr);
596 force_sig(SIGSEGV, current);
597 return;
598 } else {
599#if 0
600 static volatile long tlong;
601#endif
602
603 printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",
604 !(ssw & RW) ? "write" : "read", addr,
605 fp->ptregs.pc, ssw);
606 asm volatile ("ptestr #1,%1@,#0\n\t"
607 "pmove %%psr,%0"
608 : "=m" (temp)
609 : "a" (addr));
610 mmusr = temp;
611
612 printk ("level 0 mmusr is %#x\n", mmusr);
613#if 0
614 asm volatile ("pmove %%tt0,%0"
615 : "=m" (tlong));
616 printk("tt0 is %#lx, ", tlong);
617 asm volatile ("pmove %%tt1,%0"
618 : "=m" (tlong));
619 printk("tt1 is %#lx\n", tlong);
620#endif
621#ifdef DEBUG
622 printk("Unknown SIGSEGV - 1\n");
623#endif
624 die_if_kernel("Oops",&fp->ptregs,mmusr);
625 force_sig(SIGSEGV, current);
626 return;
627 }
628
629
630 if (!(ssw & RW) || (ssw & RM))
631 asm volatile ("ploadw %1,%0@" :
632 : "a" (addr), "d" (ssw));
633 else
634 asm volatile ("ploadr %1,%0@" :
635 : "a" (addr), "d" (ssw));
636 }
637
638
639
640 if (!(ssw & (FC|FB)))
641 return;
642
643 if (fp->ptregs.sr & PS_S) {
644 printk("Instruction fault at %#010lx\n",
645 fp->ptregs.pc);
646 buserr:
647 printk ("BAD KERNEL BUSERR\n");
648 die_if_kernel("Oops",&fp->ptregs,0);
649 force_sig(SIGKILL, current);
650 return;
651 }
652
653
654 if (fp->ptregs.format == 10)
655 addr = fp->ptregs.pc + 4;
656 else
657 addr = fp->un.fmtb.baddr;
658 if (ssw & FC)
659 addr -= 2;
660
661 if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)
662
663
664 goto create_atc_entry;
665
666#ifdef DEBUG
667 asm volatile ("ptestr #1,%2@,#7,%0\n\t"
668 "pmove %%psr,%1"
669 : "=a&" (desc), "=m" (temp)
670 : "a" (addr));
671#else
672 asm volatile ("ptestr #1,%1@,#7\n\t"
673 "pmove %%psr,%0"
674 : "=m" (temp) : "a" (addr));
675#endif
676 mmusr = temp;
677
678#ifdef DEBUG
679 printk ("mmusr is %#x for addr %#lx in task %p\n",
680 mmusr, addr, current);
681 printk ("descriptor address is %#lx, contents %#lx\n",
682 __va(desc), *(unsigned long *)__va(desc));
683#endif
684
685 if (mmusr & MMU_I)
686 do_page_fault (&fp->ptregs, addr, 0);
687 else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
688 printk ("invalid insn access at %#lx from pc %#lx\n",
689 addr, fp->ptregs.pc);
690#ifdef DEBUG
691 printk("Unknown SIGSEGV - 2\n");
692#endif
693 die_if_kernel("Oops",&fp->ptregs,mmusr);
694 force_sig(SIGSEGV, current);
695 return;
696 }
697
698create_atc_entry:
699
700 asm volatile ("ploadr #2,%0@" :
701 : "a" (addr));
702}
703#endif
704#endif
705
706#if defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU)
707#include <asm/mcfmmu.h>
708
709
710
711
712
713
714static const unsigned char fs_err_code[] = {
715 0,
716 0,
717 0,
718 0,
719 1,
720 0,
721 0,
722 0,
723 2,
724 3,
725 2,
726 0,
727 1,
728 1,
729 0,
730 0
731};
732
733static inline void access_errorcf(unsigned int fs, struct frame *fp)
734{
735 unsigned long mmusr, addr;
736 unsigned int err_code;
737 int need_page_fault;
738
739 mmusr = mmu_read(MMUSR);
740 addr = mmu_read(MMUAR);
741
742
743
744
745
746
747 switch (fs) {
748 case 5:
749 need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 0);
750 addr = fp->ptregs.pc;
751 break;
752 case 6:
753 need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 1);
754 addr = fp->ptregs.pc + sizeof(long);
755 break;
756 case 10:
757 need_page_fault = cf_tlb_miss(&fp->ptregs, 1, 1, 0);
758 break;
759 case 14:
760 need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 1, 0);
761 break;
762 default:
763
764
765
766
767
768
769
770
771
772
773
774
775 need_page_fault = 1;
776 break;
777 }
778
779 if (need_page_fault) {
780 err_code = fs_err_code[fs];
781 if ((fs == 13) && (mmusr & MMUSR_WF))
782 err_code |= 2;
783 do_page_fault(&fp->ptregs, addr, err_code);
784 }
785}
786#endif
787
788asmlinkage void buserr_c(struct frame *fp)
789{
790
791 if (user_mode(&fp->ptregs))
792 current->thread.esp0 = (unsigned long) fp;
793
794#ifdef DEBUG
795 printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);
796#endif
797
798#if defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU)
799 if (CPU_IS_COLDFIRE) {
800 unsigned int fs;
801 fs = (fp->ptregs.vector & 0x3) |
802 ((fp->ptregs.vector & 0xc00) >> 8);
803 switch (fs) {
804 case 0x5:
805 case 0x6:
806 case 0x7:
807 case 0x9:
808 case 0xa:
809 case 0xd:
810 case 0xe:
811 case 0xf:
812 access_errorcf(fs, fp);
813 return;
814 default:
815 break;
816 }
817 }
818#endif
819
820 switch (fp->ptregs.format) {
821#if defined (CONFIG_M68060)
822 case 4:
823 access_error060 (fp);
824 break;
825#endif
826#if defined (CONFIG_M68040)
827 case 0x7:
828 access_error040 (fp);
829 break;
830#endif
831#if defined (CPU_M68020_OR_M68030)
832 case 0xa:
833 case 0xb:
834 bus_error030 (fp);
835 break;
836#endif
837 default:
838 die_if_kernel("bad frame format",&fp->ptregs,0);
839#ifdef DEBUG
840 printk("Unknown SIGSEGV - 4\n");
841#endif
842 force_sig(SIGSEGV, current);
843 }
844}
845
846
847static int kstack_depth_to_print = 48;
848
849void show_trace(unsigned long *stack)
850{
851 unsigned long *endstack;
852 unsigned long addr;
853 int i;
854
855 printk("Call Trace:");
856 addr = (unsigned long)stack + THREAD_SIZE - 1;
857 endstack = (unsigned long *)(addr & -THREAD_SIZE);
858 i = 0;
859 while (stack + 1 <= endstack) {
860 addr = *stack++;
861
862
863
864
865
866
867
868
869 if (__kernel_text_address(addr)) {
870#ifndef CONFIG_KALLSYMS
871 if (i % 5 == 0)
872 printk("\n ");
873#endif
874 printk(" [<%08lx>] %pS\n", addr, (void *)addr);
875 i++;
876 }
877 }
878 printk("\n");
879}
880
881void show_registers(struct pt_regs *regs)
882{
883 struct frame *fp = (struct frame *)regs;
884 mm_segment_t old_fs = get_fs();
885 u16 c, *cp;
886 unsigned long addr;
887 int i;
888
889 print_modules();
890 printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);
891 printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2);
892 printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
893 regs->d0, regs->d1, regs->d2, regs->d3);
894 printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
895 regs->d4, regs->d5, regs->a0, regs->a1);
896
897 printk("Process %s (pid: %d, task=%p)\n",
898 current->comm, task_pid_nr(current), current);
899 addr = (unsigned long)&fp->un;
900 printk("Frame format=%X ", regs->format);
901 switch (regs->format) {
902 case 0x2:
903 printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);
904 addr += sizeof(fp->un.fmt2);
905 break;
906 case 0x3:
907 printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);
908 addr += sizeof(fp->un.fmt3);
909 break;
910 case 0x4:
911 printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"
912 : "eff addr=%08lx pc=%08lx\n"),
913 fp->un.fmt4.effaddr, fp->un.fmt4.pc);
914 addr += sizeof(fp->un.fmt4);
915 break;
916 case 0x7:
917 printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",
918 fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
919 printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",
920 fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
921 printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",
922 fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
923 printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",
924 fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
925 printk("push data: %08lx %08lx %08lx %08lx\n",
926 fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
927 fp->un.fmt7.pd3);
928 addr += sizeof(fp->un.fmt7);
929 break;
930 case 0x9:
931 printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);
932 addr += sizeof(fp->un.fmt9);
933 break;
934 case 0xa:
935 printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
936 fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
937 fp->un.fmta.daddr, fp->un.fmta.dobuf);
938 addr += sizeof(fp->un.fmta);
939 break;
940 case 0xb:
941 printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
942 fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
943 fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
944 printk("baddr=%08lx dibuf=%08lx ver=%x\n",
945 fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
946 addr += sizeof(fp->un.fmtb);
947 break;
948 default:
949 printk("\n");
950 }
951 show_stack(NULL, (unsigned long *)addr);
952
953 printk("Code:");
954 set_fs(KERNEL_DS);
955 cp = (u16 *)regs->pc;
956 for (i = -8; i < 16; i++) {
957 if (get_user(c, cp + i) && i >= 0) {
958 printk(" Bad PC value.");
959 break;
960 }
961 printk(i ? " %04x" : " <%04x>", c);
962 }
963 set_fs(old_fs);
964 printk ("\n");
965}
966
967void show_stack(struct task_struct *task, unsigned long *stack)
968{
969 unsigned long *p;
970 unsigned long *endstack;
971 int i;
972
973 if (!stack) {
974 if (task)
975 stack = (unsigned long *)task->thread.esp0;
976 else
977 stack = (unsigned long *)&stack;
978 }
979 endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
980
981 printk("Stack from %08lx:", (unsigned long)stack);
982 p = stack;
983 for (i = 0; i < kstack_depth_to_print; i++) {
984 if (p + 1 > endstack)
985 break;
986 if (i % 8 == 0)
987 printk("\n ");
988 printk(" %08lx", *p++);
989 }
990 printk("\n");
991 show_trace(stack);
992}
993
994
995
996
997
998
999
1000
1001
1002void bad_super_trap (struct frame *fp)
1003{
1004 int vector = (fp->ptregs.vector >> 2) & 0xff;
1005
1006 console_verbose();
1007 if (vector < ARRAY_SIZE(vec_names))
1008 printk ("*** %s *** FORMAT=%X\n",
1009 vec_names[vector],
1010 fp->ptregs.format);
1011 else
1012 printk ("*** Exception %d *** FORMAT=%X\n",
1013 vector, fp->ptregs.format);
1014 if (vector == VEC_ADDRERR && CPU_IS_020_OR_030) {
1015 unsigned short ssw = fp->un.fmtb.ssw;
1016
1017 printk ("SSW=%#06x ", ssw);
1018
1019 if (ssw & RC)
1020 printk ("Pipe stage C instruction fault at %#010lx\n",
1021 (fp->ptregs.format) == 0xA ?
1022 fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);
1023 if (ssw & RB)
1024 printk ("Pipe stage B instruction fault at %#010lx\n",
1025 (fp->ptregs.format) == 0xA ?
1026 fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
1027 if (ssw & DF)
1028 printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
1029 ssw & RW ? "read" : "write",
1030 fp->un.fmtb.daddr, space_names[ssw & DFC],
1031 fp->ptregs.pc);
1032 }
1033 printk ("Current process id is %d\n", task_pid_nr(current));
1034 die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
1035}
1036
1037asmlinkage void trap_c(struct frame *fp)
1038{
1039 int sig;
1040 int vector = (fp->ptregs.vector >> 2) & 0xff;
1041 siginfo_t info;
1042
1043 if (fp->ptregs.sr & PS_S) {
1044 if (vector == VEC_TRACE) {
1045
1046
1047
1048 } else if (!handle_kernel_fault(&fp->ptregs))
1049 bad_super_trap(fp);
1050 return;
1051 }
1052
1053
1054 switch (vector) {
1055 case VEC_ADDRERR:
1056 info.si_code = BUS_ADRALN;
1057 sig = SIGBUS;
1058 break;
1059 case VEC_ILLEGAL:
1060 case VEC_LINE10:
1061 case VEC_LINE11:
1062 info.si_code = ILL_ILLOPC;
1063 sig = SIGILL;
1064 break;
1065 case VEC_PRIV:
1066 info.si_code = ILL_PRVOPC;
1067 sig = SIGILL;
1068 break;
1069 case VEC_COPROC:
1070 info.si_code = ILL_COPROC;
1071 sig = SIGILL;
1072 break;
1073 case VEC_TRAP1:
1074 case VEC_TRAP2:
1075 case VEC_TRAP3:
1076 case VEC_TRAP4:
1077 case VEC_TRAP5:
1078 case VEC_TRAP6:
1079 case VEC_TRAP7:
1080 case VEC_TRAP8:
1081 case VEC_TRAP9:
1082 case VEC_TRAP10:
1083 case VEC_TRAP11:
1084 case VEC_TRAP12:
1085 case VEC_TRAP13:
1086 case VEC_TRAP14:
1087 info.si_code = ILL_ILLTRP;
1088 sig = SIGILL;
1089 break;
1090 case VEC_FPBRUC:
1091 case VEC_FPOE:
1092 case VEC_FPNAN:
1093 info.si_code = FPE_FLTINV;
1094 sig = SIGFPE;
1095 break;
1096 case VEC_FPIR:
1097 info.si_code = FPE_FLTRES;
1098 sig = SIGFPE;
1099 break;
1100 case VEC_FPDIVZ:
1101 info.si_code = FPE_FLTDIV;
1102 sig = SIGFPE;
1103 break;
1104 case VEC_FPUNDER:
1105 info.si_code = FPE_FLTUND;
1106 sig = SIGFPE;
1107 break;
1108 case VEC_FPOVER:
1109 info.si_code = FPE_FLTOVF;
1110 sig = SIGFPE;
1111 break;
1112 case VEC_ZERODIV:
1113 info.si_code = FPE_INTDIV;
1114 sig = SIGFPE;
1115 break;
1116 case VEC_CHK:
1117 case VEC_TRAP:
1118 info.si_code = FPE_INTOVF;
1119 sig = SIGFPE;
1120 break;
1121 case VEC_TRACE:
1122 info.si_code = TRAP_TRACE;
1123 sig = SIGTRAP;
1124 break;
1125 case VEC_TRAP15:
1126 info.si_code = TRAP_BRKPT;
1127 sig = SIGTRAP;
1128 break;
1129 default:
1130 info.si_code = ILL_ILLOPC;
1131 sig = SIGILL;
1132 break;
1133 }
1134 info.si_signo = sig;
1135 info.si_errno = 0;
1136 switch (fp->ptregs.format) {
1137 default:
1138 info.si_addr = (void *) fp->ptregs.pc;
1139 break;
1140 case 2:
1141 info.si_addr = (void *) fp->un.fmt2.iaddr;
1142 break;
1143 case 7:
1144 info.si_addr = (void *) fp->un.fmt7.effaddr;
1145 break;
1146 case 9:
1147 info.si_addr = (void *) fp->un.fmt9.iaddr;
1148 break;
1149 case 10:
1150 info.si_addr = (void *) fp->un.fmta.daddr;
1151 break;
1152 case 11:
1153 info.si_addr = (void *) fp->un.fmtb.daddr;
1154 break;
1155 }
1156 force_sig_info (sig, &info, current);
1157}
1158
1159void die_if_kernel (char *str, struct pt_regs *fp, int nr)
1160{
1161 if (!(fp->sr & PS_S))
1162 return;
1163
1164 console_verbose();
1165 printk("%s: %08x\n",str,nr);
1166 show_registers(fp);
1167 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
1168 do_exit(SIGSEGV);
1169}
1170
1171asmlinkage void set_esp0(unsigned long ssp)
1172{
1173 current->thread.esp0 = ssp;
1174}
1175
1176
1177
1178
1179
1180asmlinkage void fpsp040_die(void)
1181{
1182 do_exit(SIGSEGV);
1183}
1184
1185#ifdef CONFIG_M68KFPU_EMU
1186asmlinkage void fpemu_signal(int signal, int code, void *addr)
1187{
1188 siginfo_t info;
1189
1190 info.si_signo = signal;
1191 info.si_errno = 0;
1192 info.si_code = code;
1193 info.si_addr = addr;
1194 force_sig_info(signal, &info, current);
1195}
1196#endif
1197