1. 程式人生 > 實用技巧 >ARM GIC(六)gicv3架構-LPI

ARM GIC(六)gicv3架構-LPI

在gicv3中,引入了一種新的中斷型別。message based interrupts,訊息中斷。

一、訊息中斷

外設,不在通過專用中斷線,向gic傳送中斷,而是寫gic的暫存器,來發送中斷。
在這裡插入圖片描述

這樣的一個好處是,可以減少中斷線的個數。

為了支援訊息中斷,gicv3,增加了LPI,來支援訊息中斷。並且為他分配了特別多的中斷號,從8192開始,移植到16777216。

LPI,locality-specific peripheral interrupts。spec中,用了一章,來介紹這個LPI。

二、LPI介紹

LPI是一種基於訊息的邊沿中斷。也就是,中斷資訊,不在通過中斷線,進行傳遞,而是通過memory。gic內部,提供一個暫存器,當外設往這個地址,寫入資料時,就往gic傳送了一箇中斷。

在soc系統中,外設想要傳送中斷給gic,是需要一根中斷線的。如果現在一個外設,需要增加一箇中斷,那麼就要增加一根中斷線,然後連線到gic。這樣,就需要修改設計。而引入了LPI之後,當外設需要增加中斷,只需要使用LPI方式,傳輸中斷即可,不需要修改soc設計。

引入了LPI之後,gicv3中,還加入了ITS元件,interrupt translation service。ITS將接收到的LPI中斷,進行解析,然後傳送到對應的redistributor,再由redistributor將中斷資訊,傳送給cpu interface。

以下是帶LPI的框圖。外設,通過寫 GITS_TRANSLATER 暫存器,來傳遞訊息中斷。

在這裡插入圖片描述

LPI,和SPI,PPI,SGI有些差別,LPI的中斷的配置,以及中斷的狀態,是儲存在memory的表中,而不是儲存在gic的暫存器中的。

◾GICR_PROPBASER:儲存LPI中斷配置表的基地址

◾GICR_PENDBASER: 儲存LPI中斷狀態表的基地址

這裡,就涉及到兩個表:

1、LPI中斷配置表

該表,儲存在memory中。基地址,由GICR_PROPBASER暫存器決定。

在這裡插入圖片描述

該暫存器描述如下:

在這裡插入圖片描述

其中的Physical_Address欄位,指定了LPI中斷配置表的基地址。

對於LPI配置表,每個LPI中斷,佔用1個位元組,指定了該中斷的使能和中斷優先順序。

在這裡插入圖片描述

當外部發送LPI中斷給redistributor,redistributor首先要查該表,也就是要訪問memory來獲取LPI中斷的配置。為了加速這過程,redistributor中可以配置cache,用來快取LPI中斷的配置資訊。

因為有了cache,所以LPI中斷的配置資訊,就有了2份拷貝,一份在memory中,一份在redistributor的cache中。如果軟體修改了memory中的LPI中斷的配置資訊,需要將redistributor中的cache資訊給無效掉。

2、LPI中斷狀態表

該表,處於memory中,儲存了LPI中斷的狀態,是否pending狀態。

LPI中斷的狀態,不是儲存在暫存器中,而是儲存在memory中的pending表中。該狀態表,由redistributor來進行更改。而該table的基地址,是由軟體來設定的。

軟體通過設定 GICR_PENDBASER 暫存器來設定。

在這裡插入圖片描述

該暫存器,設定LPI狀態表的基地址,該狀態表的memory的屬性,如shareability,cache屬性等。

在這裡插入圖片描述

每個LPI中斷,佔用一個bit空間

◾0: 該LPI中斷,沒有處於pending狀態

◾1: 該LPI中斷,處於pending狀態

該狀態表,由redistributor來設定。軟體如果修改該表,會引發unpredictable行為。

三、LPI的實現方式

為了實現LPI,gicv3定義了以下兩種方法來實現:

◾使用ITS,將外設傳送到eventID,轉換成LPI 中斷號

◾forwarding方式,直接訪問redistributor的暫存器GICR_SERLPIR,直接傳送LPI中斷

1、forwarding方式

這種方式,比較簡單,主要由下面幾個暫存器來實現:

◾GICR_SERLPIR

◾GICR_CLRLPIR

◾GICR_INVLPIR

◾GICR_INVALLR

◾GICR_SYNCR

其gic框圖如下所示:

在這裡插入圖片描述

GICR_SERLPIR,將指定的LPI中斷,設定為pending狀態。
在這裡插入圖片描述

