Merge "feat(versal-net): add SDEI support" into integration
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..6a89eeb
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,199 @@
+---
+AccessModifierOffset: -4
+AlignAfterOpenBracket: Align
+AlignArrayOfStructures: None
+AlignConsecutiveMacros: None
+AlignConsecutiveAssignments: None
+AlignConsecutiveBitFields: None
+AlignConsecutiveDeclarations: None
+AlignEscapedNewlines: Left
+AlignOperands:   Align
+AlignTrailingComments: false
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortEnumsOnASingleLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortLambdasOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: MultiLine
+AttributeMacros:
+  - __capability
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterCaseLabel:  false
+  AfterClass:      false
+  AfterControlStatement: Never
+  AfterEnum:       false
+  AfterFunction:   true
+  AfterNamespace:  true
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  AfterExternBlock: false
+  BeforeCatch:     false
+  BeforeElse:      false
+  BeforeLambdaBody: false
+  BeforeWhile:     false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeConceptDeclarations: true
+BreakBeforeBraces: Custom
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: false
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeComma
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: false
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+QualifierAlignment: Leave
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 8
+ContinuationIndentWidth: 8
+Cpp11BracedListStyle: false
+DeriveLineEnding: true
+DerivePointerAlignment: false
+DisableFormat:   false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
+ExperimentalAutoDetectBinPacking: false
+PackConstructorInitializers: BinPack
+BasedOnStyle:    ''
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+AllowAllConstructorInitializersOnNextLine: true
+FixNamespaceComments: false
+ForEachMacros:
+  - fdt_for_each_compatible_node
+  - fdt_for_each_property_offset
+  - fdt_for_each_subnode
+  - for_each_err_record_info
+  - for_each_subscriber
+IfMacros:
+  - KJ_IF_MAYBE
+IncludeBlocks:   Regroup
+IncludeCategories:
+  - Regex:           '^<(assert|complex|ctype|errno|fenv|float|inttypes|iso646|limits|locale|math|setjmp|signal|stdalign|stdarg|stdatomic|stdbool|stdckdint|stddef|stdint|stdio|stdlib|stdnoreturn|string|tgmath|threads|time|uchar|wchar|wctype)\.h>$'
+    Priority:        0
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '^<lib/(compiler-rt|libfdt|mbedtls|zlib)/.+>$'
+    Priority:        1
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '^<(platform(_def)?\.h)|(plat[_/].+)>$'
+    Priority:        2
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '^<.+>$'
+    Priority:        3
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '^".+"$'
+    Priority:        4
+    SortPriority:    0
+    CaseSensitive:   false
+IncludeIsMainRegex: '(Test)?$'
+IncludeIsMainSourceRegex: ''
+IndentAccessModifiers: false
+IndentCaseLabels: false
+IndentCaseBlocks: false
+IndentGotoLabels: false
+IndentPPDirectives: None
+IndentExternBlock: AfterExternBlock
+IndentRequires:  false
+IndentWidth:     8
+IndentWrappedFunctionNames: false
+InsertTrailingCommas: None
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+LambdaBodyIndentation: Signature
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 8
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 10
+PenaltyBreakBeforeFirstCallParameter: 30
+PenaltyBreakComment: 10
+PenaltyBreakFirstLessLess: 0
+PenaltyBreakOpenParenthesis: 0
+PenaltyBreakString: 10
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 100
+PenaltyReturnTypeOnItsOwnLine: 60
+PenaltyIndentedWhitespace: 0
+PointerAlignment: Right
+PPIndentWidth:   -1
+ReferenceAlignment: Pointer
+ReflowComments:  false
+RemoveBracesLLVM: false
+SeparateDefinitionBlocks: Leave
+ShortNamespaceLines: 1
+SortIncludes:    CaseInsensitive
+SortJavaStaticImport: Before
+SortUsingDeclarations: false
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatementsExceptControlMacros
+SpaceBeforeParensOptions:
+  AfterControlStatements: true
+  AfterForeachMacros: false
+  AfterFunctionDefinitionName: false
+  AfterFunctionDeclarationName: false
+  AfterIfMacros:   false
+  AfterOverloadedOperator: false
+  BeforeNonEmptyParentheses: false
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  Never
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: false
+SpacesInCStyleCastParentheses: false
+SpacesInLineCommentPrefix:
+  Minimum:         1
+  Maximum:         -1
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+SpaceBeforeSquareBrackets: false
+BitFieldColonSpacing: Both
+Standard:        c++03
+StatementAttributeLikeMacros:
+  - Q_EMIT
+StatementMacros:
+  - Q_UNUSED
+  - QT_REQUIRE_VERSION
+TabWidth:        8
+UseCRLF:         false
+UseTab:          Always
+WhitespaceSensitiveMacros:
+  - STRINGIZE
+  - PP_STRINGIZE
+  - BOOST_PP_STRINGIZE
+  - NS_SWIFT_NAME
+  - CF_SWIFT_NAME
+...
diff --git a/Makefile b/Makefile
index 6d5a0c3..150aa30 100644
--- a/Makefile
+++ b/Makefile
@@ -652,7 +652,7 @@
 ################################################################################
 include ${MAKE_HELPERS_DIRECTORY}march.mk
 
-TF_CFLAGS   +=	$(march-directive)
+TF_CFLAGS	+=	$(march-directive)
 ASFLAGS		+=	$(march-directive)
 
 # This internal flag is common option which is set to 1 for scenarios
@@ -938,6 +938,34 @@
 	endif
 endif #(CTX_INCLUDE_PAUTH_REGS)
 
+# Check ENABLE_FEAT_PAUTH_LR
+ifneq (${ENABLE_FEAT_PAUTH_LR},0)
+
+# Make sure PAUTH is enabled
+ifeq (${ENABLE_PAUTH},0)
+	$(error Error: PAUTH_LR cannot be used without PAUTH (see BRANCH_PROTECTION))
+endif
+
+# Make sure SCTLR2 is enabled
+ifeq (${ENABLE_FEAT_SCTLR2},0)
+	$(error Error: PAUTH_LR cannot be used without ENABLE_FEAT_SCTLR2)
+endif
+
+# FEAT_PAUTH_LR is only supported in aarch64 state
+ifneq (${ARCH},aarch64)
+	$(error ENABLE_FEAT_PAUTH_LR requires AArch64)
+endif
+
+# Currently, FEAT_PAUTH_LR is only supported by arm/clang compilers
+# TODO implement for GCC when support is added
+ifeq ($($(ARCH)-cc-id),arm-clang)
+	arch-features	:= $(arch-features)+pauth-lr
+else
+	$(error Error: ENABLE_FEAT_PAUTH_LR not supported for GCC compiler)
+endif
+
+endif # ${ENABLE_FEAT_PAUTH_LR}
+
 ifeq ($(FEATURE_DETECTION),1)
         $(info FEATURE_DETECTION is an experimental feature)
 endif #(FEATURE_DETECTION)
@@ -984,7 +1012,7 @@
 	endif
 
 	# FEAT_RNG_TRAP is not supported in AArch32
-	ifeq (${ENABLE_FEAT_RNG_TRAP},1)
+	ifneq (${ENABLE_FEAT_RNG_TRAP},0)
                 $(error "ENABLE_FEAT_RNG_TRAP cannot be used with ARCH=aarch32")
 	endif
 
@@ -1324,6 +1352,7 @@
 	ENABLE_TRBE_FOR_NS \
 	ENABLE_BTI \
 	ENABLE_PAUTH \
+	ENABLE_FEAT_PAUTH_LR \
 	ENABLE_FEAT_AMU \
 	ENABLE_FEAT_AMUv1p1 \
 	ENABLE_FEAT_CSV2_2 \
@@ -1410,6 +1439,7 @@
 	ENABLE_FEAT_DEBUGV8P9 \
 	ENABLE_FEAT_MPAM \
 	ENABLE_PAUTH \
+	ENABLE_FEAT_PAUTH_LR \
 	ENABLE_PIE \
 	ENABLE_PMF \
 	ENABLE_PSCI_STAT \
diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c
index 984fdaa..114a57d 100644
--- a/bl31/bl31_traps.c
+++ b/bl31/bl31_traps.c
@@ -90,19 +90,17 @@
  * Explicitly create all bits of SPSR to get PSTATE at exception return.
  *
  * The code is based on "Aarch64.exceptions.takeexception" described in
- * DDI0602 revision 2023-06.
- * "https://developer.arm.com/documentation/ddi0602/2023-06/Shared-Pseudocode/
+ * DDI0602 revision 2025-03.
+ * "https://developer.arm.com/documentation/ddi0597/2025-03/Shared-Pseudocode/
  * aarch64-exceptions-takeexception"
  *
- * NOTE: This piece of code must be reviewed every release to ensure that
- * we keep up with new ARCH features which introduces a new SPSR bit.
+ * NOTE: This piece of code must be reviewed every release against the latest
+ * takeexception sequence to ensure that we keep up with new arch features that
+ * affect the PSTATE.
  *
- * TF-A 2.12 release review
- * The latest version available is 2024-09, which has two extra features which
- * impacts generation of SPSR, since these features are not implemented in TF-A
- * at the time of release, just log the feature names here to be taken up when
- * feature support is introduced.
- *  - FEAT_PAuth_LR (2023 extension)
+ * TF-A 2.13 release review
+ *
+ * Review of version 2025-03 indicates we are missing support for one feature.
  *  - FEAT_UINJ (2024 extension)
  */
 u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el)
@@ -204,6 +202,12 @@
 		new_spsr |= (gcscr & GCSCR_EXLOCK_EN_BIT) ? SPSR_EXLOCK_BIT_AARCH64 : 0;
 	}
 
+	/* If FEAT_PAUTH_LR present then zero the PACM bit. */
+	new_spsr |= old_spsr & SPSR_PACM_BIT_AARCH64;
+	if (is_feat_pauth_lr_present()) {
+		new_spsr &= ~SPSR_PACM_BIT_AARCH64;
+	}
+
 	return new_spsr;
 }
 
diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S
index b4e7a7a..4ea2f5b 100644
--- a/bl32/tsp/aarch64/tsp_entrypoint.S
+++ b/bl32/tsp/aarch64/tsp_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -51,6 +51,15 @@
 	.endm
 
 func tsp_entrypoint _align=3
+	/*---------------------------------------------
+	 * Save arguments x0 - x3 from BL1 for future
+	 * use.
+	 * ---------------------------------------------
+	 */
+	mov	x20, x0
+	mov	x21, x1
+	mov	x22, x2
+	mov	x23, x3
 
 #if ENABLE_PIE
 		/*
@@ -173,6 +182,16 @@
 	bl	update_stack_protector_canary
 #endif
 
+	/*---------------------------------------------
+	 * Save arguments x0 - x3 from prio stage for
+	 * future use.
+	 * ---------------------------------------------
+	 */
+	mov	x0, x20
+	mov	x1, x21
+	mov	x2, x22
+	mov	x3, x23
+
 	/* ---------------------------------------------
 	 * Perform TSP setup
 	 * ---------------------------------------------
diff --git a/bl32/tsp/tsp_common.c b/bl32/tsp/tsp_common.c
index e69c054..144349a 100644
--- a/bl32/tsp/tsp_common.c
+++ b/bl32/tsp/tsp_common.c
@@ -64,13 +64,14 @@
 /*******************************************************************************
  * Setup function for TSP.
  ******************************************************************************/
-void tsp_setup(void)
+void tsp_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
+	       u_register_t arg3)
 {
 	/* Enable early console if EARLY_CONSOLE flag is enabled */
 	plat_setup_early_console();
 
 	/* Perform early platform-specific setup. */
-	tsp_early_platform_setup();
+	tsp_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	/* Perform late platform-specific setup. */
 	tsp_plat_arch_setup();
diff --git a/changelog.yaml b/changelog.yaml
index 6e7f179..93eeb73 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -205,13 +205,6 @@
             deprecated:
               - plat/tc
 
-            subsections:
-              - title: TC0
-                scope: tc0
-
-                deprecated:
-                  - plat/tc0
-
           - title: Corstone-1000
             scope: corstone-1000
 
@@ -1403,6 +1396,9 @@
     scope: tools
 
     subsections:
+      - title: Clang-Format
+        scope: clang-format
+
       - title: Dependabot
         scope: dependabot
 
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 4d285d3..2d80b42 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -330,7 +330,7 @@
 	 * revisions so that we catch them as they come along
 	 */
 	check_feature(FEAT_STATE_ALWAYS, read_feat_pmuv3_id_field(),
-		      "PMUv3", 1, ID_AA64DFR0_PMUVER_PMUV3P8);
+		      "PMUv3", 1, ID_AA64DFR0_PMUVER_PMUV3P9);
 
 	/* v8.1 features */
 	check_feature(ENABLE_FEAT_PAN, read_feat_pan_id_field(), "PAN", 1, 3);
@@ -429,6 +429,7 @@
 	/* v9.4 features */
 	check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
 	check_feature(ENABLE_RME, read_feat_rme_id_field(), "RME", 1, 1);
+	check_feature(ENABLE_FEAT_PAUTH_LR, is_feat_pauth_lr_present(), "PAUTH_LR", 1, 1);
 
 	if (tainted) {
 		panic();
diff --git a/docs/about/lts.rst b/docs/about/lts.rst
index 5aa32a2..593f9dc 100644
--- a/docs/about/lts.rst
+++ b/docs/about/lts.rst
@@ -283,8 +283,9 @@
    cherry-pick -x sha1-hash``.
 #. Some of the patches of this list may not be taken, mainly due to false
    positive. If in doubt, that can be discussed either in the “tf-a-lts” channel
-   on Discord or during the LTS weekly meeting. There could also be patches to
-   be taken in tf-a-ci-scripts or tf-a-tests.
+   on Discord or during the LTS weekly meeting.
+#. Some dependency patches, not listed in the CSV file, may have to be taken, to ease the
+   application of the LTS patches. This can also be discussed with the other LTS maintainers.
 #. Push the stack of changes: ``git push origin
    HEAD:refs/for/lts-v2.x%topic=for-lts-v2.x.y+1``. You might need the
    ``--no-verify`` option: ``git push origin --no-verify
@@ -298,6 +299,13 @@
    present, Gerrit will automatically merge the patch. LTS maintainers will then
    trigger a Jenkins job that will take care of the release (tag, mail, and
    readthedocs update).
+#. Some features may also require updates in other repositories (tf-a-ci-scripts,
+   tf-a-job-configs or tf-a-tests...). For tf-a-job-configs, there are no LTS branches, but
+   dedicated scripts for each LTS version which have to be updated manually. This is the case
+   for e.g. MbedTLS updates. For tf-a-ci-scripts and tf-a-tests, there are LTS branches and patches
+   will be cherry-picked from master branch to the LTS branch the same way it is done for TF-A.
+   There is no automation for those repositories. So the patches will have to be merged manually,
+   and for tf-a-ci-scripts and tf-a-tests, tags will also have to be set manually.
 
 Execution Plan
 **************
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index a011297..f1ce15a 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -226,10 +226,10 @@
 ^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Michal Simek <michal.simek@amd.com>
 :|G|: `michalsimek`_
-:|M|: Amit Nagal <amit.nagal@amd.com>
-:|G|: `amit-nagal`_
 :|M|: Akshay Belsare <akshay.belsare@amd.com>
 :|G|: `Akshay-Belsare`_
+:|M|: Maheedhar Sai Bollapalli <maheedharsai.bollapalli@amd.com>
+:|G|: `maheedhar-bollapalli`_
 :|F|: drivers/arm/dcc/
 :|F|: include/drivers/arm/dcc.h
 
@@ -912,15 +912,17 @@
 :|F|: docs/plat/socionext-uniphier.rst
 :|F|: plat/socionext/uniphier/
 
-Xilinx platform port
-^^^^^^^^^^^^^^^^^^^^
+AMD-Xilinx platform port
+^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Michal Simek <michal.simek@amd.com>
 :|G|: `michalsimek`_
-:|M|: Amit Nagal <amit.nagal@amd.com>
-:|G|: `amit-nagal`_
 :|M|: Akshay Belsare <akshay.belsare@amd.com>
 :|G|: `Akshay-Belsare`_
+:|M|: Maheedhar Sai Bollapalli <maheedharsai.bollapalli@amd.com>
+:|G|: `maheedhar-bollapalli`_
+:|F|: docs/plat/amd\*
 :|F|: docs/plat/xilinx\*
+:|F|: plat/amd/
 :|F|: plat/xilinx/
 
 
@@ -1035,7 +1037,6 @@
 .. _abdellatif-elkhlifi: https://github.com/abdellatif-elkhlifi
 .. _Akshay-Belsare: https://github.com/Akshay-Belsare
 .. _AlexeiFedorov: https://github.com/AlexeiFedorov
-.. _amit-nagal: https://github.com/amit-nagal
 .. _andersdellien-arm: https://github.com/andersdellien-arm
 .. _Andre-ARM: https://github.com/Andre-ARM
 .. _Anson-Huang: https://github.com/Anson-Huang
@@ -1085,6 +1086,7 @@
 .. _leon-chen-mtk: https://github.com/leon-chen-mtk
 .. _linyidi: https://github.com/linyidi
 .. _madhukar-Arm: https://github.com/madhukar-Arm
