一、GIC中斷使能
對于外設(shè)中斷,處理器可以通過:
- 寫入GICD_ISENABLERn 寄存器的對應bit來使能該中斷。
- 寫入 GICD_ICENABLERn 寄存器的對應bit來禁止該中斷。
對于SGI中斷是否能通過上述兩個寄存器來enable和disable,這個由具體的實現(xiàn)( IMPLEMENTATION DEFINED)來定義。
此外寫入GICD_ISENABLERn 和GICD_ICENABLERn 寄存器只是控制Distributor是否能將該中斷轉(zhuǎn)發(fā)到CPU interface,并不會阻止該中斷改變狀態(tài)。比如寫入GICD_ICENABLERn 寄存器來disable對應中斷,并不能阻止他變成pending狀態(tài)。
二、設(shè)置或清除一個中斷的Pending狀態(tài)
對于外設(shè)中斷,處理器可以:
- 寫入GICD_ISPENDRn寄存器的對應bit來設(shè)置中斷狀態(tài)為pending。
- 寫入 GICD_ICPENDRn寄存器的對應bit來清除該中斷的pending狀態(tài)。
- 對于電平敏感的中斷:
- 如果中斷信號已經(jīng)被assert,處理器再寫入GICD_ICPENDRn寄存器的對應bit來清除中斷將不產(chǎn)生作用。
- 如果處理器通過寫入GICD_ISPENDRn來使對應中斷狀態(tài)變?yōu)閜ending,將忽略該中斷的硬件信號,并且保留pending狀態(tài),不管該中斷是被asserted還是deasserted。
- 包含pending的中斷狀態(tài)有兩種:
(1)pending
(2)active and pending - 對于邊沿觸發(fā)的中斷來講,包含pending的中斷狀態(tài)可以通過寫入GICD_ISPENDRn寄存器,或者GIC對該中斷信號的assertion來進行鎖定。
- 但是對于電平敏感的中斷來講,它的包含pending的中斷狀態(tài)可以通過寫入GICD_ISPENDRn寄存器來鎖定,但是不能根據(jù)傳遞到GIC的中斷信號來鎖定。
以下是電平敏感中斷的電路邏輯示意圖:
此外,對于SGI中斷,GIC將忽略對GICD_ISPENDRn和GICD_ICPENDRn寄存器的寫入,處理器不能通過寫入這些寄存器來改變SGI中斷的中斷狀態(tài)。一般情況下,處理器可以通過寫入 GICD_SGIR寄存器來使SGI中斷變成pending,在GICv2中,SGI的pending狀態(tài)可以通過直接寫入GICD_SPENDSGIRn 和 GICD_CPENDSGIRn 寄存器的對應位來改變。
2.1 Interrupt Set-Pending Registers, GICD_ISPENDRn
GICD_ISPENDRn寄存器提供一個Set-pending bit,對該bit寫入1能夠?qū)庠O(shè)中斷的狀態(tài)設(shè)置為pending,讀取對應bit則可以知道該中斷是否處于pending狀態(tài)。
在多處理器系統(tǒng)中,GICD_ISPENDR0(PPI和SGI)寄存器被每個與GIC相連的處理器banked(復用)。
從GICD_ISPENDR0開始,寄存器里每個bit代表一個不同中斷ID的中斷控制位,比如GICD_ISPENDR0[0]表示控制中斷ID為0的中斷。
對該寄存器進行讀取:
- 讀到0:表明對應中斷在任何處理器中都不處于pending狀態(tài)。
- 讀到1:
- 對于SGI和PPI中斷,當前中斷在當前處理器中是pending狀態(tài)的。
- 對于SPI中斷,當前中斷至少在一個處理器中處于pending狀態(tài)。
上文提到過,對于SGI中斷,寫入GICD_ISPENDRn寄存器的操作將會被忽略,因為SGI有自己的Set-pending寄存器 SGI
Set-Pending Registers, GICD_SPENDSGIRn。對于SPI和PPI中斷來講:
- 寫入0:無影響
- 寫入1:其效果取決于是邊緣觸發(fā)還是電平敏感中斷:
- 邊緣觸發(fā)(Edge-triggered),如果當前中斷已經(jīng)是pending狀態(tài),則不受影響;如果之前是inactive狀態(tài),則會變成pending狀態(tài);如果之前是active狀態(tài),則會變成active and pending狀態(tài)。
- 電平敏感(Level sensitive),如果當前中斷已經(jīng)是pending狀態(tài),如果對應中斷信號已經(jīng)被asserted,寫操作將不會改變中斷的狀態(tài),但是該中斷信號被deasserted后該中斷將仍保持pending狀態(tài);如果對應中斷未處于pending狀態(tài),如果之前是inactive狀態(tài),則會變成pending狀態(tài);如果之前是active狀態(tài),則會變成active and pending狀態(tài)。
2.2 Interrupt Clear-Pending Registers, GICD_ICPENDRn
GICD_ICPENDRs為GIC支持的每個中斷提供一個Clear-pending bit。寫入對應中斷的Clear-pending位將清除該中斷的pending狀態(tài)。讀取該bit位是否為1可以確定中斷是否處于pending狀態(tài)。
對該寄存器進行讀取:
- 讀到0:表明對應中斷在任何處理器中都不處于pending狀態(tài)。
- 讀到1:
- 對于SGI和PPI中斷,當前中斷在當前處理器中是pending狀態(tài)的。
- 對于SPI中斷,當前中斷至少在一個處理器中處于pending狀態(tài)。
對于SPI和PPI中斷來講:
- 寫入0:無影響
- 寫入1:其效果取決于是邊緣觸發(fā)還是電平敏感中斷:
- 邊緣觸發(fā)(Edge-triggered),如果中斷不處于pending狀態(tài),則不受影響。如果之前是pending狀態(tài),則會變成inactive狀態(tài);如果之前是active and pending狀態(tài),則會變成active狀態(tài)。
- 電平敏感(Level sensitive),如果當前中斷的pending狀態(tài)是由于寫入GICD_ISPENDRn寄存器導致的:如果之前是pending狀態(tài),則會變成inactive狀態(tài);如果之前是active and pending狀態(tài),則會變成active狀態(tài)。否則,如果中斷信號仍被asseted,中斷將保持pending狀態(tài)。
三、查找處于active或者pending狀態(tài)的中斷
若想知道一個中斷是否處于pending狀態(tài),可以讀取 GICD_ISPENDRn 或者GICD_ICPENDRn寄存器。若想知道中斷是否處于active狀態(tài),可以讀取 GICD_ISACTIVERn 或者GICD_ICACTIVERn,這兩個寄存器有Set-active和clear-active 位用來控制中斷的active狀態(tài)。
四、產(chǎn)生SGI中斷
處理器可以通過寫入GICD_SGIR寄存器來產(chǎn)生一個SGI中斷,一個SGI中斷可以設(shè)置多個目標處理器,并且SGIR寄存器里有目標寄存器列表。GICD_SGIR包括如下優(yōu)化:
- 只中斷寫入GICD_SGIR的處理器
- 中斷除寫入GICD_SGIR的處理器以外的所有處理器
- 來自不同處理器的SGI中斷使用同一個中斷ID,所以任何目標處理器可以收到來自不同處理器產(chǎn)生的相同中斷ID的SGI。但是如果以下條件不同,則任意兩個SGI中斷的pending狀態(tài)是獨立的:
- 中斷ID
- 源處理器
- 目標處理器
在CPU interface中,在任何時候,一次只能有一個特定中斷ID的中斷處于active狀態(tài),這意味著CPU interface不能同時有兩個SGI處于active狀態(tài),甚至是不同處理器使用相同中斷ID的SGI中斷發(fā)送中斷信號到該處理器。
在目標處理器的CPU interface中,通過讀取 GICC_IAR寄存器,可以獲得中斷ID,以及產(chǎn)生該中斷的CPU ID,即源處理器ID。中斷ID加上源處理器ID,可以讓目標處理器獲知該中斷獨一無二的來源。
此外,在多處理器系統(tǒng)中,每個SGI中斷的優(yōu)先級可以為每個目標處理器單獨設(shè)置,詳情可查看 Interrupt Priority Registers, GICD_IPRIORITYRn,中斷優(yōu)先級寄存器。對于每個CPU interface來講,對于所有優(yōu)先級相同的,特定中斷ID的,處于pending狀態(tài)的SGI中斷,CPU interface序列化地處理它們,具體的系列化處理順序取決于系統(tǒng)的實現(xiàn)定義(IMPLEMENTATION SPECIFIC.)。
4.1 Software Generated Interrupt Register, GICD_SGIR
處理器寫入GICD_SGIR可以產(chǎn)生SGI中斷。使用限制:通過寫入 GICD_CTLR寄存器來將Distributor的轉(zhuǎn)發(fā)功能禁止,是否會影響GICD_SGIR,這個由具體的實現(xiàn)定義( IMPLEMENTATION DEFINED)。以下是GICD_SGIR寄存器的字段分配圖:
- [25:24] TargetListFilter:這將決定Distributor如何處理被請求的SGI中斷,即要轉(zhuǎn)發(fā)到何處:
- 0b00:將中斷轉(zhuǎn)發(fā)到在CPUTargetList定義的CPU interface中
- 0b01:將中斷轉(zhuǎn)發(fā)到所有CPU interface中,除了當前請求中斷的處理器。
- 0b10:將中斷轉(zhuǎn)發(fā)到當前請求SGI中斷的處理器相連的CPU interface中。
- 0b11:保留
- [23:16] CPUTargetList:如果TargetListFilter的值為0b00,CPUTargetList中將定義Distributor必須被轉(zhuǎn)發(fā)到的CPU interface。CPUTargetList中共八個bit,每個bit代表一個處理器。比如CPUTargetList[0]對應CPU interface 0,如果CPUTargetList[0]=1,表明該SGI中斷必須轉(zhuǎn)發(fā)到CPU interface 0。如果TargetListFilter的值為0b00,并且CPUTargetList也為0,說明Distributor不需要將中斷轉(zhuǎn)發(fā)到任何CPU interface。
- [15] NSATT:僅在系統(tǒng)包含安全擴展中實現(xiàn),如果沒有實現(xiàn)安全擴展,這個字段將保留。NSATT指定SGI需要的security value:
- 只有當SGI在該CPU interface上被配置為Group 0時,才將SGIINTID字段中指定的SGI轉(zhuǎn)發(fā)到指定的CPU interface。
- 只有當SGI在該CPU interface上被配置為Group 1時,才將SGIINTID字段中指定的SGI轉(zhuǎn)發(fā)到指定的CPU interface。
- 該字段只可以在安全狀態(tài)下被寫入,只有當指定的SGI中斷被配置成group 1時,任何對GICD_SGIR的非安全寫入才會生成SGI,并且忽略NSATT的值。
- [3:0] SGIINTID :需要被轉(zhuǎn)發(fā)到指定的CPU interface中的SGI中斷的中斷ID,范圍是0到15。
4.2 安全擴展下產(chǎn)生SGI中斷
如果GIC實現(xiàn)了安全擴展,通過寫入GICD_SGIR寄存器,使得SGI中斷轉(zhuǎn)發(fā)到指定的處理器,這取決于:
- 寫入GICD_SGIR的是Group 0(secure)還是Group 1(non-secure)
- 對于secure寫入SGIR,寫入 GICD_SGIR的NSATT字段的值。
- 在目標處理器中,特定的中斷是否被配置成Group 0(secure)還是Group 1(non-secure)。
GICD_IGROUPR0寄存器中保存了SGI中斷的安全狀態(tài)。在多處理器系統(tǒng)中, GICD_IGROUPR0被每個與之相聯(lián)的處理器banked(復用),所以系統(tǒng)可以為每個處理器獨立設(shè)置SGI中斷的安全狀態(tài)。對GICD_SGIR寄存器寫一次,可以配置多個目標處理器,對于每個目標處理器,Distributor將決定是否將SGI中斷轉(zhuǎn)發(fā)到該處理器。
下表展示了Distributor是否可以將SGI轉(zhuǎn)發(fā)到指定的CPU interface的真值表:
五、GIC 1-N模型
GIC在多處理器實現(xiàn)中,會使用1-N模型,處理有多個目標處理器的外設(shè)中斷,比如SPI。這意味著,這意味著,當GIC從其中一個目標處理器識別出一個中斷確認時,它將清除所有其他目標處理器上的中斷的pending狀態(tài)。GIC必須確保使用1-N模型處理的任何中斷時,只能被一個CPU interface確認,并且所有其他CPU interface都返回一個虛假中斷ID。
當目標處理器試圖確認中斷時,有兩種情況會發(fā)生:
- 處理器讀取 GICC_IAR寄存器,并獲得需要被服務的中斷的ID。在GICv1中,如果多個處理器讀取GICC_IAR寄存器的時間非常接近,可以會有多個處理器會獲取到該中斷ID。系統(tǒng)必修要求在目標處理器上運行的軟件來確保只有一個處理器能進行中斷服務程序。一種典型的實現(xiàn)方案是使用共享內(nèi)存,并且在中斷服務程序(interrupt service routine,ISR)中加鎖。
- 處理器讀取 GICC_IAR寄存器,獲取到虛假中斷ID:1023。該處理器會從中斷服務程序中返回,并且不用寫入GICC_EOIR寄存器。讀到虛假中斷ID,是因為原始的中斷不再 處于pending狀態(tài),一般是因為有其他目標處理器在處理該中斷。
評論
查看更多