ARM GICv3中斷控制器

1. 前言

GIC,Generic Interrupt Controller。是ARM公司提供的一個通用的中斷控制器。主要作用爲:
接受硬件中斷信號,並經過一定處理後,分發給對應的CPU進行處理。

當前GIC 有四個版本,GIC v1~v4, 主要區別如下表:
在這裏插入圖片描述

本文主要介紹GIC v3控制器, 基於linux kernel 4.19.0。

2. GIC v3中斷類別

GICv3定義了以下中斷類型:
SPI (Shared Peripheral Interrupt)
公用的外部設備中斷,也定義爲共享中斷。可以多個Cpu或者說Core處理,不限定特定的Cpu。比如按鍵觸發一箇中斷,手機觸摸屏觸發的中斷。
PPI (Private Peripheral Interrupt)
私有外設中斷。這是每個核心私有的中斷。PPI太冗長會送達到指定的CPU上,應用場景有CPU本地時鐘。
SGI (Software Generated Interrupt)
軟件觸發的中斷。軟件可以通過寫GICD_SGIR寄存器來觸發一箇中斷事件,一般用於核間通信。
LPI (Locality-specific Peripheral Interrupt)
LPI是GICv3中的新特性,它們在很多方面與其他類型的中斷不同。LPI始終是基於消息的中斷,它們的配置保存在表中而不是寄存器。比如PCIe的MSI/MSI-x中斷。

硬件中斷號 中斷類型
0-15 SGI
16 - 31 PPI
32 - 1019 SPI
1020 - 1023 用於指示特殊情況的特殊中斷
1024 - 8191 Reservd
8192 - MAX LPI

3. GIC v3組成

在這裏插入圖片描述
GICv3控制器由以下部分組成:
distributor: SPI中斷的管理,將中斷髮送給redistributor
redistributor: PPI,SGI,LPI中斷的管理,將中斷髮送給cpu interface
cpu interface: 傳輸中斷給core
ITS: Interrupt Translation Service, 用來解析LPI中斷
其中,cpu interface是實現在core內部的,distributor,redistributor,ITS是實現在gic內部的.

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。

Redistributor詳述
對於每個連接的PE,都有一個Redistributor.
該block的主要功能包括:
(1)啓用和禁用SGI和PPI。
(2)設置SGI和PPI的優先級。
(3)將每個PPI設置爲電平觸發或邊緣觸發。
(4)將每個SGI和PPI分配給中斷組。
(5)控制SGI和PPI的狀態。
(6)內存中數據結構的基址控制,支持LPI的相關中斷屬性和掛起狀態。
(7)電源管理支持。

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 and active(這是和該interrupt source的信號有關,例如如果是電平中斷並且保持了該asserted電平,那麼就是pending and active)。processor ack了中斷之後,CPU interface就會deassert nIRQCPU和nFIQCPU信號線。
(c)中斷處理完畢的通知。當interrupt handler處理完了一箇中斷的時候,會向寫CPU interface的寄存器從而通知GIC CPU已經處理完該中斷。做這個動作一方面是通知Distributor將中斷狀態修改爲deactive,另外一方面,CPU interface會priority drop,從而允許其他的pending的interrupt向CPU提交。
(d)設定priority mask。通過priority mask,可以mask掉一些優先級比較低的中斷,這些中斷不會通知到CPU。
(e)設定preemption的策略
(f)在多箇中斷事件同時到來的時候,選擇一個優先級最高的通知processor

3. 中斷處理流程

在這裏插入圖片描述
從上圖可以看出,中斷處理可以分成兩類:
(1)中斷要通過distributor的中斷流程
–>外設發起中斷,發送給distributor
–>distributor將該中斷,分發給合適的re-distributor
–>re-distributor將中斷信息,發送給cpu interface。
–>cpu interface產生合適的中斷異常給處理器
–>處理器接收該異常,並且軟件處理該中斷

它的中斷狀態機如下圖所示
在這裏插入圖片描述
有四種中斷狀態:

中斷狀態 描述
Inactive 中斷即沒有Pending也沒有Active
Pending 由於外設硬件產生了中斷事件(或者軟件觸發)該中斷事件已經通過硬件信號通知到GIC,等待GIC分配的那個CPU進行處理
Active CPU已經應答(acknowledge)了該interrupt請求,並且正在處理中
Active and Pending 當一箇中斷源處於Active狀態的時候,同一中斷源又觸發了中斷,進入pending狀態

processor ack了一箇中斷後,該中斷會被設定爲active。當處理完成後,仍然要通知GIC,中斷已經處理完畢了。這時候,如果沒有pending的中斷,GIC就會將該interrupt設定爲inactive狀態。操作GIC中的End of Interrupt Register可以完成end of interrupt事件通知。

(2)中斷不通過distributor,比如LPI中斷
外設發起中斷,發送給ITS
–>ITS分析中斷,決定將來發送的re-distributor
–>ITS將中斷髮送給合適的re-distributor

4. LPI

LPI是基於消息的中斷。。也就是,中斷信息不在通過中斷線進行傳遞,而是通過memory。
gic內部提供一個寄存器,當外設往這個地址寫入數據時,就往gic發送了一箇中斷。
在soc系統中,外設想要發送中斷給gic,是需要一根中斷線的。如果現在一個外設,需要增加一箇中斷,那麼就要增加一根中斷線,然後連接到gic。這樣,就需要修改設計。而引入了LPI之後,當外設需要增加中斷,只需要使用LPI方式,傳輸中斷即可,不需要修改soc設計。

傳統的GIC流程:
在這裏插入圖片描述
在傳統的GIC流程中如上圖,外圍設備的中斷觸發線是引出到GIC上的,這樣可以理解爲一個物理的SIGNAL,比如一個高電平信號,邊沿觸發信號。

消息中斷流程:
在這裏插入圖片描述
使用消息將中斷從外設轉發到中斷控制器,無需每個中斷源提供專用信號。 這樣的一個好處是,可以減少中斷線的個數。

在GICv3中,SPI可以是基於消息的中斷,但LPI始終是基於消息的中斷。

5.ITS

引入了LPI之後,gicv3中,還加入了ITS組件,interrupt translation service。ITS將接收到的LPI中斷,進行解析,然後發送到對應的redistributor,再由redistributor將中斷信息,發送給cpu interface。
在這裏插入圖片描述
外設,通過寫GITS_TRANSLATER寄存器,發起LPI中斷。寫操作,給ITS提供2個信息:
EventID: 值保存在GITS_TRANSLATER寄存器中,表示外設發送中斷的事件類型
DeviceID: 表示哪一個外設發起LPI中斷。該值的傳遞,是實現自定義,例如,可以使用AXI的user信號來傳遞。
ITS將DeviceID和eventID,通過一系列查表,得到LPI中斷號,再使用LPI中斷號查表,得到該中斷的目標cpu。

ITS將LPI中斷號,LPI中斷對應的目標cpu,發送給對應的redistributor。redistributor再將該中斷信息,發送給CPU。

6.參考資料

GICv3_Software_Overview_Official_Release_B

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