+.. _maheedhar-bollapalli: https://github.com/maheedhar-bollapalli
 .. _manish-pandey-arm: https://github.com/manish-pandey-arm
 .. _ManishVB-Arm: https://github.com/ManishVB-Arm
 .. _marcbonnici: https://github.com/marcbonnici
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 1ff2037..6a07271 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -747,7 +747,10 @@
    fid,x0,[63:0],UInt64,Command FID
    ecam_address,x1,[63:0],UInt64,Used to identify the root complex(RC)
    rp_id,x2,[63:0],UInt64,Used to identify the root port within the root complex(RC)
-   Keyset[12]:Dir[11]:Substream[10:8]:StreamID[7:0],x3,[63:0],UInt64,IDE selective stream informationKey set: can be 0 or 1unused bits MBZ.
+   "Keyset[12]:
+   Dir[11]:
+   Substream[10:8]:
+   StreamID[7:0]",x3,[63:0],UInt64,IDE selective stream informationKey set: can be 0 or 1unused bits MBZ.
    KeqQW0,x4,[63:0],UInt64,Quad word of key [63:0]
    KeqQW1,x5,[63:0],UInt64,Quad word of key [127:64]
    KeqQW2,x6,[63:0],UInt64,Quad word of key [191:128]
@@ -763,7 +766,7 @@
 
 .. csv-table:: Output values for RMM_IDE_KEY_PROG
    :header: "Name", "Register", "Field", "Type", "Description"
-   :widths: 1 1 1 2 4
+   :widths: 1 1 1 1 5
 
    Result,x0,[63:0],Error Code,Command return status
 
@@ -777,10 +780,10 @@
    :header: "ID", "Condition"
    :widths: 1 5
 
-   ``E_RMM_OK``,Key programming is successful.
-   ``E_RMM_FAULT``,Key programming is not successful.
-   ``E_RMM_INVAL``,Key programming arguments are incorrect.
-   ``E_RMM_UNK``,Unknown error or the SMC is not present if the version is < 0.6
+   ``E_RMM_OK``,The Key programming is successful.
+   ``E_RMM_FAULT``,The Key programming is not successful.
+   ``E_RMM_INVAL``,The Key programming arguments are incorrect.
+   ``E_RMM_UNK``,Unknown error or the SMC is not present if the version is < 0.6.
    ``E_RMM_AGAIN``,Returned only for non-blocking mode. IDE-KM interface is busy or request is full. Retry required.
    ``E_RMM_INPROGRESS``,Returned only for non-blocking mode. The caller must issue RMM_IDE_KM_PULL_RESPONSE SMC to pull the response.
 
@@ -811,7 +814,10 @@
    fid,x0,[63:0],UInt64,Command FID
    ecam_address,x1,[63:0],UInt64,Used to identify the root complex(RC)
    rp_id,x2,[63:0],UInt64,Used to identify the root port within the root complex(RC)
-   Keyset[12]:Dir[11]:Substream[10:8]:StreamID[7:0],x3,[63:0],UInt64,IDE selective stream information. Key set can be 0 or 1. Unused bits MBZ.
+   "Keyset[12]:
+   Dir[11]:
+   Substream[10:8]:
+   StreamID[7:0]",x3,[63:0],UInt64,IDE selective stream information. Key set can be 0 or 1. Unused bits MBZ.
    request_id,x4,[63:0],UInt64,Used only in non-blocking mode. Ignored in blocking mode.
    cookie,x5,[63:0],UInt64,Used only in non-blocking mode. Ignored in blocking mode.
 
@@ -821,7 +827,7 @@
 
 .. csv-table:: Output values for RMM_IDE_KEY_SET_GO
    :header: "Name", "Register", "Field", "Type", "Description"
-   :widths: 1 1 1 2 4
+   :widths: 1 1 1 1 5
 
    Result,x0,[63:0],Error Code,Command return status
 
@@ -835,9 +841,9 @@
    :header: "ID", "Condition"
    :widths: 1 5
 
-   ``E_RMM_OK``,Key set go is successful.
-   ``E_RMM_FAULT``,Key set go is not successful.
-   ``E_RMM_INVAL``,incorrect arguments.
+   ``E_RMM_OK``,The Key set go is successful.
+   ``E_RMM_FAULT``,The Key set go is not successful.
+   ``E_RMM_INVAL``,Incorrect arguments.
    ``E_RMM_UNK``,Unknown error or the SMC is not present if the version is < 0.6.
    ``E_RMM_AGAIN``,Returned only for non-blocking mode. IDE-KM interface is busy or request is full. Retry required.
    ``E_RMM_INPROGRESS``,Returned only for non-blocking mode. The caller must issue RMM_IDE_KM_PULL_RESPONSE SMC to pull the response.
@@ -869,7 +875,10 @@
    fid,x0,[63:0],UInt64,Command FID
    ecam_address,x1,[63:0],UInt64,Used to identify the root complex(RC)
    rp_id,x2,[63:0],UInt64,Used to identify the root port within the root complex(RC)
-   Keyset[12]:Dir[11]:Substream[10:8]:StreamID[7:0],x3,[63:0],UInt64,IDE selective stream information. Key set can be 0 or 1. Unused bits MBZ.
+   "Keyset[12]:
+   Dir[11]:
+   Substream[10:8]:
+   StreamID[7:0]",x3,[63:0],UInt64,IDE selective stream information. Key set can be 0 or 1. Unused bits MBZ.
    request_id,x4,[63:0],UInt64,Used only in non-blocking mode. Ignored in blocking mode.
    cookie,x5,[63:0],UInt64,Used only in non-blocking mode. Ignored in blocking mode.
 
@@ -879,7 +888,7 @@
 
 .. csv-table:: Output values for RMM_IDE_KEY_SET_STOP
    :header: "Name", "Register", "Field", "Type", "Description"
-   :widths: 1 1 1 2 4
+   :widths: 1 1 1 1 5
 
    Result,x0,[63:0],Error Code,Command return status
 
@@ -893,9 +902,9 @@
    :header: "ID", "Condition"
    :widths: 1 5
 
-   ``E_RMM_OK``,Key set go is successful.
-   ``E_RMM_FAULT``,Key set go is not successful.
-   ``E_RMM_INVAL``,incorrect arguments.
+   ``E_RMM_OK``,The Key set stop is successful.
+   ``E_RMM_FAULT``,The Key set stop is not successful.
+   ``E_RMM_INVAL``,Incorrect arguments.
    ``E_RMM_UNK``,Unknown error or the SMC is not present if the version is < 0.6.
    ``E_RMM_AGAIN``,Returned only for non-blocking mode. IDE-KM interface is busy or request is full. Retry required.
    ``E_RMM_INPROGRESS``,Returned only for non-blocking mode. The caller must issue RMM_IDE_KM_PULL_RESPONSE SMC to pull the response.
@@ -936,7 +945,7 @@
 
 .. csv-table:: Output values for RMM_IDE_KM_PULL_RESPONSE
    :header: "Name", "Register", "Field", "Type", "Description"
-   :widths: 1 1 1 2 4
+   :widths: 1 1 1 1 5
 
    Result,x0,[63:0],Error Code,Command return status
    Result,x1,[63:0],Error Code,Retrieved response corresponding to previous IDE_KM requests.
@@ -949,16 +958,23 @@
 The table below shows all the possible error codes returned in ``Result`` upon
 a failure. The errors are ordered by condition check.
 
-.. csv-table:: Failure conditions for RMM_IDE_KM_PULL_RESPONSE
+.. csv-table:: Failure conditions for RMM_IDE_KM_PULL_RESPONSE(x0)
    :header: "ID", "Condition"
    :widths: 1 5
 
-   ``E_RMM_OK``,Key set go is successful.
-   ``E_RMM_FAULT``,Key set go is not successful.
-   ``E_RMM_INVAL``,incorrect arguments.
+   ``E_RMM_OK``,Response is retrieved successfully.
+   ``E_RMM_INVAL``,Arguments to pull response SMC is not correct.
    ``E_RMM_UNK``,Unknown error or the SMC is not present if the version is < 0.6.
-   ``E_RMM_AGAIN``,KM request is empty and no response if available.
+   ``E_RMM_AGAIN``,IDE-KM response queue is empty and no response is available.
 
+.. csv-table:: Failure conditions for RMM_IDE_KM_PULL_RESPONSE(x1)
+   :header: "ID", "Condition"
+   :widths: 1 5
+
+   ``E_RMM_OK``,The previous request was successful.
+   ``E_RMM_FAULT``,The previous request was not successful.
+   ``E_RMM_INVAL``,Arguments to previous request were incorrect.
+   ``E_RMM_UNK``,Previous request returned unknown error.
 
 RMM-EL3 world switch register save restore convention
 _____________________________________________________
diff --git a/docs/design_documents/measured_boot.rst b/docs/design_documents/measured_boot.rst
index 1f76770..a9d2fa9 100644
--- a/docs/design_documents/measured_boot.rst
+++ b/docs/design_documents/measured_boot.rst
@@ -231,9 +231,9 @@
    - Public key data size is passed as the third argument to this function.
    - This function must return 0 on success, a signed integer error code
      otherwise.
-   - In TC2 platform, this function is used to calculate the hash of the given
-     key and forward this hash to |RSE| alongside the measurement of the image
-     which the key signs.
+   - In Total Compute platform, this function is used to calculate the hash
+     of the given key and forward this hash to |RSE| alongside the measurement
+     of the image which the key signs.
 
 --------------
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index e5f7b30..32daf1e 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -405,6 +405,12 @@
    flag can take values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
+-  ``ENABLE_FEAT_PAUTH_LR``: Numeric value to enable the ``FEAT_PAUTH_LR``
+   extension. ``FEAT_PAUTH_LR`` is an optional feature available from Arm v9.4
+   onwards. This feature requires PAUTH to be enabled via the
+   ``BRANCH_PROTECTION`` flag. This flag can take the values 0 to 2, to align
+   with the ``ENABLE_FEAT`` mechanism. Default value is ``0``.
+
 -  ``ENABLE_FEAT_RNG``: Numeric value to enable the ``FEAT_RNG`` extension.
    ``FEAT_RNG`` is an optional feature available on Arm v8.5 onwards. This
    flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
diff --git a/docs/plat/arm/tc/index.rst b/docs/plat/arm/tc/index.rst
index 467738c..d57b48e 100644
--- a/docs/plat/arm/tc/index.rst
+++ b/docs/plat/arm/tc/index.rst
@@ -17,12 +17,8 @@
 the Total Compute platform number. The platforms support the CPU variants
 listed as below:
 
--  TC0 has support for Cortex A510, Cortex A710 and Cortex X2. (Note TC0 is now deprecated)
--  TC1 has support for Cortex A510, Cortex A715 and Cortex X3. (Note TC1 is now deprecated)
--  TC2 has support for Cortex A520, Cortex A720 and Cortex x4. (Note TC2 is now deprecated)
 -  TC3 has support for Cortex A520, Cortex A725 and Cortex x925.
 
-
 Boot Sequence
 -------------
 
@@ -59,6 +55,6 @@
 
 --------------
 
-*Copyright (c) 2020-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2025, Arm Limited. All rights reserved.*
 
 .. _Arm Toolchain: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index d0d6889..a30f55d 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -72,7 +72,7 @@
 +----------------+----------------+--------------------+--------------------+
 |    Platform    |     Vendor     | Deprecated version |  Deleted version   |
 +================+================+====================+====================+
-|      TC2       |      Arm       |        2.12        |         TBD        |
+|      TC2       |      Arm       |        2.12        |         2.13       |
 |                |                |                    |                    |
 +----------------+----------------+--------------------+--------------------+
 |     fvp_r      |      Arm       |        2.13        |         2.13       |
diff --git a/drivers/measured_boot/event_log/event_handoff.c b/drivers/measured_boot/event_log/event_handoff.c
new file mode 100644
index 0000000..238ea27
--- /dev/null
+++ b/drivers/measured_boot/event_log/event_handoff.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <common/debug.h>
+#include <drivers/measured_boot/event_log/event_handoff.h>
+
+#include <platform_def.h>
+
+static uint8_t *get_log_ptr(struct transfer_list_entry *te, size_t offset)
+{
+	uint8_t *base_ptr = transfer_list_entry_data(te);
+
+	if (base_ptr == NULL) {
+		return NULL;
+	}
+
+	return base_ptr + offset;
+}
+
+uint8_t *transfer_list_event_log_extend(struct transfer_list_header *tl,
+					size_t req_size, size_t *free)
+{
+	struct transfer_list_entry *existing_entry;
+	struct transfer_list_entry *new_entry;
+	uint8_t *old_data;
+	size_t existing_offset;
+	size_t old_size;
+
+	if (tl == NULL || free == NULL || req_size == 0) {
+		ERROR("Invalid arguments to event log extend.\n");
+		return NULL;
+	}
+
+	existing_entry = transfer_list_find(tl, TL_TAG_TPM_EVLOG);
+	existing_offset = EVENT_LOG_RESERVED_BYTES;
+
+	if (existing_entry != NULL) {
+		existing_offset = existing_entry->data_size;
+
+		if (transfer_list_set_data_size(tl, existing_entry,
+						req_size + existing_offset)) {
+			VERBOSE("TPM event log entry resized: new space %zu bytes at offset %zu\n",
+				req_size, existing_offset);
+
+			*free = existing_entry->data_size - existing_offset;
+
+			return get_log_ptr(existing_entry, existing_offset);
+		}
+	}
+
+	/* Add new entry (resize failed or no existing entry) */
+	new_entry = transfer_list_add(tl, TL_TAG_TPM_EVLOG,
+				      req_size + existing_offset, NULL);
+
+	if (new_entry == NULL) {
+		ERROR("Failed to add TPM event log entry to transfer list.\n");
+		return NULL;
+	}
+
+	VERBOSE("New TPM event log entry added at %p\n",
+		transfer_list_entry_data(new_entry));
+
+	if (existing_entry != NULL) {
+		old_data = transfer_list_entry_data(existing_entry);
+		old_size = existing_offset;
+
+		VERBOSE("Copying existing event log (%zu bytes) to new entry at %p\n",
+			old_size, transfer_list_entry_data(new_entry));
+
+		memmove(transfer_list_entry_data(new_entry), old_data,
+			old_size);
+
+		transfer_list_rem(tl, existing_entry);
+	}
+
+	*free = new_entry->data_size - existing_offset;
+
+	return get_log_ptr(new_entry, existing_offset);
+}
+
+uint8_t *transfer_list_event_log_finish(struct transfer_list_header *tl,
+					uintptr_t cursor)
+{
+	uintptr_t entry_data_base;
+	size_t final_log_size;
+	struct transfer_list_entry *entry;
+
+	entry = transfer_list_find(tl, TL_TAG_TPM_EVLOG);
+	entry_data_base = (uintptr_t)transfer_list_entry_data(entry);
+
+	if (cursor < entry_data_base ||
+	    cursor >= entry_data_base + entry->data_size) {
+		ERROR("Invalid cursor: outside event log bounds.\n");
+		return NULL;
+	}
+
+	final_log_size = cursor - entry_data_base;
+
+	if (!transfer_list_set_data_size(tl, entry, final_log_size)) {
+		ERROR("Unable to resize event log TE.\n");
+		return NULL;
+	}
+
+	transfer_list_update_checksum(tl);
+
+	VERBOSE("TPM event log finalized: trimmed to %zu bytes",
+		final_log_size - EVENT_LOG_RESERVED_BYTES);
+
+	/* Ensure changes are visible to the next stage. */
+	flush_dcache_range((uintptr_t)tl, tl->size);
+
+	return get_log_ptr(entry, EVENT_LOG_RESERVED_BYTES);
+}
diff --git a/drivers/measured_boot/event_log/event_log.mk b/drivers/measured_boot/event_log/event_log.mk
index df3460f..09c15da 100644
--- a/drivers/measured_boot/event_log/event_log.mk
+++ b/drivers/measured_boot/event_log/event_log.mk
@@ -47,3 +47,8 @@
 
 EVENT_LOG_SOURCES	:= ${EVENT_LOG_SRC_DIR}event_log.c		\
 			   ${EVENT_LOG_SRC_DIR}event_print.c
+
+
+ifeq (${TRANSFER_LIST}, 1)
+EVENT_LOG_SOURCES	+= ${EVENT_LOG_SRC_DIR}/event_handoff.c
+endif
diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
index 92182a0..ac9d99a 100644
--- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -19,7 +19,7 @@
 #define S32CC_DDR_PLL_VCO_FREQ		(1600U * MHZ)
 #define S32CC_DDR_PLL_PHI0_FREQ		(800U * MHZ)
 #define S32CC_PERIPH_DFS_PHI3_FREQ	(800U * MHZ)
