先看下ARM官方文档中所定义的向量表
第一行描述: 没有发生Exception切换,且SP使用的是SP_EL0
第二行描述: 没有发生Exception切换,且SP使用的是SP_ELx(x=1,2,3)
第三行描述: 发生l Exception切换,且target level使用的是aarch64;
第四行描述: 发生l Exception切换,且target level使用的是aarch32;
在宏内核体系中,第一行是不会用到的。不考虑aarch32,第四行也用不着;
如果SCR_EL3.FIQ=1,那么cpu在EL3时来的FIQ,将使用第二行向量表;
如果SCR_EL3.FIQ=1,那么cpu在EL0/1时来的FIQ,将使用第三行向量表;
而我们在看下ATF的向量表定义的代码,发现第二行的向量表没有实现,这是为什么呢?
.
.section .vectors, "ax"; .align 11
.align 7
runtime_exceptions:
/* -----------------------------------------------------
* Current EL with _sp_el0 : 0x0 - 0x200
* -----------------------------------------------------
*/
sync_exception_sp_el0:
/* -----------------------------------------------------
* We don't expect any synchronous exceptions from EL3
* -----------------------------------------------------
*/
bl report_unhandled_exception
check_vector_size sync_exception_sp_el0
.align 7
/* -----------------------------------------------------
* EL3 code is non-reentrant. Any asynchronous exception
* is a serious error. Loop infinitely.
* -----------------------------------------------------
*/
irq_sp_el0:
bl report_unhandled_interrupt
check_vector_size irq_sp_el0
.align 7
fiq_sp_el0:
bl report_unhandled_interrupt
check_vector_size fiq_sp_el0
.align 7
serror_sp_el0:
bl report_unhandled_exception
check_vector_size serror_sp_el0
/* -----------------------------------------------------
* Current EL with SPx: 0x200 - 0x400
* -----------------------------------------------------
*/
.align 7
sync_exception_sp_elx:
/* -----------------------------------------------------
* This exception will trigger if anything went wrong
* during a previous exception entry or exit or while
* handling an earlier unexpected synchronous exception.
* There is a high probability that SP_EL3 is corrupted.
* -----------------------------------------------------
*/
bl report_unhandled_exception
check_vector_size sync_exception_sp_elx
.align 7
irq_sp_elx:
bl report_unhandled_interrupt
check_vector_size irq_sp_elx
.align 7
fiq_sp_elx:
bl report_unhandled_interrupt
check_vector_size fiq_sp_elx
.align 7
serror_sp_elx:
bl report_unhandled_exception
check_vector_size serror_sp_elx
/* -----------------------------------------------------
* Lower EL using AArch64 : 0x400 - 0x600
* -----------------------------------------------------
*/
.align 7
sync_exception_aarch64:
/* -----------------------------------------------------
* This exception vector will be the entry point for
* SMCs and traps that are unhandled at lower ELs most
* commonly. SP_EL3 should point to a valid cpu context
* where the general purpose and system register state
* can be saved.
* -----------------------------------------------------
*/
handle_sync_exception
check_vector_size sync_exception_aarch64
.align 7
/* -----------------------------------------------------
* Asynchronous exceptions from lower ELs are not
* currently supported. Report their occurrence.
* -----------------------------------------------------
*/
irq_aarch64:
handle_interrupt_exception irq_aarch64
check_vector_size irq_aarch64
.align 7
fiq_aarch64:
handle_interrupt_exception fiq_aarch64
check_vector_size fiq_aarch64
.align 7
serror_aarch64:
bl report_unhandled_exception
check_vector_size serror_aarch64
/* -----------------------------------------------------
* Lower EL using AArch32 : 0x600 - 0x800
* -----------------------------------------------------
*/
.align 7
sync_exception_aarch32:
/* -----------------------------------------------------
* This exception vector will be the entry point for
* SMCs and traps that are unhandled at lower ELs most
* commonly. SP_EL3 should point to a valid cpu context
* where the general purpose and system register state
* can be saved.
* -----------------------------------------------------
*/
handle_sync_exception
check_vector_size sync_exception_aarch32
.align 7
/* -----------------------------------------------------
* Asynchronous exceptions from lower ELs are not
* currently supported. Report their occurrence.
* -----------------------------------------------------
*/
irq_aarch32:
handle_interrupt_exception irq_aarch32
check_vector_size irq_aarch32
.align 7
fiq_aarch32:
handle_interrupt_exception fiq_aarch32
check_vector_size fiq_aarch32
.align 7
serror_aarch32:
bl report_unhandled_exception
check_vector_size serror_aarch32
在ATF/docs/firmware-design.md中找到了答案, 原来是在进入ATF之前,disable了所有的exception,ATF又没有修改PSTATE.DAIF,所有在ATF Runtime时 irq/fiq/serror/svnc都是disabled。所以异常向量表的第二行,也就用不着了。
Required CPU state when calling
bl31_entrypoint()
during cold boot
This function must only be called by the primary CPU.
On entry to this function the calling primary CPU must be executing in AArch64
EL3, little-endian data access, and all interrupt sources masked:
- PSTATE.EL = 3
- PSTATE.RW = 1
- PSTATE.DAIF = 0xf
- SCTLR_EL3.EE = 0