本篇说的是MIPS的异常与中断。
异常与中断
可能很多人不是太明白这两者的含义:
- 异常,是指计算机在执行程序的过程中,当出现异常情况或特殊请求时,计算机停止现行程序的运行,转而对这些异常情况或特殊请求的处理。
- 中断,是异常的一种,通常指的是由于外设引起的中断,在MIPS中,一般占用0号异常。中断运行结束后会返回被打断程序的间断处,继续执行原程序。
不包括中断的异常例如:TLB相关的异常,cache出错的异常,软件中断异常,浮点异常等。
另外提到异常,在MIPS中都会提及到一个"精确异常"的词。MIPS是一个流水线的处理器,例如通常5级流水线会包含:取址,读取寄存器,执行运算逻辑,访问内存,写回寄存器。这几步会被并行的在流水线上执行,所以,当一个异常产生了时,下一条指令很可能已经在流水线上了。精确异常指的就是,在抛出异常的位置,之前的指令都已经执行完毕,该指令之后的指令都不需要软件处理上做任何考虑。
异常和中断处理
MIPS处理器是一种非常简洁的处理器,一个核心包括了基本的指令处理。对于一些其他的,例如在其他系统中经常见到的:中断处理,MMU单元,cache等,MIPS处理器采用的是CP0协处理器来解决,相应的也就有了CP0相关的指令。
也就是说,一块MIPS处理器,它会有基本相同的系统相关部件处理方式,而不是把这些做为外设推到各个厂家去自行实现。例如异常入口位置是固定的,MMU操作、cache操作方式相同的等。当然,根据具体芯片外设的不同,外设中断也需要相应的中断控制器。
当SR(BEV = 0)时,异常入口位置将位于RAM上:EBase + 偏移量(MIPS32 release1的EBase是0x8000 0000)
EBase + 0x200 Interrupts (Cause(IV) = 1)
EBase + 0x180 General exceptions
EBase + 0x100 Cache error
EBase + 0x000 Simple TLB refill (SR(EXL) = 0)
对于MIPS32,中断异常的入口点在offset 0x180或 offset 0x200,具体是哪个取决于Cause寄存器的值。MIPS32 release2在release1的基础上添加了向量中断的扩展。而MIPS2,中断异常的入口点则是0x80000200。
当异常来临时,CP0中的SR寄存器会反映出相应的状态处理。EPC寄存器存放着异常来临前的位置,当异常结束后,应该再跳转回来继续运行。
下图是SR寄存器的格式:
与中断相关的几个位:
IE,全局中断使能位;
EXL,任意异常发生时置位,并会进入核心态,禁止中断。
ERL,在CPU发现收到错误数据时置位。
IM0 - 7,中断0 - 7的屏蔽位;
中断仅在以下条件满足的时候触发:
1. SR寄存器中的IE位置位
2. SR寄存器中的EXL和ERL位置零。
3. 中断源触发了中断
中断异常处理的过程:
1. 在异常处理程序入口,被中断打断的程序只有很少状态信息保存了下来,所以第一件要做的事就是保存当前上下文的信息到栈中,以不覆盖被中断程序的重要数据。
2. 查询Cause (ExcCode)以分派不同的异常。如果是异常0,需要转到中断处理程序中进行处理。
3. 如果是中断,进入到中断派发流程,需要从外设中断控制器中读出是哪个中断触发,然后寻找相应的中断服务例程进行运行。
4. 从异常返回:异常结束处理是另一个CPU状态发生变化的区域。
下图是Cause寄存器的格式:
与异常、中断相关的位:
ExcCode,对应的是,当异常产生时,是哪个异常触发了。
IP0 - IP7,对应一组八个独立的中断位,也就是八个中断,通常有2个软中断,6个硬中断:
* 定时器中断通常被连接到了IP7(即硬中断的中断5上)。
* performance counter是CP0中的一个寄存器,它会按照CPU主频或半频的方式计数。
(定时器中断是和OS密切相关的,特别是当程序携带时间特性时,都需要依赖它来进行运转下去)
[
本帖最后由 ffxz 于 2010-11-5 22:34 编辑 ]