This source file includes following definitions.
- trap_init
- set_evector
- console_verbose
- access_error060
- probe040
- do_040writeback
- access_error040
- bus_error030
- buserr_c
- dump_stack
- bad_super_trap
- trap_c
- set_esp0
- die_if_kernel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <linux/config.h>
21 #include <linux/sched.h>
22 #include <linux/signal.h>
23 #include <linux/kernel.h>
24 #include <linux/mm.h>
25 #include <linux/types.h>
26 #include <linux/a.out.h>
27 #include <linux/user.h>
28 #include <linux/string.h>
29 #include <linux/linkage.h>
30
31 #include <asm/system.h>
32 #include <asm/segment.h>
33 #include <asm/traps.h>
34 #include <asm/bootinfo.h>
35 #include <asm/pgtable.h>
36 #include <asm/machdep.h>
37
38
39 asmlinkage void system_call(void);
40 asmlinkage void buserr(void);
41 asmlinkage void trap(void);
42 asmlinkage void inthandler(void);
43 asmlinkage void nmihandler(void);
44
45 e_vector vectors[256] = {
46 0, 0, buserr, trap, trap, trap, trap, trap,
47 trap, trap, trap, trap, trap, trap, trap, trap,
48 trap, trap, trap, trap, trap, trap, trap, trap,
49 inthandler, inthandler, inthandler, inthandler,
50 inthandler, inthandler, inthandler, inthandler,
51
52 system_call, trap, trap, trap, trap, trap, trap, trap,
53 trap, trap, trap, trap, trap, trap, trap, trap,
54 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
55 };
56
57
58 asm(".text\n"
59 __ALIGN_STR "\n"
60 SYMBOL_NAME_STR(nmihandler) ": rte");
61
62 void trap_init (void)
63 {
64 int i;
65
66
67 __asm__ volatile ("movec %0,%/vbr" : : "r" ((void*)vectors));
68
69 for (i = 48; i < 64; i++)
70 vectors[i] = trap;
71
72 for (i = 64; i < 256; i++)
73 vectors[i] = inthandler;
74
75
76 if (MACH_IS_AMIGA) {
77 vectors[VEC_INT7] = nmihandler;
78 }
79
80 #ifdef CONFIG_FPSP_040
81 if (m68k_is040or060 == 4) {
82
83 asmlinkage void dz_vec(void) asm ("dz");
84 asmlinkage void inex_vec(void) asm ("inex");
85 asmlinkage void ovfl_vec(void) asm ("ovfl");
86 asmlinkage void unfl_vec(void) asm ("unfl");
87 asmlinkage void snan_vec(void) asm ("snan");
88 asmlinkage void operr_vec(void) asm ("operr");
89 asmlinkage void bsun_vec(void) asm ("bsun");
90 asmlinkage void fline_vec(void) asm ("fline");
91 asmlinkage void unsupp_vec(void) asm ("unsupp");
92
93 vectors[VEC_FPDIVZ] = dz_vec;
94 vectors[VEC_FPIR] = inex_vec;
95 vectors[VEC_FPOVER] = ovfl_vec;
96 vectors[VEC_FPUNDER] = unfl_vec;
97 vectors[VEC_FPNAN] = snan_vec;
98 vectors[VEC_FPOE] = operr_vec;
99 vectors[VEC_FPBRUC] = bsun_vec;
100 vectors[VEC_FPBRUC] = bsun_vec;
101 vectors[VEC_LINE11] = fline_vec;
102 vectors[VEC_FPUNSUP] = unsupp_vec;
103 }
104 #endif
105 #ifdef CONFIG_IFPSP_060
106 if (m68k_is040or060 == 6) {
107
108 asmlinkage void snan_vec(void) asm ("_060_fpsp_snan");
109 asmlinkage void operr_vec(void) asm ("_060_fpsp_operr");
110 asmlinkage void ovfl_vec(void) asm ("_060_fpsp_ovfl");
111 asmlinkage void unfl_vec(void) asm ("_060_fpsp_unfl");
112 asmlinkage void dz_vec(void) asm ("_060_fpsp_dz");
113 asmlinkage void inex_vec(void) asm ("_060_fpsp_inex");
114 asmlinkage void fline_vec(void) asm ("_060_fpsp_fline");
115 asmlinkage void unsupp_vec(void) asm ("_060_fpsp_unsupp");
116 asmlinkage void effadd_vec(void) asm ("_060_fpsp_effadd");
117
118 asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");
119
120 vectors[VEC_FPNAN] = snan_vec;
121 vectors[VEC_FPOE] = operr_vec;
122 vectors[VEC_FPOVER] = ovfl_vec;
123 vectors[VEC_FPUNDER] = unfl_vec;
124 vectors[VEC_FPDIVZ] = dz_vec;
125 vectors[VEC_FPIR] = inex_vec;
126 vectors[VEC_LINE11] = fline_vec;
127 vectors[VEC_FPUNSUP] = unsupp_vec;
128 vectors[VEC_UNIMPEA] = effadd_vec;
129
130
131
132 vectors[VEC_UNIMPII] = unimp_vec;
133
134 }
135 #endif
136 }
137
138 void set_evector(int vecnum, void (*handler)(void))
139 {
140 if (vecnum >= 0 && vecnum <= 256)
141 vectors[vecnum] = handler;
142 }
143
144
145 static inline void console_verbose(void)
146 {
147 extern int console_loglevel;
148 console_loglevel = 15;
149 mach_debug_init();
150 }
151
152 char *vec_names[] = {
153 "RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR",
154 "ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc",
155 "PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111",
156 "UNASSIGNED RESERVED 12", "COPROCESSOR PROTOCOL VIOLATION",
157 "FORMAT ERROR", "UNINITIALIZED INTERRUPT",
158 "UNASSIGNED RESERVED 16", "UNASSIGNED RESERVED 17",
159 "UNASSIGNED RESERVED 18", "UNASSIGNED RESERVED 19",
160 "UNASSIGNED RESERVED 20", "UNASSIGNED RESERVED 21",
161 "UNASSIGNED RESERVED 22", "UNASSIGNED RESERVED 23",
162 "SPURIOUS INTERRUPT", "LEVEL 1 INT", "LEVEL 2 INT", "LEVEL 3 INT",
163 "LEVEL 4 INT", "LEVEL 5 INT", "LEVEL 6 INT", "LEVEL 7 INT",
164 "SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
165 "TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
166 "TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
167 "TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15"
168 };
169
170 char *space_names[] = {
171 "Space 0", "User Data", "User Program", "Space 3",
172 "Space 4", "Super Data", "Super Program", "CPU"
173 };
174
175
176
177 extern void die_if_kernel(char *,struct pt_regs *,int);
178 asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
179 unsigned long error_code);
180
181 asmlinkage void trap_c(struct frame *fp);
182
183 static inline void access_error060 (struct frame *fp)
184 {
185 unsigned long fslw = fp->un.fmt4.pc;
186
187 #ifdef DEBUG
188 printk("fslw=%#lx, fa=%#lx\n", ssw, fp->un.fmt4.effaddr);
189 #endif
190
191 if (fslw & MMU060_BPE) {
192
193 __asm__ __volatile__ ("movec %/cacr,%/d0\n\t"
194 "orl #0x00400000,%/d0\n\t"
195 "movec %/d0,%/cacr"
196 : : : "d0" );
197
198 if (!(fslw & MMU060_ERR_BITS))
199 return;
200 }
201
202 if (fslw & (MMU060_DESC_ERR | MMU060_WP)) {
203 unsigned long errorcode;
204 unsigned long addr = fp->un.fmt4.effaddr;
205 errorcode = ((fslw & MMU060_WP) ? 1 : 0) |
206 ((fslw & MMU060_W) ? 2 : 0);
207 #ifdef DEBUG
208 printk("errorcode = %d\n", errorcode );
209 #endif
210 if (fslw & MMU060_MA)
211 addr = PAGE_ALIGN(addr);
212 do_page_fault( (struct pt_regs *)fp, addr, errorcode );
213 }
214 else {
215 printk( "68060 access error, fslw=%lx\n", fslw );
216 trap_c( fp );
217 }
218 }
219
220 static unsigned long probe040 (int iswrite, int fc, unsigned long addr)
221 {
222 unsigned long mmusr;
223 unsigned long fs = get_fs();
224
225 set_fs (fc);
226
227 if (iswrite)
228
229 asm volatile ("movel %1,%/a0\n\t"
230 ".word 0xf548\n\t"
231 ".long 0x4e7a8805\n\t"
232 "movel %/a0,%0"
233 : "=g" (mmusr)
234 : "g" (addr)
235 : "a0");
236 else
237 asm volatile ("movel %1,%/a0\n\t"
238 ".word 0xf568\n\t"
239 ".long 0x4e7a8805\n\t"
240 "movel %/a0,%0"
241 : "=g" (mmusr)
242 : "g" (addr)
243 : "a0");
244
245
246 set_fs (fs);
247
248 return mmusr;
249 }
250
251 static void do_040writeback (unsigned short ssw,
252 unsigned short wbs,
253 unsigned long wba,
254 unsigned long wbd,
255 struct frame *fp)
256 {
257 unsigned long fs = get_fs ();
258 unsigned long mmusr;
259 unsigned long errorcode;
260
261
262
263
264
265
266
267 mmusr = probe040 (1, wbs & WBTM_040, wba);
268 errorcode = (mmusr & MMU_R_040) ? 3 : 2;
269 if (do_page_fault ((struct pt_regs *)fp, wba, errorcode))
270
271 return;
272
273 set_fs (wbs & WBTM_040);
274 switch (wbs & WBSIZ_040) {
275 case BA_SIZE_BYTE:
276 put_fs_byte (wbd & 0xff, (char *)wba);
277 break;
278 case BA_SIZE_WORD:
279 put_fs_word (wbd & 0xffff, (short *)wba);
280 break;
281 case BA_SIZE_LONG:
282 put_fs_long (wbd, (int *)wba);
283 break;
284 }
285 set_fs (fs);
286 }
287
288 static inline void access_error040 (struct frame *fp)
289 {
290 unsigned short ssw = fp->un.fmt7.ssw;
291 unsigned long mmusr;
292
293 #ifdef DEBUG
294 printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);
295 printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,
296 fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);
297 printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",
298 fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,
299 fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);
300 #endif
301
302
303 if (ssw & ATC_040) {
304 unsigned long addr = fp->un.fmt7.faddr;
305 unsigned long errorcode;
306
307
308
309
310
311 if (ssw & MA_040)
312 addr = PAGE_ALIGN (addr);
313
314
315 mmusr = probe040 (!(ssw & RW_040), ssw & TM_040, addr);
316
317
318
319
320
321 errorcode = ((mmusr & MMU_R_040) ? 1 : 0) |
322 ((ssw & RW_040) ? 0 : 2);
323 do_page_fault ((struct pt_regs *)fp, addr, errorcode);
324 } else {
325 printk ("68040 access error, ssw=%x\n", ssw);
326 trap_c (fp);
327 }
328
329 #if 0
330 if (fp->un.fmt7.wb1s & WBV_040)
331 printk("access_error040: cannot handle 1st writeback. oops.\n");
332 #endif
333
334
335
336
337
338
339
340
341
342
343 if (fp->un.fmt7.wb2s & WBV_040 && (fp->un.fmt7.wb2s &
344 WBTT_040) != BA_TT_MOVE16)
345 do_040writeback (ssw,
346 fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,
347 fp->un.fmt7.wb2d, fp);
348
349 if (fp->un.fmt7.wb3s & WBV_040)
350 do_040writeback (ssw, fp->un.fmt7.wb3s,
351 fp->un.fmt7.wb3a, fp->un.fmt7.wb3d,
352 fp);
353 }
354
355 static inline void bus_error030 (struct frame *fp)
356 {
357 volatile unsigned short temp;
358 unsigned short mmusr;
359 unsigned long addr, desc, errorcode;
360 unsigned short ssw = fp->un.fmtb.ssw;
361 int user_space_fault = 1;
362
363 #if DEBUG
364 printk ("pid = %x ", current->pid);
365 printk ("SSW=%#06x ", ssw);
366
367 if (ssw & (FC | FB))
368 printk ("Instruction fault at %#010lx\n",
369 ssw & FC ?
370 fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
371 :
372 fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
373 if (ssw & DF)
374 printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
375 ssw & RW ? "read" : "write",
376 fp->un.fmtb.daddr,
377 space_names[ssw & DFC], fp->ptregs.pc);
378 #endif
379
380 if (fp->ptregs.sr & PS_S) {
381
382 if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {
383
384 if (ssw & (FC | FB))
385 printk ("Instruction fault at %#010lx\n",
386 fp->ptregs.pc);
387 if (ssw & DF) {
388 printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
389 ssw & RW ? "read" : "write",
390 fp->un.fmtb.daddr,
391 space_names[ssw & DFC], fp->ptregs.pc);
392 }
393 printk ("BAD KERNEL BUSERR\n");
394 die_if_kernel("Oops",&fp->ptregs,0);
395 force_sig(SIGSEGV, current);
396 user_space_fault = 0;
397 }
398 } else {
399
400 if (!(ssw & (FC | FB)) && !(ssw & DF))
401
402 panic ("USER BUSERR w/o instruction or data fault");
403 user_space_fault = 1;
404 #if DEBUG
405 printk("User space bus-error\n");
406 #endif
407 }
408
409
410
411
412
413 if (ssw & DF)
414 {
415 addr = fp->un.fmtb.daddr;
416
417 if (user_space_fault) {
418 asm volatile ("ptestr #1,%2@,#7,%0\n\t"
419 "pmove %/psr,%1@"
420 : "=a&" (desc)
421 : "a" (&temp), "a" (addr));
422 mmusr = temp;
423 } else
424 mmusr = MMU_I;
425
426 #if DEBUG
427 printk ("mmusr is %#x for addr %#lx in task %p\n",
428 mmusr, addr, current);
429 printk ("descriptor address is %#lx, contents %#lx\n",
430 mm_ptov(desc), *(unsigned long *)mm_ptov(desc));
431 #endif
432
433 errorcode = (mmusr & MMU_I) ? 0 : 1;
434
435 if (!(ssw & RW) || ssw & RM)
436 errorcode |= 2;
437
438 if (mmusr & MMU_I)
439 do_page_fault ((struct pt_regs *)fp, addr, errorcode);
440
441
442
443 else if ((mmusr & MMU_WP) && (!(ssw & RW) || ssw & RM))
444 do_page_fault ((struct pt_regs *)fp, addr, errorcode);
445 else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
446 printk ("invalid %s access at %#lx from pc %#lx\n",
447 !(ssw & RW) ? "write" : "read", addr,
448 fp->ptregs.pc);
449 die_if_kernel("Oops",&fp->ptregs,mmusr);
450 force_sig(SIGSEGV, current);
451 return;
452 } else {
453 #ifdef DEBUG
454 static volatile long tlong;
455 #endif
456
457 printk ("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",
458 !(ssw & RW) ? "write" : "read", addr,
459 fp->ptregs.pc, ssw);
460 asm volatile ("ptestr #1,%1@,#0\n\t"
461 "pmove %/psr,%0@"
462 :
463 : "a" (&temp), "a" (addr));
464 mmusr = temp;
465
466 printk ("level 0 mmusr is %#x\n", mmusr);
467 #if 0
468 asm volatile ("pmove %/tt0,%0@"
469 :
470 : "a" (&tlong));
471 printk ("tt0 is %#lx, ", tlong);
472 asm volatile ("pmove %/tt1,%0@"
473 :
474 : "a" (&tlong));
475 printk ("tt1 is %#lx\n", tlong);
476 #endif
477 #if DEBUG
478 printk("Unknown SIGSEGV - 1\n");
479 #endif
480 die_if_kernel("Oops",&fp->ptregs,mmusr);
481 force_sig(SIGSEGV, current);
482 return;
483 }
484
485
486 if (!(ssw & RW))
487 asm volatile ("ploadw #1,%0@" :
488 : "a" (addr));
489 else
490 asm volatile ("ploadr #1,%0@" :
491 : "a" (addr));
492
493
494
495
496
497 if ((ssw & RB) && (mmusr & MMU_I))
498 {
499 unsigned long iaddr;
500
501 if ((fp->ptregs.format) == 0xB)
502 iaddr = fp->un.fmtb.baddr;
503 else
504 iaddr = fp->ptregs.pc + 4;
505 if (((addr ^ iaddr) & PAGE_MASK) == 0)
506 {
507
508
509 asm volatile ("ptestr #1,%1@,#0\n\t"
510 "pmove %/psr,%0@"
511 : : "a" (&temp), "a" (iaddr));
512 mmusr = temp;
513 #ifdef DEBUG
514 printk ("prefetch iaddr=%#lx ssw=%#x mmusr=%#x\n",
515 iaddr, ssw, mmusr);
516 #endif
517 if (!(mmusr & MMU_I))
518 {
519 unsigned short insn;
520 asm volatile ("movesw %1@,%0"
521 : "=r" (insn)
522 : "a" (iaddr));
523 fp->un.fmtb.isb = insn;
524 fp->un.fmtb.ssw &= ~RB;
525 }
526 }
527 }
528 }
529
530
531
532
533 if ((fp->ptregs.format) == 0xA )
534 if (ssw & FC)
535 addr = fp->ptregs.pc + 2;
536 else if (ssw & FB)
537 addr = fp->ptregs.pc + 4;
538 else
539 return;
540 else
541 if (ssw & FC)
542 addr = fp->un.fmtb.baddr - 2;
543 else if (ssw & FB)
544 addr = fp->un.fmtb.baddr;
545 else
546 return;
547
548 if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)
549
550 return;
551
552 if (user_space_fault) {
553 asm volatile ("ptestr #1,%2@,#7,%0\n\t"
554 "pmove %/psr,%1@"
555 : "=a&" (desc)
556 : "a" (&temp), "a" (addr));
557 mmusr = temp;
558 } else
559 mmusr = MMU_I;
560
561 #ifdef DEBUG
562 printk ("mmusr is %#x for addr %#lx in task %p\n",
563 mmusr, addr, current);
564 printk ("descriptor address is %#lx, contents %#lx\n",
565 mm_ptov(desc), *(unsigned long *)mm_ptov(desc));
566 #endif
567
568 errorcode = (mmusr & MMU_I) ? 0 : 1;
569
570 if (mmusr & MMU_I)
571 do_page_fault ((struct pt_regs *)fp, addr, errorcode);
572 else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
573 printk ("invalid insn access at %#lx from pc %#lx\n",
574 addr, fp->ptregs.pc);
575 #if DEBUG
576 printk("Unknown SIGSEGV - 2\n");
577 #endif
578 die_if_kernel("Oops",&fp->ptregs,mmusr);
579 force_sig(SIGSEGV, current);
580 return;
581 } else {
582 #ifdef DEBUG
583 static volatile long tlong;
584 #endif
585
586 printk ("weird insn access at %#lx from pc %#lx (ssw is %#x)\n",
587 addr, fp->ptregs.pc, ssw);
588 asm volatile ("ptestr #1,%1@,#0\n\t"
589 "pmove %/psr,%0@"
590 :
591 : "a" (&temp), "a" (addr));
592 mmusr = temp;
593
594 printk ("level 0 mmusr is %#x\n", mmusr);
595 #ifdef DEBUG
596 if (boot_info.cputype & CPU_68030) {
597 asm volatile ("pmove %/tt0,%0@"
598 :
599 : "a" (&tlong));
600 printk ("tt0 is %#lx, ", tlong);
601 asm volatile ("pmove %/tt1,%0@"
602 :
603 : "a" (&tlong));
604 printk ("tt1 is %#lx\n", tlong);
605 }
606
607 #endif
608 #if DEBUG
609 printk("Unknown SIGSEGV - 3\n");
610 #endif
611 die_if_kernel("Oops",&fp->ptregs,mmusr);
612 force_sig(SIGSEGV, current);
613 return;
614 }
615
616
617 asm volatile ("ploadr #1,%0@" :
618 : "a" (addr));
619 }
620
621 asmlinkage void buserr_c(struct frame *fp)
622 {
623
624 if (user_mode(&fp->ptregs))
625 current->tss.esp0 = (unsigned long) fp;
626
627 #if DEBUG
628 printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);
629 #endif
630
631 switch (fp->ptregs.format) {
632 case 4:
633 access_error060 (fp);
634 break;
635 case 0x7:
636 access_error040 (fp);
637 break;
638 case 0xa:
639 case 0xb:
640 bus_error030 (fp);
641 break;
642 default:
643 die_if_kernel("bad frame format",&fp->ptregs,0);
644 #if DEBUG
645 printk("Unknown SIGSEGV - 4\n");
646 #endif
647 force_sig(SIGSEGV, current);
648 }
649 }
650
651
652 int kstack_depth_to_print = 48;
653
654
655
656 #define MODULE_RANGE (8*1024*1024)
657
658 static void dump_stack(struct frame *fp)
659 {
660 unsigned long *stack, *endstack, addr, module_start, module_end;
661 extern char _start, _etext;
662 int i;
663
664 addr = (unsigned long)&fp->un;
665 printk("Frame format=%X ", fp->ptregs.format);
666 switch (fp->ptregs.format) {
667 case 0x2:
668 printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);
669 addr += sizeof(fp->un.fmt2);
670 break;
671 case 0x3:
672 printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);
673 addr += sizeof(fp->un.fmt3);
674 break;
675 case 0x4:
676 printk((m68k_is040or060 == 6 ? "fault addr=%08lx fslw=%08lx\n"
677 : "eff addr=%08lx pc=%08lx\n"),
678 fp->un.fmt4.effaddr, fp->un.fmt4.pc);
679 addr += sizeof(fp->un.fmt4);
680 break;
681 case 0x7:
682 printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",
683 fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
684 printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",
685 fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
686 printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",
687 fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
688 printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",
689 fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
690 printk("push data: %08lx %08lx %08lx %08lx\n",
691 fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
692 fp->un.fmt7.pd3);
693 addr += sizeof(fp->un.fmt7);
694 break;
695 case 0x9:
696 printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);
697 addr += sizeof(fp->un.fmt9);
698 break;
699 case 0xa:
700 printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
701 fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
702 fp->un.fmta.daddr, fp->un.fmta.dobuf);
703 addr += sizeof(fp->un.fmta);
704 break;
705 case 0xb:
706 printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
707 fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
708 fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
709 printk("baddr=%08lx dibuf=%08lx ver=%x\n",
710 fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
711 addr += sizeof(fp->un.fmtb);
712 break;
713 default:
714 printk("\n");
715 }
716
717 stack = (unsigned long *)addr;
718 endstack = (unsigned long *)PAGE_ALIGN(addr);
719
720 printk("Stack from %08lx:\n ", (unsigned long)stack);
721 for (i = 0; i < kstack_depth_to_print; i++) {
722 if (stack + 1 > endstack)
723 break;
724 if (i && ((i % 8) == 0))
725 printk("\n ");
726 printk("%08lx ", *stack++);
727 }
728
729 printk ("\nCall Trace: ");
730 stack = (unsigned long *) addr;
731 i = 1;
732 module_start = VMALLOC_START;
733 module_end = module_start + MODULE_RANGE;
734 while (stack + 1 <= endstack) {
735 addr = *stack++;
736
737
738
739
740
741
742
743
744 if (((addr >= (unsigned long) &_start) &&
745 (addr <= (unsigned long) &_etext)) ||
746 ((addr >= module_start) && (addr <= module_end))) {
747 if (i && ((i % 8) == 0))
748 printk("\n ");
749 printk("[<%08lx>] ", addr);
750 i++;
751 }
752 }
753 printk("\nCode: ");
754 for (i = 0; i < 10; i++)
755 printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]);
756 printk ("\n");
757 }
758
759 void bad_super_trap (struct frame *fp)
760 {
761 console_verbose();
762 if ((fp->ptregs.vector) < 48*4)
763 printk ("*** %s *** FORMAT=%X\n",
764 vec_names[(fp->ptregs.vector) >> 2],
765 fp->ptregs.format);
766 else
767 printk ("*** Exception %d *** FORMAT=%X\n",
768 (fp->ptregs.vector) >> 2,
769 fp->ptregs.format);
770 if (((fp->ptregs.vector) >> 2) == VEC_ADDRERR
771 && !m68k_is040or060) {
772 unsigned short ssw = fp->un.fmtb.ssw;
773
774 printk ("SSW=%#06x ", ssw);
775
776 if (ssw & RC)
777 printk ("Pipe stage C instruction fault at %#010lx\n",
778 (fp->ptregs.format) == 0xA ?
779 fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);
780 if (ssw & RB)
781 printk ("Pipe stage B instruction fault at %#010lx\n",
782 (fp->ptregs.format) == 0xA ?
783 fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
784 if (ssw & DF)
785 printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
786 ssw & RW ? "read" : "write",
787 fp->un.fmtb.daddr, space_names[ssw & DFC],
788 fp->ptregs.pc);
789 }
790 printk ("Current process id is %d\n", current->pid);
791 die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
792 }
793
794 asmlinkage void trap_c(struct frame *fp)
795 {
796 int sig;
797
798 if ((fp->ptregs.sr & PS_S)
799 && ((fp->ptregs.vector) >> 2) == VEC_TRACE
800 && !(fp->ptregs.sr & PS_T)) {
801
802 unsigned char *lp = ((unsigned char *)&fp->un.fmt2) + 4;
803 current->flags |= PF_DTRACE;
804
805 (*(unsigned short *)lp) &= ~PS_T;
806 return;
807 } else if (fp->ptregs.sr & PS_S) {
808 bad_super_trap(fp);
809 return;
810 }
811
812
813 switch ((fp->ptregs.vector) >> 2) {
814 case VEC_ADDRERR:
815 sig = SIGBUS;
816 break;
817 case VEC_BUSERR:
818 sig = SIGSEGV;
819 break;
820 case VEC_ILLEGAL:
821 case VEC_PRIV:
822 case VEC_LINE10:
823 case VEC_LINE11:
824 case VEC_COPROC:
825 case VEC_TRAP1:
826 case VEC_TRAP2:
827 case VEC_TRAP3:
828 case VEC_TRAP4:
829 case VEC_TRAP5:
830 case VEC_TRAP6:
831 case VEC_TRAP7:
832 case VEC_TRAP8:
833 case VEC_TRAP9:
834 case VEC_TRAP10:
835 case VEC_TRAP11:
836 case VEC_TRAP12:
837 case VEC_TRAP13:
838 case VEC_TRAP14:
839 sig = SIGILL;
840 break;
841 case VEC_FPBRUC:
842 case VEC_FPIR:
843 case VEC_FPDIVZ:
844 case VEC_FPUNDER:
845 case VEC_FPOE:
846 case VEC_FPOVER:
847 case VEC_FPNAN:
848 {
849 unsigned char fstate[216];
850
851 __asm__ __volatile__ ("fsave %0@" : : "a" (fstate) : "memory");
852
853 if (*(unsigned short *) fstate == 0x1f38)
854 {
855 fstate[fstate[1]] |= 1 << 3;
856 __asm__ __volatile__ ("frestore %0@" : : "a" (fstate));
857 }
858 }
859
860 case VEC_ZERODIV:
861 case VEC_TRAP:
862 sig = SIGFPE;
863 break;
864 case VEC_TRACE:
865 fp->ptregs.sr &= ~PS_T;
866 case VEC_TRAP15:
867 sig = SIGTRAP;
868 break;
869 default:
870 sig = SIGILL;
871 break;
872 }
873
874 force_sig (sig, current);
875 }
876
877 asmlinkage void set_esp0 (unsigned long ssp)
878 {
879 current->tss.esp0 = ssp;
880 }
881
882 void die_if_kernel (char *str, struct pt_regs *fp, int nr)
883 {
884 if (!(fp->sr & PS_S))
885 return;
886
887 console_verbose();
888 printk("%s: %08x\n",str,nr);
889 printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp);
890 printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
891 fp->d0, fp->d1, fp->d2, fp->d3);
892 printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
893 fp->d4, fp->d5, fp->a0, fp->a1);
894
895 if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page)
896 printk("Corrupted stack page\n");
897 printk("Process %s (pid: %d, stackpage=%08lx)\n",
898 current->comm, current->pid, current->kernel_stack_page);
899 dump_stack((struct frame *)fp);
900 do_exit(SIGSEGV);
901 }