⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 traps.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 4 页
字号:
				if (fixup != 0UL && recoverable) {					regs->tpc = fixup;					regs->tnpc = regs->tpc + 4;					regs->u_regs[UREG_G2] = g2;				}			}		}	} else {		recoverable = 0;	}	if (!recoverable)		panic("Irrecoverable deferred error trap.\n");}/* Handle a D/I cache parity error trap.  TYPE is encoded as: * * Bit0:	0=dcache,1=icache * Bit1:	0=recoverable,1=unrecoverable * * The hardware has disabled both the I-cache and D-cache in * the %dcr register.   */void cheetah_plus_parity_error(int type, struct pt_regs *regs){	if (type & 0x1)		__cheetah_flush_icache();	else		cheetah_plus_zap_dcache_parity();	cheetah_flush_dcache();	/* Re-enable I-cache/D-cache */	__asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t"			     "or %%g1, %1, %%g1\n\t"			     "stxa %%g1, [%%g0] %0\n\t"			     "membar #Sync"			     : /* no outputs */			     : "i" (ASI_DCU_CONTROL_REG),			       "i" (DCU_DC | DCU_IC)			     : "g1");	if (type & 0x2) {		printk(KERN_EMERG "CPU[%d]: Cheetah+ %c-cache parity error at TPC[%016lx]\n",		       smp_processor_id(),		       (type & 0x1) ? 'I' : 'D',		       regs->tpc);		panic("Irrecoverable Cheetah+ parity error.");	}	printk(KERN_WARNING "CPU[%d]: Cheetah+ %c-cache parity error at TPC[%016lx]\n",	       smp_processor_id(),	       (type & 0x1) ? 'I' : 'D',	       regs->tpc);}void do_fpe_common(struct pt_regs *regs){	if(regs->tstate & TSTATE_PRIV) {		regs->tpc = regs->tnpc;		regs->tnpc += 4;	} else {		unsigned long fsr = current->thread.xfsr[0];		siginfo_t info;		if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {			regs->tpc &= 0xffffffff;			regs->tnpc &= 0xffffffff;		}		info.si_signo = SIGFPE;		info.si_errno = 0;		info.si_addr = (void *)regs->tpc;		info.si_trapno = 0;		info.si_code = __SI_FAULT;		if ((fsr & 0x1c000) == (1 << 14)) {			if (fsr & 0x10)				info.si_code = FPE_FLTINV;			else if (fsr & 0x08)				info.si_code = FPE_FLTOVF;			else if (fsr & 0x04)				info.si_code = FPE_FLTUND;			else if (fsr & 0x02)				info.si_code = FPE_FLTDIV;			else if (fsr & 0x01)				info.si_code = FPE_FLTRES;		}		force_sig_info(SIGFPE, &info, current);	}}void do_fpieee(struct pt_regs *regs){	do_fpe_common(regs);}extern int do_mathemu(struct pt_regs *, struct fpustate *);void do_fpother(struct pt_regs *regs){	struct fpustate *f = FPUSTATE;	int ret = 0;	switch ((current->thread.xfsr[0] & 0x1c000)) {	case (2 << 14): /* unfinished_FPop */	case (3 << 14): /* unimplemented_FPop */		ret = do_mathemu(regs, f);		break;	}	if (ret)		return;	do_fpe_common(regs);}void do_tof(struct pt_regs *regs){	siginfo_t info;	if(regs->tstate & TSTATE_PRIV)		die_if_kernel("Penguin overflow trap from kernel mode", regs);	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {		regs->tpc &= 0xffffffff;		regs->tnpc &= 0xffffffff;	}	info.si_signo = SIGEMT;	info.si_errno = 0;	info.si_code = EMT_TAGOVF;	info.si_addr = (void *)regs->tpc;	info.si_trapno = 0;	force_sig_info(SIGEMT, &info, current);}void do_div0(struct pt_regs *regs){	siginfo_t info;	if (regs->tstate & TSTATE_PRIV)		die_if_kernel("TL0: Kernel divide by zero.", regs);	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {		regs->tpc &= 0xffffffff;		regs->tnpc &= 0xffffffff;	}	info.si_signo = SIGFPE;	info.si_errno = 0;	info.si_code = FPE_INTDIV;	info.si_addr = (void *)regs->tpc;	info.si_trapno = 0;	force_sig_info(SIGFPE, &info, current);}void instruction_dump (unsigned int *pc){	int i;	if((((unsigned long) pc) & 3))		return;	printk("Instruction DUMP:");	for(i = -3; i < 6; i++)		printk("%c%08x%c",i?' ':'<',pc[i],i?' ':'>');	printk("\n");}void user_instruction_dump (unsigned int *pc){	int i;	unsigned int buf[9];		if((((unsigned long) pc) & 3))		return;			if(copy_from_user(buf, pc - 3, sizeof(buf)))		return;	printk("Instruction DUMP:");	for(i = 0; i < 9; i++)		printk("%c%08x%c",i==3?' ':'<',buf[i],i==3?' ':'>');	printk("\n");}void show_trace_raw(struct task_struct *tsk, unsigned long ksp){	unsigned long pc, fp;	unsigned long task_base = (unsigned long)tsk;	struct reg_window *rw;	int count = 0;	fp = ksp + STACK_BIAS;	do {		/* Bogus frame pointer? */		if (fp < (task_base + sizeof(struct task_struct)) ||		    fp >= (task_base + THREAD_SIZE))			break;		rw = (struct reg_window *)fp;		pc = rw->ins[7];		printk("[%016lx] ", pc);		fp = rw->ins[6] + STACK_BIAS;	} while (++count < 16);	printk("\n");}void show_trace_task(struct task_struct *tsk){	if (tsk)		show_trace_raw(tsk, tsk->thread.ksp);}void die_if_kernel(char *str, struct pt_regs *regs){	extern void __show_regs(struct pt_regs * regs);	extern void smp_report_regs(void);	int count = 0;	struct reg_window *lastrw;		/* Amuse the user. */	printk("              \\|/ ____ \\|/\n""              \"@'/ .. \\`@\"\n""              /_| \\__/ |_\\\n""                 \\__U_/\n");	printk("%s(%d): %s\n", current->comm, current->pid, str);	__asm__ __volatile__("flushw");	__show_regs(regs);	if(regs->tstate & TSTATE_PRIV) {		struct reg_window *rw = (struct reg_window *)			(regs->u_regs[UREG_FP] + STACK_BIAS);		/* Stop the back trace when we hit userland or we		 * find some badly aligned kernel stack.		 */		lastrw = (struct reg_window *)current;		while(rw					&&		      count++ < 30				&&		      rw >= lastrw				&&		      (char *) rw < ((char *) current)		        + sizeof (union task_union) 		&&		      !(((unsigned long) rw) & 0x7)) {			printk("Caller[%016lx]\n", rw->ins[7]);			lastrw = rw;			rw = (struct reg_window *)				(rw->ins[6] + STACK_BIAS);		}		instruction_dump ((unsigned int *) regs->tpc);	} else {		if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {			regs->tpc &= 0xffffffff;			regs->tnpc &= 0xffffffff;		}		user_instruction_dump ((unsigned int *) regs->tpc);	}#ifdef CONFIG_SMP	smp_report_regs();#endif                                                		if(regs->tstate & TSTATE_PRIV)		do_exit(SIGKILL);	do_exit(SIGSEGV);}extern int handle_popc(u32 insn, struct pt_regs *regs);extern int handle_ldf_stq(u32 insn, struct pt_regs *regs);void do_illegal_instruction(struct pt_regs *regs){	unsigned long pc = regs->tpc;	unsigned long tstate = regs->tstate;	u32 insn;	siginfo_t info;	if(tstate & TSTATE_PRIV)		die_if_kernel("Kernel illegal instruction", regs);	if(current->thread.flags & SPARC_FLAG_32BIT)		pc = (u32)pc;	if (get_user(insn, (u32 *)pc) != -EFAULT) {		if ((insn & 0xc1ffc000) == 0x81700000) /* POPC */ {			if (handle_popc(insn, regs))				return;		} else if ((insn & 0xc1580000) == 0xc1100000) /* LDQ/STQ */ {			if (handle_ldf_stq(insn, regs))				return;		}	}	info.si_signo = SIGILL;	info.si_errno = 0;	info.si_code = ILL_ILLOPC;	info.si_addr = (void *)pc;	info.si_trapno = 0;	force_sig_info(SIGILL, &info, current);}void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr){	siginfo_t info;	if(regs->tstate & TSTATE_PRIV) {		extern void kernel_unaligned_trap(struct pt_regs *regs,						  unsigned int insn, 						  unsigned long sfar, unsigned long sfsr);		return kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc), sfar, sfsr);	}	info.si_signo = SIGBUS;	info.si_errno = 0;	info.si_code = BUS_ADRALN;	info.si_addr = (void *)sfar;	info.si_trapno = 0;	force_sig_info(SIGBUS, &info, current);}void do_privop(struct pt_regs *regs){	siginfo_t info;	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {		regs->tpc &= 0xffffffff;		regs->tnpc &= 0xffffffff;	}	info.si_signo = SIGILL;	info.si_errno = 0;	info.si_code = ILL_PRVOPC;	info.si_addr = (void *)regs->tpc;	info.si_trapno = 0;	force_sig_info(SIGILL, &info, current);}void do_privact(struct pt_regs *regs){	do_privop(regs);}/* Trap level 1 stuff or other traps we should never see... */void do_cee(struct pt_regs *regs){	die_if_kernel("TL0: Cache Error Exception", regs);}void do_cee_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Cache Error Exception", regs);}void do_dae_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Data Access Exception", regs);}void do_iae_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Instruction Access Exception", regs);}void do_div0_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: DIV0 Exception", regs);}void do_fpdis_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: FPU Disabled", regs);}void do_fpieee_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: FPU IEEE Exception", regs);}void do_fpother_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: FPU Other Exception", regs);}void do_ill_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Illegal Instruction Exception", regs);}void do_irq_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: IRQ Exception", regs);}void do_lddfmna_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: LDDF Exception", regs);}void do_stdfmna_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: STDF Exception", regs);}void do_paw(struct pt_regs *regs){	die_if_kernel("TL0: Phys Watchpoint Exception", regs);}void do_paw_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Phys Watchpoint Exception", regs);}void do_vaw(struct pt_regs *regs){	die_if_kernel("TL0: Virt Watchpoint Exception", regs);}void do_vaw_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Virt Watchpoint Exception", regs);}void do_tof_tl1(struct pt_regs *regs){	dump_tl1_traplog((struct tl1_traplog *)(regs + 1));	die_if_kernel("TL1: Tag Overflow Exception", regs);}void do_getpsr(struct pt_regs *regs){	regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate);	regs->tpc   = regs->tnpc;	regs->tnpc += 4;	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {		regs->tpc &= 0xffffffff;		regs->tnpc &= 0xffffffff;	}}void trap_init(void){	/* Attach to the address space of init_task. */	atomic_inc(&init_mm.mm_count);	current->active_mm = &init_mm;	/* NOTE: Other cpus have this done as they are started	 *       up on SMP.	 */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -