linux kernel 中斷子系統之(一)-- ARM GIC 硬件【轉】


轉自:https://blog.csdn.net/xiafeng1113/article/details/44998179/

一個系統中,中斷是很重要的組成部分之一,有了中斷,系統才可以不用一直輪詢(polling)是否有事件發生,系統效率才得以提高,而且對中斷的控制又通常分散在各個地方,不同的部分由不同功能的程序控制,做到了各司其職,配合無誤,系統才能正常工作。一般系統中,中斷控制分為三個地方:模塊、中斷控制器、處理器,模塊通常有寄存器可以控制是否使能中斷功能,中斷觸發條件等;中斷控制器可以管理中斷的優先級等,而處理所有中斷的處理器則有寄存器設置是否響應中斷。

1. 全景
作為 ARM 系統中通用中斷控制器的是 GIC(Generic Interrupt Controller) ,目前有四個版本,V1~V4(V2最多支持8個ARM core,V3/V4支持更多的ARM core,主要用於ARM64系統結構)。目前在ARM官方網站只能下載到Version 2的GIC architecture specification。其中GIC-500最多支持128個 cpu core,它要求ARM core必須是ARMV8指令集的(例如Cortex-A57),符合GIC architecture specification version 3。本文主要描述的是GIC-400,它更適合嵌入式系統,符合version 2的GIC architecture specification。GIC-400通過AMBA(Advanced Microcontroller Bus Architecture)這樣的片上總線連接到一個或者多個ARM processor上。先看一張 GIC 在系統中的作用全景圖(overview)。

 

 

 

從這張圖中可以看出, GIC 是聯系外設中斷和 CPU 的橋梁,也是各 CPU 之間中斷互聯的通道(也帶有管理功能),它負責檢測、管理、分發中斷,可以做到:

使能或禁止中斷;

把中斷分組到組 0 還是組 1 (安全系統中使用 FIQ , Group0 , Group1 作為非安全系統使用,連接 IRQ );

多核系統中將中斷分配到不同處理器上;

設置電平觸發還是邊沿觸發方式(不等於外設的觸發方式);

虛擬化擴展;

ARM CPU 對外的連接只有 2 個中斷,一個是 IRQ ,一個是 FIQ ,相對應的處理模式分別是一般中斷( IRQ )處理模式和快速中斷( FIQ )處理模式。所以 GIC 最后要把中斷匯集成 2 條線,與 CPU 對接。

2. 詳細設計
介紹完總體的印象,下面要介紹詳細的部分了,在介紹前,先了解 GIC 中涉及的幾個概念, GIC 中中斷類型有3種:SGI(Software-generated interrupt)、PPI(Private peripheral interrupt )、SPI(Shared peripheral interrupt)。

SGI: SGIs are generated by writing to the Software Generated Interrupt Register, GICD_SGIR. Each CPU interface can generate a maximum of 16 SGIs, ID0-ID15, for each target processor. SGI為軟件可以觸發的中斷,統一編號為0~15,用於各個core之間的通信。

PPI: A PPI is an interrupt that is specific to a single processor. All PPI signals are active-LOW level-sensitive. Table 2-3shows the PPIs that are available for each processor. PPI為每個 core 的私有外設中斷,統一編號為 16-31 ,例如每個 CPU 的 local timer 即 Arch Timer 產生的中斷就是通過 PPI 發送給 CPU 的(安全為 29, 非安全為 30)。

SPI: SPIs are triggered by events generated on associated interrupt input lines. The GIC-400 can support up to 480 SPIs corresponding to the external IRQS[479:0]signal. The number of SPIs available depends on the implemented configuration of the GIC-400. The permitted values are 0-480, in steps of 32. SPIs start at ID32.You can configure whether each SPI is edge-triggered on a rising edge or is active-HIGH level-sensitive. SPI 是系統的外設產生的中斷,為各個 core 公用的中斷,統一編號為 32~1019 ,如 global timer 、 uart 、 gpio 產生的中斷。

還是先看圖:

 

 

 

從圖中可以看出, GIC 可以清晰的划分成兩個部分:分發器( Distributor )和 CPU 接口(CPU Interface )。CPU interface有兩種,一種就是和普通processor接口,另外一種是和虛擬機接口的。Virtual CPU interface在本文中不會詳細描述。分發器其實應該叫匯聚器,在 IC 的后端設計中, layout 會把各個模塊引過來的中斷線(就是上面說的三種中斷)混接到 GIC 上,然后把混聚合的中斷接到 CPU 的 IRQ 和 FIQ 線上,這樣 CPU 就有觸覺了。

其中 Distribute 只有一套,故基地址也只有一個,而 Interface 有多套,因為每個 CPU 都對應一套 interface 。所以嚴格來說, GIC 最后輸出的線的個數應該是 CPU 的個數 * 2 ,但是通常設計時,保證了每個 CPU 看到的 interface 的基地址也是相同的,程序上看到的基地址也是相同的。

其中各個子中斷使能,設置觸發方式,優先級排序,分發到哪個 CPU 上這些功能由 Distribute 負責,總的中斷的使能,狀態的維護由 Interface 負責。

Distributor 概述

Distributor的主要的作用是檢測各個interrupt source的狀態,控制各個interrupt source的行為,分發各個interrupt source產生的中斷事件分發到指定的一個或者多個CPU interface上。雖然Distributor可以管理多個interrupt source,但是它總是把優先級最高的那個interrupt請求送往CPU interface。Distributor對中斷的控制包括:

