什么是异常
在mips中,中断、陷阱、系统调用和任何可以中断程序正常执行流的情况都称异常
1. 外部事件 ——中断
2. 内存翻译异常
3. 其他不太常见的内核修改的程序条件
4. 程序或硬件探测到的错误
5. 数据完整性错误
6. 系统调用和陷入
精确异常
在运行流程中没有任何多余效应的异常。即当异常发生时,在受害指令之前的指令被完全执行,而受害指令及后面的指令还没开始执行(注:说受害指令及后面的指令还没做任何事情是不对的,实际上受害指令是处于其指令周期的第三阶段刚完成,即ALU阶段刚完成)。精确异常有有助于保证软件设计上不受硬件实现的影响。
CP0中的EPC寄存器用于指向异常发生时指令跳转前的执行位置,一般是受害指令地址。当异常时,是返回这个地址继续执行。但如果受害指令在分支延迟槽中,则会硬件自动处理使EPC往回指一条指令,即分支指令。在重新执行分支指令时,分支延迟槽中的指令会被再执行一次。
精确异常的实现对流水线的流畅性是有一定的影响的,如果异常太多,系统执行效率就会受到影响。
异常
常规异常一般为软件的异常,而中断一般为硬件异常,中断可以是芯片内部,也可以是芯片外部触发产生。
异常发生时,跳转前最后被执行的指令是其MEM阶段刚好被执行完的那条指令。受害指令是其ALU阶段刚好执行完的那条指令。
Ø 用户特权地址的TLB重填
TLB硬件上只存在存储一定数目的地址转换条目,在运行一个虚拟内存的OS的系统中,如果如果程序得以充分的运行,应用程序就会很容易碰到一个虚拟地址在TLB中没有的情况,一个TLB不匹配的事件就发生了。异常产生后硬件帮助异常处理程序在大约13个时钟周期内完成TLB重填。
Ø 64位地址空间的TLB重填
为了充分利用64位CPU的地址空间,地址转换用了一套略为不同的寄存器布局和不同的TLB重填例程,叫做XTLB重填。
Ø 非缓存的异常入口点
出于对异常处理性能的考虑,访问中断入口地址时都要经过缓存,但是在系统启动期间,上电或重启时缓存未经初始化不能使用。因此,在早期启动期间访问不需要经过缓存,CP0寄存器中有个模式位SR(BEV)将异常处理入口定位于非缓存的、启动安全的kseg1内存区域。
Ø 奇偶/ECC校验错误
Mips32cpu可以检查到数据错误,这是不管SR(BEV)的状态,缓存错误的异常入口都在非缓存区域kseg1内存区域。
Ø 重启
MIPS系统把重启看作一个不可回归的异常来处理。
冷启动:CPU硬件完全被重新配置,软件重新加载;
热启动:软件完全重新初始化;
Ø 中断
异常向量
所有的异常入口点都位于MIPS内存映射中不需要地址转换的区域——非缓存的kseg1段和缓存的kseg0段。当SR(BEV)置位时,非缓存的异常入口时固定的,但是当SR(BEV)清零时,EBase寄存器可以通过编程一起移动所有的异常入口到其他地址。
高优先级异常有:冷启动、热重启、非屏蔽中断,
TLB 重填(32 位模式),
xTLB 重填(64 位模式),cache 错误,其他异常。
高优先级异常入口地址有以下五个:
优先级异常入口
异常类型 |
正常运行(BEV 为 0) |
启动(BEV 为 1) |
冷启动、热重启、非屏蔽中断 |
0x BFC0 0000 |
0x BFC0 0000
|
TLB 重填 |
0x 8000 0000 |
0x BFC0 0200 |
xTLB 重填 |
0x 8000 0080 |
0x BFC0 0280 |
cache 错误 |
0x A000 0100 |
0x BFC0 0300 |
其他 |
0x 8000 0180 |
0x BFC0 0380 |
状态寄存器(SR)
BEV=1 :非缓存异常处理入口固定定位于非缓存的、启动安全的kseg1内存区域
BEV=0 :异常处理入口不固定,通过EBase寄存器可以编程移动,系统正常运行时为0
MIPS 下 TLB、Cache 都要 OS 参与