Merge "feat(plat/arm): enable PIE when RESET_TO_SP_MIN=1" into integration
diff --git a/Makefile b/Makefile
index 017fc65..c013e35 100644
--- a/Makefile
+++ b/Makefile
@@ -334,7 +334,7 @@
 
 # General warnings
 WARNINGS		:=	-Wall -Wmissing-include-dirs -Wunused	\
-				-Wdisabled-optimization	-Wvla -Wshadow	\
+				-Wdisabled-optimization -Wvla -Wshadow	\
 				-Wno-unused-parameter -Wredundant-decls
 
 # Additional warnings
@@ -913,6 +913,7 @@
         ENABLE_RUNTIME_INSTRUMENTATION \
         ENABLE_SPE_FOR_LOWER_ELS \
         ENABLE_SVE_FOR_NS \
+        ENABLE_SVE_FOR_SWD \
         ERROR_DEPRECATED \
         FAULT_INJECTION_SUPPORT \
         GENERATE_COT \
@@ -1006,6 +1007,7 @@
         ENABLE_RUNTIME_INSTRUMENTATION \
         ENABLE_SPE_FOR_LOWER_ELS \
         ENABLE_SVE_FOR_NS \
+        ENABLE_SVE_FOR_SWD \
         ENCRYPT_BL31 \
         ENCRYPT_BL32 \
         ERROR_DEPRECATED \
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index fc853f3..ab638fb 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -263,6 +263,9 @@
 -  ``ERRATA_A77_1946167``: This applies errata 1946167 workaround to Cortex-A77
    CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
 
+-  ``ERRATA_A77_1791578``: This applies errata 1791578 workaround to Cortex-A77
+   CPU. This needs to be enabled for r0p0, r1p0, and r1p1, it is still open.
+
 For Cortex-A78, the following errata build flags are defined :
 
 -  ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 99fc21d..5844304 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -278,7 +278,8 @@
 -  ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension
    (SVE) for the Non-secure world only. SVE is an optional architectural feature
    for AArch64. Note that when SVE is enabled for the Non-secure world, access
-   to SIMD and floating-point functionality from the Secure world is disabled.
+   to SIMD and floating-point functionality from the Secure world is disabled by
+   default and controlled with ENABLE_SVE_FOR_SWD.
    This is to avoid corruption of the Non-secure world data in the Z-registers
    which are aliased by the SIMD and FP registers. The build option is not
    compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
@@ -286,6 +287,11 @@
    1. The default is 1 but is automatically disabled when the target
    architecture is AArch32.
 
+-  ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world.
+   SVE is an optional architectural feature for AArch64. Note that this option
+   requires ENABLE_SVE_FOR_NS to be enabled.  The default is 0 and it is
+   automatically disabled when the target architecture is AArch32.
+
 -  ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
    checks in GCC. Allowed values are "all", "strong", "default" and "none". The
    default value is set to "none". "strong" is the recommended stack protection
diff --git a/drivers/arm/css/scmi/scmi_common.c b/drivers/arm/css/scmi/scmi_common.c
index 5b3724a..ec749fb 100644
--- a/drivers/arm/css/scmi/scmi_common.c
+++ b/drivers/arm/css/scmi/scmi_common.c
@@ -173,12 +173,12 @@
 
 	ret = scmi_proto_version(ch, SCMI_PWR_DMN_PROTO_ID, &version);
 	if (ret != SCMI_E_SUCCESS) {
-		WARN("SCMI power domain protocol version message failed");
+		WARN("SCMI power domain protocol version message failed\n");
 		goto error;
 	}
 
 	if (!is_scmi_version_compatible(SCMI_PWR_DMN_PROTO_VER, version)) {
-		WARN("SCMI power domain protocol version 0x%x incompatible with driver version 0x%x",
+		WARN("SCMI power domain protocol version 0x%x incompatible with driver version 0x%x\n",
 			version, SCMI_PWR_DMN_PROTO_VER);
 		goto error;
 	}
@@ -187,12 +187,12 @@
 
 	ret = scmi_proto_version(ch, SCMI_SYS_PWR_PROTO_ID, &version);
 	if ((ret != SCMI_E_SUCCESS)) {
-		WARN("SCMI system power protocol version message failed");
+		WARN("SCMI system power protocol version message failed\n");
 		goto error;
 	}
 
 	if (!is_scmi_version_compatible(SCMI_SYS_PWR_PROTO_VER, version)) {
-		WARN("SCMI system power management protocol version 0x%x incompatible with driver version 0x%x",
+		WARN("SCMI system power management protocol version 0x%x incompatible with driver version 0x%x\n",
 			version, SCMI_SYS_PWR_PROTO_VER);
 		goto error;
 	}
diff --git a/drivers/mtd/nor/spi_nor.c b/drivers/mtd/nor/spi_nor.c
index 108f893..8111efd 100644
--- a/drivers/mtd/nor/spi_nor.c
+++ b/drivers/mtd/nor/spi_nor.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -103,7 +103,7 @@
 			0 : 1;
 	}
 
-	return (((sr & SR_WIP) != 0U) ? 1 : 0);
+	return (((sr & SR_WIP) == 0U) ? 0 : 1);
 }
 
 static int spi_nor_wait_ready(void)
