ARM架構SMMU驅動詳解

驅動定義:

static struct platform_driver arm_smmu_driver = {
	.driver	= {
		.name			= "arm-smmu-v3",
		.of_match_table		= arm_smmu_of_match,
		.suppress_bind_attrs	= true,
	},
	.probe	= arm_smmu_device_probe,
	.remove	= arm_smmu_device_remove,
	.shutdown = arm_smmu_device_shutdown,
};

註冊爲platform_driver,對"arm,smmu-v3"設備識別並驅動其初始化,設備參數參考arm,smmu-v3.txt

        smmu@2b400000 {
                compatible = "arm,smmu-v3";
                reg = <0x0 0x2b400000 0x0 0x20000>;
                interrupts = <GIC_SPI 74 IRQ_TYPE_EDGE_RISING>,
                             <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>,
                             <GIC_SPI 77 IRQ_TYPE_EDGE_RISING>,
                             <GIC_SPI 79 IRQ_TYPE_EDGE_RISING>;
                interrupt-names = "eventq", "priq", "cmdq-sync", "gerror";
                dma-coherent;
                #iommu-cells = <1>;
                msi-parent = <&its 0xff0000>;
        };

probe過程:

調用函數arm_smmu_device_probe進行probe,首先devm_kzalloc分配struct arm_smmu_device結構,調用arm_smmu_device_dt_probe對dts參數進行解析來初始化smmu結構,具體參數如上面所示,解析過程不再詳細展開。

接着判斷是否bypass,然後通過platform_get_resource獲取到smmu的io資源信息,合法性檢查之後對其進行ioremap並將虛擬地址記錄在smmu->base中。通過platform_get_irq_byname_optional解析irq並記錄。

至此基本的參數解析過程已經完成,緊接着根據參數進行硬件的初始化,通過函數arm_smmu_device_hw_probe完成。arm_smmu_init_structures用於完成smmu對應的結構,初始化完成後將smmu信息設置爲platform device的private driver。至此開始reset設備,如設定bypass模式,清空數據等,然後將其添加到iommu系統中以供其他模塊調用,同時將arm_smmu_ops賦值給iommu,通過iommu_device_register進行註冊。最後是通過arm_smmu_set_bus_ops,對支持的bus設置iommu操作方法結構,均設置爲arm_smmu_ops。

重點需要分析的就是arm_smmu_ops,也就是smmu提供給外界設置其功能的接口。

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