-#define S32CC_USDHC_FREQ		(400U * MHZ)
+#define S32CC_USDHC_FREQ		(200U * MHZ)
 
 static int setup_fxosc(void)
 {
diff --git a/fdts/tc2.dts b/fdts/tc2.dts
deleted file mode 100644
index fa16dcd..0000000
--- a/fdts/tc2.dts
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-/dts-v1/;
-
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <platform_def.h>
-
-#if TARGET_FLAVOUR_FVP
-#define LIT_CAPACITY			406
-#define MID_CAPACITY			912
-#else /* TARGET_FLAVOUR_FPGA */
-#define LIT_CAPACITY			280
-#define MID_CAPACITY			775
-/* this is an area optimized configuration of the big core */
-#define BIG2_CAPACITY			930
-#endif /* TARGET_FLAVOUR_FPGA */
-#define BIG_CAPACITY			1024
-
-#define MHU_TX_ADDR			45000000 /* hex */
-#define MHU_TX_COMPAT			"arm,mhuv2-tx","arm,primecell"
-#define MHU_TX_INT_NAME			"mhu_tx"
-
-#define MHU_RX_ADDR			45010000 /* hex */
-#define MHU_RX_COMPAT			"arm,mhuv2-rx","arm,primecell"
-#define MHU_OFFSET			0x1000
-#define MHU_MBOX_CELLS			2
-#define MHU_RX_INT_NUM			317
-#define MHU_RX_INT_NAME			"mhu_rx"
-
-#define LIT_CPU_PMU_COMPATIBLE		"arm,cortex-a520-pmu"
-#define MID_CPU_PMU_COMPATIBLE		"arm,cortex-a720-pmu"
-#define BIG_CPU_PMU_COMPATIBLE		"arm,cortex-x4-pmu"
-
-#define DSU_MPAM_ADDR			0x1 0x00010000 /* 0x1_0001_0000 */
-
-#define DPU_ADDR			2cc00000
-#define DPU_IRQ				69
-
-#define ETHERNET_ADDR			18000000
-#define ETHERNET_INT			109
-
-#define SYS_REGS_ADDR			1c010000
-
-#define MMC_ADDR			1c050000
-#define MMC_INT_0			107
-#define MMC_INT_1			108
-
-#define RTC_ADDR			1c170000
-#define RTC_INT				100
-
-#define KMI_0_ADDR			1c060000
-#define KMI_0_INT			197
-#define KMI_1_ADDR			1c070000
-#define KMI_1_INT			103
-
-#define VIRTIO_BLOCK_ADDR		1c130000
-#define VIRTIO_BLOCK_INT		204
-
-#include "tc-common.dtsi"
-#if TARGET_FLAVOUR_FVP
-#include "tc-fvp.dtsi"
-#else
-#include "tc-fpga.dtsi"
-#endif /* TARGET_FLAVOUR_FVP */
-#include "tc-base.dtsi"
-
-/ {
-	cpus {
-#if TARGET_FLAVOUR_FPGA
-		cpu-map {
-			cluster0 {
-				core8 {
-					cpu = <&CPU8>;
-				};
-				core9 {
-					cpu = <&CPU9>;
-				};
-				core10 {
-					cpu = <&CPU10>;
-				};
-				core11 {
-					cpu = <&CPU11>;
-				};
-				core12 {
-					cpu = <&CPU12>;
-				};
-				core13 {
-					cpu = <&CPU13>;
-				};
-			};
-		};
-#endif
-
-		CPU2:cpu@200 {
-			clocks = <&scmi_dvfs 0>;
-			capacity-dmips-mhz = <LIT_CAPACITY>;
-		};
-
-		CPU3:cpu@300 {
-			clocks = <&scmi_dvfs 0>;
-			capacity-dmips-mhz = <LIT_CAPACITY>;
-		};
-
-		CPU6:cpu@600 {
-			clocks = <&scmi_dvfs 1>;
-			capacity-dmips-mhz = <MID_CAPACITY>;
-		};
-
-		CPU7:cpu@700 {
-			clocks = <&scmi_dvfs 1>;
-			capacity-dmips-mhz = <MID_CAPACITY>;
-		};
-
-#if TARGET_FLAVOUR_FPGA
-		CPU8:cpu@800 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x800>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 1>;
-			capacity-dmips-mhz = <MID_CAPACITY>;
-		};
-
-		CPU9:cpu@900 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x900>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 2>;
-			capacity-dmips-mhz = <BIG2_CAPACITY>;
-		};
-
-		CPU10:cpu@A00 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0xA00>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 2>;
-			capacity-dmips-mhz = <BIG2_CAPACITY>;
-		};
-
-		CPU11:cpu@B00 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0xB00>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 2>;
-			capacity-dmips-mhz = <BIG2_CAPACITY>;
-		};
-
-		CPU12:cpu@C00 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0xC00>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 3>;
-			capacity-dmips-mhz = <BIG_CAPACITY>;
-		};
-
-		CPU13:cpu@D00 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0xD00>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 3>;
-			capacity-dmips-mhz = <BIG_CAPACITY>;
-		};
-#endif
-	};
-
-#if TARGET_FLAVOUR_FPGA
-	ete8 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU8>;
-	};
-
-	ete9 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU9>;
-	};
-
-	ete10 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU10>;
-	};
-
-	ete11 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU11>;
-	};
-
-	ete12 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU12>;
-	};
-
-	ete13 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU13>;
-	};
-#endif /* TARGET_FLAVOUR_FPGA */
-
-	cmn-pmu {
-		compatible = "arm,ci-700";
-		reg = <0x0 0x50000000 0x0 0x10000000>;
-		interrupts = <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH 0>;
-	};
-
-	mbox_db_rx: mhu@MHU_RX_ADDR {
-		arm,mhuv2-protocols = <0 1>;
-	};
-
-	mbox_db_tx: mhu@MHU_TX_ADDR {
-		arm,mhuv2-protocols = <0 1>;
-	};
-
-	firmware {
-		/*
-		 * TC2 does not have a P2A channel, but wiring one was needed to make Linux work
-		 * (by chance). At the time the SCMI driver did not support bidirectional
-		 * mailboxes so as a workaround, the A2P channel was wired for TX communication
-		 * and the synchronous replies would be read asyncrhonously as if coming from
-		 * the P2A channel, while being the actual A2P channel.
-		 *
-		 * This will not work with kernels > 5.15, but keep it around to keep TC2
-		 * working with its target kernel. Newer kernels will still work, but SCMI
-		 * won't as they check that the two regions are distinct.
-		 */
-		scmi {
-			mboxes = <&mbox_db_tx 0 0 &mbox_db_rx 0 0>;
-			shmem = <&cpu_scp_scmi_a2p &cpu_scp_scmi_a2p>;
-		};
-	};
-
-	gic: interrupt-controller@GIC_CTRL_ADDR {
-		ppi-partitions {
-			ppi_partition_little: interrupt-partition-0 {
-				affinity = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>;
-			};
-
-#if TARGET_FLAVOUR_FVP
-			ppi_partition_mid: interrupt-partition-1 {
-				affinity = <&CPU4>, <&CPU5>, <&CPU6>;
-			};
-
-			ppi_partition_big: interrupt-partition-2 {
-				affinity = <&CPU7>;
-			};
-#elif TARGET_FLAVOUR_FPGA
-			ppi_partition_mid: interrupt-partition-1 {
-				affinity = <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>, <&CPU8>;
-			};
-
-			ppi_partition_big: interrupt-partition-2 {
-				affinity = <&CPU9>, <&CPU10>, <&CPU11>, <&CPU12>, <&CPU13>;
-			};
-#endif
-		};
-	};
-
-	spe-pmu-big {
-		status = "okay";
-	};
-
-	smmu_700: iommu@3f000000 {
-		status = "okay";
-	};
-
-	dp0: display@DPU_ADDR {
-#if TC_SCMI_PD_CTRL_EN
-		power-domains = <&scmi_devpd (PLAT_MAX_CPUS_PER_CLUSTER + 2)>;
-#endif
-		iommus = <&smmu_700 0x100>;
-	};
-
-	gpu: gpu@2d000000 {
-		interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH 0>,
-			     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH 0>,
-			     <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH 0>;
-		interrupt-names = "JOB", "MMU", "GPU";
-		iommus = <&smmu_700 0x200>;
-	};
-};
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 3707520..77660b7 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -251,7 +251,7 @@
 #define ID_AA64DFR0_PMUVER_SHIFT	U(8)
 #define ID_AA64DFR0_PMUVER_MASK		U(0xf)
 #define ID_AA64DFR0_PMUVER_PMUV3	U(1)
-#define ID_AA64DFR0_PMUVER_PMUV3P8	U(8)
+#define ID_AA64DFR0_PMUVER_PMUV3P9	U(9)
 #define ID_AA64DFR0_PMUVER_IMP_DEF	U(0xf)
 
 /* ID_AA64DFR0_EL1.SEBEP definitions */
@@ -606,6 +606,11 @@
 #define SCTLR_EPAN_BIT		(ULL(1) << 57)
 #define SCTLR_RESET_VAL		SCTLR_EL3_RES1
 
+#define SCTLR2_EnPACM_BIT	(ULL(1) << 7)
+
+/* SCTLR2 currently has no RES1 fields so reset to 0 */
+#define SCTLR2_RESET_VAL	ULL(0)
+
 /* CPACR_EL1 definitions */
 #define CPACR_EL1_FPEN(x)	((x) << 20)
 #define CPACR_EL1_FP_TRAP_EL0	UL(0x1)
@@ -696,6 +701,7 @@
 #define MDCR_NSPBE_BIT		(ULL(1) << 11)
 #define MDCR_TDOSA_BIT		(ULL(1) << 10)
 #define MDCR_TDA_BIT		(ULL(1) << 9)
+#define MDCR_EnPM2_BIT		(ULL(1) << 7)
 #define MDCR_TPM_BIT		(ULL(1) << 6)
 #define MDCR_RLTE_BIT		(ULL(1) << 0)
 #define MDCR_EL3_RESET_VAL	MDCR_MTPME_BIT
@@ -855,6 +861,7 @@
 #define SPSR_PPEND_BIT		BIT(33)
 #define SPSR_EXLOCK_BIT_AARCH64	BIT_64(34)
 #define SPSR_NZCV		(SPSR_V_BIT | SPSR_C_BIT | SPSR_Z_BIT | SPSR_N_BIT)
+#define SPSR_PACM_BIT_AARCH64	BIT_64(35)
 
 #define DISABLE_ALL_EXCEPTIONS \
 		(DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
@@ -1531,6 +1538,7 @@
 /*******************************************************************************
  * FEAT_SCTLR2 - Extension to SCTLR_ELx Registers
  ******************************************************************************/
+#define SCTLR2_EL3		S3_6_C1_C0_3
 #define SCTLR2_EL2		S3_4_C1_C0_3
 #define SCTLR2_EL1		S3_0_C1_C0_3
 
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index e3068d1..757ce06 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -146,6 +146,8 @@
  * +----------------------------+
  * |	FEAT_MOPS		|
  * +----------------------------+
+ * |	FEAT_PAUTH_LR		|
+ * +----------------------------+
  */
 
 __attribute__((always_inline))
@@ -196,6 +198,35 @@
 CREATE_FEATURE_SUPPORTED(feat_pauth, is_feat_pauth_present, ENABLE_PAUTH)
 CREATE_FEATURE_SUPPORTED(ctx_pauth, is_feat_pauth_present, CTX_INCLUDE_PAUTH_REGS)
 
+/*
+ * FEAT_PAUTH_LR
+ * This feature has a non-standard discovery method so define this function
+ * manually then call use the CREATE_FEATURE_SUPPORTED macro with it. This
+ * feature is enabled with ENABLE_PAUTH when present.
+ */
+__attribute__((always_inline))
+static inline bool is_feat_pauth_lr_present(void)
+{
+	/*
+	 * FEAT_PAUTH_LR support is indicated by up to 3 fields, if one or more
+	 * of these is 0b0110 then the feature is present.
+	 *   1) id_aa64isr1_el1.api
+	 *   2) id_aa64isr1_el1.apa
+	 *   3) id_aa64isr2_el1.apa3
+	 */
+	if (ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_API_SHIFT, ID_AA64ISAR1_API_MASK) == 0b0110) {
+		return true;
+	}
+	if (ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_APA_SHIFT, ID_AA64ISAR1_APA_MASK) == 0b0110) {
+		return true;
+	}
+	if (ISOLATE_FIELD(read_id_aa64isar2_el1(), ID_AA64ISAR2_APA3_SHIFT, ID_AA64ISAR2_APA3_MASK) == 0b0110) {
+		return true;
+	}
+	return false;
+}
+CREATE_FEATURE_SUPPORTED(feat_pauth_lr, is_feat_pauth_lr_present, ENABLE_FEAT_PAUTH_LR)
+
 /* FEAT_TTST: Small translation tables */
 CREATE_FEATURE_PRESENT(feat_ttst, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_ST_SHIFT,
 			ID_AA64MMFR2_EL1_ST_MASK, 1U)
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 9419583..c885424 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -240,12 +240,11 @@
  ******************************************************************************/
 static inline u_register_t xpaci(u_register_t arg)
 {
-	register u_register_t x0 asm("x0") = arg;
+	__asm__ (".arch armv8.3-a\n"
+		 "xpaci %0\n"
+		 : "+r" (arg));
 
-	/* `xpaci x0` for compatibility with older compiler and/or older -march */
-	__asm__ (".arch armv8.3-a; xpaci %0\n" : "+r" (x0));
-
-	return x0;
+	return arg;
 }
 
 void flush_dcache_range(uintptr_t addr, size_t size);
@@ -733,6 +732,7 @@
 /* FEAT_SCTLR2 Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el1, SCTLR2_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el2, SCTLR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el3, SCTLR2_EL3)
 
 /* FEAT_LS64_ACCDATA Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(accdata_el1, ACCDATA_EL1)
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index da51bf8..8f1651d 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -230,7 +230,7 @@
 	 */
 	.macro	read reg:req
 #if ENABLE_BTI
-	bti	j
+	BTI	j
 #endif
 	mrs	x0, \reg
 	ret
@@ -241,7 +241,7 @@
 	 */
 	.macro	write reg:req
 #if ENABLE_BTI
-	bti	j
+	BTI	j
 #endif
 	msr	\reg, x1
 	ret
@@ -351,6 +351,11 @@
 	tst	\reg, \clobber
 	.endm
 
+	.macro is_feat_sctlr2_present_asm reg:req
+	mrs	\reg, ID_AA64MMFR3_EL1
+	ands	\reg, \reg, #(ID_AA64MMFR3_EL1_SCTLR2_MASK << ID_AA64MMFR3_EL1_SCTLR2_SHIFT)
+	.endm
+
 .macro call_reset_handler
 #if !(defined(IMAGE_BL2) && ENABLE_RME)
 	/* ---------------------------------------------------------------------
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 07dffb1..fce0f2c 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -45,6 +45,16 @@
 	msr	sctlr_el3, x0
 	isb
 
+#if ENABLE_FEAT_SCTLR2
+#if ENABLE_FEAT_SCTLR2 > 1
+	is_feat_sctlr2_present_asm x1
+	beq	feat_sctlr2_not_supported\@
+#endif
+	mov	x1, #SCTLR2_RESET_VAL
+	msr	SCTLR2_EL3, x1
+feat_sctlr2_not_supported\@:
+#endif
+
 #ifdef IMAGE_BL31
 	/* ---------------------------------------------------------------------
 	 * Initialise the per-cpu cache pointer to the CPU.
diff --git a/include/bl32/tsp/platform_tsp.h b/include/bl32/tsp/platform_tsp.h
index fe8a2c9..81a1a40 100644
--- a/include/bl32/tsp/platform_tsp.h
+++ b/include/bl32/tsp/platform_tsp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +10,8 @@
 /*******************************************************************************
  * Mandatory TSP functions (only if platform contains a TSP)
  ******************************************************************************/
-void tsp_early_platform_setup(void);
+void tsp_early_platform_setup(u_register_t arg0, u_register_t arg1,
+			      u_register_t arg2, u_register_t arg3);
 void tsp_plat_arch_setup(void);
 void tsp_platform_setup(void);
 
diff --git a/include/bl32/tsp/tsp.h b/include/bl32/tsp/tsp.h
index a63abf1..bc152e5 100644
--- a/include/bl32/tsp/tsp.h
+++ b/include/bl32/tsp/tsp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -106,7 +106,8 @@
 	tsp_vector_isn_t abort_yield_smc_entry;
 } tsp_vectors_t;
 
-void tsp_setup(void);
+void tsp_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
+	       u_register_t arg3);
 
 #endif /* __ASSEMBLER__ */
 
diff --git a/include/common/asm_macros_common.S b/include/common/asm_macros_common.S
index fd0ea81..9172b55 100644
--- a/include/common/asm_macros_common.S
+++ b/include/common/asm_macros_common.S
@@ -7,6 +7,20 @@
 #define ASM_MACROS_COMMON_S
 
 	/*
+	 * Provide a wrapper for the "bti" instructions using the more
+	 * compatible "hint" encoding, otherwise older toolchains would reject
+	 * this when not compiled for a BTI capable machine (-march=armv8.5-a).
+	 */
+	.macro	BTI _targets
+	.ifc	\_targets, j
+	hint	#36
+	.endif
+	.ifc	\_targets, jc
+	hint	#38
+	.endif
+	.endm
+
+	/*
 	 * This macro is used to create a function label and place the
 	 * code into a separate text section based on the function name
 	 * to enable elimination of unused code during linking. It also adds
@@ -42,7 +56,7 @@
 	/* When Branch Target Identification is enabled, insert "bti jc"
 	 * instruction to enable indirect calls and branches
 	 */