@@ -141,7 +141,7 @@
 	}
 
 	sr |= SR_QUAD_EN_MX;
-	ret = spi_nor_reg(SPI_NOR_OP_WRSR, &sr, 1, SPI_MEM_DATA_OUT);
+	ret = spi_nor_reg(SPI_NOR_OP_WRSR, &sr, 1U, SPI_MEM_DATA_OUT);
 	if (ret != 0) {
 		return ret;
 	}
@@ -168,7 +168,7 @@
 		return ret;
 	}
 
-	ret = spi_nor_reg(SPI_NOR_OP_WRSR, sr_cr, 2, SPI_MEM_DATA_OUT);
+	ret = spi_nor_reg(SPI_NOR_OP_WRSR, sr_cr, 2U, SPI_MEM_DATA_OUT);
 	if (ret != 0) {
 		return -EINVAL;
 	}
@@ -230,7 +230,7 @@
 	}
 
 	return spi_nor_reg(nor_dev.bank_write_cmd, &nor_dev.selected_bank,
-			   1, SPI_MEM_DATA_OUT);
+			   1U, SPI_MEM_DATA_OUT);
 }
 
 static int spi_nor_write_bar(uint32_t offset)
@@ -248,7 +248,7 @@
 	}
 
 	ret = spi_nor_reg(nor_dev.bank_write_cmd, &selected_bank,
-			  1, SPI_MEM_DATA_OUT);
+			  1U, SPI_MEM_DATA_OUT);
 	if (ret != 0) {
 		return ret;
 	}
@@ -260,11 +260,11 @@
 
 static int spi_nor_read_bar(void)
 {
-	uint8_t selected_bank = 0;
+	uint8_t selected_bank = 0U;
 	int ret;
 
 	ret = spi_nor_reg(nor_dev.bank_read_cmd, &selected_bank,
-			  1, SPI_MEM_DATA_IN);
+			  1U, SPI_MEM_DATA_IN);
 	if (ret != 0) {
 		return ret;
 	}
@@ -280,7 +280,7 @@
 	size_t remain_len;
 	int ret;
 
-	*length_read = 0;
+	*length_read = 0U;
 	nor_dev.read_op.addr.val = offset;
 	nor_dev.read_op.data.buf = (void *)buffer;
 
@@ -324,7 +324,7 @@
 
 int spi_nor_init(unsigned long long *size, unsigned int *erase_size)
 {
-	int ret = 0;
+	int ret;
 	uint8_t id;
 
 	/* Default read command used */
@@ -339,7 +339,7 @@
 		return -EINVAL;
 	}
 
