Merge "feat(stm32mp1): only fuse monotonic counter on closed devices" into integration
diff --git a/Makefile b/Makefile
index f36b782..3536763 100644
--- a/Makefile
+++ b/Makefile
@@ -100,14 +100,12 @@
 export HOSTCC
 
 CC			:=	${CROSS_COMPILE}gcc
-CPP			:=	${CROSS_COMPILE}cpp
+CPP			:=	${CROSS_COMPILE}gcc -E
 AS			:=	${CROSS_COMPILE}gcc
-AR			:=	${CROSS_COMPILE}ar
+AR			:=	${CROSS_COMPILE}gcc-ar
 LINKER			:=	${CROSS_COMPILE}ld
 OC			:=	${CROSS_COMPILE}objcopy
 OD			:=	${CROSS_COMPILE}objdump
-NM			:=	${CROSS_COMPILE}nm
-PP			:=	${CROSS_COMPILE}gcc -E
 DTC			:=	dtc
 
 # Use ${LD}.bfd instead if it exists (as absolute path or together with $PATH).
@@ -187,7 +185,6 @@
 	endif
 
 	CPP		:=	$(CC) -E $(TF_CFLAGS_$(ARCH))
-	PP		:=	$(CC) -E $(TF_CFLAGS_$(ARCH))
 	AS		:=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
 else ifneq ($(findstring gcc,$(notdir $(CC))),)
 	ifeq ($(ENABLE_LTO),1)
@@ -356,6 +353,7 @@
 # LD = gcc (used when GCC LTO is enabled)
 else ifneq ($(findstring gcc,$(notdir $(LD))),)
 	# Pass ld options with Wl or Xlinker switches
+	TF_LDFLAGS		+=	$(call ld_option,-Xlinker --no-warn-rwx-segments)
 	TF_LDFLAGS		+=	-Wl,--fatal-warnings -O1
 	TF_LDFLAGS		+=	-Wl,--gc-sections
 
@@ -1258,6 +1256,7 @@
 	ENABLE_FEAT_AMU \
 	ENABLE_FEAT_AMUv1p1 \
 	ENABLE_FEAT_CSV2_2 \
+	ENABLE_FEAT_CSV2_3 \
 	ENABLE_FEAT_DIT \
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_FGT \
@@ -1413,6 +1412,7 @@
 	ENABLE_FEAT_SEL2 \
 	ENABLE_FEAT_VHE \
 	ENABLE_FEAT_CSV2_2 \
+	ENABLE_FEAT_CSV2_3 \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_TCR2 \
 	ENABLE_FEAT_S2PIE \
diff --git a/changelog.yaml b/changelog.yaml
index f67ad29..35ffaa8 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -774,6 +774,9 @@
       - title: PSCI
         scope: psci
 
+      - title: ROMlib
+        scope: romlib
+
       - title: GPT
         scope: gpt
 
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 49b5360..57d6ae0 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -204,6 +204,8 @@
 		      "S1POE", 1, 1);
 	check_feature(ENABLE_FEAT_MTE_PERM, read_feat_mte_perm_id_field(),
 		      "MTE_PERM", 1, 1);
+	check_feature(ENABLE_FEAT_CSV2_3, read_feat_csv2_id_field(),
+		      "CSV2_3", 3, 3);
 
 	/* v9.0 features */
 	check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
diff --git a/docs/about/contact.rst b/docs/about/contact.rst
index 4f482bd..bb73dfe 100644
--- a/docs/about/contact.rst
+++ b/docs/about/contact.rst
@@ -36,9 +36,8 @@
 Issue Tracker
 ^^^^^^^^^^^^^
 
-Bug reports may be filed on the `issue tracker`_ on the TrustedFirmware.org
-website. Using this tracker gives everyone visibility of the known issues in
-TF-A.
+Bug reports may be filed on the `issue tracker`_ on Github. Using this tracker
+gives everyone visibility of the known issues in TF-A.
 
 Arm Licensees
 ^^^^^^^^^^^^^
@@ -46,7 +45,7 @@
 Arm licensees have an additional support conduit - they may contact Arm directly
 via their partner managers.
 
-.. _`issue tracker`: https://developer.trustedfirmware.org
+.. _`issue tracker`: https://github.com/TrustedFirmware-A/trusted-firmware-a/issues
 .. _`TF-A development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
 .. _`TF-A-Tests development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a-tests.lists.trustedfirmware.org/
 .. _`summary of all the lists`: https://lists.trustedfirmware.org/mailman3/lists/
diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst
index 07637dd..9d85bef 100644
--- a/docs/components/granule-protection-tables-design.rst
+++ b/docs/components/granule-protection-tables-design.rst
@@ -80,8 +80,8 @@
 below.
 
 In the reference implementation for FVP models, you can find an example of PAS
-region definitions in the file ``include/plat/arm/common/arm_pas_def.h``. Table
-creation API calls can be found in ``plat/arm/common/arm_bl2_setup.c`` and
+region definitions in the file ``plat/arm/board/fvp/include/fvp_pas_def.h``.
+Table creation API calls can be found in ``plat/arm/common/arm_common.c`` and
 runtime initialization API calls can be seen in
 ``plat/arm/common/arm_bl31_setup.c``.
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index b859924..cc20261 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -188,12 +188,12 @@
 -  ``CTX_INCLUDE_NEVE_REGS``: Numeric value, when set will cause the Armv8.4-NV
    registers to be saved/restored when entering/exiting an EL2 execution
    context. This flag can take values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. Default value is 0.
+   ``ENABLE_FEAT`` mechanism. Default value is 0.
 
 -  ``CTX_INCLUDE_PAUTH_REGS``: Numeric value to enable the Pointer
    Authentication for Secure world. This will cause the ARMv8.3-PAuth registers
    to be included when saving and restoring the CPU context as part of world
-   switch. This flag can take values 0 to 2, to align with ``FEATURE_DETECTION``
+   switch. This flag can take values 0 to 2, to align with ``ENABLE_FEAT``
    mechanism. Default value is 0.
 
    Note that Pointer Authentication is enabled for Non-secure world irrespective
@@ -214,7 +214,7 @@
 
 -  ``DISABLE_MTPMU``: Numeric option to disable ``FEAT_MTPMU`` (Multi Threaded
    PMU). ``FEAT_MTPMU`` is an optional feature available on Armv8.6 onwards.
-   This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
+   This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. Default is ``0``.
 
 -  ``DYN_DISABLE_AUTH``: Provides the capability to dynamically disable Trusted
@@ -261,9 +261,35 @@
    builds, but this behaviour can be overridden in each platform's Makefile or
    in the build command line.
 
+-  ``ENABLE_FEAT``
+   The Arm architecture defines several architecture extension features,
+   named FEAT_xxx in the architecure manual. Some of those features require
+   setup code in higher exception levels, other features might be used by TF-A
+   code itself.
+   Most of the feature flags defined in the TF-A build system permit to take
+   the values 0, 1 or 2, with the following meaning:
+
+   ::
+
+     ENABLE_FEAT_* = 0: Feature is disabled statically at compile time.
+     ENABLE_FEAT_* = 1: Feature is enabled unconditionally at compile time.
+     ENABLE_FEAT_* = 2: Feature is enabled, but checked at runtime.
+
+   When setting the flag to 0, the feature is disabled during compilation,
+   and the compiler's optimisation stage and the linker will try to remove
+   as much of this code as possible.
+   If it is defined to 1, the code will use the feature unconditionally, so the
+   CPU is expected to support that feature. The FEATURE_DETECTION debug
+   feature, if enabled, will verify this.
+   If the feature flag is set to 2, support for the feature will be compiled
+   in, but its existence will be checked at runtime, so it works on CPUs with
+   or without the feature. This is mostly useful for platforms which either
+   support multiple different CPUs, or where the CPU is configured at runtime,
+   like in emulators.
+
 -  ``ENABLE_FEAT_AMU``: Numeric value to enable Activity Monitor Unit
    extensions. This flag can take the values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. This is an optional architectural feature
+   ``ENABLE_FEAT`` mechanism. This is an optional architectural feature
    available on v8.4 onwards. Some v8.2 implementations also implement an AMU
    and this option can be used to enable this feature on those systems as well.
    This flag can take the values 0 to 2, the default is 0.
@@ -271,52 +297,59 @@
 -  ``ENABLE_FEAT_AMUv1p1``: Numeric value to enable the ``FEAT_AMUv1p1``
    extension. ``FEAT_AMUv1p1`` is an optional feature available on Arm v8.6
    onwards. This flag can take the values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
+   ``ENABLE_FEAT`` mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_CSV2_2``: Numeric value to enable the ``FEAT_CSV2_2``
    extension. It allows access to the SCXTNUM_EL2 (Software Context Number)
    register during EL2 context save/restore operations. ``FEAT_CSV2_2`` is an
    optional feature available on Arm v8.0 onwards. This flag can take values
-   0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
+   0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``.
 
+-  ``ENABLE_FEAT_CSV2_3``: Numeric value to enable support for ``FEAT_CSV2_3``
+   extension. This feature is supported in AArch64 state only and is an optional
+   feature available in Arm v8.0 implementations.
+   ``FEAT_CSV2_3`` implies the implementation of ``FEAT_CSV2_2``.
+   The flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
 -  ``ENABLE_FEAT_DIT``: Numeric value to enable ``FEAT_DIT`` (Data Independent
    Timing) extension. It allows setting the ``DIT`` bit of PSTATE in EL3.
    ``FEAT_DIT`` is a mandatory  architectural feature and is enabled from v8.4
    and upwards. This flag can take the values 0 to 2, to align  with the
