__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