optee的异常向量表-(irq,fiq,svc...)
生活随笔
收集整理的這篇文章主要介紹了
optee的异常向量表-(irq,fiq,svc...)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1、 optee中的異常向量表thread_excp_vect
- 1.1、異步異常elx_irq、elx_fiq中斷的處理
- 1.2、同步異常el0_sync_a64、el0_sync_a32中斷的處理
★★★ 友情鏈接 : 個人博客導讀首頁—點擊此處 ★★★
以thread_a64.S為例,thread_a32.S暫不分析
1、 optee中的異常向量表thread_excp_vect
其中el0_sync_a64和el0_sync_a32是同步異常處理函數,當執行svc指令是會調用該函數;
#define INV_INSN 0.section .text.thread_excp_vect.align 11, INV_INSN FUNC thread_excp_vect , :/* -----------------------------------------------------* EL1 with SP0 : 0x0 - 0x180* -----------------------------------------------------*/.align 7, INV_INSN el1_sync_sp0:store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3b el1_sync_abortcheck_vector_size el1_sync_sp0.align 7, INV_INSN el1_irq_sp0:store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3b elx_irqcheck_vector_size el1_irq_sp0.align 7, INV_INSN el1_fiq_sp0:store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3b elx_fiqcheck_vector_size el1_fiq_sp0.align 7, INV_INSN el1_serror_sp0:b el1_serror_sp0check_vector_size el1_serror_sp0/* -----------------------------------------------------* Current EL with SP1: 0x200 - 0x380* -----------------------------------------------------*/.align 7, INV_INSN el1_sync_sp1:b el1_sync_sp1check_vector_size el1_sync_sp1.align 7, INV_INSN el1_irq_sp1:b el1_irq_sp1check_vector_size el1_irq_sp1.align 7, INV_INSN el1_fiq_sp1:b el1_fiq_sp1check_vector_size el1_fiq_sp1.align 7, INV_INSN el1_serror_sp1:b el1_serror_sp1check_vector_size el1_serror_sp1/* -----------------------------------------------------* Lower EL using AArch64 : 0x400 - 0x580* -----------------------------------------------------*/.align 7, INV_INSN el0_sync_a64:restore_mappingmrs x2, esr_el1mrs x3, sp_el0lsr x2, x2, #ESR_EC_SHIFTcmp x2, #ESR_EC_AARCH64_SVCb.eq el0_svcb el0_sync_abortcheck_vector_size el0_sync_a64.align 7, INV_INSN el0_irq_a64:restore_mappingb elx_irqcheck_vector_size el0_irq_a64.align 7, INV_INSN el0_fiq_a64:restore_mappingb elx_fiqcheck_vector_size el0_fiq_a64.align 7, INV_INSN el0_serror_a64:b el0_serror_a64check_vector_size el0_serror_a64/* -----------------------------------------------------* Lower EL using AArch32 : 0x0 - 0x180* -----------------------------------------------------*/.align 7, INV_INSN el0_sync_a32:restore_mappingmrs x2, esr_el1mrs x3, sp_el0lsr x2, x2, #ESR_EC_SHIFTcmp x2, #ESR_EC_AARCH32_SVCb.eq el0_svcb el0_sync_abortcheck_vector_size el0_sync_a32.align 7, INV_INSN el0_irq_a32:restore_mappingb elx_irqcheck_vector_size el0_irq_a32.align 7, INV_INSN el0_fiq_a32:restore_mappingb elx_fiqcheck_vector_size el0_fiq_a32.align 7, INV_INSN el0_serror_a32:b el0_serror_a32check_vector_size el0_serror_a32中斷向量表的注冊:
static vaddr_t get_excp_vect(void) { #ifdef CFG_CORE_WORKAROUND_SPECTRE_BP_SECuint32_t midr = read_midr();if (get_midr_implementer(midr) != MIDR_IMPLEMENTER_ARM)return (vaddr_t)thread_excp_vect;switch (get_midr_primary_part(midr)) { #ifdef ARM32case CORTEX_A8_PART_NUM:case CORTEX_A9_PART_NUM:case CORTEX_A17_PART_NUM: #endifcase CORTEX_A57_PART_NUM:case CORTEX_A72_PART_NUM:case CORTEX_A73_PART_NUM:case CORTEX_A75_PART_NUM:return select_vector((vaddr_t)thread_excp_vect_workaround); #ifdef ARM32case CORTEX_A15_PART_NUM:return select_vector((vaddr_t)thread_excp_vect_workaround_a15); #endifdefault:return (vaddr_t)thread_excp_vect;} #endif /*CFG_CORE_WORKAROUND_SPECTRE_BP_SEC*/return (vaddr_t)thread_excp_vect; }當中斷來時,根據向量表中的跳轉 ,會調用到elx_irq和elx_fiq函數
1.1、異步異常elx_irq、elx_fiq中斷的處理
foreign是外部中斷處理和native內部中斷處理:
LOCAL_FUNC elx_irq , : #if defined(CFG_ARM_GICV3)native_intr_handler irq #elseforeign_intr_handler irq #endif END_FUNC elx_irqLOCAL_FUNC elx_fiq , : #if defined(CFG_ARM_GICV3)foreign_intr_handler fiq #elsenative_intr_handler fiq #endif END_FUNC elx_fiqgicv3和gicv2的中斷處理有什么不同呢?
- 在gicv2中,IRQ固定是給REE用的,FIQ固定是給TEE用的,所以如果在TEE中來了一個IRQ,則會調用foreign_intr_handler irq,foreign前綴是外部的意思,TEE中的處理,就是該函數中調用SMC,切回到REE,讓REE來處理這個中斷;
- 在gicv3中,在TEE中響應的IRQ是給TEE用的,在TEE中響應的FIQ是給REE用的,所以如果在TEE中來了一個FIQ,則會調用foreign_intr_handler fiq,foreign前綴是外部的意思,TEE中的處理,就是該函數中調用SMC,切回到REE,讓REE來處理這個中斷;
1.2、同步異常el0_sync_a64、el0_sync_a32中斷的處理
.align 7, INV_INSN el0_sync_a64:restore_mappingmrs x2, esr_el1mrs x3, sp_el0lsr x2, x2, #ESR_EC_SHIFTcmp x2, #ESR_EC_AARCH64_SVCb.eq el0_svcb el0_sync_abortcheck_vector_size el0_sync_a64LOCAL_FUNC el0_svc , :/* get pointer to current thread context in x0 */get_thread_ctx sp, 0, 1, 2/* load saved kernel sp */ldr x0, [x0, #THREAD_CTX_KERN_SP]/* Keep pointer to initial recod in x1 */mov x1, sp/* Switch to SP_EL0 and restore kernel sp */msr spsel, #0mov x2, sp /* Save SP_EL0 */mov sp, x0/* Make room for struct thread_svc_regs */sub sp, sp, #THREAD_SVC_REG_SIZEstp x30,x2, [sp, #THREAD_SVC_REG_X30]/* Restore x0-x3 */ldp x2, x3, [x1, #THREAD_CORE_LOCAL_X2]ldp x0, x1, [x1, #THREAD_CORE_LOCAL_X0]/* Prepare the argument for the handler */store_xregs sp, THREAD_SVC_REG_X0, 0, 14mrs x0, elr_el1mrs x1, spsr_el1store_xregs sp, THREAD_SVC_REG_ELR, 0, 1mov x0, sp/** Unmask native interrupts, Serror, and debug exceptions since we have* nothing left in sp_el1. Note that the SVC handler is excepted to* re-enable foreign interrupts by itself.*/ #if defined(CFG_ARM_GICV3)msr daifclr, #(DAIFBIT_IRQ | DAIFBIT_ABT | DAIFBIT_DBG) #elsemsr daifclr, #(DAIFBIT_FIQ | DAIFBIT_ABT | DAIFBIT_DBG) #endif/* Call the handler */bl tee_svc_handler/* Mask all maskable exceptions since we're switching back to sp_el1 */msr daifset, #DAIFBIT_ALL/** Save kernel sp we'll had at the beginning of this function.* This is when this TA has called another TA because* __thread_enter_user_mode() also saves the stack pointer in this* field.*/msr spsel, #1get_thread_ctx sp, 0, 1, 2msr spsel, #0add x1, sp, #THREAD_SVC_REG_SIZEstr x1, [x0, #THREAD_CTX_KERN_SP]/* Restore registers to the required state and return*/load_xregs sp, THREAD_SVC_REG_ELR, 0, 1msr elr_el1, x0msr spsr_el1, x1load_xregs sp, THREAD_SVC_REG_X2, 2, 14mov x30, spldr x0, [x30, #THREAD_SVC_REG_SP_EL0]mov sp, x0b_if_spsr_is_el0 w1, 1fldp x0, x1, [x30, THREAD_SVC_REG_X0]ldr x30, [x30, #THREAD_SVC_REG_X30]eret1: ldp x0, x1, [x30, THREAD_SVC_REG_X0]ldr x30, [x30, #THREAD_SVC_REG_X30]msr spsel, #1store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 1b eret_to_el0 END_FUNC el0_svc總結
以上是生活随笔為你收集整理的optee的异常向量表-(irq,fiq,svc...)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [gic]-ARM gicv2和gicv
- 下一篇: optee中的thread_vector