optee中的中断处理详解
生活随笔
收集整理的這篇文章主要介紹了
optee中的中断处理详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
快速鏈接:
.
👉👉👉 個人博客筆記導讀目錄(全部) 👈👈👈
文章目錄
- 1、注冊一個中斷
- 2、調用到中斷處理函數
1、注冊一個中斷
注冊中斷很簡單,itr_add和itr_enable就可以了
struct itr_handler temp_irq = {50, //中斷號0, //flagtemp_itr_handler, //handler&temp_data[0], //paramaters{NULL} //link };itr_add(&temp_irq); itr_enable(50);2、調用到中斷處理函數
在secure中斷產生后,PE跳轉到optee的中斷向量表中的irq offset:
el1_irq_sp0:store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3b elx_irqcheck_vector_size el1_irq_sp0調用native_intr_handler函數
LOCAL_FUNC elx_irq , : #if defined(CFG_ARM_GICV3)native_intr_handler irq #elseforeign_intr_handler irq #endif END_FUNC elx_irqnative_intr_handler調用thread_nintr_handler_ptr,也就是在平臺中注冊的handler函數
/* The handler of native interrupt. */ .macro native_intr_handler mode:req/** Update core local flags*/ldr w1, [sp, #THREAD_CORE_LOCAL_FLAGS]lsl w1, w1, #THREAD_CLF_SAVED_SHIFT.ifc \mode\(),fiqorr w1, w1, #THREAD_CLF_FIQ.elseorr w1, w1, #THREAD_CLF_IRQ.endiforr w1, w1, #THREAD_CLF_TMPstr w1, [sp, #THREAD_CORE_LOCAL_FLAGS]/* load tmp_stack_va_end */ldr x1, [sp, #THREAD_CORE_LOCAL_TMP_STACK_VA_END]/* Keep original SP_EL0 */mrs x2, sp_el0/* Switch to SP_EL0 */msr spsel, #0mov sp, x1/** Save registers on stack that can be corrupted by a call to* a C function*//* Make room for struct elx_nintr_rec */sub sp, sp, #ELX_NINTR_REC_SIZE/* Store x4..x18 */store_xregs sp, ELX_NINTR_REC_X(4), 4, 18/* Store lr and original sp_el0 */stp x30, x2, [sp, #ELX_NINTR_REC_LR]bl thread_check_canariesadr x16, thread_nintr_handler_ptrldr x16, [x16]blr x16/** Restore registers*//* Restore x4..x18 */load_xregs sp, ELX_NINTR_REC_X(4), 4, 18/* Load lr and original sp_el0 */ldp x30, x2, [sp, #ELX_NINTR_REC_LR]/* Restore SP_El0 */mov sp, x2/* Switch back to SP_EL1 */msr spsel, #1/* Update core local flags */ldr w0, [sp, #THREAD_CORE_LOCAL_FLAGS]lsr w0, w0, #THREAD_CLF_SAVED_SHIFTstr w0, [sp, #THREAD_CORE_LOCAL_FLAGS]mrs x0, spsr_el1/* Restore x2..x3 */load_xregs sp, THREAD_CORE_LOCAL_X2, 2, 3b_if_spsr_is_el0 w0, 1f/* Restore x0..x1 */load_xregs sp, THREAD_CORE_LOCAL_X0, 0, 1/* Return from exception */eret 1: b eret_to_el0 .endm平臺的gic中段函數注冊,在arch/arm/plat-xxx/main.c中
static const struct thread_handlers handlers = {.std_smc = tee_entry_std,.fast_smc = tee_entry_fast,.nintr = main_fiq, #if defined(CFG_WITH_ARM_TRUSTED_FW).cpu_on = cpu_on_handler,.cpu_off = pm_do_nothing,.cpu_suspend = pm_do_nothing,.cpu_resume = pm_do_nothing,.system_off = pm_do_nothing,.system_reset = pm_do_nothing, #else.cpu_on = pm_panic,.cpu_off = pm_panic,.cpu_suspend = pm_panic,.cpu_resume = pm_panic,.system_off = pm_panic,.system_reset = pm_panic, #endif };如果使用的是gic,在平臺的handler函數中,會直接調用gic中的gic_it_handle
static void main_fiq(void) {gic_it_handle(&gic_data); }我們在看gic_it_handle函數,也是非常的簡單,
void gic_it_handle(struct gic_data *gd) {uint32_t iar;uint32_t id;iar = gic_read_iar(gd); //------------------------從gic中讀取中斷號id = iar & GICC_IAR_IT_ID_MASK;if (id < gd->max_it)itr_handle(id); //--------------------調用itr_add注冊的中斷處理函數elseDMSG("ignoring interrupt %" PRIu32, id);gic_write_eoir(gd, iar); //--------------------取消中斷active(或者叫清除gic中的中斷標記) }調用gic_it_add注冊的中斷處理函數
void itr_handle(size_t it) {struct itr_handler *h = find_handler(it); //----------------------- 找到itr_add注冊時添加的handlerif (!h) {EMSG("Disabling unhandled interrupt %zu", it);itr_chip->ops->disable(itr_chip, it);return;}if (h->handler(h) != ITRR_HANDLED) { //-----------------------執行handlerEMSG("Disabling interrupt %zu not handled by handler", it);itr_chip->ops->disable(itr_chip, it);} }總結
以上是生活随笔為你收集整理的optee中的中断处理详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [ARM异常]-ARMV8的异步异常(中
- 下一篇: [mmu/cache]-ARMV8 MM