天天看點

linux IRQ Management(一)- ARM GIC

  • 學習ARM GIC (Generic Interrupt Controller )

1.Interrupt

  Interrupt是異步産生的,不是由CPU執行程式産生的,中斷屬于異常的一種,中斷是唯一與CPU運作無關的異常。

2.Interrupt Controller

  Interrupt Controller是連接配接外設中斷系統和CPU系統的橋梁。根據外設irq request line的多少,Interrupt Controller可以級聯。

  The Generic Interrupt Controller (GIC) architecture defines:

  • The architectural requirements for handling all interrupt sources for any PE connected to a GIC.
  • A common interrupt controller programming interface applicable to uniprocessor or multiprocessor systems.

  The GIC is an architected resource that supports and controls interrupts. It provides:

  • registers for managing interrupt sources
  • interrupt behavior
  • the routing of interrupts to one or more PEs(Processing element)

  Support for:

  • Locality-specific Peripheral Interrupts (LPIs).
  • Private Peripheral Interrupts (PPIs).
  • Software Generated Interrupts (SGIs).
  • Shared Peripheral Interrupts (SPIs).
  • Interrupt masking and prioritization.
  • Uniprocessor and multiprocessor systems.
  • Wakeup events in power management environments.

GIC-400 Interrupt Controller:

linux IRQ Management(一)- ARM GIC

2.1.Interrupts types

  • Peripheral interrupt: This is an interrupt asserted by a signal to the GIC.
    • SPI (Shared Peripheral Interrupt)

      This is a global peripheral interrupt that can be routed to a specified PE, or to one of a group of PEs.

    • PPI (Private Peripheral Interrupt)

      This is peripheral interrupt that targets a single, specific PE. An example of a PPI is an interrupt from the Generic Timer of a PE.

    • LPI (Locality-specific Peripheral Interrupt)

      In particular, LPIs are always message-based interrupts, and their configuration is held in tables in memory rather than registers.

  • Software-generated interrupt (SGI):

    This is an interrupt generated by software writing to a GICD_SGIR register in the GIC. The system uses SGIs for interprocessor communication.

2.2.Interrupt Identifiers

  Each interrupt source is identified by an ID number, referred to as an INTID. The available INTIDs are grouped into ranges, and each range is assigned to a particular type of interrupt.

linux IRQ Management(一)- ARM GIC

2.3.Interrupt prioritization

  This section describes interrupt prioritization in the GIC architecture. Prioritization describes the:

  • Configuration and control of interrupt priority.
  • Order of execution of pending interrupts.
  • Determination of when interrupts are visible to a target PE, including:
    • Interrupt priority masking.
    • Priority grouping.
    • Preemption of an active interrupt
linux IRQ Management(一)- ARM GIC

  通過設定GICD_IPRIORITYRn寄存器,來設定中斷的優先級。這個寄存器是位元組有效的,也就是一個位元組,對應一個中斷的優先級。優先級數值越小,那麼這個中斷的優先級越高。高優先級的中斷,是可以搶占低優先級的中斷。

2.4. GICv2 架構圖

linux IRQ Management(一)- ARM GIC

2.5.GICv3 Programmers’ model

  The register interface of a GICv3 interrupt controller is split into three groups:

  • Distributor interface
  • Redistributor interface
  • CPU interface
    linux IRQ Management(一)- ARM GIC
    如上所示:
  • Distributor
    • The Distributor block performs interrupt prioritization and distribution to the CPU interface blocks that connect to the processors in the system.
    • The Distributor block registers are identified by the GICD_ prefix. They contain global settings that affect all PEs connected to the interrupt controller.
  • Redistributors
    • Enabling and disabling SGIs and PPIs.
    • Setting the priority level of SGIs and PPIs.
    • Setting each PPI to be level-sensitive or edge-triggered.
    • Assigning each SGI and PPI to an interrupt group.
    • Controlling the state of SGIs and PPIs.
    • Base address control for the data structures in memory that support the associated interrupt properties and pending state for LPIs.
    • Power management support for the connected PE
  • CPU interfaces
    • Each CPU interface block performs priority masking and preemption handling for a connected processor in the system.A GIC can implement up to eight CPU interfaces, numbered from 0-7.
    • CPU interface block registers are identified by the GICC_ prefix.
    • When describing a GIC that includes the GIC Virtualization Extensions, a CPU interface is sometimes called a physical CPU interface, to avoid possible confusion with a virtual CPU interface.
  • Virtual CPU interfaces
    • The GIC Virtualization Extensions add a virtual CPU interface for each processor in the system.
  • GIC registers

    使用memory-mapped的方式去通路的,即記憶體會留有一片空間給GIC,cpu通過通路這部分空間,對gic進行操作。寄存器,分為以下:

    • GICD_*:Distributor registers
    • GICH_*:Virtual interface control registers
    • GICV_*:Virtual interface control registers
    • GICC_*:Virtual cpu interface registers
    • GICR_*:Redistributors registers

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

2.5.1.Distributor(中斷分發器)

  The GIC-400 Distributor receives interrupts and presents the highest priority pending interrupt to each CPU interface.

