[ATF]-ATF的异常向量表介绍-(irq,fiq,smc,hyc...)

文章目录


★★★ 友情链接 : 个人博客导读首页—点击此处 ★★★

思考
(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中的中断处理函数
上一篇:go des


下一篇:Windows多线程——临界区、事件、互斥量、信号量详解加代码