文章目录
思考
(1)、smc是如何调用到ATF中的smc_handler64()函数的?
(2)、进入EL3(ATF)的方式有几种?
在ree或tee中执行smc指令后,cpu将触发同步异常,此时cpu进入ATF的sync_exception_aarch64,在干函数中调用了handle_sync_exception()—>smc_handler64()
也就是说,进入EL3(ATF)的方式有两种:
(1)、同步异常:smc指令
(2)、异步异常:产生了routing到EL3的FIQ或IRQ
armv8异常:
- asynchronous exception 异步异常,例如IRQ、FIQ、Serror
- synchronous exception 同步异常,例如hyc、smc
1、同步异常向量表-(smc)
smc同步异常调用的都是handle_sync_exception
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
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
1.1、handle_sync_exception调用smc_handler64处理同步异常
.macro handle_sync_exception
/* Enable the SError interrupt */
msr daifclr, #DAIF_ABT_BIT
str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
mrs x30, esr_el3
ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
cmp x30, #EC_AARCH32_SMC
b.eq smc_handler32
cmp x30, #EC_AARCH64_SMC
b.eq smc_handler64
/* -----------------------------------------------------
* The following code handles any synchronous exception
* that is not an SMC.
* -----------------------------------------------------
*/
bl report_unhandled_exception
.endm
2、异类步异常向量表-(irq,fiq…)
irq/fiq异步异常调用的是handle_interrupt_exception
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
2.1、get_interrupt_type_handler获取ATF注册的中断处理函数
interrupt_type_handler_t get_interrupt_type_handler(uint32_t type)
{
if (validate_interrupt_type(type))
return NULL;
return intr_type_descs[type].handler;
}
2.2、handle_interrupt_exception调用ATF中注册的handler函数
.macro handle_interrupt_exception label
/* Enable the SError interrupt */
msr daifclr, #DAIF_ABT_BIT
str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
bl save_gp_registers
/*
* Save the EL3 system registers needed to return from
* this exception.
*/
mrs x0, spsr_el3
mrs x1, elr_el3
stp x0, x1, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
/* Switch to the runtime stack i.e. SP_EL0 */
ldr x2, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
mov x20, sp
msr spsel, #0
mov sp, x2
/*
* Find out whether this is a valid interrupt type. If the
* interrupt controller reports a spurious interrupt then
* return to where we came from.
*/
bl plat_ic_get_pending_interrupt_type
cmp x0, #INTR_TYPE_INVAL
b.eq interrupt_exit_\label
/*
* Get the registered handler for this interrupt type. A
* NULL return value could be 'cause of the following
* conditions:
*
* a. An interrupt of a type was routed correctly but a
* handler for its type was not registered.
*
* b. An interrupt of a type was not routed correctly so
* a handler for its type was not registered.
*
* c. An interrupt of a type was routed correctly to EL3,
* but was deasserted before its pending state could
* be read. Another interrupt of a different type pended
* at the same time and its type was reported as pending
* instead. However, a handler for this type was not
* registered.
*
* a. and b. can only happen due to a programming error.
* The occurrence of c. could be beyond the control of
* Trusted Firmware. It makes sense to return from this
* exception instead of reporting an error.
*/
bl get_interrupt_type_handler
cbz x0, interrupt_exit_\label
mov x21, x0
mov x0, #INTR_ID_UNAVAILABLE
/* Set the current security state in the 'flags' parameter */
mrs x2, scr_el3
ubfx x1, x2, #0, #1
/* Restore the reference to the 'handle' i.e. SP_EL3 */
mov x2, x20
/* x3 will point to a cookie (not used now) */
mov x3, xzr
/* Call the interrupt type handler */
blr x21
interrupt_exit_\label:
/* Return from exception, possibly in a different security state */
b el3_exit
.endm
剖析该段汇编的关键代码:
bl get_interrupt_type_handler //获取注册的中断处理函数, 返回函数地址,保存在X0中
cbz x0, interrupt_exit_\label
mov x21, x0 //X0保存到了X21中
.....
blr x21 //跳转到X21,就是跳转到ATF中的中断处理函数