linux IRQ Management(一)- ARM GIC

  收集所有的中斷來源,并且為每個中斷源設定中斷優先級,中斷分組,中斷目的core。當有中斷産生時,将目前最高優先級中斷,發送給對應的cpu interface。Distributor 功能:

  • 全局中斷使能
  • 每個中斷的使能
  • 中斷的優先級
  • 中斷的分組
  • 中斷的目的core
  • 中斷觸發方式
  • 對于SGI中斷,傳輸中斷到指定的core
  • 每個中斷的狀态管理
  • 提供軟體,可以修改中斷的pending狀态

  Global settings

  The Distributor control register (GICD_CTLR) must be configured to enable the interrupt groups and to set the routing mode.

  • Enable Affinity routing (ARE bits)

    The ARE bits in GICD_CTLR control whether affinity routing is enabled. If affinity routing is not enabled, GICv3 can be configured for legacy operation . Whether affinity routing is enabled or not can be controlled separately for Secure and Non-secure state.

  • Enables

    GICD_CTLR contains separate enable bits for Group 0, Secure Group 1 and Non-secure Group 1:

    • GICD_CTLR.EnableGrp1S enables distribution of Secure Group 1 interrupts.
    • GICD_CTLR.EnableGrp1NS enables distribution of Non-secure Group 1 interrupts.
    • GICD_CTLR.EnableGrp0 enables distribution of Group 0 interrupts.

2.5.2.Cpu Interface

  Each CPU interface block provides the interface for a processor that is connected to the GIC. CPU interface hosts registers to mask, identify and control states of interrupts forwarded to that core.Each CPU interface provides a programming interface for:

  • enabling the signaling of interrupt requests to the processor
  • acknowledging an interrupt
  • indicating completion of the processing of an interrupt
  • setting an interrupt priority mask for the processor
  • defining the preemption policy for the processor
  • determining the highest priority pending interrupt for the processor.

  When enabled, a CPU interface takes the highest priority pending interrupt for its connected processor and determines whether the interrupt has sufficient priority for it to signal the interrupt request to the processor. To determine whether to signal the interrupt request to the processor, the CPU interface considers the interrupt priority mask and the preemption settings for the processor. At any time, the connected processor can read the priority of its highest priority active interrupt from its GICC_HPPIR, a CPU interface register.

2.5.3.Interrupt states

  The interrupt controller maintains a state machine for each SPI, PPI and SGI interrupt source. This state machine consists of four states:

  • Inactive

    The interrupt source is not currently asserted.

  • Pending

    The interrupt source has been asserted, but the interrupt has not yet been acknowledged by a PE.

  • Active

    The interrupt source has been asserted, and the interrupt has been acknowledged by a PE.

  • Active and Pending

    An instance of the interrupt has been acknowledged, and another instance is now pending.

    linux IRQ Management(一)- ARM GIC
    State change:
  • Inactive to Pending

    An interrupt transitions from inactive to pending when the interrupt source is asserted.At this point the GIC asserts the interrupt signal to the PE (if the interrupt is enabled and is of sufficient priority).

  • Pending to Active & Pending

    The interrupt transitions from pending to active and pending when a PE acknowledges the interrupt by reading one of the GICC_IAR(Interrupt Acknowledge Registers,for Group 0 interrupts) or GICC_AIAR(Aliased Interrupt Acknowledge Register,for Group 1 interrupts) in the CPU interface. This read is typically part of an interrupt handling routine that executes after an interrupt exception is taken. However, software can also poll the GICC_IAR.At this point the GIC deasserts the interrupt signal to the PE.

  • Active and Pending to Active

    The interrupt transitions from active and pending to active when the peripheral de-asserts the interrupt signal. This typically happens in response to the interrupt handling software that is executing on the PE writing to a status register in the peripheral.

  • Active to Inactive

    The interrupt goes from active to inactive when the PE writes to one of the EOIRs (End of Interrupt Registers) in the CPU interface. This indicates that the PE has finished handling the interrupt.

2.5.4.Interrupt lifecycle

