RISC-V学习笔记【中断和异常】

更新时间:2023-05-12 13:22:05 阅读: 评论:0

RISC-V学习笔记【中断和异常】
RISC-V架构的中断与异常
⼀般来说由处理器内部的事件或程序执⾏中的事件引起的程序跳转称为异常;⼀般的由处理器外部因素引起的程序跳转称为中断
⼴义上来说中断和异常都被处理器视为异常,⼀般将其分为同步异常和异步异常
同步异常
同步异常:由于执⾏程序指令流或者试图执⾏程序指令流⽽造成的异常
表现:CPU外部环境⼀定,多次执⾏时每次能够精确复现
常见的同步异常包括但不限于:
取指令访问到⾮法的地址区间
读写数据访问地址属性出错
取指令地址⾮对齐错误
⾮法指令错误
执⾏调试断点指令
异步异常
异步异常:产⽣原因不能被精确定位于某条指令的异常
表现:CPU外部环境⼀定,但是每次发⽣异常的指令PC都可能会不⼀样
最常见的异步异常就是外部中断。外部中断的发⽣和中断请求到达时处理器执⾏的指令都是不确定的,这就导致很难出现反复执⾏同⼀条指令时恰好发⽣外部中断。外部中断也因此常常被直接⽤“异步异常中断”指代
根据处理器响应异常后的状态,可以分为精确异步异常和⾮精确异步异常
精确异步异常
响应异常后处理器状态能精确反映为某⼀条指令的边界
外部中断狭义来讲就是⼀种精确异步异常:执⾏完以后还会返回到原来断开的指令处继续执⾏
⾮精确异步异常
响应异常后处理器状态不能精确反映为某⼀条指令的边界
读写存储器出错是⼀种最常见的⾮精确异步异常
访问存储器时处理器还会接着执⾏指令,如果在此期间出现了访问错误进⽽触发异常,处理器会在处理到之后的某条指令时进⼊异常服务程序,难以预测当前执⾏到了哪个指令
写⼊缓存⾏时,也可能发⽣类似的错误,具体的原理与访问情况类似
异常处理机制
RISC-V架构要求必须实现机器模式的异常处理机制,蜂鸟E203也只实现了机器模式
RISC-V对于异常处理的实现相对简单,并不如ARM Cortex系列CPU那样具有复杂的NVIC或GIC中断控制器
执⾏异常处理的流程如下:
进⼊异常
该过程在RISC-V架构中定义为陷阱(Trap),也就是“进⼊异常”
1. 停⽌执⾏当前程序流,转⽽从CSR寄存器mtvec定义的PC地址开始执⾏
mtvec即机器模式异常⼊⼝基地址寄存器(Machine Trap-Vector Ba-Address Register)
这是⼀个可读写的CSR寄存器,可使⽤软件编程。mtvec寄存器的低2位是MODE域,当MODE=0时,所有异常响应时处理器跳转到BASE值指⽰的PC地址;当MODE=1时,会分情况参考mtvec寄存器的⾼30位BASE域:由CPU内部引发的狭义异常出现时,CPU 跳转到BASE值指定的PC地址,当由CPU外部引发的狭义中断出现时,CPU跳转到BASE+4*CAUSE值指⽰的PC地址,其中CAUSE 值表⽰中断对应异常编号,也就是中断号
在配合使⽤SoC时通常会使⽤MODE=1的情况,这样机器就能对外部中断进⾏更好的响应
2. 让硬件更新⼏个CSR寄存器
1. 机器模式异常原因寄存器mcau(Cachine Cau Register)
⽤于反映当前的异常种类,软件可以查询该寄存器来了解异常原因
2. 机器模式异常PC寄存器mepc(Machine Exception Program Counter)
异常的返回地址由mepc保存,进⼊异常时硬件会⾃动将mepc更新为当前遇到异常的指令PC值,特别地,软件也可以更改这个寄存器,这样就会导致从异常返回时跳转到其他地⽅
对中断⽽⾔,mepc的值保存为下⼀条尚未执⾏的指令
对异常⽽⾔,mepc的值被更新为当前发⽣异常的指令PC,这样有助于在异常服务程序中修正当前指令出现的错误;但是如果异常由ecall或ebreak造成,mepc的值会被更新为ecall或ebreak指令⾃⼰的PC,在指令返回时如果直接使⽤mepc保存的PC值将导致跳回ecall或ebreak导致死循环。需要在异常处理程序中⽤软件改变mepc=mepc+4或mepc=mepc+2
3. 机器模式异常值寄存器mtval(Machine Trap Value Register)
进⼊异常时硬件会⾃动更新mtval来反映引起当前异常的存储器访问地址或指令编码:对于存储器访问异常会保存指令访问的地址,对于⾮法指令,则会保存该指令的编码
4. 机器模式状态寄存器mstatus(Machine Status Register)
mstatus的某些域会在进⼊异常时被改写。
MPIE域的值更新位异常发⽣前MIE域(表⽰机器模式下中断的开/关,1为全局打开,0为全局关闭)
的值,由此能够使⽤MPIE 的值恢复出异常发⽣前MIE的值;MIE则会被置0,进⼊异常服务程序后全局中断关闭;MPP(⽤于记录异常发⽣之前的⼯作模式,对只⽀持机器模式的CPU来说MPP的值永远是2’b11)的值会被更新到异常发⽣之前的状态
中断等待:就是等待当前发⽣的中断被处理,简单理解成指⽰中断发⽣的标志即可
执⾏异常服务程序
以下为执⾏分⽀异常处理的异常服务程序⽚段
通过读取mcau的值来判断异常的类型,进⽽进⼊不同的异常服务⼦程序
特别注意:RISC-V中规定进⼊和退出异常机制中没有硬件⾃动保存和恢复上下⽂的操作,软件需要明确地使⽤指令进⾏上下⽂的保存和恢复
uintptr_t handle_trap(uintptr_t mcau,uintptr_t epc)
{
if(0)
{
//来⾃PLIC的外部中断
}
el if((mcau & MCAUSE_INT)&&(mcau & MCAUSE_CAUSE)==IRQ_M_EXIT)
{
handle_m_ext_interrupt();//来⾃PLIC的外部中断
}
el if((mcau & MCAUSE_INT)&&(mcau & MCAUSE_CAUSE)==IRQ_M_TIMER)
{
handle_m_time_interrupt();
}
el
{
write(1,"trap\n",5);
_exit(1+mcau);
}
return epc;
}
PLIC在之后的SoC部分讲述
退出异常
RISC-V定义了⼀组退出异常指令,软件在机器模式下必须使⽤MRET退出异常,这会导致
1. 停⽌执⾏当前程序流,从CSR寄存器mepc定义的PC值开始执⾏
恢复现场,可以继续之前被终⽌的程序流
2. 同时更新CSR寄存器机器模式状态寄存器mstatus
1. MIE域的值被更新为当前MPIE的值
2. MPIE域的值被更新为1(打开全局中断)
中断分类
RISC-V定义了4种中断类型,⼤体上和ARM架构的中断类似,中断类型选取都是通过屏蔽寄存器来控制,下⾯所说的由xx寄存器控制就是指由xx寄存器来负责屏蔽某种中断类型
外部中断External Interrupt
来⾃核⼼外的中断,常见的GPIO、UART中断都属于这个中断
由CSR寄存器mie中的MEIE控制,等待标志反映在CSR寄存器mip中的MEIP域
定时器(也就是计时器)中断Timer Interrupt
来⾃定时器的中断
由mie寄存器的MTIE域控制,等待标志反映在mip寄存器中的MTIP域
软件中断Software Interrupt
来⾃软件⾃⼰触发的中断
由mie寄存器中的MSIE域控制,等待标志反映在mip寄存器的MSIP域
调试中断Debug Interrupt
⽤于实现调试器的中断
RISC-V定义了⼀个平台级别中断控制器PLIC(Platform Level Interrupt Controller),可⽤于多个外部中断源的优先级仲裁和派发
PLIC可以将多个外部中断源仲裁为⼀个bit的中断信号送⼊处理器核,处理器核接收到中断进⼊异常服务程序后可以通过读PLIC的相关寄存器查看中断源的编号和信息,在处理完响应中断服务程序后可以通过写PLIC的相关九年起和外部中断源寄存器来清除中断源
PLIC就相当于RISC-V上的弱化版NVIC
RISC-V规定系统平台⾄少有⼀个定时器,并应配由2个64位寄存器mtime(反映当前定时器的计数值)和mtimecmp(设置计时器⽐较值),当mtime中的计数值⼤于等于mtimecmp中设置的⽐较值时,计时器就会产⽣计时器中断,中断期间会⼀直拉⾼直到重写mtimecmp的值⼤于mtime中的值
特别地,两个定时器寄存器不归属于CSR寄存器,⽽是定义为存储器地址映射的系统寄存器,由配套SoC控制,这样就使得位于内核中的定时器变成了“⼀半外设”
这个定时器的时钟必须是为低速(意味着省电)的电源常开(意味着准确稳定)的时钟,它是⼀种实时计时器
中断屏蔽
RISC-V中狭义上的异常是不可屏蔽的,但狭义上的中断可以被屏蔽
CSR寄存器中的机器模式中断使能寄存器mie负责控制中断的屏蔽,这就是上⾯所说的
MEIE控制外部中断
MTIE控制计时器中断
MSIE控制软件中断
中断等待
和中断屏蔽部分类似,中断等待在之前的中断分类部分列出,需要注意等待寄存器的属性都是只读,软件⽆法写⼊,只有这些中断的源头被清除后才能将中断源撤销
中断的撤销⽅法会在下⾯的SoC部分介绍
中断优先级与嵌套中断
RISC-V中不存在⾼优先级中断可以打断低优先级中断的硬件⽀持
外部中断来⾃PLIC,所以外部中断的优先级由PLIC控制,但是最后决定执⾏中断的还是CPU
细⼼的读者可能注意到:RISVC-V架构CPU在进⼊中断后会关闭全局中断,也就是说进⼊中断后⽆法响应新的中断,这就导致只能使⽤软件⽅式才能实现中断嵌套
理论上可以使⽤如下⽅法:
1. 进⼊异常后,软件查询mcau确认中断造成异常,执⾏中断服务程序
2. 强⾏改写mstatus的值,将MIE域的值改为1
在此环节,需要配置mie寄存器中的MEIE/MTIE/MSIE域来选择性屏蔽不同类型的中断
还要配置PLIC阈值寄存器来选择性屏蔽不同优先级的中断
3. 在嵌套中断发⽣前,软件必须将上下⽂保存在存储器堆栈内,并在嵌套中断服务函数执⾏完毕后恢复上下⽂
这⾥的上下⽂不仅包括控制寄存器、通⽤寄存器组,还包括mepc寄存器等其他CSR寄存器的值,否则就会导致程序跑飞
SoC对中断的处理
下图是蜂鸟E203的系统结构框图
蜂鸟E203的SoC只⽀持机器模式定义的中断,且不⽀持MPU、MMU(不会⽣成虚拟地址页错误异常)
⽀持3种基本中断类型,但不⽀持JTAG调试中断,这需要使⽤调试器来进⾏
mtvec寄存器最低位MODE域仅⽀持模式0,在异常响应时处理器跳转到BASE域指⽰的PC地址,这就需要使⽤软件来判断异常类型
对于同步异常,mepc值更新为发⽣异常的指令PC值;对于精确异步异常,mepc更新为下⼀条尚未执⾏的指令PC值;⾮精确异步异
常,mepc更新为当前发⽣异常的指令PC值
CLIENT模块
CLIENT即处理器核局部中断控制器(Core Local Interrupts Controller)
⽤于产⽣计时器中断和软件中断
它作为⼀个存储器地址映射的模块,可以说是⼀个⽚上外设,只⽀持操作尺⼨为32位的读写访问
CLIENT内有⼀个32位的msip寄存器,其最低位是有效位,会被直接作为软件中断信号送到处理器核,写1可以进⼊中断等待,写0可以清除中断
当且仅当全局中断和软件中断局部中断被打开时才能响应软件中断
同时CLIENT内还设置了mtime计数寄存器和mtimecmp⽐较寄存器,上电后默认会进⾏计数,在使⽤中⼀般不直接操作CPU的寄存器,⽽是通过存储器地址映射操作CLIENT的寄存器来达到控制核内定时器的效果
PLIC与外部中断
PLIC被挂载到专⽤的总线接⼝,直接对内核负责
蜂鸟E203的配套SoC中实现了RISC-V规定的PLIC,可以实现类似ARM的NVIC的功能
SoC的外部中断源⼀共有53个,其中0被预留表⽰不存在的中断,每个中断号和中断源⼀⼀对应
PLIC寄存器只⽀持操作尺⼨为32的读写访问。
E203的PLIC仅⽀持单内核机器模式,所以禁⽤到了PLIC的Target 0
理论上PLIC能够⽀持1024个中断源,但因为SoC外设不多,只⽀持了53个中断源,但是还预留有剩下的中断源空间。
总结
RISC-V(蜂鸟E203)的中断、异常处理机制⽐较简单,但是仍然可以⽤类似ARM Cortex-M系列的理念套⽤,也是外设中断控制器作
为“丞相”,CPU当“皇帝”的思路,使⽤中断屏蔽机制来初步筛选中断类型;最⼤的不同就在于RISC-V将更多的任务扔给了软件实现

本文发布于:2023-05-12 13:22:05,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/599906.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:中断   寄存器   软件   指令   处理器   机器   模式
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图