-   ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
+   ``ENABLE_FEAT`` mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_ECV``: Numeric value to enable support for the Enhanced Counter
    Virtualization feature, allowing for access to the CNTPOFF_EL2 (Counter-timer
    Physical Offset register) during EL2 to EL3 context save/restore operations.
    Its a mandatory architectural feature and is enabled from v8.6 and upwards.
-   This flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps)
    feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained
    Read Trap Register) during EL2 to EL3 context save/restore operations.
    Its a mandatory architectural feature and is enabled from v8.6 and upwards.
-   This flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_HCX``: Numeric value to set the bit SCR_EL3.HXEn in EL3 to
    allow access to HCRX_EL2 (extended hypervisor control register) from EL2 as
    well as adding HCRX_EL2 to the EL2 context save/restore operations. Its a
    mandatory architectural feature and is enabled from v8.7 and upwards. This
-   flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_MTE``: Numeric value to enable Memory Tagging Extension
    if the platform wants to use this feature in the Secure world and MTE is
    enabled at ELX. This flag can take values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
+   ``ENABLE_FEAT`` mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_MTE_PERM``: Numeric value to enable support for
    ``FEAT_MTE_PERM``, which introduces Allocation tag access permission to
    memory region attributes. ``FEAT_MTE_PERM`` is a optional architectural
    feature available from v8.9 and upwards.  This flag can take the values 0 to
-   2, to align  with the ``FEATURE_DETECTION`` mechanism. Default value is
+   2, to align  with the ``ENABLE_FEAT`` mechanism. Default value is
    ``0``.
 
 -  ``ENABLE_FEAT_PAN``: Numeric value to enable the ``FEAT_PAN`` (Privileged
@@ -324,17 +357,17 @@
    permission fault for any privileged data access from EL1/EL2 to virtual
    memory address, accessible at EL0, provided (HCR_EL2.E2H=1). It is a
    mandatory architectural feature and is enabled from v8.1 and upwards. This
-   flag can take values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   flag can take 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 ``FEATURE_DETECTION``
+   flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_RNG_TRAP``: Numeric value to enable the ``FEAT_RNG_TRAP``
    extension. This feature is only supported in AArch64 state. This flag can
-   take values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
+   take values 0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``. ``FEAT_RNG_TRAP`` is an optional feature from
    Armv8.5 onwards.
 
@@ -346,13 +379,13 @@
 
 -  ``ENABLE_FEAT_SEL2``: Numeric value to enable the ``FEAT_SEL2`` (Secure EL2)
    extension. ``FEAT_SEL2`` is a mandatory feature available on Arm v8.4.
-   This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
+   This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. Default is ``0``.
 
 -  ``ENABLE_FEAT_TWED``: Numeric value to enable the ``FEAT_TWED`` (Delayed
    trapping of WFE Instruction) extension. ``FEAT_TWED`` is a optional feature
    available on Arm v8.6. This flag can take values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. Default is ``0``.
+   ``ENABLE_FEAT`` mechanism. Default is ``0``.
 
     When ``ENABLE_FEAT_TWED`` is set to ``1``, WFE instruction trapping gets
     delayed by the amount of value in ``TWED_DELAY``.
@@ -361,40 +394,40 @@
    Host Extensions) extension. It allows access to CONTEXTIDR_EL2 register
    during EL2 context save/restore operations.``FEAT_VHE`` is a mandatory
    architectural feature and is enabled from v8.1 and upwards. It can take
-   values 0 to 2, to align  with the ``FEATURE_DETECTION`` mechanism.
+   values 0 to 2, to align  with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``.
 
 -  ``ENABLE_FEAT_TCR2``: Numeric value to set the bit SCR_EL3.ENTCR2 in EL3 to
    allow access to TCR2_EL2 (extended translation control) from EL2 as
    well as adding TCR2_EL2 to the EL2 context save/restore operations. Its a
    mandatory architectural feature and is enabled from v8.9 and upwards. This
-   flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_S2PIE``: Numeric value to enable support for FEAT_S2PIE
    at EL2 and below, and context switch relevant registers.  This flag
-   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_S1PIE``: Numeric value to enable support for FEAT_S1PIE
    at EL2 and below, and context switch relevant registers.  This flag
-   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_S2POE``: Numeric value to enable support for FEAT_S2POE
    at EL2 and below, and context switch relevant registers.  This flag
-   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_S1POE``: Numeric value to enable support for FEAT_S1POE
    at EL2 and below, and context switch relevant registers.  This flag
-   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_GCS``: Numeric value to set the bit SCR_EL3.GCSEn in EL3 to
    allow use of Guarded Control Stack from EL2 as well as adding the GCS
    registers to the EL2 context save/restore operations. This flag can take
-   the values 0 to 2, to align  with the ``FEATURE_DETECTION`` mechanism.
+   the values 0 to 2, to align  with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``.
 
 -  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
@@ -407,7 +440,7 @@
    various ELs can assign themselves to desired partition to control their
    performance aspects.
 
-   This flag can take values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   This flag can take values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. When this option is set to ``1`` or ``2``, EL3 allows lower ELs to
    access their own MPAM registers without trapping into EL3. This option
    doesn't make use of partitioning in EL3, however. Platform initialisation
@@ -448,7 +481,7 @@
 
 -  ``ENABLE_SPE_FOR_NS`` : Numeric value to enable Statistical Profiling
    extensions. This is an optional architectural feature for AArch64.
-   This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+   This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. The default is 2 but is automatically disabled when the target
    architecture is AArch32.
 
@@ -462,7 +495,7 @@
    compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
    assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS``
    enabled.  This flag can take the values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. At this time, this build option cannot be
+   ``ENABLE_FEAT`` mechanism. At this time, this build option cannot be
    used on systems that have SPM_MM enabled. The default is 1.
 
 -  ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world.
@@ -1078,26 +1111,26 @@
 - ``ENABLE_BRBE_FOR_NS``: Numeric value to enable access to the branch record
   buffer registers from NS ELs when FEAT_BRBE is implemented. BRBE is an
   optional architectural feature for AArch64. This flag can take the values
-  0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. The default is 0
+  0 to 2, to align with the ``ENABLE_FEAT`` mechanism. The default is 0
   and it is automatically disabled when the target architecture is AArch32.
 
 - ``ENABLE_TRBE_FOR_NS``: Numeric value to enable access of trace buffer
   control registers from NS ELs, NS-EL2 or NS-EL1(when NS-EL2 is implemented
   but unused) when FEAT_TRBE is implemented. TRBE is an optional architectural
   feature for AArch64. This flag can take the values  0 to 2, to align with the
-  ``FEATURE_DETECTION`` mechanism. The default is 0 and it is automatically
+  ``ENABLE_FEAT`` mechanism. The default is 0 and it is automatically
   disabled when the target architecture is AArch32.
 
 - ``ENABLE_SYS_REG_TRACE_FOR_NS``: Numeric value to enable trace system
   registers access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented
   but unused). This feature is available if trace unit such as ETMv4.x, and
   ETE(extending ETM feature) is implemented. This flag can take the values
-  0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. The default is 0.
+  0 to 2, to align with the ``ENABLE_FEAT`` mechanism. The default is 0.
 
 - ``ENABLE_TRF_FOR_NS``: Numeric value to enable trace filter control registers
   access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented but unused),
   if FEAT_TRF is implemented. This flag can take the values 0 to 2, to align
-  with the ``FEATURE_DETECTION`` mechanism. This flag is disabled by default.
+  with the ``ENABLE_FEAT`` mechanism. This flag is disabled by default.
 
 - ``CONDITIONAL_CMO``: Boolean option to enable call to platform-defined routine
   ``plat_can_cmo`` which will return zero if cache management operations should
@@ -1225,7 +1258,7 @@
 
 -  ``ENABLE_RME``: Numeric value to enable support for the ARMv9 Realm
    Management Extension. This flag can take the values 0 to 2, to align with
-   the ``FEATURE_DETECTION`` mechanism. Default value is 0.
+   the ``ENABLE_FEAT`` mechanism. Default value is 0.
 
 -  ``ENABLE_SME_FOR_NS``: Numeric value to enable Scalable Matrix Extension
    (SME), SVE, and FPU/SIMD for the non-secure world only. These features share
@@ -1235,7 +1268,7 @@
    superset of SVE. SME is an optional architectural feature for AArch64.
    At this time, this build option cannot be used on systems that have
    SPD=spmd/SPM_MM and atempting to build with this option will fail.
-   This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+   This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. Default is 0.
 
 -  ``ENABLE_SME2_FOR_NS``: Numeric value to enable Scalable Matrix Extension
@@ -1243,7 +1276,7 @@
    architectural feature for AArch64.
    This should be set along with ENABLE_SME_FOR_NS=1, if not, the default SME
    accesses will still be trapped. This flag can take the values 0 to 2, to
-   align with the ``FEATURE_DETECTION`` mechanism. Default is 0.
+   align with the ``ENABLE_FEAT`` mechanism. Default is 0.
 
 -  ``ENABLE_SME_FOR_SWD``: Boolean option to enable the Scalable Matrix
    Extension for secure world. Used along with SVE and FPU/SIMD.
