《Cortex™-A系列編程者指南(V3.0)》第13章筆記


  在本章,我們會看看ARM處理器處理中斷的一系列方法,簡單地看看通用中斷控制器(Generic Interrupt Controller,GIC)架構


  舊版本的ARM架構允許實現者在他們的外部中斷控制器設計中相當大的自由,沒有關於中斷類型或數量,或者是被用於中斷控制模塊接口的軟件模型的協議。GIC架構提供一個更爲嚴格的控制規範,使得來自不同製造商之間的中斷控制器之間有更高程度的一致性。這使得中斷處理代碼變得更加可移植。


13.1 外部中斷請求


  如我們在第12章的異常類型中討論的,所有的ARM處理器有兩種外部中斷請求,FIQ和IRQ。它們都是電平敏感低電平有效的輸入。個別實現具有中斷控制器,接受來自多種外部源的中斷請求,並把映射到FIQ或IRQ上,引起處理器獲取一個異常。


  總的來說,中斷異常僅在合適的CPSR位(分別是F和I位)清除時才能被獲取


  CPS彙編語言指令提供一種簡單的機制來使能或禁止由CPSR A,I和F位(分別是異步中止,IRQ和FIQ)控制的異常。另外,CPS可以被用於修改模式,如下所示。

CPS #<mode>
CPSIE <if>
CPSID <if>
  <mode>是要修改的模式號碼。如果這個選項被忽略,不會發生模式切換。這些模式的值在表4-1中所列。


  IE或ID會分別使能或禁止異常。使用一個或多個字母A,I和F指定異常的使能或禁止。相應字母被忽略的異常不會被修改。


  在Cortex-A系列處理器中,配置處理器從而使FIQ不會被軟件屏蔽是可能的。這被稱爲不可屏蔽FIQ,由硬件配置輸入信號控制,在處理器復位時被採樣。它們在獲取到FIQ異常時仍然會自動被屏蔽。


13.1.1 分配中斷


  一個系統總是會有一箇中斷控制器,它接收來自多個外部硬件的中斷請求。這通常包含一些寄存器來使能運行在ARM處理器上的軟件來屏蔽個別中斷源,應答來自外部設備的中斷和確定當前激活的中斷源。


  中斷控制器可以是特定於系統的,或它也可以是ARM通用中斷控制器(GIC)架構的實現,這會在接下來的13.2節的通用中斷控制器中講述。

13.1.2 最簡單的中斷處理


  這表示最簡單的那種中斷處理。一箇中斷產生並且在處理那個中斷時,後續中算被禁止。我們只能在第一個中斷請求完成時處理後續中斷,在此期間沒有一個更高優先級或更加緊急的中斷需要被處理。這通常對於嵌入式系統來說是不合適的,但在繼續一個更爲真實的例子之前是非常有用的。


  處理一箇中斷的步驟如下:

a. 外部硬件引發了一個IRQ異常。處理器自動執行幾個步驟。當前模式PC的內容被存放在LR_IRQ。CPSR寄存器被拷貝到SPSR_IRQ。CPSR的底部字節被更新以切換到IRQ模式,並且禁止IRQ,阻止後續異常發生。PC設置到向量表中的IRQ入口。

b. 向量表中IRQ入口的指令(跳轉到中斷處理的分支)被執行。

c. 中斷處理程序保存被中斷程序的上下文(就是,它壓入會被中斷處理函數損壞的任何寄存器到堆棧)。

d. 中斷處理程序決定需要處理的中斷源,調用合適的設備驅動。

e. 最後,SPSR_IRQ被拷回CPSR,切換系統回先前執行的模式。同時,PC從LR_IRQ恢復。


