总论
软硬件分工
异常处理流时一个需要软硬件协作的流程,如果仅有计组的知识,恐怕不能对异常处理流有完整的认识,但是从操作系统的角度来看就可以理解,这是因为在CPU的层面已经将异常处理流的硬件部分封装起来了,我们只需要了解CPU给操作系统的接口,就可以利用这些接口的信息和功能完成异常处理流的软件部分。
由上图可知,蓝色部分是硬件部分,黄色部分是软件部分,红色部分即两部分接口。因此最重要的就是这两个接口寄存器的意义,Cause寄存器为选择哪一种异常处理函数提供了决策的依据,EPC为有朝一日返回这个进程提供了支持(异常处理完成后不一定会返回异常发生所在的进程,比如时钟中断导致的进程切换)。
概念
异常:

所有的“控制流异常情况的原因”统称为“异常”,同步异常指的是处理器执行某条指令而导致的异常,异步异常指的是异常触发的原因与处理器当前正在执行的指令无关的异常。
异常处理流程

硬件部分
SR寄存器
SR寄存器不是接口即无需暴露给操作系统,这个寄存器的作用是控制异常,所有的异常需要经过SR寄存器的处理之后才将数据保存在Cause中,进而提供给操作系统。
我们通过SR寄存器中的掩码、中段使能和异常等级等位来实现掩码和使能的操作,进而确定是否发出异常信号和更新EPC等处理。
我们查看MIPS R3000的结构:

除了上述的掩码位等,我们来看SR[5:0]的二重栈结构,其中KU如果置1,就说明当前进程处于内核态(内核态可以使用的指令更多,访问的地址空间更大),IE如果置1,说明当前允许异常发生(是异常,不止是中断),三个下标,o代表old,p代表previous,c代表current。
二重栈的工作流程,当发生异常时,previous的内容被拷贝到old中,current的内容被拷贝到previous中,然后当eret指令下达,又将数据恢复。
Cause寄存器
Cause寄存器的内容由CP0生成,然后操作系统来访问这个值。

Cause寄存器使用ExeCode记录异常,BD同样是对OS的接口,如果异常指令是一个分支延迟槽指令,这位就会被置1.因为当异常指令位延迟槽指令时,EPC的值就会变成延迟槽指令的前一条指令。我们在软件侧可以利用BD来获得真正发生异常的指令。

IP 是 Interrupt pending 的意思,他的意思结合代码来看就很容易,它记录的是现在发生的中断,但是这些中断不一定被响应,还有看 IM 的设置。IP 只是一个单纯的记录者。
最重要的是 ExcCode,异常码,CPU 会根据异常的不同,将这个域设置成不同的值,操作系统通过读取这里的值,就可以获得这次异常的信息,R3000 常用的异常码如下:


软件总论
我们要讲的异常处理函数有如下几个:
| 异常处理函数 | 编号 | 解释 |
|---|---|---|
| handle_reserved | 无 | 没有内容,用于初始化异常分发矩阵 |
| handle_int | 0 | 用于处理时钟中断,主要是换进程调度 |
| handle_mod | 1 | 当尝试写一个只读的虚拟页面的时候会触发,主要会进行一个写时复制处理 |
| handle_tlb | 2 | 当 TLB 缺失的时候会触发,会把需要的页表项调入 TLB |
| handle_tlb | 3 | 似乎与上面相同 |
| handle_sys | 8 | 当使用 syscall 指令的时候调用,会根据系统调用号去决定异常处理的功能 |

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/37224.html