@@ -1257,41 +1290,16 @@
    must not be used if ``SPMC_AT_EL3`` is enabled.
 
 -  ``FEATURE_DETECTION``: Boolean option to enable the architectural features
-   detection mechanism. It detects whether the Architectural features enabled
-   through feature specific build flags are supported by the PE or not by
-   validating them either at boot phase or at runtime based on the value
-   possessed by the feature flag (0 to 2) and report error messages at an early
-   stage. This flag will also enable errata ordering checking for ``DEBUG``
-   builds.
-
-   This prevents and benefits us from EL3 runtime exceptions during context save
-   and restore routines guarded by these build flags. Henceforth validating them
-   before their usage provides more control on the actions taken under them.
-
-   The mechanism permits the build flags to take values 0, 1 or 2 and
-   evaluates them accordingly.
-
-   Lets consider ``ENABLE_FEAT_HCX``, build flag for ``FEAT_HCX`` as an example:
-
-   ::
-
-     ENABLE_FEAT_HCX = 0: Feature disabled statically at compile time.
-     ENABLE_FEAT_HCX = 1: Feature Enabled and the flag is validated at boottime.
-     ENABLE_FEAT_HCX = 2: Feature Enabled and the flag is validated at runtime.
-
-   In the above example, if the feature build flag, ``ENABLE_FEAT_HCX`` set to
-   0, feature is disabled statically during compilation. If it is defined as 1,
-   feature is validated, wherein FEAT_HCX is detected at boot time. In case not
-   implemented by the PE, a hard panic is generated. Finally, if the flag is set
-   to 2, feature is validated at runtime.
-
-   Note that the entire implementation is divided into two phases, wherein as
-   as part of phase-1 we are supporting the values 0,1. Value 2 is currently not
-   supported and is planned to be handled explicilty in phase-2 implementation.
+   verification mechanism. This is a debug feature that compares the
+   architectural features enabled through the feature specific build flags
+   (ENABLE_FEAT_xxx) with the features actually available on the CPU running,
+   and reports any discrepancies.
+   This flag will also enable errata ordering checking for ``DEBUG`` builds.
 
-   ``FEATURE_DETECTION`` macro is disabled by default. Platforms can explicitly
-   make use of this by mechanism, by enabling it to validate whether they have
-   set their build flags properly at an early phase.
+   It is expected that this feature is only used for flexible platforms like
+   software emulators, or for hardware platforms at bringup time, to verify
+   that the configured feature set matches the CPU.
+   The ``FEATURE_DETECTION`` macro is disabled by default.
 
 -  ``PSA_CRYPTO``: Boolean option for enabling MbedTLS PSA crypto APIs support.
    The platform will use PSA compliant Crypto APIs during authentication and
diff --git a/docs/process/commit-style.rst b/docs/process/commit-style.rst
index d7e937b..c287599 100644
--- a/docs/process/commit-style.rst
+++ b/docs/process/commit-style.rst
@@ -149,5 +149,5 @@
 .. _Conventional Commits: https://www.conventionalcommits.org/en/v1.0.0
 .. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html
 .. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html
-.. _issue: https://developer.trustedfirmware.org/project/board/1/
+.. _issue: https://github.com/TrustedFirmware-A/trusted-firmware-a/issues
 .. _quick summary: https://www.conventionalcommits.org/en/v1.0.0/#summary
diff --git a/docs/process/security.rst b/docs/process/security.rst
index c49ca6e..1e7ac2e 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -76,7 +76,7 @@
 |  |TFV-11| |  A Malformed SDEI SMC can cause out of bound memory read         |
 +-----------+------------------------------------------------------------------+
 
-.. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
+.. _issue tracker: https://github.com/TrustedFirmware-A/trusted-firmware-a/issues
 .. _mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
 
 .. |TFV-1| replace:: :ref:`Advisory TFV-1 (CVE-2016-10319)`
