天天看點

【Linux中斷子系統】疑問記錄

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

【Linux中斷子系統】疑問記錄

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;
           

繼續閱讀