Merge changes from topic "smmuv3_fix" into integration
* changes:
feat(smmu): separate out smmuv3_security_init from smmuv3_init
feat(smmu): fix to perform INV_ALL before enabling GPC
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index 6c6f978..6932e61 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -69,16 +69,31 @@
return smmuv3_poll(smmu_base + SMMU_S_GBPA, SMMU_S_GBPA_UPDATE, 0U);
}
-/*
- * Initialize the SMMU by invalidating all secure caches and TLBs.
- * Abort all incoming transactions in order to implement a default
- * deny policy on reset
- */
+/* Initialize the SMMU by invalidating all secure caches and TLBs. */
int __init smmuv3_init(uintptr_t smmu_base)
{
- /* Abort all incoming transactions */
- if (smmuv3_security_init(smmu_base) != 0)
+ /*
+ * Initiate invalidation of secure caches and TLBs if the SMMU
+ * supports secure state. If not, it's implementation defined
+ * as to how SMMU_S_INIT register is accessed.
+ * As per Arm SMMUv3 specification the SMMU_S_INIT register in a SMMU
+ * with RME implementation has following properties:
+ * a) all SMMU registers that are specified to be accessible only in
+ * the Secure physical address space are additionally accessible in
+ * Root physical address space.
+ * b) as GPT information is permitted to be cached in a TLB, the
+ * SMMU_S_INIT.INV_ALL operation also invalidates all GPT information
+ * cached in TLBs.
+ * Additionally, it is Root firmware’s responsibility to write to
+ * INV_ALL before enabling SMMU_ROOT_CR0.{ACCESSEN,GPCEN}.
+ */
+ mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
+
+ /* Wait for global invalidation operation to finish */
+ if (smmuv3_poll(smmu_base + SMMU_S_INIT,
+ SMMU_S_INIT_INV_ALL, 0U) != 0) {
return -1;
+ }
#if ENABLE_RME
@@ -137,23 +152,7 @@
#endif /* ENABLE_RME */
- /*
- * Initiate invalidation of secure caches and TLBs if the SMMU
- * supports secure state. If not, it's implementation defined
- * as to how SMMU_S_INIT register is accessed.
- * Arm SMMU Arch RME supplement, section 3.4: all SMMU registers
- * specified to be accessible only in secure physical address space are
- * additionally accessible in root physical address space in an SMMU
- * with RME.
- * Section 3.3: as GPT information is permitted to be cached in a TLB,
- * the SMMU_S_INIT.INV_ALL mechanism also invalidates GPT information
- * cached in TLBs.
- */
- mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
-
- /* Wait for global invalidation operation to finish */
- return smmuv3_poll(smmu_base + SMMU_S_INIT,
- SMMU_S_INIT_INV_ALL, 0U);
+ return 0;
}
int smmuv3_ns_set_abort_all(uintptr_t smmu_base)
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index e46dbc9..93289b6 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -73,8 +73,19 @@
fvp_timer_init();
/* On FVP RevC, initialize SMMUv3 */
- if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U)
- smmuv3_init(PLAT_FVP_SMMUV3_BASE);
+ if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) {
+ if (smmuv3_security_init(PLAT_FVP_SMMUV3_BASE) != 0) {
+ /*
+ * Don't proceed for smmuv3 initialization if the
+ * security init failed.
+ */
+ return;
+ }
+ /* SMMUv3 initialization failure is not fatal */
+ if (smmuv3_init(PLAT_FVP_SMMUV3_BASE) != 0) {
+ WARN("Failed initializing SMMU.\n");
+ }
+ }
}
void __init bl31_plat_arch_setup(void)