diff --git a/drivers/st/bsec/bsec3.c b/drivers/st/bsec/bsec3.c
new file mode 100644
index 0000000..a803a3a
--- /dev/null
+++ b/drivers/st/bsec/bsec3.c
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/st/bsec.h>
+#include <drivers/st/bsec3_reg.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#define BSEC_IP_VERSION_1_0	U(0x10)
+#define BSEC_IP_ID_3		U(0x100033)
+
+#define MAX_NB_TRIES		U(3)
+
+/*
+ * IP configuration
+ */
+#define BSEC_OTP_MASK			GENMASK_32(4, 0)
+#define BSEC_OTP_BANK_SHIFT		U(5)
+#define BSEC_TIMEOUT_VALUE		U(0x800000) /* ~7sec @1.2GHz */
+
+/* Magic use to indicated valid SHADOW = 'B' 'S' 'E' 'C' */
+#define BSEC_MAGIC			U(0x42534543)
+
+#define OTP_MAX_SIZE			(STM32MP2_OTP_MAX_ID + U(1))
+
+struct bsec_shadow {
+	uint32_t magic;
+	uint32_t state;
+	uint32_t value[OTP_MAX_SIZE];
+	uint32_t status[OTP_MAX_SIZE];
+};
+
+static uint32_t otp_bank(uint32_t otp)
+{
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	return (otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT;
+}
+
+static uint32_t otp_bit_mask(uint32_t otp)
+{
+	return BIT(otp & BSEC_OTP_MASK);
+}
+
+/*
+ * bsec_get_status: return status register value.
+ */
+static uint32_t bsec_get_status(void)
+{
+	return mmio_read_32(BSEC_BASE + BSEC_OTPSR);
+}
+
+/*
+ * bsec_get_version: return BSEC version.
+ */
+static uint32_t bsec_get_version(void)
+{
+	return mmio_read_32(BSEC_BASE + BSEC_VERR) & BSEC_VERR_MASK;
+}
+
+/*
+ * bsec_get_id: return BSEC ID.
+ */
+static uint32_t bsec_get_id(void)
+{
+	return mmio_read_32(BSEC_BASE + BSEC_IPIDR);
+}
+
+static bool is_fuse_shadowed(uint32_t otp)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+	uint32_t bank_value;
+
+	bank_value = mmio_read_32(BSEC_BASE + BSEC_SFSR(bank));
+
+	if ((bank_value & otp_mask) != 0U) {
+		return true;
+	}
+
+	return false;
+}
+
+static void poll_otp_status_busy(void)
+{
+	uint32_t timeout = BSEC_TIMEOUT_VALUE;
+
+	while (((bsec_get_status() & BSEC_OTPSR_BUSY) != 0U) && (timeout != 0U)) {
+		timeout--;
+	}
+
+	if ((bsec_get_status() & BSEC_OTPSR_BUSY) != 0U) {
+		ERROR("BSEC timeout\n");
+		panic();
+	}
+}
+
+static uint32_t check_read_error(uint32_t otp)
+{
+	uint32_t status = bsec_get_status();
+
+	if ((status & BSEC_OTPSR_SECF) != 0U) {
+		VERBOSE("BSEC read %u single error correction detected\n", otp);
+	}
+
+	if ((status & BSEC_OTPSR_PPLF) != 0U) {
+		VERBOSE("BSEC read %u permanent programming lock detected.\n", otp);
+	}
+
+	if ((status & BSEC_OTPSR_PPLMF) != 0U) {
+		ERROR("BSEC read %u error 0x%x\n", otp, status);
+		return BSEC_ERROR;
+	}
+
+	if ((status & (BSEC_OTPSR_DISTURBF | BSEC_OTPSR_DEDF | BSEC_OTPSR_AMEF)) != 0U) {
+		ERROR("BSEC read %u error 0x%x with invalid FVR\n", otp, status);
+		return BSEC_RETRY;
+	}
+
+	return BSEC_OK;
+}
+
+static uint32_t check_program_error(uint32_t otp)
+{
+	uint32_t status = bsec_get_status();
+
+	if ((status & BSEC_OTPSR_PROGFAIL) != 0U) {
+		ERROR("BSEC program %u error 0x%x\n", otp, status);
+		return BSEC_RETRY;
+	}
+
+	return BSEC_OK;
+}
+
+static void check_reset_error(void)
+{
+	uint32_t status = bsec_get_status();
+
+	/* check initial status reporting */
+	if ((status & BSEC_OTPSR_BUSY) != 0U) {
+		VERBOSE("BSEC reset and busy when OTPSR read\n");
+	}
+	if ((status & BSEC_OTPSR_HIDEUP) != 0U) {
+		VERBOSE("BSEC upper fuse are not accessible (HIDEUP)\n");
+	}
+	if ((status & BSEC_OTPSR_OTPSEC) != 0U) {
+		VERBOSE("BSEC reset single error correction detected\n");
+	}
+	if ((status & BSEC_OTPSR_OTPNVIR) == 0U) {
+		VERBOSE("BSEC reset first fuse word 0 is detected zero\n");
+	}
+	if ((status & BSEC_OTPSR_OTPERR) != 0U) {
+		ERROR("BSEC reset critical error 0x%x\n", status);
+		panic();
+	}
+	if ((status & BSEC_OTPSR_FUSEOK) != BSEC_OTPSR_FUSEOK) {
+		ERROR("BSEC reset critical error 0x%x\n", status);
+		panic();
+	}
+}
+
+static bool is_bsec_write_locked(void)
+{
+	return (mmio_read_32(BSEC_BASE + BSEC_LOCKR) & BSEC_LOCKR_GWLOCK_MASK) != 0U;
+}
+
+/*
+ * bsec_probe: initialize BSEC driver.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_probe(void)
+{
+	uint32_t version = bsec_get_version();
+	uint32_t id = bsec_get_id();
+
+	if ((version != BSEC_IP_VERSION_1_0) || (id != BSEC_IP_ID_3)) {
+		ERROR("%s: version = 0x%x, id = 0x%x\n", __func__, version, id);
+		panic();
+	}
+
+	check_reset_error();
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+static uint32_t bsec_shadow_register(uint32_t otp)
+{
+	uint32_t result;
+	uint32_t i;
+	bool value;
+
+	result = bsec_read_sr_lock(otp, &value);
+	if (result != BSEC_OK) {
+		WARN("BSEC: %u Sticky-read bit read Error %u\n", otp, result);
+	} else if (value) {
+		VERBOSE("BSEC: OTP %u is locked and will not be refreshed\n", otp);
+	}
+
+	for (i = 0U; i < MAX_NB_TRIES; i++) {
+		mmio_write_32(BSEC_BASE + BSEC_OTPCR, otp);
+
+		poll_otp_status_busy();
+
+		result = check_read_error(otp);
+		if (result != BSEC_RETRY) {
+			break;
+		}
+	}
+
+	return result;
+}
+
+/*
+ * bsec_write_otp: write a value in shadow OTP.
+ * val: value to program.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
+{
+	bool state;
+	uint32_t result;
+
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	if (!is_fuse_shadowed(otp)) {
+		return BSEC_ERROR;
+	}
+
+	if (is_bsec_write_locked()) {
+		return BSEC_WRITE_LOCKED;
+	}
+
+	result = bsec_read_sw_lock(otp, &state);
+	if (result != BSEC_OK) {
+		WARN("Shadow register is SW locked\n");
+		return result;
+	}
+
+	mmio_write_32(BSEC_BASE + BSEC_FVR(otp), val);
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_program_otp: program a bit in SAFMEM after the prog.
+ *	The OTP data is not refreshed.
+ * val: value to program.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
+{
+	uint32_t result;
+	uint32_t i;
+	bool value;
+
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	if (is_bsec_write_locked() == true) {
+		return BSEC_WRITE_LOCKED;
+	}
+
+	result = bsec_read_sp_lock(otp, &value);
+	if (result != BSEC_OK) {
+		WARN("BSEC: %u Sticky-prog bit read Error %u\n", otp, result);
+	} else if (value) {
+		WARN("BSEC: OTP locked, prog will be ignored\n");
+		return BSEC_WRITE_LOCKED;
+	}
+
+	mmio_write_32(BSEC_BASE + BSEC_WDR, val);
+
+	for (i = 0U; i < MAX_NB_TRIES; i++) {
+		mmio_write_32(BSEC_BASE + BSEC_OTPCR, otp | BSEC_OTPCR_PROG);
+
+		poll_otp_status_busy();
+
+		result = check_program_error(otp);
+		if (result != BSEC_RETRY) {
+			break;
+		}
+	}
+
+	return result;
+}
+
+/*
+ * bsec_read_debug_conf: read debug configuration.
+ */
+uint32_t bsec_read_debug_conf(void)
+{
+	return mmio_read_32(BSEC_BASE + BSEC_DENR);
+}
+
+static uint32_t bsec_lock_register_set(uint32_t offset, uint32_t mask)
+{
+	uint32_t value = mmio_read_32(BSEC_BASE + offset);
+
+	/* The lock is already set */
+	if ((value & mask) != 0U) {
+		return BSEC_OK;
+	}
+
+	if (is_bsec_write_locked()) {
+		return BSEC_WRITE_LOCKED;
+	}
+
+	value |= mask;
+
+	mmio_write_32(BSEC_BASE + offset, value);
+
+	return BSEC_OK;
+}
+
+static bool bsec_lock_register_get(uint32_t offset, uint32_t mask)
+{
+	uint32_t value = mmio_read_32(BSEC_BASE + offset);
+
+	return (value & mask) != 0U;
+}
+
+/*
+ * bsec_set_sr_lock: set shadow-read lock.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_sr_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	return bsec_lock_register_set(BSEC_SRLOCK(bank), otp_mask);
+}
+
+/*
+ * bsec_read_sr_lock: read shadow-read lock.
+ * otp: OTP number.
+ * value: read value (true or false).
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_sr_lock(uint32_t otp, bool *value)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	assert(value != NULL);
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	*value = bsec_lock_register_get(BSEC_SRLOCK(bank), otp_mask);
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_set_sw_lock: set shadow-write lock.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_sw_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	return bsec_lock_register_set(BSEC_SWLOCK(bank), otp_mask);
+}
+
+/*
+ * bsec_read_sw_lock: read shadow-write lock.
+ * otp: OTP number.
+ * value: read value (true or false).
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_sw_lock(uint32_t otp, bool *value)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	assert(value != NULL);
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	*value = bsec_lock_register_get(BSEC_SWLOCK(bank), otp_mask);
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_set_sp_lock: set shadow-program lock.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_sp_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	return bsec_lock_register_set(BSEC_SPLOCK(bank), otp_mask);
+}
+
+/*
+ * bsec_read_sp_lock: read shadow-program lock.
+ * otp: OTP number.
+ * value: read value (true or false).
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_sp_lock(uint32_t otp, bool *value)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	assert(value != NULL);
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	*value = bsec_lock_register_get(BSEC_SPLOCK(bank), otp_mask);
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_get_secure_state: read state in BSEC status register.
+ * return: secure state
+ */
+uint32_t bsec_get_secure_state(void)
+{
+	uint32_t state = BSEC_STATE_INVALID;
+	uint32_t status = bsec_get_status();
+	uint32_t bsec_sr = mmio_read_32(BSEC_BASE + BSEC_SR);
+
+	if ((status & BSEC_OTPSR_FUSEOK) == BSEC_OTPSR_FUSEOK) {
+		/* NVSTATE is only valid if FUSEOK */
+		uint32_t nvstates = (bsec_sr & BSEC_SR_NVSTATE_MASK) >> BSEC_SR_NVSTATE_SHIFT;
+
+		if (nvstates == BSEC_SR_NVSTATE_OPEN) {
+			state = BSEC_STATE_SEC_OPEN;
+		} else if (nvstates == BSEC_SR_NVSTATE_CLOSED) {
+			state = BSEC_STATE_SEC_CLOSED;
+		} else {
+			VERBOSE("%s nvstates = %u\n", __func__, nvstates);
+		}
+	}
+
+	return state;
+}
+
+/*
+ * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
+ * val: read value.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp)
+{
+	assert(val != NULL);
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	*val = 0U;
+
+	if (is_bsec_write_locked()) {
+		return BSEC_WRITE_LOCKED;
+	}
+
+	if (!is_fuse_shadowed(otp)) {
+		uint32_t result = bsec_shadow_register(otp);
+
+		if (result != BSEC_OK) {
+			ERROR("BSEC: %u Shadowing Error %u\n", otp, result);
+			return result;
+		}
+	}
+
+	*val = mmio_read_32(BSEC_BASE + BSEC_FVR(otp));
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_read_otp: read an OTP data value.
+ * val: read value.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
+{
+	assert(val != NULL);
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	return bsec_shadow_read_otp(val, otp);
+}
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index acc1751..a2063f1 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -137,6 +137,7 @@
 static inline bool is_feat_ecv_supported(void) { return false; }
 static inline bool is_feat_ecv_v2_supported(void) { return false; }
 static inline bool is_feat_csv2_2_supported(void) { return false; }
+static inline bool is_feat_csv2_3_supported(void) { return false; }
 static inline bool is_feat_ras_supported(void) { return false; }
 
 /* The following features are supported in AArch64 only. */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index e9d22b6..b88d6c6 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -197,6 +197,7 @@
 #define ID_AA64PFR0_CSV2_MASK			ULL(0xf)
 #define ID_AA64PFR0_CSV2_LENGTH			U(4)
 #define ID_AA64PFR0_CSV2_2_SUPPORTED		ULL(0x2)
+#define ID_AA64PFR0_CSV2_3_SUPPORTED		ULL(0x3)
 
 #define ID_AA64PFR0_FEAT_RME_SHIFT		U(52)
 #define ID_AA64PFR0_FEAT_RME_MASK		ULL(0xf)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index deea6d4..c053c4d 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -187,10 +187,28 @@
 	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB_SHIFT);
 }
 