13.1.3 嵌套的中斷處理


  在嵌套的中斷處理中,我們在中斷處理被完全服務完之前重行使能中斷。這允許我們優先化中斷,以增加額外的複雜性爲代價極大縮短高優先級事件的延遲。


  一個可重入中斷處理程序在中斷使能,跳轉到嵌套子程序或C函數之前必須保存IRQ狀態,切換處理器模式,爲新的處理器模式保存狀態。這是因爲新的中斷可能在任何事件發生,這會引起處理器存儲新中斷的返回地址到LR_IRQ,覆蓋原來的中斷。當原來的中斷試圖返回主程序,它會引起系統失敗。嵌套的中斷處理程序必須在重新使能中斷之前改變到另外一個內核模式,以防止此類情況發生。


<注意>
  一個程序是可重入的,如果它可以在它執行中被中斷,然後在先前版本完成之前被再次調用。


  因此,一個可重入中斷處理程序必須在一個IRQ異常被引發並且控制被傳遞到按照先前描述的中斷處理程序之後,採取下列步驟

a. 中斷處理程序保存被中斷程序的上下文(那就是,它壓入任何會被處理函數毀壞的寄存器到替代內核模式的堆棧,包括返回地址和SPSR_IRQ)。

b. 它確定需要被處理的中斷源,清除外部硬件中的中斷源(防止它立即觸發另一箇中斷)。

c. 中斷處理函數修改處理器SVC模式,CPSR I位被設置(中斷仍然被禁止)。

d. 中斷處理程序保存異常返回地址到堆棧(爲新模式的堆棧,位於內核存儲區),並且重新使能中斷。

e. 調用合適的設備驅動。

f. 在完成時,中斷處理程序禁止IRQ,從堆棧獲取異常返回地址。

g. 從替代內核模式的堆棧恢復被中斷程序的上下文。這包括恢復PC,CPSR切換到先前執行的模式。如果SPSR的I位沒有置位,重新使能中斷。


13.2 通用中斷控制器


  GIC架構定義了一個通用中斷控制器(Generic Interrupt Controller, GIC),它由單核或多核系統中爲管理中斷的硬件資源集組成。GIC提供內存映射寄存器,它可用於管理中斷源和行爲,並且(在多核系統中)路由中斷到單獨的處理器。它使得軟件能夠屏蔽、使能和禁止來自獨立源的中斷,優先化(硬件上)單個源的中斷,生成軟件中斷。它也爲信任區安全擴展提供支持,如第26章安全中所描述。GIC接受系統級聲明的中斷,並且可以將它們傳遞到它所連接到每個處理器,潛在地導致一個IRQ或FIQ異常被引發。


  從軟件角度,一個GIC有兩個主要的功能模塊:

<分配器>

在多核系統中的所有處理器之間被分享。被用於配置例如優先級、路由等事情,也用於提供全局使能或禁止單箇中斷。

<CPU接口>

每個處理器處理中斷的私有通道。這是你發現已被觸發的中斷,通知當你已完成處理一箇中斷。


  每個中斷可以被認爲處於四個狀態之一:
 > 未激活
 > 掛起 --- 這意味着中斷源已經聲明,但是等待被處理器處理
 > 激活 --- 這描述一個已被處理器承認的中斷,並且當前正在服務
 > 激活並掛起--- 這描述的情形爲,處理器正在處理終端,GIC從相同的源有一個掛起的中斷


  中斷可以是很多不同的類型:

軟件生成的中斷(Software Generated Interrupt, SGI)

  這通過寫一個專用寄存器生成,軟件生成中斷寄存器(Software Generated Interrupt Register, ICDSGIR)。這通常被用於內部處理器之間的通信

私有外設中斷(Private Peripheral Interrupt, PPI)

  由對一個單獨的處理器私有的外設生成

