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

📄 exception.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
字号:
/*	$Id: exception.c,v 1.11 2003/08/10 11:15:26 pefo Exp $ *//* * Copyright (c) 2000-2002 Opsycon AB * Copyright (c) 2002 Patrik Lindergren (www.lindergren.com) *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by Opsycon AB. *	This product includes software developed by Patrik Lindergren. * 4. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#include <stdio.h>#include <termio.h>#include <string.h>#include <setjmp.h>#include <stdlib.h>#include <signal.h>#include <machine/cpu.h>#include <machine/frame.h>#ifdef _KERNEL#undef _KERNEL#include <sys/ioctl.h>#define _KERNEL#else#include <sys/ioctl.h>#endif#include <pmon.h>#include <debugger.h>#include "mod_debugger.h"extern void _go __P((void));extern char *sbddbgintr(unsigned int);extern char _pmon_snap_trap;/* *  For each CPU this table have a pointer to its cpuinfo area. */struct trapframe *cpuinfotab[8];#if NMOD_DEBUGGER > 0/* *  exception() *      An exception has been generated. Need to sort out from where. *      frame is a pointer to cpu data saved on the PMON2000 stack. */voidexception(frame)	struct trapframe *frame;{	int exc_type;	int i, flag;	char *p = 0;	struct trapframe *cpuinfo;	/*	 *  Check if exception is handled by special handler.	 */	if (md_check_exception_handler(frame)) {		return;	}#if defined(SMP)	cpuinfo = cpuinfotab[tgt_smpwhoami()];	*cpuinfo = *frame;		/* Save the frame */	if (md_getpc(frame) == &_pmon_snap_trap) {		/* XXX Instruction size */		md_setpc(cpuinfo, (register_t)&_pmon_snap_trap+4);		_go();	}	if (tgt_smpwhoami() != 0) {//		printf("PMON: CPU %d idling\n", tgt_smpwhoami() + 1);		tgt_smpidle();//		printf("PMON: CPU %d running\n", tgt_smpwhoami() + 1);		_go();	}#else	cpuinfo = cpuinfotab[0];	*cpuinfo = *frame;		/* Save the frame */#endif	if (md_check_exception_handler(cpuinfo)) {		_go();	}	exc_type = md_exc_type(frame);#if 0    if (exc_type == EXC_INT && (p = sbddbgintr (Cause & Status)))      printf ("\r\n%s Interrupt\r\n", p);    if (trace_mode == TRACE_DC || trace_mode == TRACE_DS) {	/* pass all exceptions to remote debugger */	remove_trace_breakpoint ();	dbgmode ();    }#endif	if(exc_type != EXC_BPT && exc_type != EXC_TRC && exc_type != EXC_WTCH) {		if (!p) {			md_dumpexc(frame);		}		pmon_stop (0);	}	else if (trace_mode == TRACE_NO) {	/* no bpts set */		printf ("\r\nBreakpoint reached while not in trace mode!\r\n");		md_fpsave(cpuinfo);		pmon_stop (0);	}	else if (trace_mode == TRACE_GB) {	/* go & break */		if (BptTmp.addr != NO_BPT) {			store_word ((void *)BptTmp.addr, BptTmp.value);			BptTmp.addr = NO_BPT;		}		for (i = 0; i < MAX_BPT; i++) {			if (Bpt[i].addr != NO_BPT) {				store_word ((void *)Bpt[i].addr, Bpt[i].value);			}		}		if (exc_type == EXC_WTCH) {			printf ("\r\nStopped at HW Bpt %d\r\n", MAX_BPT);		}		else {			for (i = 0; i < MAX_BPT; i++) {				if(Bpt[i].addr == (int)md_get_excpc(frame)) {					printf ("\r\nStopped at Bpt %d\n", i);					md_fpsave(cpuinfo);					pmon_stop (Bpt[i].cmdstr);				}			}		}		md_fpsave(cpuinfo);		pmon_stop (0);	}    	remove_trace_breakpoint ();	if (trace_mode == TRACE_TB) {		md_fpsave(cpuinfo);		pmon_stop (0);		/* trace & break */	}	else if (trace_mode == TRACE_TN) {		for (i = 0; i < MAX_BPT; i++) {			if(Bpt[i].addr == (int)md_get_excpc(frame)) {				printf ("\r\nStopped at Bpt %d\r\n", i);				md_fpsave(cpuinfo);				pmon_stop (Bpt[i].cmdstr);			}		}		if(trace_invalid && !is_validpc(md_get_excpc(frame))) {			printf ("\r\nStopped: Invalid PC value\r\n");			md_fpsave(cpuinfo);			pmon_stop (0);		}		for (i = 0; i < STOPMAX; i++) {			if (stopval[i].addr == 0) {				continue;			}			if ((stopval[i].sense == 0 &&				load_word ((u_int32_t *)stopval[i].addr) == stopval[i].value)				|| (stopval[i].sense == 1 &&				load_word ((u_int32_t *)stopval[i].addr) != stopval[i].value)) {				if (stopval[i].sense == 0) {					p = " == ";				}				else {					p = " != ";				}				if (!strcmp(stopval[i].name, "MEMORY")) {					printf ("\r\nStopped: 0x%08x%s0x%08x\r\n",						stopval[i].addr, p, stopval[i].value);				}				else {					printf ("\r\nStopped: %s%s0x%08x\r\n", stopval[i].name,						p, stopval[i].value);				}				md_fpsave(cpuinfo);				pmon_stop (0);			}		}		flag = 1;		if (trace_bflag || trace_cflag) {			if(trace_bflag && md_is_branch(md_get_excpc(frame))) {				flag = 1;			}			else if(trace_cflag && md_is_call(md_get_excpc(frame))) {				flag = 1;			}			else {				flag = 0;			}		}		if (flag) {			addpchist (md_get_excpc(frame));			if (trace_verbose) {#if NCMD_L > 0				char tmp[80];				md_disasm (tmp, md_get_excpc(frame));				printf ("%s\r\n", tmp);#endif /* */#ifdef HAVE_DLYSLOT				if (md_is_branch(md_get_excpc(frame))) {				/* print the branch delay slot too */					md_disasm(tmp, md_get_excpc(frame) + 4);					printf ("%s\r\n", tmp);				}#endif			}			else {				dotik (256, 1);			}		}		else {			dotik (256, 1);		}		if (trace_count) {			trace_count--;		}		if (trace_count == 1) {			trace_mode = TRACE_TB;		}		if (setTrcbp (md_get_excpc(frame), trace_over)) {			md_fpsave(cpuinfo);			pmon_stop (0);		}		store_trace_breakpoint ();		console_state(2);		_go ();	}/* else TRACE_TG  trace & go, set on g or c if starting at bpt */	trace_mode = TRACE_GB;	/* go & break */	store_breakpoint ();	console_state(2);	_go ();}#elsevoidexception(frame)	struct trapframe *frame;{#if 0	int exc_type;	int i, flag;	char *p = 0;extern char    *sbddbgintr(unsigned int);	cpuinfo= *frame;	exc_type = md_exc_type(frame);	if(exc_type != EXC_BPT && exc_type != EXC_TRC && exc_type != EXC_WTCH) {		if (!p) {			printf ("\r\nException Cause=%s, SR=%p, PC=%p\r\n",				md_getexcname(frame), (int)md_getsr(), md_getpc());		}		pmon_stop (0);	}	else if (trace_mode == TRACE_NO) {	/* no bpts set */		printf ("\r\nBreakpoint reached while not in trace mode!\r\n");		md_fpsave(cpuinfo);		pmon_stop (0);	}	else if (trace_mode == TRACE_GB) {	/* go & break */		if (BptTmp.addr != NO_BPT) {			store_word ((void *)BptTmp.addr, BptTmp.value);			BptTmp.addr = NO_BPT;		}		for (i = 0; i < MAX_BPT; i++) {			if (Bpt[i].addr != NO_BPT) {				store_word ((void *)Bpt[i].addr, Bpt[i].value);			}		}		if (exc_type == EXC_WTCH) {			printf ("\r\nStopped at HW Bpt %d\r\n", MAX_BPT);		}		else {			for (i = 0; i < MAX_BPT; i++) {				if(Bpt[i].addr == (int)md_get_excpc(frame)) {					printf ("\r\nStopped at Bpt %d\n", i);					md_fpsave(cpuinfo);					pmon_stop (Bpt[i].cmdstr);				}			}		}		md_fpsave(cpuinfo);		pmon_stop (0);	}    	remove_trace_breakpoint ();	if (trace_mode == TRACE_TB) {		md_fpsave(cpuinfo);		pmon_stop (0);		/* trace & break */	}	else if (trace_mode == TRACE_TN) {		for (i = 0; i < MAX_BPT; i++) {			if(Bpt[i].addr == (int)md_get_excpc(frame)) {				printf ("\r\nStopped at Bpt %d\r\n", i);				md_fpsave(cpuinfo);				pmon_stop (Bpt[i].cmdstr);			}		}		if(trace_invalid && !is_validpc(md_get_excpc(frame))) {			printf ("\r\nStopped: Invalid PC value\r\n");			md_fpsave(cpuinfo);			pmon_stop (0);		}		for (i = 0; i < STOPMAX; i++) {			if (stopval[i].addr == 0) {				continue;			}			if ((stopval[i].sense == 0 &&				load_word (stopval[i].addr) == stopval[i].value)				|| (stopval[i].sense == 1 &&				load_word (stopval[i].addr) != stopval[i].value)) {				if (stopval[i].sense == 0) {					p = " == ";				}				else {					p = " != ";				}				if (!strcmp(stopval[i].name, "MEMORY")) {					printf ("\r\nStopped: 0x%08x%s0x%08x\r\n",						stopval[i].addr, p, stopval[i].value);				}				else {					printf ("\r\nStopped: %s%s0x%08x\r\n", stopval[i].name,						p, stopval[i].value);				}				md_fpsave(cpuinfo);				pmon_stop (0);			}		}		flag = 1;		if (trace_bflag || trace_cflag) {			if(trace_bflag && md_is_branch(md_get_excpc(frame))) {				flag = 1;			}			else if(trace_cflag && md_is_call(md_get_excpc(frame))) {				flag = 1;			}			else {				flag = 0;			}		}		if (flag) {			addpchist (md_get_excpc(frame));			if (trace_verbose) {			}			else {				dotik (256, 1);			}		}		else {			dotik (256, 1);		}		if (trace_count) {			trace_count--;		}		if (trace_count == 1) {			trace_mode = TRACE_TB;		}		if (setTrcbp (md_get_excpc(frame), trace_over)) {			md_fpsave(cpuinfo);			pmon_stop (0);		}		store_trace_breakpoint ();		console_state(2);		_go ();	}/* else TRACE_TG  trace & go, set on g or c if starting at bpt */	trace_mode = TRACE_GB;	/* go & break */	store_breakpoint ();#endif	console_state(2);	_go ();}#endif /* NMOD_DEBUGGER */

⌨️ 快捷键说明

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