中斷管理基礎學習筆記 - 1.概述【轉】

轉自:https://blog.csdn.net/jasonactions/article/details/115536240?spm=1001.2014.3001.5501

目錄
1. 前言
2. 中斷控制器
2.1 Linux內核中斷管理分層架構
2.2 GIC中斷控制器
3. 虛擬中斷號和硬中斷號
4. 中斷管理主要數據結構
參考文檔
1. 前言
本專題我們開始學習進程管理部分。本文主要參考了《奔跑吧, Linux內核》、ULA、ULK的相關內容。
本節記錄ARM架構下中斷是如何管理的,Linux內核中的中斷管理機制是如何設計與實現的,以及常用的下半部機制,如軟中斷、tasklet、workqueue等。本文及後續中斷相關筆記均以qemu 5.0.0內嵌平臺爲例,中斷控制器採用GIC-400控制器,支持GIC version2技術規範。

kernel版本:5.10
平臺:arm64

注:
爲方便閱讀,正文標題採用分級結構標識,每一級用一個"-“表示,如:兩級爲”|- -", 三級爲”|- - -“

2. 中斷控制器
2.1 Linux內核中斷管理分層架構
硬件層:CPU和中斷控制器的連接;
處理器架構管理層:如CPU中斷異常處理;
中斷控制器管理層:如IRQ號的映射;
Linux內核通用中斷處理層:如中斷註冊與中斷處理

2.2 GIC中斷控制器

 

 


GIC中斷控制器構成
1.distributor
集中管理所有中斷源
(1)配置中斷的優先級
(2)設置每個中斷可路由的CPU列表
(3)向各個CPU interface配送最高優先級的中斷
(4)中斷屏蔽、中斷搶佔
(5)配置中斷是邊緣觸發還是水平觸發。
2.cpu interface
cpu interface是GIC連接到CPU的接口,每個cpu intterface提供了一個編程接口,主要功能包括:
(0) 使能中斷請求信號到CPU;
(1) acknowledging中斷,表示CPU接受到中斷請求;
(2)指示中斷的處理完成;
(3)設置處理器中斷優先級,高於此優先級方可發送給處理器;
(4)設置處理器的搶佔策略;
(5)確定處理器的最高優先級待處理中斷?
支持的中斷類型
中斷類型 硬件中斷號範圍 含義 應用場景
SGI私有軟件觸發中斷 0~15 用於多核之間的通信 通常用於多核通信,linux通常用作IPI中斷,傳達到系統指定的CPU上
PPI私有外設中斷 16~31 每個處理器核心私有的中斷 如CPU本地時鐘local timer
SPI公用外設中斷 32~1019 公用的外設中斷 用於公用外設的中斷,如按鍵、SPI、TP等

 

 


中斷狀態

 

 

inactive(不活躍)狀態:中斷處於無效狀態;
pending(等待)狀態:中斷處於有效狀態,但是等待CPU響應該中斷;
active(活躍)狀態:CPU已經響應中斷;
active and pending(活躍並等待)狀態:CPU正在響應中斷,但是該中斷源又發送中斷過來
參考: 《ARM® Generic Interrupt Controller Architecture version 2.0 》3.2.4 Interrupt handling state machine
Transition A1 or A2, add pending state
(1) For an SGI, occurs if either:
• Software writes to a GICD_SGIR that specifies the processor as a target.
• Software on the target processor writes to the GICD_SPENDSGIRn bit that corresponds to the required source processor and interrupt ID
(2) For an SPI or PPI, occurs if either:
• a peripheral asserts an interrupt request signal
• software writes to an GICD_ISPENDRn.
Transition B1 or B2, remove pending state
(1) For an SGI, occurs if software on the target processor writes to the relevant bit of the GICD_CPENDSGIRn.
(2) For an SPI or PPI, occurs if either:
• the level-sensitive interrupt is pending only because of the assertion of an input signal, and that signal is deasserted
• the interrupt is pending only because of the assertion of an edge-triggered interrupt signal, or a write to an GICD_ISPENDRn, and software writes to the corresponding GICD_ICPENDRn.
Transition C, pending to active
If the interrupt is enabled and of Sufficient priority to be signaled to the processor, occurs when software reads from the GICC_IAR
Transition D, pending to active and pending
(1) For an SGI, this transition occurs in either of the following circumstances:
•If a write to set the SGI state to pending occurs at approximately the same time as a read of GICC_IAR.
• When two or more pending SGIs with the same interrupt ID originate from the same source processor and target the same processor. If one of the SGIs follows transition C, the other SGIs follow transition D
(2) For an SPI or PPI this transition occurs if all the following apply:
• The interrupt is enabled.
• Software reads from the GICC_IAR. This read adds the active state to the interrupt.
• In addition, one of the following conditions applies:
— For a level-sensitive interrupt, the interrupt signal remains asserted. This is usually the case, because the peripheral does not deassert the interrupt until the processor has serviced the interrupt.
— For an edge-triggered interrupt, whether this transition occurs depends on the timing of the read of the GICC_IAR relative to the detection of the reassertion of the interrupt.Otherwise the read of the GICC_IAR causes transition C, possibly followed by transition A2.
Transition E1 or E2, remove active state
Occurs when software deactivates an interrupt by writing to either GICC_EOIR or GICC_DIR. For more information see Priority drop and interrupt deactivation on page 3-38. In a GIC implementation the includes the Virtualization Extensions, also occurs if the virtual CPU interface signals that the corresponding physical interrupt has been deactivated.

