异常向量的位置

Reset, Soft Reset和NMI异常的入口地址始终是 0xBFC0 0000;

EJTAG Debug异常的入口地址是 0xBFC0 0480 (if ProbTrap=0), 或者0xFF20 0200 (if ProbTrap=1);

EBase

CP0 Ebase寄存器中保存着异常向量的基地址,系统复位是Ebase的值是0x8000 0000。这个值是可以修改的, 也就是允许用户指定异常向量的位置。但PMON和Linux内核中都没有修改这个值,因此EBase=0x80000000

异常向量偏移量

异常 | 向量偏移

TLB Refill, EXL=0 | 0x000 64-bit XTLB Refill, EXL=0 | 0x080 Cache error | 0x100 General Exception | 0x180 Interrupt, Cause_IV=0 | 0x180 Interrupt, Cause_IV=1 | 0x200

注意中断的偏移量受Cause_IV的影响

中断的初始化过程

unsigned long exception_handlers[32];

start_kernel()
    trap_init()
	    set_handler(0x180, &except_vec3_generic, 0x80);
		    set_except_vector(int n, void *addr);
			    exception_handlers[n] = addr;

默认的异常处理函数为handle_reserved:

	/*
	 * Setup default vectors
	 */
	for (i = 0; i <= 31; i++)
		set_except_vector(i, handle_reserved);

异常处理函数

extern asmlinkage void handle_adel(void);
extern asmlinkage void handle_ades(void);
extern asmlinkage void handle_ibe(void);
extern asmlinkage void handle_dbe(void);
extern asmlinkage void handle_sys(void);
extern asmlinkage void handle_bp(void);
extern asmlinkage void handle_ri(void);
extern asmlinkage void handle_ri_rdhwr_vivt(void);
extern asmlinkage void handle_ri_rdhwr(void);
extern asmlinkage void handle_cpu(void);
extern asmlinkage void handle_ov(void);
extern asmlinkage void handle_tr(void);
extern asmlinkage void handle_fpe(void);
extern asmlinkage void handle_ftlb(void);
extern asmlinkage void handle_mdmx(void);
extern asmlinkage void handle_watch(void);
extern asmlinkage void handle_mt(void);
extern asmlinkage void handle_dsp(void);
extern asmlinkage void handle_mcheck(void);
extern asmlinkage void handle_reserved(void);

这些函数都是在 arch/mips/kernel/genex.S文件中用BUILD_HANDLER宏造出来的。