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"]: