IRQ Number 軟體虛拟的 辨別外設中斷
HW interrupt ID 硬體上的辨別外設中斷
1、irq domain幹什麼用的,為什麼要使用它?
irq domain就是指中斷領域,任何超出這個範圍的定義就沒有意義了。
IRQ domain來描述一個中斷控制器(IRQ Controller)所管理的中斷源。換句話說,每個中斷控制器都有自己的domain。我們可以将IRQ Domain看作是IRQ Controller的軟體抽象。
這裡所說的“中斷控制器”,不僅指硬體上實際存在的中斷控制器,也可以是一個“虛拟”的中斷控制器。例如,假設我們有一塊CPU,它有多個GPIO Pin可以作為外部中斷源使用(事實上大多數嵌入式CPU都有這樣的GPIO)。
我們還假定所有的GPIO中斷都複用到該CPU的同一個中斷向量。在這樣的情況下,這多個GPIO中斷就可以抽象成一個虛拟的中斷控制器,它連接配接到CPU的某個中斷向量上。
這樣做的好處在于,可以将“對中斷控制器的中斷響應”和“對産生中斷的外部裝置的中斷響應”分離開來。我們還是看一個例子,假定我們有若幹個GPIO,分别接了不同外設(如按鍵、外部以太網控制器等),
當這些外設産生中斷的時候,CPU内部的GPIO控制器會置位相應的中斷标志位,并向CPU送出中斷請求。這樣,對每一個外設中斷,我們實際上要進行兩級中斷服務:第一級中斷服務判斷是哪個GPIO産生了中斷,
并需要清除GPIO控制器内部某個寄存器中的某個标志位;第二級中斷服務才是服務産生中斷的那個外設的。顯然,第一級中斷服務代碼對每個産生GPIO中斷的外設是類似的。有了IRQ Domain的幫助,
第一級中斷服務代碼就可以統一,裝置驅動程式隻需要關心第二級中斷服務就可以了。
2、如何注冊一個irq domain,注冊irq domain的動作到底是做什麼了操作?
三種方法:
1、irq_domain_add_linear (線性映射)
2、irq_domain_add_tree (Radix Tree map)
3、irq_domain_add_nomap (no map)
根據自己的映射類型,初始化struct irq_domain中的各個成員,
調用__irq_domain_add将該irq domain挂入irq_domain_list的全局清單
3、為什麼IRQ Number需要HW interrupt ID映射過來?
1、驅動工程師而言,我們和CPU視角是一樣的,我們隻希望得到一個IRQ number,而不關系具體是那個interrupt controller上的那個HW interrupt ID。
這樣一個好處是在中斷相關的硬體發生變化的時候,驅動軟體不需要修改
2、interrupt controller級聯的情況下,僅僅使用HW interrupt ID已經不能唯一辨別一個外設中斷,還需要知道HW interrupt ID所屬的interrupt controller
因為HW interrupt ID在不同的interrupt controller上是會重複編碼。
4、如何知道系統irq domain的目前采用哪種映射關系?
映射有三種:
1、線性映射
2、Radix Tree map (powerPC和MIPS硬體平台用到)
3、no map 即:hw interrupt id就是 irq number,寄存器配置HW interrupt ID而不是實體連接配接特性決定
是以arm架構使用 線性映射
5、如何擷取HW interrupt ID?
interrupt controller會對連接配接其上的interrupt source(根據其在Interrupt controller中實體特性)進行編号(也就是HW interrupt ID了
int (*xlate)(struct irq_domain *d, struct device_node *node,
const u32 *intspec, unsigned int intsize,
unsigned long *out_hwirq, unsigned int *out_type);
軟體上通過調用 irq domain的irq_domain_ops結構的xlate回調函數成員 将指定的裝置(node參數)上若幹個(intsize參數)中斷屬性(intspec參數)翻譯成HW interrupt ID(out_hwirq參數)和trigger類型(out_type)。
6、HW interrput ID如何轉換成IRQ number?
由IRQ domain負責,通過irq_create_mapping
7、什麼是interrupt flow control?
中斷流控制
軟體上設定一些标志位和硬體上 mask或者unmask interrupt controller等,具體表現為調用中斷描述符的irq chip driver進行mask,ack等callback函數。
8、每一個IRQ都有中斷描述符嗎?
系統中每一個連接配接外設的中斷線(irq request line)用一個中斷描述符來描述,每一個外設的interrupt request line配置設定一個中斷号(irq number),
系統中有多少個中斷線(或者叫做中斷源)就有多少個中斷描述符struct irq_desc
NR_IRQS定義了該硬體平台IRQ的最大數目
linux核心中有一個資料結構儲存了所有中斷描述符的資訊,具體表現為以下兩種:
(1)即一個靜态定義的數組,irq number作為index, 有空洞,存在空間浪費
(2)打開CONFIG_SPARSE_IRQ 使用Radix tree儲存,這時候,每一個中斷描述符都是動态配置設定,然後插入到radix tree中
描述一個具體的中斷 struct irq_desc,簡稱中斷描述符
描述一個具體中斷的底層相關資料結構 struct irq_data
描述一個具體中端底層若幹和具體interrupt controller相關的callback函數 strcut irq_chip
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPR1UMFpWW6J1MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL2ADO5ITMzIjM1EzNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
9、GIC支援多少個中斷号?
linux-4.9/drivers/irqchip/irq-gic.c
/*
* Find out how many interrupts are supported.
* The GIC only supports up to 1020 interrupt sources.
*/
gic_irqs = readl_relaxed(gic_data_dist_base(gic) + GIC_DIST_CTR) & 0x1f;
gic_irqs = (gic_irqs + 1) * 32;
if (gic_irqs > 1020)
gic_irqs = 1020;