GICR_INVLPIR,將指定的LPI中斷,清除pending狀態。暫存器內容和GICR_SERLPIR一致。

在這裡插入圖片描述

GICR_INVLPIR,將快取中,指定LPI的快取給無效掉,使GIC重新從memory中載入LPI的配置。
在這裡插入圖片描述

GICR_INVALLR,將快取中,所有LPI的快取給無效掉,使GIC重新從memory中,載入LPI中斷的配置。

在這裡插入圖片描述

GICR_SYNCR,對redistributor的操作是否完成。

在這裡插入圖片描述

暫存器,只有第0bit是有效的。如果為0,表示當前對redistributor的操作是完成的,如果為1,那麼是沒有完成的。
在這裡插入圖片描述

2、使用ITS方式

理解了forwarding方式,那麼理解ITS方式,就要容易了。forwarding方式,是直接得到了LPI的中斷號。

但是對於ITS方式,是不知道LPI的中斷號的。需要將外設傳送的DeviceID,eventID,通過一系列查表,得到LPI的中斷號以及該中斷對應的target redistributor,然後將LPI中斷,傳送給對應的redistributor。

下圖是帶有ITS的gic框圖:

在這裡插入圖片描述

外設,通過寫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。

四、ITS

ITS是一個元件,用來提供給外設,傳送LPI中斷的,然後將LPI中斷,傳送給redistributor。

1、ITS處理流程

ITS使用三類表格,實現LPI的轉換和對映:

◾device table: 對映deviceID到中斷轉換表

◾interrupt translation table:對映EventID到INTID。以及INTID屬於的collection組

◾collection table:對映collection到redistributor

在這裡插入圖片描述

當外設往GITS_TRANSLATER暫存器中寫資料後,ITS做如下操作:

◾使用DeviceID,從裝置表(device table)中選擇索引為DeviceID的表項。從該表項中,得到中斷對映表的位置

◾使用EventID,從中斷對映表中選擇索引為EventID的表項。得到中斷號,以及中斷所屬的collection號

◾使用collection號,從collection表格中,選擇索引為collection號的表項。得到redistributor的對映資訊

◾根據collection表項的對映資訊,將中斷資訊,傳送給對應的redistributor

以上是物理LPI中斷的ITS流程。虛擬LPI中斷的ITS流程與之類似。以下是處理流程圖:

在這裡插入圖片描述

2、ITS命令

ITS操作,會涉及到很多表,而這些表的建立,維護是通過ITS命令,來實現的。雖然這些表,是在記憶體中的,但是GICv3和GICv4,不支援直接訪問這些表,而是要通過ITS命令,來配置這些表。

ITS的操作,是通過命令,來控制的。外部通過傳送命令給ITS,ITS然後去執行命令,每個命令,佔32位元組。

ITS有command佇列,命令寫在這個佇列裡面。ITS會自動的按照佇列順序,一一執行。
在這裡插入圖片描述

每個命令佔32個位元組。

命令,存放在記憶體中,GITS_CBASE,儲存命令的首地址。GITS_CREADR,是由ITS控制,表示下一個命令的地址。GITS_CWRITER,是下一個待寫命令的地址。軟體往GITS_CWRITER地址處,寫入命令,之後ITS就會執行這個命令。

ITS提供的命令,有很多,可以查閱GIC手冊獲取更多。

以下是CLEAR命令。

在這裡插入圖片描述

3、ITS table

ITS包括很多個表,這些表均處於 non-secure區域。

GITS_BASER,指定ITS表的基地址和大小。軟體,在使用ITS之前,必須要配置。

在這裡插入圖片描述

其中的Physical_Address欄位,就指定了表的基地址所在位置。

以下是各個表的基地址,對應的暫存器。

在這裡插入圖片描述

五、總結

gicv3中,引入了訊息中斷,並且為之,支援了LPI。分配了大量的中斷號,用於LPI。對於LPI的實現,有2種方式,一種是訪問redistributor提供的暫存器,一種是使用ITS。

不過對於手機arm cpu來說,其實是不需要LPI的,因為現有的中斷,已經符合要求,加入了LPI,讓gic更復雜,讓軟體操作,也更復雜。但是對於伺服器arm cpu,這個,就需要了,因為這個可以和PCIE相連,實現訊息中斷。個人感覺,這個LPI中斷,是為arm伺服器cpu,所使用的。

對於提供的gic IP來說,比如gic600,是有配置選項,決定,是否是否支援LPI中斷,以及是否需要ITS。

原文首發於駿的世界部落格
作者:盧駿.
更多Arm技術相關的文章請關注我,每週都有更新。