-	assert(nor_dev.size != 0);
+	assert(nor_dev.size != 0U);
 
 	if (nor_dev.size > BANK_SIZE) {
 		nor_dev.flags |= SPI_NOR_USE_BANK;
diff --git a/fdts/tc0.dts b/fdts/tc0.dts
index a4f7a4d..9051b7b 100644
--- a/fdts/tc0.dts
+++ b/fdts/tc0.dts
@@ -17,6 +17,7 @@
 	};
 
 	chosen {
+		bootargs = "console=ttyAMA0 debug user_debug=31 earlycon=pl011,0x7ff80000 loglevel=9 androidboot.hardware=total_compute androidboot.boot_devices=1c050000.mmci ip=dhcp androidboot.selinux=permissive allow_mismatched_32bit_el0";
 		stdout-path = "serial0:115200n8";
 	};
 
@@ -85,6 +86,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			capacity-dmips-mhz = <406>;
 		};
 
 		CPU1:cpu@100 {
@@ -94,6 +96,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			capacity-dmips-mhz = <406>;
 		};
 
 		CPU2:cpu@200 {
@@ -103,6 +106,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			capacity-dmips-mhz = <406>;
 		};
 
 		CPU3:cpu@300 {
@@ -112,6 +116,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 0>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			capacity-dmips-mhz = <406>;
 		};
 
 		CPU4:cpu@400 {
@@ -121,6 +126,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			capacity-dmips-mhz = <912>;
 		};
 
 		CPU5:cpu@500 {
@@ -130,6 +136,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			capacity-dmips-mhz = <912>;
 		};
 
 		CPU6:cpu@600 {
@@ -139,6 +146,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 1>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			capacity-dmips-mhz = <912>;
 		};
 
 		CPU7:cpu@700 {
@@ -148,6 +156,7 @@
 			enable-method = "psci";
 			clocks = <&scmi_dvfs 2>;
 			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			capacity-dmips-mhz = <1024>;
 		};
 
 	};
@@ -169,7 +178,7 @@
 	};
 
 	psci {
-		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
 		method = "smc";
 	};
 
@@ -188,31 +197,32 @@
 	};
 
 	mbox_db_rx: mhu@45010000 {
-		compatible = "arm,mhuv2","arm,primecell";
+		compatible = "arm,mhuv2-rx","arm,primecell";
 		reg = <0x0 0x45010000 0x0 0x1000>;
 		clocks = <&soc_refclk100mhz>;
 		clock-names = "apb_pclk";
-		#mbox-cells = <1>;
+		#mbox-cells = <2>;
 		interrupts = <0 317 4>;
 		interrupt-names = "mhu_rx";
 		mhu-protocol = "doorbell";
+		arm,mhuv2-protocols = <0 1>;
 	};
 
 	mbox_db_tx: mhu@45000000 {
-		compatible = "arm,mhuv2","arm,primecell";
+		compatible = "arm,mhuv2-tx","arm,primecell";
 		reg = <0x0 0x45000000 0x0 0x1000>;
 		clocks = <&soc_refclk100mhz>;
 		clock-names = "apb_pclk";
-		#mbox-cells = <1>;
+		#mbox-cells = <2>;
 		interrupt-names = "mhu_tx";
 		mhu-protocol = "doorbell";
+		arm,mhuv2-protocols = <0 1>;
 	};
 
 	scmi {
 		compatible = "arm,scmi";
-		method = "mailbox-doorbell";
 		mbox-names = "tx", "rx";
-		mboxes = <&mbox_db_tx 0 &mbox_db_rx 0>;
+		mboxes = <&mbox_db_tx 0 0 &mbox_db_rx 0 0 >;
 		shmem = <&cpu_scp_scmi_mem &cpu_scp_scmi_mem>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -430,16 +440,4 @@
 		};
 	};
 
-	ffa {
-		compatible = "arm,ffa";
-		conduit = "smc";
-		mem_share_buffer = "tx";
-	};
-
-	firmware {
-		optee {
-		      compatible = "linaro,optee-tz";
-		      method = "ffa";
-		};
-	};
 };
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 9ef9c26..3383a3b 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -170,6 +170,7 @@
 #define ID_AA64PFR0_GIC_MASK	ULL(0xf)
 #define ID_AA64PFR0_SVE_SHIFT	U(32)
 #define ID_AA64PFR0_SVE_MASK	ULL(0xf)
