diff options
| author | Andrew Turner <andrew@FreeBSD.org> | 2026-09-18 11:28:41 +0000 |
|---|---|---|
| committer | Andrew Turner <andrew@FreeBSD.org> | 2026-09-18 11:28:41 +0000 |
| commit | 6dca6e2aa89d877cf2bc8135c6936008e2a6af72 (patch) | |
| tree | 383f60c5921e78f7471658085faecda034a51dd5 /sys | |
| parent | 0bcd0616ff86675869d998a491eccc38e413cdad (diff) | |
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
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arm64/iommu/smmu.c | 28 | ||||
| -rw-r--r-- | sys/arm64/iommu/smmureg.h | 16 |
2 files changed, 44 insertions, 0 deletions
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 @@ -1512,6 +1512,32 @@ smmu_check_features(struct smmu_softc *sc) } 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 */ |