-	 bti	jc
+	BTI	jc
 #endif
 	.endm
 
diff --git a/include/drivers/measured_boot/event_log/event_handoff.h b/include/drivers/measured_boot/event_log/event_handoff.h
new file mode 100644
index 0000000..e969d1f
--- /dev/null
+++ b/include/drivers/measured_boot/event_log/event_handoff.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef HANDOFF_H
+#define HANDOFF_H
+
+#include <stdint.h>
+
+#include <lib/transfer_list.h>
+
+/**
+ * Initializes or extends the TPM event log in the transfer list.
+ *
+ * If an event log entry exists, attempts to resize it. Otherwise, adds a new entry.
+ * Copies old data if needed. Updates free to reflect available space.
+ *
+ * @param tl         Pointer to the transfer list header.
+ * @param req_size   Requested size (bytes)
+ * @param free       Available size (bytes)
+ * @return           Pointer to writable space in the log, or NULL on failure.
+ */
+uint8_t *transfer_list_event_log_extend(struct transfer_list_header *tl,
+					size_t req_size, size_t *free);
+
+/**
+ * Finalizes the event log after writing is complete.
+ *
+ * Resizes the event log to match actual data written, updates checksum,
+ * and flushes cache for the next stage.
+ *
+ * @param tl         Pointer to the transfer list header.
+ * @param cursor     End offset of written log data.
+ * @return           Pointer to finalized log data (past reserved bytes), or NULL.
+ */
+uint8_t *transfer_list_event_log_finish(struct transfer_list_header *tl,
+					uintptr_t cursor);
+
+#define EVENT_LOG_RESERVED_BYTES U(4)
+
+#endif /* HANDOFF_H */
diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h
index 50e4721..b5adfdc 100644
--- a/include/drivers/measured_boot/event_log/event_log.h
+++ b/include/drivers/measured_boot/event_log/event_log.h
@@ -11,6 +11,7 @@
 #include <stdint.h>
 
 #include <drivers/auth/crypto_mod.h>
+#include "event_handoff.h"
 #include "tcg.h"
 
 /*
diff --git a/include/drivers/mmc.h b/include/drivers/mmc.h
index e94693d..454a85a 100644
--- a/include/drivers/mmc.h
+++ b/include/drivers/mmc.h
@@ -19,29 +19,29 @@
 
 #define MMC_ACMD(_x)			U(_x)
 
-#define OCR_POWERUP			BIT(31)
-#define OCR_HCS				BIT(30)
-#define OCR_BYTE_MODE			(U(0) << 29)
-#define OCR_SECTOR_MODE			(U(2) << 29)
-#define OCR_ACCESS_MODE_MASK		(U(3) << 29)
-#define OCR_3_5_3_6			BIT(23)
-#define OCR_3_4_3_5			BIT(22)
-#define OCR_3_3_3_4			BIT(21)
-#define OCR_3_2_3_3			BIT(20)
-#define OCR_3_1_3_2			BIT(19)
-#define OCR_3_0_3_1			BIT(18)
-#define OCR_2_9_3_0			BIT(17)
-#define OCR_2_8_2_9			BIT(16)
-#define OCR_2_7_2_8			BIT(15)
-#define OCR_VDD_MIN_2V7			GENMASK(23, 15)
-#define OCR_VDD_MIN_2V0			GENMASK(14, 8)
-#define OCR_VDD_MIN_1V7			BIT(7)
+#define OCR_POWERUP			BIT_32(31U)
+#define OCR_HCS				BIT_32(30U)
+#define OCR_BYTE_MODE			(U(0) << 29U)
+#define OCR_SECTOR_MODE			(U(2) << 29U)
+#define OCR_ACCESS_MODE_MASK		(U(3) << 29U)
+#define OCR_3_5_3_6			BIT_32(23U)
+#define OCR_3_4_3_5			BIT_32(22U)
+#define OCR_3_3_3_4			BIT_32(21U)
+#define OCR_3_2_3_3			BIT_32(20U)
+#define OCR_3_1_3_2			BIT_32(19U)
+#define OCR_3_0_3_1			BIT_32(18U)
+#define OCR_2_9_3_0			BIT_32(17U)
+#define OCR_2_8_2_9			BIT_32(16U)
+#define OCR_2_7_2_8			BIT_32(15U)
+#define OCR_VDD_MIN_2V7			GENMASK_32(23U, 15U)
+#define OCR_VDD_MIN_2V0			GENMASK_32(14U, 8U)
+#define OCR_VDD_MIN_1V7			BIT_32(7U)
 
-#define MMC_RSP_48			BIT(0)
-#define MMC_RSP_136			BIT(1)		/* 136 bit response */
-#define MMC_RSP_CRC			BIT(2)		/* expect valid crc */
-#define MMC_RSP_CMD_IDX			BIT(3)		/* response contains cmd idx */
-#define MMC_RSP_BUSY			BIT(4)		/* device may be busy */
+#define MMC_RSP_48			BIT_32(0U)
+#define MMC_RSP_136			BIT_32(1U)		/* 136 bit response */
+#define MMC_RSP_CRC			BIT_32(2U)		/* expect valid crc */
+#define MMC_RSP_CMD_IDX			BIT_32(3U)		/* response contains cmd idx */
+#define MMC_RSP_BUSY			BIT_32(4U)		/* device may be busy */
 
 /* JEDEC 4.51 chapter 6.12 */
 #define MMC_RESPONSE_R1			(MMC_RSP_48 | MMC_RSP_CMD_IDX | MMC_RSP_CRC)
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index c43beb6..402e07f 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -50,22 +50,6 @@
 	 *	Numeric value expected to read from CPU's MIDR
 	 * _resetfunc:
 	 *	Reset function for the CPU.
-	 * _extra1:
-	 *	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-2017-5715 needs to be applied or not.
-	 * _extra2:
-	 *	This is a placeholder for future per CPU operations. Currently
-	 *	some CPUs use this entry to set a function to disable the
-	 *	workaround for CVE-2018-3639.
-	 * _extra3:
-	 *	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:
@@ -78,7 +62,6 @@
 	 *	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, _extra4:req, \
 		_e_handler:req, _power_down_ops:vararg
 	.section .cpu_ops, "a"
 	.align 3
@@ -87,10 +70,6 @@
 #if defined(IMAGE_AT_EL3)
 	.quad \_resetfunc
 #endif
-	.quad \_extra1
-	.quad \_extra2
-	.quad \_extra3
-	.quad \_extra4
 	.quad \_e_handler
 #ifdef IMAGE_BL31
 	/* Insert list of functions */
@@ -153,28 +132,13 @@
 
 	.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, 0, \
-			\_power_down_ops
+		declare_cpu_ops_base \_name, \_midr, \_resetfunc, 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, 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, \_extra4, 0, \_power_down_ops
+			\_e_handler, \_power_down_ops
 	.endm
 
 	/*
@@ -240,7 +204,7 @@
  *	Default value is 0.
  */
 .macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _split_wa=0
-#if REPORT_ERRATA || ERRATA_ABI_SUPPORT
+#if INCLUDE_ERRATA_LIST
 	.pushsection .rodata.errata_entries
 		.align	3
 		.ifndef \_cpu\()_errata_list_start
@@ -550,7 +514,7 @@
 	.align \_align
 	\_name:
 #if ENABLE_BTI
-	bti	jc
+	BTI	jc
 #endif
 .endm
 
diff --git a/include/lib/cpus/cpu_ops.h b/include/lib/cpus/cpu_ops.h
index 0b08919..5ba78cf 100644
--- a/include/lib/cpus/cpu_ops.h
+++ b/include/lib/cpus/cpu_ops.h
@@ -22,14 +22,6 @@
 /* The number of CPU operations allowed */
 #define CPU_MAX_PWR_DWN_OPS		2
 
-#if __aarch64__
-#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__ */
-
-
 /*
  * Define the sizes of the fields in the cpu_ops structure. Word size is set per
  * Aarch so keep these definitions the same and each can include whatever it
@@ -41,10 +33,6 @@
 #else
 #define CPU_RESET_FUNC_SIZE	0
 #endif /* IMAGE_AT_EL3 */
-#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)
@@ -86,11 +74,7 @@
 #define CPU_MIDR		0
 #define CPU_RESET_FUNC		CPU_MIDR + CPU_MIDR_SIZE
 #if __aarch64__
-#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_EXTRA4_FUNC		CPU_EXTRA3_FUNC + CPU_EXTRA3_FUNC_SIZE
-#define CPU_E_HANDLER_FUNC	CPU_EXTRA4_FUNC + CPU_EXTRA4_FUNC_SIZE
+#define CPU_E_HANDLER_FUNC	CPU_RESET_FUNC + CPU_RESET_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
@@ -117,10 +101,6 @@
 	void (*reset_func)(void);
 #endif /* IMAGE_AT_EL3 */
 #if __aarch64__
-	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 1f5f5ea..235e2b9 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.h
@@ -27,6 +27,18 @@
 #define ERRATA_APPLIES		1
 #define ERRATA_MISSING		2
 
+/* Errata ID for smc workarounds */
+#define ARCH_WORKAROUND_2		2
+#define ARCH_WORKAROUND_3		3
+
+#define INCLUDE_ERRATA_LIST	(		\
+	REPORT_ERRATA			|	\
+	ERRATA_ABI_SUPPORT		|	\
+	WORKAROUND_CVE_2017_5715	|	\
+	WORKAROUND_CVE_2018_3639	|	\
+	WORKAROUND_CVE_2022_23960	|	\
+	WORKAROUND_CVE_2024_7881)
+
 #ifndef __ASSEMBLER__
 #include <lib/cassert.h>
 
@@ -70,6 +82,8 @@
 bool check_if_trbe_disable_affected_core(void);
 int check_wa_cve_2024_7881(void);
 bool errata_ich_vmcr_el2_applies(void);
+struct erratum_entry *find_erratum_entry(uint32_t errata_id);
+int check_erratum_applies(uint32_t cve, int errata_id);
 
 #else
 
@@ -82,8 +96,6 @@
  * unlikely event that this does happen, prepending the CVE id with a 0 should
  * resolve the conflict
  */
-#define ERRATUM(id)		0, id
-#define CVE(year, id)		year, id
 #define NO_ISB			1
 #define NO_ASSERT		0
 #define NO_APPLY_AT_RESET	0
@@ -96,6 +108,9 @@
 
 #endif /* __ASSEMBLER__ */
 
+#define ERRATUM(id)		0, id
+#define CVE(year, id)		year, id
+
 /* Macro to get CPU revision code for checking errata version compatibility. */
 #define CPU_REV(r, p)		((r << 4) | p)
 
diff --git a/include/lib/cpus/wa_cve_2017_5715.h b/include/lib/cpus/wa_cve_2017_5715.h
deleted file mode 100644
index 2ad56e1..0000000
--- a/include/lib/cpus/wa_cve_2017_5715.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef WA_CVE_2017_5715_H
-#define WA_CVE_2017_5715_H
-
-int check_wa_cve_2017_5715(void);
-
-#endif /* WA_CVE_2017_5715_H */
diff --git a/include/lib/cpus/wa_cve_2018_3639.h b/include/lib/cpus/wa_cve_2018_3639.h
deleted file mode 100644
index 5a7c9bf..0000000
--- a/include/lib/cpus/wa_cve_2018_3639.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef WA_CVE_2018_3639_H
-#define WA_CVE_2018_3639_H
-
-void *wa_cve_2018_3639_get_disable_ptr(void);
-
-#endif /* WA_CVE_2018_3639_H */
diff --git a/include/lib/cpus/wa_cve_2022_23960.h b/include/lib/cpus/wa_cve_2022_23960.h
deleted file mode 100644
index 50c0f76..0000000
--- a/include/lib/cpus/wa_cve_2022_23960.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef WA_CVE_2022_23960_H
-#define WA_CVE_2022_23960_H
-
-int check_smccc_arch_wa3_applies(void);
-
-#endif /* WA_CVE_2022_23960_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 4a856a7..aed85f5 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -300,7 +300,8 @@
 void arm_transfer_list_get_heap_info(void **heap_addr, size_t *heap_size);
 
 /* TSP utility functions */
-void arm_tsp_early_platform_setup(void);
+void arm_tsp_early_platform_setup(u_register_t arg0, u_register_t arg1,
+				  u_register_t arg2, u_register_t arg3);
 
 /* SP_MIN utility functions */
 void arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h
index 699a8d7..10ac2f1 100644
--- a/include/services/arm_arch_svc.h
+++ b/include/services/arm_arch_svc.h
@@ -95,6 +95,12 @@
 #define SCR_FEAT_AMUv1p1 (0)
 #endif
 
+#if ENABLE_FEAT_TWED
+#define SCR_FEAT_TWED SCR_TWEDEn_BIT
+#else
+#define SCR_FEAT_TWED (0)
+#endif
+
 #if ENABLE_FEAT_ECV
 #define SCR_FEAT_ECV SCR_ECVEN_BIT
 #else
@@ -119,7 +125,7 @@
 #define SCR_FEAT_CSV2_2 (0)
 #endif
 
-#if ENABLE_FEAT_RAS
+#if !RAS_TRAP_NS_ERR_REC_ACCESS
 #define SCR_FEAT_RAS SCR_TERR_BIT
 #else
 #define SCR_FEAT_RAS (0)
@@ -182,6 +188,7 @@
 	SCR_FEAT_HCX		|						\
 	SCR_FEAT_LS64_ACCDATA	|						\
 	SCR_FEAT_AMUv1p1	|						\
+	SCR_FEAT_TWED		|						\
 	SCR_FEAT_ECV		|						\
 	SCR_FEAT_FGT		|						\
 	SCR_FEAT_MTE2		|						\
@@ -289,6 +296,7 @@
 	MDCR_FEAT_SPE		|						\
 	MDCR_TDOSA_BIT		|						\
 	MDCR_TDA_BIT		|						\
+	MDCR_EnPM2_BIT		|						\
 	MDCR_TPM_BIT		| /* FEAT_PMUv3 */				\
 	MDCR_PLAT_FEATS)
 #define MDCR_EL3_FLIPPED (							\
diff --git a/lib/aarch64/cache_helpers.S b/lib/aarch64/cache_helpers.S
index ff9a4e6..cc46c53 100644
--- a/lib/aarch64/cache_helpers.S
+++ b/lib/aarch64/cache_helpers.S
@@ -215,7 +215,7 @@
 
 	.macro	dcsw_loop _op
 #if ENABLE_BTI
-	bti	j
+	BTI	j
 #endif
 loop2_\_op:
 	lsl	w7, w6, w2		// w7 = aligned max set number
diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S
index adacc5c..553f6f9 100644
--- a/lib/cpus/aarch64/cortex_a57.S
+++ b/lib/cpus/aarch64/cortex_a57.S
@@ -65,15 +65,20 @@
 	ret
 endfunc cortex_a57_disable_ext_debug
 
+/* Erratum entry and check function for SMCCC_ARCH_WORKAROUND_3 */
+add_erratum_entry cortex_a57, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960
+
+check_erratum_chosen cortex_a57, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960
+
 /*
  * Disable the over-read from the LDNP/STNP instruction. The SDEN doesn't
- * provide and erratum number, so assign it an obvious 1
+ * provide and erratum number, so assign it an obvious 99999
  */
-workaround_reset_start cortex_a57, ERRATUM(1), A57_DISABLE_NON_TEMPORAL_HINT
+workaround_reset_start cortex_a57, ERRATUM(99999), A57_DISABLE_NON_TEMPORAL_HINT
 	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_DIS_OVERREAD
-workaround_reset_end cortex_a57, ERRATUM(1)
+workaround_reset_end cortex_a57, ERRATUM(99999)
 
-check_erratum_ls cortex_a57, ERRATUM(1), CPU_REV(1, 2)
+check_erratum_ls cortex_a57, ERRATUM(99999), CPU_REV(1, 2)
 
 workaround_reset_start cortex_a57, ERRATUM(806969), ERRATA_A57_806969
 	sysreg_bit_set CORTEX_A57_CPUACTLR_EL1, CORTEX_A57_CPUACTLR_EL1_NO_ALLOC_WBWA
@@ -187,11 +192,6 @@
 	sysreg_bit_set CORTEX_A57_ECTLR_EL1, CORTEX_A57_ECTLR_SMP_BIT
 cpu_reset_func_end cortex_a57
 