(1)中斷enable或者disable的控制。Distributor對中斷的控制分成兩個級別。一個是全局中斷的控制(GIC_DIST_CTRL)。一旦disable了全局的中斷,那么任何的interrupt source產生的interrupt event都不會被傳遞到CPU interface。另外一個級別是對針對各個interrupt source進行控制(GIC_DIST_ENABLE_CLEAR),disable某一個interrupt source會導致該interrupt event不會分發到CPU interface,但不影響其他interrupt source產生interrupt event的分發。

(2)控制將當前優先級最高的中斷事件分發到一個或者一組CPU interface。當一個中斷事件分發到多個CPU interface的時候,GIC的內部邏輯應該保證只assert 一個CPU。

(3)優先級控制。

(4)interrupt屬性設定。例如是level-sensitive還是edge-triggered

(5)interrupt group的設定

Distributor可以管理若干個interrupt source,這些interrupt source用ID來標識,我們稱之interrupt ID。

 

CPU interface

CPU interface這個block主要用於和process進行接口。該block的主要功能包括:

(a)enable或者disable CPU interface向連接的CPU assert中斷事件。對於ARM,CPU interface block和CPU之間的中斷信號線是nIRQCPU和nFIQCPU。如果disable了中斷,那么即便是Distributor分發了一個中斷事件到CPU interface,但是也不會assert指定的nIRQ或者nFIQ通知processor。

(b)ackowledging中斷。processor會向CPU interface block應答中斷,中斷一旦被應答,Distributor就會把該中斷的狀態從pending狀態修改成active。如果沒有后續pending的中斷,那么CPU interface就會deassert nIRQCPU和nFIQCPU信號線。如果在這個過程中又產生了新的中斷,那么Distributor就會把該中斷的狀態從pending狀態修改成pending and active。這時候,CPU interface仍然會保持nIRQ或者nFIQ信號的asserted狀態,也就是向processor signal下一個中斷。

(c)中斷處理完畢的通知。當interrupt handler處理完了一個中斷的時候,會向寫CPU interface的寄存器從而通知GIC CPU已經處理完該中斷。做這個動作一方面是通知Distributor將中斷狀態修改為deactive,另外一方面,可以允許其他的pending的interrupt向CPU interface提交。

(d)設定priority mask。通過priority mask,可以mask掉一些優先級比較低的中斷,這些中斷不會通知到CPU。

(e)設定preemption的策略

(f)在多個中斷事件同時到來的時候,選擇一個優先級最高的通知processor


不同系統設置中斷的親和性是不同的,比如網絡服務器中,總是希望盡快的響應網絡請求,功耗不是很在乎,因此可以將不同中斷分配到不同 CPU 上,以盡快響應中斷,而嵌入式系統中,對功耗很在乎,通常要把中斷綁定到 CPU0 上,這樣其他 CPU 空閑時,可以進入 IDLE 狀態,以節省功耗,ARM CPU 正常運行時,只使用 Arch Timer,不會使用 Global Timer ,即系統的 Timer 不會運行。但 CPU 電源被關閉后,此 CPU 的 Arch Timer 也會被關閉,因此, CPU 進入關電的 IDLE 狀態時,要先將其 Timer 切換至 Global Timer ,這樣在下一個 Timer 到來時,如果是非啟動 CPU ,會有響應 Global Timer 中的 CPU 發送的 SGI 中斷,有中斷后,會有其他模塊將其從斷電狀態中帶出,如果是 CPU0 ,同樣收到中斷后,其他模塊將其帶出斷電狀態,不過此時的中斷不再是 SGI ,而是 Global Timer 的中斷。

通常 Distribute 屬於系統電源域,而interface屬於 CPU 電源域,所以每次 CPU 斷電重新上電(系統不斷電)后, Interface 都要恢復原值或重

 

 

新初始化。另外如果要讓 CPU 一直在 WFI 狀態,則需要設置 Interface 的 GICC_CTLR 寄存器為 0 ,否則CPU會從 WFI 狀態中退出。

寄存器在安全和非安全模式讀到值是不同的,這並不是說明安全和非安全狀態下,同一個地址的寄存器存在備份(就像 IRQ 和 FIQ 模式下,有些寄存器存在備份),而是因為寄存器的不同 bit 的屬性不同,有些屬於安全寄存器的 bit 在非安全狀態下讀到的為 0 ,所以 CPU 復位后,在未切換到非安全系統前,要先設置 GIC ,否則安全系統不能響應中斷,即安全系統不能使用, CPU 就會停在哪里靜靜的休息,此時看到的現象是: CPU 在 WFI 狀態,系統的時鍾也是停止的, 因為 CPU 的 Arch-Timer 得不到響應, tick 計數不會改變。

3. 中斷的處理流程
中斷的處理流程是:distributor會把收集來的中斷,先緩存一下,依次把優先級最高的那個interrupt請求送往CPU interface,CPU讀取一個中斷,其實就是讀取interface的一個寄存器,只不過這個寄存器存放的是中斷號,這時候中斷的狀態由pending轉為active,cpu處理完了以后,將中斷號寫入GIC的interface,告訴GIC處理完了,可以將這個中斷清理了。

 

 

 

 

查看系統上的中斷是怎么分配在 CPU 情況和響應次數的命令:

# cat /proc/interrupts

 

 

4. 寄存器
  

 

 

 

 

 

 

 

參考:

DDI0471B_gic400_r0p1_trm.pdf

IHI 0048B, ARM Generic Interrupt Controller Architecture Specification, Ver 2.0.pdf

http://www.wowotech.net/linux_kenrel/gic_driver.html

http://blog.csdn.net/velanjun/article/details/8757862

http://www.ibm.com/developerworks/cn/linux/l-cn-linuxkernelint/index.html

點贊 2
————————————————
版權聲明:本文為CSDN博主「xiafeng1113」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/xiafeng1113/article/details/44998179/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM