【中断篇】中断控制器及中断检测时序
🌟🌟🌟博主主頁:MuggleZero?🌟🌟🌟
?《ARMv8架構初學者筆記》專欄地址:《ARMv8架構初學者筆記》
GIC-500控制器支持GICv3架構,具有以下中斷類型:
-
SGI(軟件觸發中斷),16個
ID0~15,處理器之間的中斷,也就是說一個core產生的中斷被送到其他core上。每個core上的SGI相互獨立(設置獨立、ID范圍獨立)。
-
PPI(私有的外設中斷),16個
ID16~31,每個處理器核心的私有中斷,PPI會被送到指定的CPU上處理。
-
SPI(共享的外設中斷),960個
ID32~991,對應了spi[991:32]位。你可以對每個SPI進行編程,使其針對一個特定的核或任何核。在一個核上激活一個SPI,就會激活所有核的SPI。也就是說,GIC-500最多允許一個核來激活一個SPI。每個SPI的設置也在所有內核之間共享。
-
LPI(指定區域的外設中斷)
GIC-500始終支持多達57344個LPI,有一個緩存用于保存最頻繁中斷的設置。ITS和LPI的設置存儲在主存儲器中,因此一個高速緩存的缺失可能會導致多達三次的內存往返。第一個LPI的ID號是8192。
LPI通常用于產生基于消息的中斷的外圍設備。一個LPI在一個給定的時間內只針對一個內核。當外設寫到ITS(中斷映射服務)時就會產生LPI,ITS(中斷映射服務)也持有控制LPI產生和維護的寄存器。ITS(中斷映射服務)提供中斷ID轉換,如果系統MMU也存在于這些外設中,則允許外設直接由虛擬機擁有。因此LPI更適合虛擬機。
GIC的一般架構
GIC控制器由仲裁單元、再分配單元、中斷映射單元和CPU接口模塊組成。仲裁單元為每一個中斷源維護了一個狀態機,狀態包含inactive、pending、active和active and pending。
-
仲裁單元:提供了SPI的路由配置,并保存所有相關的路由和優先級信息。
-
再分配單元:提供了PPI和SGI的配置設置,總是在有限的時間內向CPU接口提交具有最高優先級的未決中斷。
SPI中斷檢測流程
當GIC檢測到中斷發生的時候,將其標記為pending狀態。
對于處于pending的中斷,仲裁單元會確定目標CPU,將中斷請求發送到這個CPU上。
對于每個CPU,仲裁單元會從pending中的中斷選擇優先級最高的,然后將其發到目標CPU的interaface上
CPU interface會決定這個中斷是否可以發給CPU。如果可以發送,則GIC發送一個中斷請求信號給該CPU,使得CPU進入中斷異常。
當CPU進入中斷異常后,中斷處理程序會去讀取GICC_IAR寄存器來響應中斷,寄存器會返回硬件中斷號。
當處理器完成中斷服務后,必須發送一個EOI(End of Interrupt)給GIC控制器。
中斷優先級搶占
GIC控制器支持中斷優先級搶占功能。對于優先級高的中斷A,如果有一個低優先級且處于pending狀態的中斷B,GIC會做出裁決,讓A去搶占B,優先將A的中斷請求發送給CPU。CPU也會應答高優先級中斷。
下圖是GIC400中的時序圖。假設M和N都是SPI類型的中斷并通過FIQ來處理,高電平觸發,N比M優先級高,它們的目標CPU相同。
工作流程如下:
T1
GIC的仲裁單元檢測到中斷輸入M的引腳電平出現了電平變化,
T2
此時仲裁單元設置中斷M得狀態為pending。
T17
經過tph個時鐘后,CPU interface會拉低nFIQCPU[n]信號(在中斷M變成pending后,大概需要15個周期來拉低nFIQCPU[n]信號),仲裁單元需要這15個周期來判斷pending狀態下哪個中斷優先級最高。
T42
仲裁單元檢測到另一個優先級更高的中斷N。
T43
接著T42,仲裁單元用中斷N替換中斷M為當前pending狀態下優先級最高的中斷,并且設置中斷N的狀態的pending。
T58
CPU interface在nFIQCPU[n]信號低的狀態下,更新GICC_IAR寄存器中的Interrupt ID域,將該域的值變為中斷N的硬件中斷號。
T61
CPU(Linux中的中斷服務程序)讀取GICC_IAR寄存器,即軟件響應了中斷。這時仲裁單元又會把中斷N的狀態從pending設置為active and pending。
T61~T131:Linux處理中斷N的中斷服務程序
T64時刻,在中斷N被Linux內核響應后的3個時鐘內,CPU interface模塊完成了對nFIQCPU[n]信號的deasserts,即拉高了nFIQCPU[n]信號。
T126時刻外設也deassert了該中斷N;
T128時刻移除了該中斷N的pending狀態;
T131時刻,Linux中的內核中斷服務程序將中斷N的ID號寫入GICC_EOIR寄存器完成中斷N的全部處理過程。
T146、T211和T214
在將中斷N的ID號寫入GICC_EOIR寄存器后的tph個時鐘后,仲裁單元會選擇下一個最高優先級的中斷M,發送中斷請求給CPU interface模塊。CPU interface模塊會拉低nFIQCPU[n]信號來向CPU報告這個中斷M。
T211時刻,Linux中的內核中斷服務程序讀取GICC_IAR寄存器來響應中斷,仲裁單元將中斷M設置為active and pending。
T214時刻,在CPU響應中斷后的3個時鐘內,CPU interface模塊會拉高nFIQCPU[n]信號來完成更多動作。
總結
對于中斷時序來說,如果出現更高優先級的中斷,仲裁單元會優先處理,將其設置為優先級最高的pending狀態。
對于pending狀態的處理,大致流程是:
CPU interface模塊拉低nFIQCPU[n]信號來向CPU報告中斷;
Linux中斷服務程序讀取GICC_IAR寄存器來響應中斷,并且設置狀態為active and pending;
響應后的三個周期內,CPU interface模塊拉高nFIQCPU[n]信號
移除當前中斷的pend ing狀態
Linux中斷服務程序將中斷的硬件ID寫入GICC_EOIR。
處理下一個中斷。
歡迎關注我的個人微信公眾號,一起交流學習嵌入式開發知識!
關注「求密勒實驗室」
總結
以上是生活随笔為你收集整理的【中断篇】中断控制器及中断检测时序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 游戏辅助教程-地址篇 CE找地址技巧
- 下一篇: 午端阳粽飘香端午节PPT模板