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

📄 traps.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/arch/parisc/traps.c * *  Copyright (C) 1991, 1992  Linus Torvalds *  Copyright (C) 1999, 2000  Philipp Rumpf <prumpf@tux.org> *//* * 'Traps.c' handles hardware traps and faults after we have saved some * state in 'asm.s'. */#include <linux/config.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/ptrace.h>#include <linux/timer.h>#include <linux/mm.h>#include <linux/smp.h>#include <linux/smp_lock.h>#include <linux/spinlock.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/console.h>#include <asm/system.h>#include <asm/uaccess.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/traps.h>#include <asm/unaligned.h>#include <asm/atomic.h>#include <asm/smp.h>#include <asm/pdc.h>#include "../math-emu/math-emu.h"	/* for handle_fpe() */#ifdef CONFIG_KWDB#include <kdb/break.h>		/* for BI2_KGDB_GDB */#include <kdb/kgdb_types.h>	/* for __() */#include <kdb/save_state.h>	/* for struct save_state */#include <kdb/kgdb_machine.h>	/* for pt_regs_to_ssp and ssp_to_pt_regs */#include <kdb/trap.h>		/* for I_BRK_INST */#endif /* CONFIG_KWDB */#define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */			  /*  dumped to the console via printk)          */static int printbinary(char *buf, unsigned long x, int nbits){	unsigned long mask = 1UL << (nbits - 1);	while (mask != 0) {		*buf++ = (mask & x ? '1' : '0');		mask >>= 1;	}	*buf = '\0';	return nbits;}#ifdef __LP64__#define RFMT "%016lx"#else#define RFMT "%08lx"#endifvoid show_regs(struct pt_regs *regs){	int i;	char buf[128], *p;	char *level;	unsigned long cr30;	unsigned long cr31;	level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT;	printk("%s\n", level); /* don't want to have that pretty register dump messed up */	printk("%s     YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level);	printbinary(buf, regs->gr[0], 32);	printk("%sPSW: %s %s\n", level, buf, print_tainted());	for (i = 0; i < 32; i += 4) {		int j;		p = buf;		p += sprintf(p, "%sr%02d-%02d ", level, i, i + 3);		for (j = 0; j < 4; j++) {			p += sprintf(p, " " RFMT, (i+j) == 0 ? 0 : regs->gr[i + j]);		}		printk("%s\n", buf);	}	for (i = 0; i < 8; i += 4) {		int j;		p = buf;		p += sprintf(p, "%ssr%d-%d  ", level, i, i + 3);		for (j = 0; j < 4; j++) {			p += sprintf(p, " " RFMT, regs->sr[i + j]);		}		printk("%s\n", buf);	}#if RIDICULOUSLY_VERBOSE	for (i = 0; i < 32; i += 2)		printk("%sFR%02d : %016lx  FR%2d : %016lx", level, i,				regs->fr[i], i+1, regs->fr[i+1]);#endif	cr30 = mfctl(30);	cr31 = mfctl(31);	printk("%s\n", level);	printk("%sIASQ: " RFMT " " RFMT " IAOQ: " RFMT " " RFMT "\n",	       level, regs->iasq[0], regs->iasq[1], regs->iaoq[0], regs->iaoq[1]);	printk("%s IIR: %08lx    ISR: " RFMT "  IOR: " RFMT "\n",	       level, regs->iir, regs->isr, regs->ior);	printk("%s CPU: %8d   CR30: " RFMT " CR31: " RFMT "\n",	       level, ((struct task_struct *)cr30)->processor, cr30, cr31);	printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);}static void dump_stack(unsigned long from, unsigned long to, int istackflag){	unsigned int *fromptr;	unsigned int *toptr;	fromptr = (unsigned int *)from;	toptr = (unsigned int *)to;	printk("\n");	printk(KERN_CRIT "Dumping %sStack from 0x%p to 0x%p:\n",			istackflag ? "Interrupt " : "",			fromptr, toptr);	while (fromptr < toptr) {		printk(KERN_CRIT "%04lx %08x %08x %08x %08x %08x %08x %08x %08x\n",		    ((unsigned long)fromptr) & 0xffff,		    fromptr[0], fromptr[1], fromptr[2], fromptr[3],		    fromptr[4], fromptr[5], fromptr[6], fromptr[7]);		fromptr += 8;	}}void show_stack(struct pt_regs *regs){#if 1	/* If regs->sr[7] == 0, we are on a kernel stack */	if (regs->sr[7] == 0) {		unsigned long sp = regs->gr[30];		unsigned long cr30;		unsigned long cr31;		unsigned long stack_start;		struct pt_regs *int_regs;		cr30 = mfctl(30);		cr31 = mfctl(31);		stack_start = sp & ~(ISTACK_SIZE - 1);		if (stack_start == cr31) {		    /*		     * We are on the interrupt stack, get the stack		     * pointer from the first pt_regs structure on		     * the interrupt stack, so we can dump the task		     * stack first.		     */		    int_regs = (struct pt_regs *)cr31;		    sp = int_regs->gr[30];		    stack_start = sp & ~(INIT_TASK_SIZE - 1);		    if (stack_start != cr30) {			printk(KERN_CRIT "WARNING! Interrupt-Stack pointer and cr30 do not correspond!\n");			printk(KERN_CRIT "Dumping virtual address stack instead\n");			dump_stack((unsigned long)__va(stack_start), (unsigned long)__va(sp), 0);		    } else {			dump_stack(stack_start, sp, 0);		    };		    printk("\n\n" KERN_DEBUG "Registers at Interrupt:\n");		    show_regs(int_regs);		    /* Now dump the interrupt stack */		    sp = regs->gr[30];		    stack_start = sp & ~(ISTACK_SIZE - 1);		    dump_stack(stack_start,sp,1);		}		else		{		    /* Stack Dump! */		    printk(KERN_CRIT "WARNING! Stack pointer and cr30 do not correspond!\n");		    printk(KERN_CRIT "Dumping virtual address stack instead\n");		    dump_stack((unsigned long)__va(stack_start), (unsigned long)__va(sp), 0);		}	}#endif}void die_if_kernel(char *str, struct pt_regs *regs, long err){	if (user_mode(regs)) {#ifdef PRINT_USER_FAULTS		if (err == 0)			return; /* STFU */		/* XXX for debugging only */		printk(KERN_DEBUG "%s (pid %d): %s (code %ld)\n",			current->comm, current->pid, str, err);		show_regs(regs);#endif		return;	}		/* unlock the pdc lock if necessary */	pdc_emergency_unlock();	/* maybe the kernel hasn't booted very far yet and hasn't been able 	 * to initialize the serial or STI console. In that case we should 	 * re-enable the pdc console, so that the user will be able to 	 * identify the problem. */	if (!console_drivers)		pdc_console_restart();		printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",		current->comm, current->pid, str, err);	show_regs(regs);	/* Wot's wrong wif bein' racy? */	if (current->thread.flags & PARISC_KERNEL_DEATH) {		printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__);		sti();		while (1);	}	current->thread.flags |= PARISC_KERNEL_DEATH;	do_exit(SIGSEGV);}int syscall_ipi(int (*syscall) (struct pt_regs *), struct pt_regs *regs){	return syscall(regs);}/* gdb uses break 4,8 */#define GDB_BREAK_INSN 0x10004void handle_gdb_break(struct pt_regs *regs, int wot){	struct siginfo si;	si.si_code = wot;	si.si_addr = (void *) (regs->iaoq[0] & ~3);	si.si_signo = SIGTRAP;	si.si_errno = 0;	force_sig_info(SIGTRAP, &si, current);}void handle_break(unsigned iir, struct pt_regs *regs){	struct siginfo si;#ifdef CONFIG_KWDB	struct save_state ssp;#endif /* CONFIG_KWDB */   	switch(iir) {	case 0x00:#ifdef PRINT_USER_FAULTS		printk(KERN_DEBUG "break 0,0: pid=%d command='%s'\n",		       current->pid, current->comm);#endif		die_if_kernel("Breakpoint", regs, 0);#ifdef PRINT_USER_FAULTS		show_regs(regs);#endif		si.si_code = TRAP_BRKPT;		si.si_addr = (void *) (regs->iaoq[0] & ~3);		si.si_signo = SIGTRAP;		force_sig_info(SIGTRAP, &si, current);		break;	case GDB_BREAK_INSN:		die_if_kernel("Breakpoint", regs, 0);		handle_gdb_break(regs, TRAP_BRKPT);		break;#ifdef CONFIG_KWDB	case KGDB_BREAK_INSN:		mtctl(0, 15);		pt_regs_to_ssp(regs, &ssp);		kgdb_trap(I_BRK_INST, &ssp, 1);		ssp_to_pt_regs(&ssp, regs);		break;	case KGDB_INIT_BREAK_INSN:		mtctl(0, 15);		pt_regs_to_ssp(regs, &ssp);		kgdb_trap(I_BRK_INST, &ssp, 1);		ssp_to_pt_regs(&ssp, regs);		/* Advance pcoq to skip break */		regs->iaoq[0] = regs->iaoq[1];		regs->iaoq[1] += 4;		break;#endif /* CONFIG_KWDB */	default:#ifdef PRINT_USER_FAULTS		printk(KERN_DEBUG "break %#08x: pid=%d command='%s'\n",		       iir, current->pid, current->comm);		show_regs(regs);#endif		si.si_signo = SIGTRAP;		si.si_code = TRAP_BRKPT;		si.si_addr = (void *) (regs->iaoq[0] & ~3);		force_sig_info(SIGTRAP, &si, current);		return;	}}int handle_toc(void){	printk(KERN_CRIT "TOC call.\n");	return 0;}static void default_trap(int code, struct pt_regs *regs){	printk(KERN_ERR "Trap %d on CPU %d\n", code, smp_processor_id());	show_regs(regs);}void (*cpu_lpmc) (int code, struct pt_regs *regs) = default_trap;#ifdef CONFIG_KWDBint debug_call (void){    printk (KERN_DEBUG "Debug call.\n");    return 0;}int debug_call_leaf (void){    return 0;}#endif /* CONFIG_KWDB */void transfer_pim_to_trap_frame(struct pt_regs *regs){    register int i;    extern unsigned int hpmc_pim_data[];    struct pdc_hpmc_pim_11 *pim_narrow;    struct pdc_hpmc_pim_20 *pim_wide;    if (boot_cpu_data.cpu_type >= pcxu) {	pim_wide = (struct pdc_hpmc_pim_20 *)hpmc_pim_data;	/*	 * Note: The following code will probably generate a	 * bunch of truncation error warnings from the compiler.	 * Could be handled with an ifdef, but perhaps there	 * is a better way.	 */	regs->gr[0] = pim_wide->cr[22];	for (i = 1; i < 32; i++)	    regs->gr[i] = pim_wide->gr[i];	for (i = 0; i < 32; i++)	    regs->fr[i] = pim_wide->fr[i];	for (i = 0; i < 8; i++)	    regs->sr[i] = pim_wide->sr[i];	regs->iasq[0] = pim_wide->cr[17];	regs->iasq[1] = pim_wide->iasq_back;	regs->iaoq[0] = pim_wide->cr[18];	regs->iaoq[1] = pim_wide->iaoq_back;	regs->sar  = pim_wide->cr[11];	regs->iir  = pim_wide->cr[19];	regs->isr  = pim_wide->cr[20];	regs->ior  = pim_wide->cr[21];    }    else {	pim_narrow = (struct pdc_hpmc_pim_11 *)hpmc_pim_data;	regs->gr[0] = pim_narrow->cr[22];

⌨️ 快捷键说明

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