5-Interrupt Management Framework
引流關鍵詞: 中斷、同步異常、異步異常、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、安全、內存管理、頁表…
快速鏈接:
.
👉👉👉 個人博客筆記導讀目錄(全部) 👈👈👈
[專欄目錄]-ATF/FF-A/specification學習
5.中斷管理框架
該框架負責管理路由到 EL3 的中斷。它還允許 EL3 軟件配置中斷路由行為。其主要目標是實現以下兩個要求。
(1) 當執行處于非安全狀態(正常世界)時,應該可以將打算由安全軟件(安全中斷)處理的中斷路由到 EL3。然后,框架應負責將中斷控制權交給 EL3 或 Secure-EL1 中的軟件,具體取決于軟件配置和 GIC 實現。此要求確保安全中斷在安全軟件的交付和處理方面處于安全軟件的控制之下,而不會受到非安全軟件的干預。
(2) 當執行在低于 EL3 的安全世界中執行時,應該可以將打算由非安全軟件(非安全中斷)處理的中斷路由到正常世界中最后執行的異常級別。這可以在有或沒有在 Secure-EL1/Secure-EL0 中執行的軟件知識的情況下完成。方法的選擇應由安全軟件控制。此要求確保非安全軟件能夠與安全軟件一起執行而不會覆蓋它。
5.1。概念
5.1.1。中斷類型
根據處理中斷的異常級別,框架將中斷分類為以下之一。
(1) 安全 EL1 中斷。根據當前執行上下文的安全狀態,這種類型的中斷可以路由到 EL3 或 Secure-EL1。它總是在 Secure-EL1 中處理。
(2) 非安全中斷。根據當前執行上下文的安全狀態,這種類型的中斷可以路由到 EL3、Secure-EL1、Non-secure EL1 或 EL2。它總是在非安全 EL1 或 EL2 中處理。
(3) EL3 中斷。根據當前執行上下文的安全狀態,這種類型的中斷可以路由到 EL3 或 Secure-EL1。它總是在 EL3 中處理。
以下常量定義了框架實現中的各種中斷類型。
#define INTR_TYPE_S_EL1 0 #define INTR_TYPE_EL3 1 #define INTR_TYPE_NS 25.1.2. 路由模型
一種類型的中斷可以生成為 FIQ 或 IRQ。中斷類型的目標異常級別通過 EL3 的安全配置寄存器中的 FIQ 和 IRQ 位(SCR_EL3.FIQ和SCR_EL3.IRQ 位)進行配置。當SCR_EL3.FIQ=1 時,FIQ 被路由到 EL3。否則,它們將被路由到能夠處理中斷的第一異常級別 (FEL)。當 SCR_EL3.IRQ=1 時,IRQ 被路由到 EL3。否則,它們將被路由到 FEL。在進入該安全狀態下的較低異常級別之前,該寄存器由 EL3 軟件為每個安全狀態獨立配置。
一種中斷類型(生成為 FIQ 或 IRQ)的路由模型被定義為每個安全狀態的目標異常級別。它由每個安全狀態的單個位表示。值0表示應將中斷路由到 FEL。值1表示中斷應該被路由到 EL3。路由模型僅適用于不在 EL3 中執行的情況。
中斷類型的默認路由模型是將其路由到處于任一安全狀態的 FEL。
5.1.3. 有效的路由模型
該框架認為每種中斷類型的某些路由模型是不正確的,因為它們與第 1 節中提到的要求相沖突。以下小節描述了所有可能的路由模型并指定哪些是有效的或無效的。EL3 中斷當前僅支持 GIC 版本 3.0 (Arm GICv3),僅支持 Secure-EL1 和非安全中斷類型用于 GIC 版本 2.0 (Arm GICv2)(請參閱中斷管理框架中的假設)。以下小節中使用的術語解釋如下。
(1) CSS : Current Security State。當前安全狀態。0何時安全,1何時不安全
(2) TEL3 : Target Exception Level 3。目標異常級別 3。0針對 FEL 時。1當針對 EL3 時。
5.1.3.1。安全 EL1 中斷
-
(1) CSS=0,電話 3=0。當執行處于安全狀態時,中斷被路由到 FEL。這是一個有效的路由模型,因為安全軟件控制著處理安全中斷。
-
(2) CSS=0,電話 3=1。當執行處于安全狀態時,中斷被路由到 EL3。這是一個有效的路由模型,因為 EL3 中的安全軟件可以將中斷移交給 Secure-EL1 進行處理。
-
(3) CSS=1,電話 3=0。當執行處于非安全狀態時,中斷被路由到 FEL。這是一個無效的路由模型,因為安全中斷對安全軟件不可見,這違反了 Arm 安全擴展背后的動機。
-
(4) CSS=1,電話 3=1。當執行處于非安全狀態時,中斷被路由到 EL3。這是一個有效的路由模型,因為 EL3 中的安全軟件可以將中斷移交給 Secure-EL1 進行處理。
5.1.3.2。非安全中斷
-
(1) CSS=0,電話 3=0。當執行處于安全狀態時,中斷被路由到 FEL。這允許安全軟件捕獲非安全中斷,執行其簿記并通過 EL3 將中斷交給非安全軟件。這是一個有效的路由模型,因為安全軟件控制其執行如何被非安全中斷搶占。
-
(2) CSS=0,電話 3=1。當執行處于安全狀態時,中斷被路由到 EL3。這是一個有效的路由模型,因為 EL3 中的安全軟件可以在將中斷交給非安全軟件之前保存 Secure-EL1/Secure-EL0 中的軟件狀態。該模型需要 Secure-EL1 和 EL3 軟件之間的額外協調,以確保前者的狀態被后者正確保存。
-
(3) CSS=1,電話 3=0。當執行處于非安全狀態時,中斷被路由到 FEL。這是一個有效的路由模型,因為非安全中斷由非安全軟件處理。
-
(4) CSS=1,電話 3=1。當執行處于非安全狀態時,中斷被路由到 EL3。這是一個無效的路由模型,因為沒有正當理由將中斷路由到 EL3 軟件,然后將其返回給非安全軟件進行處理。
5.1.3.3。EL3 中斷
-
(1) CSS=0,電話 3=0。在 Secure-EL1/Secure-EL0 中執行時,中斷被路由到 FEL。這是一個有效的路由模型,因為 Secure-EL1/Secure-EL0 中的安全軟件控制其執行如何被 EL3 中斷搶占,并且可以將中斷移交給 EL3 進行處理。
但是,當EL3_EXCEPTION_HANDLING是時1,此路由模型無效,因為 EL3 中斷無條件路由到 EL3,并且 EL3 中斷將始終搶占 Secure EL1/EL0 執行。請參閱異常處理文檔。 -
(2) CSS=0,電話 3=1。在 Secure-EL1/Secure-EL0 中執行時,中斷被路由到 EL3。這是一個有效的路由模型,因為 EL3 中的安全軟件可以處理中斷。
-
(3) - (1) CSS=1,電話 3=0。當執行處于非安全狀態時,中斷被路由到 FEL。這是一個無效的路由模型,因為安全中斷對安全軟件不可見,這違反了 Arm 安全擴展背后的動機。
-
(4) CSS=1,電話 3=1。當執行處于非安全狀態時,中斷被路由到 EL3。這是一個有效的路由模型,因為 EL3 中的安全軟件可以處理中斷。
5.1.4。中斷類型到信號的映射
該框架旨在與平臺實現的任何中斷控制器一起使用。中斷控制器可以根據當前的安全狀態向 CPU 生成一種類型的中斷作為 FIQ 或 IRQ 信號。類型和信號之間的映射只有平臺知道。SCR_EL3框架使用此信息來確定在為某種中斷應用路由模型時是否應該編程 IRQ 或 FIQ 位。平臺通過 API 提供此信息 plat_interrupt_type_to_line()(在 移植指南中描述)。例如,在 FVP 端口上,當平臺使用 Arm GICv2 中斷控制器時,Secure-EL1 中斷通過 FIQ 信號發出,而非安全中斷通過 IRQ 信號發出。這適用于執行處于任一安全狀態時。
5.1.4.1。幾種中斷類型映射到一個信號的效果
需要注意的是,如果多個中斷類型映射到單個中斷信號,并且如果任何一種中斷類型為特定安全狀態設置TEL3=1 ,則在該安全狀態下,中斷信號將被路由到 EL3。這意味著使用相同中斷信號的所有其他中斷類型將被強制使用相同的路由模型。在為中斷類型選擇路由模型時應牢記這一點。
例如,在 Arm GICv3 中,當執行上下文為 Secure-EL1/Secure-EL0 時,EL3 和非安全中斷類型都映射到 FIQ 信號。因此,如果任一中斷類型設置路由模型使得TEL3=1當CSS=0時,FIQ 位SCR_EL3將被編程為在 Secure-EL1/Secure-EL0 中執行時將 FIQ 信號路由到 EL3,從而有效地路由其他中斷類型也到EL3。
5.2. 中斷管理框架中的假設
該框架做出以下假設以簡化其實現。
-
(1) 盡管該框架支持 2 種類型的安全中斷(EL3 和 Secure-EL1 中斷),但只有 Arm GICv3 之類的中斷控制器架構才能以 Group 0 中斷的形式支持 EL3 中斷。在 Arm GICv2 中,假定所有安全中斷都在 Secure-EL1 中處理。它們可以通過 EL3 傳送到 Secure-EL1,但不能在 EL3 中處理。
-
(2) 在 EL3 執行期間,中斷異常(PSTATE.I和位)被屏蔽。F
-
(3) 中斷管理:以下部分描述了中斷處理框架如何管理中斷。這需要:
提供一個接口以允許注冊處理程序和為一種中斷類型指定路由模型。
在生成中斷時實現對中斷類型的手動控制到其注冊處理程序的支持。
中斷管理的兩個方面都涉及從 EL3 到 Secure-EL1 的安全軟件堆棧中的各種組件。這些組件在軟件組件一節中進行了描述。該框架將與每種類型的中斷相關的信息存儲在以下數據結構中。
typedef struct intr_type_desc {interrupt_type_handler_t handler;uint32_t flags;uint32_t scr_el3[2]; } intr_type_desc_t;該flags字段將中斷類型的路由模型存儲在位[1:0] 中。Bit[0] 存儲執行處于安全狀態時的路由模型。當執行處于非安全狀態時,Bit[1] 存儲路由模型。如第Routing model部分所述,值0表示中斷應針對 FEL。值1意味著它應該針對 EL3。其余位為保留位和 SBZ。set_interrupt_rm_flag()應使用 輔助宏來設置flags參數中的位。
該scr_el3[2]字段還存儲路由模型,但作為該字段中的模型到每個安全狀態flags中相應位的映射。SCR_EL3
該框架還依賴于平臺端口來配置中斷控制器以區分安全中斷和非安全中斷。該平臺應了解系統中存在的安全設備及其相關的中斷號。它應該配置中斷控制器以啟用安全中斷,確保它們的優先級始終高于非安全中斷,并將它們定位到主 CPU。它還應該導出移植指南中描述的接口以啟用中斷處理。
在本文檔的其余部分,為簡單起見,考慮了 Arm GICv2 系統,并假設 FIQ 信號用于生成 Secure-EL1 中斷,而 IRQ 信號用于在任一安全狀態下生成非安全中斷. 不考慮 EL3 中斷。
5.3. 軟件組件
中斷管理的角色和職責細分為在 EL3 和 Secure-EL1 中運行的軟件的以下組件。下面簡要介紹每個組件。
-
(1) EL3 運行時固件。該組件對 TF-A 的所有端口都是通用的。
-
(2) 安全有效載荷調度 (SPD) 服務。該服務與在 Secure-EL1/Secure-EL0 中運行并負責在安全和非安全狀態之間切換執行的安全有效負載 (SP) 軟件接口。開關由安全監視器調用觸發,它使用上下文管理庫導出的 API 來實現此功能。在兩種安全狀態之間切換執行也是中斷管理的要求。這導致對 SPD 服務的嚴重依賴。TF-A 實現了一個示例測試安全有效負載調度程序 (TSPD) 服務。
SPD 服務插入到 EL3 運行時固件中,并且可能對 TF-A 的某些端口通用。 -
(3) 安全有效載荷 (SP)。在生產系統上,安全有效負載對應于運行在 Secure-EL1/Secure-EL0 中的安全操作系統。它與 SPD 服務接口以管理與非安全軟件的通信。TF-A 實現了一個名為 Test Secure Payload (TSP) 的示例安全有效負載,它僅在 Secure-EL1 中運行。
安全有效負載實現對于 TF-A 的某些端口可能是通用的,就像 SPD 服務一樣。
5.4. 中斷注冊
本節詳細描述了在 為中斷類型注冊處理程序期間每個軟件組件(請參閱軟件組件)的作用。
5.4.1。EL3 運行時固件
該組件為中斷類型的處理程序聲明了以下原型。
typedef uint64_t (*interrupt_type_handler_t)(uint32_t id,uint32_t flags,void *handle,void *cookie);is 參數是保留的id,只有在存在確定 id 的萬無一失的方法時,才能在將來用于傳遞最高掛起中斷的中斷 id。目前它包含INTR_ID_UNAVAILABLE.
該flags參數包含如下雜項信息。
-
(1) 安全狀態,位 [0]。該位指示產生中斷時較低異常級別的安全狀態。值1表示它處于非安全狀態。值0表示它處于安全狀態。處理程序可以使用該位來確保根據注冊期間指定的路由模型生成和路由中斷。
-
(2) 保留,位 [31:1]。其余位保留供將來使用。
該handle參數指向參數中cpu_context指定的安全狀態的當前 CPU 的結構flags。
一旦處理程序例程完成,執行將返回到安全或非安全狀態。處理程序例程必須為目標安全狀態返回一個指向 cpu_context當前 CPU 結構的指針。在 AArch64 上,調用者當前忽略此返回值,因為cpu_context預期將由處理程序通過上下文管理庫 API 設置要使用的適當值??梢浦驳闹袛嗵幚沓绦驅崿F必須在返回指針指向的結構中以及通過上下文管理庫 API 設置目標上下文。處理程序應將所有錯誤條件視為嚴重錯誤,并在其實現中采取適當的措施,例如使用斷言失敗。
運行時固件提供以下 API,用于為特定類型的中斷注冊處理程序。Secure Payload Dispatcher 服務應使用此 API 為 Secure-EL1 注冊一個處理程序,并可選擇為非安全中斷注冊一個處理程序。此 API 還要求調用者指定中斷類型的路由模型。
int32_t register_interrupt_type_handler(uint32_t type,interrupt_type_handler handler,uint64_t flags);該type參數可以是上面列出的三種中斷類型之一, INTR_TYPE_S_EL1即INTR_TYPE_NS& INTR_TYPE_EL3。該flags參數如第 2 節所述。
該函數將0在成功注冊后返回。-EALREADY如果已注冊中斷類型的處理程序,它將返回 。如果type無法識別或flags或handler無效,它將返回-EINVAL。
中斷路由由在SCR_EL3.FIQ/IRQ任一安全狀態下進入較低異常級別之前的位配置控制。上下文管理庫為每個 CPU 結構中的每個安全狀態維護SCR_EL3系統寄存器的副本。cpu_context它導出以下 API 以讓 EL3 運行時固件編程并檢索當前 CPU 的每個安全狀態的路由模型。函數使用SCR_EL3存儲在 中的值在從 EL3 異常級別返回之前對寄存器進行編程 。cpu_contextel3_exit()SCR_EL3
uint32_t cm_get_scr_el3(uint32_t security_state); void cm_write_scr_el3_bit(uint32_t security_state,uint32_t bit_pos,uint32_t value);cm_get_scr_el3()返回SCR_EL3當前 CPU 的指定安全狀態的寄存器值。cm_write_scr_el3_bit()將0或寫入1 指定的位bit_pos。register_interrupt_type_handler()調用 API,該 API根據使用和API 的路由模型進行set_routing_model()編程。SCR_EL3cm_get_scr_el3()cm_write_scr_el3_bit()
值得注意的是,在當前框架的實現中,EL3 運行時固件負責對路由模型進行編程。SPD 負責確保在收到中斷時遵循路由模型。
5.4.2. 安全有效負載調度程序?
SPD 服務負責確定和維護自身支持的中斷路由模型和 Secure Payload。它還負責根據路由模型在安全和非安全軟件之間傳送中斷。它可以在構建時或運行時確定路由模型。它必須使用此信息使用register_interrupt_type_handler()EL3 運行時固件中的 API 為每種中斷類型注冊處理程序。
如果 SPD 服務在構建時不知道路由模型,則它必須由 SP 作為其初始化的結果提供。只有在 SP 初始化完成后,SPD 才應該對路由模型進行編程,例如在變量指向的 SPD 初始化函數中bl32_init。
SPD 應確定在接收到來自 EL3 運行時固件的中斷后將控制權傳遞給安全有效負載的機制。此信息可以在構建時提供給 SPD 服務,也可以由 SP 在運行時提供。
5.4.3. 測試安全有效負載調度程序行為?
注意: 在本文檔討論TSP_NS_INTR_ASYNC_PREEMPT的情況下 1,相同的結果也適用于當EL3_EXCEPTION_HANDLING是1。
TSPD 僅處理 Secure-EL1 中斷,并在構建時提供以下路由模型。
-
Secure-EL1 中斷在執行處于非安全狀態時路由到 EL3,并且在執行處于安全狀態時路由到 FEL,即CSS=0、TEL3=0和CSS=1、TEL3=1用于 Secure-EL1 中斷
-
當構建標志TSP_NS_INTR_ASYNC_PREEMPT為零時,默認路由模型用于非安全中斷。它們以任一安全狀態(即CSS=0、TEL3=0和CSS=1、TEL3=0用于非安全中斷)被路由到 FEL。
-
當構建標志TSP_NS_INTR_ASYNC_PREEMPT定義為 1 時,當執行處于安全狀態時,非安全中斷被路由到 EL3,即CSS=0,對于非安全中斷,TEL3=1。這有效地搶占了 Secure-EL1。默認路由模型用于非安全狀態下的非安全中斷。即CSS=1, TEL3=0。
它在函數中執行以下操作tspd_init()來滿足前面提到的要求:
(1) 它將控制權傳遞給測試安全有效負載以執行其初始化。TSP 在 SP 中提供向量表的地址, tsp_vectors其中還包括sel1_intr_entry字段中 Secure-EL1 中斷的處理程序。當 TSPD 接收到 Secure-EL1 中斷時,它會將控制權傳遞給位于該地址的 TSP。
TSP 和 TSPD 之間的切換協議要求 TSPDPSTATE.DAIF在調用時屏蔽所有中斷(位) tsp_sel1_intr_entry()。TSP 必須保留被調用方保存的通用、SP_EL1/Secure-EL0、LR、VFP 和系統寄存器。它可以 x0-x18用來啟用其 C 運行時。
(2) TSPD 實現了 Secure-EL1 中斷的處理函數。該函數使用 API 注冊到 EL3 運行時固件 register_interrupt_type_handler(),如下所示
/* Forward declaration */ interrupt_type_handler tspd_secure_el1_interrupt_handler; int32_t rc, flags = 0; set_interrupt_rm_flag(flags, NON_SECURE); rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,tspd_secure_el1_interrupt_handler,flags); if (rc)panic();(3) 當構建標志TSP_NS_INTR_ASYNC_PREEMPT定義為 1 時,TSPD 為非安全中斷實現處理函數。該函數使用 API 注冊到 EL3 運行時固件 register_interrupt_type_handler(),如下所示
/* Forward declaration */ interrupt_type_handler tspd_ns_interrupt_handler; int32_t rc, flags = 0; set_interrupt_rm_flag(flags, SECURE); rc = register_interrupt_type_handler(INTR_TYPE_NS,tspd_ns_interrupt_handler,flags); if (rc)panic();5.4.4。安全有效載荷
安全有效負載必須在 Secure-EL1 (Secure-EL1 IHF) 上實現中斷處理框架,以支持其選擇的中斷路由模型。安全有效負載執行將在以下情況之間交替。
-
(1) 在啟用了 IRQ、FIQ 或兩者的中斷的代碼中,如果一個中斷類型針對 FEL,那么它將被路由到 Secure-EL1 異常向量表。這被定義為處理中斷的異步模式。此模式適用于 Secure-EL1 和非安全中斷。
-
(2) 在兩個中斷都被禁用的代碼中,如果一個中斷類型以 FEL 為目標,那么執行最終將遷移到非安全狀態。任何非安全中斷都將按照CSS=1 和 TEL3=0的路由模型中的描述進行處理。Secure-EL1 中斷將被路由到 EL3(根據CSS=1 和 TEL3=1的路由模型),SPD 服務會將它們交給 SP。這被定義為處理中斷的同步模式。
SP 實現的中斷處理框架應支持這些中斷處理模型中的一種或兩種,具體取決于所選的路由模型。
以下列表簡要描述了有效路由模型的選擇(請參閱有效路由模型)如何影響 Secure-EL1 IHF 的實現。如果在編譯時 SPD 服務不知道中斷路由模型的選擇,那么 SP 應該在運行時在其初始化階段將此信息傳遞給 SPD 服務。
如前所述,考慮了一個 Arm GICv2 系統,并假設 FIQ 信號用于生成 Secure-EL1 中斷,而 IRQ 信號用于在任一安全狀態下生成非安全中斷。
5.4.4.1。安全有效載荷 IHF 設計 wrt 安全 EL1 中斷?
-
(1) CSS=0,電話 3=0。如果PSTATE.F=0,Secure-EL1 中斷將在 Secure-EL1 FIQ 異常向量之一處觸發。Secure-EL1 IHF 應該支持異步處理 FIQ 中斷。
如果PSTATE.F=1那么 Secure-EL1 中斷將按照同步中斷處理模型進行處理。SP 可以通過在注冊階段將 Secure-EL1 中斷的單獨入口點導出到 SPD 服務來實現此場景。SPD 服務還需要知道系統的狀態、通用目的以及PSTATE它應該安排將執行返回給 SP 的寄存器。如果 SPD 服務在構建時不知道該信息,則 SP 應在注冊階段以實現定義的方式提供此信息。 -
(2) CSS=1,電話 3=1。當執行處于非安全狀態時,中斷被路由到 EL3。它們應該通過上面 1. 中描述的同步中斷處理模型來處理。
-
(3) CSS=0,電話 3=1。當執行處于安全狀態時,Secure-EL1 中斷被路由到 EL3。SP 將看不到它們。Secure-EL1/Secure-EL0 中的PSTATE.F位不會屏蔽 FIQ。EL3 運行時固件將調用 SPD 服務為 Secure-EL1 中斷注冊的處理程序。然后,Secure-EL1 IHF 應該通過上面 1. 中描述的同步中斷處理模型來處理所有 Secure-EL1 中斷。
5.4.4.2。安全有效載荷 IHF 設計 wrt 非安全中斷
-
(1) CSS=0,電話 3=0。如果PSTATE.I=0,將在 Secure-EL1 IRQ 異常向量之一處觸發非安全中斷。Secure-EL1 IHF 應與 SPD 服務協調以將執行轉移到應處理中斷的非安全狀態,例如,SP 可以分配一個功能標識符以向 SPD 服務發出 SMC64 或 SMC32,這表明SP 執行已被非安全中斷搶占。如果 SPD 服務在編譯時不知道這個函數標識符,那么 SP 可以在注冊階段提供它。
如果PSTATE.I=1然后非安全中斷將掛起,直到在非安全狀態下恢復執行。 -
(2) CSS=0,電話 3=1。非安全中斷被路由到 EL3。SP 將看不到它們。Secure-EL1/Secure-EL0 中的PSTATE.I位無效。SPD 服務應注冊一個非安全中斷處理程序,該處理程序應正確保存 SP 狀態并在將處理中斷的非安全狀態下恢復執行。Secure-EL1 IHF 不需要采取任何行動。
-
(3) CSS=1,電話 3=0。非安全中斷在非安全狀態 (EL1/EL2) 的 FEL 中處理,并且對 SP 不可見。此路由模型不影響 SP 行為。
Secure Payload 還必須確保所有 Secure-EL1 中斷都通過 EL3 運行時固件的平臺端口在中斷控制器上正確配置。它應該配置 EL3 運行時固件通過其平臺端口不知道的任何其他 Secure-EL1 中斷。
5.4.5。測試安全有效負載行為
TSP 選擇的 Secure-EL1 和非安全中斷的路由模型在部分Secure Payload Dispatcher中進行了描述。它在構建時為 TSPD 服務所知。
tsp_sel1_intr_entry()TSP實現了一個入口點(它將對該入口點的引用傳遞 tsp_vectors給 TSPD 服務。
TSP 還將通過變量引用的默認異常向量表替換為 early_exceptions能夠處理在相同 (Secure-EL1) 異常級別采取的 FIQ 和 IRQ 異常的向量表。該表通過tsp_exceptions變量引用并編程到 VBAR_EL1。它迎合異步處理模型。
TSP 還對 Arm Generic Timer 塊中的安全物理定時器進行編程,以引發周期性中斷(每半秒一次),以測試軟件組件中列出的所有軟件組件的中斷管理。
5.5. 中斷處理?
本節詳細描述了每個軟件組件(請參閱軟件組件一節)在處理特定類型的中斷中的作用。
5.5.1。EL3 運行時固件?
EL3 運行時固件填充變量引用的 IRQ 和 FIQ 異常向量runtime_exceptions,如下所示。
-
(1) 從當前異常級別獲取的 IRQ 和 FIQ 異常具有 SP_EL0或被SP_EL3報告為不可恢復的錯誤條件。如前所述,EL3 運行時固件總是在 設置PSTATE.I和PSTATE.F位的情況下執行。
-
(2) 以下文本描述了如何處理使用 AArch64 或 AArch32 從較低異常級別獲取的 IRQ 和 FIQ 異常。
產生中斷時,每種中斷類型的向量負責:
-
(1) 進入異常后立即保存整個通用寄存器上下文 (x0-x30)。寄存器保存在寄存器cpu_context 引用的 per-cpu 數據結構中SP_EL3。
-
(2) ELR_EL3將,SP_EL0和system 寄存器保存在寄存器引用SPSR_EL3的 per-cpu數據結構中。cpu_contextSP_EL3
-
(3) CTX_RUNTIME_SP通過從 per-cpucpu_context數據結構中恢復值SP_EL0并執行指令來切換到 C 運行時堆棧。msr spsel, #0
-
(4) 確定中斷的類型。Secure-EL1 中斷將在 FIQ 向量處發出信號。非安全中斷將在 IRQ 向量處發出信號。平臺應實現以下 API 來確定掛起中斷的類型。
它應該返回INTR_TYPE_S_EL1或INTR_TYPE_NS。
- (5) 確定已生成中斷類型的處理程序。為此目的添加了以下 API。
它返回對該中斷類型的已注冊處理程序的引用。從第2 節中描述handler的結構中檢索。如果沒有為這種類型的中斷注冊處理程序,則返回。這種情況被報告為不可恢復的錯誤情況。intr_type_desc_tNULL
- (6) 為生成的中斷類型調用注冊的處理函數。該id參數設置為INTR_ID_UNAVAILABLE當前。id 連同當前安全狀態和對當前安全狀態cpu_context_t 結構的引用作為參數傳遞給處理函數。
處理函數返回cpu_context_t 對目標安全狀態的 per-cpu 結構的引用。
- (7) 調用el3_exit()以從 EL3 返回到由處理程序例程確定的安全狀態中的較低異常級別。該el3_exit() 函數負責從 cpu_context_t目標安全狀態的數據結構中恢復寄存器上下文。
5.5.2. 安全有效負載調度程序
5.5.2.1。中斷入口
當 EL3 運行時固件為該類型的中斷調用處理函數時,SPD 服務開始處理該中斷。SPD 服務負責以下工作:
- (1) 驗證中斷。這涉及確保根據注冊期間 SPD 服務指定的中斷路由模型生成中斷。flags它應該使用中斷被從中獲取的異常級別的安全狀態(在處理程序的參數中傳遞)來確定這一點。如果中斷未被識別,則處理程序應將其視為不可恢復的錯誤條件。
SPD 服務可以為 Secure-EL1 和/或非安全中斷注冊處理程序。非安全中斷不應該從非安全狀態路由到 EL3。此外,如果選擇了在執行處于安全狀態時將 Secure-EL1 中斷路由到 S-EL1 的路由模型,則永遠不應將 S-EL1 中斷從安全狀態路由到 EL3。處理程序可以使用安全狀態標志來檢查這一點。
- (2) 確定是否需要上下文切換。這取決于路由模型和中斷類型。對于非安全和 S-EL1 中斷,如果產生中斷的執行上下文的安全狀態與處理中斷所需的安全狀態不同,則需要進行上下文切換。以下 2 種情況需要從安全到非安全的上下文切換,反之亦然:
– 從非安全狀態獲取的 Secure-EL1 中斷應路由到安全有效負載。
– 從安全狀態獲取的非安全中斷應路由到最后一個已知的非安全異常級別。
SPD 服務必須保存當前安全狀態的系統寄存器上下文。然后它必須恢復目標安全狀態的系統寄存器上下文。它應該使用cm_set_next_eret_context()API 來確保下一個cpu_context要恢復的是目標安全狀態。
如果目標狀態是安全的,則應根據其實現的同步中斷處理模型將執行交給 SP。在 SP 中執行時,可以將 Secure-EL1 中斷路由到 EL3。這意味著在處理另一個更高優先級的 Secure-EL1 中斷或 EL3 中斷的中斷時,可以搶占 SP 執行。在將控制權交給 SP 之前,SPD 服務應該能夠處理這種搶占或管理安全中斷優先級。
- (3) cpu_context如果中斷已成功驗證并準備好在較低的異常級別處理,則將處理程序的返回值設置為 per-cpu 。
路由模型允許非安全中斷在安全狀態下中斷 Secure-EL1(如果已配置為這樣做)。SPD 服務和 SP 應該實現一種機制,將這些中斷路由到非安全狀態下的最后一個已知異常級別。前者要保存SP上下文,恢復非安全上下文,安排進入非安全狀態,以便處理中斷。
5.5.2.2。中斷出口?
當 Secure Payload 處理完 Secure-EL1 中斷后,它可以通過 SMC32 或 SMC64 將控制權返回給 SPD 服務。SPD 服務應處理此安全監視器調用,以便在異常級別和最初獲取 Secure-EL1 中斷的安全狀態中恢復執行。
5.5.2.3。測試安全有效負載調度程序 Secure-EL1 中斷處理?
示例 TSPD 服務為從非安全狀態獲取的 Secure-EL1 中斷注冊處理程序。在 S-EL1 中執行期間,TSPD 期望 Secure-EL1 中斷由 TSP 在 S-EL1 中處理。它的處理程序 tspd_secure_el1_interrupt_handler()只希望為源自非安全狀態的 Secure-EL1 調用。它在被調用時執行以下操作。
-
(1) 它使用flags參數中提供的安全狀態來確保安全中斷源自非安全狀態。它斷言如果不是這種情況。
-
(2) 它通過調用保存非安全狀態的系統寄存器上下文 cm_el1_sysregs_context_save(NON_SECURE);。
-
(3) 它將ELR_EL3系統寄存器設置為tsp_sel1_intr_entry并設置 SPSR_EL3.DAIF安全 CPU 上下文中的位。它設置x0為 TSP_HANDLE_SEL1_INTR_AND_RETURN。如果 TSP 在 SMC 處理期間被非安全中斷提前搶占yielding,請保存將被丟棄的寄存器,即ELR_EL3和SPSR_EL3,以便能夠重新進入 TSP 以進行 Secure-EL1 中斷處理。它不需要保存任何其他安全上下文,因為預計 TSP 會保留它(請參閱測試安全有效負載調度程序行為部分)。
-
(4) 它通過調用來恢復安全狀態的系統寄存器上下文 cm_el1_sysregs_context_restore(SECURE);。
-
(5) 它確保安全的 CPU 上下文用于通過調用cm_set_next_eret_context(SECURE);.
-
(6) 它返回 per-cpucpu_context以指示中斷現在可以由 SP 處理。x1寫入elr_el3 非安全狀態的寄存器值。SP 使用此信息進行調試。
下圖描述了在執行處于非安全狀態時產生 Secure-EL1 中斷時 TSPD 如何實現中斷處理。
TSP 發出一個帶有TSP_HANDLED_S_EL1_INTR函數標識符的 SMC,以表示中斷處理的完成。
tspd_smc_handler()TSPD 服務在接收到具有TSP_HANDLED_S_EL1_INTR作為功能標識符的 SMC 時在功能中采取以下操作:
-
(1) 它確保調用源自安全狀態,否則執行返回到SMC_UNKin的非安全狀態x0。
-
(2) 如果 TSP 早先被非安全中斷搶占,它將保存的ELR_EL3和系統寄存器恢復到安全 CPU 上下文(參見上面的步驟 3)。SPSR_EL3
-
(3) 它通過調用恢復非安全狀態的系統寄存器上下文cm_el1_sysregs_context_restore(NON_SECURE)。
-
(4) 它確保使用非安全 CPU 上下文通過調用cm_set_next_eret_context(NON_SECURE).
-
(5) tspd_smc_handler()返回對非安全的引用cpu_context 作為返回值。
5.5.2.4。測試安全有效負載調度程序非安全中斷處理
Secure-EL1 中的 TSP 可以在 SMC 處理期間被非安全中斷搶占, yielding或者在 Secure-EL1 中斷處理期間被更高優先級的 EL3 中斷搶占。當EL3_EXCEPTION_HANDLING是時0,只有非安全中斷會導致 TSP 搶占,因為系統中沒有 EL3 中斷。EL3_EXCEPTION_HANDLING=1然而,任何 EL3 中斷都可能搶占安全執行。
應該注意的是,當 TSP 被搶占時,TSPD 僅允許進入 TSP 以進行 Secure-EL1 中斷處理或恢復被搶占的 yieldingSMC 以響應TSP_FID_RESUME來自正常世界的 SMC。(請參閱搶占 SMC 對非安全軟件的影響一節)。
在 SMC 處理期間在 Secure-EL1 中觸發的非安全中斷yielding可以路由到 EL3 或 Secure-EL1,并由構建選項控制TSP_NS_INTR_ASYNC_PREEMPT(請參閱測試安全負載調度程序行為一節)。如果設置了構建選項,TSPD 將為非安全中斷設置路由模型,使其從安全狀態(即TEL3=1,CSS=0)路由到 EL3,并注冊tspd_ns_interrupt_handler()為非安全中斷處理程序。被調用的tspd_ns_interrupt_handler()on 確保中斷源自安全狀態,并禁用非安全中斷從安全狀態到 EL3 的路由。這是為了防止在重新進入 TSP 以處理在正常環境中執行時觸發的 Secure-EL1 中斷時進一步搶占(通過非安全中斷)。這tspd_ns_interrupt_handler()然后調用 tspd_handle_sp_preemption()以進行進一步處理。
如果TSP_NS_INTR_ASYNC_PREEMPT構建選項為零(默認),則安全狀態下非安全中斷的默認路由模型生效,即TEL3=0, CSS=0。在yieldingSMC 處理期間,IRQ 異常未被屏蔽PSTATE.I=0,即在 Secure-EL1 IRQ 異常向量處將觸發非安全中斷。TSP 保存通用寄存器上下文并發出一個 SMCTSP_PREEMPTED作為功能標識符,以表示 TSP 的搶占。TSPD SMC 處理程序 tspd_smc_handler()確保 SMC 調用源自安全狀態,否則執行返回到非安全狀態 SMC_UNKin x0。然后它調用tspd_handle_sp_preemption()以進行進一步處理。
tspd_handle_sp_preemption()被調用時會執行以下操作:
-
(1) 它通過調用來保存安全狀態的系統寄存器上下文 cm_el1_sysregs_context_save(SECURE)。
-
(2) 它通過調用恢復非安全狀態的系統寄存器上下文cm_el1_sysregs_context_restore(NON_SECURE)。
-
(3) 它確保使用非安全 CPU 上下文通過調用cm_set_next_eret_context(NON_SECURE).
-
(4) SMC_PREEMPTED設置為 x0 并在恢復非安全上下文后返回非安全狀態。
yieldingNormal World 有望在SMC 搶占后通過發布一個 SMCTSP_FID_RESUME作為功能標識符來恢復 TSP (請參閱搶占 SMC 對非安全軟件的影響一節)。tspd_smc_handler()TSPD 服務在收到此 SMC 后在功能上采取以下行動:
-
(1) 它確保呼叫源自非安全狀態。否則會引發斷言。
-
(2) 檢查 TSP 是否需要恢復,即檢查它是否被搶占。然后它通過調用保存非安全狀態的系統寄存器上下文 cm_el1_sysregs_context_save(NON_SECURE)。
-
(3) 通過調用恢復安全上下文 cm_el1_sysregs_context_restore(SECURE)
-
(4) 它確保安全的 CPU 上下文用于通過調用cm_set_next_eret_context(SECURE).
-
(5) tspd_smc_handler()返回對安全的引用cpu_context作為返回值。
下圖描述了當構建標志為 0時在 TSP with PSTATE.I= 0 中執行期間生成的非安全中斷時,TSP/TSPD 如何處理該中斷。TSP_NS_INTR_ASYNC_PREEMPT
5.5.3. 安全有效負載中斷處理
SP 應該實現同步和異步中斷處理模型中的一種或兩種,具體取決于它選擇的中斷路由模型(如安全有效負載部分所述)。
在同步模型中,它應該在從構建時間或注冊階段商定的入口點接收來自 SPD 服務的控制后開始處理 Secure-EL1 中斷。在處理中斷之前,SP 應該保存任何 Secure-EL1 系統寄存器上下文,以便稍后在 SP 中恢復正常執行,SPSR_EL1例如ELR_EL1. 處理完中斷后,SP 可以將控制權返回到最初獲取中斷的異常級別和安全狀態。SP 應使用 SMC32 或 SMC64 請求 SPD 服務執行此操作。
PSTATE.I在異步模型中,當和位為 0時,Secure Payload 負責在其異常向量表中的 IRQ 和 FIQ 向量處處理非安全和 Secure-EL1 中斷。PSTATE.F如前所述,當生成非安全中斷時, SP 應與 SPD 服務協調,以將控制權傳遞回最后一個已知異常級別的非安全狀態。這將允許在非安全狀態下處理非安全中斷。
5.5.3.1。測試安全有效負載行為?
TSPD 將 Secure-EL1 中斷的控制權交給 TSP 在 tsp_sel1_intr_entry(). TSP 處理中斷,同時確保保持部分測試安全負載調度程序行為中描述的切換協議。它通過調用來更新一些統計信息 tsp_update_sync_sel1_intr_stats()。然后它調用 tsp_common_int_handler()which。
-
(1) 檢查中斷是否為安全物理定時器中斷。它使用平臺 APIplat_ic_get_pending_interrupt_id()來獲取中斷號。如果它不是安全物理定時器中斷,則意味著更高優先級的中斷已經搶占了它。通過發出具有作為功能標識符的 SMC 來調用 tsp_handle_preemption()將控制權移交回 EL3 。TSP_PREEMPTED
-
(2) 通過使用平臺 API 確認安全定時器中斷中斷 plat_ic_acknowledge_interrupt()、調用 tsp_generic_timer_handler()以重新編程安全物理通用定時器并調用plat_ic_end_of_interrupt()平臺 API 以發出中斷處理結束的信號來處理安全定時器中斷中斷。
TSP 通過發出 SMC64 TSP_HANDLED_S_EL1_INTR作為功能標識符將控制權交還給 TSPD。
TSP 處理異步模型下的中斷如下。
-
(1) Secure-EL1 中斷通過調用該tsp_common_int_handler() 函數來處理。該功能已在上面進行了描述。
-
(2) 通過調用函數來處理非安全中斷,該tsp_common_int_handler() 函數最終調用tsp_handle_preemption()并發出 SMC64TSP_PREEMPTED作為函數標識符。當 TSPD 將控制權交給 TSP 以響應具有TSP_FID_RESUME非安全狀態的功能標識符的 SMC 時,執行在此 SMC 指令之后的指令處恢復執行(請參閱測試安全有效載荷調度程序非安全中斷處理部分)。
5.6. 其他注意事項
5.6.1。搶占 SMC 對非安全軟件的影響
對安全有效負載的yieldingSMC 調用可以被非安全中斷搶占,并且執行可以返回到非安全世界以處理中斷(有關yieldingSMC 的詳細信息,請參閱SMC 調用約定)。在這種情況下,SMC 調用尚未完成其執行,執行必須返回到安全有效負載以恢復被搶占的 SMC 調用。這可以通過發出指示恢復被搶占的 SMC 的 SMC 調用來實現。
fastSMC 不能被搶占,因此這種情況不會發生在快速 SMC 調用中。
在 Test Secure Payload 實現中,TSP_FID_RESUME被指定為恢復 SMC FID。重要的是要注意這TSP_FID_RESUME是一個 yieldingSMC,這意味著它也可以被搶占。發布yieldingSMC 的典型非安全軟件序列如下所示,假設P.STATE.I=0處于非安全狀態:
int rc; rc = smc(TSP_YIELD_SMC_FID, ...); /* Issue a Yielding SMC call */ /* The pending non-secure interrupt is handled by the interrupt handlerand returns back here. */ while (rc == SMC_PREEMPTED) { /* Check if the SMC call is preempted */rc = smc(TSP_FID_RESUME); /* Issue resume SMC call */ }是TSP_YIELD_SMC_FID任何yieldingSMC 函數標識符,并且 smc() 函數調用帶有所需參數的 SMC 調用。掛起的非安全中斷導致 IRQ 異常,注冊在異常向量中的 IRQ 處理程序處理非安全中斷并返回。測試來自 SMC 調用的返回值SMC_PREEMPTED以檢查它是否被搶占。如果是,則TSP_FID_RESUME發出恢復 SMC 調用。再次測試 SMC 調用的返回值,檢查是否被搶占。這是在循環中完成的,直到 SMC 調用成功或失敗。如果yielding SMC 被搶占,在使用 SMC 恢復并完成之前,當前 TSPD 通過返回錯誤TSP_FID_RESUME來防止任何其他 SMC 調用重新進入 TSP
總結
以上是生活随笔為你收集整理的5-Interrupt Management Framework的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 4.11-固件映像包 (FIP)
- 下一篇: 6-PSCI Power Domain