+#define ID_AA64PFR0_SVE_LENGTH	U(4)
 #define ID_AA64PFR0_SEL2_SHIFT	U(36)
 #define ID_AA64PFR0_SEL2_MASK	ULL(0xf)
 #define ID_AA64PFR0_MPAM_SHIFT	U(40)
@@ -529,7 +530,7 @@
 #define TTA_BIT			(U(1) << 20)
 #define TFP_BIT			(U(1) << 10)
 #define CPTR_EZ_BIT		(U(1) << 8)
-#define CPTR_EL3_RESET_VAL	U(0x0)
+#define CPTR_EL3_RESET_VAL	(TCPAC_BIT | TAM_BIT | TTA_BIT | TFP_BIT & ~(CPTR_EZ_BIT))
 
 /* CPTR_EL2 definitions */
 #define CPTR_EL2_RES1		((U(1) << 13) | (U(1) << 12) | (U(0x3ff)))
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index b610b37..9734335 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -185,7 +185,14 @@
 	 * CPTR_EL3.TFP: Set to zero so that accesses to the V- or Z- registers
 	 *  by Advanced SIMD, floating-point or SVE instructions (if implemented)
 	 *  do not trap to EL3.
+	 *
+	 * CPTR_EL3.TAM: Set to one so that Activity Monitor access is
+	 *  trapped to EL3 by default.
+	 *
+	 * CPTR_EL3.EZ: Set to zero so that all SVE functionality is trapped
+	 *  to EL3 by default.
 	 */
+
 	mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT))
 	msr	cptr_el3, x0
 
diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h
index 0a42a5d..5753e90 100644
--- a/include/lib/cpus/aarch64/cortex_a77.h
+++ b/include/lib/cpus/aarch64/cortex_a77.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,12 @@
 #define CORTEX_A77_CPUPWRCTLR_EL1			S3_0_C15_C2_7
 #define CORTEX_A77_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	(U(1) << 0)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A77_ACTLR2_EL1				S3_0_C15_C1_1
+#define CORTEX_A77_ACTLR2_EL1_BIT_2			(ULL(1) << 2)
+
 #define CORTEX_A77_CPUPSELR_EL3				S3_6_C15_C8_0
 #define CORTEX_A77_CPUPCR_EL3				S3_6_C15_C8_1
 #define CORTEX_A77_CPUPOR_EL3				S3_6_C15_C8_2
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 9d9f9d3..d449a65 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -61,7 +61,9 @@
 #define CTX_ELR_EL3		U(0x20)
 #define CTX_PMCR_EL0		U(0x28)
 #define CTX_IS_IN_EL3		U(0x30)
-#define CTX_EL3STATE_END	U(0x40) /* Align to the next 16 byte boundary */
+#define CTX_CPTR_EL3		U(0x38)
+#define CTX_ZCR_EL3		U(0x40)
+#define CTX_EL3STATE_END	U(0x50) /* Align to the next 16 byte boundary */
 
 /*******************************************************************************
  * Constants that allow assembler code to access members of and the
diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h
index 83df177..c85e08c 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,9 +7,8 @@
 #ifndef SVE_H
 #define SVE_H
 
-#include <stdbool.h>
+#include <context.h>
 
-bool sve_supported(void);
-void sve_enable(bool el2_unused);
+void sve_enable(cpu_context_t *context);
 
 #endif /* SVE_H */
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index 06b23d9..8c8f4d3 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -166,6 +166,34 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_1946167
 
+	/* --------------------------------------------------
+	 * Errata Workaround for Cortex A77 Errata #1791578.
+	 * This applies to revisions r0p0, r1p0, and r1p1 and is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * --------------------------------------------------
+	 */
+func errata_a77_1791578_wa
+	/* Check workaround compatibility. */
+	mov	x17, x30
+	bl	check_errata_1791578
+	cbz	x0, 1f
+
+	/* Set bit 2 in ACTLR2_EL1 */
+	mrs     x1, CORTEX_A77_ACTLR2_EL1
+	orr	x1, x1, #CORTEX_A77_ACTLR2_EL1_BIT_2
+	msr     CORTEX_A77_ACTLR2_EL1, x1
+	isb
+1:
+	ret	x17
+endfunc errata_a77_1791578_wa
+
+func check_errata_1791578
+	/* Applies to r0p0, r1p0, and r1p1 right now */
+	mov	x1, #0x11
+	b	cpu_rev_var_ls
+endfunc check_errata_1791578
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A77.
 	 * Shall clobber: x0-x19
