iommu: msm: Add decoding to PAR when fault occurs
Add decoding of the PAR register when a VA2PA translation fault
occurs to help in debugging.
Change-Id: Ie3c442d29c3c10f7437acbb63262eb51bc9cc9ab
Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-v1.h b/arch/arm/mach-msm/include/mach/iommu_hw-v1.h
index 1c20d04..04cd441 100644
--- a/arch/arm/mach-msm/include/mach/iommu_hw-v1.h
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-v1.h
@@ -19,6 +19,8 @@
#define GET_GLOBAL_REG(reg, base) (readl_relaxed((base) + (reg)))
#define GET_CTX_REG(reg, base, ctx) \
(readl_relaxed((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT)))
+#define GET_CTX_REG_L(reg, base, ctx) \
+ (readll_relaxed((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT)))
#define SET_GLOBAL_REG(reg, base, val) writel_relaxed((val), ((base) + (reg)))
@@ -196,7 +198,7 @@
#define GET_CONTEXTIDR(b, c) GET_CTX_REG(CB_CONTEXTIDR, (b), (c))
#define GET_PRRR(b, c) GET_CTX_REG(CB_PRRR, (b), (c))
#define GET_NMRR(b, c) GET_CTX_REG(CB_NMRR, (b), (c))
-#define GET_PAR(b, c) GET_CTX_REG(CB_PAR, (b), (c))
+#define GET_PAR(b, c) GET_CTX_REG_L(CB_PAR, (b), (c))
#define GET_FSR(b, c) GET_CTX_REG(CB_FSR, (b), (c))
#define GET_FSRRESTORE(b, c) GET_CTX_REG(CB_FSRRESTORE, (b), (c))
#define GET_FAR(b, c) GET_CTX_REG(CB_FAR, (b), (c))
@@ -1307,6 +1309,7 @@
#define CB_PAR_TF (CB_PAR_TF_MASK << CB_PAR_TF_SHIFT)
#define CB_PAR_AFF (CB_PAR_AFF_MASK << CB_PAR_AFF_SHIFT)
#define CB_PAR_PF (CB_PAR_PF_MASK << CB_PAR_PF_SHIFT)
+#define CB_PAR_EF (CB_PAR_EF_MASK << CB_PAR_EF_SHIFT)
#define CB_PAR_TLBMCF (CB_PAR_TLBMCF_MASK << CB_PAR_TLBMCF_SHIFT)
#define CB_PAR_TLBLKF (CB_PAR_TLBLKF_MASK << CB_PAR_TLBLKF_SHIFT)
#define CB_PAR_ATOT (CB_PAR_ATOT_MASK << CB_PAR_ATOT_SHIFT)
@@ -1682,11 +1685,12 @@
#define CB_PAR_TF_MASK 0x01
#define CB_PAR_AFF_MASK 0x01
#define CB_PAR_PF_MASK 0x01
+#define CB_PAR_EF_MASK 0x01
#define CB_PAR_TLBMCF_MASK 0x01
#define CB_PAR_TLBLKF_MASK 0x01
-#define CB_PAR_ATOT_MASK 0x01
-#define CB_PAR_PLVL_MASK 0x03
-#define CB_PAR_STAGE_MASK 0x01
+#define CB_PAR_ATOT_MASK 0x01ULL
+#define CB_PAR_PLVL_MASK 0x03ULL
+#define CB_PAR_STAGE_MASK 0x01ULL
/* Primary Region Remap Register: CB_PRRR */
#define CB_PRRR_TR0_MASK 0x03
@@ -2052,11 +2056,12 @@
#define CB_PAR_TF_SHIFT 1
#define CB_PAR_AFF_SHIFT 2
#define CB_PAR_PF_SHIFT 3
+#define CB_PAR_EF_SHIFT 4
#define CB_PAR_TLBMCF_SHIFT 5
#define CB_PAR_TLBLKF_SHIFT 6
#define CB_PAR_ATOT_SHIFT 31
-#define CB_PAR_PLVL_SHIFT 0
-#define CB_PAR_STAGE_SHIFT 3
+#define CB_PAR_PLVL_SHIFT 32
+#define CB_PAR_STAGE_SHIFT 35
/* Primary Region Remap Register: CB_PRRR */
#define CB_PRRR_TR0_SHIFT 0
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index a400b58..aed2b47 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -769,7 +769,7 @@
struct msm_iommu_priv *priv;
struct msm_iommu_drvdata *iommu_drvdata;
struct msm_iommu_ctx_drvdata *ctx_drvdata;
- unsigned int par;
+ u64 par;
void __iomem *base;
phys_addr_t ret = 0;
int ctx;
@@ -802,6 +802,23 @@
__disable_clocks(iommu_drvdata);
if (par & CB_PAR_F) {
+ unsigned int level = (par & CB_PAR_PLVL) >> CB_PAR_PLVL_SHIFT;
+ pr_err("IOMMU translation fault!\n");
+ pr_err("name = %s\n", iommu_drvdata->name);
+ pr_err("context = %s (%d)\n", ctx_drvdata->name,
+ ctx_drvdata->num);
+ pr_err("Interesting registers:\n");
+ pr_err("PAR = %16llx [%s%s%s%s%s%s%s%sPLVL%u %s]\n", par,
+ (par & CB_PAR_F) ? "F " : "",
+ (par & CB_PAR_TF) ? "TF " : "",
+ (par & CB_PAR_AFF) ? "AFF " : "",
+ (par & CB_PAR_PF) ? "PF " : "",
+ (par & CB_PAR_EF) ? "EF " : "",
+ (par & CB_PAR_TLBMCF) ? "TLBMCF " : "",
+ (par & CB_PAR_TLBLKF) ? "TLBLKF " : "",
+ (par & CB_PAR_ATOT) ? "ATOT " : "",
+ level,
+ (par & CB_PAR_STAGE) ? "S2 " : "S1 ");
ret = 0;
} else {
/* We are dealing with a supersection */