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

📄 traps.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (i = 1; i < 32; i++)	    regs->gr[i] = pim_narrow->gr[i];	for (i = 0; i < 32; i++)	    regs->fr[i] = pim_narrow->fr[i];	for (i = 0; i < 8; i++)	    regs->sr[i] = pim_narrow->sr[i];	regs->iasq[0] = pim_narrow->cr[17];	regs->iasq[1] = pim_narrow->iasq_back;	regs->iaoq[0] = pim_narrow->cr[18];	regs->iaoq[1] = pim_narrow->iaoq_back;	regs->sar  = pim_narrow->cr[11];	regs->iir  = pim_narrow->cr[19];	regs->isr  = pim_narrow->cr[20];	regs->ior  = pim_narrow->cr[21];    }    /*     * The following fields only have meaning if we came through     * another path. So just zero them here.     */    regs->ksp = 0;    regs->kpc = 0;    regs->orig_r28 = 0;}/* * This routine handles page faults.  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();	if (code == 1)	    transfer_pim_to_trap_frame(regs);	show_stack(regs);	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);		for(;;)	    ;}void handle_interruption(int code, struct pt_regs *regs){	unsigned long fault_address = 0;	unsigned long fault_space = 0;	struct siginfo si;#ifdef CONFIG_KWDB	struct save_state ssp;#endif /* CONFIG_KWDB */   	if (code == 1)	    pdc_console_restart();  /* switch back to pdc if HPMC */	else	    sti();#if 0	printk(KERN_CRIT "Interruption # %d\n", code);#endif	switch(code) {	case  1:		/* High-priority machine check (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 */		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;	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 14:		/* Assist Exception Trap, i.e. floating point exception. */		die_if_kernel("Floating point exception", regs, 0); /* quiet */		handle_fpe(regs);		return;	case 17:		/* Non-access data TLB miss fault/Non-access data page fault */		/* TODO: Still need to add slow path emulation code here */		fault_address = regs->ior;		parisc_terminate("Non access data tlb fault!",regs,code,fault_address);	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 15: /* Data TLB miss fault/Data page fault */	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 */#ifndef CONFIG_KWDB		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;#else		/* Kernel debugger: */		mtctl(0, 15);		pt_regs_to_ssp(regs, &ssp);		kgdb_trap(I_TAKEN_BR, &ssp, 1);		ssp_to_pt_regs(&ssp, regs);		break;#endif /* CONFIG_KWDB */	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;		}		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)		    parisc_terminate("Kernel Fault", regs, code, fault_address);	}#ifdef CONFIG_KWDB	debug_call_leaf ();#endif /* CONFIG_KWDB */	do_page_fault(regs, code, fault_address);}void show_trace_task(struct task_struct *tsk){    	BUG();}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 + -