{
int flags, ret;
u32 fsr, far, fsynr, resume;
- unsigned long iova;
+ paddr_t iova;
struct iommu_domain *domain = dev;
struct arm_smmu_domain *smmu_domain = domain->priv;
struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
far = readl_relaxed(cb_base + ARM_SMMU_CB_FAR_LO);
iova = far;
-#ifdef CONFIG_64BIT
+ /* Xen: The fault address maybe higher than 32 bits on arm32 */
far = readl_relaxed(cb_base + ARM_SMMU_CB_FAR_HI);
- iova |= ((unsigned long)far << 32);
-#endif
+ iova |= ((paddr_t)far << 32);
if (!report_iommu_fault(domain, smmu->dev, iova, flags)) {
ret = IRQ_HANDLED;
resume = RESUME_RETRY;
} else {
dev_err_ratelimited(smmu->dev,
- "Unhandled context fault: iova=0x%08lx, fsynr=0x%x, cb=%d\n",
+ "Unhandled context fault: iova=0x%"PRIpaddr", fsynr=0x%x, cb=%d\n",
iova, fsynr, cfg->cbndx);
ret = IRQ_NONE;
resume = RESUME_TERMINATE;
reg |= (64 - smmu->s1_input_size) << TTBCR_T0SZ_SHIFT;
}
} else {
+#if CONFIG_ARM_32
+ /* Xen: Midway is using 40-bit address space. Though it may
+ * not work on other ARM32 platform with SMMU-v1.
+ * TODO: A quirk may be necessary if we have to support
+ * other ARM32 platform with SMMU-v1.
+ */
+ reg = 0x18 << TTBCR_T0SZ_SHIFT;
+#else
reg = 0;
+#endif
}
/* Xen: The attributes to walk the page table should be the same as
#endif
#endif
+ /*
+ * Xen: SMMU v1: Only 40 bits input address size is supported for
+ * arm32. See arm_smmu_init_context_bank
+ */
+#ifdef CONFIG_ARM_32
+ if ( smmu->version == ARM_SMMU_V1 && smmu->s2_input_size != 40 )
+ {
+ dev_err(smmu->dev,
+ "Stage-2 Input size %ld not supported for SMMUv1\n",
+ smmu->s2_input_size);
+ return -ENODEV;;
+ }
+#endif
+
/* The stage-2 output mask is also applied for bypass */
size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK);
smmu->s2_output_size = min_t(unsigned long, PHYS_MASK_SHIFT, size);