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

📄 traps.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This routine handles various exception codes.  It determines the address, * and the problem, and then passes it off to one of the appropriate * routines. */void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset){	static spinlock_t terminate_lock = SPIN_LOCK_UNLOCKED;	set_eiem(0);	__cli();	spin_lock(&terminate_lock);	/* unlock the pdc lock if necessary */	pdc_emergency_unlock();	/* restart pdc console if necessary */	if (!console_drivers)		pdc_console_restart();	/* Not all switch paths will gutter the processor... */	switch(code){	case 1:		transfer_pim_to_trap_frame(regs);		break;	    	default:		/* Fall through */		break;	}	show_stack((unsigned long *)regs->gr[30]);	printk("\n");	printk(KERN_CRIT "%s: Code=%d regs=%p (Addr=" RFMT ")\n",			msg, code, regs, offset);	show_regs(regs);	spin_unlock(&terminate_lock);	/* put soft power button back under hardware control;	 * if the user had pressed it once at any time, the 	 * system will shut down immediately right here. */	pdc_soft_power_button(0);		/* Gutter the processor... */	for(;;)	    ;}void handle_interruption(int code, struct pt_regs *regs){	unsigned long fault_address = 0;	unsigned long fault_space = 0;	struct siginfo si;	/* HACK! jsm is going to fix this.	 * entry.S will manage I-bit - only enable I-bit if it was	 * enabled before we took the "trap".	 */	if (code != 1)		local_irq_enable();	switch(code) {	case  1:		/* High-priority machine check (HPMC) */		pdc_console_restart();  /* switch back to pdc if HPMC */		/* set up a new led state on systems shipped with a LED State panel */		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC);		parisc_terminate("High Priority Machine Check (HPMC)",				regs, code, 0);		/* NOT REACHED */			case  2:		/* Power failure interrupt */		printk(KERN_CRIT "Power failure interrupt !\n");		return;	case  3:		/* Recovery counter trap */		regs->gr[0] &= ~PSW_R;		if (regs->iasq[0])			handle_gdb_break(regs, TRAP_TRACE);		/* else this must be the start of a syscall - just let it run */		return;	case  5:		/* Low-priority machine check */		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC);		flush_all_caches();		cpu_lpmc(5, regs);		return;	case  6:		/* Instruction TLB miss fault/Instruction page fault */		fault_address = regs->iaoq[0];		fault_space   = regs->iasq[0];		break;	case  8:		/* Illegal instruction trap */		die_if_kernel("Illegal instruction", regs, code);		si.si_code = ILL_ILLOPC;		goto give_sigill;	case  9:		/* Break instruction trap */		handle_break(regs->iir,regs);		return;		case 10:		/* Privileged operation trap */		die_if_kernel("Privileged operation", regs, code);		si.si_code = ILL_PRVOPC;		goto give_sigill;		case 11:		/* Privileged register trap */		if ((regs->iir & 0xffdfffe0) == 0x034008a0) {			/* This is a MFCTL cr26/cr27 to gr instruction.			 * PCXS traps on this, so we need to emulate it.			 */			if (regs->iir & 0x00200000)				regs->gr[regs->iir & 0x1f] = mfctl(27);			else				regs->gr[regs->iir & 0x1f] = mfctl(26);			regs->iaoq[0] = regs->iaoq[1];			regs->iaoq[1] += 4;			regs->iasq[0] = regs->iasq[1];			return;		}		die_if_kernel("Privileged register usage", regs, code);		si.si_code = ILL_PRVREG;		/* Fall thru */	give_sigill:		si.si_signo = SIGILL;		si.si_errno = 0;		si.si_addr = (void *) regs->iaoq[0];		force_sig_info(SIGILL, &si, current);		return;	case 12:		/* Overflow Trap, let the userland signal handler do the cleanup */		si.si_signo = SIGFPE;		si.si_code = FPE_INTOVF;		si.si_addr = (void *) regs->iaoq[0];		force_sig_info(SIGFPE, &si, current);		return;		case 13:		/* Conditional Trap 		   The condition succees in an instruction which traps on condition  */		si.si_signo = SIGFPE;		/* Set to zero, and let the userspace app figure it out from		   the insn pointed to by si_addr */		si.si_code = 0;		si.si_addr = (void *) regs->iaoq[0];		force_sig_info(SIGFPE, &si, current);		return;	case 14:		/* Assist Exception Trap, i.e. floating point exception. */		die_if_kernel("Floating point exception", regs, 0); /* quiet */		handle_fpe(regs);		return;	case 15: 		/* Data TLB miss fault/Data page fault */			/* Fall thru */	case 16:		/* Non-access instruction TLB miss fault */		/* The instruction TLB entry needed for the target address of the FIC		   is absent, and hardware can't find it, so we get to cleanup */		/* Fall thru */	case 17:		/* Non-access data TLB miss fault/Non-access data page fault */		/* TODO: Still need to add slow path emulation code here */		/* TODO: Understand what is meant by the TODO listed 		   above this one. (Carlos) */		fault_address = regs->ior;		fault_space = regs->isr;		break;	case 18:		/* PCXS only -- later cpu's split this into types 26,27 & 28 */		/* Check for unaligned access */		if (check_unaligned(regs)) {			handle_unaligned(regs);			return;		}		/* Fall Through */	case 26: 		/* PCXL: Data memory access rights trap */		fault_address = regs->ior;		fault_space   = regs->isr;		break;	case 19:		/* Data memory break trap */		regs->gr[0] |= PSW_X; /* So we can single-step over the trap */		/* fall thru */	case 21:		/* Page reference trap */		handle_gdb_break(regs, TRAP_HWBKPT);		return;	case 25:		/* Taken branch trap */		regs->gr[0] &= ~PSW_T;		if (regs->iasq[0])			handle_gdb_break(regs, TRAP_BRANCH);		/* else this must be the start of a syscall - just let it		 * run.		 */		return;	case  7:  		/* Instruction access rights */		/* PCXL: Instruction memory protection trap */		/*		 * This could be caused by either: 1) a process attempting		 * to execute within a vma that does not have execute		 * permission, or 2) an access rights violation caused by a		 * flush only translation set up by ptep_get_and_clear().		 * So we check the vma permissions to differentiate the two.		 * If the vma indicates we have execute permission, then		 * the cause is the latter one. In this case, we need to		 * call do_page_fault() to fix the problem.		 */		if (user_mode(regs)) {			struct vm_area_struct *vma;			down_read(&current->mm->mmap_sem);			vma = find_vma(current->mm,regs->iaoq[0]);			if (vma && (regs->iaoq[0] >= vma->vm_start)				&& (vma->vm_flags & VM_EXEC)) {				fault_address = regs->iaoq[0];				fault_space = regs->iasq[0];				up_read(&current->mm->mmap_sem);				break; /* call do_page_fault() */			}			up_read(&current->mm->mmap_sem);		}		/* Fall Through */	case 27: 		/* Data memory protection ID trap */		die_if_kernel("Protection id trap", regs, code);		si.si_code = SEGV_MAPERR;		si.si_signo = SIGSEGV;		si.si_errno = 0;		if (code == 7)		    si.si_addr = (void *) regs->iaoq[0];		else		    si.si_addr = (void *) regs->ior;		force_sig_info(SIGSEGV, &si, current);		return;	case 28: 		/* Unaligned data reference trap */		handle_unaligned(regs);		return;	default:		if (user_mode(regs)) {#ifdef PRINT_USER_FAULTS			printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n",			    current->pid, current->comm);			show_regs(regs);#endif			/* SIGBUS, for lack of a better one. */			si.si_signo = SIGBUS;			si.si_code = BUS_OBJERR;			si.si_errno = 0;			si.si_addr = (void *) regs->ior;			force_sig_info(SIGBUS, &si, current);			return;		}				pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);		parisc_terminate("Unexpected interruption", regs, code, 0);		/* NOT REACHED */	}	if (user_mode(regs)) {	    if (fault_space != regs->sr[7]) {#ifdef PRINT_USER_FAULTS		if (fault_space == 0)			printk(KERN_DEBUG "User Fault on Kernel Space ");		else			printk(KERN_DEBUG "User Fault (long pointer) ");		printk("pid=%d command='%s'\n", current->pid, current->comm);		show_regs(regs);#endif		si.si_signo = SIGSEGV;		si.si_errno = 0;		si.si_code = SEGV_MAPERR;		si.si_addr = (void *) regs->ior;		force_sig_info(SIGSEGV, &si, current);		return;	    }	}	else {	    /*	     * The kernel should never fault on its own address space.	     */	    if (fault_space == 0) {		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);		parisc_terminate("Kernel Fault", regs, code, fault_address);		/** NOT REACHED **/	    }	}	do_page_fault(regs, code, fault_address);}int __init check_ivt(void *iva){	int i;	u32 check = 0;	u32 *ivap;	u32 *hpmcp;	u32 length;	extern void os_hpmc(void);	extern void os_hpmc_end(void);	if (strcmp((char *)iva, "cows can fly"))		return -1;	ivap = (u32 *)iva;	for (i = 0; i < 8; i++)	    *ivap++ = 0;	/* Compute Checksum for HPMC handler */	length = (u32)((unsigned long)os_hpmc_end - (unsigned long)os_hpmc);	ivap[7] = length;	hpmcp = (u32 *)os_hpmc;	for (i=0; i<length/4; i++)	    check += *hpmcp++;	for (i=0; i<8; i++)	    check += ivap[i];	ivap[5] = -check;	return 0;}	#ifndef __LP64__extern const void fault_vector_11;#endifextern const void fault_vector_20;void __init trap_init(void){	void *iva;	if (boot_cpu_data.cpu_type >= pcxu)		iva = (void *) &fault_vector_20;	else#ifdef __LP64__		panic("Can't boot 64-bit OS on PA1.1 processor!");#else		iva = (void *) &fault_vector_11;#endif	if (check_ivt(iva))		panic("IVT invalid");}

⌨️ 快捷键说明

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