Merge "feat(mt8196): enable appropriate errata" into integration
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..a2b4732
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,5 @@
+package.json @CJKay
+package-lock.json @CJKay
+
+pyproject.toml @CJKay
+poetry.lock @CJKay
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..b565bcb
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,37 @@
+version: 2
+updates:
+  - target-branch: "main"
+    package-ecosystem: "npm"
+    directories: ["/"]
+    schedule:
+      interval: "daily"
+
+  - target-branch: "lts-v2.10"
+    package-ecosystem: "npm"
+    directories: ["/"]
+    schedule:
+      interval: "daily"
+
+  - target-branch: "lts-v2.8"
+    package-ecosystem: "npm"
+    directories: ["/"]
+    schedule:
+      interval: "daily"
+
+  - target-branch: "main"
+    package-ecosystem: "pip"
+    directories: ["/", "/tools/cot_dt2c", "/tools/tlc"]
+    schedule:
+      interval: "daily"
+
+  - target-branch: "lts-v2.10"
+    package-ecosystem: "pip"
+    directories: ["/"]
+    schedule:
+      interval: "daily"
+
+  - target-branch: "lts-v2.8"
+    package-ecosystem: "pip"
+    directories: ["/"]
+    schedule:
+      interval: "daily"
diff --git a/Makefile b/Makefile
index 58c98a1..fae34c5 100644
--- a/Makefile
+++ b/Makefile
@@ -115,6 +115,9 @@
 SP_MK_GEN		?=	${SPTOOLPATH}/sp_mk_generator.py
 SP_DTS_LIST_FRAGMENT	?=	${BUILD_PLAT}/sp_list_fragment.dts
 
+# Variables for use with sptool
+TLCTOOL 		?=	poetry run tlc
+
 # Variables for use with ROMLIB
 ROMLIBPATH		?=	lib/romlib
 
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 369ec6f..17b2954 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -38,6 +38,10 @@
    in EL3 FW. This build option should be set to 1 if the target platform contains
    at least 1 CPU that requires this mitigation. Defaults to 1.
 
+-  ``WORKAROUND_CVE_2024_7881``: Enables mitigation for `CVE-2024-7881`.
+   This build option should be set to 1 if the target platform contains at
+   least 1 CPU that requires this mitigation. Defaults to 1.
+
 .. _arm_cpu_macros_errata_workarounds:
 
 CPU Errata Workarounds
@@ -1055,7 +1059,7 @@
 
 --------------
 
-*Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.*
 
 .. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
 .. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639
diff --git a/include/lib/cpus/aarch64/cortex_x4.h b/include/lib/cpus/aarch64/cortex_x4.h
index f701216..116f9a0 100644
--- a/include/lib/cpus/aarch64/cortex_x4.h
+++ b/include/lib/cpus/aarch64/cortex_x4.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,6 +36,11 @@
 #define CORTEX_X4_CPUACTLR5_EL1				S3_0_C15_C8_0
 #define CORTEX_X4_CPUACTLR5_EL1_BIT_14			(ULL(1) << 14)
 
+/*******************************************************************************
+ * CPU Auxiliary control register 6 specific definitions
+ ******************************************************************************/
+#define CORTEX_X4_CPUACTLR6_EL1				S3_0_C15_C8_1
+
 #ifndef __ASSEMBLER__
 #if ERRATA_X4_2726228
 long check_erratum_cortex_x4_2726228(long cpu_rev);
diff --git a/include/lib/cpus/aarch64/cortex_x925.h b/include/lib/cpus/aarch64/cortex_x925.h
index b0d0ca4..ecbbb59 100644
--- a/include/lib/cpus/aarch64/cortex_x925.h
+++ b/include/lib/cpus/aarch64/cortex_x925.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,4 +21,9 @@
 #define CORTEX_X925_CPUPWRCTLR_EL1				S3_0_C15_C2_7
 #define CORTEX_X925_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
+/*******************************************************************************
+ * CPU Auxiliary control register 6 specific definitions
+ ******************************************************************************/
+#define CORTEX_X925_CPUACTLR6_EL1                                S3_0_C15_C8_1
+
 #endif /* CORTEX_X925_H */
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 5e92934..0ce9c3c 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -63,6 +63,10 @@
 	 *	This is a placeholder for future per CPU operations. Currently,
 	 *	some CPUs use this entry to set a test function to determine if
 	 *	the workaround for CVE-2022-23960 needs to be applied or not.
+	 * _extra4:
+	 *	This is a placeholder for future per CPU operations. Currently,
+	 *	some CPUs use this entry to set a test function to determine if
+	 *	the workaround for CVE-2024-7881 needs to be applied or not.
 	 * _e_handler:
 	 *	This is a placeholder for future per CPU exception handlers.
 	 * _power_down_ops:
@@ -75,7 +79,8 @@
 	 *	used to handle power down at subsequent levels
 	 */
 	.macro declare_cpu_ops_base _name:req, _midr:req, _resetfunc:req, \
-		_extra1:req, _extra2:req, _extra3:req, _e_handler:req, _power_down_ops:vararg
+		_extra1:req, _extra2:req, _extra3:req, _extra4:req, \
+		_e_handler:req, _power_down_ops:vararg
 	.section .cpu_ops, "a"
 	.align 3
 	.type cpu_ops_\_name, %object
@@ -86,6 +91,7 @@
 	.quad \_extra1
 	.quad \_extra2
 	.quad \_extra3
+	.quad \_extra4
 	.quad \_e_handler
 #ifdef IMAGE_BL31
 	/* Insert list of functions */
@@ -148,21 +154,28 @@
 
 	.macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
 		_power_down_ops:vararg
-		declare_cpu_ops_base \_name, \_midr, \_resetfunc, 0, 0, 0, 0, \
+		declare_cpu_ops_base \_name, \_midr, \_resetfunc, 0, 0, 0, 0, 0, \
 			\_power_down_ops
 	.endm
 
 	.macro declare_cpu_ops_eh _name:req, _midr:req, _resetfunc:req, \
 		_e_handler:req, _power_down_ops:vararg
 		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
-			0, 0, 0, \_e_handler, \_power_down_ops
+			0, 0, 0, 0, \_e_handler, \_power_down_ops
 	.endm
 
 	.macro declare_cpu_ops_wa _name:req, _midr:req, \
 		_resetfunc:req, _extra1:req, _extra2:req, \
 		_extra3:req, _power_down_ops:vararg
 		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
