ARM GIC(三) gicv2架構【轉】


轉自:http://www.lujun.org.cn/?p=3861

ARM的cpu,特別是cortex-A系列的CPU,目前都是多core的cpu,因此對於多core的cpu的中斷管理,就不能像單core那樣簡單去管理,由此arm定義了GICv2架構,來支持多核cpu的中斷管理。

一、gicv2架構

GICv2,支持最大8個core。其框圖如下圖所示:

 

 

在gicv2中,gic由兩個大模塊組成:

  • distributor:實現中斷分發,對於PPI,SGI是各個core獨有的中斷,不參與目的core的仲裁,SPI,是所有core共享的,根據配置決定中斷發往的core。最后選擇最高優先級中斷發送給cpu interface。寄存器使用 GICD_ 作為前綴。一個gic中,只有一個GICD。

  • cpu interface:將GICD發送的中斷信息,通過IRQ,FIQ管腳,傳輸給core。寄存器使用 GICC_ 作為前綴。每一個core,有一個cpu interface。

  • virtual cpu interface:將GICD發送的虛擬中斷信息,通過VIRQ,VFIQ管腳,傳輸給core。每一個core,有一個virtual cpu interface。而在這virtual cpu interface中,又包含以下兩個組件:

    • virtual interface control:寄存器使用 GICH_ 作為前綴

    • virtual cpu interface:寄存器使用 GICV_ 作為前綴

圖中的virtual interface,是用於支持虛擬中斷,本系列不討論虛擬中斷。

GICv2支持中斷旁路模式,也就是gic外部的FIQ,IRQ直接接到core的FIQ,IRQ上,相當於gic是不使能的。也就是CFGSDISABLE是有效的,將GIC給無效掉。

gicv2,定義了自己的一些寄存器,這些寄存器,都是使用memory-mapped的方式去訪問的,也就是在soc中,會留有一片空間,給gic。cpu通過訪問這部分空間,來對gic進行操作。

寄存器,分為以下:

  • GICD_*: distributor的寄存器

  • GICH_*: 虛擬interface的控制寄存器

  • GICV_*:虛擬interface的控制寄存器

  • GICC_*: 虛擬cpu interface的寄存器

二、中斷分組

givc2,將中斷,分成了group0和group1。使用寄存器GICD_IGROUPRn來對每個中斷,設置組。

 

 

  • group0:安全中斷,由nFIQ驅動

  • group1:非安全中斷,由nIRQ驅動

三、中斷號

gicv2,支持最大1020個中斷。其中斷號分配如下:

中斷號

分配

中斷來源

寄存器

ID0-ID7

非安全軟中斷

軟件

GICD_SGIR

ID8-ID15

安全軟中斷

軟件

GICD_SGIR

ID16-ID31

私有中斷

外設

no

ID32-ID1019

共享中斷

外設

no

四、gic結構

gic主要包括以下兩個組件:

  • distributor

  • cpu interface

1、distributor

中斷分發器,用來收集所有的中斷來源,並且為每個中斷源設置中斷優先級,中斷分組,中斷目的core。當有中斷產生時,將當前最高優先級中斷,發送給對應的cpu interface。

distributor對中斷提供以下的功能:

  • 全局中斷使能

  • 每個中斷的使能

  • 中斷的優先級

  • 中斷的分組

  • 中斷的目的core

  • 中斷觸發方式

  • 對於SGI中斷,傳輸中斷到指定的core

  • 每個中斷的狀態管理

  • 提供軟件,可以修改中斷的pending狀態

2、cpu interface

cpu interface,將GICD發送的中斷信息,通過IRQ,FIQ管腳,發送給連接到該cpu接口的core。

cpu interface提供了一下的功能:

  • 將中斷請求發送給cpu

  • 對中斷進行認可(acknowledging an interrupt)

  • 中斷完成識別(indicating completion of an interrupt)

  • 設置中斷優先級屏蔽

  • 定義中斷搶占策略

  • 決定當前處於pending狀態最高優先級中斷

五、中斷認可

中斷認可,是指cpu響應該中斷。此時中斷狀態從pending狀態,變為active狀態。通過訪問GICC_IAR寄存器,來對中斷進行認可。

  • GICC_IAR: 認可group0的中斷

  • GICC_AIAR: 認可group1的中斷