-/* FEAT_CSV2_2: Cache Speculation Variant 2 */
-CREATE_FEATURE_FUNCS(feat_csv2, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT, 0)
+/*
+ * FEAT_CSV2: Cache Speculation Variant 2. This checks bit fields[56-59]
+ * of id_aa64pfr0_el1 register and can be used to check for below features:
+ * FEAT_CSV2_2: Cache Speculation Variant CSV2_2.
+ * FEAT_CSV2_3: Cache Speculation Variant CSV2_3.
+ * 0b0000 - Feature FEAT_CSV2 is not implemented.
+ * 0b0001 - Feature FEAT_CSV2 is implemented, but FEAT_CSV2_2 and FEAT_CSV2_3
+ *          are not implemented.
+ * 0b0010 - Feature FEAT_CSV2_2 is implemented but FEAT_CSV2_3 is not
+ *          implemented.
+ * 0b0011 - Feature FEAT_CSV2_3 is implemented.
+ */
+static inline unsigned int read_feat_csv2_id_field(void)
+{
+	return (unsigned int)(read_id_aa64pfr0_el1() >>
+		ID_AA64PFR0_CSV2_SHIFT) & ID_AA64PFR0_CSV2_MASK;
+}
+
 CREATE_FEATURE_FUNCS_VER(feat_csv2_2, read_feat_csv2_id_field,
 			 ID_AA64PFR0_CSV2_2_SUPPORTED, ENABLE_FEAT_CSV2_2)
+CREATE_FEATURE_FUNCS_VER(feat_csv2_3, read_feat_csv2_id_field,
+			 ID_AA64PFR0_CSV2_3_SUPPORTED, ENABLE_FEAT_CSV2_3)
 
 /* FEAT_SPE: Statistical Profiling Extension */
 CREATE_FEATURE_FUNCS(feat_spe, id_aa64dfr0_el1, ID_AA64DFR0_PMS_SHIFT,
diff --git a/include/drivers/st/bsec3_reg.h b/include/drivers/st/bsec3_reg.h
new file mode 100644
index 0000000..177e30b
--- /dev/null
+++ b/include/drivers/st/bsec3_reg.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BSEC3_REG_H
+#define BSEC3_REG_H
+
+#include <lib/utils_def.h>
+
+/* BSEC REGISTER OFFSET (base relative) */
+#define BSEC_FVR(x)			(U(0x000) + 4U * (x))
+#define BSEC_SPLOCK(x)			(U(0x800) + 4U * (x))
+#define BSEC_SWLOCK(x)			(U(0x840) + 4U * (x))
+#define BSEC_SRLOCK(x)			(U(0x880) + 4U * (x))
+#define BSEC_OTPVLDR(x)			(U(0x8C0) + 4U * (x))
+#define BSEC_SFSR(x)			(U(0x940) + 4U * (x))
+#define BSEC_OTPCR			U(0xC04)
+#define BSEC_WDR			U(0xC08)
+#define BSEC_SCRATCHR0			U(0xE00)
+#define BSEC_SCRATCHR1			U(0xE04)
+#define BSEC_SCRATCHR2			U(0xE08)
+#define BSEC_SCRATCHR3			U(0xE0C)
+#define BSEC_LOCKR			U(0xE10)
+#define BSEC_JTAGINR			U(0xE14)
+#define BSEC_JTAGOUTR			U(0xE18)
+#define BSEC_DENR			U(0xE20)
+#define BSEC_UNMAPR			U(0xE24)
+#define BSEC_SR				U(0xE40)
+#define BSEC_OTPSR			U(0xE44)
+#define BSEC_WRCR			U(0xF00)
+#define BSEC_HWCFGR			U(0xFF0)
+#define BSEC_VERR			U(0xFF4)
+#define BSEC_IPIDR			U(0xFF8)
+#define BSEC_SIDR			U(0xFFC)
+
+/* BSEC_OTPCR register fields */
+#define BSEC_OTPCR_ADDR_MASK		GENMASK_32(8, 0)
+#define BSEC_OTPCR_ADDR_SHIFT		U(0)
+#define BSEC_OTPCR_PROG			BIT_32(13)
+#define BSEC_OTPCR_PPLOCK		BIT_32(14)
+#define BSEC_OTPCR_LASTCID_MASK		GENMASK_32(21, 19)
+#define BSEC_OTPCR_LASTCID_SHIFT	U(19)
+
+/* BSEC_LOCKR register fields */
+#define BSEC_LOCKR_GWLOCK_MASK		BIT_32(0)
+#define BSEC_LOCKR_GWLOCK_SHIFT		U(0)
+#define BSEC_LOCKR_DENLOCK_MASK		BIT_32(1)
+#define BSEC_LOCKR_DENLOCK_SHIFT	U(1)
+#define BSEC_LOCKR_HKLOCK_MASK		BIT_32(2)
+#define BSEC_LOCKR_HKLOCK_SHIFT		U(2)
+
+/* BSEC_DENR register fields */
+#define BSEC_DENR_LPDBGEN		BIT_32(0)
+#define BSEC_DENR_DBGENA		BIT_32(1)
+#define BSEC_DENR_NIDENA		BIT_32(2)
+#define BSEC_DENR_DEVICEEN		BIT_32(3)
+#define BSEC_DENR_HDPEN			BIT_32(4)
+#define BSEC_DENR_SPIDENA		BIT_32(5)
+#define BSEC_DENR_SPNIDENA		BIT_32(6)
+#define BSEC_DENR_DBGSWEN		BIT_32(7)
+#define BSEC_DENR_DBGENM		BIT_32(8)
+#define BSEC_DENR_NIDENM		BIT_32(9)
+#define BSEC_DENR_SPIDENM		BIT_32(10)
+#define BSEC_DENR_SPNIDENM		BIT_32(11)
+#define BSEC_DENR_CFGSDIS		BIT_32(12)
+#define BSEC_DENR_CP15SDIS_MASK		GENMASK_32(14, 13)
+#define BSEC_DENR_CP15SDIS_SHIFT	U(13)
+#define BSEC_DENR_LPDBGDIS		BIT_32(15)
+#define BSEC_DENR_ALL_MSK		GENMASK_32(15, 0)
+
+/* BSEC_SR register fields */
+#define BSEC_SR_BUSY			BIT_32(0)
+#define BSEC_SR_HVALID			BIT_32(1)
+#define BSEC_SR_RNGERR			BIT_32(2)
+#define BSEC_SR_HKWW_MASK		GENMASK_32(15, 8)
+#define BSEC_SR_HKWW_SHIFT		U(8)
+#define BSEC_SR_NVSTATE_MASK		GENMASK_32(31, 26)
+#define BSEC_SR_NVSTATE_SHIFT		U(26)
+#define BSEC_SR_NVSTATE_OPEN		U(0x16)
+#define BSEC_SR_NVSTATE_CLOSED		U(0x0D)
+#define BSEC_SR_NVSTATE_OTP_LOCKED	U(0x23)
+
+/* BSEC_OTPSR register fields */
+#define BSEC_OTPSR_BUSY			BIT_32(0)
+#define BSEC_OTPSR_FUSEOK		BIT_32(1)
+#define BSEC_OTPSR_HIDEUP		BIT_32(2)
+#define BSEC_OTPSR_OTPNVIR		BIT_32(4)
+#define BSEC_OTPSR_OTPERR		BIT_32(5)
+#define BSEC_OTPSR_OTPSEC		BIT_32(6)
+#define BSEC_OTPSR_PROGFAIL		BIT_32(16)
+#define BSEC_OTPSR_DISTURBF		BIT_32(17)
+#define BSEC_OTPSR_DEDF			BIT_32(18)
+#define BSEC_OTPSR_SECF			BIT_32(19)
+#define BSEC_OTPSR_PPLF			BIT_32(20)
+#define BSEC_OTPSR_PPLMF		BIT_32(21)
+#define BSEC_OTPSR_AMEF			BIT_32(22)
+
+/* BSEC_VERR register fields */
+#define BSEC_VERR_MASK			GENMASK_32(7, 0)
+
+#endif /* BSEC3_REG_H */
diff --git a/include/lib/cpus/aarch64/cortex_a35.h b/include/lib/cpus/aarch64/cortex_a35.h
index cef2960..c82b4eb 100644
--- a/include/lib/cpus/aarch64/cortex_a35.h
+++ b/include/lib/cpus/aarch64/cortex_a35.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,9 @@
 /* Cortex-A35 Main ID register for revision 0 */
 #define CORTEX_A35_MIDR				U(0x410FD040)
 
+/* L2 Extended Control Register */
+#define CORTEX_A35_L2ECTLR_EL1			S3_1_C11_C0_3
+
 /*******************************************************************************
  * CPU Extended Control register specific definitions.
  * CPUECTLR_EL1 is an implementation-specific register.
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 54b184d..c3a88e7 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -150,10 +150,10 @@
 #endif /* (SPD_tspd || SPD_opteed || SPD_spmd) && MEASURED_BOOT */
 
 #if ENABLE_RME
-#define ARM_L1_GPT_ADDR_BASE		(ARM_DRAM1_BASE +		\
+#define ARM_L1_GPT_BASE		(ARM_DRAM1_BASE +		\
 					ARM_DRAM1_SIZE -		\
 					ARM_L1_GPT_SIZE)
-#define ARM_L1_GPT_END			(ARM_L1_GPT_ADDR_BASE +		\
+#define ARM_L1_GPT_END			(ARM_L1_GPT_BASE +		\
 					ARM_L1_GPT_SIZE - 1U)
 
 #define ARM_REALM_BASE			(ARM_EL3_RMM_SHARED_BASE -	\
@@ -343,7 +343,7 @@
 
 
 #define ARM_MAP_GPT_L1_DRAM	MAP_REGION_FLAT(			\
-					ARM_L1_GPT_ADDR_BASE,		\
+					ARM_L1_GPT_BASE,		\
 					ARM_L1_GPT_SIZE,		\
 					MT_MEMORY | MT_RW | EL3_PAS)
 