@@ -191,6 +219,11 @@
 	bl	errata_a77_1946167_wa
 #endif
 
+#if ERRATA_A77_1791578
+	mov	x0, x18
+	bl	errata_a77_1791578_wa
+#endif
+
 	ret	x19
 endfunc cortex_a77_reset_func
 
@@ -227,6 +260,7 @@
 	report_errata ERRATA_A77_1508412, cortex_a77, 1508412
 	report_errata ERRATA_A77_1925769, cortex_a77, 1925769
 	report_errata ERRATA_A77_1946167, cortex_a77, 1946167
+	report_errata ERRATA_A77_1791578, cortex_a77, 1791578
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 541a2a2..b1747af 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -294,6 +294,10 @@
 # only to revision <= r1p1 of the Cortex A77 cpu.
 ERRATA_A77_1946167	?=0
 
+# Flag to apply erratum 1791578 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, and r1p1, it is still open.
+ERRATA_A77_1791578	?=0
+
 # Flag to apply erratum 1688305 workaround during reset. This erratum applies
 # to revisions r0p0 - r1p0 of the A78 cpu.
 ERRATA_A78_1688305	?=0
@@ -597,6 +601,10 @@
 $(eval $(call assert_boolean,ERRATA_A77_1946167))
 $(eval $(call add_define,ERRATA_A77_1946167))
 
+# Process ERRATA_A77_1791578 flag
+$(eval $(call assert_boolean,ERRATA_A77_1791578))
+$(eval $(call add_define,ERRATA_A77_1791578))
+
 # Process ERRATA_A78_1688305 flag
 $(eval $(call assert_boolean,ERRATA_A78_1688305))
 $(eval $(call add_define,ERRATA_A78_1688305))
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 0ec9ffd..d610fd4 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -901,6 +901,29 @@
 	msr	spsr_el3, x16
 	msr	elr_el3, x17
 