六、中斷完成

中斷完成,是指cpu處理完中斷。此時中斷狀態從active狀態,變為inactive狀態。gic中,對中斷完成,定義了以下兩個stage:

  • 優先級重置(priority drop):將當前中斷屏蔽的最高優先級進行重置,以便能夠響應低優先級中斷。group0中斷,通過寫GICC_EOIR寄存器,來實現優先級重置,group1中斷,通過寫 GICC_AEOIR 寄存器,來實現優先級重置。

  • 中斷無效(interrupt deactivation):將中斷的狀態,設置為inactive狀態。通過寫 GICC_DIR 寄存器,來實現中斷無效。

這里為什么要對中斷完成,定義2個stage,其實是有考慮的。對於中斷來說,我們是希望中斷處理程序越短越好,但是有些中斷處理程序,就是比較長,在這種情況下,就會使其他中斷得到相應,從而影響實時性。

比如當前cpu在響應優先級為4的中斷A,但是這個中斷A的中斷處理程序比較長,此時如果有優先級為5的中斷B到來,那么cpu是不會響應這個中斷的。

在軟件上,會將中斷處理程序分為兩部分,分為上半部分,和下半部分。在上半部分,完成中斷最緊急的任務,然后就可以通知GIC,降低當前的中斷處理優先級,以便其他中斷能夠得到響應。在下半部分,處理該中斷的其他事情。

在這種機制下,低優先級的中斷,不用等待高優先級的中斷,完全執行完中斷處理程序后,就可以被cpu所響應,提高實時性。

為了實現上述機制,就將中斷完成分成了2步。還是剛剛的例子,cpu在響應優先級為4的中斷A,當中斷A的上半部分完成后,通知GIC,優先級重置(drop priority),GIC將當前的最高優先級中斷重置,重置到響應中斷A之前的優先級,比如優先級6,那么此時優先級為5的中斷B,就可以被cpu響應。最后中斷A的下半部分完成后,通知GIC,將該中斷A的狀態,設置為inactive狀態,此時中斷A就真正的完成了。

當然,也可以不將中斷完成分成2步,就1步。通過控制 GICC_CTLR寄存器的EOImode比特,來決定是否將中斷完成分成2步。

七、bypass功能

gicv2支持bypass功能,這樣gic就不起作用了,core的中斷管腳,直接由soc的其他部門信號驅動。

如下圖所示,通過控制 GICC_CLTR 寄存器的一些比特位,來實現bypass功能。不過這個功能一般不使用,不然何必要在arm的soc中,加入gic呢?

 

 

八、中斷處理流程

中斷處理流程,包含了以下幾步:

  • GIC決定每個中斷的使能狀態,不使能的中斷,是不能發送中斷的

  • 如果某個中斷的中斷源有效,GIC將該中斷的狀態設置為pending狀態,然后判斷該中斷的目標core

  • 對於每一個core,GIC將當前處於pending狀態的優先級最高的中斷,發送給該core的cpu interface

  • cpu interface接收GIC發送的中斷請求,判斷優先級是否滿足要求,如果滿足,就將中斷通過nFIQ或nIRQ管腳,發送給core。

  • core響應該中斷,通過讀取 GICC_IAR 寄存器,來認可該中斷。讀取該寄存器,如果是軟中斷,返回源處理器ID,否則返回中斷號。

  • 當core認可該中斷后,GIC將該中斷的狀態,修改為active狀態

  • 當core完成該中斷后,通過寫 EOIR (end of interrupt register)來實現優先級重置,寫 GICC_DIR 寄存器,來無效該中斷

九、中斷使能和禁止

通過設置GICD_ISENABLERn寄存器,來使中斷使能,通過設置GICD_ICENABLERn寄存器,來使中斷禁止。

這兩個寄存器,都是bit有效的寄存器,也就是一個bit,關聯一個中斷。

比如對於GICD_ISENABLER寄存器,描述如下:

 

 

十、中斷pending