+			\_extra1, \_extra2, \_extra3, 0, 0, \_power_down_ops
+	.endm
+
+	.macro declare_cpu_ops_wa_4 _name:req, _midr:req, \
+		_resetfunc:req, _extra1:req, _extra2:req, \
+		_extra3:req, _extra4:req, _power_down_ops:vararg
+		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
-			\_extra1, \_extra2, \_extra3, 0, \_power_down_ops
+			\_extra1, \_extra2, \_extra3, \_extra4, 0, \_power_down_ops
 	.endm
 
 	/*
diff --git a/include/lib/cpus/aarch64/neoverse_v2.h b/include/lib/cpus/aarch64/neoverse_v2.h
index 1171e95..427cafa 100644
--- a/include/lib/cpus/aarch64/neoverse_v2.h
+++ b/include/lib/cpus/aarch64/neoverse_v2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -58,4 +58,9 @@
 #define NEOVERSE_V2_CPUACTLR5_EL1_BIT_56		(ULL(1) << 56)
 #define NEOVERSE_V2_CPUACTLR5_EL1_BIT_55		(ULL(1) << 55)
 
+/*******************************************************************************
+ * CPU Auxiliary control register 6 specific definitions
+ ******************************************************************************/
+#define NEOVERSE_V2_CPUACTLR6_EL1			S3_0_C15_C8_1
+
 #endif /* NEOVERSE_V2_H */
diff --git a/include/lib/cpus/aarch64/neoverse_v3.h b/include/lib/cpus/aarch64/neoverse_v3.h
index e5f75ba..a31bdd3 100644
--- a/include/lib/cpus/aarch64/neoverse_v3.h
+++ b/include/lib/cpus/aarch64/neoverse_v3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,7 +22,12 @@
 /*******************************************************************************
  * CPU Power Control register specific definitions
  ******************************************************************************/
-#define NEOVERSE_V3_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define NEOVERSE_V3_CPUPWRCTLR_EL1				S3_0_C15_C2_7
 #define NEOVERSE_V3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
+/*******************************************************************************
+ * CPU Auxiliary control register 6 specific definitions
+ ******************************************************************************/
+#define NEOVERSE_V3_CPUACTLR6_EL1                                S3_0_C15_C8_1
+
 #endif /* NEOVERSE_V3_H */
diff --git a/include/lib/cpus/cpu_ops.h b/include/lib/cpus/cpu_ops.h
index 0084189..c1bdf8d 100644
--- a/include/lib/cpus/cpu_ops.h
+++ b/include/lib/cpus/cpu_ops.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,6 +28,7 @@
 #define CPU_NO_EXTRA1_FUNC		0
 #define CPU_NO_EXTRA2_FUNC		0
 #define CPU_NO_EXTRA3_FUNC		0
+#define CPU_NO_EXTRA4_FUNC		0
 #endif /* __aarch64__ */
 
 
@@ -45,6 +46,7 @@
 #define CPU_EXTRA1_FUNC_SIZE	CPU_WORD_SIZE
 #define CPU_EXTRA2_FUNC_SIZE	CPU_WORD_SIZE
 #define CPU_EXTRA3_FUNC_SIZE	CPU_WORD_SIZE
+#define CPU_EXTRA4_FUNC_SIZE	CPU_WORD_SIZE
 #define CPU_E_HANDLER_FUNC_SIZE CPU_WORD_SIZE
 /* The power down core and cluster is needed only in BL31 and BL32 */
 #if defined(IMAGE_BL31) || defined(IMAGE_BL32)
@@ -89,7 +91,8 @@
 #define CPU_EXTRA1_FUNC		CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
 #define CPU_EXTRA2_FUNC		CPU_EXTRA1_FUNC + CPU_EXTRA1_FUNC_SIZE
 #define CPU_EXTRA3_FUNC		CPU_EXTRA2_FUNC + CPU_EXTRA2_FUNC_SIZE
-#define CPU_E_HANDLER_FUNC	CPU_EXTRA3_FUNC + CPU_EXTRA3_FUNC_SIZE
+#define CPU_EXTRA4_FUNC		CPU_EXTRA3_FUNC + CPU_EXTRA3_FUNC_SIZE
+#define CPU_E_HANDLER_FUNC	CPU_EXTRA4_FUNC + CPU_EXTRA4_FUNC_SIZE
 #define CPU_PWR_DWN_OPS		CPU_E_HANDLER_FUNC + CPU_E_HANDLER_FUNC_SIZE
 #else
 #define CPU_PWR_DWN_OPS		CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
@@ -119,6 +122,7 @@
 	void (*extra1_func)(void);
 	void (*extra2_func)(void);
 	void (*extra3_func)(void);
+	void (*extra4_func)(void);
 	void (*e_handler_func)(long es);
 #endif /* __aarch64__ */
 #if (defined(IMAGE_BL31) || defined(IMAGE_BL32)) && CPU_MAX_PWR_DWN_OPS
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
index 2c31515..a2f2fc6 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -48,6 +48,8 @@
 unsigned int check_if_affected_core(void);
 #endif
 
+int check_wa_cve_2024_7881(void);
+
 /*
  * NOTE that this structure will be different on AArch32 and AArch64. The
  * uintptr_t will reflect the change and the alignment will be correct in both.
diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h
index c2b1f41..ed9bc95 100644
--- a/include/services/arm_arch_svc.h
+++ b/include/services/arm_arch_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #define SMCCC_ARCH_WORKAROUND_2		U(0x80007FFF)
 #define SMCCC_ARCH_WORKAROUND_3		U(0x80003FFF)
 #define SMCCC_ARCH_FEATURE_AVAILABILITY		U(0x80000003)
+#define SMCCC_ARCH_WORKAROUND_4		U(0x80000004)
 
 #define SMCCC_GET_SOC_VERSION		U(0)
 #define SMCCC_GET_SOC_REVISION		U(1)
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index 6becf7b..4a0212e 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -111,6 +111,17 @@
 
 check_erratum_chosen cortex_x3, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+workaround_reset_start cortex_x3, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
+	/* ---------------------------------
+	 * Sets BIT41 of CPUACTLR6_EL1 which
+	 * disables L1 Data cache prefetcher
+	 * ---------------------------------
+	 */
+	sysreg_bit_set CORTEX_X3_CPUACTLR6_EL1, BIT(41)
+workaround_reset_end cortex_x3, CVE(2024, 7881)
+
+check_erratum_chosen cortex_x3, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
+
 cpu_reset_func_start cortex_x3
 	/* Disable speculative loads */
 	msr	SSBS, xzr
@@ -151,6 +162,10 @@
 	ret
 endfunc cortex_x3_cpu_reg_dump
 
-declare_cpu_ops cortex_x3, CORTEX_X3_MIDR, \
+declare_cpu_ops_wa_4 cortex_x3, CORTEX_X3_MIDR, \
 	cortex_x3_reset_func, \
+	CPU_NO_EXTRA1_FUNC, \
+	CPU_NO_EXTRA2_FUNC, \
+	CPU_NO_EXTRA3_FUNC, \
+	check_erratum_cortex_x3_7881, \
 	cortex_x3_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index 81704da..5765828 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -108,6 +108,17 @@
 
 check_erratum_chosen cortex_x4, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+workaround_reset_start cortex_x4, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