-func check_smccc_arch_workaround_3
-	mov	x0, #ERRATA_APPLIES
-	ret
-endfunc check_smccc_arch_workaround_3
-
 	/* ----------------------------------------------------
 	 * The CPU Ops core power down function for Cortex-A57.
 	 * ----------------------------------------------------
@@ -307,10 +307,7 @@
 	ret
 endfunc cortex_a57_cpu_reg_dump
 
-declare_cpu_ops_wa cortex_a57, CORTEX_A57_MIDR, \
+declare_cpu_ops cortex_a57, CORTEX_A57_MIDR, \
 	cortex_a57_reset_func, \
-	check_erratum_cortex_a57_5715, \
-	CPU_NO_EXTRA2_FUNC, \
-	check_smccc_arch_workaround_3, \
 	cortex_a57_core_pwr_dwn, \
 	cortex_a57_cluster_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a72.S b/lib/cpus/aarch64/cortex_a72.S
index fee28ee..23b27ab 100644
--- a/lib/cpus/aarch64/cortex_a72.S
+++ b/lib/cpus/aarch64/cortex_a72.S
@@ -76,14 +76,17 @@
 	ret
 endfunc cortex_a72_disable_ext_debug
 
-func check_smccc_arch_workaround_3
+check_erratum_custom_start cortex_a72, ERRATUM(ARCH_WORKAROUND_3)
 	cpu_check_csv2	x0, 1f
 	mov	x0, #ERRATA_APPLIES
 	ret
 1:
 	mov	x0, #ERRATA_NOT_APPLIES
 	ret
-endfunc check_smccc_arch_workaround_3
+check_erratum_custom_end cortex_a72, ERRATUM(ARCH_WORKAROUND_3)
+
+/* Erratum entry and check function for SMCCC_ARCH_WORKAROUND_3 */
+add_erratum_entry cortex_a72, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960
 
 workaround_reset_start cortex_a72, ERRATUM(859971), ERRATA_A72_859971
 	sysreg_bit_set CORTEX_A72_CPUACTLR_EL1, CORTEX_A72_CPUACTLR_EL1_DIS_INSTR_PREFETCH
@@ -294,10 +297,7 @@
 	ret
 endfunc cortex_a72_cpu_reg_dump
 
-declare_cpu_ops_wa cortex_a72, CORTEX_A72_MIDR, \
+declare_cpu_ops cortex_a72, CORTEX_A72_MIDR, \
 	cortex_a72_reset_func, \
-	check_erratum_cortex_a72_5715, \
-	CPU_NO_EXTRA2_FUNC, \
-	check_smccc_arch_workaround_3, \
 	cortex_a72_core_pwr_dwn, \
 	cortex_a72_cluster_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a73.S b/lib/cpus/aarch64/cortex_a73.S
index d1fc6d4..9cc6fdb 100644
--- a/lib/cpus/aarch64/cortex_a73.S
+++ b/lib/cpus/aarch64/cortex_a73.S
@@ -33,10 +33,10 @@
 	ret
 endfunc cortex_a73_disable_smp
 
-func check_smccc_arch_workaround_3
-	mov	x0, #ERRATA_APPLIES
-	ret
-endfunc check_smccc_arch_workaround_3
+/* Erratum entry and check function for SMCCC_ARCH_WORKAROUND_3 */
+add_erratum_entry cortex_a73, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960
+
+check_erratum_chosen cortex_a73, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960
 
 workaround_reset_start cortex_a73, ERRATUM(852427), ERRATA_A73_852427
 	sysreg_bit_set CORTEX_A73_DIAGNOSTIC_REGISTER, BIT(12)
@@ -200,10 +200,7 @@
 	ret
 endfunc cortex_a73_cpu_reg_dump
 
-declare_cpu_ops_wa cortex_a73, CORTEX_A73_MIDR, \
+declare_cpu_ops cortex_a73, CORTEX_A73_MIDR, \
 	cortex_a73_reset_func, \
-	check_erratum_cortex_a73_5715, \
-	CPU_NO_EXTRA2_FUNC, \
-	check_smccc_arch_workaround_3, \
 	cortex_a73_core_pwr_dwn, \
 	cortex_a73_cluster_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index 13599ca..ef9c067 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -20,6 +20,11 @@
 
 cpu_reset_prologue cortex_a75
 
+/* Erratum entry and check function for SMCCC_ARCH_WORKAROUND_3 */
+add_erratum_entry cortex_a75, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960
+
+check_erratum_chosen cortex_a75, ERRATUM(ARCH_WORKAROUND_3), WORKAROUND_CVE_2022_23960
+
 workaround_reset_start cortex_a75, ERRATUM(764081), ERRATA_A75_764081
 	sysreg_bit_set sctlr_el3, SCTLR_IESB_BIT
 workaround_reset_end cortex_a75, ERRATUM(764081)
@@ -131,11 +136,6 @@
 #endif
 cpu_reset_func_end cortex_a75
 
-func check_smccc_arch_workaround_3
-	mov	x0, #ERRATA_APPLIES
-	ret
-endfunc check_smccc_arch_workaround_3
-
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
@@ -170,9 +170,6 @@
 	ret
 endfunc cortex_a75_cpu_reg_dump
 
-declare_cpu_ops_wa cortex_a75, CORTEX_A75_MIDR, \
+declare_cpu_ops cortex_a75, CORTEX_A75_MIDR, \
 	cortex_a75_reset_func, \
-	check_erratum_cortex_a75_5715, \
-	CPU_NO_EXTRA2_FUNC, \
-	check_smccc_arch_workaround_3, \
 	cortex_a75_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index b8d5b4f..ca5ccf7 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -301,6 +301,11 @@
 endfunc apply_cve_2018_3639_sync_wa
 #endif /* DYNAMIC_WORKAROUND_CVE_2018_3639 */
 
+/* Erratum entry and check function for SMCCC_ARCH_WORKAROUND_2*/
+add_erratum_entry cortex_a76, ERRATUM(ARCH_WORKAROUND_2), WORKAROUND_CVE_2018_3639
+
+check_erratum_chosen cortex_a76, ERRATUM(ARCH_WORKAROUND_2), WORKAROUND_CVE_2018_3639
+
 workaround_reset_start cortex_a76, ERRATUM(798953), ERRATA_DSU_798953
 	errata_dsu_798953_wa_impl
 workaround_reset_end cortex_a76, ERRATUM(798953)
@@ -535,9 +540,6 @@
 	ret
 endfunc cortex_a76_cpu_reg_dump
 
-declare_cpu_ops_wa cortex_a76, CORTEX_A76_MIDR, \
+declare_cpu_ops cortex_a76, CORTEX_A76_MIDR, \
 	cortex_a76_reset_func, \
-	CPU_NO_EXTRA1_FUNC, \
-	cortex_a76_disable_wa_cve_2018_3639, \
-	CPU_NO_EXTRA3_FUNC, \
 	cortex_a76_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index c4872fe..158ee0e 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -167,10 +167,6 @@
 	ret
 endfunc cortex_x3_cpu_reg_dump
 
-declare_cpu_ops_wa_4 cortex_x3, CORTEX_X3_MIDR, \
+declare_cpu_ops 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 fbbe925..1d0c377 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -169,10 +169,6 @@
 	ret
 endfunc cortex_x4_cpu_reg_dump
 
-declare_cpu_ops_wa_4 cortex_x4, CORTEX_X4_MIDR, \
+declare_cpu_ops 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 093d91d..0663b21 100644
--- a/lib/cpus/aarch64/cortex_x925.S
+++ b/lib/cpus/aarch64/cortex_x925.S
@@ -99,10 +99,6 @@
 	ret
 endfunc cortex_x925_cpu_reg_dump
 
-declare_cpu_ops_wa_4 cortex_x925, CORTEX_X925_MIDR, \
+declare_cpu_ops 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 e608422..105da5c 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -188,143 +188,3 @@
 	get_rev_var x0, x1
 	ret
 endfunc cpu_get_rev_var
-
-/*
- * int check_wa_cve_2017_5715(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_2017_5715
-func check_wa_cve_2017_5715
-	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_EXTRA1_FUNC]
-	/*
-	 * If the reserved function pointer is NULL, this CPU
-	 * is unaffected by CVE-2017-5715 so bail out.
-	 */
-	cmp	x0, #CPU_NO_EXTRA1_FUNC
-	beq	1f
-	br	x0
-1:
-	mov	x0, #ERRATA_NOT_APPLIES
-	ret
-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
- * for CVE-2018-3639.
- * The function pointer is only returned on cores that employ
- * dynamic mitigation.  If the core uses static mitigation or is
- * unaffected by CVE-2018-3639 this function returns NULL.
- *
- * NOTE: Must be called only after cpu_ops have been initialized
- *       in per-CPU data.
- */
-	.globl	wa_cve_2018_3639_get_disable_ptr
-func wa_cve_2018_3639_get_disable_ptr
-	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_EXTRA2_FUNC]
-	ret
-endfunc wa_cve_2018_3639_get_disable_ptr
-
-/*
- * int check_smccc_arch_wa3_applies(void);
- *
- * This function checks whether SMCCC_ARCH_WORKAROUND_3 is enabled to mitigate
- * CVE-2022-23960 for this CPU. It returns:
- *  - ERRATA_APPLIES when SMCCC_ARCH_WORKAROUND_3 can be invoked to mitigate
- *    the CVE.
- *  - ERRATA_NOT_APPLIES when SMCCC_ARCH_WORKAROUND_3 should not be invoked to
- *    mitigate the CVE.
- *
- * NOTE: Must be called only after cpu_ops have been initialized
- *       in per-CPU data.
- */
-	.globl	check_smccc_arch_wa3_applies
-func check_smccc_arch_wa3_applies
-	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_EXTRA3_FUNC]
-	/*
-	 * If the reserved function pointer is NULL, this CPU
-	 * is unaffected by CVE-2022-23960 so bail out.
-	 */
-	cmp	x0, #CPU_NO_EXTRA3_FUNC
-	beq	1f
-	br	x0
-1:
-	mov	x0, #ERRATA_NOT_APPLIES
-	ret
-endfunc check_smccc_arch_wa3_applies
diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S
index 64158e7..22cd3ba 100644
--- a/lib/cpus/aarch64/denver.S
+++ b/lib/cpus/aarch64/denver.S
@@ -319,11 +319,8 @@
 
 /* macro to declare cpu_ops for Denver SKUs */
 .macro	denver_cpu_ops_wa midr
-	declare_cpu_ops_wa denver, \midr, \
+	declare_cpu_ops denver, \midr, \
 		denver_reset_func, \
-		check_erratum_denver_5715, \
-		CPU_NO_EXTRA2_FUNC, \
-		CPU_NO_EXTRA3_FUNC, \
 		denver_core_pwr_dwn, \
 		denver_cluster_pwr_dwn
 .endm
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index ce84942..9526b80 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -148,10 +148,6 @@
 	ret
 endfunc neoverse_v2_cpu_reg_dump
 
-declare_cpu_ops_wa_4 neoverse_v2, NEOVERSE_V2_MIDR, \
+declare_cpu_ops 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 2ead062..ca108e7 100644
--- a/lib/cpus/aarch64/neoverse_v3.S
+++ b/lib/cpus/aarch64/neoverse_v3.S
@@ -124,10 +124,6 @@
 	neoverse_v3_reset_func, \
 	neoverse_v3_core_pwr_dwn
 
-declare_cpu_ops_wa_4 neoverse_v3, NEOVERSE_V3_MIDR, \
+declare_cpu_ops 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/errata_common.c b/lib/cpus/errata_common.c
index 0530647..a1e6d60 100644
--- a/lib/cpus/errata_common.c
+++ b/lib/cpus/errata_common.c
@@ -6,6 +6,8 @@
 
 /* Runtime C routines for errata workarounds and common routines */
 
+#include <assert.h>
+
 #include <arch.h>
 #include <arch_helpers.h>
 #include <cortex_a75.h>
@@ -26,6 +28,31 @@
 #include <neoverse_n3.h>
 #include <neoverse_v3.h>
 
