git: 6dca6e2aa89d - main - arm64/smmu: Start handling errata

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Mon, 21 Sep 2026 15:26:08 UTC
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=6dca6e2aa89d877cf2bc8135c6936008e2a6af72

commit 6dca6e2aa89d877cf2bc8135c6936008e2a6af72
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2026-09-18 11:28:41 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2026-09-18 11:28:41 +0000

    arm64/smmu: Start handling errata
    
    Handle the Arm MMU-600 erratum 1076982 where when we poll for a sync
    command completion we can't use the wait-for-event instruction.
    
    This is in preparation for later adding support for polling for sync
    command completion and is not an issue on stable branches.
    
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D59486
---
 sys/arm64/iommu/smmu.c    | 28 ++++++++++++++++++++++++++++
 sys/arm64/iommu/smmureg.h | 16 ++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/sys/arm64/iommu/smmu.c b/sys/arm64/iommu/smmu.c
index 9a6f15e83def..38cdd507a9c2 100644
--- a/sys/arm64/iommu/smmu.c
+++ b/sys/arm64/iommu/smmu.c
@@ -1511,6 +1511,32 @@ smmu_check_features(struct smmu_softc *sc)
 	return (0);
 }
 
+static void
+smmu_check_errata(struct smmu_softc *sc)
+{
+	uint32_t reg;
+	u_int variant;
+
+#define	 SMMU_Implementer_ARM		0x43b
+#define	 SMMU_ProductID_ARM_MMU_600	0x483
+
+	reg = bus_read_4(sc->res[0], SMMU_IIDR);
+	variant = SMMU_Variant_GET(reg);
+
+	switch(SMMU_ProductID_GET(reg)) {
+	case SMMU_Implementer_ARM:
+		switch (SMMU_ProductID_GET(reg)) {
+		/* Arm erratum 1076982 */
+		if (variant < 1)
+			sc->features &= ~SMMU_FEATURE_SEV;
+		default:
+			break;
+		}
+	default:
+		break;
+	}
+}
+
 static void
 smmu_init_asids(struct smmu_softc *sc)
 {
@@ -1572,6 +1598,8 @@ smmu_attach(device_t dev)
 		return (ENXIO);
 	}
 
+	smmu_check_errata(sc);
+
 	smmu_init_asids(sc);
 
 	error = smmu_init_queues(sc);
diff --git a/sys/arm64/iommu/smmureg.h b/sys/arm64/iommu/smmureg.h
index d62f145ceef7..0929089a7a36 100644
--- a/sys/arm64/iommu/smmureg.h
+++ b/sys/arm64/iommu/smmureg.h
@@ -114,6 +114,22 @@
 #define	 IDR5_OAS_48		(0x5 << IDR5_OAS_S)
 #define	 IDR5_OAS_52		(0x6 << IDR5_OAS_S) /* Reserved in SMMU v3.0 */
 #define	SMMU_IIDR		0x018
+#define	 SMMU_ProductID_SHIFT	20
+#define	 SMMU_ProductID_MASK	(0xfffu << SMMU_ProductID_SHIFT)
+#define	 SMMU_ProductID_GET(x)	\
+    (((x) & SMMU_ProductID_MASK) >> SMMU_ProductID_SHIFT)
+#define	 SMMU_Variant_SHIFT	16
+#define	 SMMU_Variant_MASK	(0xfu << SMMU_Variant_SHIFT)
+#define	 SMMU_Variant_GET(x)	\
+    (((x) & SMMU_Variant_MASK) >> SMMU_Variant_SHIFT)
+#define	 SMMU_Revision_SHIFT	12
+#define	 SMMU_Revision_MASK	(0xfu << SMMU_Revision_SHIFT)
+#define	 SMMU_Revision_GET(x)	\
+    (((x) & SMMU_Revision_MASK) >> SMMU_Revision_SHIFT)
+#define	 SMMU_Implementer_SHIFT	0
+#define	 SMMU_Implementer_MASK	(0xfffu << SMMU_Implementer_SHIFT)
+#define	 SMMU_Implementer_GET(x) \
+    (((x) & SMMU_Implementer_MASK) >> SMMU_Implementer_SHIFT)
 #define	SMMU_AIDR		0x01C
 #define	SMMU_CR0		0x020
 #define	 CR0_VMW_S		6 /* VMID Wildcard */