Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d143647 authored by Jeremy Gebben's avatar Jeremy Gebben Committed by Tarun Karra
Browse files

iommu/arm-smmu: add support for TTBR0, CONTEXTIDR and PROCID attributes



Add fields to arm_smmu_cfg to store asid, vmid, and procid so that they
can queried easily.

Program the CONTEXTIDR register during attach so that the PROCID
attribute functions as expected.

Change-Id: I2e2b3926fbf021754e89edda9a6857d2e3a7138b
Signed-off-by: default avatarJeremy Gebben <jgebben@codeaurora.org>
parent 1923762d
Loading
Loading
Loading
Loading
+51 −2
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@
#define ARM_SMMU_CB_TTBR1_LO		0x28
#define ARM_SMMU_CB_TTBR1_HI		0x2c
#define ARM_SMMU_CB_TTBCR		0x30
#define ARM_SMMU_CB_CONTEXTIDR		0x34
#define ARM_SMMU_CB_S1_MAIR0		0x38
#define ARM_SMMU_CB_S1_MAIR1		0x3c
#define ARM_SMMU_CB_PAR_LO		0x50
@@ -397,11 +398,17 @@ struct arm_smmu_cfg {
	u8				cbndx;
	u8				irptndx;
	u32				cbar;
	u32				procid;
	u16				asid;
	u8				vmid;
};
#define INVALID_IRPTNDX			0xff
#define INVALID_CBNDX			0xff
#define INVALID_ASID			0xffff
#define INVALID_VMID			0xff

#define ARM_SMMU_CB_ASID(cfg)		((cfg)->cbndx + 1)
#define ARM_SMMU_CB_VMID(cfg)		((cfg)->cbndx + 2)
#define ARM_SMMU_CB_ASID(cfg)		((cfg)->asid)
#define ARM_SMMU_CB_VMID(cfg)		((cfg)->vmid)

enum arm_smmu_domain_stage {
	ARM_SMMU_DOMAIN_S1 = 0,
@@ -1285,6 +1292,8 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
		.tlb		= &arm_smmu_gather_ops,
	};

	cfg->asid = cfg->cbndx + 1;
	cfg->vmid = cfg->cbndx + 2;
	smmu_domain->smmu = smmu;
	pgtbl_ops = alloc_io_pgtable_ops(fmt, &smmu_domain->pgtbl_cfg,
					 smmu_domain);
@@ -1368,6 +1377,11 @@ static int arm_smmu_domain_init(struct iommu_domain *domain)

	smmu_domain->secure_vmid = VMID_INVAL;
	INIT_LIST_HEAD(&smmu_domain->pte_info_list);
	smmu_domain->cfg.cbndx = INVALID_CBNDX;
	smmu_domain->cfg.irptndx = INVALID_IRPTNDX;
	smmu_domain->cfg.asid = INVALID_ASID;
	smmu_domain->cfg.vmid = INVALID_VMID;

	mutex_init(&smmu_domain->init_mutex);
	spin_lock_init(&smmu_domain->pgtbl_lock);
	domain->priv = smmu_domain;
@@ -1949,6 +1963,31 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
		*((unsigned int *) data) = smmu_domain->cfg.cbndx;
		ret = 0;
		break;
	case DOMAIN_ATTR_TTBR0: {
		u64 val;
		/* not valid until we are attached */
		if (smmu_domain->smmu == NULL)
			return -ENODEV;

		val = smmu_domain->pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0];
		if (smmu_domain->cfg.cbar != CBAR_TYPE_S2_TRANS)
			val |= (u64)ARM_SMMU_CB_ASID(&smmu_domain->cfg)
					<< (32ULL + TTBRn_HI_ASID_SHIFT);
		*((u64 *)data) = val;
		ret = 0;
		break;
	}
	case DOMAIN_ATTR_CONTEXTIDR:
		/* not valid until attached */
		if (smmu_domain->smmu == NULL)
			return -ENODEV;
		*((u32 *)data) = smmu_domain->cfg.procid;
		ret = 0;
		break;
	case DOMAIN_ATTR_PROCID:
		*((u32 *)data) = smmu_domain->cfg.procid;
		ret = 0;
		break;
	default:
		ret = -ENODEV;
		break;
@@ -2013,6 +2052,16 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
			smmu_domain->attributes &= ~(1 << DOMAIN_ATTR_ATOMIC);
		break;
	}
	case DOMAIN_ATTR_PROCID:
		if (smmu_domain->smmu != NULL) {
			dev_err(smmu_domain->smmu->dev,
			  "cannot change procid attribute while attached\n");
			ret = -EBUSY;
			break;
		}
		smmu_domain->cfg.procid = *((u32 *)data);
		ret = 0;
		break;
	default:
		ret = -ENODEV;
	}