📄 traps.c
字号:
/* * linux/arch/m68knommu/kernel/traps.c * * Copyright (C) 1998 D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>, * Kenneth Albanowski <kjahds@kjahds.com> * The Silver Hammer Group, Ltd. * * (Blame me for the icky bits -- kja) * * Based on: * * linux/arch/m68k/kernel/traps.c * * Copyright (C) 1993, 1994 by Hamish Macdonald * * 68040 fixes by Michael Rausch * 68040 fixes by Martin Apel * 68060 fixes by Roman Hodek * 68060 fixes by Jesper Skov * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. *//* * Sets up all exception vectors */#include <linux/config.h>#include <linux/sched.h>#include <linux/signal.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/types.h>#include <linux/a.out.h>#include <linux/user.h>#include <linux/string.h>#include <linux/linkage.h>#include <asm/setup.h>#include <asm/system.h>#include <asm/segment.h>#include <asm/traps.h>#include <asm/pgtable.h>#include <asm/machdep.h>#ifdef CONFIG_M68328#include <asm/MC68328.h>#endif#ifdef CONFIG_M68EZ328#include <asm/MC68EZ328.h>#endif/* assembler routines */asmlinkage void system_call(void);asmlinkage void buserr(void);asmlinkage void trap(void);asmlinkage void trap3(void);asmlinkage void trap4(void);asmlinkage void trap5(void);asmlinkage void trap6(void);asmlinkage void trap7(void);asmlinkage void trap8(void);asmlinkage void trap9(void);asmlinkage void trap10(void);asmlinkage void trap11(void);asmlinkage void trap12(void);asmlinkage void trap13(void);asmlinkage void trap14(void);asmlinkage void trap15(void);asmlinkage void trap33(void);asmlinkage void trap34(void);asmlinkage void trap35(void);asmlinkage void trap36(void);asmlinkage void trap37(void);asmlinkage void trap38(void);asmlinkage void trap39(void);asmlinkage void trap40(void);asmlinkage void trap41(void);asmlinkage void trap42(void);asmlinkage void trap43(void);asmlinkage void trap44(void);asmlinkage void trap45(void);asmlinkage void trap46(void);asmlinkage void trap47(void);asmlinkage void bad_interrupt(void);asmlinkage void inthandler(void);asmlinkage void inthandler1(void);asmlinkage void inthandler2(void);asmlinkage void inthandler3(void);asmlinkage void inthandler4(void);asmlinkage void inthandler5(void);asmlinkage void inthandler6(void);asmlinkage void inthandler7(void);/*static void ignore(void);*//* extern e_vector _ramvec[]; */e_vector *_ramvec = (void *)0;extern e_vector _romvec[];#if defined( CONFIG_PILOT ) && defined( CONFIG_M68328 )asm (" .global _start, _ramend .section .romvec .long _ramend-4, _start /* Stack & reset vector */ .long 0xFEEDBEEF /* Card signature */ .word -1 /* Version of card header */ .word 0 /* Flags */ .byte 'u', 'C' /* 32 bytes card name */ .org 48 .byte 'u', 'C' /* 32 bytes manuf name */ .org 80 .word 0 /* Card version */ .long 0 /* Creation date */ .word 0 /* RAM blocks */ .long 0 /* RAM list offset */ .long 0 /* */ .long 0 /* */ .long 0 /* */ .long 0x10000 /* BigROM offset */ .long 0x100000 /* Card size in bytes */ .word 0x00 /* CRC of card */ .org 0x10000");#endif #if defined( CONFIG_M68328 ) || defined ( CONFIG_M68EZ328 )asm (" .global _start, _ramend .section .romvece_vectors: .long _ramend-4, _start, buserr, trap, trap, trap, trap, trap .long trap, trap, trap, trap, trap, trap, trap, trap .long trap, trap, trap, trap, trap, trap, trap, trap .long trap, trap, trap, trap .long trap, trap, trap, trap /*.long inthandler, inthandler, inthandler, inthandler .long inthandler4, inthandler, inthandler, inthandler */ /* TRAP #0-15 */ .long system_call, trap, trap, trap, trap, trap, trap, trap .long trap, trap, trap, trap, trap, trap, trap, trap .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .text ignore: rte");#endif /* CONFIG_M68328 || CONFIG_M68EZ328 */#ifdef CONFIG_M68332asm (" .global _start, _ramend .section .romvece_vectors: .long _ramend-4, _start, buserr, trap, trap, trap, trap, trap .long trap, trap, trap, trap, trap, trap, trap, trap .long trap, trap, trap, trap, trap, trap, trap, trap .long trap, trap, trap, trap .long trap, trap, trap, trap /*.long inthandler, inthandler, inthandler, inthandler .long inthandler4, inthandler, inthandler, inthandler */ /* TRAP #0-15 */ .long system_call, trap, trap, trap, trap, trap, trap, trap .long trap, trap, trap, trap, trap, trap, trap, trap .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .text ignore: rte");#endif /* CONFIG_M68332 */void trap_init (void){ int i;#if defined( CONFIG_M68328 ) || defined( CONFIG_M68EZ328 )#if 0 /* Use ROM vectors as defaults. */ memcpy(_ramvec, _romvec, 1024); /* Set up our vector table */#endif _ramvec[2] = buserr; _ramvec[3] = trap3; _ramvec[4] = trap4; _ramvec[5] = trap5; _ramvec[6] = trap6; _ramvec[7] = trap7; _ramvec[8] = trap8; _ramvec[9] = trap9; _ramvec[10] = trap10; _ramvec[11] = trap11; _ramvec[12] = trap12; _ramvec[13] = trap13; _ramvec[14] = trap14; _ramvec[15] = trap15;#if 0 _ramvec[33] = trap33; _ramvec[34] = trap34; _ramvec[35] = trap35; _ramvec[36] = trap36; _ramvec[37] = trap37; _ramvec[38] = trap38; _ramvec[39] = trap39; _ramvec[40] = trap40; _ramvec[41] = trap41; _ramvec[42] = trap42; _ramvec[43] = trap43; _ramvec[44] = trap44; _ramvec[45] = trap45; _ramvec[46] = trap46; _ramvec[47] = trap47;#endif _ramvec[32] = system_call; _ramvec[64] = bad_interrupt; _ramvec[65] = inthandler1; _ramvec[66] = inthandler2; _ramvec[67] = inthandler3; _ramvec[68] = inthandler4; _ramvec[69] = inthandler5; _ramvec[70] = inthandler6; _ramvec[71] = inthandler7; IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */#endif /* CONFIG_M68328 || CONFIG_M68EZ328 */#ifdef CONFIG_M68332 /* we boot on ROM vectors. */ memcpy(_ramvec, _romvec, 1024); (*(volatile char*)0xfffa1f) = 0; __asm__( " movec %0, %/vbr" : : "a" (_ramvec)); /*for (i = 3; i < 16; i++) _ramvec[i] = trap; for (i = 33; i < 64; i++) _ramvec[i] = trap;*/ for (i = 0; i < 256; i++) _ramvec[i] = inthandler; _ramvec[32] = system_call;#endif }void set_evector(int vecnum, void (*handler)(void)){ if (vecnum >= 0 && vecnum <= 256) _ramvec[vecnum] = handler;}static inline void console_verbose(void){ extern int console_loglevel; console_loglevel = 15; if (mach_debug_init) mach_debug_init();}char *vec_names[] = { "RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR", "ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc", "PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111", "UNASSIGNED RESERVED 12", "COPROCESSOR PROTOCOL VIOLATION", "FORMAT ERROR", "UNINITIALIZED INTERRUPT", "UNASSIGNED RESERVED 16", "UNASSIGNED RESERVED 17", "UNASSIGNED RESERVED 18", "UNASSIGNED RESERVED 19", "UNASSIGNED RESERVED 20", "UNASSIGNED RESERVED 21", "UNASSIGNED RESERVED 22", "UNASSIGNED RESERVED 23", "SPURIOUS INTERRUPT", "LEVEL 1 INT", "LEVEL 2 INT", "LEVEL 3 INT", "LEVEL 4 INT", "LEVEL 5 INT", "LEVEL 6 INT", "LEVEL 7 INT", "SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3", "TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7", "TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11", "TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15" };/* FIXME: We need to look an alternate table for CPU with no sfc dfc */char *space_names[] = { "Space 0", "User Data", "User Program", "Space 3", "Space 4", "Super Data", "Super Program", "CPU" };extern void die_if_kernel(char *,struct pt_regs *,int);asmlinkage void trap_c(int vector, struct frame *fp);asmlinkage void buserr_c(struct frame *fp){ /* Only set esp0 if coming from user mode */ if (user_mode(&fp->ptregs)) current->tss.esp0 = (unsigned long) fp;#if DEBUG printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);#endif /* insert handler here */ force_sig(SIGSEGV, current);}int kstack_depth_to_print = 48;/* MODULE_RANGE is a guess of how much space is likely to be vmalloced. */#define MODULE_RANGE (8*1024*1024)void dump_stack(struct frame *fp){ unsigned long *stack, *endstack, addr/*, module_start, module_end*/; /*extern char _start, _etext;*/ int i; addr = (unsigned long)&fp->un; printk("Frame format=%X ", fp->ptregs.format); switch (fp->ptregs.format) { case 0x2: printk("instr addr=%08lx\n", fp->un.fmt2.iaddr); addr += sizeof(fp->un.fmt2); break; case 0x3: printk("eff addr=%08lx\n", fp->un.fmt3.effaddr); addr += sizeof(fp->un.fmt3); break; case 0x4: printk("fault addr=%08lx fslw=%08lx\n", fp->un.fmt4.effaddr, fp->un.fmt4.pc); addr += sizeof(fp->un.fmt4); break; case 0x7: printk("eff addr=%08lx ssw=%04x faddr=%08lx\n", fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr); printk("wb 1 stat/addr/data: %04x %08lx %08lx\n", fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0); printk("wb 2 stat/addr/data: %04x %08lx %08lx\n", fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d); printk("wb 3 stat/addr/data: %04x %08lx %08lx\n", fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d); printk("push data: %08lx %08lx %08lx %08lx\n", fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2, fp->un.fmt7.pd3); addr += sizeof(fp->un.fmt7); break; case 0x9: printk("instr addr=%08lx\n", fp->un.fmt9.iaddr); addr += sizeof(fp->un.fmt9); break; case 0xa: printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb, fp->un.fmta.daddr, fp->un.fmta.dobuf); addr += sizeof(fp->un.fmta); break; case 0xb: printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb, fp->un.fmtb.daddr, fp->un.fmtb.dobuf); printk("baddr=%08lx dibuf=%08lx ver=%x\n", fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver); addr += sizeof(fp->un.fmtb); break; case 0xc: printk("pc=%08lx itc=%04x faddr=%08lx dbuf=%08lx\n", fp->un.fmtc.pc, fp->un.fmtc.itc, fp->un.fmtc.faddr, fp->un.fmtc.dbuf); printk("code=%02x ssr=%08x\n", fp->un.fmtc.code, fp->un.fmtc.ssr); addr += sizeof(fp->un.fmtc); break; default: printk("\n"); } stack = (unsigned long *)addr; endstack = (unsigned long *)PAGE_ALIGN(addr); printk("Stack from %08lx:\n ", (unsigned long)stack); for (i = 0; i < kstack_depth_to_print; i++) { if (stack + 1 > endstack) break; if (i && ((i % 8) == 0)) printk("\n "); printk("%08lx ", *stack++); } printk ("\nCall Trace: "); stack = (unsigned long *) addr; i = 1;#if 0 module_start = VMALLOC_START; module_end = module_start + MODULE_RANGE; while (stack + 1 <= endstack) { addr = *stack++; /* * If the address is either in the text segment of the * kernel, or in the region which contains vmalloc'ed * memory, it *may* be the address of a calling * routine; if so, print it so that someone tracing * down the cause of the crash will be able to figure * out the call path that was taken. */ if (((addr >= (unsigned long) &_start) && (addr <= (unsigned long) &_etext)) || ((addr >= module_start) && (addr <= module_end))) { if (i && ((i % 8) == 0)) printk("\n "); printk("[<%08lx>] ", addr); i++; } }#endif printk("\nCode: "); for (i = 0; i < 10; i++) printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]); printk ("\n");}static int bad_super_trap_count = 0;void bad_super_trap (struct frame *fp){ if (bad_super_trap_count++) { /* *(volatile char *)0xdeadbeef = 'O'; *(volatile char *)0xdeadbeef = 'o'; *(volatile char *)0xdeadbeef = 'p'; *(volatile char *)0xdeadbeef = 's'; *(volatile char *)0xdeadbeef = '!';*/ *(volatile char *)0xFFFFF907 = 'O'; *(volatile char *)0xFFFFF907 = 'o'; *(volatile char *)0xFFFFF907 = 'p'; *(volatile char *)0xFFFFF907 = 's'; *(volatile char *)0xFFFFF907 = '!'; while(1); } printk ("Current process id is %d\n", current->pid); panic ("Trap from supervisor state");}asmlinkage void trap_c(int vector, struct frame *fp){ int sig; if ((fp->ptregs.sr & PS_S) && ((fp->ptregs.vector) >> 2) == VEC_TRACE && !(fp->ptregs.sr & PS_T)) { /* traced a trapping instruction */ unsigned char *lp = ((unsigned char *)&fp->un.fmt2) + 4; current->flags |= PF_DTRACE; /* clear the trace bit */ (*(unsigned short *)lp) &= ~PS_T; return; } else if (fp->ptregs.sr & PS_S) { bad_super_trap(fp); return; } /* send the appropriate signal to the user program */ switch (vector) { case VEC_ADDRERR: sig = SIGBUS; break; case VEC_BUSERR: sig = SIGSEGV; break; case VEC_ILLEGAL: case VEC_PRIV: case VEC_LINE10: case VEC_LINE11: case VEC_COPROC: case VEC_TRAP1: case VEC_TRAP2: case VEC_TRAP3: case VEC_TRAP4: case VEC_TRAP5: case VEC_TRAP6: case VEC_TRAP7: case VEC_TRAP8: case VEC_TRAP9: case VEC_TRAP10: case VEC_TRAP11: case VEC_TRAP12: case VEC_TRAP13: case VEC_TRAP14: sig = SIGILL; break;#ifndef NO_FPU case VEC_FPBRUC: case VEC_FPIR: case VEC_FPDIVZ: case VEC_FPUNDER: case VEC_FPOE: case VEC_FPOVER: case VEC_FPNAN: { unsigned char fstate[216]; __asm__ __volatile__ ("fsave %0@" : : "a" (fstate) : "memory"); /* Set the exception pending bit in the 68882 idle frame */ if (*(unsigned short *) fstate == 0x1f38) { fstate[fstate[1]] |= 1 << 3; __asm__ __volatile__ ("frestore %0@" : : "a" (fstate)); } } /* fall through */#endif case VEC_ZERODIV: case VEC_TRAP: sig = SIGFPE; break; case VEC_TRACE: /* ptrace single step */ fp->ptregs.sr &= ~PS_T; case VEC_TRAP15: /* breakpoint */ sig = SIGTRAP; break; default: sig = SIGILL; break; } send_sig (sig, current, 1);}asmlinkage void set_esp0 (unsigned long ssp){ current->tss.esp0 = ssp;}void die_if_kernel (char *str, struct pt_regs *fp, int nr){ if (!(fp->sr & PS_S)) return; console_verbose(); printk("%s: %08x\n",str,nr); printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", fp->d0, fp->d1, fp->d2, fp->d3); printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", fp->d4, fp->d5, fp->a0, fp->a1); if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page) printk("Corrupted stack page\n"); printk("Process %s (pid: %d, stackpage=%08lx)\n", current->comm, current->pid, current->kernel_stack_page); dump_stack((struct frame *)fp); do_exit(SIGSEGV);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -