上次我们讲了处理器的中断和异常,只是从高到低俯视了这一功能。没有落到实处,没有具体到细节。上一章有一处有问题,在此改正一下,狭义的中断和狭义的异常一起构成了广义的异常而非广义的中断。这一次,我们就来讲讲RISC-V特权架构,顺便把RISC-V架构中的中断和异常探索得更加深入。
CPU可以运行在好几种特权模式下。RISC-V中定义了三种特权模式,分别是机器模式(machinemode)、监管者模式(supervisor mode)和用户模式(user mode)。不同的领域和不同的厂家有不同的称呼。在操作系统中,机器模式体现为实模式,用户模式则体现为保护模式。早期的dos系统就是运行在实模式下。
RISC-V中的三种特权模式的编码、名称和缩写
为什么要划分这么多种的模式呢?目的是为了保护电脑运行环境不被破坏。比如说一个病毒线程想要篡改其他线程中的内存数据,甚至是破坏操作系统,这种操作肯定是不被允许的。我们必须为每一个线程划定一个空间,每个线程只能访问属于自己的空间。具体操作以后会讲。那问题就解决了吗?没有。作为操作系统,得能够有效的控制别的线程的运行情况,必要的时候将读写一些线程。因此操作系统必须要被赋予更高级的权限,或者说要与其他的应用线程区别对待,因此不同特权模式应运而生。
其中操作系统的线程代码就是运行在机器模式下,应用程序运行在用户模式下,有些时候比如windows系统里会忽然弹出一个管理员权限的许可窗口,如果你点了确定,可以理解为应用程序的权限经过你的许可提高到了监管者模式。注意:机器模式的权限是最高的,用户模式的权限是最低的。如果用户的权限过高,他们可能会弄坏电脑。
那么RISC-V的CPU是怎么做的呢?
首先,RISC-V架构中定义了一些控制和状态寄存器(control and status register),简称CSR,与32个物理寄存器不同(物理寄存器可以认为是5位地址寻址的),这些CSR是用12位地址进行寻址的,并且地址空间是私有独立的,不同于全局地址空间。并且,针对这些CSR寄存器的读写有相应的特殊指令,这些特殊指令都有被定义在之前讲的RISC-V指令集图卡中。其中某些特权指令只能在机器模式中被执行(需要等级权限),如果在用户模式中遇到这些特权指令,处理器就会抛出异常,相应的线程可能会被杀死,或者由用户自行决定。其次,CSR的种类有很多,举几个机器模式中要用到的CSR。比如mvendorid寄存器,它在12位的地址空间的地址是0xf11,它的用途是保存厂商标识代码的,所有的电子产品生产厂商可以向美国JEDEC协会付费申请一个厂商标识代码(也可以向我申请,我不收费,有意联系)。再比如misa(指令集寄存器),地址是0x301,用途是指示此CPU支持哪些指令集。类似的CSR有很多,在此不一一赘述,下面重点说说八个和机器模式中断与异常有关的CSR。
它们分别是:mepc(异常PC寄存器)、mtvec(异常向量基地址寄存器)、mcause(异常原因寄存器)、mie(中断使能寄存器)、mip(中断等待寄存器)、mtval(异常值寄存器)、mscratch(草稿寄存器)和mstatus(线程状态寄存器)。其中每个寄存器命名开头的m是机器模式的意思。相应的还有其他模式中断与异常的CSR。
mstatus寄存器的具体字段,仅需注意红色画圈部分
机器模式下,异常发生时,mepc用于保存当前线程的PC值(或者异常的PC值),并将异常服务程序的入口地址从mtvec写入PC寄存器中。倘若支持向量中断并且是狭义中断发生时,那么PC值设置为mtvec-1+异常序号编码*4(之所以-1,是因为mtvec最低位是硬件是否支持向量中断的标志位,1表示支持向量中断,在硬件电路中我们大可以直接将最后一位抹掉实现-1),而狭义异常发生时,PC值仍设置成mtvec不变。根据异常或中断来源,将其来源序号写入mcause中。将mtval设置为出错的地址或其他适用于特定异常的信息字。将mstatus中的MIE字段(注意,是MIE字段,不是mie寄存器,字段是指寄存器中的某一段数值,MIE字段属于mstatus寄存器的一部分)写到MPIE字段中后,再将MIE字段写0,用以禁止接受狭义中断,此时狭义中断如果发生,硬件将不做响应。因此,RISC-V能且只能支持软件中断嵌套。狭义异常是不需要嵌套的,异常服务程序中不会再发生狭义异常,除非你异常服务程序写得有问题。将发生中断前的权限模式写到mstatus中的MPP字段内。可以想象到,当中断或异常结束后,这些保存了的东西是要复原回来的,线程方能继续执行。
注意:以上过程均是由硬件自己完成,该过程中,没有指令被执行。硬件准备完成后,PC跳转到mtvec这个统一的地址入口,异常服务程序才开始处理异常。(以上过程有些繁杂,慢慢看,你会明白设计者的用意的)
异常服务程序具体怎么做呢?如果不支持向量中断,那么异常服务程序一上来,就先查询mcause寄存器,看看这个异常是狭义中断还是狭义异常,具体是哪出了问题。根据不同的问题再次跳转到不同的地址,对症下药解决问题。比如说打3d游戏的时候鼠标传来了一个中断,CPU跳转到异常服务程序,经查询mcause得知这是一个鼠标传来的中断,进而访问鼠标的驱动程序,并将相应数值传递给这款3d游戏,从而3d游戏渲染新的一帧画面,最后画面完成旋转。
以上便是RISC-V架构在机器模式下对异常的处理。具体细节需要参考RISC-V架构书。
审核编辑:刘清
-
中断
+关注
关注
5文章
898浏览量
41484 -
状态寄存器
+关注
关注
0文章
39浏览量
7084 -
RISC-V
+关注
关注
45文章
2275浏览量
46142
发布评论请先 登录
相关推荐
评论