通過設置GICD_ISPENDRn或GICD_ICPENDRn寄存器,可以讀取和修改中斷的pending狀態。這兩個寄存器,也是bit有效的寄存器,一個bit,關聯一個中斷。

十一、中斷active

    通過設置GICD_ISACTIVERn或GICD_ICACTIVERn寄存器,可以讀取和修改中斷的active狀態。這兩個寄存器,也是bit有效的寄存器,一個bit,關聯一個中斷。

十二、產生軟中斷

通過寫 GICD_SGIR 寄存器,來產生軟中斷。軟中斷,可以指定產生中斷,發往執行的core,也可以發送多個core。

對於軟中斷,這個是軟件產生的中斷。比如軟件,想給執行自己的core,發送一個中斷,就可以通過軟中斷來產生。或者軟件,想起其他的core,發送一個中斷,也可以通過軟中斷來產生。

寄存器如下:

 

 

1、TargetListFileter

對於TargetListFileter:決定distributor將軟中斷,如何發送給cpu interface。

 

 

  • 0b00:按照CPUTargetList的指定,來發送軟中斷

  • 0b01:按照CPUTargetList的指定,來發送軟中斷,但是不能發送給自己

  • 0b10:軟中斷,只能發送給自己

2、CPUTargetList

描述如下:

 

 

對於多core的系統,會給每個core一個編號。gicv2支持最多8個core,因此core的編號就是0-7,剛好8個bit,可以表示。

這樣的CPUTargetList,就和8個cpu相對應。第0bit,表示core0,第7bit,表示core7。

如果想給core1,core2,core7發送軟中斷,那么此時這個位域要填入0x84。

3、NSATT

描述如下:

 

 

這個用來支持安全擴展,在gicv2中,將中斷進行了分組

  • group0:安全中斷

  • group1:非安全中斷

這個bit,用來表示發送的軟中斷,是安全中斷,還是非安全中斷。而且這個bit,只有core處於安全狀態的時候,才能寫。如果core是處於非安全狀態,那么這個bit被忽略,也就是只能發非安全的軟中斷。

4、SGIINTID

發送的軟中斷的中斷號。

十三、中斷優先級

gicv2,支持最小16個,最大256個中斷優先級,如下圖所示:

 

 

如果實現的中斷優先級小於256個,那么最低的幾個bit,是為0的。

通過設置GICD_IPRIORITYRn寄存器,來設置中斷的優先級。這個寄存器是字節有效的,也就是一個字節,對應一個中斷的優先級。優先級數值越小,那么這個中斷的優先級越高。

高優先級的中斷,是可以搶占低優先級的中斷。

十四、gic使用例子

下圖是gic的使用例子:

 

 

外部的中斷,連接到gic。由distributor進行中斷分組。中斷請求,由distributor發送給cpu interface,cpu interface再發送給處理器。

對於支持安全擴展,其應用如下:

 

 

安全中斷,處於group0,非安全中斷處於group1。

十五、gic寄存器

gic寄存器,分為兩部分,一部分是distributor的寄存器,另一部分是cpu interface的寄存器。

兩部分的寄存器,均是通過memory-mapped的方式來訪問。

下圖是distributor的寄存器:

 

 

下圖是cpu interface的寄存器:

 

 

十六、總結

以上就是GICv2的介紹,更多的內容,需要查看gicv2的文檔。

gicv2比較簡單,最多只能支持8個core,超過了8個core,那么就不能使用gicv2了。不過這也不是大問題,對於手機的arm處理器來說,最多也就8個core。但是對於服務器,桌面級的arm處理器,那么就可能會超過8個core,此時gicv2就不適用了,所以ARM后面又加入GICv3,v4架構。

GICv2的寄存器,都是通過memory-mapped的方式訪問。但是中斷在一個soc系統中,是經常會產生的,那么處理器就會經常的讀取gic的寄存器,而使用memory-mapped的方式去訪問,就會影響中斷響應速度。在之后的GICv3,v3中,就加入了使用系統寄存器來進行訪問,加快中斷處理。

GICv2只是一個gic的架構,其實現的對應的IP是gic400。

此條目發表在 ARM分類目錄,貼了 gic標簽。將 固定鏈接加入收藏夾。


免責聲明!

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



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