共享外設中斷(Shared Peripheral Interrupt, SPI)

  由一個可以被中斷控制器路由到超過一個處理器的外設生成。


  中斷可以是邊緣觸發的(當在相關輸入上中斷控制器檢測到一個上升沿時考慮確認,並且保持確認直到被清除)或者是電平敏感的(僅在相關到中斷控制器的輸入是高電平時被確認)。


  獨立的中斷源可以使用一個ID號來唄確認。GIC賦值一個指定範圍的ID值到不同類型的中斷。


  處理器硬件與處理器當前中斷優先級比較。如果中斷有足夠的優先級,一箇中斷異常請求信號被髮出。


  我們在第22章會回到GIC的主題,那裏講述了ARM多核處理器中的實現。關於GIC更爲詳細的信息可以在單獨處理器的TRM(Technical Reference Manual)《ARM通用中斷處理器架構規範》(ARM Generic Interrupt Controller Architecture specification)中找到。


13.2.1 配置


  訪問通用中斷處理寄存器是內存映射的。在一個使用GIC的多核處理器中,這通過使用對每個處理器私有的接口來完成(進一步細節看22章第6節的SMP系統中的處理中斷)。


  分配器包含一個配置寄存器集,數目取決於實現了多少個外部中斷:
 > 中斷配置寄存器配置獨立中斷源爲邊沿或電平敏感的。
 > 中斷優先級寄存器爲每個獨立中斷設置優先級值。較低的值表示較高的優先級。


  CPU接口爲中斷處理提供寄存器的每覈實例,相對於配置:
 > 優先級屏蔽寄存器阻止低於某個優先級的中斷被傳遞到處理器。最低優先級的中斷絕不會被傳遞。
 > 二進制點寄存器(The Binary Point Register)爲了優先級的目的使得可配數量的優先級值的最低有效位被忽略。這使得中斷被如此配置,相似優先級的中斷組不會相互搶佔,但是如果同時發生仍然會以優先級的順序被處理。


  初始化序列

a. 使用分配器控制寄存器(Distributor Control Register)使能分配器;

b. 使用使能設置和優先級寄存器使能和設置SPI(Shared Peripheral Interrupt, 共享外設中斷)的優先級。中斷的復位後優先級對它們來說可能太低,以至於不能遞交。

c. 使用CPU接口控制寄存器(CPU Interface Control Register)使能CPU接口。

d. 設置優先級屏蔽寄存器(Priority Mask Register)。(復位值阻止所有中斷被遞交)

e. 使用使能設置和優先級寄存器(Enable Set and Priority Level registers)使能和設置私有外設中斷(Private Peripheral Interrupts)和軟件生成中斷(Software Generated

Interrupts)。這些操作是在分配器優先級寄存器(Distributor Priority Level registers)中被執行。這些寄存器是分組的,爲每個處理器提供一份獨立的拷貝。

f. 確保中斷在向量表中的有效入口存在。

g. 清除CPSR中的I位。


13.2.2 中斷處理


  當一個處理器獲取到一箇中斷異常,它讀取中斷應答寄存器(Interrupt Acknowledge Register, ICCIAR),來應答中斷。這個讀取返回一箇中斷ID,它被用於選擇正確的中斷處理程序。當GIC看到這個讀取,它恰當地將終端的狀態從掛起切換到激活或激活並掛起。如果當前沒有中斷掛起,一個爲假中斷的預定義ID被返回。


  如果一箇中斷被激活,中斷控制器就將IRQ輸入報告給處理器。這意味着中斷復位例程現在可以重新使能中斷。這使得較高優先級中斷的到來可以搶佔當前中斷的處理。


  當中斷服務例程已完成處理中斷,它通過寫GIC中的中斷結束寄存器(End of Interrupt Register,ICCEOIR)來發消息。直到這一過程被完成,那個中斷(並且任何較低優先級的中斷)的新信號不會被檢測到。


> 中斷號碼ID1020-ID1023特殊用途保留,包括髮布假中斷的信號。

> 中斷ID值在ID32-ID1019之間的被用於SPI(共享外設中斷)

> 中斷號碼ID0-ID31之間的被用於私有於一個處理器接口的中斷。在多核系統(或者是在一個多核GIC實現)中,這些號碼在每個核的基礎上被分組。ID0-ID15被用於SGI(軟件生成中斷),ID16-ID31被用於PPI(私有外設中斷)。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章