——————————————————————异常第四步 一些简单的东西——————————————————————
给这么个题目就是想说,这步骤的划分其实是我捏造的,大概是这顺序,但没求证过!
简单的东西不多
栈指针的选择算是一个,
哎呦,一不小心在前面写完了。。。参看一下SPSR下SP的描述。
第二个简单的东西是清除物理SError中断异常,
如果是虚拟SError中断则清除HCR_EL2.VSE
当HCR_EL2.{TGE=0,AMO=1},虚拟SError即使能,HCR_EL2.VSE位即为虚拟SError中断标志。
如果SCTLR_ELx.IESB在当前异常等级是1,则PE插入一个错误同步事件,
认真的讲,我并不知道上一句话什么意思,与ARM Relability Availability and Serviceablity RAS相关。
——————————————————————异常第五步 异常向量——————————————————————
我天!!!终于到头了,异常向量。
啊!!熟悉的异常向量,跳转到异常向量,就是真正的开始处理异常了,
而在跳转之前,还是需要介绍一下异常向量的细节的。
异常向量是当PE执行一个异常的时候就会跳转到异常向量的地址执行异常处理。
异常向量存在于向量表,
这个向量表占有一段连续的字节对齐的地址,
从向量基地址开始,
每个异常等级都有一个相关联的向量基地址寄存器(VBAR Vector Base Address Register)。
至此,一次异常终于得到了执行,
但其实我省略了很多东西:
一次同步异常,很可能是被主动发起,
发起的同时如果会有一些参数需要传入,这其中是如何操作的,
拍脑门儿的说,肯定是先把东西放到寄存器,然后触发异常,但实际运作方式必然更加复杂。
对于异步异常(大概也就是中断之类),被处理的时机在哪儿?是一条指令执行完毕?还是在某些固定的点
?这些都是没有仔细分析的(主要也是因为在搜索引擎上可以找到更好的答案,我懒得抄)。
另外,写到目前为止,我都没有将MMU的故事放进来,
因为那是可以同样写一段更长的文字来描述,
但是可以记下两个寄存器,
一阶段页表转换失败保存失败的虚拟地址的寄存器FAR_ELx(这个寄存器有三个),
二阶段页表转换失败保存IPA的寄存器HPFAR_EL2(我认为这个寄存器应该只有一个,最起码是没有EL1的),
——————————————————————异常 返回——————————————————————
异常从发生到处理,在上面已经有了不完整的描述,
异常的返回同样繁复,但很明显会比上面的东西轻松许多。
之前也提到了ERET指令,ERET指令是触发从异常返回的指令
其实我一开始觉着,处理完了返回,就直接指令流指回去不就OK了,就像函数返回一样,
很明显我没有考虑存在不同异常等级间返回存在的:PSTATE切换,PC切换,更不必说栈指针了。
最终异常返回的情况:
第一种要返回的情况是返回之前执行的指令流,
这已经是最简单的了吧,
从ELR_ELx从取出地址放到PC、从SPSR_ELx取出状态放到PSTATE,
看看吧,这就是一次系统调用结束返回所需要的开销,
微内核改为用户态服务提供,需要等着30个寄存器重新换一遍,
更不必说引起cache的更新、TLB的切换
与系统调用,咋比?
虽然较真儿的说,这样的比较不合理,
因为进程切换完之后可以一次处理很多业务,从响应时间上讲。。。
第二种要返回的情况是进入新的执行线程,比如
Secure monitor启动hypervisor;
hypervisor启动OS内核;
OS内核启动进程。