linux IRQ Management(一)- ARM GIC
  • Generate interrupt. An interrupt is generated either by the peripheral or by software.
  • Distribute. The IRI(Interrupt Routing Infrastructure) performs interrupt grouping, interrupt prioritization, and controls the forwarding of interrupts to the CPU interfaces.
  • Deliver. A physical CPU interface delivers interrupts to the corresponding PE.
  • Activate. When software running on a PE acknowledges an interrupt, the GIC sets the highest active priority to that of the activated interrupt, and for SPIs, SGIs, and PPIs the interrupt becomes active.
  • Priority drop. Software running on the PE signals to the GIC that the highest priority interrupt has been handled to the point where the running priority can be dropped. The running priority then has the value that it had before the interrupt was acknowledged. This is the point where the end of interrupt is indicated by the interrupt handler. The end of the interrupt can be configured to also perform deactivation of the interrupt.
  • Deactivation. Deactivation clears the active state of the interrupt, and thereby allows the interrupt, when it is pending, to be taken again. Deactivation is not required for LPIs. Deactivation can be configured to occur at the same time as the priority drop, or it can be configured to occur later as the result of an explicit interrupt deactivation operation. This latter approach allows for software architectures where there is an advantage to separating interrupt handling into initial handling and scheduled handling.

  When the processor acknowledges the interrupt at the CPU interface:

  • Distributor changes the status of the interrupt from pending to either active, or active and pending.
  • CPU interface can signal another interrupt to the processor, to preempt interrupts that are active on the processor. If there is no pending interrupt with sufficient priority for signaling to the processor, the interface deasserts the interrupt request signal to the processor.

  When the interrupt handler on the processor has completed the processing of an interrupt, it writes to the CPU interface to indicate interrupt completion. There are two stages to interrupt completion:

  • priority drop(優先級重置): the priority of the processed interrupt can no longer prevent the signaling of another interrupt to the processor.
  • interrupt deactivation(中斷無效): the Distributor removes the active state of the interrupt. Either:

    • from active and pending, to pending

    • from active, to idle.

  這兩個stages是否同時發生或者單獨發生可以通過the GICC_CTLR.EOI(End of Interrupt) mode bit determines:

  • the two stages happen together, when the processor writes to the CPU interface End of Interrupt register.
  • the two stages are separated, so that:
    • priority drop happens when the processor writes to the CPU interface End of Interrupt register.
    • interrupt deactivation happens later, when the processor writes to the CPU interface Deactivate Interrupt register.

  重點中斷完成為什麼定義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步。

2.6.中斷案例分析

  How the GIC-400 handles two physical interrupts of different priority.In the example, interrupts N and M:

• Are set to be level-sensitive.

• Are SPIs, so they are signaled using the active-HIGH IRQS input.

• Target the same processor.

• Are configured to be Group 0 and the GICC_CTLR of the target CPU interface has the FIQEn bit set, so they are signaled to that CPU as FIQs.

linux IRQ Management(一)- ARM GIC
  • T1 The Distributor detects the assertion of Group 0 interrupt M.
  • T2 The Distributor sets interrupt M to pending.
  • T17 The CPU interface asserts nFIQCPU[n].

    The assertion of nFIQCPU[n] occurs some CLK cycles after interrupt M becomes pending. In Figure B-1, the latency at the physical interface is tph = 15 clock cycles.

  • T42 The Distributor detects the assertion of a higher priority Group 0 interrupt, N.
  • T43 The Distributor replaces interrupt M with interrupt N as the highest priority pending interrupt and sets N to pending.
  • T58 tph clock cycles after interrupt N became pending, the CPU interface asserts nFIQCPU[n]. The state of nFIQCPU[n] is unchanged because nFIQCPU[n] was asserted at T17. The CPU interface updates the InterruptID field in the GICC_IAR, to contain the ID value for interrupt N.
  • T61 The processor reads the GICC_IAR, acknowledging the highest priority pending interrupt, N.The Distributor sets interrupt N to active and pending.
  • T61-T131 The processor services interrupt N.
  • T64 3 clock cycles after interrupt N has been acknowledged, the CPU interface

    deasserts nFIQCPU[n].

  • T126 The peripheral deasserts interrupt N.
  • T128 The pending state is removed from N.
  • T131 The processor writes to the End of Interrupt Register, GICC_EOIR, with the ID of interrupt N and the Distributor deactivates interrupt N.
  • T146 tph clock cycles after GICC_EOIR was written to for N, the Distributor forwards the new highest priority pending interrupt, M, to the CPU interface, which asserts nFIQCPU[n].
  • T211 The processor reads the GICC_IAR, acknowledging the highest priority pending interrupt, M, and the Distributor sets interrupt M to active and pending.
  • T214 3 clock cycles after interrupt M has been acknowledged, the CPU interface deasserts nFIQCPU[n].

2.7.中斷分組

  The GICv3 architecture supports the ARM TrustZone technology. Each INTID must be assigned a group and security setting. GICv3 supports three combinations:

linux IRQ Management(一)- ARM GIC

  Group 0 interrupts are always signaled as FIQs. Group 1 interrupts are signaled as either IRQs or FIQs depending on the current Security state and Exception level of the PE.

2.8.Interrupt enables

For peripheral interrupts, a processor:

  • enables an interrupt by writing to the appropriate GICD_ISENABLERn(Interrupt Set-Enable Registers) bit
  • disables an interrupt by writing to the appropriate GICD_ICENABLERn(Interrupt Clear-Enable Registers) bit

3.Linux GIC code

drivers/irqchip目錄下儲存在各種不同的中斷控制器的驅動代碼:

  • irq-gic-common.c中是GIC V2和V3的通用代碼;
  • irq-gic.c是V2 specific的代碼;
  • irq-gic-v3.c是V3 specific的代碼

參考資料:

http://www.lujun.org.cn/?p=3874

Arm® Generic Interrupt Controller Architecture Specification GIC architecture version 3 and version 4.pdf

GICv3_Software_Overview_Official_Release_B.pdf

繼續閱讀