+struct erratum_entry *find_erratum_entry(uint32_t errata_id)
+{
+	struct cpu_ops *cpu_ops;
+	struct erratum_entry *entry, *end;
+
+	cpu_ops = get_cpu_ops_ptr();
+	assert(cpu_ops != NULL);
+
+	entry = cpu_ops->errata_list_start;
+	assert(entry != NULL);
+
+	end = cpu_ops->errata_list_end;
+	assert(end != NULL);
+
+	end--; /* point to the last erratum entry of the queried cpu */
+
+	while ((entry <= end)) {
+		if (entry->id == errata_id) {
+			return entry;
+		}
+		entry += 1;
+	}
+	return NULL;
+}
+
 bool check_if_trbe_disable_affected_core(void)
 {
 	switch (EXTRACT_PARTNUM(read_midr())) {
@@ -151,3 +178,21 @@
 
 	return false;
 }
+
+int check_erratum_applies(uint32_t cve, int errata_id)
+{
+	struct erratum_entry *entry;
+	long rev_var;
+
+	rev_var = cpu_get_rev_var();
+
+	entry = find_erratum_entry(errata_id);
+
+	if (entry == NULL) {
+		return ERRATA_NOT_APPLIES;
+	}
+
+	assert(entry->cve == cve);
+
+	return entry->check_func(rev_var);
+}
diff --git a/lib/extensions/pauth/pauth.c b/lib/extensions/pauth/pauth.c
index 2dd0d28..fbbcaa2 100644
--- a/lib/extensions/pauth/pauth.c
+++ b/lib/extensions/pauth/pauth.c
@@ -62,16 +62,25 @@
 void __no_pauth pauth_enable_el3(void)
 {
 	write_sctlr_el3(read_sctlr_el3() | SCTLR_EnIA_BIT);
+
+	if (is_feat_pauth_lr_supported()) {
+		write_sctlr2_el3(read_sctlr2_el3() | SCTLR2_EnPACM_BIT);
+	}
+
 	isb();
 }
 
 void __no_pauth pauth_enable_el1(void)
 {
 	write_sctlr_el1(read_sctlr_el1() | SCTLR_EnIA_BIT);
+
+	if (is_feat_pauth_lr_supported()) {
+		write_sctlr2_el1(read_sctlr2_el1() | SCTLR2_EnPACM_BIT);
+	}
+
 	isb();
 }
 
-/* Enable PAuth for EL2 */
 void pauth_enable_el2(void)
 {
 	u_register_t hcr_el2 = read_hcr_el2();
diff --git a/lib/extensions/pmuv3/aarch64/pmuv3.c b/lib/extensions/pmuv3/aarch64/pmuv3.c
index 61d1258..b47b664 100644
--- a/lib/extensions/pmuv3/aarch64/pmuv3.c
+++ b/lib/extensions/pmuv3/aarch64/pmuv3.c
@@ -78,11 +78,14 @@
 	 *   1  |  1   |    enabled   | disabled only for counters 0 to
 	 *                              MDCR_EL2.HPMN - 1. Enabled for the rest
 	 *
+	 * MDCR_EL3.EnPM2: Set to one so that various PMUv3p9 related system
+	 * register accesses do not trap to EL3.
+	 *
 	 * MDCR_EL3.TPM: Set to zero so that EL0, EL1, and EL2 System register
 	 *  accesses to all Performance Monitors registers do not trap to EL3.
 	 */
-	mdcr_el3_val = (mdcr_el3_val | MDCR_SCCD_BIT | MDCR_MCCD_BIT) &
-		  ~(MDCR_MPMX_BIT | MDCR_SPME_BIT | MDCR_TPM_BIT);
+	mdcr_el3_val |= MDCR_SCCD_BIT | MDCR_MCCD_BIT | MDCR_EnPM2_BIT;
+	mdcr_el3_val &=	~(MDCR_MPMX_BIT | MDCR_SPME_BIT | MDCR_TPM_BIT);
 	mdcr_el3_val = mtpmu_disable_el3(mdcr_el3_val);
 
 	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
diff --git a/lib/libc/printf.c b/lib/libc/printf.c
index f8c4a26..2a4b9db 100644
--- a/lib/libc/printf.c
+++ b/lib/libc/printf.c
@@ -44,19 +44,19 @@
 	unsigned int rem;
 
 	/* num_buf is only large enough for radix >= 10 */
-	if (radix < 10) {
+	if (radix < 10U) {
 		assert(0);
 		return 0;
 	}
 
 	do {
 		rem = (uint32_t)(unum % radix);
-		if (rem < 0xa) {
+		if (rem < 0xaU) {
 			num_buf[i] = '0' + rem;
 		} else if (uppercase) {
-			num_buf[i] = 'A' + (rem - 0xa);
+			num_buf[i] = 'A' + (rem - 0xaU);
 		} else {
-			num_buf[i] = 'a' + (rem - 0xa);
+			num_buf[i] = 'a' + (rem - 0xaU);
 		}
 		i++;
 		unum /= radix;
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 56bfb64..1561a59 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -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
 #
@@ -160,6 +160,11 @@
 # direct setting. Use BRANCH_PROTECTION to enable PAUTH.
 ENABLE_PAUTH			?=	0
 
+# FEAT_PAUTH_LR is an optional architectural feature, so this flag must be set
+# manually in addition to the BRANCH_PROTECTION flag which is used for other
+# branch protection and pointer authentication features.
+ENABLE_FEAT_PAUTH_LR		?=	0
+
 # Include pointer authentication (ARMv8.3-PAuth) registers in cpu context. This
 # must be set to 1 if the platform wants to use this feature in the Secure
 # world. It is not necessary for use in the Non-secure world.
diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
index 7e2d9cc..d6b6863 100644
--- a/plat/arm/board/fvp/fvp_bl1_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
@@ -8,11 +8,16 @@
 
 #include <drivers/measured_boot/event_log/event_log.h>
 #include <drivers/measured_boot/metadata.h>
-#include <plat/arm/common/plat_arm.h>
 #include <tools_share/zero_oid.h>
 
+#include <plat/arm/common/plat_arm.h>
+
 /* Event Log data */
+#if TRANSFER_LIST
+static uint8_t *event_log;
+#else
 static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE];
+#endif
 
 /* FVP table with platform specific image IDs, names and PCRs */
 const event_log_metadata_t fvp_event_log_metadata[] = {
@@ -20,14 +25,23 @@
 	{ TB_FW_CONFIG_ID, MBOOT_TB_FW_CONFIG_STRING, PCR_0 },
 	{ BL2_IMAGE_ID, MBOOT_BL2_IMAGE_STRING, PCR_0 },
 
-	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
+	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
 };
 
 void bl1_plat_mboot_init(void)
 {
-	size_t event_log_max_size = PLAT_ARM_EVENT_LOG_MAX_SIZE;
+	size_t event_log_max_size;
 	int rc;
 
+#if TRANSFER_LIST
+	event_log = transfer_list_event_log_extend(
+		secure_tl, PLAT_ARM_EVENT_LOG_MAX_SIZE,
+		&event_log_max_size);
+	assert(event_log != NULL);
+#else
+	event_log_max_size = sizeof(event_log);
+#endif
+
 	rc = event_log_init(event_log, event_log + event_log_max_size);
 	if (rc < 0) {
 		ERROR("Failed to initialize event log (%d).\n", rc);
@@ -43,18 +57,28 @@
 
 void bl1_plat_mboot_finish(void)
 {
-	size_t event_log_cur_size;
+	size_t event_log_cur_size = event_log_get_cur_size(event_log);
 
-	event_log_cur_size = event_log_get_cur_size(event_log);
-	int rc = arm_set_tb_fw_info((uintptr_t)event_log,
-				    event_log_cur_size,
-				    PLAT_ARM_EVENT_LOG_MAX_SIZE);
-	if (rc != 0) {
-		/*
-		 * It is a fatal error because on FVP platform, BL2 software
-		 * assumes that a valid Event Log buffer exist and it will use
-		 * same Event Log buffer to append image measurements.
-		 */
-		panic();
+#if TRANSFER_LIST
+	uint8_t *rc = transfer_list_event_log_finish(
+		secure_tl, (uintptr_t)event_log + event_log_cur_size);
+
+	if (rc != NULL) {
+		return;
 	}
+#else
+	int rc = arm_set_tb_fw_info((uintptr_t)event_log, event_log_cur_size,
+				PLAT_ARM_EVENT_LOG_MAX_SIZE);
+	if (rc == 0) {
+		return;
+	}
+#endif
+
+	/*
+	 * Panic if we fail to set up the event log for the next stage. This is a fatal
+	 * error because, on the FVP platform, BL2 software assumes that a valid
+	 * Event Log buffer exists and will use the same Event Log buffer to append image
+	 * measurements.
+	 */
+	panic();
 }
diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
index 28aef92..1fae0cf 100644
--- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
@@ -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
  */
@@ -19,7 +19,7 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/common_def.h>
 
-#if defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)
+#if !TRANSFER_LIST && (defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd))
 CASSERT(ARM_EVENT_LOG_DRAM1_SIZE >= PLAT_ARM_EVENT_LOG_MAX_SIZE, \
 	assert_res_eventlog_mem_insufficient);
 #endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */
@@ -61,10 +61,17 @@
 {
 	uint8_t *event_log_start;
 	uint8_t *event_log_finish;
-	size_t bl1_event_log_size;
-	size_t event_log_max_size;
-	int rc;
+	size_t bl1_event_log_size __unused;
+	size_t event_log_max_size __unused;
+	int rc __unused;
 
+#if TRANSFER_LIST
+	event_log_start = transfer_list_event_log_extend(
+		secure_tl, PLAT_ARM_EVENT_LOG_MAX_SIZE, &event_log_max_size);
+	event_log_finish = event_log_start + event_log_max_size;
+
+	event_log_base = (uintptr_t)event_log_start;
+#else
 	rc = arm_get_tb_fw_info(&event_log_base, &bl1_event_log_size,
 				&event_log_max_size);
 	if (rc != 0) {
@@ -82,10 +89,11 @@
 	 * BL1 and BL2 share the same Event Log buffer and that BL2 will
 	 * append its measurements after BL1's
 	 */
-	event_log_start = (uint8_t *)((uintptr_t)event_log_base +
-				      bl1_event_log_size);
-	event_log_finish = (uint8_t *)((uintptr_t)event_log_base +
-				       event_log_max_size);
+	event_log_start =
+		(uint8_t *)((uintptr_t)event_log_base + bl1_event_log_size);
+	event_log_finish =
+		(uint8_t *)((uintptr_t)event_log_base + event_log_max_size);
+#endif
 
 	event_log_init((uint8_t *)event_log_start, event_log_finish);
 }
@@ -160,7 +168,7 @@
 	int rc;
 
 	/* Event Log address in Non-Secure memory */
-	uintptr_t ns_log_addr;
+	uintptr_t ns_log_addr __unused;
 
 	/* Event Log filled size */
 	size_t event_log_cur_size;
@@ -172,6 +180,15 @@
 
 	event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
 
+#if TRANSFER_LIST
+	/*
+	 * Re-size the event log for the next stage and update the size to include
+	 * the entire event log (i.e., not just what this stage has added.)
+	 */
+	event_log_base = (uintptr_t)transfer_list_event_log_finish(
+		secure_tl, (uintptr_t)event_log_base + event_log_cur_size);
+	event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
+#else
 #if defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)
 	/* Copy Event Log to TZC secured DRAM memory */
 	(void)memcpy((void *)ARM_EVENT_LOG_DRAM1_BASE,
@@ -217,6 +234,7 @@
 		panic();
 	}
 #endif /* defined(SPD_tspd) || defined(SPD_spmd) */
+#endif /* TRANSFER_LIST */
 
 	event_log_dump((uint8_t *)event_log_base, event_log_cur_size);
 }
diff --git a/plat/arm/board/fvp/fvp_private.h b/plat/arm/board/fvp/fvp_private.h
index 9a51eb7..7e53a65 100644
--- a/plat/arm/board/fvp/fvp_private.h
+++ b/plat/arm/board/fvp/fvp_private.h
@@ -19,7 +19,6 @@
 void fvp_interconnect_enable(void);
 void fvp_interconnect_disable(void);
 void fvp_timer_init(void);
-void tsp_early_platform_setup(void);
 void fvp_pcpu_init(void);
 void fvp_gic_driver_pre_init(void);
 
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 854e48a..68ff0fe 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -206,7 +206,7 @@
 #  define PLAT_ARM_MMAP_ENTRIES		12
 #  define MAX_XLAT_TABLES		6
 # else
-#  define PLAT_ARM_MMAP_ENTRIES		11
+#  define PLAT_ARM_MMAP_ENTRIES		12
 #  define MAX_XLAT_TABLES		5
 # endif /* (IMAGE_BL2 && ENABLE_RME) */
 #else
@@ -514,8 +514,12 @@
 /* Account for additional measurements of secure partitions and SPM. */
 #define	PLAT_ARM_EVENT_LOG_MAX_SIZE		UL(0x800)
 #else
+#if defined(IMAGE_BL1) && TRANSFER_LIST
+#define PLAT_ARM_EVENT_LOG_MAX_SIZE		UL(0x200)
+#else
 #define	PLAT_ARM_EVENT_LOG_MAX_SIZE		UL(0x400)
 #endif
+#endif
 
 /*
  * Maximum size of Event Log buffer used for DRTM
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index beb6d5d..8e8870c 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -292,7 +292,7 @@
 				plat/arm/board/fvp/fvp_ide_keymgmt.c
 endif
 
-ifeq (${ENABLE_FEAT_RNG_TRAP},1)
+ifneq (${ENABLE_FEAT_RNG_TRAP},0)
 BL31_SOURCES		+=	plat/arm/board/fvp/fvp_sync_traps.c
 endif
 
diff --git a/plat/arm/board/fvp/tsp/fvp_tsp_setup.c b/plat/arm/board/fvp/tsp/fvp_tsp_setup.c
index 3c8a963..53a84c6 100644
--- a/plat/arm/board/fvp/tsp/fvp_tsp_setup.c
+++ b/plat/arm/board/fvp/tsp/fvp_tsp_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,9 +8,10 @@
 
 #include "../fvp_private.h"
 
-void tsp_early_platform_setup(void)
+void tsp_early_platform_setup(u_register_t arg0, u_register_t arg1,
+			      u_register_t arg2, u_register_t arg3)
 {
-	arm_tsp_early_platform_setup();
+	arm_tsp_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	/* Initialize the platform config for future decision making */
 	fvp_config_setup();
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 0216000..76bae38 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -258,11 +258,7 @@
 #define TC_FLASH0_RO	MAP_REGION_FLAT(V2M_FLASH0_BASE,\
 						V2M_FLASH0_SIZE,	\
 						MT_DEVICE | MT_RO | MT_SECURE)
-#if TARGET_PLATFORM == 2
-#define PLAT_ARM_NSTIMER_FRAME_ID	U(0)
-#else
 #define PLAT_ARM_NSTIMER_FRAME_ID	U(1)
-#endif
 
 #define PLAT_ARM_TRUSTED_ROM_BASE	0x0
 
@@ -276,10 +272,7 @@
 #define PLAT_ARM_NSRAM_SIZE		0x00008000	/* 64KB */
 #endif /* TARGET_FLAVOUR_FPGA */
 
-#if TARGET_PLATFORM <= 2
-#define PLAT_ARM_DRAM2_BASE		ULL(0x8080000000)
-#define PLAT_ARM_DRAM2_SIZE             ULL(0x180000000)
-#elif TARGET_PLATFORM >= 3
+#if TARGET_PLATFORM >= 3
 
 #if TC_FPGA_FS_IMG_IN_RAM
 /* 10GB reserved for system+userdata+vendor images */
@@ -348,28 +341,19 @@
 					 CSS_SCMI_PAYLOAD_SIZE_MAX)
 
 #define PLAT_ARM_CLUSTER_COUNT		U(1)
-#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM == 2
-#define PLAT_MAX_CPUS_PER_CLUSTER	U(14)
-#else /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM == 2 */
 #define PLAT_MAX_CPUS_PER_CLUSTER	U(8)
-#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM == 2 */
 #define PLAT_MAX_PE_PER_CPU		U(1)
 
 #define PLATFORM_CORE_COUNT		(PLAT_MAX_CPUS_PER_CLUSTER * PLAT_ARM_CLUSTER_COUNT)
 
 /* Message Handling Unit (MHU) base addresses */
-#if TARGET_PLATFORM <= 2
-	#define PLAT_CSS_MHU_BASE		UL(0x45400000)
-#elif TARGET_PLATFORM >= 3
+#if TARGET_PLATFORM >= 3
 	#define PLAT_CSS_MHU_BASE		UL(0x46000000)
 #endif /* TARGET_PLATFORM >= 3 */
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
 /* AP<->RSS MHUs */
-#if TARGET_PLATFORM <= 2
-#define PLAT_RSE_AP_SND_MHU_BASE	UL(0x2A840000)
-#define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x2A850000)
-#elif TARGET_PLATFORM == 3
+#if TARGET_PLATFORM == 3
 #define PLAT_RSE_AP_SND_MHU_BASE	UL(0x49000000)
 #define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x49100000)
 #elif TARGET_PLATFORM == 4
@@ -403,36 +387,6 @@
  */
 #define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x30000
 
-#if TARGET_PLATFORM <= 2
-/* TZC Related Constants */
-#define PLAT_ARM_TZC_BASE		UL(0x25000000)
-#define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
-
-#define TZC400_OFFSET			UL(0x1000000)
-#define TZC400_COUNT			4
-
-#define TZC400_BASE(n)			(PLAT_ARM_TZC_BASE + \
-					 (n * TZC400_OFFSET))
-
-#define TZC_NSAID_DEFAULT		U(0)
-
-#define PLAT_ARM_TZC_NS_DEV_ACCESS	\
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DEFAULT))
-
-/*
- * The first region below, TC_TZC_DRAM1_BASE (0xf9000000) to
- * ARM_SCP_TZC_DRAM1_END (0xffffffff) will mark the last 112 MB of DRAM as
- * secure. The second and third regions gives non secure access to rest of DRAM.
- */
-#define TC_TZC_REGIONS_DEF	\
-	{TC_TZC_DRAM1_BASE, ARM_SCP_TZC_DRAM1_END,	\
-		TZC_REGION_S_RDWR, PLAT_ARM_TZC_NS_DEV_ACCESS},	\
-	{TC_NS_DRAM1_BASE, TC_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS,	\
-		PLAT_ARM_TZC_NS_DEV_ACCESS},	\
-	{PLAT_ARM_DRAM2_BASE, PLAT_ARM_DRAM2_END,	\
-		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
-#endif
-
 /* virtual address used by dynamic mem_protect for chunk_base */
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
 
@@ -468,13 +422,11 @@
 #undef  ARM_CONSOLE_BAUDRATE
 #define ARM_CONSOLE_BAUDRATE		38400
 
-#if TARGET_PLATFORM <= 2
-#define TC_UARTCLK			5000000
-#elif TARGET_PLATFORM == 3
+#if TARGET_PLATFORM == 3
 #define TC_UARTCLK			3750000
 #elif TARGET_PLATFORM == 4
 #define TC_UARTCLK			4000000
-#endif /* TARGET_PLATFORM <=2 */
+#endif /* TARGET_PLATFORM == 3 */
 
 
 #if TARGET_FLAVOUR_FVP
diff --git a/plat/arm/board/tc/include/tc_helpers.S b/plat/arm/board/tc/include/tc_helpers.S
index cc2f760..9a8172a 100644
--- a/plat/arm/board/tc/include/tc_helpers.S
+++ b/plat/arm/board/tc/include/tc_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -74,10 +74,6 @@
 	ret
 endfunc enable_dsu_pmu_el1_access
 
-func TC_HANDLER(2)
-	ret
-endfunc TC_HANDLER(2)
-
 func TC_HANDLER(3)
 	mov	x9, lr
 	bl	mark_extllc_presence
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index bbccce6..b29f0d6 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -67,15 +67,10 @@
 endif
 endif
 
-ifneq ($(shell expr $(TARGET_PLATFORM) \<= 1), 0)
+ifneq ($(shell expr $(TARGET_PLATFORM) \<= 2), 0)
         $(error Platform ${PLAT}$(TARGET_PLATFORM) is no longer available.)
 endif
 
-ifneq ($(shell expr $(TARGET_PLATFORM) = 2), 0)
-        $(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
-          Some of the features might not work as expected)
-endif
-
 ifeq ($(shell expr $(TARGET_PLATFORM) \<= 4), 0)
         $(error TARGET_PLATFORM must be less than or equal to 4)
 endif
@@ -109,35 +104,13 @@
 # Save DSU PMU registers on cluster off and restore them on cluster on
 PRESERVE_DSU_PMU_REGS		:= 1
 
-# Specify MHU type based on platform
-ifneq ($(filter ${TARGET_PLATFORM}, 2),)
-	PLAT_MHU		:= MHUv2
-else
-	PLAT_MHU		:= MHUv3
-endif
+PLAT_MHU		:= MHUv3
 
 TC_BASE	=	plat/arm/board/tc
 
 PLAT_INCLUDES		+=	-I${TC_BASE}/include/ \
 				-I${TC_BASE}/fdts/
 
-# CPU libraries for TARGET_PLATFORM=1
-ifeq (${TARGET_PLATFORM}, 1)
-TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a510.S \
-			lib/cpus/aarch64/cortex_a715.S \
-			lib/cpus/aarch64/cortex_x3.S
-endif
-
-# CPU libraries for TARGET_PLATFORM=2
-ifeq (${TARGET_PLATFORM}, 2)
-ERRATA_A520_2938996	:=	1
-ERRATA_X4_2726228	:=	1
-
-TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a520.S \
-			lib/cpus/aarch64/cortex_a720.S \
-			lib/cpus/aarch64/cortex_x4.S
-endif
-
 # CPU libraries for TARGET_PLATFORM=3
 ifeq (${TARGET_PLATFORM}, 3)
 ERRATA_A520_2938996	:=	1
@@ -183,10 +156,6 @@
 				drivers/arm/tzc/tzc400.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-ifeq ($(shell test $(TARGET_PLATFORM) -le 2; echo $$?),0)
-BL2_SOURCES		+=	plat/arm/common/arm_tzc400.c
-endif
-
 BL31_SOURCES		+=	${INTERCONNECT_SOURCES}	\
 				${TC_CPU_SOURCES}	\
 				${TC_BASE}/tc_bl31_setup.c	\
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index a358390..7f2014b 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -54,15 +54,6 @@
 }
 #endif /* PLATFORM_TEST_TFM_TESTSUITE */
 
-#if TARGET_PLATFORM <= 2
-static scmi_channel_plat_info_t tc_scmi_plat_info = {
-	.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
-	.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
-	.db_preserve_mask = 0xfffffffe,
-	.db_modify_mask = 0x1,
-	.ring_doorbell = &mhuv2_ring_doorbell,
-};
-#elif TARGET_PLATFORM >= 3
 static scmi_channel_plat_info_t tc_scmi_plat_info = {
 	.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
 	.db_reg_addr = PLAT_CSS_MHU_BASE + MHU_V3_SENDER_REG_SET(0),
@@ -70,7 +61,6 @@
 	.db_modify_mask = 0x1,
 	.ring_doorbell = &mhu_ring_doorbell,
 };
-#endif
 
 /* the bottom 3 AMU group 1 counters */
 #define MPMM_GEARS ((1 << 0) | (1 << 1) | (1 << 2))
diff --git a/plat/arm/board/tc/tc_security.c b/plat/arm/board/tc/tc_security.c
index 7c7a1a1..804a35b 100644
--- a/plat/arm/board/tc/tc_security.c
+++ b/plat/arm/board/tc/tc_security.c
@@ -7,21 +7,8 @@
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
 
-#if (TARGET_PLATFORM <= 2)
-static const arm_tzc_regions_info_t tzc_regions[] = {
-	TC_TZC_REGIONS_DEF,
-	{}
-};
-#endif
-
 /* Initialize the secure environment */
 void plat_arm_security_setup(void)
 {
-#if (TARGET_PLATFORM <= 2)
-	unsigned int i;
 
-	for (i = 0U; i < TZC400_COUNT; i++) {
-		arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
-	}
-#endif
 }
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index bd3946c..522017f 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -320,6 +320,13 @@
 void arm_bl2_setup_next_ep_info(bl_mem_params_node_t *next_param_node)
 {
 	entry_point_info_t *ep __unused;
+
+	/*
+	 * Information might have been added to the TL before this (i.e. event log)
+	 * make sure the checksum is up to date.
+	 */
+	transfer_list_update_checksum(secure_tl);
+
 	ep = transfer_list_set_handoff_args(secure_tl,
 					    &next_param_node->ep_info);
 	assert(ep != NULL);
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 82f96ba..f196269 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -133,7 +133,12 @@
 	}
 #endif
 	else {
+#if TRANSFER_LIST && !RESET_TO_BL31
+		next_image_info = transfer_list_set_handoff_args(
+			secure_tl, &bl32_image_ep_info);
+#else
 		next_image_info = &bl32_image_ep_info;
+#endif
 	}
 
 	/*
@@ -394,6 +399,16 @@
 	te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size,
 			       transfer_list_entry_data(te));
 	assert(te != NULL);
+
+	te = transfer_list_find(secure_tl, TL_TAG_TPM_EVLOG);
+	if (te != NULL) {
+		te = transfer_list_add(ns_tl, TL_TAG_TPM_EVLOG, te->data_size,
+				  transfer_list_entry_data(te));
+		if (te == NULL) {
+			ERROR("Failed to load event log in Non-Secure transfer list\n");
+			panic();
+		}
+	}
 #endif /* TRANSFER_LIST && !RESET_TO_BL31 */
 
 #if RESET_TO_BL31
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index d3c2a96..418a9d8 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -456,6 +456,9 @@
     ifeq (${MEASURED_BOOT},1)
          BL1_SOURCES		+= 	${EVENT_LOG_SOURCES}
          BL2_SOURCES		+= 	${EVENT_LOG_SOURCES}
+         ifeq (${SPD_tspd},1)
+             BL32_SOURCES		+= 	${EVENT_LOG_SOURCES}
+         endif
     endif
 
     ifeq (${DRTM_SUPPORT},1)
diff --git a/plat/arm/common/tsp/arm_tsp.mk b/plat/arm/common/tsp/arm_tsp.mk
index 4ad77c6..d7592df 100644
--- a/plat/arm/common/tsp/arm_tsp.mk
+++ b/plat/arm/common/tsp/arm_tsp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,3 +8,10 @@
 BL32_SOURCES		+=	plat/arm/common/arm_topology.c			\
 				plat/arm/common/tsp/arm_tsp_setup.c		\
 				plat/common/aarch64/platform_mp_stack.S
+
+ifeq (${TRANSFER_LIST},1)
+BL32_SOURCES	+=	$(TRANSFER_LIST_SOURCES)
+ifeq (${MEASURED_BOOT},1)
+BL32_SOURCES	+=	$(EVENT_LOG_SOURCES)
+endif
+endif
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index 4f45579..d018dee 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -13,6 +13,9 @@
 #include <common/debug.h>
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
+#if TRANSFER_LIST && MEASURED_BOOT
+#include <drivers/measured_boot/event_log/event_log.h>
+#endif
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -26,13 +29,32 @@
 					BL32_END - BL32_BASE,		\
 					MT_MEMORY | MT_RW | MT_SECURE)
 
+#define MAP_FW_HANDOFF		MAP_REGION_FLAT(			\
+					PLAT_ARM_EL3_FW_HANDOFF_BASE,	\
+					PLAT_ARM_FW_HANDOFF_SIZE,	\
+					MT_MEMORY | MT_RO | MT_SECURE)
+
+struct transfer_list_header *secure_tl __unused;
+
 /*******************************************************************************
  * Initialize the UART
  ******************************************************************************/
 static console_t arm_tsp_runtime_console;
 
