这部分代码用于处理Exception中断,对于内核而言是相当重要的,其实现在arch/blackfin/mach-common/entry.S文件中。
ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
/* Since the kernel stack can be anywhere, it's not guaranteed to be
* covered by a CPLB. Switch to an exception stack; use RETN as a
* scratch register (for want of a better option).
*/
EX_SCRATCH_REG = sp;
sp.l = _exception_stack_top;
sp.h = _exception_stack_top;
/* Try to deal with syscalls quickly. */
[--sp] = ASTAT;
[--sp] = (R7:6, P5:4);
DEBUG_STOP_HWTRACE(p5, r7)
r7 = SEQSTAT; /* reason code is in bit 5:0 */
r6.l = lo(SEQSTAT_EXCAUSE);
r6.h = hi(SEQSTAT_EXCAUSE);
r7 = r7 & r6;
p5.h = _ex_table;
p5.l = _ex_table;
p4 = r7;
p5 = p5 + (p4 << 2);
p4 = [p5];
jump (p4);
.Lbadsys:
r7 = -ENOSYS; /* signextending enough */
[sp + PT_R0] = r7; /* return value from system call */
jump .Lsyscall_really_exit;
ENDPROC(_trap)
在这里EX_SCRATCH_REG定义成RETN这个寄存器。
而_exception_stack_top是在本文件中定义的缓冲区的最高位置。
_exception_stack:
// .rept 1024
// .long 0;
// .endr
.byte4 _exception_stack_buffer[1024];
_exception_stack_top:
_ex_table是在本文件中定义的函数指针的数组,它指明了所有可能的64种异常的入口:
ENTRY(_ex_table)
/* entry for each EXCAUSE[5:0]
* This table must be in sync with the table in ./kernel/traps.c
* EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined
*/
.long _ex_syscall /* 0x00 - User Defined - Linux Syscall */
.long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */
…
_ex_table.end:
因而,这一段程序就是根据不同的EXCEPTION的类型,调用相应的入口函数进行处理。