【精选】IOMMU/SMMUV3代码分析(4)IO设备与SMMU的关联1_iommu_ops_linux解码者的博客

iort_iommu_configure_id
	iort_pci_iommu_init
		iort_iommu_xlate			//根据SMMU类型的acpi_iort_node 找出fwnode_handle,再找出iommu_ops
			arm_smmu_iort_xlate
				iommu_fwspec_init //kzalloc 创建iommu_fwspec    ,关联iommu_fwspec
					fwspec->iommu_fwnode = iommu_fwnode(上面找出的类型fwnode_handle)
					fwspec->ops = ops
					dev_iommu_fwspec_set  // dev->iommu->fwspec = fwspec   
	iort_add_device_replay
		iommu_probe_device
			__iommu_probe_device
				dev_iommu_get //分配dev->iommu (dev_iommu结构体)
				iommu_dev = ops->probe_device(dev)   //找到device在硬件上关联的iommu_device(arm_smmu_device成员)   ------(1)
				dev->iommu->iommu_dev = iommu_dev;
				iommu_group_get_for_dev  //创建iommu_group
					group = ops->device_group(dev);
						pci_device_group(dev)/generic_device_group(dev)   ----- (2)
					iommu_group_add_device(group, dev) //添加device到sysfs gorup目录
						dev->iommu_group = group; 
			iommu_group_get
			iommu_alloc_default_domain
			__iommu_attach_device



(1):arm-smmu-v3.c
arm_smmu_probe_device
	dev_iommu_fwspec_get	//获取到device的iommu_fwspec
	arm_smmu_get_by_fwnode	  //根据arm_smmu_drivr驱动找设备。。、以及iommu_fwspec->iommu_fwnode
		
		
(2)iommu.c
pci_device_group
	iommu_group_alloc  //分配内存,并创建/sys/kernel/iommu_groups/
		kzalloc
		ida_simple_get //分配唯一id
		kobject_init_and_add
		kobject_create_and_add



struct device {
	struct fwnode_handle	*fwnode;
	struct iommu_group	*iommu_group;
	struct dev_iommu	*iommu;

}


struct dev_iommu {
	struct mutex lock;
	struct iommu_fault_param	*fault_param;
	struct iopf_device_param	*iopf_param;
	struct iommu_fwspec		*fwspec;
	struct iommu_device		*iommu_dev;
	void				*priv;
};

struct iommu_fwspec {
	const struct iommu_ops	*ops;
	struct fwnode_handle	*iommu_fwnode;
	u32			flags;
	unsigned int		num_ids;
	u32			ids[];
};


//
struct fwnode_handle {
	struct fwnode_handle *secondary;
	const struct fwnode_operations *ops;
	struct device *dev;
	struct list_head suppliers;
	struct list_head consumers;
	u8 flags;
};

设备树:

pci:
[    2.228735]  of_dma_configure_id+0x154/0x280
[    2.233001]  pci_dma_configure+0x44/0xd0
[    2.236919]  really_probe+0xa0/0x490
[    2.240488]  driver_probe_device+0x58/0xc0
[    2.244579]  __device_attach_driver+0xa8/0x10c
[    2.249016]  bus_for_each_drv+0x78/0xd0
[    2.252845]  __device_attach+0xdc/0x180
[    2.256674]  device_attach+0x14/0x20
[    2.260244]  pci_bus_add_device+0x50/0xb4
[    2.264247]  pci_bus_add_devices+0x3c/0x8c
[    2.268338]  pci_host_probe+0x40/0xc4
[    2.271995]  pci_host_common_probe+0x110/0x190
[    2.276434]  platform_drv_probe+0x54/0xb0
[    2.280437]  really_probe+0xe4/0x490
[    2.284006]  driver_probe_device+0x58/0xc0

platform:
[    3.305584]  dump_stack+0xd0/0x12c
[    3.308982]  of_dma_configure_id+0x154/0x280
[    3.313249]  platform_dma_configure+0x20/0x90
[    3.317600]  really_probe+0xa0/0x490
[    3.321169]  driver_probe_device+0x58/0xc0
[    3.325259]  device_driver_attach+0xc0/0xd0
[    3.329436]  __driver_attach+0x84/0x124
[    3.333265]  bus_for_each_dev+0x70/0xd0
[    3.337094]  driver_attach+0x24/0x30
[    3.340664]  bus_add_driver+0x104/0x1ec
[    3.344493]  driver_register+0x78/0x130
[    3.348323]  __platform_driver_register+0x4c/0x60
[    3.353023]  macb_driver_init+0x1c/0x28
[    3.356852]  do_one_initcall+0x50/0x1b0






of_iommu_configure
	of_pci_iommu_init  //pci
		of_iommu_configure_dev_id
			of_iommu_xlate
				iommu_fwspec_init
			
	of_iommu_configure_device
		of_iommu_configure_dev_id
			of_iommu_xlate
				iommu_fwspec_init
		of_iommu_configure_dev
			of_iommu_xlate
				iommu_fwspec_init