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

Commit 72ac9228 authored by Prakash Gupta's avatar Prakash Gupta
Browse files

iommu: arm-smmu: dump additional smmu registers in fault handler



In order to ease debugging the context fault, dump additional smmu
registers in context fault handler.

example output:
arm-smmu 15000000.apps-smmu: FAR    = 0x0000000000001000
arm-smmu 15000000.apps-smmu: PAR    = 0x0000000000000000
arm-smmu 15000000.apps-smmu: FSR    = 0x00000402 [TF R ]
arm-smmu 15000000.apps-smmu: TTBR0  = 0x0000000000000000
arm-smmu 15000000.apps-smmu: TTBR1  = 0x0000000000000000
arm-smmu 15000000.apps-smmu: SCTLR  = 0x00c00027 ACTLR  = 0x00000003
arm-smmu 15000000.apps-smmu: CBAR  = 0x0001f300
arm-smmu 15000000.apps-smmu: MAIR0   = 0xf404ff44 MAIR1   = 0x000000e4

Change-Id: I7f0a41551ac4b8bb02f951930f16325c7b8d7635
Signed-off-by: default avatarPrakash Gupta <guptap@codeaurora.org>
parent 17eb0120
Loading
Loading
Loading
Loading
+59 −17
Original line number Diff line number Diff line
@@ -1406,6 +1406,62 @@ static struct iommu_gather_ops msm_smmu_gather_ops = {
	.free_pages_exact = arm_smmu_free_pages_exact,
};

static void print_ctx_regs(struct arm_smmu_device *smmu, struct arm_smmu_cfg
			   *cfg, unsigned int fsr)
{
	u32 fsynr0;
	void __iomem *cb_base = ARM_SMMU_CB(smmu, cfg->cbndx);
	void __iomem *gr1_base = ARM_SMMU_GR1(smmu);
	bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;

	fsynr0 = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);

	dev_err(smmu->dev, "FAR    = 0x%016llx\n",
		readq_relaxed(cb_base + ARM_SMMU_CB_FAR));
	dev_err(smmu->dev, "PAR    = 0x%pK\n",
		readq_relaxed(cb_base + ARM_SMMU_CB_PAR));

	dev_err(smmu->dev,
		"FSR    = 0x%08x [%s%s%s%s%s%s%s%s%s%s]\n",
		fsr,
		(fsr & 0x02) ?  (fsynr0 & 0x10 ?
				 "TF W " : "TF R ") : "",
		(fsr & 0x04) ? "AFF " : "",
		(fsr & 0x08) ? (fsynr0 & 0x10 ?
				"PF W " : "PF R ") : "",
		(fsr & 0x10) ? "EF " : "",
		(fsr & 0x20) ? "TLBMCF " : "",
		(fsr & 0x40) ? "TLBLKF " : "",
		(fsr & 0x80) ? "MHF " : "",
		(fsr & 0x100) ? "UUT " : "",
		(fsr & 0x40000000) ? "SS " : "",
		(fsr & 0x80000000) ? "MULTI " : "");

	if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
		dev_err(smmu->dev, "TTBR0  = 0x%pK\n",
			readl_relaxed(cb_base + ARM_SMMU_CB_TTBR0));
		dev_err(smmu->dev, "TTBR1  = 0x%pK\n",
			readl_relaxed(cb_base + ARM_SMMU_CB_TTBR1));
	} else {
		dev_err(smmu->dev, "TTBR0  = 0x%pK\n",
			readq_relaxed(cb_base + ARM_SMMU_CB_TTBR0));
		if (stage1)
			dev_err(smmu->dev, "TTBR1  = 0x%pK\n",
				readq_relaxed(cb_base + ARM_SMMU_CB_TTBR1));
	}


	dev_err(smmu->dev, "SCTLR  = 0x%08x ACTLR  = 0x%08x\n",
	       readl_relaxed(cb_base + ARM_SMMU_CB_SCTLR),
	       readl_relaxed(cb_base + ARM_SMMU_CB_ACTLR));
	dev_err(smmu->dev, "CBAR  = 0x%08x\n",
	       readl_relaxed(gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx)));
	dev_err(smmu->dev, "MAIR0   = 0x%08x MAIR1   = 0x%08x\n",
	       readl_relaxed(cb_base + ARM_SMMU_CB_S1_MAIR0),
	       readl_relaxed(cb_base + ARM_SMMU_CB_S1_MAIR1));

}

static phys_addr_t arm_smmu_verify_fault(struct iommu_domain *domain,
					 dma_addr_t iova, u32 fsr)
{
@@ -1499,23 +1555,9 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
			dev_err(smmu->dev,
				"Unhandled context fault: iova=0x%08lx, cb=%d, fsr=0x%x, fsynr0=0x%x, fsynr1=0x%x\n",
				iova, cfg->cbndx, fsr, fsynr0, fsynr1);
			dev_err(smmu->dev, "FAR    = %016lx\n",
				(unsigned long)iova);
			dev_err(smmu->dev,
				"FSR    = %08x [%s%s%s%s%s%s%s%s%s%s]\n",
				fsr,
				(fsr & 0x02) ?  (fsynr0 & 0x10 ?
						"TF W " : "TF R ") : "",
				(fsr & 0x04) ? "AFF " : "",
				(fsr & 0x08) ? (fsynr0 & 0x10 ?
						"PF W " : "PF R ") : "",
				(fsr & 0x10) ? "EF " : "",
				(fsr & 0x20) ? "TLBMCF " : "",
				(fsr & 0x40) ? "TLBLKF " : "",
				(fsr & 0x80) ? "MHF " : "",
				(fsr & 0x100) ? "UUT " : "",
				(fsr & 0x40000000) ? "SS " : "",
				(fsr & 0x80000000) ? "MULTI " : "");

			print_ctx_regs(smmu, cfg, fsr);

			dev_err(smmu->dev,
				"soft iova-to-phys=%pa\n", &phys_soft);
			if (!phys_soft)