-void arm_tsp_early_platform_setup(void)
+void arm_tsp_early_platform_setup(u_register_t arg0, u_register_t arg1,
+			      u_register_t arg2, u_register_t arg3)
 {
+#if TRANSFER_LIST
+	secure_tl = (struct transfer_list_header *)arg3;
+	assert(secure_tl != NULL);
+
+	if (transfer_list_check_header(secure_tl) == TL_OPS_NON) {
+		ERROR("Invalid transfer list received");
+		transfer_list_dump(secure_tl);
+		panic();
+	}
+#endif
+
 	/*
 	 * Initialize a different console than already in use to display
 	 * messages from TSP
@@ -41,16 +63,18 @@
 					PLAT_ARM_TSP_UART_CLK_IN_HZ,
 					ARM_CONSOLE_BAUDRATE,
 					&arm_tsp_runtime_console);
-	if (rc == 0)
+	if (rc == 0) {
 		panic();
+	}
 
 	console_set_scope(&arm_tsp_runtime_console,
 			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
 }
 
-void tsp_early_platform_setup(void)
+void tsp_early_platform_setup(u_register_t arg0, u_register_t arg1,
+			      u_register_t arg2, u_register_t arg3)
 {
-	arm_tsp_early_platform_setup();
+	arm_tsp_early_platform_setup(arg0, arg1, arg2, arg3);
 }
 
 /*******************************************************************************
@@ -58,6 +82,8 @@
  ******************************************************************************/
 void tsp_platform_setup(void)
 {
+	struct transfer_list_entry *te __unused;
+
 	/*
 	 * On GICv2 the driver must be initialised before calling the plat_ic_*
 	 * functions as they need the data structures. Higher versions don't.
@@ -65,6 +91,17 @@
 #if USE_GIC_DRIVER == 2
 	gic_init(plat_my_core_pos());
 #endif
+
+#if TRANSFER_LIST && MEASURED_BOOT
+	te = transfer_list_find(secure_tl, TL_TAG_TPM_EVLOG);
+	assert(te != NULL);
+
+	/*
+	 * Note the actual log is offset 4-bytes from the start of entry data, the
+	 * first bytes are reserved.
+	 */
+	event_log_dump(transfer_list_entry_data(te) + U(4), te->data_size - U(4));
+#endif
 }
 
 /*******************************************************************************
@@ -81,6 +118,9 @@
 	const mmap_region_t bl_regions[] = {
 		MAP_BL_TSP_TOTAL,
 		ARM_MAP_BL_RO,
+#if TRANSFER_LIST
+		MAP_FW_HANDOFF,
+#endif
 		{0}
 	};
 
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 98b99d1..c848cae 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -149,6 +149,7 @@
 ERRATA_A53_835769	:=	1
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
+ERRATA_A53_1530924	:=	1
 
 IMX_DRAM_RETENTION	?=	1
 $(eval $(call assert_boolean,IMX_DRAM_RETENTION))
diff --git a/plat/mediatek/build_helpers/options.mk b/plat/mediatek/build_helpers/options.mk
index 75cc80a..c55f50e 100644
--- a/plat/mediatek/build_helpers/options.mk
+++ b/plat/mediatek/build_helpers/options.mk
@@ -1,27 +1,30 @@
 #
-# Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2022-2025, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 # call add_defined_option to evaluate MTK defined value
-$(eval $(call add_defined_option,MTK_SIP_KERNEL_BOOT_ENABLE))
-$(eval $(call add_defined_option,PLAT_EXTRA_RODATA_INCLUDES))
-$(eval $(call add_defined_option,MTK_EXTRA_LINKERFILE))
-$(eval $(call add_defined_option,MTK_BL31_AS_BL2))
-$(eval $(call add_defined_option,MTK_BL33_IS_64BIT))
-$(eval $(call add_defined_option,PLAT_XLAT_TABLES_DYNAMIC))
-$(eval $(call add_defined_option,MTK_ADAPTED))
-$(eval $(call add_defined_option,MTK_PUBEVENT_ENABLE))
-$(eval $(call add_defined_option,MTK_SOC))
-$(eval $(call add_defined_option,UART_CLOCK))
-$(eval $(call add_defined_option,UART_BAUDRATE))
-$(eval $(call add_defined_option,CONFIG_MTK_MCUSYS))
-$(eval $(call add_defined_option,CONFIG_MTK_PM_SUPPORT))
-$(eval $(call add_defined_option,CONFIG_MTK_CPU_PM_SUPPORT))
-$(eval $(call add_defined_option,CONFIG_MTK_SMP_EN))
-$(eval $(call add_defined_option,CONFIG_MTK_CPU_SUSPEND_EN))
-$(eval $(call add_defined_option,CONFIG_MTK_PM_ARCH))
-$(eval $(call add_defined_option,CONFIG_MTK_CPU_PM_ARCH))
-$(eval $(call add_defined_option,CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND))
-$(eval $(call add_defined_option,CONFIG_MTK_MTCMOS))
+DEFINED_OPTIONS := \
+	CONFIG_MTK_CPU_PM_ARCH \
+	CONFIG_MTK_CPU_PM_SUPPORT \
+	CONFIG_MTK_CPU_SUSPEND_EN \
+	CONFIG_MTK_MCUSYS \
+	CONFIG_MTK_MTCMOS \
+	CONFIG_MTK_PM_ARCH \
+	CONFIG_MTK_PM_SUPPORT \
+	CONFIG_MTK_SMP_EN \
+	CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND \
+	MTK_ADAPTED \
+	MTK_BL31_AS_BL2 \
+	MTK_BL33_IS_64BIT \
+	MTK_EXTRA_LINKERFILE \
+	MTK_PUBEVENT_ENABLE \
+	MTK_SIP_KERNEL_BOOT_ENABLE \
+	MTK_SOC \
+	PLAT_EXTRA_RODATA_INCLUDES \
+	PLAT_XLAT_TABLES_DYNAMIC \
+	UART_BAUDRATE \
+	UART_CLOCK
+
+$(foreach opt, $(DEFINED_OPTIONS),$(eval $(call add_defined_option,$(opt))))
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.c b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.c
index 632af52..70168d1 100644
--- a/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.c
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.c
@@ -22,7 +22,15 @@
 	uint32_t count = 0;
 
 	while ((mmio_read_32(reg) & mask) != expect) {
-		if (count > retry_times) {
+		/*
+		 * If retry_times == HW_SEM_NO_WAIT, it is just for checking if the hardware
+		 * semaphore can be locked or not. The purpose is for SMMU to check NPU power
+		 * status. Hence, just returning -EBUSY is okay. There is no need to show any
+		 * ERROR message here.
+		 */
+		if (retry_times == HW_SEM_NO_WAIT) {
+			return -EBUSY;
+		} else if (count > retry_times) {
 			ERROR("%s: timed out, reg = %x, mask = %x, expect = %x\n",
 			       __func__, reg, mask, expect);
 			return -EBUSY;
@@ -116,14 +124,14 @@
 {
 	return apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_CTRL,
 					APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_STA,
-					APU_HW_SEM_SYS_APMCU, HW_SEM_GET, 0, 0);
+					APU_HW_SEM_SYS_APMCU, HW_SEM_GET, HW_SEM_NO_WAIT, 0);
 }
 
 int rv_iommu_hw_sem_unlock(void)
 {
 	return apu_hw_sema_ctl_per_mbox(APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_CTRL,
 					APU_MBOX(APU_HW_SEM_SYS_APMCU) + APU_MBOX_SEMA1_STA,
-					APU_HW_SEM_SYS_APMCU, HW_SEM_PUT, 0, 0);
+					APU_HW_SEM_SYS_APMCU, HW_SEM_PUT, HW_SEM_NO_WAIT, 0);
 }
 
 int apu_hw_sema_ctl(uint32_t sem_addr, uint8_t usr_bit, uint8_t ctl, uint32_t timeout,
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.h b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.h
index b5a48e2..17f5500 100644
--- a/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.h
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_rv_pwr_ctrl.h
@@ -27,6 +27,7 @@
 		    uint8_t bypass);
 
 #define HW_SEM_TIMEOUT	(300) /* 300 us */
+#define HW_SEM_NO_WAIT	(0)   /* no wait */
 
 /* APU MBOX */
 #define MBOX_WKUP_CFG		(0x80)
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_lp_irqremain.c b/plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_lp_irqremain.c
index 563e6b5..a1c903e 100644
--- a/plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_lp_irqremain.c
+++ b/plat/mediatek/drivers/cpu_pm/cpcv5_4/mt_lp_irqremain.c
@@ -7,12 +7,11 @@
 #include <stdint.h>
 #include <stdio.h>
 
-#include <drivers/cirq.h>
-
 #include <platform_def.h>
 
 #include <lib/pm/mtk_pm.h>
 #include <lpm_v2/mt_lp_rm.h>
+#include <mt_cirq.h>
 #include "mt_cpu_pm.h"
 #include "mt_lp_irqremain.h"
 
diff --git a/plat/mediatek/drivers/smmu/smmu.c b/plat/mediatek/drivers/smmu/smmu.c
index 4d31071..a3d83ec 100644
--- a/plat/mediatek/drivers/smmu/smmu.c
+++ b/plat/mediatek/drivers/smmu/smmu.c
@@ -255,9 +255,6 @@
 		break;
 	}
 
-	if (ret)
-		ERROR(TAG "%s, smmu_%u cmd:%u fail:%u\n", __func__, smmu_id, cmd_id, ret);
-
 	return ret;
 }
 /* Register MTK SMMU service */
diff --git a/plat/mediatek/mt8189/include/platform_def.h b/plat/mediatek/mt8189/include/platform_def.h
index 66bec16..e61aaa2 100644
--- a/plat/mediatek/mt8189/include/platform_def.h
+++ b/plat/mediatek/mt8189/include/platform_def.h
@@ -45,6 +45,15 @@
 #define UART_BAUDRATE	(115200)
 
 /*******************************************************************************
+ * CIRQ related constants
+ ******************************************************************************/
+#define SYS_CIRQ_BASE		(IO_PHYS + 204000)
+#define MD_WDT_IRQ_BIT_ID	(519)
+#define CIRQ_REG_NUM		(19)
+#define CIRQ_SPI_START		(128)
+#define CIRQ_IRQ_NUM		(598)
+
+/*******************************************************************************
  * System counter frequency related constants
  ******************************************************************************/
 #define SYS_COUNTER_FREQ_IN_HZ	(13000000)
@@ -81,6 +90,18 @@
 #define BL31_LIMIT			(TZRAM_BASE + TZRAM_SIZE)
 
 /*******************************************************************************
+ * GIC-600 & interrupt handling related constants
+ ******************************************************************************/
+/* Base MTK_platform compatible GIC memory map */
+#define BASE_GICD_BASE		(MT_GIC_BASE)
+#define MT_GIC_RDIST_BASE	(MT_GIC_BASE + 0x40000)
+#define DEV_IRQ_ID		300
+
+#define PLAT_MTK_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(DEV_IRQ_ID, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
+/*******************************************************************************
  * Platform specific page table and MMU setup constants
  ******************************************************************************/
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
diff --git a/plat/mediatek/mt8189/platform.mk b/plat/mediatek/mt8189/platform.mk
index 31a5ed5..7e40146 100644
--- a/plat/mediatek/mt8189/platform.mk
+++ b/plat/mediatek/mt8189/platform.mk
@@ -27,6 +27,8 @@
 MODULES-y += $(MTK_PLAT)/lib/mtk_init
 MODULES-y += $(MTK_PLAT)/lib/pm
 MODULES-y += $(MTK_PLAT)/topology
+MODULES-y += $(MTK_PLAT)/drivers/cirq
+MODULES-y += $(MTK_PLAT)/drivers/gic600
 MODULES-y += $(MTK_PLAT)/drivers/mcusys
 MODULES-y += $(MTK_PLAT)/drivers/timer
 
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
index 84a25e9..7412756 100644
--- a/plat/mediatek/mt8196/plat_config.mk
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -50,6 +50,7 @@
 CPU_PWR_TOPOLOGY := group_4_3_1
 CPU_PM_CORE_ARCH64_ONLY := y
 CPU_PM_DOMAIN_CORE_ONLY := n
+CPU_PM_IRQ_REMAIN_ENABLE := y
 CPU_PM_SUSPEND_NOTIFY := y
 CONFIG_MTK_SPM_SUPPORT := y
 CONFIG_MTK_SPM_COMMON_SUPPORT := y
diff --git a/plat/nxp/s32/s32g274ardb2/plat_helpers.S b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
index 7121900..a7dda0d 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_helpers.S
+++ b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
@@ -113,14 +113,12 @@
 /* void platform_mem_init(void); */
 func platform_mem_init
 	mov	x10, x30
-	mov	x0, #BL31_BASE
-	mov	x1, #(BL31_LIMIT & 0xFFFFU)
-	movk	x1, #(BL31_LIMIT >> 16), lsl #16
+	mov_imm	x0, BL31_BASE
+	mov_imm	x1, BL31_LIMIT
 	sub	x1, x1, x0
 	bl	zeromem
-	mov	x0, #BL33_BASE
-	mov	x1, #(BL33_LIMIT & 0xFFFFU)
-	movk	x1, #(BL33_LIMIT >> 16), lsl #16
+	mov_imm	x0, BL33_BASE
+	mov_imm	x1, BL33_LIMIT
 	sub	x1, x1, x0
 	bl	zeromem
 	mov	x30, x10
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_gold.S b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
index 49b7cf0..61eb755 100644
--- a/plat/qti/common/src/aarch64/qti_kryo4_gold.S
+++ b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
@@ -59,9 +59,7 @@
 	ret
 endfunc qti_kryo4_gold_cpu_reg_dump
 
-declare_cpu_ops_wa	qti_kryo4_gold, QTI_KRYO4_GOLD_MIDR,	\
+declare_cpu_ops	qti_kryo4_gold, QTI_KRYO4_GOLD_MIDR,	\
 		qti_kryo4_gold_reset_func,		\
-		CPU_NO_EXTRA1_FUNC,		\
-		cortex_a76_disable_wa_cve_2018_3639,	\
 		cortex_a76_core_pwr_dwn,	\
 		qti_kryo4_gold_cluster_pwr_dwn
diff --git a/plat/qti/msm8916/tsp/msm8916_tsp_setup.c b/plat/qti/msm8916/tsp/msm8916_tsp_setup.c
index 218af57..88d3c93 100644
--- a/plat/qti/msm8916/tsp/msm8916_tsp_setup.c
+++ b/plat/qti/msm8916/tsp/msm8916_tsp_setup.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2023, Stephan Gerhold <stephan@gerhold.net>
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +11,8 @@
 #include "../msm8916_setup.h"
 #include <platform_def.h>
 
-void tsp_early_platform_setup(void)
+void tsp_early_platform_setup(u_register_t arg0, u_register_t arg1,
+			      u_register_t arg2, u_register_t arg3)
 {
 	msm8916_early_platform_setup();
 }
diff --git a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c
index 4bbb259..31583b5 100644
--- a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c
+++ b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,7 +15,8 @@
 
 static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN;
 
-void tsp_early_platform_setup(void)
+void tsp_early_platform_setup(u_register_t arg0, u_register_t arg1,
+			      u_register_t arg2, u_register_t arg3)
 {
 	uniphier_soc = uniphier_get_soc_id();
 	if (uniphier_soc == UNIPHIER_SOC_UNKNOWN)
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 610acc7..7a3e72f 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -27,7 +27,7 @@
  * power down. Therefore, there is no doubt to use the spin_lock here.
  */
 #if !HW_ASSISTED_COHERENCY
-DEFINE_BAKERY_LOCK(pm_secure_lock);
+static DEFINE_BAKERY_LOCK(pm_secure_lock);
 static inline void pm_ipi_lock_get(void)
 {
 	bakery_lock_get(&pm_secure_lock);
diff --git a/plat/xilinx/common/tsp/tsp_plat_setup.c b/plat/xilinx/common/tsp/tsp_plat_setup.c
index 21c29c3..5df4b6e 100644
--- a/plat/xilinx/common/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/common/tsp/tsp_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2023, Advanced Micro Devices. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -17,7 +17,8 @@
 /*******************************************************************************
  * Initialize the UART
  ******************************************************************************/
-void tsp_early_platform_setup(void)
+void tsp_early_platform_setup(u_register_t arg0, u_register_t arg1,
+			      u_register_t arg2, u_register_t arg3)
 {
 	/*
 	 * Register a different console than already in use to display
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index de2cac8..77e3fb0 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,7 +28,7 @@
 
 #define UNDEFINED_CPUID		(~0U)
 
-DEFINE_BAKERY_LOCK(pm_client_secure_lock);
+static DEFINE_BAKERY_LOCK(pm_client_secure_lock);
 
 static const struct pm_ipi apu_ipi = {
 	.local_ipi_id = IPI_LOCAL_ID,
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 46333af..6051de8 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -7,9 +7,6 @@
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <lib/cpus/errata.h>
-#include <lib/cpus/wa_cve_2017_5715.h>
-#include <lib/cpus/wa_cve_2018_3639.h>
-#include <lib/cpus/wa_cve_2022_23960.h>
 #include <lib/smccc.h>
 #include <services/arm_arch_svc.h>
 #include <smccc_helpers.h>
@@ -35,8 +32,11 @@
 	/* Workaround checks are currently only implemented for aarch64 */
 #if WORKAROUND_CVE_2017_5715
 	case SMCCC_ARCH_WORKAROUND_1:
-		if (check_wa_cve_2017_5715() == ERRATA_NOT_APPLIES)
+		if (check_erratum_applies(CVE(2017, 5715))
+			== ERRATA_NOT_APPLIES) {
 			return 1;
+		}
+
 		return 0; /* ERRATA_APPLIES || ERRATA_MISSING */
 #endif
 
@@ -66,8 +66,10 @@
 		 * or permanently mitigated, report the latter as not
 		 * needing dynamic mitigation.
 		 */
-		if (wa_cve_2018_3639_get_disable_ptr() == NULL)
+		if (check_erratum_applies(ERRATUM(ARCH_WORKAROUND_2))
+			== ERRATA_NOT_APPLIES)
 			return 1;
+
 		/*
 		 * If we get here, this CPU requires dynamic mitigation
 		 * so report it as such.
@@ -87,10 +89,13 @@
 		 * CVE-2017-5715 since this SMC can be used instead of
 		 * SMCCC_ARCH_WORKAROUND_1.
 		 */
-		if ((check_smccc_arch_wa3_applies() == ERRATA_NOT_APPLIES) &&
-		    (check_wa_cve_2017_5715() == ERRATA_NOT_APPLIES)) {
+		if ((check_erratum_applies(ERRATUM(ARCH_WORKAROUND_3))
+			== ERRATA_NOT_APPLIES) &&
+		    (check_erratum_applies(CVE(2017, 5715))
+			== ERRATA_NOT_APPLIES)) {
 			return 1;
 		}
+
 		return 0; /* ERRATA_APPLIES || ERRATA_MISSING */
 #endif
 
@@ -101,7 +106,7 @@
 
 #if WORKAROUND_CVE_2024_7881
 	case SMCCC_ARCH_WORKAROUND_4:
-		if (check_wa_cve_2024_7881() != ERRATA_APPLIES) {
+		if (check_erratum_applies(CVE(2024, 7881)) != ERRATA_APPLIES) {
 			return SMC_ARCH_CALL_NOT_SUPPORTED;
 		}
 		return 0;
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
index d688431..d685eef 100644
--- a/services/std_svc/errata_abi/cpu_errata_info.h
+++ b/services/std_svc/errata_abi/cpu_errata_info.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
  */
@@ -48,5 +48,5 @@
 	struct   em_cpu cpu_errata_list[MAX_PLAT_CPU_ERRATA_ENTRIES];
 };
 
-int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag);
+int32_t verify_errata_implemented(uint32_t errata_id);
 #endif /* ERRATA_CPUSPEC_H */
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index a945637..74a1586 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -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
  */
@@ -166,50 +166,33 @@
 #endif
 
 /* Function to check if the errata exists for the specific CPU and rxpx */
-int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag)
+int32_t verify_errata_implemented(uint32_t errata_id)
 {
-	int32_t ret_val;
-	struct cpu_ops *cpu_ops;
-	struct erratum_entry *entry, *end;
+	struct erratum_entry *entry;
 	long rev_var;
 
-	ret_val = EM_UNKNOWN_ERRATUM;
 	rev_var = cpu_get_rev_var();
 
 #if ERRATA_NON_ARM_INTERCONNECT
-	ret_val = non_arm_interconnect_errata(errata_id, rev_var);
+	int32_t ret_val = non_arm_interconnect_errata(errata_id, rev_var);
 	if (ret_val != EM_UNKNOWN_ERRATUM) {
 		return ret_val;
 	}
 #endif
+	entry = find_erratum_entry(errata_id);
+	if (entry == NULL)
+		return EM_UNKNOWN_ERRATUM;
 
-	cpu_ops = get_cpu_ops_ptr();
-	assert(cpu_ops != NULL);
-
-	entry = cpu_ops->errata_list_start;
-	assert(entry != NULL);
-
-	end = cpu_ops->errata_list_end;
-	assert(end != NULL);
-
-	end--; /* point to the last erratum entry of the queried cpu */
-
-	while ((entry <= end) && (ret_val == EM_UNKNOWN_ERRATUM)) {
-		if (entry->id == errata_id) {
-			if (entry->check_func(rev_var)) {
-				if (entry->chosen & WA_ENABLED_MASK)
-					if (entry->chosen & SPLIT_WA_MASK)
-						return EM_AFFECTED;
-					else
-						return EM_HIGHER_EL_MITIGATION;
-				else
-					return EM_AFFECTED;
-			}
-			return EM_NOT_AFFECTED;
-		}
-		entry += 1;
+	if (entry->check_func(rev_var)) {
+		if (entry->chosen & WA_ENABLED_MASK)
+			if (entry->chosen & SPLIT_WA_MASK)
+				return EM_AFFECTED;
+			else
+				return EM_HIGHER_EL_MITIGATION;
+		else
+			return EM_AFFECTED;
 	}
-	return ret_val;
+	return EM_NOT_AFFECTED;
 }
 
 /* Predicate indicating that a function id is part of EM_ABI */
@@ -271,7 +254,7 @@
 		if (((uint32_t)x2 != 0) && (validate_spsr_mode())) {
 			SMC_RET1(handle, EM_INVALID_PARAMETERS);
 		}
-		ret_id = verify_errata_implemented((uint32_t)x1, (uint32_t)x2);
+		ret_id = verify_errata_implemented((uint32_t)x1);
 		SMC_RET1(handle, ret_id);
 		break; /* unreachable */
 	default:
diff --git a/services/std_svc/sdei/sdei_event.c b/services/std_svc/sdei/sdei_event.c
index e0c7971..cc8f557 100644
--- a/services/std_svc/sdei/sdei_event.c
+++ b/services/std_svc/sdei/sdei_event.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,14 +19,14 @@
  * Both shared and private maps are stored in single-dimensional array. Private
  * event entries are kept for each PE forming a 2D array.
  */
-sdei_entry_t *get_event_entry(sdei_ev_map_t *map)
+sdei_entry_t *get_event_entry(const sdei_ev_map_t *map)
 {
 	const sdei_mapping_t *mapping;
 	sdei_entry_t *cpu_priv_base;
 	unsigned int base_idx;
 	long int idx;
 
-	if (is_event_private(map)) {
+	if ((map->map_flags & BIT_32(SDEI_MAPF_PRIVATE_SHIFT_)) != 0U) {
 		/*
 		 * For a private map, find the index of the mapping in the
 		 * array.
@@ -52,6 +52,39 @@
 }
 
 /*
+ * Retrieve the SDEI entry for the given mapping and target PE.
+ *
+ * on success : Returns a pointer to the SDEI entry
+ *
+ * On error, returns NULL
+ *
+ * Both shared and private maps are stored in single-dimensional array. Private
+ * event entries are kept for each PE forming a 2D array.
+ */
+sdei_entry_t *get_event_entry_target_pe(long int mapsub, unsigned int nm, uint64_t target_pe)
+{
+	sdei_entry_t *cpu_priv_base;
+	unsigned int base_idx;
+	long int idx;
+
+	/*
+	 * For a private map, find the index of the mapping in the
+	 * array.
+	 */
+	idx = mapsub;
+
+	/* Base of private mappings for this CPU */
+	base_idx = (unsigned int) plat_core_pos_by_mpidr(target_pe);
+	base_idx *= nm;
+	cpu_priv_base = &sdei_private_event_table[base_idx];
+	/*
+	 * Return the address of the entry at the same index in the
+	 * per-CPU event entry.
+	 */
+	return &cpu_priv_base[idx];
+}
+
+/*
  * Find event mapping for a given interrupt number: On success, returns pointer
  * to the event mapping. On error, returns NULL.
  */
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index c58adba..4854b2e 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -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
  */
@@ -29,7 +29,8 @@
 #define MAX_EVENT_NESTING	2U
 
 /* Per-CPU SDEI state access macro */
-#define sdei_get_this_pe_state()	(&cpu_state[plat_my_core_pos()])
+#define sdei_get_this_pe_state()		(&cpu_state[plat_my_core_pos()])
+#define sdei_get_target_pe_state(_pe)	(&cpu_state[plat_core_pos_by_mpidr(_pe)])
 
 /* Structure to store information about an outstanding dispatch */
 typedef struct sdei_dispatch_context {
@@ -58,6 +59,13 @@
 /* SDEI states for all cores in the system */
 static sdei_cpu_state_t cpu_state[PLATFORM_CORE_COUNT];
 
+bool sdei_is_target_pe_masked(uint64_t target_pe)
+{
+	const sdei_cpu_state_t *state = sdei_get_target_pe_state(target_pe);
+
+	return state->pe_masked;
+}
+
 int64_t sdei_pe_mask(void)
 {
 	int64_t ret = 0;
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index 01cc131..bbc9f73 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -910,25 +910,54 @@
 /* Send a signal to another SDEI client PE */
 static int sdei_signal(int ev_num, uint64_t target_pe)
 {
+	unsigned int i;
 	sdei_ev_map_t *map;
+	sdei_ev_map_t *map_priv;
+	sdei_entry_t *se;
 
 	/* Only event 0 can be signalled */
-	if (ev_num != SDEI_EVENT_0)
+	if (ev_num != SDEI_EVENT_0) {
 		return SDEI_EINVAL;
+	}
 
 	/* Find mapping for event 0 */
 	map = find_event_map(SDEI_EVENT_0);
-	if (map == NULL)
+	if (map == NULL) {
 		return SDEI_EINVAL;
+	}
 
 	/* The event must be signalable */
-	if (!is_event_signalable(map))
+	if (!is_event_signalable(map)) {
 		return SDEI_EINVAL;
+	}
 
 	/* Validate target */
-	if (!is_valid_mpidr(target_pe))
+	if (!is_valid_mpidr(target_pe)) {
 		return SDEI_EINVAL;
+	}
 
+	/* The event must be unmasked */
+	if (sdei_is_target_pe_masked(target_pe)) {
+		return SDEI_EINVAL;
+	}
+
+	/* The event must be registered and enabled */
+	if (is_event_private(map)) {
+		map_priv = SDEI_PRIVATE_MAPPING()->map;
+		for (i = 0; i < SDEI_PRIVATE_MAPPING()->num_maps; i++) {
+			if (map_priv->ev_num == SDEI_EVENT_0) {
+				se = get_event_entry_target_pe((long int) i,
+				(unsigned int) SDEI_PRIVATE_MAPPING()->num_maps, target_pe);
+				if (!(GET_EV_STATE((se), REGISTERED))) {
+					return SDEI_EINVAL;
+				}
+				if (!(GET_EV_STATE((se), ENABLED))) {
+					return SDEI_EINVAL;
+				}
+			}
+			map_priv++;
+		}
+	}
 	/* Raise SGI. Platform will validate target_pe */
 	plat_ic_raise_el3_sgi((int) map->intr, (u_register_t) target_pe);
 
diff --git a/services/std_svc/sdei/sdei_private.h b/services/std_svc/sdei/sdei_private.h
index 44a7301..d48db46 100644
--- a/services/std_svc/sdei/sdei_private.h
+++ b/services/std_svc/sdei/sdei_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -232,13 +232,15 @@
 
 sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared);
 sdei_ev_map_t *find_event_map(int ev_num);
-sdei_entry_t *get_event_entry(sdei_ev_map_t *map);
+sdei_entry_t *get_event_entry(const sdei_ev_map_t *map);
+sdei_entry_t *get_event_entry_target_pe(long int mapsub, unsigned int nm, uint64_t target_pe);
 
 int64_t sdei_event_context(void *handle, unsigned int param);
 int sdei_event_complete(bool resume, uint64_t pc);
 
-void sdei_pe_unmask(void);
+bool sdei_is_target_pe_masked(uint64_t target_pe);
 int64_t sdei_pe_mask(void);
+void sdei_pe_unmask(void);
 
 int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
 		void *cookie);