drivers/iommu/vsi-iommu.c

Source file repositories/reference/linux-study-clean/drivers/iommu/vsi-iommu.c

File Facts

System
Linux kernel
Corpus path
drivers/iommu/vsi-iommu.c
Extension
.c
Size
20666 bytes
Lines
792
Domain
Driver Families
Bucket
drivers/iommu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct vsi_iommu {
	struct device *dev;
	void __iomem *regs;
	struct clk_bulk_data *clocks;
	int num_clocks;
	struct iommu_device iommu;
	struct list_head node; /* entry in vsi_iommu_domain.iommus */
	struct iommu_domain *domain; /* domain to which iommu is attached */
	spinlock_t lock; /* lock to protect vsi_iommu fields */
	int irq;
	bool enable;
};

struct vsi_iommu_domain {
	struct list_head iommus;
	struct device *dev;
	u32 *dt;
	dma_addr_t dt_dma;
	struct iommu_domain domain;
	u64 *pta;
	dma_addr_t pta_dma;
	spinlock_t lock; /* lock to protect vsi_iommu_domain fields */
};

static struct iommu_domain vsi_identity_domain;

#define NUM_DT_ENTRIES	1024
#define NUM_PT_ENTRIES	1024

#define SPAGE_SIZE	BIT(12)

/* vsi iommu regs address */
#define VSI_MMU_CONFIG1_BASE			0x1ac
#define VSI_MMU_AHB_EXCEPTION_BASE		0x380
#define VSI_MMU_AHB_CONTROL_BASE		0x388
#define VSI_MMU_AHB_TLB_ARRAY_BASE_L_BASE	0x38C

/* MMU register offsets */
#define VSI_MMU_FLUSH_BASE		0x184
#define VSI_MMU_BIT_FLUSH		BIT(4)

#define VSI_MMU_PAGE_FAULT_ADDR		0x380
#define VSI_MMU_STATUS_BASE		0x384	/* IRQ status */

#define VSI_MMU_BIT_ENABLE		BIT(0)

#define VSI_MMU_OUT_OF_BOUND		BIT(28)
/* Irq mask */
#define VSI_MMU_IRQ_MASK		0x7

#define VSI_DTE_PT_ADDRESS_MASK		0xffffffc0
#define VSI_DTE_PT_VALID		BIT(0)

#define VSI_PAGE_DESC_LO_MASK		0xfffff000
#define VSI_PAGE_DESC_HI_MASK		GENMASK_ULL(39, 32)
#define VSI_PAGE_DESC_HI_SHIFT		(32 - 4)

static inline phys_addr_t vsi_dte_pt_address(u32 dte)
{
	return (phys_addr_t)dte & VSI_DTE_PT_ADDRESS_MASK;
}

static inline u32 vsi_mk_dte(u32 dte)
{
	return (phys_addr_t)dte | VSI_DTE_PT_VALID;
}

#define VSI_PTE_PAGE_WRITABLE		BIT(2)
#define VSI_PTE_PAGE_VALID		BIT(0)

static inline phys_addr_t vsi_pte_page_address(u64 pte)
{
	return ((pte << VSI_PAGE_DESC_HI_SHIFT) & VSI_PAGE_DESC_HI_MASK) |
	       (pte & VSI_PAGE_DESC_LO_MASK);
}

static u32 vsi_mk_pte(phys_addr_t page, int prot)
{
	u32 flags = 0;

	flags |= (prot & IOMMU_WRITE) ? VSI_PTE_PAGE_WRITABLE : 0;

	page = (page & VSI_PAGE_DESC_LO_MASK) |
	       ((page & VSI_PAGE_DESC_HI_MASK) >> VSI_PAGE_DESC_HI_SHIFT);

	return page | flags | VSI_PTE_PAGE_VALID;
}

#define VSI_DTE_PT_VALID	BIT(0)

Annotation

Implementation Notes