注:assert的意思就是把信號變爲active(可以理解爲有效),根據系統有求不同,該有效電平可以是高電平(即高有效)也可以是低電平(即低有效)。deassert的意思就是解除active狀態,就是信號變爲非active狀態,可以是高也可以是低。
從如上可以看出,對於SPI:
! pending -> pending的條件是中斷信號assert;
pending -> ! pending的條件是中斷信號deassert;
pending -> active的條件是中斷信號發送給cpu
active pending -> active or active -> inactive的條件是中斷信號被deactive

參考:https://www.cnblogs.com/LoyenWang/p/12996812.html

 

 


GIC檢測中斷的流程
1.當GIC檢測到一箇中斷髮生,會將中斷標記爲pending狀態;
2.distributor會從衆多pending狀態的中斷中選擇一個優先級最高的中斷,發送到目標CPU的CPU interface;
3.CPU interface決定這個中斷是否可以發送給CPU,如果該中斷的優先級滿足要求,GIC會發生一箇中斷請求信號給該CPU;
4.當一個CPU進入中斷異常後,會去讀取GICC_IAR寄存器來響應該中斷。寄存器會返回硬件中斷號,當GIC感知到軟件讀取了該寄存器:
(1)如果中斷源是pending狀態,那麼狀態變爲active;
(2)如果該中斷又重新產生,那麼pending狀態變爲active and pending;
(3)如果該中斷是active狀態,現在變爲 active and pending;
5.當處理器完成中斷服務,必鬚髮送一個完成信號EOI給GIC控制器(通過軟件寫EOIR),表示結束此中斷的處理過程。
注:GIC總是會選擇優先級最高的pending的中斷髮送給CPU
通過cat /proc/interrupts可以查看到當前平臺的中斷源,及對應的GIC硬件中斷號和LINUX分配的軟中斷號(虛擬中斷號)

3. 虛擬中斷號和硬中斷號
虛擬中斷號
<include/asm-generic/irq.h>
/*
* NR_IRQS is the upper bound of how many interrupts can be handled
* in the platform. It is used to size the static irq_map array,
* so don't make it too big.
*/
#ifndef NR_IRQS
#define NR_IRQS 64
#endif

NR_IRQS:表示系統支持的最大的虛擬中斷號數量,它與平臺相關

<kernel/irq/internals.h>
#ifdef CONFIG_SPARSE_IRQ
# define IRQ_BITMAP_BITS (NR_IRQS + 8196)
#else
# define IRQ_BITMAP_BITS NR_IRQS
#endif

<kernel/irq/irqdesc.c>
static DECLARE_BITMAP(allocated_irqs, IRQ_BITMAP_BITS);

Linux定義了位圖來管理這些虛擬中斷號,allocated_irqs變量分配IRQ_BITMAP_BITS個bit位,每個bit位代表一箇中斷

硬中斷號
1.0~31中斷號給了SGI和PPI
2.其它外設中斷號從32開始
3.dts中會用interrupts = <硬中斷號n>來指定硬件中斷號,其中硬中斷號n爲板子上的硬件中斷號,真正的硬件中斷號32+n
如下以qemu 5.0.0自帶的DTS爲例說明:

 

 

如上從dts中可看出串口的interrupts值爲1,代表它在板級的硬件中斷號爲1,但是要對應到GIC的硬件中斷號需要轉換(因爲外設硬中斷號從32開始)

 

 

經轉換後的硬件中斷後爲33,它對應GIC的硬件中斷號
4.每一款ARM SOC芯片設計階段,各種中斷和外設的分配情況要固定下來,通過查詢芯片手冊來確定外設的硬件中斷號。
注:
dts中的interrupts域主要包含三個屬性:
1.中斷類型:GIC_SPI(共享外設重案,用0表示);GIC_PPI(私有外設中斷,用1表示);
2.中斷ID;
3.觸發類型:IRQ_TYPE_EDGE_RISING:1,IRQ_TYPE_EDGE_FALLING:2,IRQ_TYPE_EDGE_BOTH:3,IRQ_TYPE_LEVEL_HIGH:4,IRQ_TYPE_LEVEL_LOW:8

4. 中斷管理主要數據結構

 

 


struct irq_domain
Linux 3.1引入,用來描述一箇中斷控制器, 對於GIC是在gic初始化時會註冊irq_domain
struct irq_chip
用於描述中斷控制器底層操作相關的函數操作集合
struct irq_desc
中斷描述符,每個中斷都有一箇中斷描述符
struct irqaction
用於描述某個中斷的處理函數
參考文檔
奔跑吧,Linux內核
ARM® Generic Interrupt Controller Architecture version 2.0
【原創】Linux中斷子系統(一)-中斷控制器及驅動分析
————————————————
版權聲明:本文爲CSDN博主「HZero.chen」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/jasonactions/article/details/115536240

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章