快速连接
👉👉👉【精选】ARMv8/ARMv9架构入门到精通-目录 👈👈👈
思考
1、在设置VBAR_EL1之前,会发生异常吗? 如果发生异常会怎样?
2、VBAR_EL1中写入的是物理地址还是虚拟地址
3、开启MMU之后,要不要切换异常向量表?
4、optee中有几张异常向量表?
5、unmask中断在enable mmu之前还是之后?一定是这个顺序吗?为什么?
在之前的一篇文章中(optee3.14中的异常向量表解读--中断处理解读),我们介绍了optee中的异常向量表,也知道其基地址(虚拟地址)的设置是在一个比较靠后的位置,设置了VBAR_EL1 = thread_excp_vect,以及从CPU的设置在一个更加靠后的位置。
那么今天我们再来深度探究一下在设置VBAR_EL1 = thread_excp_vect之前的时候,发生异常了会怎么办?
- _start -->(2) :在(2)之前,所有的中断都是MASK的,CPU不会taken这个中断。
(2) -->(4) : 在(2)处unmask serror中断,在(4)处mask掉了所有中断。所以在(2)--->(4)期间系统是可以接受serror中断,此时来的serror中断,cpu将跳转到serror异常向量。事实上
reset_vect_table
向量表中的所有向量,都是死循环(optee_os/core/arch/arm/kernel/entry_a64.S) SErrorSP0: b SErrorSP0 check_vector_size SErrorSP0 .....
- (4)--->std call(yiled call) :(4)已经退出了optee的初始化程序。在下次cpu进入optee时,如果是fast call,那么不会Unmask中断。如果是std call(yiled call)则会Unmask所有中断,那么此时发生的任何异常,cpu将跳转到
thread_excp_vect
向量表
总结写在最后:
1、optee中有两张异常向量表:reset_vect_table
和thread_excp_vect
,其中:
reset_vect_table
:是开机初始化时使用的一张向量表,里面所有的offset的实现都是死循环(相当于未实现),且在开机初始化阶段,只开启了serror中断,所以也不会发生sync、irq、fiq。thread_excp_vect
:开机初始化完成之前设置的向量表。当optee退出之后,下次再因为std call(yield call)进来,会Unmask所有中断,此时会使用这张向量表.
2、写入到VBAR_EL1的是物理地址还是虚拟地址?
reset_vect_table
: 因为是在整个开机初始化的大部分区间,都要使用该向量表,且包括enable_mmu之前和enable_mmu之后的区间。所以答案也是不言而喻,reset_vect_table
的地址一定是VA=PA,那么是怎样做到的呢? 细心的同学可能会发现identity_map
关键字,其实就是将该表存放到了section端,切实一一映射的一块区间。LOCAL_FUNC reset_vect_table , :, .identity_map
reset_vect_table
: reset_vect_table其实定义成了一个函数原型,向量offset对其的方式填入到这个函数体内。最后再将函数地址写入到vbar_el1,故此处是虚拟地址.
关注"Arm精选"公众号,备注进ARM交流讨论区。