@@ -422,7 +422,7 @@
  * Map L0_GPT with read and write permissions
  */
 #if ENABLE_RME
-#define ARM_MAP_L0_GPT_REGION		MAP_REGION_FLAT(ARM_L0_GPT_ADDR_BASE,	\
+#define ARM_MAP_L0_GPT_REGION		MAP_REGION_FLAT(ARM_L0_GPT_BASE,	\
 						ARM_L0_GPT_SIZE,		\
 						MT_MEMORY | MT_RW | MT_ROOT)
 #endif
@@ -533,8 +533,8 @@
  * configuration memory, 4KB aligned.
  */
 #define ARM_L0_GPT_SIZE			(PAGE_SIZE)
-#define ARM_L0_GPT_ADDR_BASE		(ARM_FW_CONFIGS_LIMIT)
-#define ARM_L0_GPT_LIMIT		(ARM_L0_GPT_ADDR_BASE + ARM_L0_GPT_SIZE)
+#define ARM_L0_GPT_BASE		(ARM_FW_CONFIGS_LIMIT)
+#define ARM_L0_GPT_LIMIT		(ARM_L0_GPT_BASE + ARM_L0_GPT_SIZE)
 #else
 #define ARM_L0_GPT_SIZE			U(0)
 #endif
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 0fb06a6..4c425a7 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <lib/bakery_lock.h>
 #include <lib/cassert.h>
 #include <lib/el3_runtime/cpu_data.h>
+#include <lib/gpt_rme/gpt_rme.h>
 #include <lib/spinlock.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
@@ -31,6 +32,17 @@
 	unsigned int nsaid_permissions;
 } arm_tzc_regions_info_t;
 
+typedef struct arm_gpt_info {
+	pas_region_t *pas_region_base;
+	unsigned int pas_region_count;
+	uintptr_t l0_base;
+	uintptr_t l1_base;
+	size_t l0_size;
+	size_t l1_size;
+	gpccr_pps_e pps;
+	gpccr_pgs_e pgs;
+} arm_gpt_info_t;
+
 /*******************************************************************************
  * Default mapping definition of the TrustZone Controller for ARM standard
  * platforms.
@@ -362,6 +374,9 @@
 unsigned int plat_arm_calc_core_pos(u_register_t mpidr);
 const mmap_region_t *plat_arm_get_mmap(void);
 
+const arm_gpt_info_t *plat_arm_get_gpt_info(void);
+void arm_gpt_setup(void);
+
 /* Allow platform to override psci_pm_ops during runtime */
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops);
 
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 389c086..176308e 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -107,7 +107,12 @@
 #endif /* NS_TIMER_SWITCH */
 
 	/* Save MTE system registers if the build has instructed so */
-#if CTX_INCLUDE_MTE_REGS
+#if ENABLE_FEAT_MTE
+#if ENABLE_FEAT_MTE == 2
+	mrs x8, id_aa64pfr1_el1
+	and x8, x8, #(ID_AA64PFR1_EL1_MTE_MASK << ID_AA64PFR1_EL1_MTE_SHIFT)
+	cbz x8, no_mte_save
+#endif
 	mrs	x15, TFSRE0_EL1
 	mrs	x16, TFSR_EL1
 	stp	x15, x16, [x0, #CTX_TFSRE0_EL1]
@@ -115,7 +120,9 @@
 	mrs	x9, RGSR_EL1
 	mrs	x10, GCR_EL1
 	stp	x9, x10, [x0, #CTX_RGSR_EL1]
-#endif /* CTX_INCLUDE_MTE_REGS */
+
+no_mte_save:
+#endif /* ENABLE_FEAT_MTE */
 
 	ret
 endfunc el1_sysregs_context_save
@@ -206,7 +213,13 @@
 #endif /* NS_TIMER_SWITCH */
 
 	/* Restore MTE system registers if the build has instructed so */
-#if CTX_INCLUDE_MTE_REGS
+#if ENABLE_FEAT_MTE
+#if ENABLE_FEAT_MTE == 2
+	mrs x8, id_aa64pfr1_el1
+	and x8, x8, #(ID_AA64PFR1_EL1_MTE_MASK << ID_AA64PFR1_EL1_MTE_SHIFT)
+	cbz x8, no_mte_restore
+#endif
+
 	ldp	x11, x12, [x0, #CTX_TFSRE0_EL1]
 	msr	TFSRE0_EL1, x11
 	msr	TFSR_EL1, x12
@@ -214,7 +227,9 @@
 	ldp	x13, x14, [x0, #CTX_RGSR_EL1]
 	msr	RGSR_EL1, x13
 	msr	GCR_EL1, x14
-#endif /* CTX_INCLUDE_MTE_REGS */
+
+no_mte_restore:
+#endif /* ENABLE_FEAT_MTE */
 
 	/* No explict ISB required here as ERET covers it */
 	ret
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 780537d..00c6008 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -168,6 +168,7 @@
 
 	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT;
 
+	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
 		/* Enable access to the SCXTNUM_ELx registers. */
 		scr_el3 |= SCR_EnSCXT_BIT;
@@ -236,6 +237,7 @@
 	scr_el3 |= SCR_TERR_BIT;
 #endif
 
+	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
 		/* Enable access to the SCXTNUM_ELx registers. */
 		scr_el3 |= SCR_EnSCXT_BIT;
@@ -1293,6 +1295,7 @@
 		write_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2, read_trfcr_el2());
 	}
 
+	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
 		write_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2, read_scxtnum_el2());
 	}
@@ -1333,9 +1336,10 @@
 	el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
 
 	el2_sysregs_context_restore_common(el2_sysregs_ctx);
-#if CTX_INCLUDE_MTE_REGS
-	write_tfsr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2));
-#endif
+
+	if (is_feat_mte_supported()) {
+		write_tfsr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2));
+	}
 
 #if CTX_INCLUDE_MPAM_REGS
 	if (is_feat_mpam_supported()) {
@@ -1369,6 +1373,7 @@
 		write_trfcr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2));
 	}
 
+	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
 		write_scxtnum_el2(read_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2));
 	}
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index c3ddc5a..3b62aaa 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -1,14 +1,14 @@
 #
-# Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-AS          = $(CROSS_COMPILE)as
-AR          = $(CROSS_COMPILE)ar
+AS          = $(CROSS_COMPILE)gcc
+AR          = $(CROSS_COMPILE)gcc-ar
 LD          = $(CROSS_COMPILE)ld
 OC          = $(CROSS_COMPILE)objcopy
-CPP         = $(CROSS_COMPILE)cpp
+CPP         = $(CROSS_COMPILE)gcc -E
 ROMLIB_GEN  = ./romlib_generator.py
 BUILD_DIR   = $(BUILD_PLAT)/romlib
 LIB_DIR     = $(BUILD_PLAT)/lib
@@ -48,11 +48,11 @@
 
 %.o: %.s
 	@echo "  AS      $@"
-	$(Q)$(AS) $(ASFLAGS) -o $@ $<
+	$(Q)$(AS) -c $(ASFLAGS) -o $@ $<
 
 $(BUILD_DIR)/%.o: %.s
 	@echo "  AS      $@"
-	$(Q)$(AS) $(ASFLAGS) -o $@ $<
+	$(Q)$(AS) -c $(ASFLAGS) -o $@ $<
 
 $(BUILD_DIR)/romlib.ld: romlib.ld.S
 	@echo "  PP      $@"
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 9ac9332..bb4e224 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -169,6 +169,10 @@
 # Flag to enable CSV2_2 extension.
 ENABLE_FEAT_CSV2_2			?=	0
 
+# Flag to enable CSV2_3 extension. FEAT_CSV2_3 enables access to the
+# SCXTNUM_ELx register.
+ENABLE_FEAT_CSV2_3			?=	0
+
 # By default, disable access of trace system registers from NS lower
 # ELs  i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
 # system register trace is implemented. This feature is available if
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 08a6046..2d2f141 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -101,9 +101,7 @@
 
 # Convenience function to check for a given linker option. An call to
 # $(call ld_option, --no-XYZ) will return --no-XYZ if supported by the linker
-define ld_option
-	$(shell if $(LD) $(1) -v >/dev/null 2>&1; then echo $(1); fi )
-endef
+ld_option = $(shell $(LD) $(1) -Wl,--version >/dev/null 2>&1 || $(LD) $(1) -v >/dev/null 2>&1 && echo $(1))
 
 # Convenience function to check for a given compiler option. A call to
 # $(call cc_option, --no-XYZ) will return --no-XYZ if supported by the compiler
