optee中添加一个中断以及底层代码的相关解读
optee、中斷、gic、gicv3、itr_add、安全中斷、tee、trustzone、ATF
★★★ 個人博客導讀首頁—點擊此處 ★★★
.
說明:
在默認情況下,本文講述的都是ARMV8-aarch64架構,optee3.14版本
思考:
如何將一個中斷配置成安全中斷?
如何打開或關閉某一個中斷?
中斷來了之后,能否指定routing到哪個Core?
optee中如何注冊一個中斷?
能否指定一個中斷為FIQ或IRQ?
1、optee中注冊一個中斷
其實呢,我們在代碼全局搜索itr_add是能搜索到好多示例的
我們以optee_os/core/arch/arm/plat-stm32mp1/plat_tzc400.c代碼為例,進行一個講解:
(1)、定義一個struct itr_handler結構體,.it為硬件中斷號,.handler執行中斷處理函數
(optee_os/core/arch/arm/plat-stm32mp1/plat_tzc400.c)static enum itr_return tzc_it_handler(struct itr_handler *handler __unused){EMSG("TZC permission failure");tzc_fail_dump();if (IS_ENABLED(CFG_STM32MP_PANIC_ON_TZC_PERM_VIOLATION))panic();elsetzc_int_clear();return ITRR_HANDLED;}static struct itr_handler tzc_itr_handler = {.it = STM32MP1_IRQ_TZC,.handler = tzc_it_handler,};DECLARE_KEEP_PAGER(tzc_itr_handler);(2)、在初始化的代碼中,注冊該中斷和enable該中斷
itr_add(&tzc_itr_handler); itr_enable(tzc_itr_handler.it);至此一個中斷示例講完了,就是這么簡單。
2、optee中斷的處理流程
(1)、有關itr_core_handler
在中間層實現了一個名叫itr_core_handler虛函數,如果平臺未實現該函數,則發生中斷時會調用此處函數。此處邏輯就是panic()
(optee_os/core/kernel/interrupt.c)134 /* This function is supposed to be overridden in platform specific code */ 135 void __weak __noreturn itr_core_handler(void) 136 { 137 panic("Secure interrupt handler not defined"); 138 }(2)、gic層的處理
- 讀gicd寄存器,讀取中斷號
- 進行中斷處理
- 寫EOIR(End of Interrupt Registers),將該中斷號的中斷置為inactive
有關EOIR寄存器的介紹,可參見gic文檔
小小小總結一下: optee os中的中斷管理,不算復雜, 只有一個硬件中斷號,也不需要給中斷號做map。不像Linux抽象出來irq domain、中斷級聯、硬件中斷號和軟件中斷號需要進行map
3、optee中斷的API介紹(或叫中間層)
- itr_handle : 回調driver中注冊的handler函數。itr_handle維護者一個LIST,將中斷號和driver中的handler結構體綁定
- itr_add : 注冊一個中斷
- itr_enable : enable一個中斷,其實就是修改gicd寄存器, 注:這是Linux Kernel沒有的API吧,optee勝一局
- itr_disable :disable一個中斷,其實就是修改gicd寄存器, 注:這是Linux Kernel沒有的API吧,optee勝一局
- itr_raise_sgi : 產生一個SGI中斷
- itr_set_affinity :設置中斷affinity,也就是指定一個中斷,發生中斷時routing到哪顆Core上。 注:這是Linux Kernel沒有的API吧,optee勝一局
4、注冊要給中斷時底層都做了什么(itr_add做了什么?)
我們知道itr_add()調用了gic_op_add()函數,那么我們就從gic_op_add()看起
(1)、gic_op_add做了哪些事情呢?
- gic_it_add:向gic中注冊中斷
- gic_it_set_cpu_mask:設置該中斷的cpu mask,其實就是設置哪些cpu可以接受該中斷,這里設置的是any online core
- gic_it_set_prio : 設置中斷優先級,中斷優先級是0x00-0xFF,數字越小優先級越高,這里設置的是0X01
(2)、gic_it_add向gic中注冊中斷都干了什么事情呢
- Disable the interrupt
- Make it non-pending
- Assign it to group0
- Assign it to group1S
我們以gicv3為例,這里也許你就有疑問了,為啥要Assign it to group0呢? 其實不要看這里的注釋,需要在gicv3/gicv3的文檔中可以找到答案:
- 如果是gicv2,那么操作GICD_IGROUPR寄存器,給相關bit清0,就是將該中斷配置成group0,gicv2中group0是安全中斷,這符合我們的要求。
- 如果是gicv3,那么先操作GICD_IGROUPR寄存器,給相關bit清0,清零該bit后對應了兩種結果:
將該中斷置成了group0或group1s. 那么到底是用哪種結果呢? 那時gic硬件在處理該中斷時,還會再看GICD_IGROUPMODR寄存器,如果對應的bit為1, 那么該中斷就是group1s,否則是group0。
所以呢,如果是gicv3,這里結合GICD_IGROUPR和GICD_IGROUPMODR就能將該中斷號配置成group1s
GICD_IGROUPMODR對應表格中的Group modifier bit
GICD_IGROUPR對應表格中的Group state bit
總結
以上是生活随笔為你收集整理的optee中添加一个中断以及底层代码的相关解读的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: optee3.14中的异常向量表解读--
- 下一篇: optee中的panic函数实现