+#if IMAGE_BL31
+	/* ----------------------------------------------------------
+	 * Restore CPTR_EL3, ZCR_EL3 for SVE support.
+	 * If SVE is not supported - skip the restoration.
+	 * ZCR is only restored if SVE is supported and enabled.
+	 * Synchronization is required before zcr_el3 is addressed.
+	 * ----------------------------------------------------------
+	 */
+	mrs	x17, id_aa64pfr0_el1
+	ubfx	x17, x17, ID_AA64PFR0_SVE_SHIFT, ID_AA64PFR0_SVE_LENGTH
+	cbz	x17, sve_not_enabled
+
+	ldp	x19, x20, [sp, #CTX_EL3STATE_OFFSET + CTX_CPTR_EL3]
+	msr	cptr_el3, x19
+
+	ands	x19, x19, #CPTR_EZ_BIT
+	beq	sve_not_enabled
+
+	isb
+	msr	S3_6_C1_C2_0, x20 /* zcr_el3 */
+sve_not_enabled:
+#endif
+
 #if IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639
 	/* ----------------------------------------------------------
 	 * Restore mitigation state as it was on entry to EL3
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 96023b6..7a25151 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -178,8 +178,20 @@
 	 *  indicated by the interrupt routing model for BL31.
 	 */
 	scr_el3 |= get_scr_el3_from_routing_model(security_state);
+
+#if ENABLE_SVE_FOR_NS
+	if (security_state == NON_SECURE) {
+		sve_enable(ctx);
+	}
+#endif
+#if ENABLE_SVE_FOR_SWD
+	if (security_state == SECURE) {
+		sve_enable(ctx);
+	}
 #endif
 
+#endif
+
 	/*
 	 * SCR_EL3.HCE: Enable HVC instructions if next execution state is
 	 * AArch64 and next EL is EL2, or if next execution state is AArch32 and
@@ -334,10 +346,6 @@
 	amu_enable(el2_unused);
 #endif
 
-#if ENABLE_SVE_FOR_NS
-	sve_enable(el2_unused);
-#endif
-
 #if ENABLE_MPAM_FOR_LOWER_ELS
 	mpam_enable(el2_unused);
 #endif
diff --git a/lib/extensions/sve/sve.c b/lib/extensions/sve/sve.c
index fa4ac77..7043cc2 100644
--- a/lib/extensions/sve/sve.c
+++ b/lib/extensions/sve/sve.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,13 @@
 #include <lib/el3_runtime/pubsub.h>
 #include <lib/extensions/sve.h>
 
-bool sve_supported(void)
+/*
+ * Converts SVE vector size restriction in bytes to LEN according to ZCR_EL3 documentation.
+ * VECTOR_SIZE = (LEN+1) * 128
+ */
+#define CONVERT_SVE_LENGTH(x)	(((x / 128) - 1))
+
+static bool sve_supported(void)
 {
 	uint64_t features;
 
@@ -19,113 +25,19 @@
 	return (features & ID_AA64PFR0_SVE_MASK) == 1U;
 }
 
-static void *disable_sve_hook(const void *arg)
-{
-	uint64_t cptr;
-
-	if (!sve_supported())
-		return (void *)-1;
-
-	/*
-	 * Disable SVE, SIMD and FP access for the Secure world.
-	 * As the SIMD/FP registers are part of the SVE Z-registers, any
-	 * use of SIMD/FP functionality will corrupt the SVE registers.
-	 * Therefore it is necessary to prevent use of SIMD/FP support
-	 * in the Secure world as well as SVE functionality.
-	 */
-	cptr = read_cptr_el3();
-	cptr = (cptr | TFP_BIT) & ~(CPTR_EZ_BIT);
-	write_cptr_el3(cptr);
-
-	/*
-	 * No explicit ISB required here as ERET to switch to Secure
-	 * world covers it
-	 */
-	return (void *)0;
-}
-
-static void *enable_sve_hook(const void *arg)
-{
-	uint64_t cptr;
-
-	if (!sve_supported())
-		return (void *)-1;
-
-	/*
-	 * Enable SVE, SIMD and FP access for the Non-secure world.
-	 */
-	cptr = read_cptr_el3();
-	cptr = (cptr | CPTR_EZ_BIT) & ~(TFP_BIT);
-	write_cptr_el3(cptr);
-
-	/*
-	 * No explicit ISB required here as ERET to switch to Non-secure
-	 * world covers it
-	 */
-	return (void *)0;
-}
-
-void sve_enable(bool el2_unused)
+void sve_enable(cpu_context_t *context)
 {
-	uint64_t cptr;
-
-	if (!sve_supported())
+	if (!sve_supported()) {
 		return;
-
-#if CTX_INCLUDE_FPREGS
-	/*
-	 * CTX_INCLUDE_FPREGS is not supported on SVE enabled systems.
-	 */
-	assert(0);
-#endif
-	/*
-	 * Update CPTR_EL3 to enable access to SVE functionality for the
-	 * Non-secure world.
-	 * NOTE - assumed that CPTR_EL3.TFP is set to allow access to
-	 * the SIMD, floating-point and SVE support.
-	 *
-	 * CPTR_EL3.EZ: Set to 1 to enable access to SVE  functionality
-	 *  in the Non-secure world.
-	 */
-	cptr = read_cptr_el3();
-	cptr |= CPTR_EZ_BIT;
-	write_cptr_el3(cptr);
-
-	/*
-	 * Need explicit ISB here to guarantee that update to ZCR_ELx
-	 * and CPTR_EL2.TZ do not result in trap to EL3.
-	 */
-	isb();
+	}
 
-	/*
-	 * Ensure lower ELs have access to full vector length.
-	 */
-	write_zcr_el3(ZCR_EL3_LEN_MASK);
+	u_register_t cptr_el3 = read_cptr_el3();
 
-	if (el2_unused) {
-		/*
-		 * Update CPTR_EL2 to enable access to SVE functionality
-		 * for Non-secure world, EL2 and Non-secure EL1 and EL0.
-		 * NOTE - assumed that CPTR_EL2.TFP is set to allow
-		 * access to the SIMD, floating-point and SVE support.
-		 *
-		 * CPTR_EL2.TZ: Set to 0 to enable access to SVE support
-		 *  for EL2 and Non-secure EL1 and EL0.
-		 */
-		cptr = read_cptr_el2();
-		cptr &= ~(CPTR_EL2_TZ_BIT);
-		write_cptr_el2(cptr);
+	/* Enable access to SVE functionality for all ELs. */
+	cptr_el3 = (cptr_el3 | CPTR_EZ_BIT) & ~(TFP_BIT);
+	write_ctx_reg(get_el3state_ctx(context), CTX_CPTR_EL3, cptr_el3);
 
-		/*
-		 * Ensure lower ELs have access to full vector length.
-		 */
-		write_zcr_el2(ZCR_EL2_LEN_MASK);
-	}
-	/*
-	 * No explicit ISB required here as ERET to switch to
-	 * Non-secure world covers it.
-	 */
+	/* Restrict maximum SVE vector length (SVE_VECTOR_LENGTH+1) * 128. */
+	write_ctx_reg(get_el3state_ctx(context), CTX_ZCR_EL3,
+		(ZCR_EL3_LEN_MASK & CONVERT_SVE_LENGTH(512)));
 }
-
-SUBSCRIBE_TO_EVENT(cm_exited_normal_world, disable_sve_hook);
-SUBSCRIBE_TO_EVENT(cm_entering_normal_world, enable_sve_hook);
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 0433123..b2d1ee2 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -299,13 +299,15 @@
 ENABLE_AMU			:= 0
 AMU_RESTRICT_COUNTERS		:= 0
 
-# By default, enable Scalable Vector Extension if implemented for Non-secure
+# By default, enable Scalable Vector Extension if implemented only for Non-secure
 # lower ELs
 # Note SVE is only supported on AArch64 - therefore do not enable in AArch32
 ifneq (${ARCH},aarch32)
     ENABLE_SVE_FOR_NS		:= 1
+    ENABLE_SVE_FOR_SWD		:= 0
 else
     override ENABLE_SVE_FOR_NS	:= 0
+    override ENABLE_SVE_FOR_SWD  := 0
 endif
 
 SANITIZE_UB := off
diff --git a/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts b/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts
index 2f459b0..44c7008 100644
--- a/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts
+++ b/plat/arm/board/tc0/fdts/tc0_spmc_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,7 +40,7 @@
 			is_ffa_partition;
 			debug_name = "cactus-tertiary";
 			load_address = <0xfe200000>;
-			vcpu_count = <8>;
+			vcpu_count = <1>;
 			mem_size = <1048576>;
 		};
 	};
diff --git a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
index 38fd0e0..28ed7ae 100644
--- a/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
+++ b/plat/arm/board/tc0/fdts/tc0_tb_fw_config.dts
@@ -39,24 +39,24 @@
 #endif
 #if OPTEE_SP_FW_CONFIG
 		op-tee {
-		       uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>;
+		       uuid = "486178e0-e7f8-11e3-bc5e-0002a5d5c51b";
 		       load-address = <0xfd280000>;
 		};
 #else
 		cactus-primary {
-			uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>;
+			uuid = "b4b5671e-4a90-4fe1-b81f-fb13dae1dacb";
 			load-address = <0xfe000000>;
 			owner = "SiP";
 		};
 
 		cactus-secondary {
-			uuid = <0xd1582309 0xf02347b9 0x827c4464 0xf5578fc8>;
+			uuid = "d1582309-f023-47b9-827c-4464f5578fc8";
 			load-address = <0xfe100000>;
 			owner = "Plat";
 		};
 
 		cactus-tertiary {
-			uuid = <0x79b55c73 0x1d8c44b9 0x859361e1 0x770ad8d2>;
+			uuid = "79b55c73-1d8c-44b9-8593-61e1770ad8d2";
 			load-address = <0xfe200000>;
 		};
 #endif