@@ -658,7 +656,7 @@
 $(DOBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
 	$${ECHO} "  CPP     $$<"
 	$(eval DTBS       := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
-	$$(Q)$$(PP) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
+	$$(Q)$$(CPP) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
 	$${ECHO} "  DTC     $$<"
 	$$(Q)$$(DTC) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $(DPRE)
 
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index ebd5266..97d000e 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <common/debug.h>
 #include <common/desc_image_load.h>
 #include <drivers/arm/sp804_delay_timer.h>
+#include <fvp_pas_def.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/transfer_list.h>
@@ -21,6 +22,32 @@
 
 static struct transfer_list_header *ns_tl __unused;
 
+#if ENABLE_RME
+/*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+static pas_region_t pas_regions[] = {
+	ARM_PAS_KERNEL,
+	ARM_PAS_SECURE,
+	ARM_PAS_REALM,
+	ARM_PAS_EL3_DRAM,
+	ARM_PAS_GPTS,
+	ARM_PAS_KERNEL_1
+};
+
+static const arm_gpt_info_t arm_gpt_info = {
+	.pas_region_base  = pas_regions,
+	.pas_region_count = (unsigned int)ARRAY_SIZE(pas_regions),
+	.l0_base = (uintptr_t)ARM_L0_GPT_BASE,
+	.l1_base = (uintptr_t)ARM_L1_GPT_BASE,
+	.l0_size = (size_t)ARM_L0_GPT_SIZE,
+	.l1_size = (size_t)ARM_L1_GPT_SIZE,
+	.pps = GPCCR_PPS_64GB,
+	.pgs = GPCCR_PGS_4K
+};
+#endif
+
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
 {
 	arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
@@ -41,6 +68,13 @@
 	fvp_timer_init();
 }
 
+#if ENABLE_RME
+const arm_gpt_info_t *plat_arm_get_gpt_info(void)
+{
+	return &arm_gpt_info;
+}
+#endif /* ENABLE_RME */
+
 /*******************************************************************************
  * This function returns the list of executable images
  ******************************************************************************/
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index c40a3ce..beae242 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,6 @@
 #endif
 
 #include <plat/arm/common/arm_config.h>
-#include <plat/arm/common/arm_pas_def.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
diff --git a/include/plat/arm/common/arm_pas_def.h b/plat/arm/board/fvp/include/fvp_pas_def.h
similarity index 94%
rename from include/plat/arm/common/arm_pas_def.h
rename to plat/arm/board/fvp/include/fvp_pas_def.h
index fba8d2c..4684387 100644
--- a/include/plat/arm/common/arm_pas_def.h
+++ b/plat/arm/board/fvp/include/fvp_pas_def.h
@@ -1,13 +1,13 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#ifndef ARM_PAS_DEF_H
-#define ARM_PAS_DEF_H
+#ifndef FVP_PAS_DEF_H
+#define FVP_PAS_DEF_H
 
 #include <lib/gpt_rme/gpt_rme.h>
-#include <plat/arm/common/arm_def.h>
+#include <platform_def.h>
 
 /*****************************************************************************
  * PAS regions used to initialize the Granule Protection Table (GPT)
@@ -107,11 +107,11 @@
 							       ARM_EL3_TZC_DRAM1_SIZE, \
 							       GPT_GPI_ROOT)
 
-#define	ARM_PAS_GPTS			GPT_MAP_REGION_GRANULE(ARM_L1_GPT_ADDR_BASE, \
+#define	ARM_PAS_GPTS			GPT_MAP_REGION_GRANULE(ARM_L1_GPT_BASE, \
 							       ARM_L1_GPT_SIZE, \
 							       GPT_GPI_ROOT)
 
 /* GPT Configuration options */
 #define PLATFORM_L0GPTSZ		GPCCR_L0GPTSZ_30BITS
 
-#endif /* ARM_PAS_DEF_H */
+#endif /* FVP_PAS_DEF_H */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index df26dd7..eef06d4 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -75,6 +75,7 @@
 endif
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 ENABLE_FEAT_CSV2_2		:= 2
+ENABLE_FEAT_CSV2_3		:= 2
 ENABLE_FEAT_DIT			:= 2
 ENABLE_FEAT_PAN			:= 2
 ENABLE_FEAT_MTE_PERM		:= 2
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 3e8109e..30d0647 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,9 +23,6 @@
 #include <lib/optee_utils.h>
 #endif
 #include <lib/utils.h>
-#if ENABLE_RME
-#include <plat/arm/common/arm_pas_def.h>
-#endif
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -134,48 +131,6 @@
 	arm_bl2_platform_setup();
 }
 
-#if ENABLE_RME
-static void arm_bl2_plat_gpt_setup(void)
-{
-	/*
-	 * The GPT library might modify the gpt regions structure to optimize
-	 * the layout, so the array cannot be constant.
-	 */
-	pas_region_t pas_regions[] = {
-		ARM_PAS_KERNEL,
-		ARM_PAS_SECURE,
-		ARM_PAS_REALM,
-		ARM_PAS_EL3_DRAM,
-		ARM_PAS_GPTS,
-		ARM_PAS_KERNEL_1
-	};
-
-	/* Initialize entire protected space to GPT_GPI_ANY. */
-	if (gpt_init_l0_tables(GPCCR_PPS_64GB, ARM_L0_GPT_ADDR_BASE,
-		ARM_L0_GPT_SIZE) < 0) {
-		ERROR("gpt_init_l0_tables() failed!\n");
-		panic();
-	}
-
-	/* Carve out defined PAS ranges. */
-	if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
-				   ARM_L1_GPT_ADDR_BASE,
-				   ARM_L1_GPT_SIZE,
-				   pas_regions,
-				   (unsigned int)(sizeof(pas_regions) /
-				   sizeof(pas_region_t))) < 0) {
-		ERROR("gpt_init_pas_l1_tables() failed!\n");
-		panic();
-	}
-
-	INFO("Enabling Granule Protection Checks\n");
-	if (gpt_enable() < 0) {
-		ERROR("gpt_enable() failed!\n");
-		panic();
-	}
-}
-#endif /* ENABLE_RME */
-
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here.
  * When RME is enabled the secure environment is initialised before
@@ -216,7 +171,7 @@
 	enable_mmu_el3(0);
 
 	/* Initialise and enable granule protection after MMU. */
-	arm_bl2_plat_gpt_setup();
+	arm_gpt_setup();
 #else
 	enable_mmu_el1(0);
 #endif
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index fc68114..21cc39c 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -241,3 +241,43 @@
 {
 	return plat_arm_mmap;
 }
+
+#if ENABLE_RME
+void arm_gpt_setup(void)
+{
+	/*
+	 * It is to be noted that any Arm platform that reuses arm_gpt_setup
+	 * must implement plat_arm_get_gpt_info within its platform code
+	 */
+	const arm_gpt_info_t *arm_gpt_info =
+		plat_arm_get_gpt_info();
+
+	if (arm_gpt_info == NULL) {
+		ERROR("arm_gpt_info not initialized!!\n");
+		panic();
+	}
+
+	/* Initialize entire protected space to GPT_GPI_ANY. */
+	if (gpt_init_l0_tables(arm_gpt_info->pps, arm_gpt_info->l0_base,
+		arm_gpt_info->l0_size) < 0) {
+		ERROR("gpt_init_l0_tables() failed!\n");
+		panic();
+	}
+
+	/* Carve out defined PAS ranges. */
+	if (gpt_init_pas_l1_tables(arm_gpt_info->pgs,
+				   arm_gpt_info->l1_base,
+				   arm_gpt_info->l1_size,
+				   arm_gpt_info->pas_region_base,
+				   arm_gpt_info->pas_region_count) < 0) {
+		ERROR("gpt_init_pas_l1_tables() failed!\n");
+		panic();
+	}
+
+	INFO("Enabling Granule Protection Checks\n");
+	if (gpt_enable() < 0) {
+		ERROR("gpt_enable() failed!\n");
+		panic();
+	}
+}
+#endif /* ENABLE_RME */
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index ec8631a..f830b64 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -17,6 +17,15 @@
 #include <lib/mmio.h>
 #include <sci/sci.h>
 
+#if defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+/*
+ * Defined in
+ * table 11. ROM event log buffer address location
+ * AN12853 "i.MX ROMs Log Events"
+ */
+#define ROM_LOG_BUFFER_ADDR	0x9E0
+#endif
+
 #if defined(PLAT_imx8qm) || defined(PLAT_imx8qx)
 
 #ifdef PLAT_imx8qm
@@ -177,6 +186,76 @@
 }
 #endif /* defined(PLAT_imx8mm) || defined(PLAT_imx8mq) */
 
+#if defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+static bool is_secondary_boot(void)
+{
+	uint32_t *rom_log_addr = (uint32_t *)ROM_LOG_BUFFER_ADDR;
+	bool is_secondary = false;
+	uint32_t *rom_log;
+	uint8_t event_id;
+
+	/* If the ROM event log pointer is not valid. */
+	if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xB00000 ||
+	    *rom_log_addr & 0x3) {
+		return false;
+	}
+
+	/* Parse the ROM event ID version 2 log */
+	rom_log = (uint32_t *)(uintptr_t)(*rom_log_addr);
+	for (size_t i = 0; i < 128; i++) {
+		event_id = rom_log[i] >> 24;
+		switch (event_id) {
+		case 0x00: /* End of list */
+			return is_secondary;
+		/* Log entries with 1 parameter, skip 1 */
+		case 0x80: /* Perform the device initialization */
+		case 0x81: /* The boot device initialization completes */
+		case 0x82: /* Execute boot device driver pre-config */
+		case 0x8F: /* The boot device initialization fails */
+		case 0x90: /* Start to read data from boot device */
+		case 0x91: /* Reading data from boot device completes */
+		case 0x9F: /* Reading data from boot device fails */
+			i += 1;
+			continue;
+		/* Log entries with 2 parameters, skip 2 */
+		case 0xA0: /* Image authentication result */
+		case 0xC0: /* Jump to the boot image soon */
+			i += 2;
+			continue;
+		/* Booted the primary boot image */
+		case 0x50:
+			is_secondary = false;
+			continue;
+		/* Booted the secondary boot image */
+		case 0x51:
+			is_secondary = true;
+			continue;
+		}
+	}
+
+	return is_secondary;
+}
+
+int imx_src_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3,
+		    void *handle)
+{
+	switch (x1) {
+	case IMX_SIP_SRC_SET_SECONDARY_BOOT:
+		/* we do support that on these SoCs */
+		break;
+	case IMX_SIP_SRC_IS_SECONDARY_BOOT:
+		return is_secondary_boot();
+	default:
+		return SMC_UNK;
+	};
+
+	return 0;
+}
+#endif /* defined(PLAT_imx8mn) || defined(PLAT_imx8mp) */
+
 static uint64_t imx_get_commit_hash(u_register_t x2,
 		    u_register_t x3,
 		    u_register_t x4)
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 6d6633c..69d4f05 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -60,7 +60,8 @@
 	case IMX_SIP_MISC_SET_TEMP:
 		SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
 #endif