+	/* ---------------------------------
+	 * Sets BIT41 of CPUACTLR6_EL1 which
+	 * disables L1 Data cache prefetcher
+	 * ---------------------------------
+	 */
+	sysreg_bit_set CORTEX_X4_CPUACTLR6_EL1, BIT(41)
+workaround_reset_end cortex_x4, CVE(2024, 7881)
+
+check_erratum_chosen cortex_x4, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
+
 cpu_reset_func_start cortex_x4
 	/* Disable speculative loads */
 	msr	SSBS, xzr
@@ -149,6 +160,10 @@
 	ret
 endfunc cortex_x4_cpu_reg_dump
 
-declare_cpu_ops cortex_x4, CORTEX_X4_MIDR, \
+declare_cpu_ops_wa_4 cortex_x4, CORTEX_X4_MIDR, \
 	cortex_x4_reset_func, \
+	CPU_NO_EXTRA1_FUNC, \
+	CPU_NO_EXTRA2_FUNC, \
+	CPU_NO_EXTRA3_FUNC, \
+	check_erratum_cortex_x4_7881, \
 	cortex_x4_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x925.S b/lib/cpus/aarch64/cortex_x925.S
index 3a31664..5b6632a 100644
--- a/lib/cpus/aarch64/cortex_x925.S
+++ b/lib/cpus/aarch64/cortex_x925.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,6 +28,17 @@
 
 check_erratum_ls cortex_x925, CVE(2024, 5660), CPU_REV(0, 1)
 
+workaround_reset_start cortex_x925, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
+	/* ---------------------------------
+         * Sets BIT41 of CPUACTLR6_EL1 which
+         * disables L1 Data cache prefetcher
+         * ---------------------------------
+         */
+	sysreg_bit_set CORTEX_X925_CPUACTLR6_EL1, BIT(41)
+workaround_reset_end cortex_x925, CVE(2024, 7881)
+
+check_erratum_chosen cortex_x925, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
+
 cpu_reset_func_start cortex_x925
 	/* Disable speculative loads */
 	msr	SSBS, xzr
@@ -66,6 +77,10 @@
 	ret
 endfunc cortex_x925_cpu_reg_dump
 
-declare_cpu_ops cortex_x925, CORTEX_X925_MIDR, \
+declare_cpu_ops_wa_4 cortex_x925, CORTEX_X925_MIDR, \
 	cortex_x925_reset_func, \
+	CPU_NO_EXTRA1_FUNC, \
+	CPU_NO_EXTRA2_FUNC, \
+	CPU_NO_EXTRA3_FUNC, \
+	check_erratum_cortex_x925_7881, \
 	cortex_x925_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 3aa4f15..0f9a3b8 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -327,6 +327,43 @@
 endfunc check_wa_cve_2017_5715
 
 /*
+ * int check_wa_cve_2024_7881(void);
+ *
+ * This function returns:
+ *  - ERRATA_APPLIES when firmware mitigation is required.
+ *  - ERRATA_NOT_APPLIES when firmware mitigation is _not_ required.
+ *  - ERRATA_MISSING when firmware mitigation would be required but
+ *    is not compiled in.
+ *
+ * NOTE: Must be called only after cpu_ops have been initialized
+ *       in per-CPU data.
+ */
+.globl	check_wa_cve_2024_7881
+func check_wa_cve_2024_7881
+	mrs	x0, tpidr_el3
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
+	ldr	x0, [x0, #CPU_DATA_CPU_OPS_PTR]
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
+	ldr	x0, [x0, #CPU_EXTRA4_FUNC]
+	/*
+	 * If the reserved function pointer is NULL, this CPU
+	 * is unaffected by CVE-2024-7881 so bail out.
+	 */
+	cmp	x0, #CPU_NO_EXTRA4_FUNC
+	beq	1f
+	br	x0
+1:
+	mov	x0, #ERRATA_NOT_APPLIES
+	ret
+endfunc check_wa_cve_2024_7881
+
+/*
  * void *wa_cve_2018_3639_get_disable_ptr(void);
  *
  * Returns a function pointer which is used to disable mitigation
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index f56a5e8..b43f6dd 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -97,6 +97,17 @@
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V2_BHB_LOOP_COUNT, neoverse_v2
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_reset_start neoverse_v2, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
+       /* ---------------------------------
+        * Sets BIT41 of CPUACTLR6_EL1 which
+        * disables L1 Data cache prefetcher
+        * ---------------------------------
+        */
+       sysreg_bit_set NEOVERSE_V2_CPUACTLR6_EL1, BIT(41)
+workaround_reset_end neoverse_v2, CVE(2024, 7881)
+
+check_erratum_chosen neoverse_v2, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -142,6 +153,10 @@
 	ret
 endfunc neoverse_v2_cpu_reg_dump
 
-declare_cpu_ops neoverse_v2, NEOVERSE_V2_MIDR, \
+declare_cpu_ops_wa_4 neoverse_v2, NEOVERSE_V2_MIDR, \
 	neoverse_v2_reset_func, \
+	CPU_NO_EXTRA1_FUNC, \
+	CPU_NO_EXTRA2_FUNC, \
+	CPU_NO_EXTRA3_FUNC, \
+	check_erratum_neoverse_v2_7881, \
 	neoverse_v2_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_v3.S b/lib/cpus/aarch64/neoverse_v3.S
index 4346d7d..69b6627 100644
--- a/lib/cpus/aarch64/neoverse_v3.S
+++ b/lib/cpus/aarch64/neoverse_v3.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -46,6 +46,17 @@
 
 check_erratum_chosen neoverse_v3, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+workaround_reset_start neoverse_v3, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
+       /* ---------------------------------
+        * Sets BIT41 of CPUACTLR6_EL1 which
+        * disables L1 Data cache prefetcher
+        * ---------------------------------
+        */
+       sysreg_bit_set NEOVERSE_V3_CPUACTLR6_EL1, BIT(41)
+workaround_reset_end neoverse_v3, CVE(2024, 7881)
+
+check_erratum_chosen neoverse_v3, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
+
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
@@ -90,6 +101,10 @@
 	neoverse_v3_reset_func, \
 	neoverse_v3_core_pwr_dwn
 
-declare_cpu_ops neoverse_v3, NEOVERSE_V3_MIDR, \
+declare_cpu_ops_wa_4 neoverse_v3, NEOVERSE_V3_MIDR, \
 	neoverse_v3_reset_func, \
+	CPU_NO_EXTRA1_FUNC, \
+	CPU_NO_EXTRA2_FUNC, \
+	CPU_NO_EXTRA3_FUNC, \
+	check_erratum_neoverse_v3_7881, \
 	neoverse_v3_core_pwr_dwn
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index d532460..1984689 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -32,6 +32,8 @@
 CPU_FLAG_LIST += DYNAMIC_WORKAROUND_CVE_2018_3639
 WORKAROUND_CVE_2022_23960		?=1
 CPU_FLAG_LIST += WORKAROUND_CVE_2022_23960
+WORKAROUND_CVE_2024_7881		?=1
+CPU_FLAG_LIST += WORKAROUND_CVE_2024_7881
 
 # Flag to disable Hardware page aggregation(HPA).
 # This flag is enabled by default.
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
index 10fe666..dba83ab 100644
--- a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
@@ -44,6 +44,23 @@
 	return (size_t)RMM_SHARED_SIZE;
 }
 
+/*
+ * Calculate checksum of 64-bit words @buffer with @size length
+ */
+static uint64_t checksum_calc(uint64_t *buffer, size_t size)
+{
+	uint64_t sum = 0UL;
+
+	assert(((uintptr_t)buffer & (sizeof(uint64_t) - 1UL)) == 0UL);
+	assert((size & (sizeof(uint64_t) - 1UL)) == 0UL);
+
+	for (unsigned long i = 0UL; i < (size / sizeof(uint64_t)); i++) {
+		sum += buffer[i];
+	}
+
+	return sum;
+}
+
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 {
 	uint64_t checksum, num_banks, num_consoles;
@@ -138,8 +155,8 @@
 	bank_ptr[1].size = ARM_DRAM2_SIZE;
 
 	/* Update checksum */
-	checksum += bank_ptr[0].base + bank_ptr[0].size + bank_ptr[1].base +
-		bank_ptr[1].size;
+	checksum += checksum_calc((uint64_t *)bank_ptr,
+		sizeof(struct ns_dram_bank) * num_banks);
 
 	/* Checksum must be 0 */
 	manifest->plat_dram.checksum = ~checksum + 1UL;
@@ -148,20 +165,20 @@
 	checksum = num_consoles + (uint64_t)console_ptr;
 
 	/* Zero out the console info struct */
-	memset((void *)console_ptr, '\0',
+	(void)memset((void *)console_ptr, '\0',
 		sizeof(struct console_info) * num_consoles);
 
-	console_ptr[0].map_pages = 1;
+	console_ptr[0].map_pages = 1UL;
 	console_ptr[0].base = NRD_CSS_RMM_CONSOLE_BASE;
 	console_ptr[0].clk_in_hz = NRD_CSS_RMM_CONSOLE_CLK_IN_HZ;
 	console_ptr[0].baud_rate = NRD_CSS_RMM_CONSOLE_BAUD;
 
-	strlcpy(console_ptr[0].name, NRD_CSS_RMM_CONSOLE_NAME,
+	(void)strlcpy(console_ptr[0].name, NRD_CSS_RMM_CONSOLE_NAME,
 		sizeof(console_ptr[0].name));
 
 	/* Update checksum */
-	checksum += console_ptr[0].base + console_ptr[0].map_pages +
-		console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
+	checksum += checksum_calc((uint64_t *)console_ptr,
+		sizeof(struct console_info) * num_consoles);
 
 	/* Checksum must be 0 */
 	manifest->plat_console.checksum = ~checksum + 1UL;
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 1ec7c44..b2b3253 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -160,6 +160,11 @@
 PLAT_BL_COMMON_SOURCES	+=	${TC_BASE}/tc_plat.c	\
 				${TC_BASE}/include/tc_helpers.S
 
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES	+=	${TC_BASE}/tc_stack_protector.c
+endif
+
 BL1_SOURCES		+=	${INTERCONNECT_SOURCES}	\
 				${TC_CPU_SOURCES}	\
 				${TC_BASE}/tc_trusted_boot.c	\
diff --git a/plat/arm/board/tc/tc_stack_protector.c b/plat/arm/board/tc/tc_stack_protector.c
new file mode 100644
index 0000000..89701fb
--- /dev/null
+++ b/plat/arm/board/tc/tc_stack_protector.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <plat/common/platform.h>
+
+#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL)
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+	/*
+	 * On the Total Compute platform, it can generate RNG via MHU channel
+	 * and communicate with RSE. But the stack protector canary function
+	 * is needed prior to MHU channel gets ready.
+	 *
+	 * Since now MHU module cannot distinguish if MHU channel has been
+	 * initialized or not, if it arbitrarily tries to send message, it will
+	 * cause panic. For this reason, this function cannot rollback to
+	 * dummy random number based on the MHU failure.
+	 *
+	 * For above reasons, simply return a value of the combination of a
+	 * timer's value and a compile-time constant.
+	 */
+	return RANDOM_CANARY_VALUE ^ read_cntpct_el0();
+}
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index 840ffdd..9445798 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -127,10 +127,21 @@
 #define SDMMC_WRITE_BLOCKS			mmc_write_blocks
 
 /*******************************************************************************
- * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * sysmgr.boot_scratch_cold6 Bits[3:0] is used to indicate L2 reset
  * is done and HPS should trigger warm reset via RMR_EL3.
  ******************************************************************************/
-#define L2_RESET_DONE_REG			0xFFD12218
+/*
+ * Magic key bits: 4 bits[3:0] from boot scratch register COLD6 are used to
+ * indicate the below requests/status
+ *     0x0       : Default value on reset, not used
+ *     0x1       : L2/warm reset is completed
+ *     0x2 - 0xF : Reserved for future use
+ */
+#define BS_REG_MAGIC_KEYS_MASK			0x0F
+#define BS_REG_MAGIC_KEYS_POS			0x00
+#define L2_RESET_DONE_STATUS			(0x01 << BS_REG_MAGIC_KEYS_POS)
+
+#define L2_RESET_DONE_REG			SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_6)
 
 /* Platform specific system counter */
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ		U(400)
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
index ab03928..03559e1 100644
--- a/plat/intel/soc/agilex5/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -237,9 +237,9 @@
 	unsigned int pchctlr_new = 0x00;
 	uint32_t boot_core = 0x00;
 
-	/* Store magic number for SMP secondary cores boot */
-	mmio_write_32(L2_RESET_DONE_REG, SMP_SEC_CORE_BOOT_REQ);
-
+	/* Set bit for SMP secondary cores boot */
+	mmio_clrsetbits_32(L2_RESET_DONE_REG, BS_REG_MAGIC_KEYS_MASK,
+			   SMP_SEC_CORE_BOOT_REQ);
 	boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
 	/* Update the p-channel based on cpu id */
 	pch_cpu = 1 << cpu_id;
diff --git a/plat/intel/soc/agilex5/include/socfpga_plat_def.h b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
index c1f3cc5..282958a 100644
--- a/plat/intel/soc/agilex5/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -96,6 +96,21 @@
 								OCRAM_REGION_0_OFFSET)
 #define OCRAM_NON_SECURE_ENABLE					0x0
 
+
+/*
+ * Magic key bits: 4 bits[5:2] from boot scratch register COLD3 are used to
+ * indicate the below requests/status
+ *     0x0       : Default value on reset, not used
+ *     0x1       : L2/warm reset is completed
+ *     0x2       : SMP secondary core boot requests
+ *     0x3 - 0xF : Reserved for future use
+ */
+#define BS_REG_MAGIC_KEYS_MASK			0x3C
+#define BS_REG_MAGIC_KEYS_POS			0x02
+#define L2_RESET_DONE_STATUS			(0x01 << BS_REG_MAGIC_KEYS_POS)
+#define SMP_SEC_CORE_BOOT_REQ			(0x02 << BS_REG_MAGIC_KEYS_POS)
+#define ALIGN_CHECK_64BIT_MASK			0x07
+
 /*******************************************************************************
  * Platform memory map related constants
  ******************************************************************************/
@@ -157,9 +172,9 @@
 #define SDMMC_WRITE_BLOCKS					sdmmc_write_blocks
 
 /*******************************************************************************
- * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
- * is done and HPS should trigger warm reset via RMR_EL3.
+ * sysmgr.boot_scratch_cold3 bits[5:2] are used to indicate L2 reset
+ * is done, or SMP secondary cores boot request status.
  ******************************************************************************/
-#define L2_RESET_DONE_REG					0x10D12218
+#define L2_RESET_DONE_REG					SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_3)
 
 #endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index b3d5665..74ce279 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -98,7 +98,36 @@
 endfunc plat_my_core_pos
 
 func warm_reset_req
-	str	xzr, [x4]
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* Clear the markup before going for warm reset */
+	bic	x2, x2, #BS_REG_MAGIC_KEYS_MASK
+	/* Check if the address is 64 bit aligned or not */
+	ldr	x4, =L2_RESET_DONE_REG
+	tst	x4, #ALIGN_CHECK_64BIT_MASK
+	b.ne	unaligned_store
+	/* Device memory address is aligned, store the value directly */
+	str	x2, [x4]
+	b	continue_warm_reset
+
+	/* Unaligned store, use byte by byte method to store */
+unaligned_store:
+	strb	w2, [x4]
+	lsr	x2, x2, #8
+	add	x4, x4, #1
+	strb	w2, [x4]
+	lsr	x2, x2, #8
+	add	x4, x4, #1
+	strb	w2, [x4]
+	lsr	x2, x2, #8
+	add	x4, x4, #1
+	strb	w2, [x4]
+#else
+	/* Clear the markup before going for warm reset */
+	bic	x2, x2, #BS_REG_MAGIC_KEYS_MASK
+	str	x2, [x4]
+#endif
+
+continue_warm_reset:
 	bl	plat_is_my_cpu_primary
 	cbz	x0, cpu_in_wfi
 	mov_imm x1, PLAT_SEC_ENTRY
@@ -116,36 +145,71 @@
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 func plat_get_my_entrypoint
 	ldr	x4, =L2_RESET_DONE_REG
-	ldr	x5, [x4]
+
+	/* Check if the address is 64 bit aligned or not */
+	tst	x4, #ALIGN_CHECK_64BIT_MASK
+	b.ne	unaligned_load
+
+	/* Device memory address is aligned, load the value directly */
+	ldr	x1, [x4]
+	b	events_check
+
+	/*
+	 * It is unaligned device memory access. Read only LSB 32 bits
+	 * byte by byte and combine them to get the 32 bit value.
+	 */
+unaligned_load:
+	ldrb	w1, [x4]
+	ldrb	w2, [x4, #1]
+	ldrb	w3, [x4, #2]
+	ldrb	w4, [x4, #3]
+	orr	x1, x1, x2, lsl #8
+	orr	x1, x1, x3, lsl #16
+	orr	x1, x1, x4, lsl #24
+
+events_check:
+	/* Keep a backup of the boot scratch register contents */
+	mov	x2, x1
+
+	/* Mask and get the required bits */
+	and	x1, x1, #BS_REG_MAGIC_KEYS_MASK
 
 	/* Check for warm reset request */
-	ldr	x1, =L2_RESET_DONE_STATUS
+	ldr	x5, =L2_RESET_DONE_STATUS
 	cmp	x1, x5
 	b.eq	warm_reset_req
 
 	/* Check for SMP secondary cores boot request */
-	ldr	x1, =SMP_SEC_CORE_BOOT_REQ
+	ldr	x5, =SMP_SEC_CORE_BOOT_REQ
 	cmp	x1, x5
 	b.eq	smp_request
 
-	/* Otherwise it is cold reset */
+	/* Otherwise it is a cold reset request */
 	mov	x0, #0
 	ret
+
 smp_request:
 	/*
-	 * Return the address 'bl31_warm_entrypoint', which is passed to
-	 * 'psci_setup' routine as part of BL31 initialization.
+	 * On the SMP boot request, return the address 'bl31_warm_entrypoint',
+	 * which is passed to 'psci_setup' routine as part of BL31
+	 * initialization.
 	 */
-	mov_imm	x1, PLAT_SEC_ENTRY
+	ldr	x1, =PLAT_SEC_ENTRY
 	ldr	x0, [x1]
-	/* Clear the mark up before return */
-	str	xzr, [x4]
 	ret
 endfunc plat_get_my_entrypoint
 #else
 func plat_get_my_entrypoint
 	ldr	x4, =L2_RESET_DONE_REG
 	ldr	x5, [x4]
+
+	/* Keep a backup of the boot scratch register contents */
+	mov	x2, x5
+
+	/* Mask and get only the required bits */
+	and	x5, x5, #BS_REG_MAGIC_KEYS_MASK
+
+	/* Check for warm reset request */
 	ldr	x1, =L2_RESET_DONE_STATUS
 	cmp	x1, x5
 	b.eq	warm_reset_req
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index a820e41..e2efeb1 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -38,12 +38,6 @@
 /* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
 #define PLAT_CPU_RELEASE_ADDR			0xffd12210
 
-/* Magic word to indicate L2 reset is completed */
-#define L2_RESET_DONE_STATUS			0x1228E5E7
-
-/* Magic word to differentiate for SMP secondary core boot request */
-#define SMP_SEC_CORE_BOOT_REQ			0x1228E5E8
-
 /* Define next boot image name and offset */
 /* Get non-secure image entrypoint for BL33. Zephyr and Linux */
 #ifdef PRELOADED_BL33_BASE
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index f653318..0d612e2 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -1052,7 +1052,7 @@
 					1000);
 
 		if (ret < 0) {
-			ERROR("F2S bridge fpga handshake fpgahsack: Timeout\n");
+			VERBOSE("F2S bridge fpga handshake fpgahsack: Timeout\n");
 		}
 
 		/*
@@ -1082,7 +1082,7 @@
 					1000);
 
 		if (ret < 0) {
-			ERROR("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
+			VERBOSE("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
 		}
 
 		/*
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index 50d4820..99c7412 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -223,6 +223,10 @@
 	invalidate_cache_low_el();
 #endif
 
+	/* Set warm reset request bit before issuing the command to SDM. */
+	mmio_clrsetbits_32(L2_RESET_DONE_REG, BS_REG_MAGIC_KEYS_MASK,
+			   L2_RESET_DONE_STATUS);
+
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 	mailbox_reset_warm(reset_type);
 #else
@@ -238,9 +242,6 @@
 	gicv2_cpuif_disable();
 #endif
 
-	/* Store magic number */
-	mmio_write_32(L2_RESET_DONE_REG, L2_RESET_DONE_STATUS);
-
 	/* Increase timeout */
 	mmio_write_32(SOCFPGA_RSTMGR(HDSKTIMEOUT), 0xffffff);
 
diff --git a/plat/intel/soc/n5x/include/socfpga_plat_def.h b/plat/intel/soc/n5x/include/socfpga_plat_def.h
index 6f0a40b..cfc9f9d 100644
--- a/plat/intel/soc/n5x/include/socfpga_plat_def.h
+++ b/plat/intel/soc/n5x/include/socfpga_plat_def.h
@@ -44,7 +44,7 @@
 #define SOCFPGA_MMC_REG_BASE			U(0xff808000)
 #define SOCFPGA_RSTMGR_REG_BASE			U(0xffd11000)
 #define SOCFPGA_SYSMGR_REG_BASE			U(0xffd12000)
-#define SOCFPGA_ECC_QSPI_REG_BASE				U(0xffa22000)
+#define SOCFPGA_ECC_QSPI_REG_BASE		U(0xffa22000)
 
 #define SOCFPGA_L4_PER_SCR_REG_BASE		U(0xffd21000)
 #define SOCFPGA_L4_SYS_SCR_REG_BASE		U(0xffd21100)
@@ -91,7 +91,7 @@
 /*******************************************************************************
  * WDT related constants
  ******************************************************************************/
-#define WDT_BASE			(0xFFD00200)
+#define WDT_BASE				(0xFFD00200)
 
 /*******************************************************************************
  * GIC related constants
@@ -102,7 +102,7 @@
 #define PLAT_GICR_BASE				0
 
 #define PLAT_SYS_COUNTER_FREQ_IN_TICKS		(400000000)
-#define PLAT_HZ_CONVERT_TO_MHZ		(1000000)
+#define PLAT_HZ_CONVERT_TO_MHZ			(1000000)
 
 /*******************************************************************************
  * SDMMC related pointer function
@@ -111,10 +111,21 @@
 #define SDMMC_WRITE_BLOCKS			mmc_write_blocks
 
 /*******************************************************************************
- * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * sysmgr.boot_scratch_cold6 Bits[3:0] is used to indicate L2 reset
  * is done and HPS should trigger warm reset via RMR_EL3.
  ******************************************************************************/
-#define L2_RESET_DONE_REG			0xFFD12218
+/*
+ * Magic key bits: 4 bits[3:0] from boot scratch register COLD6 are used to
+ * indicate the below requests/status
+ *     0x0       : Default value on reset, not used
+ *     0x1       : L2/warm reset is completed
+ *     0x2 - 0xF : Reserved for future use
+ */
+#define BS_REG_MAGIC_KEYS_MASK			0x0F
+#define BS_REG_MAGIC_KEYS_POS			0x00
+#define L2_RESET_DONE_STATUS			(0x01 << BS_REG_MAGIC_KEYS_POS)
+
+#define L2_RESET_DONE_REG			SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_6)
 
 /* Platform specific system counter */
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ		U(400)
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 90345c3..b6272fc 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -45,7 +45,7 @@
 
 #define SOCFPGA_RSTMGR_REG_BASE			0xffd11000
 #define SOCFPGA_SYSMGR_REG_BASE			0xffd12000
-#define SOCFPGA_ECC_QSPI_REG_BASE				0xffa22000
+#define SOCFPGA_ECC_QSPI_REG_BASE		0xffa22000
 
 #define SOCFPGA_L4_PER_SCR_REG_BASE		0xffd21000
 #define SOCFPGA_L4_SYS_SCR_REG_BASE		0xffd21100
@@ -91,7 +91,7 @@
 /*******************************************************************************
  * WDT related constants
  ******************************************************************************/
-#define WDT_BASE			(0xFFD00200)
+#define WDT_BASE				(0xFFD00200)
 
 /*******************************************************************************
  * GIC related constants
@@ -102,7 +102,7 @@
 #define PLAT_GICR_BASE				0
 
 #define PLAT_SYS_COUNTER_FREQ_IN_TICKS		(400000000)
-#define PLAT_HZ_CONVERT_TO_MHZ		(1000000)
+#define PLAT_HZ_CONVERT_TO_MHZ			(1000000)
 
 /*******************************************************************************
  * SDMMC related pointer function
@@ -111,10 +111,21 @@
 #define SDMMC_WRITE_BLOCKS			mmc_write_blocks
 
 /*******************************************************************************
- * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * sysmgr.boot_scratch_cold6 Bits[3:0] is used to indicate L2 reset
  * is done and HPS should trigger warm reset via RMR_EL3.
  ******************************************************************************/
-#define L2_RESET_DONE_REG			0xFFD12218
+/*
+ * Magic key bits: 4 bits[3:0] from boot scratch register COLD6 are used to
+ * indicate the below requests/status
+ *     0x0       : Default value on reset, not used
+ *     0x1       : L2/warm reset is completed
+ *     0x2 - 0xF : Reserved for future use
+ */
+#define BS_REG_MAGIC_KEYS_MASK			0x0F
+#define BS_REG_MAGIC_KEYS_POS			0x00
+#define L2_RESET_DONE_STATUS			(0x01 << BS_REG_MAGIC_KEYS_POS)
+
+#define L2_RESET_DONE_REG			SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_6)
 
 /* Platform specific system counter */
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ		U(400)
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_power.c b/plat/mediatek/drivers/apusys/mt8196/apusys_power.c
index 4262d63..dcf6423 100644
--- a/plat/mediatek/drivers/apusys/mt8196/apusys_power.c
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_power.c
@@ -1,16 +1,12 @@
 /*
- * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2024-2025, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <inttypes.h>
 
-#define SPMI_ENABLE	(0)
-
-#if SPMI_ENABLE
 #include <include/drivers/spmi_api.h>
-#endif
 
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
@@ -259,16 +255,13 @@
 	uint32_t en_set_offset = BUCK_VAPU_PMIC_REG_EN_SET_ADDR;
 	uint32_t en_clr_offset = BUCK_VAPU_PMIC_REG_EN_CLR_ADDR;
 	uint32_t en_shift = BUCK_VAPU_PMIC_REG_EN_SHIFT;
-#if SPMI_ENABLE
 	struct spmi_device *vsram_sdev;
-#endif
 	unsigned char vsram = 0;
 
 	mmio_write_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, AUTO_BUCK_EN);
 
 	mmio_write_32((APUSYS_PCU + APU_PCU_BUCK_STEP_SEL), BUCK_STEP_SEL_VAL);
 
-#if SPMI_ENABLE
 	vsram_sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
 	if (!vsram_sdev) {
 		ERROR("[APUPW] VSRAM BUCK4 get device fail\n");
@@ -279,7 +272,6 @@
 		ERROR("[APUPW] VSRAM BUCK4 read fail\n");
 		return -1;
 	}
-#endif
 
 	mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_L,
 		      (BUCK_VAPU_PMIC_REG_VOSEL_ADDR << PMIC_OFF_ADDR_OFF) | vsram);
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
index fbd2aa0..a0d21c6 100644
--- a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
@@ -1,14 +1,13 @@
 /*
- * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2024-2025, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#define ENABLE_SMPU_PROTECT	(0)
+#define ENABLE_SMPU_PROTECT	(1)
 
 #if ENABLE_SMPU_PROTECT
 #include "emi.h"
-#include "mt_emi.h"
 #endif
 
 #include <common/debug.h>
diff --git a/plat/mediatek/drivers/apusys/mt8196/rules.mk b/plat/mediatek/drivers/apusys/mt8196/rules.mk
index 4ffaf73..aeb6d3d 100644
--- a/plat/mediatek/drivers/apusys/mt8196/rules.mk
+++ b/plat/mediatek/drivers/apusys/mt8196/rules.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+# Copyright (c) 2024-2025, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -10,7 +10,6 @@
 
 ifeq (${CONFIG_MTK_APUSYS_EMI_SUPPORT}, y)
 PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/common
-PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/${MTK_SOC}
 endif
 
 LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_ammu.c
diff --git a/plat/mediatek/drivers/mminfra/mminfra_stub.c b/plat/mediatek/drivers/mminfra/mminfra_stub.c
new file mode 100644
index 0000000..dc37280
--- /dev/null
+++ b/plat/mediatek/drivers/mminfra/mminfra_stub.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/mminfra_public.h>
+
+int mminfra_get_if_in_use(void)
+{
+	return 0;
+}
+
+int mminfra_put(void)
+{
+	return 0;
+}
diff --git a/plat/mediatek/drivers/mminfra/rules.mk b/plat/mediatek/drivers/mminfra/rules.mk
new file mode 100644
index 0000000..f3a6822
--- /dev/null
+++ b/plat/mediatek/drivers/mminfra/rules.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mminfra
+
+PLAT_INCLUDES += -I${MTK_PLAT}/include/drivers/
+
+ifeq ($(MTKLIB_PATH),)
+LOCAL_SRCS-y := ${LOCAL_DIR}/mminfra_stub.c
+endif
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/include/drivers/mminfra_public.h b/plat/mediatek/include/drivers/mminfra_public.h
new file mode 100644
index 0000000..14ab361
--- /dev/null
+++ b/plat/mediatek/include/drivers/mminfra_public.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef MMINFRA_PUBLIC_H
+#define MMINFRA_PUBLIC_H
+
+#define MMINFRA_RET_ERR		(-1)
+#define MMINFRA_RET_POWER_OFF	0
+#define MMINFRA_RET_POWER_ON	1
+
+int mminfra_get_if_in_use(void);
+int mminfra_put(void);
+
+#endif
diff --git a/plat/mediatek/mt8196/include/platform_def.h b/plat/mediatek/mt8196/include/platform_def.h
index 4752e5b..72d83e6 100644
--- a/plat/mediatek/mt8196/include/platform_def.h
+++ b/plat/mediatek/mt8196/include/platform_def.h
@@ -148,6 +148,15 @@
 			GIC_INTR_CFG_LEVEL)
 
 /*******************************************************************************
+ * CIRQ related constants
+ ******************************************************************************/
+#define SYS_CIRQ_BASE		(IO_PHYS + 0x1CB000)
+#define MD_WDT_IRQ_BIT_ID	(397)
+#define CIRQ_REG_NUM		(26)
+#define CIRQ_SPI_START		(128)
+#define CIRQ_IRQ_NUM		(831)
+
+/*******************************************************************************
  * MM IOMMU & SMI related constants
  ******************************************************************************/
 #define SMI_LARB_0_BASE		(IO_PHYS + 0x0c022000)
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
index 773407a..0c87db9 100644
--- a/plat/mediatek/mt8196/plat_config.mk
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -27,7 +27,7 @@
 
 CONFIG_ARCH_ARM_V9 := y
 CONFIG_MTK_APUSYS_CE_SUPPORT := y
-CONFIG_MTK_APUSYS_EMI_SUPPORT := n
+CONFIG_MTK_APUSYS_EMI_SUPPORT := y
 CONFIG_MTK_APUSYS_LOGTOP_SUPPORT := y
 CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT := y
 CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT := y
diff --git a/plat/mediatek/mt8196/platform.mk b/plat/mediatek/mt8196/platform.mk
index 955d71d..3a459c2 100644
--- a/plat/mediatek/mt8196/platform.mk
+++ b/plat/mediatek/mt8196/platform.mk
@@ -42,10 +42,12 @@
 MODULES-y += $(MTK_PLAT)/lib/mtk_init
 MODULES-y += $(MTK_PLAT)/lib/pm
 MODULES-y += $(MTK_PLAT)/drivers/apusys
+MODULES-y += $(MTK_PLAT)/drivers/cirq
 MODULES-y += $(MTK_PLAT)/drivers/dp
 MODULES-y += $(MTK_PLAT)/drivers/emi
 MODULES-y += $(MTK_PLAT)/drivers/gicv3
 MODULES-y += $(MTK_PLAT)/drivers/mcusys
+MODULES-y += $(MTK_PLAT)/drivers/mminfra
 MODULES-y += $(MTK_PLAT)/drivers/spm
 MODULES-y += $(MTK_PLAT)/drivers/timer
 MODULES-y += $(MTK_PLAT)/drivers/vcp
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S
index 26f3313..db2d421 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S
@@ -6,16 +6,16 @@
 
 /* convoluted way to make sure that the define is pasted just the right way */
 .macro INCBIN file sym sec
-	.section \sec
+	.section \sec, "a"
 	.global \sym
 	.type \sym, @object
 	.align 4
 \sym :
-	.incbin \file
+	.incbin "\file"
 	.size \sym , .-\sym
 	.global \sym\()_end
 \sym\()_end :
 .endm
 
-INCBIN ""RK3399M0FW"", "rk3399m0_bin", ".sram.incbin"
-INCBIN ""RK3399M0PMUFW"", "rk3399m0pmu_bin", ".pmusram.incbin"
+INCBIN RK3399M0FW, "rk3399m0_bin", ".sram.incbin"
+INCBIN RK3399M0PMUFW, "rk3399m0pmu_bin", ".pmusram.incbin"
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index 3498f91..89031b8 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -15,7 +15,7 @@
 
 #include "pm_common.h"
 
-#define CLK_NAME_LEN		(15U)
+#define CLK_NAME_LEN		(16U)
 #define MAX_PARENTS		(100U)
 #define CLK_NA_PARENT		-1
 #define CLK_DUMMY_PARENT	-2
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 6acd1b6..46333af 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -99,6 +99,14 @@
 		return SMC_ARCH_CALL_SUCCESS;
 #endif /* ARCH_FEATURE_AVAILABILITY */
 
+#if WORKAROUND_CVE_2024_7881
+	case SMCCC_ARCH_WORKAROUND_4:
+		if (check_wa_cve_2024_7881() != ERRATA_APPLIES) {
+			return SMC_ARCH_CALL_NOT_SUPPORTED;
+		}
+		return 0;
+#endif /* WORKAROUND_CVE_2024_7881 */
+
 #endif /* __aarch64__ */
 
 	/* Fallthrough */
@@ -254,6 +262,15 @@
 		 */
 		SMC_RET0(handle);
 #endif
+#if WORKAROUND_CVE_2024_7881
+	case SMCCC_ARCH_WORKAROUND_4:
+		/*
+		 * The workaround has already been applied on affected PEs
+		 * during cold boot. This function has no effect whether PE is
+		 * affected or not.
+		 */
+		SMC_RET0(handle);
+#endif /* WORKAROUND_CVE_2024_7881 */
 #endif /* __aarch64__ */
 #if ARCH_FEATURE_AVAILABILITY
 	/* return is 64 bit so only reply on SMC64 requests */
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index 9bf5cd0..f80050e 100644
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -87,6 +87,19 @@
     check_sp_layout_dir(args)
     return os.path.join(args["sp_layout_dir"], get_file_from_layout(sp_node["image"]))
 
+def get_size(sp_node):
+    if not "size" in sp_node:
+        print("WARNING: default image size 0x100000")
+        return 0x100000
+
+    # Try if it was a decimal value.
+    try:
+        return int(sp_node["size"])
+    except ValueError:
+        print("WARNING: trying to parse base 16 size")
+        # Try if it is of base 16
+        return int(sp_node["size"], 16)
+
 def get_sp_pkg(sp, args :dict):
     check_out_dir(args)
     return os.path.join(args["out_dir"], f"{sp}.pkg")
@@ -146,7 +159,6 @@
     load_address_parsed = re.search("(0x[0-9a-f]+)", load_address_lines[0])
     return load_address_parsed.group(0)
 
-
 @SpSetupActions.sp_action(global_action=True)
 def check_max_sps(sp_layout, _, args :dict):
     ''' Check validate the maximum number of SPs is respected. '''
@@ -167,31 +179,60 @@
     write_to_sp_mk_gen(f"FDT_SOURCES += {manifest_path}", args)
     return args
 
+def generate_sp_pkg(sp_node, pkg, sp_img, sp_dtb):
+    ''' Generates the rule in case SP is to be generated in an SP Pkg. '''
+    pm_offset = get_pm_offset(sp_node)
+    sptool_args = f" --pm-offset {pm_offset}" if pm_offset is not None else ""
+    image_offset = get_image_offset(sp_node)
+    sptool_args += f" --img-offset {image_offset}" if image_offset is not None else ""
+    sptool_args += f" -o {pkg}"
+    return f'''
+{pkg}: {sp_dtb} {sp_img}
+\t$(Q)echo Generating {pkg}
+\t$(Q)$(PYTHON) $(SPTOOL)  -i {sp_img}:{sp_dtb} {sptool_args}
+'''
+
+def generate_tl_pkg(sp_node, pkg, sp_img, sp_dtb, hob_path = None):
+    ''' Generate make rules for a Transfer List type package. '''
+    # TE Type for the FF-A manifest.
+    TE_FFA_MANIFEST = 0x106
+    # TE Type for the SP binary.
+    TE_SP_BINARY = 0x103
+    # TE Type for the HOB List.
+    TE_HOB_LIST = 0x3
+    tlc_add_hob = f"\t$(Q)poetry run tlc add --entry {TE_HOB_LIST} {hob_path} {pkg}" if hob_path is not None else ""
+    return f'''
+{pkg}: {sp_dtb} {sp_img}
+\t$(Q)echo Generating {pkg}
+\t$(Q)$(TLCTOOL) create --size {get_size(sp_node)} --entry {TE_FFA_MANIFEST} {sp_dtb} {pkg} --align 12
+\t$(Q)$(TLCTOOL) add --entry {TE_SP_BINARY} {sp_img} {pkg}
+'''
+
 @SpSetupActions.sp_action
-def gen_sptool_args(sp_layout, sp, args :dict):
+def gen_partition_pkg(sp_layout, sp, args :dict):
     ''' Generate Sp Pkgs rules. '''
-    sp_pkg = get_sp_pkg(sp, args)
+    pkg = get_sp_pkg(sp, args)
+
     sp_dtb_name = os.path.basename(get_file_from_layout(sp_layout[sp]["pm"]))[:-1] + "b"
     sp_dtb = os.path.join(args["out_dir"], f"fdts/{sp_dtb_name}")
     sp_img = get_sp_img_full_path(sp_layout[sp], args)
 
     # Do not generate rule if already there.
-    if is_line_in_sp_gen(f'{sp_pkg}:', args):
+    if is_line_in_sp_gen(f'{pkg}:', args):
         return args
-    write_to_sp_mk_gen(f"SP_PKGS += {sp_pkg}\n", args)
 
-    sptool_args = f" -i {sp_img}:{sp_dtb}"
-    pm_offset = get_pm_offset(sp_layout[sp])
-    sptool_args += f" --pm-offset {pm_offset}" if pm_offset is not None else ""
-    image_offset = get_image_offset(sp_layout[sp])
-    sptool_args += f" --img-offset {image_offset}" if image_offset is not None else ""
-    sptool_args += f" -o {sp_pkg}"
-    sppkg_rule = f'''
-{sp_pkg}: {sp_dtb} {sp_img}
-\t$(Q)echo Generating {sp_pkg}
-\t$(Q)$(PYTHON) $(SPTOOL) {sptool_args}
-'''
-    write_to_sp_mk_gen(sppkg_rule, args)
+    # This should include all packages of all kinds.
+    write_to_sp_mk_gen(f"SP_PKGS += {pkg}\n", args)
+    package_type = sp_layout[sp]["package"] if "package" in sp_layout[sp] else "sp_pkg"
+
+    if package_type == "sp_pkg":
+        partition_pkg_rule = generate_sp_pkg(sp_layout[sp], pkg, sp_img, sp_dtb)
+    elif package_type == "tl_pkg":
+        partition_pkg_rule = generate_tl_pkg(sp_layout[sp], pkg, sp_img, sp_dtb)
+    else:
+        raise ValueError(f"Specified invalid pkg type {package_type}")
+
+    write_to_sp_mk_gen(partition_pkg_rule, args)
     return args
 
 @SpSetupActions.sp_action(global_action=True, exec_order=1)
@@ -202,6 +243,7 @@
     args["split"] =  int(MAX_SP / 2)
     owners = [sp_layout[sp].get("owner") for sp in sp_layout]
     args["plat_max_count"] = owners.count("Plat")
+
     # If it is owned by the platform owner, it is assigned to the SiP.
     args["sip_max_count"] = len(sp_layout.keys()) - args["plat_max_count"]
     if  args["sip_max_count"] > args["split"] or args["sip_max_count"] > args["split"]: