__arm_smmu_tlb_sync呼叫過程

yooooooo發表於2024-10-20

__arm_smmu_tlb_sync呼叫過程

這個函式分別在兩處地方被呼叫:

  • arm_smmu_tlb_sync_global
#define ARM_SMMU_GR0(smmu)		((smmu)->base)
#define ARM_SMMU_GR0_sTLBGSYNC		0x70
#define ARM_SMMU_GR0_sTLBGSTATUS	0x74
static void arm_smmu_tlb_sync_global(struct arm_smmu_device *smmu)
{
	void __iomem *base = ARM_SMMU_GR0(smmu);
	unsigned long flags;

	spin_lock_irqsave(&smmu->global_sync_lock, flags);
	__arm_smmu_tlb_sync(smmu, base + ARM_SMMU_GR0_sTLBGSYNC,
			    base + ARM_SMMU_GR0_sTLBGSTATUS);
	spin_unlock_irqrestore(&smmu->global_sync_lock, flags);
}

1、透過ARM_SMMU_GR0(smmu)宏獲取SMMU的基地址,將其儲存在base變數中。

2、呼叫arm_smmu_tlb_sync函式,傳入全域性同步暫存器TLBGSYNC和狀態暫存器TLBGSTATUS的地址。這個函式通常負責發起TLB的同步操作,並檢查同步的狀態。

  • arm_smmu_tlb_sync_context
#define ARM_SMMU_CB(smmu, n)	((smmu)->cb_base + ((n) << (smmu)->pgshift))
#define ARM_SMMU_CB_S1_TLBIASID		0x610
static void arm_smmu_tlb_inv_context_s1(void *cookie)
{
	struct arm_smmu_domain *smmu_domain = cookie;
	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
	void __iomem *base = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx);

	writel_relaxed(cfg->asid, base + ARM_SMMU_CB_S1_TLBIASID);
	arm_smmu_tlb_sync_context(cookie);
}

arm_smmu_tlb_sync_global呼叫

arm_smmu_tlb_sync_global在兩處分別被呼叫:

  • arm_smmu_tlb_inv_context_s2
/* Global TLB invalidation */
#define ARM_SMMU_GR0_TLBIVMID		0x64
static void arm_smmu_tlb_inv_context_s2(void *cookie)
{
	struct arm_smmu_domain *smmu_domain = cookie;
	struct arm_smmu_device *smmu = smmu_domain->smmu;
	void __iomem *base = ARM_SMMU_GR0(smmu);

	writel_relaxed(smmu_domain->cfg.vmid, base + ARM_SMMU_GR0_TLBIVMID);
	arm_smmu_tlb_sync_global(smmu);
}
  • arm_smmu_tlb_sync_vmid
static void arm_smmu_tlb_sync_vmid(void *cookie)
{
	struct arm_smmu_domain *smmu_domain = cookie;

	arm_smmu_tlb_sync_global(smmu_domain->smmu);
}
  • arm_smmu_device_reset

相關文章