-#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq) || defined(PLAT_imx8mn) || \
+	defined(PLAT_imx8mp)
 	case IMX_SIP_SRC:
 		SMC_RET1(handle, imx_src_handler(smc_fid, x1, x2, x3, handle));
 		break;
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 0e91c71..35a9f47 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -68,7 +68,9 @@
 		    u_register_t x2, u_register_t x3);
 #endif
 
-#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq) || defined(PLAT_imx8mn) || \
+	defined(PLAT_imx8mp)
+
 int imx_src_handler(uint32_t smc_fid, u_register_t x1,
 		    u_register_t x2, u_register_t x3, void *handle);
 #endif
diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile
index 79e09f0..71548ba 100644
--- a/plat/rockchip/rk3399/drivers/m0/Makefile
+++ b/plat/rockchip/rk3399/drivers/m0/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -40,11 +40,10 @@
 
 # Cross tool
 CC			:= ${M0_CROSS_COMPILE}gcc
-CPP			:= ${M0_CROSS_COMPILE}cpp
-AR			:= ${M0_CROSS_COMPILE}ar
+CPP			:= ${M0_CROSS_COMPILE}gcc -E
+AR			:= ${M0_CROSS_COMPILE}gcc-ar
 OC			:= ${M0_CROSS_COMPILE}objcopy
 OD			:= ${M0_CROSS_COMPILE}objdump
-NM			:= ${M0_CROSS_COMPILE}nm
 
 # NOTE: The line continuation '\' is required in the next define otherwise we
 # end up with a line-feed characer at the end of the last c filename.
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 5f05f63..a7cce62 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -7,8 +7,10 @@
 #include <cdefs.h>
 #include <stdint.h>
 
+#include <common/debug.h>
 #include <plat/common/platform.h>
 
+#include <platform_def.h>
 #include <stm32mp_common.h>
 
 void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
@@ -25,4 +27,8 @@
 
 void bl2_el3_plat_arch_setup(void)
 {
+	if (stm32_otp_probe() != 0U) {
+		ERROR("OTP probe failed\n");
+		panic();
+	}
 }
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index 6ea4638..0519b16 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -46,6 +46,8 @@
 PLAT_BL_COMMON_SOURCES		+=	drivers/st/uart/${ARCH}/stm32_console.S
 PLAT_BL_COMMON_SOURCES		+=	plat/st/stm32mp2/${ARCH}/stm32mp2_helper.S
 
+PLAT_BL_COMMON_SOURCES		+=	drivers/st/bsec/bsec3.c
+
 BL2_SOURCES			+=	plat/st/stm32mp2/plat_bl2_mem_params_desc.c
 BL2_SOURCES			+=	plat/st/stm32mp2/bl2_plat_setup.c
 
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index ee105de..56c62e1 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -158,6 +158,96 @@
 #define STM32MP_SDMMC3_BASE			U(0x48240000)
 
 /*******************************************************************************
+ * STM32MP2 BSEC / OTP
+ ******************************************************************************/
+/*
+ * 367 available OTPs, the other are masked
+ * - ECIES key: 368 to 375 (only readable by bootrom)
+ * - HWKEY: 376 to 383 (never reloadable or readable)
+ */
+#define STM32MP2_OTP_MAX_ID			U(0x16F)
+#define STM32MP2_MID_OTP_START			U(0x80)
+#define STM32MP2_UPPER_OTP_START		U(0x100)
+
+/* OTP labels */
+#define PART_NUMBER_OTP				"part-number-otp"
+#define PACKAGE_OTP				"package-otp"
+#define HCONF1_OTP				"otp124"
+#define NAND_OTP				"otp16"
+#define NAND2_OTP				"otp20"
+#define BOARD_ID_OTP				"board-id"
+#define UID_OTP					"uid-otp"
+#define LIFECYCLE2_OTP				"otp18"
+#define PKH_OTP					"otp144"
+#define ENCKEY_OTP				"otp260"
+
+/* OTP mask */
+/* PACKAGE */
+#define PACKAGE_OTP_PKG_MASK			GENMASK_32(2, 0)
+#define PACKAGE_OTP_PKG_SHIFT			U(0)
+
+/* IWDG OTP */
+#define HCONF1_OTP_IWDG_HW_POS			U(0)
+#define HCONF1_OTP_IWDG_FZ_STOP_POS		U(1)
+#define HCONF1_OTP_IWDG_FZ_STANDBY_POS		U(2)
+
+/* NAND OTP */
+/* NAND parameter storage flag */
+#define NAND_PARAM_STORED_IN_OTP		BIT_32(31)
+
+/* NAND page size in bytes */
+#define NAND_PAGE_SIZE_MASK			GENMASK_32(30, 29)
+#define NAND_PAGE_SIZE_SHIFT			U(29)
+#define NAND_PAGE_SIZE_2K			U(0)
+#define NAND_PAGE_SIZE_4K			U(1)
+#define NAND_PAGE_SIZE_8K			U(2)
+
+/* NAND block size in pages */
+#define NAND_BLOCK_SIZE_MASK			GENMASK_32(28, 27)
+#define NAND_BLOCK_SIZE_SHIFT			U(27)
+#define NAND_BLOCK_SIZE_64_PAGES		U(0)
+#define NAND_BLOCK_SIZE_128_PAGES		U(1)
+#define NAND_BLOCK_SIZE_256_PAGES		U(2)
+
+/* NAND number of block (in unit of 256 blocks) */
+#define NAND_BLOCK_NB_MASK			GENMASK_32(26, 19)
+#define NAND_BLOCK_NB_SHIFT			U(19)
+#define NAND_BLOCK_NB_UNIT			U(256)
+
+/* NAND bus width in bits */
+#define NAND_WIDTH_MASK				BIT_32(18)
+#define NAND_WIDTH_SHIFT			U(18)
+
+/* NAND number of ECC bits per 512 bytes */
+#define NAND_ECC_BIT_NB_MASK			GENMASK_32(17, 15)
+#define NAND_ECC_BIT_NB_SHIFT			U(15)
+#define NAND_ECC_BIT_NB_UNSET			U(0)
+#define NAND_ECC_BIT_NB_1_BITS			U(1)
+#define NAND_ECC_BIT_NB_4_BITS			U(2)
+#define NAND_ECC_BIT_NB_8_BITS			U(3)
+#define NAND_ECC_ON_DIE				U(4)
+
+/* NAND number of planes */
+#define NAND_PLANE_BIT_NB_MASK			BIT_32(14)
+
+/* NAND2 OTP */
+#define NAND2_PAGE_SIZE_SHIFT			U(16)
+
+/* NAND2 config distribution */
+#define NAND2_CONFIG_DISTRIB			BIT_32(0)
+#define NAND2_PNAND_NAND2_SNAND_NAND1		U(0)
+#define NAND2_PNAND_NAND1_SNAND_NAND2		U(1)
+
+/* MONOTONIC OTP */
+#define MAX_MONOTONIC_VALUE			U(32)
+
+/* UID OTP */
+#define UID_WORD_NB				U(3)
+
+/* Lifecycle OTP */
+#define SECURE_BOOT_CLOSED_SECURE		GENMASK_32(3, 0)
+
+/*******************************************************************************
  * STM32MP2 TAMP
  ******************************************************************************/
 #define PLAT_MAX_TAMP_INT			U(5)
diff --git a/tools/renesas/rcar_layout_create/makefile b/tools/renesas/rcar_layout_create/makefile
index d585754..01b3d62 100644
--- a/tools/renesas/rcar_layout_create/makefile
+++ b/tools/renesas/rcar_layout_create/makefile
@@ -113,8 +113,8 @@
 # Compile
 ###################################################
 
-%.o:../%.c
-	$(CC) -c -I $< -o $@
+%.o: %.c
+	$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
 
 .PHONY: clean
 clean:
diff --git a/tools/renesas/rzg_layout_create/makefile b/tools/renesas/rzg_layout_create/makefile
index 2d438b9..92a0557 100644
--- a/tools/renesas/rzg_layout_create/makefile
+++ b/tools/renesas/rzg_layout_create/makefile
@@ -110,8 +110,8 @@
 # Compile
 ###################################################
 
-%.o:../%.c
-	$(CC) -c -I $< -o $@
+%.o: %.c
+	$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
 
 .PHONY: clean
 clean: