13-SDEI: Software Delegated Exception Interface
引流關(guān)鍵詞: 中斷、同步異常、異步異常、irq、fiq、BL1,BL2,BL3,BL31,BL32,BL33,AP_BL1,AP_BL2,AP_BL3,AP_BL31,AP_BL32,AP_BL33,SCP_BL1,SCP_BL2,BL0,BL30, optee、ATF、TF-A、Trustzone、optee3.14、MMU、VMSA、cache、TLB、arm、armv8、armv9、TEE、安全、內(nèi)存管理、頁表…
快速鏈接:
.
👉👉👉 個人博客筆記導(dǎo)讀目錄(全部) 👈👈👈
[專欄目錄]-ATF/FF-A/specification學(xué)習(xí)
13.1. 介紹
軟件委托異常接口 ( SDEI :Software Delegated Exception Interface) 是非安全世界的 Arm 規(guī)范,用于向固件注冊處理程序以接收有關(guān)系統(tǒng)事件的通知。固件將首先通過異步異常的方式接收系統(tǒng)事件,并在響應(yīng)中安排注冊的處理程序在非安全 EL 中執(zhí)行。
與 SDEI 調(diào)度程序交互(發(fā)出 SDEI 請求和接收通知)的普通世界軟件稱為SDEI 客戶端。即使客戶端在屏蔽異常的情況下執(zhí)行時,它也會在注冊的處理程序處收到事件通知。
下圖描述了一個涉及 SDEI 客戶端在 EL2 上執(zhí)行的一般序列以及由觸發(fā)綁定中斷產(chǎn)生的事件調(diào)度。如下:
作為初始化的一部分,SDEI 客戶端綁定一個非安全中斷 [1],并且 SDEI 調(diào)度程序返回一個平臺動態(tài)事件編號 [2]。然后,客戶端為該事件注冊一個處理程序 [3],啟用該事件 [5],并取消屏蔽當前 PE 上的所有事件 [7]。此序列是 SDEI 客戶端的典型序列,但可能涉及其他 SDEI 調(diào)用。
在稍后的時間點,當綁定中斷觸發(fā) [9] 時,它會被trapped在 EL3 中。中斷被移交給 SDEI 調(diào)度程序,然后安排執(zhí)行注冊的處理程序 [10]。客戶端使用SDEI_EVENT_COMPLETE[11]終止其執(zhí)行 ,然后調(diào)度程序恢復(fù)原始 EL2 執(zhí)行 [13]。請注意,在客戶端處理程序完成之前,SDEI 中斷保持活動狀態(tài),此時 EL3 執(zhí)行 EOI [12]。
除了綁定到中斷的事件(如上面的序列所示)之外,還可以明確調(diào)度 SDEI 事件以響應(yīng)其他異常,例如,在接收到SError或同步外部中止時(SError or Synchronous External Abort)。
13.2. 定義事件
選擇包含 SDEI 調(diào)度程序的平臺還必須定義平臺上可用的事件及其屬性。
該平臺預(yù)計將提供兩個事件描述符數(shù)組:一個用于private events,另一個用于shared events。該SDEI調(diào)度提供 SDEI_PRIVATE_EVENT()和SDEI_SHARED_EVENT()函數(shù)來填充事件描述符。兩個函數(shù)都有 3 個參數(shù):
- 事件編號:這必須是一個 32 位正整數(shù)。
- 對于backing interrupt中斷的事件,該事件綁定到的中斷號:
如果它不適用于某個事件,則應(yīng)將其保留為0。
如果事件是動態(tài)的,則應(yīng)將其指定為SDEI_DYN_IRQ。 - A bit map of Event flags
要定義事件 0,應(yīng)使用SDEI_DEFINE_EVENT_0()宏。這個宏只需要一個參數(shù):一個 SGI 編號來通知其他 PE。
要定義旨在顯式調(diào)度的事件(即,不是作為接收 SDEI 中斷的結(jié)果),SDEI_EXPLICIT_EVENT() 應(yīng)使用宏。它接受兩個參數(shù):
- 事件編號;
- 事件優(yōu)先級:SDEI_MAPF_CRITICAL或SDEI_MAPF_NORMAL
一旦定義了事件描述符數(shù)組,就應(yīng)該使用REGISTER_SDEI_MAP()宏將它們導(dǎo)出到 SDEI 調(diào)度程序,分別將指向私有和共享事件描述符數(shù)組的指針傳遞給它。請注意, REGISTER_SDEI_MAP()宏必須在定義數(shù)組的同一文件中使用。關(guān)于事件描述符:
- 對于事件 0:
私有數(shù)組中必須只有一個描述符,而共享數(shù)組中沒有。
該事件應(yīng)使用SDEI_DEFINE_EVENT_0().
必須綁定到平臺上的安全 SGI。 - 顯式事件應(yīng)該只在私有數(shù)組中使用。
- 靜態(tài)綁定的共享和私有中斷必須分別綁定到平臺上的共享和私有中斷。請參閱異常處理框架中的配置部分 。
- 兩個數(shù)組都應(yīng)該是一維的。該REGISTER_SDEI_MAP()宏接受復(fù)制的私人事件平臺上的每個PE的照顧。
- 兩個數(shù)組都必須按事件編號的遞增順序排序。
13.2.1. 事件標志
- SDEI_MAPF_DYNAMIC:將事件標記為動態(tài)。動態(tài)事件可以在運行時通過SDEI_INTERRUPT_BIND和SDEI_INTERRUPT_RELEASE調(diào)用綁定到(或從中釋放)任何非安全中斷 。
- SDEI_MAPF_BOUND:將事件標記為靜態(tài)綁定到中斷。這些事件不能在運行時重新綁定。
- SDEI_MAPF_NORMAL:將事件標記為具有普通優(yōu)先級。這是默認優(yōu)先級。
- SDEI_MAPF_CRITICAL:將事件標記為具有嚴重優(yōu)先級
13.3. 事件定義示例
static sdei_ev_map_t plat_private_sdei[] = {/* Event 0 definition */SDEI_DEFINE_EVENT_0(8),/* PPI */SDEI_PRIVATE_EVENT(8, 23, SDEI_MAPF_BOUND),/* Dynamic private events */SDEI_PRIVATE_EVENT(100, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),SDEI_PRIVATE_EVENT(101, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)/* Events for explicit dispatch */SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_NORMAL);SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_CRITICAL); };/* Shared event mappings */ static sdei_ev_map_t plat_shared_sdei[] = {SDEI_SHARED_EVENT(804, 0, SDEI_MAPF_DYNAMIC),/* Dynamic shared events */SDEI_SHARED_EVENT(3000, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),SDEI_SHARED_EVENT(3001, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC) };/* Export SDEI events */ REGISTER_SDEI_MAP(plat_private_sdei, plat_shared_sdei);13.4. 異常處理框架內(nèi)的配置
SDEI 調(diào)度程序與異常處理框架一起運行。這意味著平臺必須為平臺的正常和關(guān)鍵 SDEI 中斷分配優(yōu)先級:
-
為正常和關(guān)鍵 SDEI 中斷安裝優(yōu)先級描述符。
-
對于那些靜態(tài)綁定的中斷(即定義為具有SDEI_MAPF_BOUND屬性的事件),枚舉它們的屬性以便 GIC 驅(qū)動程序相應(yīng)地配置中斷。
-
中斷必須配置為以 EL3 為目標。這意味著它們應(yīng)配置為Group 0。此外,在 GICv2 系統(tǒng)上,構(gòu)建選項 GICV2_G0_FOR_EL3必須設(shè)置為1.
13.5. 確定客戶端 EL
SDEI 規(guī)范要求物理SDEI 客戶端在系統(tǒng)上實現(xiàn)的最高非安全 EL 中執(zhí)行。這意味著調(diào)度程序?qū)⒅辉试S從以下位置進行 SDEI 調(diào)用:
-
EL2,如果實現(xiàn)了 EL2。Hypervisor 預(yù)計將實現(xiàn)一個 虛擬SDEI 調(diào)度程序,以支持在非安全 EL1 中執(zhí)行的客戶操作系統(tǒng)中的 SDEI 客戶端。
-
非安全 EL1,如果 EL2 未實現(xiàn)或禁用。
請參閱 中的函數(shù)在sdei_private.h中的sdei_client_el()
13.6. 顯式分派事件
通常,SDEI 事件調(diào)度是由 PE 接收綁定到 SDEI 事件的中斷引起的。但是,在某些情況下,安全世界需要將 SDEI 事件作為過去活動的直接或間接結(jié)果進行調(diào)度,例如接收安全中斷或異常。
SDEI 調(diào)度程序?qū)崿F(xiàn)sdei_dispatch_event()為此提供了 API。API 具有以下簽名:
int sdei_dispatch_event(int ev_num);參數(shù)ev_num是要調(diào)度的事件編號。API0 在成功或-1失敗時返回。
下圖描述了一個涉及顯式分派 SDEI 事件的場景。評論如下:
作為初始化的一部分,SDEI 客戶端為平臺事件 [1] 注冊一個處理程序,啟用事件 [3],并取消屏蔽當前 PE [5]。請注意,與一般的 SDEI 調(diào)度不同,這不涉及中斷綁定,因為綁定或動態(tài)事件不能被顯式調(diào)度(參見下面的部分)。
在稍后的時間點,關(guān)鍵事件2被困在 EL3 [7] 中。EL3 執(zhí)行事件的第一級分類,RAS 組件承擔(dān)進一步處理 [8]。分派完成,但打算讓非安全世界參與進一步處理,因此決定顯式分派一個事件 [10](客戶端已經(jīng)為 [1] 注冊了該事件)。其余的順序與一般的 SDEI 分派類似:將請求的事件分派給客戶端(假設(shè)所有條件都滿足),當處理程序完成時,搶占執(zhí)行恢復(fù)。
13.6.1. 事件派發(fā)的條件?
必須滿足以下所有要求才能返回 API0并分派事件:
-
必須在 PE 上取消屏蔽 SDEI 事件。即客戶必須 PE_UNMASK事先打電話。
-
無法分派事件 0。
-
必須使用上述SDEI_EXPLICIT_EVENT()宏聲明事件。
-
該事件必須是 PE 私有的。
-
該事件必須已注冊并啟用。
-
同一事件的調(diào)度不得未完成。即它還沒有被發(fā)送并且還沒有完成。
-
事件的優(yōu)先級(嚴重或正常,由平臺在構(gòu)建時配置)不應(yīng)導(dǎo)致優(yōu)先級反轉(zhuǎn)。這意味著:
-
如果它是 Normal 優(yōu)先級,那么在 PE 上,Normal 和 Critical 優(yōu)先級調(diào)度都必須是未完成的。
-
如果它具有關(guān)鍵優(yōu)先級,則 PE 上必須沒有未完成的關(guān)鍵優(yōu)先級調(diào)度。
此外,調(diào)用者應(yīng)了解調(diào)度程序所做的以下假設(shè):
-
API的調(diào)用者是運行在EL3中的組件;例如,RAS 驅(qū)動程序。
-
異常處理框架將允許請求的調(diào)度。即調(diào)用者必須確保請求的調(diào)度具有足夠的優(yōu)先級,以免在異常處理框架內(nèi)引起優(yōu)先級倒置。
-
調(diào)用者必須為 SDEI 調(diào)度程序恢復(fù)非安全上下文做好準備,并將其標記為活動上下文。
-
調(diào)用將阻塞,直到 SDEI 客戶端完成事件(即當客戶端調(diào)用SDEI_EVENT_COMPLETE或時SDEI_COMPLETE_AND_RESUME)。
-
調(diào)用者必須準備好讓這個 API 返回失敗并進行相應(yīng)的處理。
13.7. 移植要求
移植指南中概述了 SDEI 調(diào)度程序的移植要求 。
13.8. 編寫 SDEI 事件處理程序的注意事項?
本節(jié)與一般的 SDEI 事件處理程序有關(guān),而不僅僅是在使用 TF-A SDEI 調(diào)度程序時。
SDEI 規(guī)范要求事件處理程序保留所有寄存器的內(nèi)容,x0除了x17. 如果事件處理程序是用 C 編寫的,這很重要:編譯器通常會在 C 函數(shù)的開頭和結(jié)尾調(diào)整堆棧幀。例如,AArch64 GCC 通常會產(chǎn)生以下函數(shù) prologue 和 epilogue:
c_event_handler:stp x29, x30, [sp,#-32]!mov x29, sp...bl ......ldp x29, x30, [sp],#32ret該寄存器x29在序言中用作幀指針。因為無論是有效的SDEI_EVENT_COMPLETE還是SDEI_EVENT_COMPLETE_AND_RESUME調(diào)用都不會返回到處理程序,結(jié)語永遠不會被執(zhí)行,并且寄存器x29 和x30(在上面的情況下)被無意中破壞了。這違反了 SDEI 規(guī)范,之后的正常執(zhí)行將導(dǎo)致意外行為。
為了解決這個問題,建議頂級事件處理程序在程序集中實現(xiàn),遵循以下類似模式:
asm_event_handler:/* Save link register whilst maintaining stack alignment */stp xzr, x30, [sp, #-16]!bl c_event_handler/* Restore link register */ldp xzr, x30, [sp], #16/* Complete call */ldr x0, =SDEI_EVENT_COMPLETEsmc #0b . 《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的13-SDEI: Software Delegated Exception Interface的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 12- Library at ROM
- 下一篇: 19-Realm Management