Merge changes from topic "tfa_mhuv3" into integration

* changes:
  feat(mhu): use compile flag to choose mhu version
  feat(mhu): add MHUv3 wrapper APIs for RSS comm driver
  feat(mhu): add MHUv3 doorbell driver
diff --git a/.cz-adapter.cjs b/.cz-adapter.cjs
new file mode 100644
index 0000000..26aaeb2
--- /dev/null
+++ b/.cz-adapter.cjs
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * A workaround for:
+ *
+ *     https://github.com/conventional-changelog/commitlint/issues/3949
+ */
+
+exports.prompter = async (inquirerIns, commit) => {
+    ; (await import('@commitlint/cz-commitlint')).prompter(inquirerIns, commit)
+}
diff --git a/.cz.json b/.cz.json
index 556c39f..969a73b 100644
--- a/.cz.json
+++ b/.cz.json
@@ -1,3 +1,3 @@
 {
-    "path": "@commitlint/cz-commitlint"
+    "path": "./.cz-adapter.cjs"
 }
diff --git a/.husky/commit-msg b/.husky/commit-msg
index c1c9600..b5d407b 100755
--- a/.husky/commit-msg
+++ b/.husky/commit-msg
@@ -1,7 +1,4 @@
 #!/bin/sh
 
-# shellcheck source=./_/husky.sh
-. "$(dirname "$0")/_/husky.sh"
-
 "$(dirname "$0")/commit-msg.gerrit" "$@"
 "$(dirname "$0")/commit-msg.commitlint" "$@"
diff --git a/.husky/pre-commit b/.husky/pre-commit
index afcb1f6..f438ddb 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,6 +1,3 @@
 #!/bin/sh
 
-# shellcheck source=./_/husky.sh
-. "$(dirname "$0")/_/husky.sh"
-
 "$(dirname "$0")/pre-commit.copyright" "$@"
diff --git a/Makefile b/Makefile
index ef570b2..800346a 100644
--- a/Makefile
+++ b/Makefile
@@ -1145,6 +1145,7 @@
 	HARDEN_SLS \
 	HW_ASSISTED_COHERENCY \
 	MEASURED_BOOT \
+	DICE_PROTECTION_ENVIRONMENT \
 	DRTM_SUPPORT \
 	NS_TIMER_SWITCH \
 	OVERRIDE_LIBC \
@@ -1312,6 +1313,7 @@
 	HW_ASSISTED_COHERENCY \
 	LOG_LEVEL \
 	MEASURED_BOOT \
+	DICE_PROTECTION_ENVIRONMENT \
 	DRTM_SUPPORT \
 	NS_TIMER_SWITCH \
 	PL011_GENERIC_UART \
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index c8cc2c7..9807817 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -83,7 +83,7 @@
 /*******************************************************************************
  * Simple function to initialise all BL31 helper libraries.
  ******************************************************************************/
-void __init bl31_lib_init(void)
+static void __init bl31_lib_init(void)
 {
 	cm_init();
 }
diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c
index d14a91e..f1b1fa6 100644
--- a/bl31/bl31_traps.c
+++ b/bl31/bl31_traps.c
@@ -97,7 +97,7 @@
  * 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.
  */
-static u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el)
+u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el)
 {
 	u_register_t new_spsr = 0;
 	u_register_t sctlr;
diff --git a/bl31/interrupt_mgmt.c b/bl31/interrupt_mgmt.c
index 68c7f10..a2b2c06 100644
--- a/bl31/interrupt_mgmt.c
+++ b/bl31/interrupt_mgmt.c
@@ -34,7 +34,7 @@
  *
  *           All other bits are reserved and SBZ.
  ******************************************************************************/
-typedef struct intr_type_desc {
+typedef struct {
 	interrupt_type_handler_t handler;
 	u_register_t scr_el3[2];
 	uint32_t flags;
diff --git a/changelog.yaml b/changelog.yaml
index 5696291..7f0c1ec 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -804,6 +804,9 @@
         deprecated:
           - lib/psa
 
+      - title: DICE Protection Environment
+        scope: dice
+
       - title: Context Management
         scope: context-mgmt
 
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index 654d65f..d814104 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -81,8 +81,6 @@
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
-| Mbedtls-2.x                    |     2.10    |   2.10  | Support for TF-A builds with Mbedtls-2.x will be removed|
-+--------------------------------+-------------+---------+---------------------------------------------------------+
 | STM32MP15_OPTEE_RSV_SHM        |     2.10    |   3.0   | OP-TEE manages its own memory on STM32MP15              |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
@@ -103,4 +101,4 @@
 
 --------------
 
-*Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 6f5f01f..97e164d 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -816,6 +816,16 @@
   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1 of the
   CPU. It is fixed in r1p2.
 
+For Cortex-X4, the following errata build flags are defined :
+
+- ``ERRATA_X4_2701112``: This applies erratum 2701112 workaround to Cortex-X4
+  CPU and affects system configurations that do not use an Arm interconnect IP.
+  This needs to be enabled for revisions r0p0 and is fixed in r0p1.
+  The workaround for this erratum is not implemented in EL3, but the flag can
+  be enabled/disabled at the platform level. The flag is used when the errata ABI
+  feature is enabled and can assist the Kernel in the process of
+  mitigation of the erratum.
+
 For Cortex-A510, the following errata build flags are defined :
 
 -  ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
@@ -885,6 +895,15 @@
    Cortex-A715 CPU. This needs to be enabled for revisions r0p0 and r1p0.
    It is fixed in r1p1.
 
+- ``ERRATA_A715_2344187``: This applies errata 2344187 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revisions r0p0 and r1p0. It is
+   fixed in r1p1.
+
+-  ``ERRATA_A715_2413290``: This applies errata 2413290 workaround to
+   Cortex-A715 CPU. This needs to be enabled only for revision r1p0 and
+   when SPE(Statistical profiling extension)=True. The errata is fixed
+   in r1p1.
+
 -  ``ERRATA_A715_2420947``: This applies errata 2420947 workaround to
    Cortex-A715 CPU. This needs to be enabled only for revision r1p0.
    It is fixed in r1p1.
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index ba97264..fa06c8e 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -645,6 +645,35 @@
 Data structures used in the BL31 cold boot interface
 ''''''''''''''''''''''''''''''''''''''''''''''''''''
 
+In the cold boot flow, ``entry_point_info`` is used to represent the execution
+state of an image; that is, the state of general purpose registers, PC, and
+SPSR.
+
+There are two variants of this structure, for AArch64:
+
+.. code:: c
+
+   typedef struct entry_point_info {
+        param_header_t h;
+        uintptr_t pc;
+        uint32_t spsr;
+
+        aapcs64_params_t args;
+   }
+
+and, AArch32:
+
+.. code:: c
+
+   typedef struct entry_point_info {
+      param_header_t h;
+      uintptr_t pc;
+      uint32_t spsr;
+
+      uintptr_t lr_svc;
+      aapcs32_params_t args;
+   } entry_point_info_t;
+
 These structures are designed to support compatibility and independent
 evolution of the structures and the firmware images. For example, a version of
 BL31 that can interpret the BL3x image information from different versions of
@@ -662,13 +691,17 @@
         uint8_t type;       /* type of the structure */
         uint8_t version;    /* version of this structure */
         uint16_t size;      /* size of this structure in bytes */
-        uint32_t attr;      /* attributes: unused bits SBZ */
+        uint32_t attr;      /* attributes */
     } param_header_t;
 
-The structures using this format are ``entry_point_info``, ``image_info`` and
-``bl31_params``. The code that allocates and populates these structures must set
-the header fields appropriately, and the ``SET_PARAM_HEAD()`` a macro is defined
-to simplify this action.
+In `entry_point_info`, Bits 0 and 5 of ``attr`` field are used to encode the
+security state; in other words, whether the image is to be executed in Secure,
+Non-Secure, or Realm mode.
+
+Other structures using this format are ``image_info`` and ``bl31_params``. The
+code that allocates and populates these structures must set the header fields
+appropriately, the ``SET_PARAM_HEAD()`` macro is defined to simplify this
+action.
 
 Required CPU state for BL31 Warm boot initialization
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index a8b40ad..f817da0 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -706,6 +706,13 @@
 
    This option defaults to 0.
 
+-  ``DICE_PROTECTION_ENVIRONMENT``: Boolean flag to specify the measured boot
+   backend when ``MEASURED_BOOT`` is enabled. The default value is ``0``. When
+   set to ``1`` then measurements and additional metadata collected during the
+   measured boot process are sent to the DICE Protection Environment for storage
+   and processing. A certificate chain, which represents the boot state of the
+   device, can be queried from the DPE.
+
 -  ``MARCH_DIRECTIVE``: used to pass a -march option from the platform build
    options to the compiler. An example usage:
 
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 573abdf..9053e34 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -79,6 +79,10 @@
 
 - mbed TLS == 3.4.1 (tag: ``mbedtls-3.4.1``)
 
+The following libraries are required for DICE Protection Environment support:
+
+- QCBOR == 1.2 (tag: ``v1.2``)
+
 These tools are optional:
 
 - Device Tree Compiler (DTC) >= 1.4.7
@@ -184,7 +188,7 @@
 
 --------------
 
-*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
 
 .. _Arm Developer website: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
 .. _Gerrit Code Review: https://www.gerritcodereview.com/
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 679de2b..c02e938 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -40,6 +40,9 @@
       Common Vulnerabilities and Exposures. A CVE document is commonly used to
       describe a publicly-known security vulnerability.
 
+   DICE
+      Device Identifier Composition Engine
+
    DCE
       DRTM Configuration Environment
 
@@ -52,6 +55,9 @@
    DRTM
       Dynamic Root of Trust for Measurement
 
+   DPE
+      DICE Protection Environment
+
    DS-5
       Arm Development Studio 5
 
diff --git a/docs/license.rst b/docs/license.rst
index 80f1118..8996105 100644
--- a/docs/license.rst
+++ b/docs/license.rst
@@ -85,6 +85,17 @@
 
    See the original `Linux MIT license`_.
 
+-  Some source files originating from the `Open Profile for DICE`_ project.
+   These files are licensed under the Apache License, Version 2.0, which is a
+   permissive license compatible with BSD-3-Clause. Any contributions to this
+   code must also be made under the terms of `Apache License 2.0`_.
+   These files are:
+
+   -  ``include/lib/dice/dice.h``
+
 .. _FreeBSD: http://www.freebsd.org
 .. _Linux MIT license: https://raw.githubusercontent.com/torvalds/linux/master/LICENSES/preferred/MIT
 .. _SCC: http://www.simple-cc.org/
+.. _Open Profile for DICE: https://pigweed.googlesource.com/open-dice/
+.. _Apache License 2.0: https://www.apache.org/licenses/LICENSE-2.0.txt
+
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index 3f31d40..e9dd772 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -53,3 +53,46 @@
     -   `5`   : SGI 5
     -   `6`   : SGI 6 (Default)
     -   `7`   : SGI 7
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+-----------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+------------------------------+------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------------------------------------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges
+--------------------------------------------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index aa094f7..072329a 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -76,3 +76,46 @@
 data structure is passed in the ```PMC_GLOBAL_GLOB_GEN_STORAGE4``` register.
 The register is free to be used by other software once the TF-A is bringing up
 further firmware images.
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+----------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+-------------------------------------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges
+------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst
index 4fe0d2f..c8ba27f 100644
--- a/docs/plat/xilinx-zynqmp.rst
+++ b/docs/plat/xilinx-zynqmp.rst
@@ -166,3 +166,55 @@
 - TF-A build command:
   make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1
   bl31 CUSTOM_PKG_PATH=<...>
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+------------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+-------------------------------------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges
+------------------
+
++---------------------------+---------------------------------------------------------------------------+
+| SMC Function Identifier   |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
+
+CUSTOM SIP service support
+--------------------------
+
++-------------+------------+------------+
+| Service     | 32-bit     | 64-bit     |
++-------------+------------+------------+
+| SiP Service | 0x82002000 | 0xC2002000 |
++-------------+------------+------------+
diff --git a/docs/threat_model/firmware_threat_model/threat_model.rst b/docs/threat_model/firmware_threat_model/threat_model.rst
index 63bdc8a..f8e4f7d 100644
--- a/docs/threat_model/firmware_threat_model/threat_model.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model.rst
@@ -623,6 +623,62 @@
 |                        |   UART interface(s).                                |
 +------------------------+-----------------------------------------------------+
 
++------------------------+-----------------------------------------------------+
+| ID                     | 16                                                  |
++========================+=====================================================+
+| Threat                 | | **An attacker could analyse the timing behaviour  |
+|                        |     of implemented methods in the system to infer   |
+|                        |     sensitive information.**                        |
+|                        |                                                     |
+|                        | | A timing side-channel attack is a type of attack  |
+|                        |   that exploits variations in the time it takes a   |
+|                        |   system to perform different operations. This      |
+|                        |   form of attack focuses on analyzing the time-     |
+|                        |   related information leakage that occurs during    |
+|                        |   the execution of cryptographic algorithms or      |
+|                        |   other security-sensitive processes. By observing  |
+|                        |   these timing differences, an attacker can gain    |
+|                        |   insights into the internal workings of a system   |
+|                        |   and potentially extract sensitive information.    |
+|                        |   Sensitive information that, when revealed even    |
+|                        |   partially, could heighten the susceptibility to   |
+|                        |   traditional attacks like brute-force attacks.     |
++------------------------+-----------------------------------------------------+
+| Diagram Elements       | DF2                                                 |
++------------------------+-----------------------------------------------------+
+| Affected TF-A          | BL1, BL2, BL31                                      |
+| Components             |                                                     |
++------------------------+-----------------------------------------------------+
+| Assets                 | Sensitive Data                                      |
++------------------------+-----------------------------------------------------+
+| Threat Agent           | AppDebug                                            |
++------------------------+-----------------------------------------------------+
+| Threat Type            | Information Disclosure                              |
++------------------------+------------------+----------------+-----------------+
+| Application            | Server           | IoT            | Mobile          |
++------------------------+------------------+----------------+-----------------+
+| Impact                 | Critical (5)     | Critical (5)   | Critical (5)    |
++------------------------+------------------+----------------+-----------------+
+| Likelihood             | Critical (5)     | Critical (5)   | Critical (5)    |
++------------------------+------------------+----------------+-----------------+
+| Total Risk Rating      | Critical (25)    | Critical (25)  | Critical (25)   |
++------------------------+------------------+----------------+-----------------+
+| Mitigations            | |  Ensure that the execution time of critical       |
+|                        |    operations is constant and independent of        |
+|                        |    secret data. This prevents attackers from        |
+|                        |    exploiting timing differences to infer           |
+|                        |    information about sensitive data.                |
+|                        |                                                     |
+|                        | |  Introduce random delays/timing jitter or dummy   |
+|                        |    operations to make the timing behavior of program|
+|                        |    execution less predictable. This can disrupt the |
+|                        |    correlation between the execution time and       |
+|                        |    sensitive data.                                  |
+|                        |                                                     |
++------------------------+-----------------------------------------------------+
+| Mitigations            | |  Not implemented                                  |
+| implemented?           |                                                     |
++------------------------+-----------------------------------------------------+
 
 .. _Boot Firmware Threats:
 
diff --git a/drivers/arm/css/sds/sds.c b/drivers/arm/css/sds/sds.c
index a5e6389..91f0a27 100644
--- a/drivers/arm/css/sds/sds.c
+++ b/drivers/arm/css/sds/sds.c
@@ -250,7 +250,7 @@
 	uintptr_t sds_mem_base = sds_regions[region_id].base;
 
 	if (!IS_SDS_REGION_VALID(sds_mem_base)) {
-		WARN("SDS: No valid SDS Memory Region found\n");
+		VERBOSE("SDS: No valid SDS Memory Region found\n");
 		return SDS_ERR_FAIL;
 	}
 
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
index a4786bb..5e44aa9 100644
--- a/drivers/arm/gic/v3/gic600_multichip.c
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2022-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -75,7 +75,7 @@
 		panic();
 	}
 
-	/* Poll till PUP is zero before intiating write */
+	/* Poll till PUP is zero before initiating write */
 	gicd_dchipr_wait_for_power_update_progress(base);
 
 	write_gicd_dchipr(base, read_gicd_dchipr(base) |
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index a2c6430..2bb23f9 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -19,16 +19,15 @@
 MBEDTLS_MINOR=$(shell grep -hP "define MBEDTLS_VERSION_MINOR" ${MBEDTLS_DIR}/include/mbedtls/*.h | grep -oe '\([0-9.]*\)')
 $(info MBEDTLS_VERSION_MAJOR is [${MBEDTLS_MAJOR}] MBEDTLS_VERSION_MINOR is [${MBEDTLS_MINOR}])
 
+ifneq (${MBEDTLS_MAJOR}, 3)
+  $(error Error: TF-A only supports MbedTLS versions > 3.x)
+endif
+
 # Specify mbed TLS configuration file
-ifeq (${MBEDTLS_MAJOR}, 2)
-        $(info Deprecation Notice: Please migrate to Mbedtls version 3.x (refer to TF-A documentation for the exact version number))
-	MBEDTLS_CONFIG_FILE             ?=	"<drivers/auth/mbedtls/mbedtls_config-2.h>"
-else ifeq (${MBEDTLS_MAJOR}, 3)
-	ifeq (${PSA_CRYPTO},1)
-		MBEDTLS_CONFIG_FILE     ?=      "<drivers/auth/mbedtls/psa_mbedtls_config.h>"
-	else
-		MBEDTLS_CONFIG_FILE	?=	"<drivers/auth/mbedtls/mbedtls_config-3.h>"
-	endif
+ifeq (${PSA_CRYPTO},1)
+  MBEDTLS_CONFIG_FILE    ?=    "<drivers/auth/mbedtls/psa_mbedtls_config.h>"
+else
+  MBEDTLS_CONFIG_FILE    ?=    "<drivers/auth/mbedtls/mbedtls_config-3.h>"
 endif
 
 $(eval $(call add_define,MBEDTLS_CONFIG_FILE))
@@ -42,11 +41,13 @@
 					cipher.c 			\
 					cipher_wrap.c 			\
 					constant_time.c			\
+					hash_info.c			\
 					memory_buffer_alloc.c		\
 					oid.c 				\
 					platform.c 			\
 					platform_util.c			\
 					bignum.c			\
+					bignum_core.c			\
 					gcm.c 				\
 					md.c				\
 					pk.c 				\
@@ -59,28 +60,17 @@
 					ecp_curves.c			\
 					ecp.c				\
 					rsa.c				\
+					rsa_alt_helpers.c		\
 					x509.c 				\
 					x509_crt.c 			\
 					)
 
-ifeq (${MBEDTLS_MAJOR}, 2)
-	LIBMBEDTLS_SRCS +=  $(addprefix ${MBEDTLS_DIR}/library/,	\
-						rsa_internal.c		\
-						)
-else ifeq (${MBEDTLS_MAJOR}, 3)
-	LIBMBEDTLS_SRCS +=  $(addprefix ${MBEDTLS_DIR}/library/,	\
-						bignum_core.c		\
-						rsa_alt_helpers.c	\
-						hash_info.c		\
-						)
-
-	# Currently on Mbedtls-3 there is outstanding bug due to usage
-	# of redundant declaration[1], So disable redundant-decls
-	# compilation flag to avoid compilation error when compiling with
-	# Mbedtls-3.
-	# [1]: https://github.com/Mbed-TLS/mbedtls/issues/6910
-	LIBMBEDTLS_CFLAGS += -Wno-error=redundant-decls
-endif
+# Currently on Mbedtls-3 there is outstanding bug due to usage
+# of redundant declaration[1], So disable redundant-decls
+# compilation flag to avoid compilation error when compiling with
+# Mbedtls-3.
+# [1]: https://github.com/Mbed-TLS/mbedtls/issues/6910
+LIBMBEDTLS_CFLAGS += -Wno-error=redundant-decls
 
 ifeq (${PSA_CRYPTO},1)
 LIBMBEDTLS_SRCS         += $(addprefix ${MBEDTLS_DIR}/library/,    	\
diff --git a/drivers/measured_boot/rss/dice_prot_env.c b/drivers/measured_boot/rss/dice_prot_env.c
new file mode 100644
index 0000000..81a21d1
--- /dev/null
+++ b/drivers/measured_boot/rss/dice_prot_env.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <psa/crypto_types.h>
+#include <psa/crypto_values.h>
+
+#include <common/debug.h>
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/measured_boot/rss/dice_prot_env.h>
+#include <lib/cassert.h>
+#include <lib/psa/dice_protection_environment.h>
+
+#include <platform_def.h>
+
+#define DPE_ALG_SHA512 0
+#define DPE_ALG_SHA384 1
+#define DPE_ALG_SHA256 2
+
+#if DPE_ALG_ID == DPE_ALG_SHA512
+#define	CRYPTO_MD_ID		CRYPTO_MD_SHA512
+#define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_512
+#elif DPE_ALG_ID == DPE_ALG_SHA384
+#define	CRYPTO_MD_ID		CRYPTO_MD_SHA384
+#define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_384
+#elif DPE_ALG_ID == DPE_ALG_SHA256
+#define	CRYPTO_MD_ID		CRYPTO_MD_SHA256
+#define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_256
+#else
+#  error Invalid DPE hash algorithm.
+#endif /* DPE_ALG_ID */
+
+/* Ensure that computed hash values fits into the DiceInputValues structure */
+CASSERT(DICE_HASH_SIZE >= DPE_DIGEST_SIZE,
+	assert_digest_size_bigger_than_allocated_buffer);
+
+static int initial_context_handle;
+
+static void map_metadata_to_dice_inputs(struct dpe_metadata *metadata,
+					DiceInputValues  *dice_inputs)
+{
+	/* Hash of the content certificate signing key (public part) */
+	memcpy(dice_inputs->authority_hash, metadata->signer_id,
+	       DPE_DIGEST_SIZE);
+
+	/* SW type string identifier */
+	assert(metadata->sw_type_size < DICE_CODE_DESCRIPTOR_MAX_SIZE);
+	dice_inputs->code_descriptor = metadata->sw_type;
+	dice_inputs->code_descriptor_size = metadata->sw_type_size;
+}
+
+void dpe_init(struct dpe_metadata *metadata)
+{
+	assert(metadata != NULL);
+
+	/* Init the non-const members of the metadata structure */
+	while (metadata->id != DPE_INVALID_ID) {
+		/* Terminating 0 character is not needed due to CBOR encoding */
+		metadata->sw_type_size =
+			strlen((const char *)&metadata->sw_type);
+		metadata++;
+	}
+
+	plat_dpe_get_context_handle(&initial_context_handle);
+}
+
+int dpe_measure_and_record(struct dpe_metadata *metadata,
+			   uintptr_t data_base, uint32_t data_size,
+			   uint32_t data_id)
+{
+	static int current_context_handle;
+	DiceInputValues dice_inputs = { 0 };
+	int new_parent_context_handle;
+	int new_context_handle;
+	dpe_error_t ret;
+	int rc;
+
+	assert(metadata != NULL);
+
+	/* Get the metadata associated with this image. */
+	while ((metadata->id != DPE_INVALID_ID) && (metadata->id != data_id)) {
+		metadata++;
+	}
+
+	/* If image is not present in metadata array then skip */
+	if (metadata->id == DPE_INVALID_ID) {
+		return 0;
+	}
+
+	/* Calculate hash */
+	rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
+				  (void *)data_base, data_size,
+				   dice_inputs.code_hash);
+	if (rc != 0) {
+		return rc;
+	}
+
+	map_metadata_to_dice_inputs(metadata, &dice_inputs);
+
+	/* Only at the first call */
+	if (current_context_handle == 0) {
+		current_context_handle = initial_context_handle;
+	}
+
+	VERBOSE("Calling dpe_derive_context, image_id: %d\n", metadata->id);
+	ret = dpe_derive_context(current_context_handle,
+				 metadata->cert_id,
+				 metadata->retain_parent_context,
+				 metadata->allow_new_context_to_derive,
+				 metadata->create_certificate,
+				 &dice_inputs,
+				 0, /* target_locality */
+				 false, /* return_certificate */
+				 true, /* allow_new_context_to_export */
+				 false, /* export_cdi */
+				 &new_context_handle,
+				 &new_parent_context_handle,
+				 NULL, 0, NULL,  /* new_certificate_* */
+				 NULL, 0, NULL); /* exported_cdi_* */
+	if (ret == DPE_NO_ERROR) {
+		current_context_handle = new_parent_context_handle;
+		if (metadata->allow_new_context_to_derive == true) {
+			/* Share new_context_handle with child component:
+			 * e.g: BL2, BL33.
+			 */
+			VERBOSE("Share new_context_handle with child: 0x%x\n",
+				new_context_handle);
+			plat_dpe_share_context_handle(&new_context_handle);
+		}
+	} else {
+		ERROR("dpe_derive_context failed: %d\n", ret);
+	}
+
+	return (ret == DPE_NO_ERROR) ? 0 : -1;
+}
+
+int dpe_set_signer_id(struct dpe_metadata *metadata,
+		      const void *pk_oid,
+		      const void *pk_ptr,
+		      size_t pk_len)
+{
+	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
+	int rc;
+	bool hash_calc_done = false;
+
+	assert(metadata != NULL);
+
+	/*
+	 * Do an exhaustive search over the platform metadata to find
+	 * all images whose key OID matches the one passed in argument.
+	 *
+	 * Note that it is not an error if do not get any matches.
+	 * The platform may decide not to measure all of the images
+	 * in the system.
+	 */
+	while (metadata->id != DPE_INVALID_ID) {
+		/* Get the metadata associated with this key-oid */
+		if (metadata->pk_oid == pk_oid) {
+			if (hash_calc_done == false) {
+				/* Calculate public key hash */
+				rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
+							  (void *)pk_ptr,
+							  pk_len, hash_data);
+				if (rc != 0) {
+					return rc;
+				}
+
+				hash_calc_done = true;
+			}
+
+			/*
+			 * Fill the signer-ID field with the newly/already
+			 * computed hash of the public key and update its
+			 * signer ID size field with compile-time decided
+			 * digest size.
+			 */
+			(void)memcpy(metadata->signer_id,
+				     hash_data,
+				     DPE_DIGEST_SIZE);
+			metadata->signer_id_size = DPE_DIGEST_SIZE;
+		}
+
+		metadata++;
+	}
+
+	return 0;
+}
diff --git a/drivers/measured_boot/rss/dice_prot_env.mk b/drivers/measured_boot/rss/dice_prot_env.mk
new file mode 100644
index 0000000..c5a35e0
--- /dev/null
+++ b/drivers/measured_boot/rss/dice_prot_env.mk
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Hash algorithm for DICE Protection Environment
+# SHA-256 (or stronger) is required.
+DPE_HASH_ALG	:=	sha256
+
+ifeq (${DPE_HASH_ALG}, sha512)
+    DPE_ALG_ID		:=	DPE_ALG_SHA512
+    DPE_DIGEST_SIZE	:=	64U
+else ifeq (${DPE_HASH_ALG}, sha384)
+    DPE_ALG_ID		:=	DPE_ALG_SHA384
+    DPE_DIGEST_SIZE	:=	48U
+else
+    DPE_ALG_ID		:=	DPE_ALG_SHA256
+    DPE_DIGEST_SIZE	:=	32U
+endif #DPE_HASH_ALG
+
+# Set definitions for DICE Protection Environment
+$(eval $(call add_defines,\
+    $(sort \
+        DPE_ALG_ID \
+        DPE_DIGEST_SIZE \
+)))
+
+DPE_SOURCES	+=	drivers/measured_boot/rss/dice_prot_env.c
diff --git a/drivers/measured_boot/rss/qcbor.mk b/drivers/measured_boot/rss/qcbor.mk
new file mode 100644
index 0000000..2146e5d
--- /dev/null
+++ b/drivers/measured_boot/rss/qcbor.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# TF-A was tested with v1.2 version of QCBOR
+
+ifeq (${QCBOR_DIR},)
+        $(error Error: QCBOR_DIR not set)
+endif
+
+QCBOR_SOURCES	+=	${QCBOR_DIR}/src/qcbor_encode.c \
+			${QCBOR_DIR}/src/qcbor_decode.c \
+			${QCBOR_DIR}/src/UsefulBuf.c
+
+QCBOR_INCLUDES	+=	${QCBOR_DIR}/inc
+
+# Floating point numbers are not used, so disable the support.
+# This reduces the library size as well.
+$(eval $(call add_define,QCBOR_DISABLE_FLOAT_HW_USE))
+$(eval $(call add_define,USEFULBUF_DISABLE_ALL_FLOAT))
+$(eval $(call add_define,QCBOR_DISABLE_PREFERRED_FLOAT))
diff --git a/drivers/measured_boot/rss/rss_measured_boot.c b/drivers/measured_boot/rss/rss_measured_boot.c
index 258aa8d..c44ec73 100644
--- a/drivers/measured_boot/rss/rss_measured_boot.c
+++ b/drivers/measured_boot/rss/rss_measured_boot.c
@@ -128,7 +128,7 @@
 	while (metadata_ptr->id != RSS_MBOOT_INVALID_ID) {
 		/* Get the metadata associated with this key-oid */
 		if (metadata_ptr->pk_oid == pk_oid) {
-			if (!hash_calc_done) {
+			if (hash_calc_done == false) {
 				/* Calculate public key hash */
 				rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
 							  (void *)pk_ptr,
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 42e157b..888a824 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -190,11 +190,11 @@
 static int load_mbr_entries(uintptr_t image_handle)
 {
 	mbr_entry_t mbr_entry;
-	int i;
+	unsigned int i;
 
 	list.entry_count = MBR_PRIMARY_ENTRY_NUMBER;
 
-	for (i = 0; i < list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		load_mbr_entry(image_handle, &mbr_entry, i);
 		list.list[i].start = mbr_entry.first_lba * 512;
 		list.list[i].length = mbr_entry.sector_nums * 512;
@@ -244,7 +244,7 @@
 		return result;
 	}
 
-	for (i = 0; i < (unsigned int)list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		result = load_gpt_entry(image_handle, &entry);
 		if (result != 0) {
 			VERBOSE("Failed to load gpt entry data(%u) error is (%i)\n",
@@ -441,9 +441,9 @@
  */
 const partition_entry_t *get_partition_entry(const char *name)
 {
-	int i;
+	unsigned int i;
 
-	for (i = 0; i < list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		if (strcmp(name, list.list[i].name) == 0) {
 			return &list.list[i];
 		}
@@ -457,9 +457,9 @@
 const partition_entry_t *get_partition_entry_by_type(
 	const struct efi_guid *type_guid)
 {
-	int i;
+	unsigned int i;
 
-	for (i = 0; i < list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		if (guidcmp(type_guid, &list.list[i].type_guid) == 0) {
 			return &list.list[i];
 		}
@@ -474,9 +474,9 @@
 const partition_entry_t *get_partition_entry_by_guid(
 	const struct efi_guid *part_guid)
 {
-	int i;
+	unsigned int i;
 
-	for (i = 0; i < list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		if (guidcmp(part_guid, &list.list[i].part_guid) == 0) {
 			return &list.list[i];
 		}
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index be722f3..66988d7 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -129,7 +129,11 @@
 #define DT_SDMMC2_COMPAT		"st,stm32-sdmmc2"
 #endif
 
+#if STM32MP13 || STM32MP15
 #define SDMMC_FIFO_SIZE			64U
+#else
+#define SDMMC_FIFO_SIZE			1024U
+#endif
 
 #define STM32MP_MMC_INIT_FREQ			U(400000)	/*400 KHz*/
 #define STM32MP_SD_NORMAL_SPEED_MAX_FREQ	U(25000000)	/*25 MHz*/
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 8a4c071..ee86b7e 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -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.
  * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -1401,6 +1401,8 @@
 #define RGSR_EL1		S3_0_C1_C0_5
 #define GCR_EL1			S3_0_C1_C0_6
 
+#define GCR_EL1_RRND_BIT	(UL(1) << 16)
+
 /*******************************************************************************
  * Armv8.5 - Random Number Generator Registers
  ******************************************************************************/
diff --git a/include/bl31/bl31.h b/include/bl31/bl31.h
index 1d58ef9..ed5374e 100644
--- a/include/bl31/bl31.h
+++ b/include/bl31/bl31.h
@@ -22,6 +22,5 @@
 void bl31_register_rmm_init(int32_t (*func)(void));
 void bl31_warm_entrypoint(void);
 void bl31_main(void);
-void bl31_lib_init(void);
 
 #endif /* BL31_H */
diff --git a/include/bl31/sync_handle.h b/include/bl31/sync_handle.h
index ae61f31..394252b 100644
--- a/include/bl31/sync_handle.h
+++ b/include/bl31/sync_handle.h
@@ -58,6 +58,8 @@
 /* Handler for injecting UNDEF exception to lower EL */
 void inject_undef64(cpu_context_t *ctx);
 
+u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el);
+
 /* Prototypes for system register emulation handlers provided by platforms. */
 int plat_handle_impdef_trap(uint64_t esr_el3, cpu_context_t *ctx);
 int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx);
diff --git a/include/drivers/auth/mbedtls/mbedtls_config-2.h b/include/drivers/auth/mbedtls/mbedtls_config-2.h
deleted file mode 100644
index 01e261a..0000000
--- a/include/drivers/auth/mbedtls/mbedtls_config-2.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 2015-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
-/*
- * Key algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_RSA			1
-#define TF_MBEDTLS_ECDSA		2
-#define TF_MBEDTLS_RSA_AND_ECDSA	3
-
-#define TF_MBEDTLS_USE_RSA (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA \
-		|| TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA)
-#define TF_MBEDTLS_USE_ECDSA (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA \
-		|| TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA)
-
-/*
- * Hash algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_SHA256		1
-#define TF_MBEDTLS_SHA384		2
-#define TF_MBEDTLS_SHA512		3
-
-/*
- * Configuration file to build mbed TLS with the required features for
- * Trusted Boot
- */
-
-#define MBEDTLS_PLATFORM_MEMORY
-#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
-/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */
-#define MBEDTLS_PLATFORM_SNPRINTF_ALT
-
-#define MBEDTLS_PKCS1_V21
-
-#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
-#define MBEDTLS_X509_CHECK_KEY_USAGE
-#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
-
-#define MBEDTLS_ASN1_PARSE_C
-#define MBEDTLS_ASN1_WRITE_C
-
-#define MBEDTLS_BASE64_C
-#define MBEDTLS_BIGNUM_C
-
-#define MBEDTLS_ERROR_C
-#define MBEDTLS_MD_C
-
-#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
-#define MBEDTLS_OID_C
-
-#define MBEDTLS_PK_C
-#define MBEDTLS_PK_PARSE_C
-#define MBEDTLS_PK_WRITE_C
-
-#define MBEDTLS_PLATFORM_C
-
-#if TF_MBEDTLS_USE_ECDSA
-#define MBEDTLS_ECDSA_C
-#define MBEDTLS_ECP_C
-#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
-#define MBEDTLS_ECP_NO_INTERNAL_RNG
-#endif
-#if TF_MBEDTLS_USE_RSA
-#define MBEDTLS_RSA_C
-#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
-#endif
-
-#define MBEDTLS_SHA256_C
-
-/*
- * If either Trusted Boot or Measured Boot require a stronger algorithm than
- * SHA-256, pull in SHA-512 support.
- */
-#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256) /* TBB hash algo */
-#define	MBEDTLS_SHA512_C
-#else
-   /* TBB uses SHA-256, what about measured boot? */
-#if defined(TF_MBEDTLS_MBOOT_USE_SHA512)
-#define MBEDTLS_SHA512_C
-#endif
-#endif
-
-#define MBEDTLS_VERSION_C
-
-#define MBEDTLS_X509_USE_C
-#define MBEDTLS_X509_CRT_PARSE_C
-
-#if TF_MBEDTLS_USE_AES_GCM
-#define MBEDTLS_AES_C
-#define MBEDTLS_CIPHER_C
-#define MBEDTLS_GCM_C
-#endif
-
-/* MPI / BIGNUM options */
-#define MBEDTLS_MPI_WINDOW_SIZE			2
-
-#if TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE <= 2048
-#define MBEDTLS_MPI_MAX_SIZE			256
-#else
-#define MBEDTLS_MPI_MAX_SIZE			512
-#endif
-#else
-#define MBEDTLS_MPI_MAX_SIZE			256
-#endif
-
-/* Memory buffer allocator options */
-#define MBEDTLS_MEMORY_ALIGN_MULTIPLE		8
-
-/*
- * Prevent the use of 128-bit division which
- * creates dependency on external libraries.
- */
-#define MBEDTLS_NO_UDBL_DIVISION
-
-#ifndef __ASSEMBLER__
-/* System headers required to build mbed TLS with the current configuration */
-#include <stdlib.h>
-#include <mbedtls/check_config.h>
-#endif
-
-/*
- * Determine Mbed TLS heap size
- * 13312 = 13*1024
- * 11264 = 11*1024
- * 7168  = 7*1024
- */
-#if TF_MBEDTLS_USE_ECDSA
-#define TF_MBEDTLS_HEAP_SIZE		U(13312)
-#elif TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE <= 2048
-#define TF_MBEDTLS_HEAP_SIZE		U(7168)
-#else
-#define TF_MBEDTLS_HEAP_SIZE		U(11264)
-#endif
-#endif
-
-/*
- * Warn if errors from certain functions are ignored.
- *
- * The warnings are always enabled (where supported) for critical functions
- * where ignoring the return value is almost always a bug. This macro extends
- * the warnings to more functions.
- */
-#define MBEDTLS_CHECK_RETURN_WARNING
-
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h
index 794d613..b44526a 100644
--- a/include/drivers/measured_boot/event_log/event_log.h
+++ b/include/drivers/measured_boot/event_log/event_log.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -43,51 +43,6 @@
 
 #define MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
 
-/*
- * Each event log entry has some metadata (i.e. a string) that identifies
- * what is measured.These macros define these strings.
- * Note that these strings follow the standardization recommendations
- * defined in the Arm Server Base Security Guide (a.k.a. SBSG, Arm DEN 0086),
- * where applicable. They should not be changed in the code.
- * Where the SBSG does not make recommendations, we are free to choose any
- * naming convention.
- * The key thing is to choose meaningful strings so that when the TPM event
- * log is used in attestation, the different components can be identified.
- */
-#define EVLOG_BL2_STRING		"BL_2"
-#define EVLOG_BL31_STRING		"SECURE_RT_EL3"
-#if defined(SPD_opteed)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_OPTEE"
-#elif defined(SPD_tspd)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_TSPD"
-#elif defined(SPD_tlkd)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_TLKD"
-#elif defined(SPD_trusty)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_TRUSTY"
-#else
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_UNKNOWN"
-#endif
-#define	EVLOG_BL32_EXTRA1_STRING	"SECURE_RT_EL1_OPTEE_EXTRA1"
-#define	EVLOG_BL32_EXTRA2_STRING	"SECURE_RT_EL1_OPTEE_EXTRA2"
-#define EVLOG_BL33_STRING		"BL_33"
-#define EVLOG_FW_CONFIG_STRING		"FW_CONFIG"
-#define EVLOG_HW_CONFIG_STRING		"HW_CONFIG"
-#define EVLOG_NT_FW_CONFIG_STRING	"NT_FW_CONFIG"
-#define EVLOG_SCP_BL2_STRING		"SYS_CTRL_2"
-#define EVLOG_SOC_FW_CONFIG_STRING	"SOC_FW_CONFIG"
-#define EVLOG_STM32_STRING		"STM32"
-#define EVLOG_TB_FW_CONFIG_STRING	"TB_FW_CONFIG"
-#define	EVLOG_TOS_FW_CONFIG_STRING	"TOS_FW_CONFIG"
-#define EVLOG_RMM_STRING 		"RMM"
-#define EVLOG_SP1_STRING		"SP1"
-#define EVLOG_SP2_STRING		"SP2"
-#define EVLOG_SP3_STRING		"SP3"
-#define EVLOG_SP4_STRING		"SP4"
-#define EVLOG_SP5_STRING		"SP5"
-#define EVLOG_SP6_STRING		"SP6"
-#define EVLOG_SP7_STRING		"SP7"
-#define EVLOG_SP8_STRING		"SP8"
-
 typedef struct {
 	unsigned int id;
 	const char *name;
diff --git a/include/drivers/measured_boot/metadata.h b/include/drivers/measured_boot/metadata.h
new file mode 100644
index 0000000..5e17a83
--- /dev/null
+++ b/include/drivers/measured_boot/metadata.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef METADATA_H
+#define METADATA_H
+
+/* Minimum measurement value size that can be requested to store */
+#define MEASUREMENT_VALUE_MIN_SIZE	32U
+/* Maximum measurement value size that can be requested to store */
+#define MEASUREMENT_VALUE_MAX_SIZE	64U
+/* Minimum signer id size that can be requested to store */
+#define SIGNER_ID_MIN_SIZE		MEASUREMENT_VALUE_MIN_SIZE
+/* Maximum signer id size that can be requested to store */
+#define SIGNER_ID_MAX_SIZE		MEASUREMENT_VALUE_MAX_SIZE
+/* The theoretical maximum image version is: "255.255.65535\0" */
+#define VERSION_MAX_SIZE		14U
+/* Example sw_type: "BL_2, BL_33, etc." */
+#define SW_TYPE_MAX_SIZE		32U
+
+/*
+ * Images, measured during the boot process, have some associated metadata.
+ * One of these types of metadata is the image identifier strings. These macros
+ * define these strings. They are used across the different measured boot
+ * backends.
+ * Note that these strings follow the standardization recommendations
+ * defined in the Arm Server Base Security Guide (a.k.a. SBSG, Arm DEN 0086),
+ * where applicable. They should not be changed in the code.
+ * Where the SBSG does not make recommendations, we are free to choose any
+ * naming convention.
+ * The key thing is to choose meaningful strings so that when the measured boot
+ * metadata is used in attestation, the different components can be identified.
+ */
+#define MBOOT_BL2_IMAGE_STRING		"BL_2"
+#define MBOOT_BL31_IMAGE_STRING		"SECURE_RT_EL3"
+#if defined(SPD_opteed)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_OPTEE"
+#elif defined(SPD_tspd)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_TSPD"
+#elif defined(SPD_tlkd)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_TLKD"
+#elif defined(SPD_trusty)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_TRUSTY"
+#elif defined(SPD_spmd)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_SPMD"
+#else
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_UNKNOWN"
+#endif /* SPD_opteed */
+#define MBOOT_BL32_EXTRA1_IMAGE_STRING	"SECURE_RT_EL1_OPTEE_EXTRA1"
+#define MBOOT_BL32_EXTRA2_IMAGE_STRING	"SECURE_RT_EL1_OPTEE_EXTRA2"
+#define MBOOT_BL33_IMAGE_STRING		"BL_33"
+#define MBOOT_FW_CONFIG_STRING		"FW_CONFIG"
+#define MBOOT_HW_CONFIG_STRING		"HW_CONFIG"
+#define MBOOT_NT_FW_CONFIG_STRING	"NT_FW_CONFIG"
+#define MBOOT_SCP_BL2_IMAGE_STRING	"SYS_CTRL_2"
+#define MBOOT_SOC_FW_CONFIG_STRING	"SOC_FW_CONFIG"
+#define MBOOT_STM32_STRING		"STM32"
+#define MBOOT_TB_FW_CONFIG_STRING	"TB_FW_CONFIG"
+#define MBOOT_TOS_FW_CONFIG_STRING	"TOS_FW_CONFIG"
+#define MBOOT_RMM_IMAGE_STRING		"RMM"
+#define MBOOT_SP1_STRING		"SP1"
+#define MBOOT_SP2_STRING		"SP2"
+#define MBOOT_SP3_STRING		"SP3"
+#define MBOOT_SP4_STRING		"SP4"
+#define MBOOT_SP5_STRING		"SP5"
+#define MBOOT_SP6_STRING		"SP6"
+#define MBOOT_SP7_STRING		"SP7"
+#define MBOOT_SP8_STRING		"SP8"
+
+#endif /* METADATA_H */
diff --git a/include/drivers/measured_boot/rss/dice_prot_env.h b/include/drivers/measured_boot/rss/dice_prot_env.h
new file mode 100644
index 0000000..6f754f5
--- /dev/null
+++ b/include/drivers/measured_boot/rss/dice_prot_env.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DICE_PROT_ENV_H
+#define DICE_PROT_ENV_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <drivers/measured_boot/metadata.h>
+
+#define DPE_INVALID_ID	UINT32_MAX
+
+struct dpe_metadata {
+	unsigned int id;
+	uint32_t cert_id;
+	uint8_t signer_id[SIGNER_ID_MAX_SIZE];
+	size_t  signer_id_size;
+	uint8_t version[VERSION_MAX_SIZE];
+	size_t  version_size;
+	uint8_t sw_type[SW_TYPE_MAX_SIZE];
+	size_t  sw_type_size;
+	bool allow_new_context_to_derive;
+	bool retain_parent_context;
+	bool create_certificate;
+	void *pk_oid;
+};
+
+void dpe_init(struct dpe_metadata *metadata);
+
+/* Returns 0 in case of success otherwise -1. */
+int dpe_measure_and_record(struct dpe_metadata *metadata,
+			   uintptr_t data_base, uint32_t data_size,
+			   uint32_t data_id);
+
+int dpe_set_signer_id(struct dpe_metadata *metadata,
+		      const void *pk_oid, const void *pk_ptr, size_t pk_len);
+
+/* Child components inherit their first valid context handle from their parents.
+ * How to share context handle is platform specific.
+ */
+void plat_dpe_share_context_handle(int *ctx_handle);
+void plat_dpe_get_context_handle(int *ctx_handle);
+
+#endif /* DICE_PROT_ENV_H */
diff --git a/include/drivers/measured_boot/rss/rss_measured_boot.h b/include/drivers/measured_boot/rss/rss_measured_boot.h
index 7ab517c..38f7d4e 100644
--- a/include/drivers/measured_boot/rss/rss_measured_boot.h
+++ b/include/drivers/measured_boot/rss/rss_measured_boot.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,27 +10,10 @@
 #include <stdint.h>
 
 #include <common/debug.h>
-#include <measured_boot.h>
+#include <drivers/measured_boot/metadata.h>
 
 #define RSS_MBOOT_INVALID_ID	UINT32_MAX
 
-/*
- * Each boot measurement has some metadata (i.e. a string) that identifies
- * what was measured and how. The sw_type field of the rss_mboot_metadata
- * structure represents the role of the software component that was measured.
- * The below macros define strings suitable for the sw_type.
- * The key thing is to choose meaningful strings so that when the attestation
- * token is verified, then the different components can be identified.
- */
-#define RSS_MBOOT_BL2_STRING		"BL_2"
-#define RSS_MBOOT_BL31_STRING		"SECURE_RT_EL3"
-#define RSS_MBOOT_HW_CONFIG_STRING	"HW_CONFIG"
-#define RSS_MBOOT_FW_CONFIG_STRING	"FW_CONFIG"
-#define RSS_MBOOT_TB_FW_CONFIG_STRING	"TB_FW_CONFIG"
-#define RSS_MBOOT_SOC_FW_CONFIG_STRING	"SOC_FW_CONFIG"
-#define RSS_MBOOT_RMM_STRING		"RMM"
-
-
 struct rss_mboot_metadata {
 	unsigned int id;
 	uint8_t slot;
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
index 4183570..9e22d34 100644
--- a/include/drivers/partition/partition.h
+++ b/include/drivers/partition/partition.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,7 +41,7 @@
 
 typedef struct partition_entry_list {
 	partition_entry_t	list[PLAT_PARTITION_MAX_ENTRIES];
-	int			entry_count;
+	unsigned int		entry_count;
 } partition_entry_list_t;
 
 int load_partition_table(unsigned int image_id);
diff --git a/include/lib/cpus/aarch64/cortex_a715.h b/include/lib/cpus/aarch64/cortex_a715.h
index 366894d..c7f50db 100644
--- a/include/lib/cpus/aarch64/cortex_a715.h
+++ b/include/lib/cpus/aarch64/cortex_a715.h
@@ -13,6 +13,11 @@
 #define CORTEX_A715_BHB_LOOP_COUNT				U(38)
 
 /*******************************************************************************
+ * CPU Auxiliary Control register 1 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A715_CPUACTLR_EL1				S3_0_C15_C1_0
+
+/*******************************************************************************
  * CPU Auxiliary Control register 2 specific definitions.
  ******************************************************************************/
 #define CORTEX_A715_CPUACTLR2_EL1				S3_0_C15_C1_1
@@ -22,6 +27,11 @@
  ******************************************************************************/
 #define CORTEX_A715_CPUECTLR_EL1				S3_0_C15_C1_4
 
+#define CORTEX_A715_CPUPSELR_EL3				S3_6_C15_C8_0
+#define CORTEX_A715_CPUPCR_EL3					S3_6_C15_C8_1
+#define CORTEX_A715_CPUPOR_EL3					S3_6_C15_C8_2
+#define CORTEX_A715_CPUPMR_EL3					S3_6_C15_C8_3
+
 /*******************************************************************************
  * CPU Power Control register specific definitions
  ******************************************************************************/
diff --git a/include/lib/dice/dice.h b/include/lib/dice/dice.h
new file mode 100644
index 0000000..cf54942
--- /dev/null
+++ b/include/lib/dice/dice.h
@@ -0,0 +1,166 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#ifndef DICE_DICE_H_
+#define DICE_DICE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DICE_CDI_SIZE 32
+#define DICE_HASH_SIZE 64
+#define DICE_HIDDEN_SIZE 64
+#define DICE_INLINE_CONFIG_SIZE 64
+#define DICE_PRIVATE_KEY_SEED_SIZE 32
+#define DICE_ID_SIZE 20
+
+typedef enum {
+  kDiceResultOk,
+  kDiceResultInvalidInput,
+  kDiceResultBufferTooSmall,
+  kDiceResultPlatformError,
+} DiceResult;
+
+typedef enum {
+  kDiceModeNotInitialized,
+  kDiceModeNormal,
+  kDiceModeDebug,
+  kDiceModeMaintenance,
+} DiceMode;
+
+typedef enum {
+  kDiceConfigTypeInline,
+  kDiceConfigTypeDescriptor,
+} DiceConfigType;
+
+// Contains a full set of input values describing the target program or system.
+// See the Open Profile for DICE specification for a detailed explanation of
+// these inputs.
+//
+// Fields:
+//    code_hash: A hash or similar representation of the target code.
+//    code_descriptor: An optional descriptor to be included in the certificate.
+//        This descriptor is opaque to the DICE flow and is included verbatim
+//        in the certificate with no validation. May be null.
+//    code_descriptor_size: The size in bytes of |code_descriptor|.
+//    config_type: Indicates how to interpret the remaining config-related
+//        fields. If the type is 'inline', then the 64 byte configuration input
+//        value must be provided in |config_value| and |config_descriptor| is
+//        ignored. If the type is 'descriptor', then |config_descriptor| is
+//        hashed to get the configuration input value and |config_value| is
+//        ignored.
+//    config_value: A 64-byte configuration input value when |config_type| is
+//        kDiceConfigTypeInline. Otherwise, this field is ignored.
+//    config_descriptor: A descriptor to be hashed for the configuration input
+//        value when |config_type| is kDiceConfigTypeDescriptor. Otherwise,
+//        this field is ignored and may be null.
+//    config_descriptor_size: The size in bytes of |config_descriptor|.
+//    authority_hash: A hash or similar representation of the authority used to
+//        verify the target code. If the code is not verified or the authority
+//        is implicit, for example hard coded as part of the code currently
+//        executing, then this value should be set to all zero bytes.
+//    authority_descriptor: An optional descriptor to be included in the
+//        certificate. This descriptor is opaque to the DICE flow and is
+//        included verbatim in the certificate with no validation. May be null.
+//    authority_descriptor_size: The size in bytes of |authority_descriptor|.
+//    mode: The current operating mode.
+//    hidden: Additional input which will not appear in certificates. If this is
+//        not used it should be set to all zero bytes.
+typedef struct DiceInputValues_ {
+  uint8_t code_hash[DICE_HASH_SIZE];
+  const uint8_t* code_descriptor;
+  size_t code_descriptor_size;
+  DiceConfigType config_type;
+  uint8_t config_value[DICE_INLINE_CONFIG_SIZE];
+  const uint8_t* config_descriptor;
+  size_t config_descriptor_size;
+  uint8_t authority_hash[DICE_HASH_SIZE];
+  const uint8_t* authority_descriptor;
+  size_t authority_descriptor_size;
+  DiceMode mode;
+  uint8_t hidden[DICE_HIDDEN_SIZE];
+} DiceInputValues;
+
+// Derives a |cdi_private_key_seed| from a |cdi_attest| value. On success
+// populates |cdi_private_key_seed| and returns kDiceResultOk.
+DiceResult DiceDeriveCdiPrivateKeySeed(
+    void* context, const uint8_t cdi_attest[DICE_CDI_SIZE],
+    uint8_t cdi_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE]);
+
+// Derives an |id| from a |cdi_public_key| value. Because public keys can vary
+// in length depending on the algorithm, the |cdi_public_key_size| in bytes must
+// be provided. When interpreted as an integer, |id| is big-endian. On success
+// populates |id| and returns kDiceResultOk.
+DiceResult DiceDeriveCdiCertificateId(void* context,
+                                      const uint8_t* cdi_public_key,
+                                      size_t cdi_public_key_size,
+                                      uint8_t id[DICE_ID_SIZE]);
+
+// Executes the main DICE flow.
+//
+// Given a full set of input values and the current CDI values, computes the
+// next CDI values and a matching certificate. See the Open Profile for DICE
+// specification for a detailed explanation of this flow.
+// In certain cases, the caller may not need to generate the CDI certificate.
+// The caller should signal this by setting the certificate parameters to
+// null/zero values appropriately.
+//
+// Parameters:
+//    context: Context provided by the caller that is opaque to this library
+//        but is passed through to the integration-provided operations in
+//        dice/ops.h. The value is, therefore, integration-specific and may be
+//        null.
+//    current_cdi_attest, current_cdi_seal: The current CDI values as produced
+//        by a previous DICE flow. If this is the first DICE flow in a system,
+//        the Unique Device Secret (UDS) should be used for both of these
+//        arguments.
+//    input_values: A set of input values describing the target program or
+//        system.
+//    next_cdi_certificate_buffer_size: The size in bytes of the buffer pointed
+//        to by the |next_cdi_certificate| argument. This should be set to zero
+//        if next CDI certificate should not be computed.
+//    next_cdi_certificate: On success, will be populated with the generated
+//        certificate, up to |next_cdi_certificate_buffer_size| in size. If the
+//        certificate cannot fit in the buffer, |next_cdi_certificate_size| is
+//        populated with the required size and kDiceResultBufferTooSmall is
+//        returned. This should be set to NULL if next CDI certificate should
+//        not be computed.
+//    next_cdi_certificate_actual_size: On success, will be populated with the
+//        size, in bytes, of the certificate data written to
+//        |next_cdi_certificate|. If kDiceResultBufferTooSmall is returned, will
+//        be populated with the required buffer size. This should be set to NULL
+//        if next CDI certificate should not be computed.
+//    next_cdi_attest: On success, will be populated with the next CDI value for
+//        attestation.
+//    next_cdi_seal: On success, will be populated with the next CDI value for
+//        sealing.
+DiceResult DiceMainFlow(void* context,
+                        const uint8_t current_cdi_attest[DICE_CDI_SIZE],
+                        const uint8_t current_cdi_seal[DICE_CDI_SIZE],
+                        const DiceInputValues* input_values,
+                        size_t next_cdi_certificate_buffer_size,
+                        uint8_t* next_cdi_certificate,
+                        size_t* next_cdi_certificate_actual_size,
+                        uint8_t next_cdi_attest[DICE_CDI_SIZE],
+                        uint8_t next_cdi_seal[DICE_CDI_SIZE]);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // DICE_DICE_H_
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index d5bd890..44efee5 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -7,6 +7,7 @@
 #ifndef CONTEXT_H
 #define CONTEXT_H
 
+#include <lib/el3_runtime/context_el2.h>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/utils_def.h>
 
@@ -157,102 +158,11 @@
  */
 #define CTX_EL1_SYSREGS_END		CTX_MTE_REGS_END
 
-/*
- * EL2 register set
- */
-
-#if CTX_INCLUDE_EL2_REGS
-/* For later discussion
- * ICH_AP0R<n>_EL2
- * ICH_AP1R<n>_EL2
- * AMEVCNTVOFF0<n>_EL2
- * AMEVCNTVOFF1<n>_EL2
- * ICH_LR<n>_EL2
- */
-#define CTX_EL2_SYSREGS_OFFSET	(CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)
-
-#define CTX_ACTLR_EL2		U(0x0)
-#define CTX_AFSR0_EL2		U(0x8)
-#define CTX_AFSR1_EL2		U(0x10)
-#define CTX_AMAIR_EL2		U(0x18)
-#define CTX_CNTHCTL_EL2		U(0x20)
-#define CTX_CNTVOFF_EL2		U(0x28)
-#define CTX_CPTR_EL2		U(0x30)
-#define CTX_DBGVCR32_EL2	U(0x38)
-#define CTX_ELR_EL2		U(0x40)
-#define CTX_ESR_EL2		U(0x48)
-#define CTX_FAR_EL2		U(0x50)
-#define CTX_HACR_EL2		U(0x58)
-#define CTX_HCR_EL2		U(0x60)
-#define CTX_HPFAR_EL2		U(0x68)
-#define CTX_HSTR_EL2		U(0x70)
-#define CTX_ICC_SRE_EL2		U(0x78)
-#define CTX_ICH_HCR_EL2		U(0x80)
-#define CTX_ICH_VMCR_EL2	U(0x88)
-#define CTX_MAIR_EL2		U(0x90)
-#define CTX_MDCR_EL2		U(0x98)
-#define CTX_PMSCR_EL2		U(0xa0)
-#define CTX_SCTLR_EL2		U(0xa8)
-#define CTX_SPSR_EL2		U(0xb0)
-#define CTX_SP_EL2		U(0xb8)
-#define CTX_TCR_EL2		U(0xc0)
-#define CTX_TPIDR_EL2		U(0xc8)
-#define CTX_TTBR0_EL2		U(0xd0)
-#define CTX_VBAR_EL2		U(0xd8)
-#define CTX_VMPIDR_EL2		U(0xe0)
-#define CTX_VPIDR_EL2		U(0xe8)
-#define CTX_VTCR_EL2		U(0xf0)
-#define CTX_VTTBR_EL2		U(0xf8)
-
-// Only if MTE registers in use
-#define CTX_TFSR_EL2		U(0x100)
-
-// Starting with Armv8.6
-#define CTX_HDFGRTR_EL2		U(0x108)
-#define CTX_HAFGRTR_EL2		U(0x110)
-#define CTX_HDFGWTR_EL2		U(0x118)
-#define CTX_HFGITR_EL2		U(0x120)
-#define CTX_HFGRTR_EL2		U(0x128)
-#define CTX_HFGWTR_EL2		U(0x130)
-#define CTX_CNTPOFF_EL2		U(0x138)
-
-// Starting with Armv8.4
-#define CTX_CONTEXTIDR_EL2	U(0x140)
-#define CTX_TTBR1_EL2		U(0x148)
-#define CTX_VDISR_EL2		U(0x150)
-#define CTX_VSESR_EL2		U(0x158)
-#define CTX_VNCR_EL2		U(0x160)
-#define CTX_TRFCR_EL2		U(0x168)
-
-// Starting with Armv8.5
-#define CTX_SCXTNUM_EL2		U(0x170)
-
-// Register for FEAT_HCX
-#define CTX_HCRX_EL2            U(0x178)
-
-// Starting with Armv8.9
-#define CTX_TCR2_EL2            U(0x180)
-#define CTX_POR_EL2             U(0x188)
-#define CTX_PIRE0_EL2           U(0x190)
-#define CTX_PIR_EL2             U(0x198)
-#define CTX_S2PIR_EL2		U(0x1a0)
-#define CTX_GCSCR_EL2           U(0x1a8)
-#define CTX_GCSPR_EL2           U(0x1b0)
-
-/* Align to the next 16 byte boundary */
-#define CTX_EL2_SYSREGS_END	U(0x1c0)
-
-#endif /* CTX_INCLUDE_EL2_REGS */
-
 /*******************************************************************************
  * Constants that allow assembler code to access members of and the 'fp_regs'
  * structure at their correct offsets.
  ******************************************************************************/
-#if CTX_INCLUDE_EL2_REGS
-# define CTX_FPREGS_OFFSET	(CTX_EL2_SYSREGS_OFFSET + CTX_EL2_SYSREGS_END)
-#else
 # define CTX_FPREGS_OFFSET	(CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)
-#endif
 #if CTX_INCLUDE_FPREGS
 #define CTX_FP_Q0		U(0x0)
 #define CTX_FP_Q1		U(0x10)
@@ -293,10 +203,10 @@
 #define CTX_FPREGS_END		U(0x220) /* Align to the next 16 byte boundary */
 #else
 #define CTX_FPREGS_END		U(0x210) /* Align to the next 16 byte boundary */
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
 #else
 #define CTX_FPREGS_END		U(0)
-#endif
+#endif /* CTX_INCLUDE_FPREGS */
 
 /*******************************************************************************
  * Registers related to CVE-2018-3639
@@ -373,9 +283,7 @@
 /* Constants to determine the size of individual context structures */
 #define CTX_GPREG_ALL		(CTX_GPREGS_END >> DWORD_SHIFT)
 #define CTX_EL1_SYSREGS_ALL	(CTX_EL1_SYSREGS_END >> DWORD_SHIFT)
-#if CTX_INCLUDE_EL2_REGS
-# define CTX_EL2_SYSREGS_ALL	(CTX_EL2_SYSREGS_END >> DWORD_SHIFT)
-#endif
+
 #if CTX_INCLUDE_FPREGS
 # define CTX_FPREG_ALL		(CTX_FPREGS_END >> DWORD_SHIFT)
 #endif
@@ -403,15 +311,6 @@
  */
 DEFINE_REG_STRUCT(el1_sysregs, CTX_EL1_SYSREGS_ALL);
 
-
-/*
- * AArch64 EL2 system register context structure for preserving the
- * architectural state during world switches.
- */
-#if CTX_INCLUDE_EL2_REGS
-DEFINE_REG_STRUCT(el2_sysregs, CTX_EL2_SYSREGS_ALL);
-#endif
-
 /*
  * AArch64 floating point register context structure for preserving
  * the floating point state during switches from one security state to
@@ -460,19 +359,24 @@
 	gp_regs_t gpregs_ctx;
 	el3_state_t el3state_ctx;
 	el1_sysregs_t el1_sysregs_ctx;
-#if CTX_INCLUDE_EL2_REGS
-	el2_sysregs_t el2_sysregs_ctx;
-#endif
+
 #if CTX_INCLUDE_FPREGS
 	fp_regs_t fpregs_ctx;
 #endif
 	cve_2018_3639_t cve_2018_3639_ctx;
+
 #if CTX_INCLUDE_PAUTH_REGS
 	pauth_t pauth_ctx;
 #endif
+
 #if CTX_INCLUDE_MPAM_REGS
 	mpam_t	mpam_ctx;
 #endif
+
+#if CTX_INCLUDE_EL2_REGS
+	el2_sysregs_t el2_sysregs_ctx;
+#endif
+
 } cpu_context_t;
 
 /*
@@ -512,28 +416,30 @@
  */
 CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx),
 	assert_core_context_gp_offset_mismatch);
+
+CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx),
+	assert_core_context_el3state_offset_mismatch);
+
 CASSERT(CTX_EL1_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el1_sysregs_ctx),
 	assert_core_context_el1_sys_offset_mismatch);
-#if CTX_INCLUDE_EL2_REGS
-CASSERT(CTX_EL2_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el2_sysregs_ctx),
-	assert_core_context_el2_sys_offset_mismatch);
-#endif
+
 #if CTX_INCLUDE_FPREGS
 CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx),
 	assert_core_context_fp_offset_mismatch);
-#endif
-CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx),
-	assert_core_context_el3state_offset_mismatch);
+#endif /* CTX_INCLUDE_FPREGS */
+
 CASSERT(CTX_CVE_2018_3639_OFFSET == __builtin_offsetof(cpu_context_t, cve_2018_3639_ctx),
 	assert_core_context_cve_2018_3639_offset_mismatch);
+
 #if CTX_INCLUDE_PAUTH_REGS
 CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx),
 	assert_core_context_pauth_offset_mismatch);
-#endif
+#endif /* CTX_INCLUDE_PAUTH_REGS */
+
 #if CTX_INCLUDE_MPAM_REGS
 CASSERT(CTX_MPAM_REGS_OFFSET == __builtin_offsetof(cpu_context_t, mpam_ctx),
 	assert_core_context_mpam_offset_mismatch);
-#endif
+#endif /* CTX_INCLUDE_MPAM_REGS */
 
 /*
  * Helper macro to set the general purpose registers that correspond to
diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h
new file mode 100644
index 0000000..4ad9634
--- /dev/null
+++ b/include/lib/el3_runtime/context_el2.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CONTEXT_EL2_H
+#define CONTEXT_EL2_H
+
+#ifndef __ASSEMBLER__
+/*******************************************************************************
+ * EL2 Registers:
+ * AArch64 EL2 system register context structure for preserving the
+ * architectural state during world switches.
+ ******************************************************************************/
+#if CTX_INCLUDE_EL2_REGS
+typedef struct el2_common_regs {
+	uint64_t actlr_el2;
+	uint64_t afsr0_el2;
+	uint64_t afsr1_el2;
+	uint64_t amair_el2;
+	uint64_t cnthctl_el2;
+	uint64_t cntvoff_el2;
+	uint64_t cptr_el2;
+	uint64_t dbgvcr32_el2;
+	uint64_t elr_el2;
+	uint64_t esr_el2;
+	uint64_t far_el2;
+	uint64_t hacr_el2;
+	uint64_t hcr_el2;
+	uint64_t hpfar_el2;
+	uint64_t hstr_el2;
+	uint64_t icc_sre_el2;
+	uint64_t ich_hcr_el2;
+	uint64_t ich_vmcr_el2;
+	uint64_t mair_el2;
+	uint64_t mdcr_el2;
+	uint64_t pmscr_el2;
+	uint64_t sctlr_el2;
+	uint64_t spsr_el2;
+	uint64_t sp_el2;
+	uint64_t tcr_el2;
+	uint64_t tpidr_el2;
+	uint64_t ttbr0_el2;
+	uint64_t vbar_el2;
+	uint64_t vmpidr_el2;
+	uint64_t vpidr_el2;
+	uint64_t vtcr_el2;
+	uint64_t vttbr_el2;
+} el2_common_regs_t;
+
+typedef struct el2_mte_regs {
+	uint64_t tfsr_el2;
+} el2_mte_regs_t;
+
+typedef struct el2_fgt_regs {
+	uint64_t hdfgrtr_el2;
+	uint64_t hafgrtr_el2;
+	uint64_t hdfgwtr_el2;
+	uint64_t hfgitr_el2;
+	uint64_t hfgrtr_el2;
+	uint64_t hfgwtr_el2;
+} el2_fgt_regs_t;
+
+typedef struct el2_ecv_regs {
+	uint64_t cntpoff_el2;
+} el2_ecv_regs_t;
+
+typedef struct el2_vhe_regs {
+	uint64_t contextidr_el2;
+	uint64_t ttbr1_el2;
+} el2_vhe_regs_t;
+
+typedef struct el2_ras_regs {
+	uint64_t vdisr_el2;
+	uint64_t vsesr_el2;
+} el2_ras_regs_t;
+
+typedef struct el2_neve_regs {
+	uint64_t vncr_el2;
+} el2_neve_regs_t;
+
+typedef struct el2_trf_regs {
+	uint64_t trfcr_el2;
+} el2_trf_regs_t;
+
+typedef struct el2_csv2_regs {
+	uint64_t scxtnum_el2;
+} el2_csv2_regs_t;
+
+typedef struct el2_hcx_regs {
+	uint64_t hcrx_el2;
+} el2_hcx_regs_t;
+
+typedef struct el2_tcr2_regs {
+	uint64_t tcr2_el2;
+} el2_tcr2_regs_t;
+
+typedef struct el2_sxpoe_regs {
+	uint64_t por_el2;
+} el2_sxpoe_regs_t;
+
+typedef struct el2_sxpie_regs {
+	uint64_t pire0_el2;
+	uint64_t pir_el2;
+} el2_sxpie_regs_t;
+
+typedef struct el2_s2pie_regs {
+	uint64_t s2pir_el2;
+} el2_s2pie_regs_t;
+
+typedef struct el2_gcs_regs {
+	uint64_t gcscr_el2;
+	uint64_t gcspr_el2;
+} el2_gcs_regs_t;
+
+typedef struct el2_sysregs {
+
+	el2_common_regs_t common;
+
+#if ENABLE_FEAT_MTE
+	el2_mte_regs_t mte;
+#endif
+
+#if ENABLE_FEAT_FGT
+	el2_fgt_regs_t fgt;
+#endif
+
+#if ENABLE_FEAT_ECV
+	el2_ecv_regs_t ecv;
+#endif
+
+#if ENABLE_FEAT_VHE
+	el2_vhe_regs_t vhe;
+#endif
+
+#if ENABLE_FEAT_RAS
+	el2_ras_regs_t ras;
+#endif
+
+#if CTX_INCLUDE_NEVE_REGS
+	el2_neve_regs_t neve;
+#endif
+
+#if ENABLE_TRF_FOR_NS
+	el2_trf_regs_t trf;
+#endif
+
+#if ENABLE_FEAT_CSV2_2
+	el2_csv2_regs_t csv2;
+#endif
+
+#if ENABLE_FEAT_HCX
+	el2_hcx_regs_t hcx;
+#endif
+
+#if ENABLE_FEAT_TCR2
+	el2_tcr2_regs_t tcr2;
+#endif
+
+#if (ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE)
+	el2_sxpoe_regs_t sxpoe;
+#endif
+
+#if (ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE)
+	el2_sxpie_regs_t sxpie;
+#endif
+
+#if ENABLE_FEAT_S2PIE
+	el2_s2pie_regs_t s2pie;
+#endif
+
+#if ENABLE_FEAT_GCS
+	el2_gcs_regs_t gcs;
+#endif
+
+} el2_sysregs_t;
+
+/*
+ * Macros to access members related to individual features of the el2_sysregs_t
+ * structures.
+ */
+#define read_el2_ctx_common(ctx, reg)		(((ctx)->common).reg)
+
+#define write_el2_ctx_common(ctx, reg, val)	((((ctx)->common).reg)	\
+							= (uint64_t) (val))
+
+#if ENABLE_FEAT_MTE
+#define read_el2_ctx_mte(ctx, reg)		(((ctx)->mte).reg)
+#define write_el2_ctx_mte(ctx, reg, val)	((((ctx)->mte).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_mte(ctx, reg)		ULL(0)
+#define write_el2_ctx_mte(ctx, reg, val)
+#endif /* ENABLE_FEAT_MTE */
+
+#if ENABLE_FEAT_FGT
+#define read_el2_ctx_fgt(ctx, reg)		(((ctx)->fgt).reg)
+#define write_el2_ctx_fgt(ctx, reg, val)	((((ctx)->fgt).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_fgt(ctx, reg)		ULL(0)
+#define write_el2_ctx_fgt(ctx, reg, val)
+#endif /* ENABLE_FEAT_FGT */
+
+#if ENABLE_FEAT_ECV
+#define read_el2_ctx_ecv(ctx, reg)		(((ctx)->ecv).reg)
+#define write_el2_ctx_ecv(ctx, reg, val)	((((ctx)->ecv).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_ecv(ctx, reg)		ULL(0)
+#define write_el2_ctx_ecv(ctx, reg, val)
+#endif /* ENABLE_FEAT_ECV */
+
+#if ENABLE_FEAT_VHE
+#define read_el2_ctx_vhe(ctx, reg)		(((ctx)->vhe).reg)
+#define write_el2_ctx_vhe(ctx, reg, val)	((((ctx)->vhe).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_vhe(ctx, reg)		ULL(0)
+#define write_el2_ctx_vhe(ctx, reg, val)
+#endif /* ENABLE_FEAT_VHE */
+
+#if ENABLE_FEAT_RAS
+#define read_el2_ctx_ras(ctx, reg)		(((ctx)->ras).reg)
+#define write_el2_ctx_ras(ctx, reg, val)	((((ctx)->ras).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_ras(ctx, reg)		ULL(0)
+#define write_el2_ctx_ras(ctx, reg, val)
+#endif /* ENABLE_FEAT_RAS */
+
+#if CTX_INCLUDE_NEVE_REGS
+#define read_el2_ctx_neve(ctx, reg)		(((ctx)->neve).reg)
+#define write_el2_ctx_neve(ctx, reg, val)	((((ctx)->neve).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_neve(ctx, reg)		ULL(0)
+#define write_el2_ctx_neve(ctx, reg, val)
+#endif /* CTX_INCLUDE_NEVE_REGS */
+
+#if ENABLE_TRF_FOR_NS
+#define read_el2_ctx_trf(ctx, reg)		(((ctx)->trf).reg)
+#define write_el2_ctx_trf(ctx, reg, val)	((((ctx)->trf).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_trf(ctx, reg)		ULL(0)
+#define write_el2_ctx_trf(ctx, reg, val)
+#endif /* ENABLE_TRF_FOR_NS */
+
+#if ENABLE_FEAT_CSV2_2
+#define read_el2_ctx_csv2_2(ctx, reg)		(((ctx)->csv2).reg)
+#define write_el2_ctx_csv2_2(ctx, reg, val)	((((ctx)->csv2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_csv2_2(ctx, reg)		ULL(0)
+#define write_el2_ctx_csv2_2(ctx, reg, val)
+#endif /* ENABLE_FEAT_CSV2_2 */
+
+#if ENABLE_FEAT_HCX
+#define read_el2_ctx_hcx(ctx, reg)		(((ctx)->hcx).reg)
+#define write_el2_ctx_hcx(ctx, reg, val)	((((ctx)->hcx).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_hcx(ctx, reg)		ULL(0)
+#define write_el2_ctx_hcx(ctx, reg, val)
+#endif /* ENABLE_FEAT_HCX */
+
+#if ENABLE_FEAT_TCR2
+#define read_el2_ctx_tcr2(ctx, reg)		(((ctx)->tcr2).reg)
+#define write_el2_ctx_tcr2(ctx, reg, val)	((((ctx)->tcr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_tcr2(ctx, reg)		ULL(0)
+#define write_el2_ctx_tcr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_TCR2 */
+
+#if (ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE)
+#define read_el2_ctx_sxpoe(ctx, reg)		(((ctx)->sxpoe).reg)
+#define write_el2_ctx_sxpoe(ctx, reg, val)	((((ctx)->sxpoe).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_sxpoe(ctx, reg)		ULL(0)
+#define write_el2_ctx_sxpoe(ctx, reg, val)
+#endif /*(ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE) */
+
+#if (ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE)
+#define read_el2_ctx_sxpie(ctx, reg)		(((ctx)->sxpie).reg)
+#define write_el2_ctx_sxpie(ctx, reg, val)	((((ctx)->sxpie).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_sxpie(ctx, reg)		ULL(0)
+#define write_el2_ctx_sxpie(ctx, reg, val)
+#endif /*(ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE) */
+
+#if ENABLE_FEAT_S2PIE
+#define read_el2_ctx_s2pie(ctx, reg)		(((ctx)->s2pie).reg)
+#define write_el2_ctx_s2pie(ctx, reg, val)	((((ctx)->s2pie).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_s2pie(ctx, reg)		ULL(0)
+#define write_el2_ctx_s2pie(ctx, reg, val)
+#endif /* ENABLE_FEAT_S2PIE */
+
+#if ENABLE_FEAT_GCS
+#define read_el2_ctx_gcs(ctx, reg)		(((ctx)->gcs).reg)
+#define write_el2_ctx_gcs(ctx, reg, val)	((((ctx)->gcs).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_gcs(ctx, reg)		ULL(0)
+#define write_el2_ctx_gcs(ctx, reg, val)
+#endif /* ENABLE_FEAT_GCS */
+
+#endif /* CTX_INCLUDE_EL2_REGS */
+/******************************************************************************/
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* CONTEXT_EL2_H */
diff --git a/include/lib/psa/dice_protection_environment.h b/include/lib/psa/dice_protection_environment.h
new file mode 100644
index 0000000..61b6482
--- /dev/null
+++ b/include/lib/psa/dice_protection_environment.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef DICE_PROTECTION_ENVIRONMENT_H
+#define DICE_PROTECTION_ENVIRONMENT_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <dice.h>
+
+/* Additional defines for max size limit. These limits are set by DPE in RSS. */
+#define DICE_AUTHORITY_DESCRIPTOR_MAX_SIZE	64
+#define DICE_CONFIG_DESCRIPTOR_MAX_SIZE		64
+#define DICE_CODE_DESCRIPTOR_MAX_SIZE		32
+
+typedef int32_t dpe_error_t;
+
+#define DPE_NO_ERROR			((dpe_error_t)0)
+#define DPE_INTERNAL_ERROR		((dpe_error_t)1)
+#define DPE_INVALID_COMMAND		((dpe_error_t)2)
+#define DPE_INVALID_ARGUMENT		((dpe_error_t)3)
+#define DPE_ARGUMENT_NOT_SUPPORTED	((dpe_error_t)4)
+#define DPE_SESSION_EXHAUSTED		((dpe_error_t)5)
+
+/* Custom values in RSS based DPE implementation */
+#define DPE_INSUFFICIENT_MEMORY		((dpe_error_t)128)
+#define DPE_ERR_CBOR_FORMATTING		((dpe_error_t)129)
+
+/**
+ * Client facing API. Parameters are according to the DPE spec version r0.9
+ *
+ * \brief Performs the DICE computation to derive a new context and optionally
+ *        creates an intermediate certificate. Software component measurement
+ *        must be provided in dice_inputs.
+ *
+ * \param[in]  context_handle              Input context handle for the DPE
+ *                                         context.
+ * \param[in]  cert_id                     Logical certificate id to which derived
+ *                                         context belongs to.
+ * \param[in]  retain_parent_context       Flag to indicate whether to retain the
+ *                                         parent context. True only if a client
+ *                                         will call further DPE commands on the
+ *                                         same context.
+ * \param[in]  allow_new_context_to_derive Flag to indicate whether derived context
+ *                                         can derive further. True only if the
+ *                                         new context will load further components.
+ * \param[in]  create_certificate          Flag to indicate whether to create an
+ *                                         intermediate certificate. True only if
+ *                                         it is the last component in the layer.
+ * \param[in]  dice_inputs                 DICE input values.
+ * \param[in]  target_locality             Identifies the locality to which the
+ *                                         derived context will be bound. Could be
+ *                                         MHU id.
+ * \param[in]  return_certificate          Indicates whether to return the generated
+ *                                         certificate when create_certificate is true.
+ * \param[in]  allow_new_context_to_export Indicates whether the DPE permits export of
+ *                                         the CDI from the newly derived context.
+ * \param[in]  export_cdi                  Indicates whether to export derived CDI.
+ * \param[out] new_context_handle          New handle for the derived context.
+ * \param[out] new_parent_context_handle   New handle for the parent context.
+ * \param[out] new_certificate_buf         If create_certificate and return_certificate
+ *                                         are both true, this argument holds the new
+ *                                         certificate generated for the new context
+ * \param[in]  new_certificate_buf_size    Size of the allocated buffer for
+ *                                         new certificate.
+ * \param[out] new_certificate_actual_size Actual size of the new certificate.
+ * \param[out] exported_cdi_buf            If export_cdi is true, this is the
+ *                                         exported CDI value.
+ * \param[in]  exported_cdi_buf_size       Size of the allocated buffer for
+ *                                         exported cdi.
+ * \param[out] exported_cdi_actual_size    Actual size of the exported cdi.
+ *
+ * \return Returns error code of type dpe_error_t
+ */
+dpe_error_t dpe_derive_context(int      context_handle,
+			       uint32_t cert_id,
+			       bool     retain_parent_context,
+			       bool     allow_new_context_to_derive,
+			       bool     create_certificate,
+			       const DiceInputValues *dice_inputs,
+			       int32_t  target_locality,
+			       bool     return_certificate,
+			       bool     allow_new_context_to_export,
+			       bool     export_cdi,
+			       int     *new_context_handle,
+			       int     *new_parent_context_handle,
+			       uint8_t *new_certificate_buf,
+			       size_t   new_certificate_buf_size,
+			       size_t  *new_certificate_actual_size,
+			       uint8_t *exported_cdi_buf,
+			       size_t   exported_cdi_buf_size,
+			       size_t  *exported_cdi_actual_size);
+
+#endif /* DICE_PROTECTION_ENVIRONMENT_H */
diff --git a/include/lib/psa/measured_boot.h b/include/lib/psa/measured_boot.h
index af624a6..79cdfa0 100644
--- a/include/lib/psa/measured_boot.h
+++ b/include/lib/psa/measured_boot.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -14,21 +14,6 @@
 
 #include "psa/error.h"
 
-/* Minimum measurement value size that can be requested to store */
-#define MEASUREMENT_VALUE_MIN_SIZE	32U
-/* Maximum measurement value size that can be requested to store */
-#define MEASUREMENT_VALUE_MAX_SIZE	64U
-/* Minimum signer id size that can be requested to store */
-#define SIGNER_ID_MIN_SIZE		MEASUREMENT_VALUE_MIN_SIZE
-/* Maximum signer id size that can be requested to store */
-#define SIGNER_ID_MAX_SIZE		MEASUREMENT_VALUE_MAX_SIZE
-/* The theoretical maximum image version is: "255.255.65535\0" */
-#define VERSION_MAX_SIZE		14U
-/* Example sw_type: "BL_2, BL_33, etc." */
-#define SW_TYPE_MAX_SIZE		20U
-#define NUM_OF_MEASUREMENT_SLOTS	32U
-
-
 /**
  * Extends and stores a measurement to the requested slot.
  *
diff --git a/include/lib/psa/psa_manifest/sid.h b/include/lib/psa/psa_manifest/sid.h
index 7183112..6c15656 100644
--- a/include/lib/psa/psa_manifest/sid.h
+++ b/include/lib/psa/psa_manifest/sid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -17,7 +17,10 @@
 /******** PSA_SP_MEASURED_BOOT ********/
 #define RSS_MEASURED_BOOT_HANDLE			(0x40000110U)
 
-/******** PSA_SP_DELAGATED_ATTESTATION ********/
+/******** PSA_SP_DELEGATED_ATTESTATION ********/
 #define RSS_DELEGATED_SERVICE_HANDLE			(0x40000111U)
 
+/******** PSA_SP_DICE_PROTECTION_ENVIRONMENT ********/
+#define RSS_DPE_SERVICE_HANDLE				(0x40000112U)
+
 #endif /* PSA_MANIFEST_SID_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 4c425a7..828d43a 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -290,6 +290,12 @@
 int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
 
 #if MEASURED_BOOT
+#if DICE_PROTECTION_ENVIRONMENT
+int arm_set_nt_fw_info(int *ctx_handle);
+int arm_set_tb_fw_info(int *ctx_handle);
+int arm_get_tb_fw_info(int *ctx_handle);
+#else
+/* Specific to event log backend */
 int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size);
 int arm_set_nt_fw_info(
 /*
@@ -304,6 +310,7 @@
 		       size_t log_max_size);
 int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size,
 		       size_t *log_max_size);
+#endif /* DICE_PROTECTION_ENVIRONMENT */
 #endif /* MEASURED_BOOT */
 
 /*
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 2bb23c4..4fe3620 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -243,7 +243,7 @@
 int bl1_plat_handle_pre_image_load(unsigned int image_id);
 int bl1_plat_handle_post_image_load(unsigned int image_id);
 
-#if MEASURED_BOOT
+#if (MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT)
 void bl1_plat_mboot_init(void);
 void bl1_plat_mboot_finish(void);
 #else
@@ -253,7 +253,7 @@
 static inline void bl1_plat_mboot_finish(void)
 {
 }
-#endif /* MEASURED_BOOT */
+#endif /* MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT */
 
 /*******************************************************************************
  * Mandatory BL2 functions
@@ -273,7 +273,7 @@
 /*******************************************************************************
  * Optional BL2 functions (may be overridden)
  ******************************************************************************/
-#if MEASURED_BOOT
+#if (MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT)
 void bl2_plat_mboot_init(void);
 void bl2_plat_mboot_finish(void);
 #else
@@ -283,7 +283,7 @@
 static inline void bl2_plat_mboot_finish(void)
 {
 }
-#endif /* MEASURED_BOOT */
+#endif /* MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENTs */
 
 /*******************************************************************************
  * Mandatory BL2 at EL3 functions: Must be implemented
diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h
index 9881d1a..1a2e355 100644
--- a/include/tools_share/tbbr_oid.h
+++ b/include/tools_share/tbbr_oid.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
  */
@@ -170,6 +170,12 @@
 #define SOC_FW_CONFIG_KEY_OID			SOC_FW_CONTENT_CERT_PK_OID
 #define HW_CONFIG_KEY_OID			ZERO_OID
 
+#define SCP_BL2_IMAGE_KEY_OID			SCP_FW_CONTENT_CERT_PK_OID
+#define BL32_IMAGE_KEY_OID			TRUSTED_OS_FW_CONTENT_CERT_PK_OID
+#define TOS_FW_CONFIG_KEY_OID			TRUSTED_OS_FW_CONTENT_CERT_PK_OID
+#define BL33_IMAGE_KEY_OID			NON_TRUSTED_FW_CONTENT_CERT_PK_OID
+#define NT_FW_CONFIG_KEY_OID			NON_TRUSTED_FW_CONTENT_CERT_PK_OID
+
 #ifdef PLAT_DEF_OID
 #include <platform_oid.h>
 #endif
diff --git a/lib/cpus/aarch64/cortex_a715.S b/lib/cpus/aarch64/cortex_a715.S
index 65f3c04..abd649c 100644
--- a/lib/cpus/aarch64/cortex_a715.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -32,6 +32,47 @@
 
 check_erratum_ls cortex_a715, ERRATUM(2331818), CPU_REV(1, 0)
 
+workaround_reset_start cortex_a715, ERRATUM(2344187), ERRATA_A715_2344187
+	/* GCR_EL1 is only present with FEAT_MTE2. */
+	mrs x1, ID_AA64PFR1_EL1
+	ubfx x0, x1, ID_AA64PFR1_EL1_MTE_SHIFT, #4
+	cmp x0, #MTE_IMPLEMENTED_ELX
+	bne #1f
+	sysreg_bit_set GCR_EL1, GCR_EL1_RRND_BIT
+
+1:
+	/* Mitigation upon ERETAA and ERETAB. */
+	mov x0, #2
+	msr CORTEX_A715_CPUPSELR_EL3, x0
+	isb
+	ldr x0, =0xd69f0bff
+	msr CORTEX_A715_CPUPOR_EL3, x0
+	ldr x0, =0xfffffbff
+	msr CORTEX_A715_CPUPMR_EL3, x0
+	mov x1, #0
+	orr x1, x1, #(1<<0)
+	orr x1, x1, #(3<<4)
+	orr x1, x1, #(0xf<<6)
+	orr x1, x1, #(1<<13)
+	orr x1, x1, #(1<<53)
+	msr CORTEX_A715_CPUPCR_EL3, x1
+workaround_reset_end cortex_a715, ERRATUM(2344187)
+
+check_erratum_ls cortex_a715, ERRATUM(2344187), CPU_REV(1, 0)
+
+/* Errata applies only when Static profiling extension is enabled. */
+workaround_reset_start cortex_a715, ERRATUM(2413290), ERRATA_A715_2413290
+	/* Apply the workaround by setting CPUACTLR_EL1[58:57] = 0b11. */
+	mrs x1, id_aa64dfr0_el1
+	ubfx x0, x1, ID_AA64DFR0_PMS_SHIFT, #4
+	cbz x0, 1f
+	sysreg_bit_set CORTEX_A715_CPUACTLR_EL1, BIT(57)
+	sysreg_bit_set CORTEX_A715_CPUACTLR_EL1, BIT(58)
+1:
+workaround_reset_end cortex_a715, ERRATUM(2413290)
+
+check_erratum_range cortex_a715, ERRATUM(2413290), CPU_REV(1,0), CPU_REV(1, 0)
+
 workaround_reset_start cortex_a715, ERRATUM(2420947), ERRATA_A715_2420947
         sysreg_bit_set CORTEX_A715_CPUACTLR2_EL1, BIT(33)
 workaround_reset_end cortex_a715, ERRATUM(2420947)
@@ -44,9 +85,9 @@
 
 check_erratum_range cortex_a715, ERRATUM(2429384), CPU_REV(1, 0), CPU_REV(1, 0)
 
-workaround_runtime_start cortex_a715, ERRATUM(2561034), ERRATA_A715_2561034
+workaround_reset_start cortex_a715, ERRATUM(2561034), ERRATA_A715_2561034
 	sysreg_bit_set	CORTEX_A715_CPUACTLR2_EL1, BIT(26)
-workaround_runtime_end cortex_a715, ERRATUM(2561034), NO_ISB
+workaround_reset_end cortex_a715, ERRATUM(2561034)
 
 check_erratum_range cortex_a715, ERRATUM(2561034), CPU_REV(1, 0), CPU_REV(1, 0)
 
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 1c0b092..f5997ae 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -818,6 +818,11 @@
 # to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_X3_2779509
 
+# Flag to apply erratum 2701112 workaround for platforms that do not use an
+# Arm interconnect IP. This erratum applies to revisions r0p0 of the Cortex-X4
+# cpu and is fixed in r0p1.
+CPU_FLAG_LIST += ERRATA_X4_2701112
+
 # Flag to apply erratum 1922240 workaround during reset. This erratum applies
 # to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_A510_1922240
@@ -915,6 +920,14 @@
 # to revisions r0p0 and r1p0. It is fixed in r1p1.
 CPU_FLAG_LIST += ERRATA_A715_2331818
 
+# Flag to apply erratum 2344187 workaround during reset. This erratum applies
+# to revisions r0p0, and r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2344187
+
+# Flag to apply erratum 2413290 workaround during reset. This erratum applies
+# only to revision r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2413290
+
 # Flag to apply erratum 2420947 workaround during reset. This erratum applies
 # only to revision r1p0. It is fixed in r1p1.
 CPU_FLAG_LIST += ERRATA_A715_2420947
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 922b2cf..5c8f03c 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -262,10 +262,10 @@
 	 * Initialize SCTLR_EL2 context register using Endianness value
 	 * taken from the entrypoint attribute.
 	 */
-	u_register_t sctlr_el2 = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0UL;
-	sctlr_el2 |= SCTLR_EL2_RES1;
-	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_SCTLR_EL2,
-			sctlr_el2);
+	u_register_t sctlr_el2_val = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0UL;
+	sctlr_el2_val |= SCTLR_EL2_RES1;
+	write_el2_ctx_common(get_el2_sysregs_ctx(ctx), sctlr_el2, sctlr_el2_val);
+
 
 	if (is_feat_hcx_supported()) {
 		/*
@@ -276,7 +276,7 @@
 		 * this feature if not properly initialized, especially when
 		 * it comes to those bits that enable/disable traps.
 		 */
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HCRX_EL2,
+		write_el2_ctx_hcx(get_el2_sysregs_ctx(ctx), hcrx_el2,
 			HCRX_EL2_INIT_VAL);
 	}
 
@@ -286,13 +286,14 @@
 		 * systems unaware of FEAT_FGT do not get trapped due to their lack
 		 * of initialization for this feature.
 		 */
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGITR_EL2,
+		write_el2_ctx_fgt(get_el2_sysregs_ctx(ctx), hfgitr_el2,
 			HFGITR_EL2_INIT_VAL);
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGRTR_EL2,
+		write_el2_ctx_fgt(get_el2_sysregs_ctx(ctx), hfgrtr_el2,
 			HFGRTR_EL2_INIT_VAL);
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGWTR_EL2,
+		write_el2_ctx_fgt(get_el2_sysregs_ctx(ctx), hfgwtr_el2,
 			HFGWTR_EL2_INIT_VAL);
 	}
+
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 	manage_extensions_nonsecure(ctx);
@@ -330,9 +331,9 @@
 	 * These bits are set in the gicv3 driver. Losing them (especially the
 	 * SRE bit) is problematic for all worlds. Henceforth recreate them.
 	 */
-	u_register_t icc_sre_el2 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
+	u_register_t icc_sre_el2_val = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
 				   ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
-	write_ctx_reg(el2_ctx, CTX_ICC_SRE_EL2, icc_sre_el2);
+	write_el2_ctx_common(el2_ctx, icc_sre_el2, icc_sre_el2_val);
 #endif /* CTX_INCLUDE_EL2_REGS */
 
 	/* Start with a clean SCR_EL3 copy as all relevant values are set */
@@ -987,7 +988,6 @@
 			}
 		}
 
-
 		if ((scr_el3 & SCR_HCE_BIT) != 0U) {
 			/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
 			sctlr_elx = read_ctx_reg(get_el1_sysregs_ctx(ctx),
@@ -1016,26 +1016,26 @@
 
 static void el2_sysregs_context_save_fgt(el2_sysregs_t *ctx)
 {
-	write_ctx_reg(ctx, CTX_HDFGRTR_EL2, read_hdfgrtr_el2());
+	write_el2_ctx_fgt(ctx, hdfgrtr_el2, read_hdfgrtr_el2());
 	if (is_feat_amu_supported()) {
-		write_ctx_reg(ctx, CTX_HAFGRTR_EL2, read_hafgrtr_el2());
+		write_el2_ctx_fgt(ctx, hafgrtr_el2, read_hafgrtr_el2());
 	}
-	write_ctx_reg(ctx, CTX_HDFGWTR_EL2, read_hdfgwtr_el2());
-	write_ctx_reg(ctx, CTX_HFGITR_EL2, read_hfgitr_el2());
-	write_ctx_reg(ctx, CTX_HFGRTR_EL2, read_hfgrtr_el2());
-	write_ctx_reg(ctx, CTX_HFGWTR_EL2, read_hfgwtr_el2());
+	write_el2_ctx_fgt(ctx, hdfgwtr_el2, read_hdfgwtr_el2());
+	write_el2_ctx_fgt(ctx, hfgitr_el2, read_hfgitr_el2());
+	write_el2_ctx_fgt(ctx, hfgrtr_el2, read_hfgrtr_el2());
+	write_el2_ctx_fgt(ctx, hfgwtr_el2, read_hfgwtr_el2());
 }
 
 static void el2_sysregs_context_restore_fgt(el2_sysregs_t *ctx)
 {
-	write_hdfgrtr_el2(read_ctx_reg(ctx, CTX_HDFGRTR_EL2));
+	write_hdfgrtr_el2(read_el2_ctx_fgt(ctx, hdfgrtr_el2));
 	if (is_feat_amu_supported()) {
-		write_hafgrtr_el2(read_ctx_reg(ctx, CTX_HAFGRTR_EL2));
+		write_hafgrtr_el2(read_el2_ctx_fgt(ctx, hafgrtr_el2));
 	}
-	write_hdfgwtr_el2(read_ctx_reg(ctx, CTX_HDFGWTR_EL2));
-	write_hfgitr_el2(read_ctx_reg(ctx, CTX_HFGITR_EL2));
-	write_hfgrtr_el2(read_ctx_reg(ctx, CTX_HFGRTR_EL2));
-	write_hfgwtr_el2(read_ctx_reg(ctx, CTX_HFGWTR_EL2));
+	write_hdfgwtr_el2(read_el2_ctx_fgt(ctx, hdfgwtr_el2));
+	write_hfgitr_el2(read_el2_ctx_fgt(ctx, hfgitr_el2));
+	write_hfgrtr_el2(read_el2_ctx_fgt(ctx, hfgrtr_el2));
+	write_hfgwtr_el2(read_el2_ctx_fgt(ctx, hfgwtr_el2));
 }
 
 #if CTX_INCLUDE_MPAM_REGS
@@ -1148,38 +1148,37 @@
 static void el2_sysregs_context_save_gic(el2_sysregs_t *ctx)
 {
 #if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
-	write_ctx_reg(ctx, CTX_ICC_SRE_EL2, read_icc_sre_el2());
+	write_el2_ctx_common(ctx, icc_sre_el2, read_icc_sre_el2());
 #else
 	u_register_t scr_el3 = read_scr_el3();
 	write_scr_el3(scr_el3 | SCR_NS_BIT);
 	isb();
 
-	write_ctx_reg(ctx, CTX_ICC_SRE_EL2, read_icc_sre_el2());
+	write_el2_ctx_common(ctx, icc_sre_el2, read_icc_sre_el2());
 
 	write_scr_el3(scr_el3);
 	isb();
-
 #endif
-	write_ctx_reg(ctx, CTX_ICH_HCR_EL2, read_ich_hcr_el2());
-	write_ctx_reg(ctx, CTX_ICH_VMCR_EL2, read_ich_vmcr_el2());
+	write_el2_ctx_common(ctx, ich_hcr_el2, read_ich_hcr_el2());
+	write_el2_ctx_common(ctx, ich_vmcr_el2, read_ich_vmcr_el2());
 }
 
 static void el2_sysregs_context_restore_gic(el2_sysregs_t *ctx)
 {
 #if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
-	write_icc_sre_el2(read_ctx_reg(ctx, CTX_ICC_SRE_EL2));
+	write_icc_sre_el2(read_el2_ctx_common(ctx, icc_sre_el2));
 #else
 	u_register_t scr_el3 = read_scr_el3();
 	write_scr_el3(scr_el3 | SCR_NS_BIT);
 	isb();
 
-	write_icc_sre_el2(read_ctx_reg(ctx, CTX_ICC_SRE_EL2));
+	write_icc_sre_el2(read_el2_ctx_common(ctx, icc_sre_el2));
 
 	write_scr_el3(scr_el3);
 	isb();
 #endif
-	write_ich_hcr_el2(read_ctx_reg(ctx, CTX_ICH_HCR_EL2));
-	write_ich_vmcr_el2(read_ctx_reg(ctx, CTX_ICH_VMCR_EL2));
+	write_ich_hcr_el2(read_el2_ctx_common(ctx, ich_hcr_el2));
+	write_ich_vmcr_el2(read_el2_ctx_common(ctx, ich_vmcr_el2));
 }
 
 /* -----------------------------------------------------
@@ -1190,70 +1189,70 @@
  */
 static void el2_sysregs_context_save_common(el2_sysregs_t *ctx)
 {
-	write_ctx_reg(ctx, CTX_ACTLR_EL2, read_actlr_el2());
-	write_ctx_reg(ctx, CTX_AFSR0_EL2, read_afsr0_el2());
-	write_ctx_reg(ctx, CTX_AFSR1_EL2, read_afsr1_el2());
-	write_ctx_reg(ctx, CTX_AMAIR_EL2, read_amair_el2());
-	write_ctx_reg(ctx, CTX_CNTHCTL_EL2, read_cnthctl_el2());
-	write_ctx_reg(ctx, CTX_CNTVOFF_EL2, read_cntvoff_el2());
-	write_ctx_reg(ctx, CTX_CPTR_EL2, read_cptr_el2());
+	write_el2_ctx_common(ctx, actlr_el2, read_actlr_el2());
+	write_el2_ctx_common(ctx, afsr0_el2, read_afsr0_el2());
+	write_el2_ctx_common(ctx, afsr1_el2, read_afsr1_el2());
+	write_el2_ctx_common(ctx, amair_el2, read_amair_el2());
+	write_el2_ctx_common(ctx, cnthctl_el2, read_cnthctl_el2());
+	write_el2_ctx_common(ctx, cntvoff_el2, read_cntvoff_el2());
+	write_el2_ctx_common(ctx, cptr_el2, read_cptr_el2());
 	if (CTX_INCLUDE_AARCH32_REGS) {
-		write_ctx_reg(ctx, CTX_DBGVCR32_EL2, read_dbgvcr32_el2());
+		write_el2_ctx_common(ctx, dbgvcr32_el2, read_dbgvcr32_el2());
 	}
-	write_ctx_reg(ctx, CTX_ELR_EL2, read_elr_el2());
-	write_ctx_reg(ctx, CTX_ESR_EL2, read_esr_el2());
-	write_ctx_reg(ctx, CTX_FAR_EL2, read_far_el2());
-	write_ctx_reg(ctx, CTX_HACR_EL2, read_hacr_el2());
-	write_ctx_reg(ctx, CTX_HCR_EL2, read_hcr_el2());
-	write_ctx_reg(ctx, CTX_HPFAR_EL2, read_hpfar_el2());
-	write_ctx_reg(ctx, CTX_HSTR_EL2, read_hstr_el2());
-	write_ctx_reg(ctx, CTX_MAIR_EL2, read_mair_el2());
-	write_ctx_reg(ctx, CTX_MDCR_EL2, read_mdcr_el2());
-	write_ctx_reg(ctx, CTX_SCTLR_EL2, read_sctlr_el2());
-	write_ctx_reg(ctx, CTX_SPSR_EL2, read_spsr_el2());
-	write_ctx_reg(ctx, CTX_SP_EL2, read_sp_el2());
-	write_ctx_reg(ctx, CTX_TCR_EL2, read_tcr_el2());
-	write_ctx_reg(ctx, CTX_TPIDR_EL2, read_tpidr_el2());
-	write_ctx_reg(ctx, CTX_TTBR0_EL2, read_ttbr0_el2());
-	write_ctx_reg(ctx, CTX_VBAR_EL2, read_vbar_el2());
-	write_ctx_reg(ctx, CTX_VMPIDR_EL2, read_vmpidr_el2());
-	write_ctx_reg(ctx, CTX_VPIDR_EL2, read_vpidr_el2());
-	write_ctx_reg(ctx, CTX_VTCR_EL2, read_vtcr_el2());
-	write_ctx_reg(ctx, CTX_VTTBR_EL2, read_vttbr_el2());
+	write_el2_ctx_common(ctx, elr_el2, read_elr_el2());
+	write_el2_ctx_common(ctx, esr_el2, read_esr_el2());
+	write_el2_ctx_common(ctx, far_el2, read_far_el2());
+	write_el2_ctx_common(ctx, hacr_el2, read_hacr_el2());
+	write_el2_ctx_common(ctx, hcr_el2, read_hcr_el2());
+	write_el2_ctx_common(ctx, hpfar_el2, read_hpfar_el2());
+	write_el2_ctx_common(ctx, hstr_el2, read_hstr_el2());
+	write_el2_ctx_common(ctx, mair_el2, read_mair_el2());
+	write_el2_ctx_common(ctx, mdcr_el2, read_mdcr_el2());
+	write_el2_ctx_common(ctx, sctlr_el2, read_sctlr_el2());
+	write_el2_ctx_common(ctx, spsr_el2, read_spsr_el2());
+	write_el2_ctx_common(ctx, sp_el2, read_sp_el2());
+	write_el2_ctx_common(ctx, tcr_el2, read_tcr_el2());
+	write_el2_ctx_common(ctx, tpidr_el2, read_tpidr_el2());
+	write_el2_ctx_common(ctx, ttbr0_el2, read_ttbr0_el2());
+	write_el2_ctx_common(ctx, vbar_el2, read_vbar_el2());
+	write_el2_ctx_common(ctx, vmpidr_el2, read_vmpidr_el2());
+	write_el2_ctx_common(ctx, vpidr_el2, read_vpidr_el2());
+	write_el2_ctx_common(ctx, vtcr_el2, read_vtcr_el2());
+	write_el2_ctx_common(ctx, vttbr_el2, read_vttbr_el2());
 }
 
 static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx)
 {
-	write_actlr_el2(read_ctx_reg(ctx, CTX_ACTLR_EL2));
-	write_afsr0_el2(read_ctx_reg(ctx, CTX_AFSR0_EL2));
-	write_afsr1_el2(read_ctx_reg(ctx, CTX_AFSR1_EL2));
-	write_amair_el2(read_ctx_reg(ctx, CTX_AMAIR_EL2));
-	write_cnthctl_el2(read_ctx_reg(ctx, CTX_CNTHCTL_EL2));
-	write_cntvoff_el2(read_ctx_reg(ctx, CTX_CNTVOFF_EL2));
-	write_cptr_el2(read_ctx_reg(ctx, CTX_CPTR_EL2));
+	write_actlr_el2(read_el2_ctx_common(ctx, actlr_el2));
+	write_afsr0_el2(read_el2_ctx_common(ctx, afsr0_el2));
+	write_afsr1_el2(read_el2_ctx_common(ctx, afsr1_el2));
+	write_amair_el2(read_el2_ctx_common(ctx, amair_el2));
+	write_cnthctl_el2(read_el2_ctx_common(ctx, cnthctl_el2));
+	write_cntvoff_el2(read_el2_ctx_common(ctx, cntvoff_el2));
+	write_cptr_el2(read_el2_ctx_common(ctx, cptr_el2));
 	if (CTX_INCLUDE_AARCH32_REGS) {
-		write_dbgvcr32_el2(read_ctx_reg(ctx, CTX_DBGVCR32_EL2));
+		write_dbgvcr32_el2(read_el2_ctx_common(ctx, dbgvcr32_el2));
 	}
-	write_elr_el2(read_ctx_reg(ctx, CTX_ELR_EL2));
-	write_esr_el2(read_ctx_reg(ctx, CTX_ESR_EL2));
-	write_far_el2(read_ctx_reg(ctx, CTX_FAR_EL2));
-	write_hacr_el2(read_ctx_reg(ctx, CTX_HACR_EL2));
-	write_hcr_el2(read_ctx_reg(ctx, CTX_HCR_EL2));
-	write_hpfar_el2(read_ctx_reg(ctx, CTX_HPFAR_EL2));
-	write_hstr_el2(read_ctx_reg(ctx, CTX_HSTR_EL2));
-	write_mair_el2(read_ctx_reg(ctx, CTX_MAIR_EL2));
-	write_mdcr_el2(read_ctx_reg(ctx, CTX_MDCR_EL2));
-	write_sctlr_el2(read_ctx_reg(ctx, CTX_SCTLR_EL2));
-	write_spsr_el2(read_ctx_reg(ctx, CTX_SPSR_EL2));
-	write_sp_el2(read_ctx_reg(ctx, CTX_SP_EL2));
-	write_tcr_el2(read_ctx_reg(ctx, CTX_TCR_EL2));
-	write_tpidr_el2(read_ctx_reg(ctx, CTX_TPIDR_EL2));
-	write_ttbr0_el2(read_ctx_reg(ctx, CTX_TTBR0_EL2));
-	write_vbar_el2(read_ctx_reg(ctx, CTX_VBAR_EL2));
-	write_vmpidr_el2(read_ctx_reg(ctx, CTX_VMPIDR_EL2));
-	write_vpidr_el2(read_ctx_reg(ctx, CTX_VPIDR_EL2));
-	write_vtcr_el2(read_ctx_reg(ctx, CTX_VTCR_EL2));
-	write_vttbr_el2(read_ctx_reg(ctx, CTX_VTTBR_EL2));
+	write_elr_el2(read_el2_ctx_common(ctx, elr_el2));
+	write_esr_el2(read_el2_ctx_common(ctx, esr_el2));
+	write_far_el2(read_el2_ctx_common(ctx, far_el2));
+	write_hacr_el2(read_el2_ctx_common(ctx, hacr_el2));
+	write_hcr_el2(read_el2_ctx_common(ctx, hcr_el2));
+	write_hpfar_el2(read_el2_ctx_common(ctx, hpfar_el2));
+	write_hstr_el2(read_el2_ctx_common(ctx, hstr_el2));
+	write_mair_el2(read_el2_ctx_common(ctx, mair_el2));
+	write_mdcr_el2(read_el2_ctx_common(ctx, mdcr_el2));
+	write_sctlr_el2(read_el2_ctx_common(ctx, sctlr_el2));
+	write_spsr_el2(read_el2_ctx_common(ctx, spsr_el2));
+	write_sp_el2(read_el2_ctx_common(ctx, sp_el2));
+	write_tcr_el2(read_el2_ctx_common(ctx, tcr_el2));
+	write_tpidr_el2(read_el2_ctx_common(ctx, tpidr_el2));
+	write_ttbr0_el2(read_el2_ctx_common(ctx, ttbr0_el2));
+	write_vbar_el2(read_el2_ctx_common(ctx, vbar_el2));
+	write_vmpidr_el2(read_el2_ctx_common(ctx, vmpidr_el2));
+	write_vpidr_el2(read_el2_ctx_common(ctx, vpidr_el2));
+	write_vtcr_el2(read_el2_ctx_common(ctx, vtcr_el2));
+	write_vttbr_el2(read_el2_ctx_common(ctx, vttbr_el2));
 }
 
 /*******************************************************************************
@@ -1272,8 +1271,8 @@
 	el2_sysregs_context_save_common(el2_sysregs_ctx);
 	el2_sysregs_context_save_gic(el2_sysregs_ctx);
 
-	if (is_feat_mte2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2, read_tfsr_el2());
+	if (is_feat_mte_supported()) {
+		write_el2_ctx_mte(el2_sysregs_ctx, tfsr_el2, read_tfsr_el2());
 	}
 
 #if CTX_INCLUDE_MPAM_REGS
@@ -1288,51 +1287,57 @@
 	}
 
 	if (is_feat_ecv_v2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_CNTPOFF_EL2, read_cntpoff_el2());
+		write_el2_ctx_ecv(el2_sysregs_ctx, cntpoff_el2, read_cntpoff_el2());
 	}
 
 	if (is_feat_vhe_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2, read_contextidr_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2, read_ttbr1_el2());
+		write_el2_ctx_vhe(el2_sysregs_ctx, contextidr_el2,
+					read_contextidr_el2());
+		write_el2_ctx_vhe(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2());
 	}
 
 	if (is_feat_ras_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2, read_vdisr_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2, read_vsesr_el2());
+		write_el2_ctx_ras(el2_sysregs_ctx, vdisr_el2, read_vdisr_el2());
+		write_el2_ctx_ras(el2_sysregs_ctx, vsesr_el2, read_vsesr_el2());
 	}
 
 	if (is_feat_nv2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2, read_vncr_el2());
+		write_el2_ctx_neve(el2_sysregs_ctx, vncr_el2, read_vncr_el2());
 	}
 
 	if (is_feat_trf_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2, read_trfcr_el2());
+		write_el2_ctx_trf(el2_sysregs_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());
+		write_el2_ctx_csv2_2(el2_sysregs_ctx, scxtnum_el2,
+					read_scxtnum_el2());
 	}
 
 	if (is_feat_hcx_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2, read_hcrx_el2());
+		write_el2_ctx_hcx(el2_sysregs_ctx, hcrx_el2, read_hcrx_el2());
 	}
+
 	if (is_feat_tcr2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2, read_tcr2_el2());
+		write_el2_ctx_tcr2(el2_sysregs_ctx, tcr2_el2, read_tcr2_el2());
 	}
+
 	if (is_feat_sxpie_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2, read_pire0_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2, read_pir_el2());
+		write_el2_ctx_sxpie(el2_sysregs_ctx, pire0_el2, read_pire0_el2());
+		write_el2_ctx_sxpie(el2_sysregs_ctx, pir_el2, read_pir_el2());
 	}
-	if (is_feat_s2pie_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2, read_s2pir_el2());
-	}
+
 	if (is_feat_sxpoe_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
+		write_el2_ctx_sxpoe(el2_sysregs_ctx, por_el2, read_por_el2());
 	}
+
+	if (is_feat_s2pie_supported()) {
+		write_el2_ctx_s2pie(el2_sysregs_ctx, s2pir_el2, read_s2pir_el2());
+	}
+
 	if (is_feat_gcs_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2, read_gcspr_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2, read_gcscr_el2());
+		write_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2, read_gcspr_el2());
+		write_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2, read_gcscr_el2());
 	}
 }
 
@@ -1352,8 +1357,8 @@
 	el2_sysregs_context_restore_common(el2_sysregs_ctx);
 	el2_sysregs_context_restore_gic(el2_sysregs_ctx);
 
-	if (is_feat_mte2_supported()) {
-		write_tfsr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2));
+	if (is_feat_mte_supported()) {
+		write_tfsr_el2(read_el2_ctx_mte(el2_sysregs_ctx, tfsr_el2));
 	}
 
 #if CTX_INCLUDE_MPAM_REGS
@@ -1368,50 +1373,57 @@
 	}
 
 	if (is_feat_ecv_v2_supported()) {
-		write_cntpoff_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CNTPOFF_EL2));
+		write_cntpoff_el2(read_el2_ctx_ecv(el2_sysregs_ctx, cntpoff_el2));
 	}
 
 	if (is_feat_vhe_supported()) {
-		write_contextidr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2));
-		write_ttbr1_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2));
+		write_contextidr_el2(read_el2_ctx_vhe(el2_sysregs_ctx,
+					contextidr_el2));
+		write_ttbr1_el2(read_el2_ctx_vhe(el2_sysregs_ctx, ttbr1_el2));
 	}
 
 	if (is_feat_ras_supported()) {
-		write_vdisr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2));
-		write_vsesr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2));
+		write_vdisr_el2(read_el2_ctx_ras(el2_sysregs_ctx, vdisr_el2));
+		write_vsesr_el2(read_el2_ctx_ras(el2_sysregs_ctx, vsesr_el2));
 	}
 
 	if (is_feat_nv2_supported()) {
-		write_vncr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2));
+		write_vncr_el2(read_el2_ctx_neve(el2_sysregs_ctx, vncr_el2));
 	}
+
 	if (is_feat_trf_supported()) {
-		write_trfcr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2));
+		write_trfcr_el2(read_el2_ctx_trf(el2_sysregs_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));
+		write_scxtnum_el2(read_el2_ctx_csv2_2(el2_sysregs_ctx,
+					scxtnum_el2));
 	}
 
 	if (is_feat_hcx_supported()) {
-		write_hcrx_el2(read_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2));
+		write_hcrx_el2(read_el2_ctx_hcx(el2_sysregs_ctx, hcrx_el2));
 	}
+
 	if (is_feat_tcr2_supported()) {
-		write_tcr2_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2));
+		write_tcr2_el2(read_el2_ctx_tcr2(el2_sysregs_ctx, tcr2_el2));
 	}
+
 	if (is_feat_sxpie_supported()) {
-		write_pire0_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2));
-		write_pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2));
-	}
-	if (is_feat_s2pie_supported()) {
-		write_s2pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2));
+		write_pire0_el2(read_el2_ctx_sxpie(el2_sysregs_ctx, pire0_el2));
+		write_pir_el2(read_el2_ctx_sxpie(el2_sysregs_ctx, pir_el2));
 	}
+
 	if (is_feat_sxpoe_supported()) {
-		write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
+		write_por_el2(read_el2_ctx_sxpoe(el2_sysregs_ctx, por_el2));
 	}
+
+	if (is_feat_s2pie_supported()) {
+		write_s2pir_el2(read_el2_ctx_s2pie(el2_sysregs_ctx, s2pir_el2));
+	}
+
 	if (is_feat_gcs_supported()) {
-		write_gcscr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2));
-		write_gcspr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2));
+		write_gcscr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2));
+		write_gcspr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2));
 	}
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
diff --git a/lib/extensions/pmuv3/aarch64/pmuv3.c b/lib/extensions/pmuv3/aarch64/pmuv3.c
index 61fc47d..71aa303 100644
--- a/lib/extensions/pmuv3/aarch64/pmuv3.c
+++ b/lib/extensions/pmuv3/aarch64/pmuv3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,11 +24,11 @@
 void pmuv3_enable(cpu_context_t *ctx)
 {
 #if CTX_INCLUDE_EL2_REGS
-	u_register_t mdcr_el2;
+	u_register_t mdcr_el2_val;
 
-	mdcr_el2 = read_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2);
-	mdcr_el2 = init_mdcr_el2_hpmn(mdcr_el2);
-	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2, mdcr_el2);
+	mdcr_el2_val = read_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2);
+	mdcr_el2_val = init_mdcr_el2_hpmn(mdcr_el2_val);
+	write_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2, mdcr_el2_val);
 #endif /* CTX_INCLUDE_EL2_REGS */
 }
 
diff --git a/lib/psa/dice_protection_environment.c b/lib/psa/dice_protection_environment.c
new file mode 100644
index 0000000..44a5848
--- /dev/null
+++ b/lib/psa/dice_protection_environment.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <qcbor/qcbor_decode.h>
+#include <qcbor/qcbor_encode.h>
+#include <qcbor/qcbor_spiffy_decode.h>
+
+#include <common/debug.h>
+#include <dice.h>
+#include <dice_protection_environment.h>
+#include <psa/client.h>
+#include <psa_manifest/sid.h>
+
+enum dpe_command_id_t {
+	/* Standard commands */
+	DPE_GET_PROFILE = 1,
+	DPE_OPEN_SESSION = 2,
+	DPE_CLOSE_SESSION = 3,
+	DPE_SYNC_SESSION = 4,
+	DPE_EXPORT_SESSION = 5,
+	DPE_IMPORT_SESSION = 6,
+	DPE_INITIALIZE_CONTEXT = 7,
+	DPE_DERIVE_CONTEXT = 8,
+	DPE_CERTIFY_KEY = 9,
+	DPE_SIGN = 10,
+	DPE_SEAL = 11,
+	DPE_UNSEAL = 12,
+	DPE_DERIVE_SEALING_PUBLIC_KEY = 13,
+	DPE_ROTATE_CONTEXT_HANDLE = 14,
+	DPE_DESTROY_CONTEXT = 15,
+};
+
+enum dice_input_labels_t {
+	DICE_CODE_HASH = 1,
+	DICE_CODE_DESCRIPTOR = 2,
+	DICE_CONFIG_TYPE = 3,
+	DICE_CONFIG_VALUE = 4,
+	DICE_CONFIG_DESCRIPTOR = 5,
+	DICE_AUTHORITY_HASH = 6,
+	DICE_AUTHORITY_DESCRIPTOR = 7,
+	DICE_MODE = 8,
+	DICE_HIDDEN = 9,
+};
+
+enum dpe_derive_context_input_labels_t {
+	DPE_DERIVE_CONTEXT_CONTEXT_HANDLE = 1,
+	DPE_DERIVE_CONTEXT_RETAIN_PARENT_CONTEXT = 2,
+	DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_DERIVE = 3,
+	DPE_DERIVE_CONTEXT_CREATE_CERTIFICATE = 4,
+	DPE_DERIVE_CONTEXT_NEW_SESSION_INITIATOR_HANDSHAKE = 5,
+	DPE_DERIVE_CONTEXT_INPUT_DATA = 6,
+	DPE_DERIVE_CONTEXT_INTERNAL_INPUTS = 7,
+	DPE_DERIVE_CONTEXT_TARGET_LOCALITY = 8,
+	DPE_DERIVE_CONTEXT_RETURN_CERTIFICATE = 9,
+	DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_EXPORT = 10,
+	DPE_DERIVE_CONTEXT_EXPORT_CDI = 11,
+	/* enum values 256 and onwards are reserved for custom arguments */
+	DPE_DERIVE_CONTEXT_CERT_ID = 256,
+};
+
+enum dpe_derive_context_output_labels_t {
+	DPE_DERIVE_CONTEXT_NEW_CONTEXT_HANDLE = 1,
+	DPE_DERIVE_CONTEXT_NEW_SESSION_RESPONDER_HANDSHAKE = 2,
+	DPE_DERIVE_CONTEXT_PARENT_CONTEXT_HANDLE = 3,
+	DPE_DERIVE_CONTEXT_NEW_CERTIFICATE = 4,
+	DPE_DERIVE_CONTEXT_EXPORTED_CDI = 5,
+};
+
+struct derive_context_input_t {
+	int context_handle;
+	uint32_t cert_id;
+	bool retain_parent_context;
+	bool allow_new_context_to_derive;
+	bool create_certificate;
+	const DiceInputValues *dice_inputs;
+	int32_t target_locality;
+	bool return_certificate;
+	bool allow_new_context_to_export;
+	bool export_cdi;
+};
+
+struct derive_context_output_t {
+	int new_context_handle;
+	int new_parent_context_handle;
+	const uint8_t *new_certificate;
+	size_t new_certificate_size;
+	const uint8_t *exported_cdi;
+	size_t exported_cdi_size;
+};
+
+static void encode_dice_inputs(QCBOREncodeContext *encode_ctx,
+			       const DiceInputValues *input)
+{
+	/* Wrap the DICE inputs into a byte string */
+	QCBOREncode_BstrWrapInMapN(encode_ctx, DPE_DERIVE_CONTEXT_INPUT_DATA);
+
+	/* Inside the byte string the DICE inputs are encoded as a map */
+	QCBOREncode_OpenMap(encode_ctx);
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CODE_HASH,
+				  (UsefulBufC) { input->code_hash,
+						 sizeof(input->code_hash) });
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CODE_DESCRIPTOR,
+				   (UsefulBufC) { input->code_descriptor,
+						  input->code_descriptor_size });
+
+	QCBOREncode_AddInt64ToMapN(encode_ctx, DICE_CONFIG_TYPE,
+				   input->config_type);
+
+	if (input->config_type == kDiceConfigTypeInline) {
+		QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CONFIG_VALUE,
+					   (UsefulBufC) { input->config_value,
+							  sizeof(input->config_value) });
+	} else {
+		QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CONFIG_DESCRIPTOR,
+					   (UsefulBufC) { input->config_descriptor,
+							  input->config_descriptor_size });
+	}
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_AUTHORITY_HASH,
+				   (UsefulBufC) { input->authority_hash,
+						  sizeof(input->authority_hash) });
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_AUTHORITY_DESCRIPTOR,
+				   (UsefulBufC) { input->authority_descriptor,
+						  input->authority_descriptor_size });
+
+	QCBOREncode_AddInt64ToMapN(encode_ctx, DICE_MODE, input->mode);
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_HIDDEN,
+				   (UsefulBufC) { input->hidden,
+						  sizeof(input->hidden) });
+
+	QCBOREncode_CloseMap(encode_ctx);
+	QCBOREncode_CloseBstrWrap2(encode_ctx, true, NULL);
+}
+
+static QCBORError encode_derive_context(const struct derive_context_input_t *args,
+					UsefulBuf buf,
+					UsefulBufC *encoded_buf)
+{
+	QCBOREncodeContext encode_ctx;
+
+	QCBOREncode_Init(&encode_ctx, buf);
+
+	QCBOREncode_OpenArray(&encode_ctx);
+	QCBOREncode_AddUInt64(&encode_ctx, DPE_DERIVE_CONTEXT);
+
+	/* Encode DeriveContext command */
+	QCBOREncode_OpenMap(&encode_ctx);
+	QCBOREncode_AddBytesToMapN(&encode_ctx,
+				   DPE_DERIVE_CONTEXT_CONTEXT_HANDLE,
+				   (UsefulBufC) { &args->context_handle,
+						  sizeof(args->context_handle) });
+	QCBOREncode_AddUInt64ToMapN(&encode_ctx,
+				    DPE_DERIVE_CONTEXT_CERT_ID,
+				    args->cert_id);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_RETAIN_PARENT_CONTEXT,
+				  args->retain_parent_context);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_DERIVE,
+				  args->allow_new_context_to_derive);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_CREATE_CERTIFICATE,
+				  args->create_certificate);
+	encode_dice_inputs(&encode_ctx, args->dice_inputs);
+	QCBOREncode_AddBytesToMapN(&encode_ctx,
+				   DPE_DERIVE_CONTEXT_TARGET_LOCALITY,
+				   (UsefulBufC) { &args->target_locality,
+						  sizeof(args->target_locality) });
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_RETURN_CERTIFICATE,
+				  args->return_certificate);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_EXPORT,
+				  args->allow_new_context_to_export);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_EXPORT_CDI,
+				  args->export_cdi);
+	QCBOREncode_CloseMap(&encode_ctx);
+
+	QCBOREncode_CloseArray(&encode_ctx);
+
+	return QCBOREncode_Finish(&encode_ctx, encoded_buf);
+}
+
+static QCBORError decode_derive_context_response(UsefulBufC encoded_buf,
+						 struct derive_context_output_t *args,
+						 dpe_error_t *dpe_err)
+{
+	QCBORDecodeContext decode_ctx;
+	UsefulBufC out;
+	int64_t response_dpe_err;
+
+	QCBORDecode_Init(&decode_ctx, encoded_buf, QCBOR_DECODE_MODE_NORMAL);
+
+	QCBORDecode_EnterArray(&decode_ctx, NULL);
+
+	/* Get the error code from the response. DPE returns int32_t */
+	QCBORDecode_GetInt64(&decode_ctx, &response_dpe_err);
+	*dpe_err = (dpe_error_t)response_dpe_err;
+
+	/* Decode DeriveContext response if successful */
+	if (*dpe_err == DPE_NO_ERROR) {
+		QCBORDecode_EnterMap(&decode_ctx, NULL);
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_NEW_CONTEXT_HANDLE,
+						&out);
+		if (out.len != sizeof(args->new_context_handle)) {
+			return QCBORDecode_Finish(&decode_ctx);
+		}
+		memcpy(&args->new_context_handle, out.ptr, out.len);
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_PARENT_CONTEXT_HANDLE,
+						&out);
+		if (out.len != sizeof(args->new_parent_context_handle)) {
+			return QCBORDecode_Finish(&decode_ctx);
+		}
+		memcpy(&args->new_parent_context_handle, out.ptr, out.len);
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_NEW_CERTIFICATE,
+						&out);
+		args->new_certificate = out.ptr;
+		args->new_certificate_size = out.len;
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_EXPORTED_CDI,
+						&out);
+		args->exported_cdi = out.ptr;
+		args->exported_cdi_size = out.len;
+
+		QCBORDecode_ExitMap(&decode_ctx);
+	}
+
+	QCBORDecode_ExitArray(&decode_ctx);
+
+	return QCBORDecode_Finish(&decode_ctx);
+}
+
+static int32_t dpe_client_call(const char *cmd_input, size_t cmd_input_size,
+			       char *cmd_output, size_t *cmd_output_size)
+{
+	int32_t err;
+
+	psa_invec in_vec[] = {
+		{ cmd_input, cmd_input_size },
+	};
+	psa_outvec out_vec[] = {
+		{ cmd_output, *cmd_output_size },
+	};
+
+	err = psa_call(RSS_DPE_SERVICE_HANDLE, 0,
+			in_vec, IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+
+	if (err == PSA_SUCCESS) {
+		*cmd_output_size = out_vec[0].len;
+	}
+
+	return err;
+}
+
+dpe_error_t dpe_derive_context(int context_handle,
+			       uint32_t cert_id,
+			       bool retain_parent_context,
+			       bool allow_new_context_to_derive,
+			       bool create_certificate,
+			       const DiceInputValues *dice_inputs,
+			       int32_t target_locality,
+			       bool return_certificate,
+			       bool allow_new_context_to_export,
+			       bool export_cdi,
+			       int *new_context_handle,
+			       int *new_parent_context_handle,
+			       uint8_t *new_certificate_buf,
+			       size_t new_certificate_buf_size,
+			       size_t *new_certificate_actual_size,
+			       uint8_t *exported_cdi_buf,
+			       size_t exported_cdi_buf_size,
+			       size_t *exported_cdi_actual_size)
+{
+	int32_t service_err;
+	dpe_error_t dpe_err;
+	QCBORError qcbor_err;
+	UsefulBufC encoded_buf;
+	UsefulBuf_MAKE_STACK_UB(cmd_buf, 612);
+
+	const struct derive_context_input_t in_args = {
+		context_handle,
+		cert_id,
+		retain_parent_context,
+		allow_new_context_to_derive,
+		create_certificate,
+		dice_inputs,
+		target_locality,
+		return_certificate,
+		allow_new_context_to_export,
+		export_cdi,
+	};
+	struct derive_context_output_t out_args;
+
+	/*
+	 * Validate the output params here because they are not sent to the
+	 * service. Input params are validated by the DPE service.
+	 */
+	if ((new_context_handle == NULL) ||
+	    (retain_parent_context == true && new_parent_context_handle == NULL) ||
+	    (return_certificate == true &&
+		(new_certificate_buf == NULL || new_certificate_actual_size == NULL)) ||
+	    (export_cdi == true &&
+		(exported_cdi_buf == NULL || exported_cdi_actual_size == NULL))) {
+		return DPE_INVALID_ARGUMENT;
+	}
+
+	qcbor_err = encode_derive_context(&in_args, cmd_buf, &encoded_buf);
+	if (qcbor_err != QCBOR_SUCCESS) {
+		return DPE_INTERNAL_ERROR;
+	}
+
+	service_err = dpe_client_call(encoded_buf.ptr, encoded_buf.len,
+				      cmd_buf.ptr, &cmd_buf.len);
+	if (service_err != 0) {
+		return DPE_INTERNAL_ERROR;
+	}
+
+	qcbor_err = decode_derive_context_response(UsefulBuf_Const(cmd_buf),
+						   &out_args, &dpe_err);
+	if (qcbor_err != QCBOR_SUCCESS) {
+		return DPE_INTERNAL_ERROR;
+	} else if (dpe_err != DPE_NO_ERROR) {
+		return dpe_err;
+	}
+
+	/* Copy returned values into caller's memory */
+	*new_context_handle = out_args.new_context_handle;
+
+	if (retain_parent_context == true) {
+		*new_parent_context_handle = out_args.new_parent_context_handle;
+	}
+
+	if (return_certificate == true) {
+		if (out_args.new_certificate_size > new_certificate_buf_size) {
+			return DPE_INVALID_ARGUMENT;
+		}
+
+		memcpy(new_certificate_buf, out_args.new_certificate,
+			out_args.new_certificate_size);
+		*new_certificate_actual_size = out_args.new_certificate_size;
+	}
+
+	if (export_cdi == true) {
+		if (out_args.exported_cdi_size > exported_cdi_buf_size) {
+			return DPE_INVALID_ARGUMENT;
+		}
+
+		memcpy(exported_cdi_buf, out_args.exported_cdi,
+			out_args.exported_cdi_size);
+		*exported_cdi_actual_size = out_args.exported_cdi_size;
+	}
+
+	return DPE_NO_ERROR;
+}
diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c
index 38990b5..ff1f45d 100644
--- a/lib/psa/measured_boot.c
+++ b/lib/psa/measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -8,6 +8,7 @@
 #include <string.h>
 
 #include <common/debug.h>
+#include <drivers/measured_boot/metadata.h>
 #include <measured_boot.h>
 #include <psa/client.h>
 #include <psa_manifest/sid.h>
diff --git a/lib/psa/measured_boot_private.h b/lib/psa/measured_boot_private.h
index 80d2c19..b8ca31d 100644
--- a/lib/psa/measured_boot_private.h
+++ b/lib/psa/measured_boot_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -10,6 +10,8 @@
 
 #include <stdint.h>
 
+#include <drivers/measured_boot/metadata.h>
+
 /* Measured boot message types that distinguish its services */
 #define RSS_MEASURED_BOOT_READ		1001U
 #define RSS_MEASURED_BOOT_EXTEND	1002U
diff --git a/licenses/LICENSE-APACHE-2.0.txt b/licenses/LICENSE-APACHE-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/licenses/LICENSE-APACHE-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 7fe8bf8..26d2a00 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -176,6 +176,9 @@
 # Option to build TF with Measured Boot support
 MEASURED_BOOT			:= 0
 
+# Option to enable the DICE Protection Environmnet as a Measured Boot backend
+DICE_PROTECTION_ENVIRONMENT	:=0
+
 # NS timer register save and restore
 NS_TIMER_SWITCH			:= 0
 
diff --git a/package-lock.json b/package-lock.json
index 7753a38..e60c44e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7,7 +7,6 @@
     "": {
       "name": "trusted-firmware-a",
       "version": "2.10.0",
-      "hasInstallScript": true,
       "license": "BSD-3-Clause",
       "devDependencies": {
         "@commitlint/cli": "^19.0.0",
diff --git a/package.json b/package.json
index 43c897e..7ad5c58 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
   "type": "module",
   "private": true,
   "scripts": {
-    "postinstall": "husky install",
+    "prepare": "husky",
     "release": "standard-version"
   },
   "engines": {
diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
index 477ae27..f14dbff 100644
--- a/plat/arm/board/fvp/fvp_bl1_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
@@ -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
  */
@@ -7,6 +7,7 @@
 #include <stdint.h>
 
 #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>
 
@@ -15,9 +16,9 @@
 
 /* FVP table with platform specific image IDs, names and PCRs */
 const event_log_metadata_t fvp_event_log_metadata[] = {
-	{ FW_CONFIG_ID, EVLOG_FW_CONFIG_STRING, PCR_0 },
-	{ TB_FW_CONFIG_ID, EVLOG_TB_FW_CONFIG_STRING, PCR_0 },
-	{ BL2_IMAGE_ID, EVLOG_BL2_STRING, PCR_0 },
+	{ FW_CONFIG_ID, MBOOT_FW_CONFIG_STRING, PCR_0 },
+	{ 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 */
 };
diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
index 369bcb4..8bf7dad 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-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 
 #include <common/tbbr/tbbr_img_def.h>
 #include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
 #if defined(ARM_COT_cca)
 #include <tools_share/cca_oid.h>
 #else
@@ -28,27 +29,27 @@
 
 /* FVP table with platform specific image IDs, names and PCRs */
 const event_log_metadata_t fvp_event_log_metadata[] = {
-	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
-	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
-	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
-	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
-	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
-	{ HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
-	{ NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
-	{ SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
-	{ SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
-	{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
-	{ RMM_IMAGE_ID, EVLOG_RMM_STRING, PCR_0},
+	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
+	{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
+	{ HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 },
+	{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
+	{ SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 },
+	{ SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 },
+	{ TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 },
+	{ RMM_IMAGE_ID, MBOOT_RMM_IMAGE_STRING, PCR_0},
 
 #if defined(SPD_spmd)
-	{ SP_PKG1_ID, EVLOG_SP1_STRING, PCR_0 },
-	{ SP_PKG2_ID, EVLOG_SP2_STRING, PCR_0 },
-	{ SP_PKG3_ID, EVLOG_SP3_STRING, PCR_0 },
-	{ SP_PKG4_ID, EVLOG_SP4_STRING, PCR_0 },
-	{ SP_PKG5_ID, EVLOG_SP5_STRING, PCR_0 },
-	{ SP_PKG6_ID, EVLOG_SP6_STRING, PCR_0 },
-	{ SP_PKG7_ID, EVLOG_SP7_STRING, PCR_0 },
-	{ SP_PKG8_ID, EVLOG_SP8_STRING, PCR_0 },
+	{ SP_PKG1_ID, MBOOT_SP1_STRING, PCR_0 },
+	{ SP_PKG2_ID, MBOOT_SP2_STRING, PCR_0 },
+	{ SP_PKG3_ID, MBOOT_SP3_STRING, PCR_0 },
+	{ SP_PKG4_ID, MBOOT_SP4_STRING, PCR_0 },
+	{ SP_PKG5_ID, MBOOT_SP5_STRING, PCR_0 },
+	{ SP_PKG6_ID, MBOOT_SP6_STRING, PCR_0 },
+	{ SP_PKG7_ID, MBOOT_SP7_STRING, PCR_0 },
+	{ SP_PKG8_ID, MBOOT_SP8_STRING, PCR_0 },
 #endif
 
 	{ CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 },
diff --git a/plat/arm/board/fvp/fvp_cpu_errata.mk b/plat/arm/board/fvp/fvp_cpu_errata.mk
index 342bc9f..b26fa80 100644
--- a/plat/arm/board/fvp/fvp_cpu_errata.mk
+++ b/plat/arm/board/fvp/fvp_cpu_errata.mk
@@ -16,6 +16,7 @@
 CORTEX_A78_AE_H_INC	:= 1
 CORTEX_A78C_H_INC	:= 1
 CORTEX_X3_H_INC		:= 1
+CORTEX_X4_H_INC		:= 1
 NEOVERSE_N2_H_INC	:= 1
 NEOVERSE_V1_H_INC	:= 1
 $(eval $(call add_define, CORTEX_A710_H_INC))
@@ -23,6 +24,7 @@
 $(eval $(call add_define, CORTEX_A78_AE_H_INC))
 $(eval $(call add_define, CORTEX_A78C_H_INC))
 $(eval $(call add_define, CORTEX_X3_H_INC))
+$(eval $(call add_define, CORTEX_X4_H_INC))
 $(eval $(call add_define, NEOVERSE_N2_H_INC))
 $(eval $(call add_define, NEOVERSE_V1_H_INC))
 endif
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 35086e4..569ac3f 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -204,12 +204,14 @@
 					lib/cpus/aarch64/cortex_a78_ae.S	\
 					lib/cpus/aarch64/cortex_a78c.S		\
 					lib/cpus/aarch64/cortex_a710.S		\
+					lib/cpus/aarch64/cortex_a715.S		\
 					lib/cpus/aarch64/neoverse_n_common.S	\
 					lib/cpus/aarch64/neoverse_n1.S		\
 					lib/cpus/aarch64/neoverse_n2.S		\
 					lib/cpus/aarch64/neoverse_v1.S		\
 					lib/cpus/aarch64/neoverse_e1.S		\
 					lib/cpus/aarch64/cortex_x2.S		\
+					lib/cpus/aarch64/cortex_x4.S		\
 					lib/cpus/aarch64/cortex_gelas.S		\
 					lib/cpus/aarch64/nevis.S		\
 					lib/cpus/aarch64/travis.S
diff --git a/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
index 7f1c376..371bde6 100644
--- a/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
+++ b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
@@ -95,39 +95,39 @@
 						  CTX_TTBR1_EL1);
 
 #if CTX_INCLUDE_EL2_REGS
-	cpu_info->ErrCtxEl2Reg[0]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_ELR_EL2);
-	cpu_info->ErrCtxEl2Reg[1]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_ESR_EL2);
-	cpu_info->ErrCtxEl2Reg[2]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_FAR_EL2);
-	cpu_info->ErrCtxEl2Reg[3]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_HACR_EL2);
-	cpu_info->ErrCtxEl2Reg[4]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_HCR_EL2);
-	cpu_info->ErrCtxEl2Reg[5]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_HPFAR_EL2);
-	cpu_info->ErrCtxEl2Reg[6]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_MAIR_EL2);
-	cpu_info->ErrCtxEl2Reg[7]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_SCTLR_EL2);
-	cpu_info->ErrCtxEl2Reg[8]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_SP_EL2);
-	cpu_info->ErrCtxEl2Reg[9]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_SPSR_EL2);
-	cpu_info->ErrCtxEl2Reg[10]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_TCR_EL2);
-	cpu_info->ErrCtxEl2Reg[11]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_TPIDR_EL2);
-	cpu_info->ErrCtxEl2Reg[12]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_TTBR0_EL2);
-	cpu_info->ErrCtxEl2Reg[13]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_VTCR_EL2);
-	cpu_info->ErrCtxEl2Reg[14]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_VTTBR_EL2);
-	cpu_info->ErrCtxEl2Reg[15]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_ESR_EL2);
-#endif
+	cpu_info->ErrCtxEl2Reg[0]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						elr_el2);
+	cpu_info->ErrCtxEl2Reg[1]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						esr_el2);
+	cpu_info->ErrCtxEl2Reg[2]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						far_el2);
+	cpu_info->ErrCtxEl2Reg[3]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						hacr_el2);
+	cpu_info->ErrCtxEl2Reg[4]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						hcr_el2);
+	cpu_info->ErrCtxEl2Reg[5]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						hpfar_el2);
+	cpu_info->ErrCtxEl2Reg[6]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						mair_el2);
+	cpu_info->ErrCtxEl2Reg[7]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						sctlr_el2);
+	cpu_info->ErrCtxEl2Reg[8]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						sp_el2);
+	cpu_info->ErrCtxEl2Reg[9]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						spsr_el2);
+	cpu_info->ErrCtxEl2Reg[10]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						tcr_el2);
+	cpu_info->ErrCtxEl2Reg[11]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						tpidr_el2);
+	cpu_info->ErrCtxEl2Reg[12]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						ttbr0_el2);
+	cpu_info->ErrCtxEl2Reg[13]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						vtcr_el2);
+	cpu_info->ErrCtxEl2Reg[14]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						vttbr_el2);
+	cpu_info->ErrCtxEl2Reg[15]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						esr_el2);
+#endif /* CTX_INCLUDE_EL2_REGS */
 
 	cpu_info->ErrCtxEl3Reg[0]   = read_ctx_reg(get_el3state_ctx(ctx),
 						   CTX_ELR_EL3);
diff --git a/plat/arm/board/tc/fdts/dice_prot_env.dtsi b/plat/arm/board/tc/fdts/dice_prot_env.dtsi
new file mode 100644
index 0000000..118f995
--- /dev/null
+++ b/plat/arm/board/tc/fdts/dice_prot_env.dtsi
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* DICE Protection Environment Client Config */
+dice_protection_environment: context_handle {
+	compatible = "arm,dpe_ctx_handle";
+	dpe_ctx_handle = <0x0>;
+};
diff --git a/plat/arm/board/tc/fdts/tc_fw_config.dts b/plat/arm/board/tc/fdts/tc_fw_config.dts
index 982da5b..b210e75 100644
--- a/plat/arm/board/tc/fdts/tc_fw_config.dts
+++ b/plat/arm/board/tc/fdts/tc_fw_config.dts
@@ -30,5 +30,10 @@
 			max-size = <PLAT_HW_CONFIG_DTB_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
+		nt_fw-config {
+			load-address = <0x0 (PLAT_HW_CONFIG_DTB_BASE + PLAT_HW_CONFIG_DTB_SIZE)>;
+			max-size = <0x1000>;
+			id = <NT_FW_CONFIG_ID>;
+		};
 	};
 };
diff --git a/plat/arm/board/tc/fdts/tc_nt_fw_config.dts b/plat/arm/board/tc/fdts/tc_nt_fw_config.dts
new file mode 100644
index 0000000..bb3086d
--- /dev/null
+++ b/plat/arm/board/tc/fdts/tc_nt_fw_config.dts
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+#if DICE_PROTECTION_ENVIRONMENT
+	#include "dice_prot_env.dtsi"
+#endif
+};
diff --git a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
index c58f17b..cb741a3 100644
--- a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
+++ b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
@@ -82,4 +82,7 @@
 #endif
 #endif /* ARM_BL2_SP_LIST_DTS */
 	};
+#if DICE_PROTECTION_ENVIRONMENT
+	#include "dice_prot_env.dtsi"
+#endif
 };
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index a42e39d..f7a4807 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -32,6 +32,9 @@
  *               |       DTB      |
  *               |      (32K)     |
  *  0x8000_8000  ------------------
+ *               | NT_FW_CONFIG   |
+ *               |      (4KB)     |
+ *  0x8000_9000  ------------------
  *               |       ...      |
  *  0xf8a0_0000  ------------------   TC_NS_FWU_BASE
  *               |    FWU shmem   |
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 652a17e..2f23d80 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -137,14 +137,18 @@
 
 # Add the FDT_SOURCES and options for Dynamic Config
 FDT_SOURCES		+=	${TC_BASE}/fdts/${PLAT}_fw_config.dts	\
-				${TC_BASE}/fdts/${PLAT}_tb_fw_config.dts
+				${TC_BASE}/fdts/${PLAT}_tb_fw_config.dts \
+				${TC_BASE}/fdts/${PLAT}_nt_fw_config.dts
 FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FVP_NT_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG}))
 
 ifeq (${SPD},spmd)
 ifeq ($(ARM_SPMC_MANIFEST_DTS),)
@@ -170,27 +174,56 @@
 # Include Measured Boot makefile before any Crypto library makefile.
 # Crypto library makefile may need default definitions of Measured Boot build
 # flags present in Measured Boot makefile.
+$(info Including rss_comms.mk)
 ifeq (${MEASURED_BOOT},1)
-    MEASURED_BOOT_MK := drivers/measured_boot/rss/rss_measured_boot.mk
-    $(info Including ${MEASURED_BOOT_MK})
-    include ${MEASURED_BOOT_MK}
-    $(info Including rss_comms.mk)
-    include drivers/arm/rss/rss_comms.mk
+        $(info Including rss_comms.mk)
+        include drivers/arm/rss/rss_comms.mk
 
-    BL1_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
+	BL1_SOURCES	+=	${RSS_COMMS_SOURCES}
+	BL2_SOURCES	+=	${RSS_COMMS_SOURCES}
+	PLAT_INCLUDES	+=	-Iinclude/lib/psa
+
+    ifeq (${DICE_PROTECTION_ENVIRONMENT},1)
+        $(info Including qcbor.mk)
+        include drivers/measured_boot/rss/qcbor.mk
+        $(info Including dice_prot_env.mk)
+        include drivers/measured_boot/rss/dice_prot_env.mk
+
+	BL1_SOURCES	+=	${QCBOR_SOURCES} \
+				${DPE_SOURCES} \
+				plat/arm/board/tc/tc_common_dpe.c \
+				plat/arm/board/tc/tc_bl1_dpe.c \
+				lib/psa/dice_protection_environment.c \
+				drivers/arm/css/sds/sds.c \
+				drivers/delay_timer/delay_timer.c \
+				drivers/delay_timer/generic_delay_timer.c
+
+	BL2_SOURCES	+=	${QCBOR_SOURCES} \
+				${DPE_SOURCES} \
+				plat/arm/board/tc/tc_common_dpe.c \
+				plat/arm/board/tc/tc_bl2_dpe.c \
+				lib/psa/dice_protection_environment.c
+
+	PLAT_INCLUDES	+=	-I${QCBOR_INCLUDES} \
+				-Iinclude/lib/dice
+    else
+        $(info Including rss_measured_boot.mk)
+        include drivers/measured_boot/rss/rss_measured_boot.mk
+
+	BL1_SOURCES	+=	${MEASURED_BOOT_SOURCES} \
 				plat/arm/board/tc/tc_common_measured_boot.c \
 				plat/arm/board/tc/tc_bl1_measured_boot.c \
-				lib/psa/measured_boot.c			 \
-				${RSS_COMMS_SOURCES}
+				lib/psa/measured_boot.c
 
-    BL2_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
+	BL2_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
 				plat/arm/board/tc/tc_common_measured_boot.c \
 				plat/arm/board/tc/tc_bl2_measured_boot.c \
-				lib/psa/measured_boot.c			 \
-				${RSS_COMMS_SOURCES}
-
-PLAT_INCLUDES		+=	-Iinclude/lib/psa
+				lib/psa/measured_boot.c
+    endif
+endif
 
+ifeq (${TRNG_SUPPORT},1)
+	BL31_SOURCES	+=	plat/arm/board/tc/tc_trng.c
 endif
 
 ifneq (${PLATFORM_TEST},)
diff --git a/plat/arm/board/tc/tc_bl1_dpe.c b/plat/arm/board/tc/tc_bl1_dpe.c
new file mode 100644
index 0000000..dc60fb6
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl1_dpe.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/arm/css/sds.h>
+#include <drivers/arm/rss_comms.h>
+#include <drivers/delay_timer.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/measured_boot/rss/dice_prot_env.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <tools_share/zero_oid.h>
+
+#include "tc_dpe_cert.h"
+
+struct dpe_metadata tc_dpe_metadata[] = {
+	{
+		.id = FW_CONFIG_ID,
+		.cert_id = DPE_AP_FW_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = ZERO_OID },
+	{
+		.id = TB_FW_CONFIG_ID,
+		.cert_id = DPE_AP_FW_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_TB_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = ZERO_OID },
+	{
+		.id = BL2_IMAGE_ID,
+		.cert_id = DPE_AP_FW_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL2_IMAGE_STRING,
+		.allow_new_context_to_derive = true,
+		.retain_parent_context = false,
+		.create_certificate = false,
+		.pk_oid = ZERO_OID },
+	{
+		.id = DPE_INVALID_ID }
+};
+
+/* Effective timeout of 10000 ms */
+#define RSS_DPE_BOOT_10US_RETRIES		1000000
+#define TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID	0x0000000A
+
+/* Context handle is meant to be used by BL2. Sharing it via TB_FW_CONFIG */
+static int new_ctx_handle;
+
+void plat_dpe_share_context_handle(int *ctx_handle)
+{
+	new_ctx_handle = *ctx_handle;
+}
+
+void plat_dpe_get_context_handle(int *ctx_handle)
+{
+	int retry = RSS_DPE_BOOT_10US_RETRIES;
+	int ret;
+
+	/* Initialize System level generic or SP804 timer */
+	generic_delay_timer_init();
+
+	/* Check the initialization of the Shared Data Storage area between RSS
+	 * and AP. Since AP_BL1 is executed first then a bit later the RSS
+	 * runtime, which initialize this area, therefore AP needs to check it
+	 * in a loop until it gets written by RSS Secure Runtime.
+	 */
+	VERBOSE("Waiting for DPE service initialization in RSS Secure Runtime\n");
+	while (retry > 0) {
+		ret = sds_init(SDS_RSS_AP_REGION_ID);
+		if (ret != SDS_OK) {
+			udelay(10);
+			retry--;
+		} else {
+			break;
+		}
+	}
+
+	if (retry == 0) {
+		ERROR("DPE init timeout\n");
+		plat_panic_handler();
+	} else {
+		VERBOSE("DPE init succeeded in %dms.\n",
+			(RSS_DPE_BOOT_10US_RETRIES - retry) / 100);
+	}
+
+	/* TODO: call this in a loop to avoid reading unfinished data */
+	ret = sds_struct_read(SDS_RSS_AP_REGION_ID,
+			      TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID,
+			      0,
+			      ctx_handle,
+			      sizeof(*ctx_handle),
+			      SDS_ACCESS_MODE_NON_CACHED);
+	if (ret != SDS_OK) {
+		ERROR("Unable to get DPE context handle from SDS area\n");
+		plat_panic_handler();
+	}
+
+	VERBOSE("Received DPE context handle: 0x%x\n", *ctx_handle);
+}
+
+void bl1_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSS */
+	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
+			     PLAT_RSS_AP_RCV_MHU_BASE);
+
+	dpe_init(tc_dpe_metadata);
+}
+
+void bl1_plat_mboot_finish(void)
+{
+	int rc;
+
+	VERBOSE("Share DPE context handle with BL2: 0x%x\n", new_ctx_handle);
+	rc = arm_set_tb_fw_info(&new_ctx_handle);
+	if (rc != 0) {
+		ERROR("Unable to set DPE context handle in TB_FW_CONFIG\n");
+		/*
+		 * It is a fatal error because on TC platform, BL2 software
+		 * assumes that a valid DPE context_handle is passed through
+		 * the DTB object by BL1.
+		 */
+		plat_panic_handler();
+	}
+}
diff --git a/plat/arm/board/tc/tc_bl1_measured_boot.c b/plat/arm/board/tc/tc_bl1_measured_boot.c
index 6821a6a..2e58954 100644
--- a/plat/arm/board/tc/tc_bl1_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl1_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,8 @@
 #include <stdint.h>
 
 #include <drivers/arm/rss_comms.h>
+#include <drivers/measured_boot/metadata.h>
 #include <drivers/measured_boot/rss/rss_measured_boot.h>
-#include <lib/psa/measured_boot.h>
 #include <tools_share/zero_oid.h>
 
 #include <plat/arm/common/plat_arm.h>
@@ -22,21 +22,21 @@
 		.id = FW_CONFIG_ID,
 		.slot = U(6),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_FW_CONFIG_STRING,
+		.sw_type = MBOOT_FW_CONFIG_STRING,
 		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 	{
 		.id = TB_FW_CONFIG_ID,
 		.slot = U(7),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_TB_FW_CONFIG_STRING,
+		.sw_type = MBOOT_TB_FW_CONFIG_STRING,
 		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 	{
 		.id = BL2_IMAGE_ID,
 		.slot = U(8),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_BL2_STRING,
+		.sw_type = MBOOT_BL2_IMAGE_STRING,
 		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 
diff --git a/plat/arm/board/tc/tc_bl2_dpe.c b/plat/arm/board/tc/tc_bl2_dpe.c
new file mode 100644
index 0000000..e50508f
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl2_dpe.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/arm/rss_comms.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/measured_boot/rss/dice_prot_env.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <tools_share/tbbr_oid.h>
+
+#include "tc_dpe_cert.h"
+
+/*
+ * The content and the values of this array depends on:
+ * - build config: Which components are loaded: SPMD, TOS, SPx, etc ?
+ * - boot order: the last element in a layer should be treated differently.
+ */
+
+/*
+ * TODO:
+ *     - The content of the array must be tailored according to the build
+ *       config (TOS, SPMD, etc). All loaded components (executables and
+ *       config blobs) must be present in this array.
+ *     - Current content is according to the Trusty build config.
+ */
+struct dpe_metadata tc_dpe_metadata[] = {
+	{
+		.id = BL31_IMAGE_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL31_IMAGE_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = BL31_IMAGE_KEY_OID },
+	{
+		.id = BL32_IMAGE_ID,
+		.cert_id =  DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL32_IMAGE_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = BL32_IMAGE_KEY_OID },
+	{
+		.id = BL33_IMAGE_ID,
+		.cert_id = DPE_HYPERVISOR_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL33_IMAGE_STRING,
+		.allow_new_context_to_derive = true,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = BL33_IMAGE_KEY_OID },
+
+	{
+		.id = HW_CONFIG_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_HW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = HW_CONFIG_KEY_OID },
+	{
+		.id = NT_FW_CONFIG_ID,
+		.cert_id = DPE_HYPERVISOR_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_NT_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = NT_FW_CONFIG_KEY_OID },
+	{
+		.id = SCP_BL2_IMAGE_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SCP_BL2_IMAGE_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = SCP_BL2_IMAGE_KEY_OID },
+	{
+		.id = SOC_FW_CONFIG_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = SOC_FW_CONFIG_KEY_OID },
+	{
+		.id = TOS_FW_CONFIG_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_TOS_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = TOS_FW_CONFIG_KEY_OID },
+#if defined(SPD_spmd)
+	{
+		.id = SP_PKG1_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP1_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = true, /* With Trusty only one SP is loaded */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG2_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP2_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG3_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP3_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG4_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP4_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG5_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP5_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG6_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP6_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG7_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP7_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG8_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP8_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.pk_oid = NULL },
+
+#endif
+	{
+		.id = DPE_INVALID_ID }
+};
+
+/* Context handle is meant to be used by BL33. Sharing it via NT_FW_CONFIG */
+static int new_ctx_handle;
+
+void plat_dpe_share_context_handle(int *ctx_handle)
+{
+	new_ctx_handle = *ctx_handle;
+}
+
+void plat_dpe_get_context_handle(int *ctx_handle)
+{
+	int rc;
+
+	rc = arm_get_tb_fw_info(ctx_handle);
+	if (rc != 0) {
+		ERROR("Unable to get DPE context handle from TB_FW_CONFIG\n");
+		/*
+		 * It is a fatal error because on FVP platform, BL2 software
+		 * assumes that a valid DPE context_handle is passed through
+		 * the DTB object by BL1.
+		 */
+		plat_panic_handler();
+	}
+
+	VERBOSE("Received DPE context handle: 0x%x\n", *ctx_handle);
+}
+
+void bl2_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSS */
+	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
+			     PLAT_RSS_AP_RCV_MHU_BASE);
+
+	dpe_init(tc_dpe_metadata);
+}
+
+void bl2_plat_mboot_finish(void)
+{
+	int rc;
+
+	VERBOSE("Share DPE context handle with BL33: 0x%x\n", new_ctx_handle);
+	rc = arm_set_nt_fw_info(&new_ctx_handle);
+	if (rc != 0) {
+		ERROR("Unable to set DPE context handle in NT_FW_CONFIG\n");
+		/*
+		 * It is a fatal error because on TC platform, BL33 software
+		 * assumes that a valid DPE context_handle is passed through
+		 * the DTB object by BL2.
+		 */
+		plat_panic_handler();
+	}
+}
diff --git a/plat/arm/board/tc/tc_bl2_measured_boot.c b/plat/arm/board/tc/tc_bl2_measured_boot.c
index 4b79170..fd80fdc 100644
--- a/plat/arm/board/tc/tc_bl2_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl2_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,8 @@
 #include <stdint.h>
 
 #include <drivers/arm/rss_comms.h>
+#include <drivers/measured_boot/metadata.h>
 #include <drivers/measured_boot/rss/rss_measured_boot.h>
-#include <lib/psa/measured_boot.h>
 #include <tools_share/tbbr_oid.h>
 
 #include <plat/common/common_def.h>
@@ -22,21 +22,21 @@
 		.id = BL31_IMAGE_ID,
 		.slot = U(9),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_BL31_STRING,
+		.sw_type = MBOOT_BL31_IMAGE_STRING,
 		.pk_oid = BL31_IMAGE_KEY_OID,
 		.lock_measurement = true },
 	{
 		.id = HW_CONFIG_ID,
 		.slot = U(10),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_HW_CONFIG_STRING,
+		.sw_type = MBOOT_HW_CONFIG_STRING,
 		.pk_oid = HW_CONFIG_KEY_OID,
 		.lock_measurement = true },
 	{
 		.id = SOC_FW_CONFIG_ID,
 		.slot = U(11),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_SOC_FW_CONFIG_STRING,
+		.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
 		.pk_oid = SOC_FW_CONFIG_KEY_OID,
 		.lock_measurement = true },
 	{
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 6789c2e..5742d07 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -75,25 +75,6 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	/*
-	 * Pass the hw_config to BL33 in R0. You'll notice that
-	 * arm_bl31_early_platform_setup does something similar but only behind
-	 * ARM_LINUX_KERNEL_AS_BL33 and we want to pass the DTB even to a
-	 * bootloader. Lucky for us, it copies the ep_info BL2 gave us to BL33
-	 * unconditionally in the generic case so hijack that.
-	 * TODO: this goes away with firmware handoff when it will be proper
-	 */
-
-	bl_params_node_t *bl_params = ((bl_params_t *)arg0)->head;
-
-	while (bl_params != NULL) {
-		if (bl_params->image_id == BL33_IMAGE_ID) {
-			bl_params->ep_info->args.arg0 = arg2;
-			break;
-		}
-		bl_params = bl_params->next_params_info;
-	}
-
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
 
 	/* Fill the properties struct with the info from the config dtb */
diff --git a/plat/arm/board/tc/tc_common_dpe.c b/plat/arm/board/tc/tc_common_dpe.c
new file mode 100644
index 0000000..42b5468
--- /dev/null
+++ b/plat/arm/board/tc/tc_common_dpe.c
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/rss/dice_prot_env.h>
+
+extern struct dpe_metadata tc_dpe_metadata[];
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	int err;
+
+	/* Calculate image hash and record it in the DPE service in RSS. */
+	err = dpe_measure_and_record(tc_dpe_metadata,
+				     image_data->image_base,
+				     image_data->image_size,
+				     image_id);
+	if (err != 0) {
+		ERROR("%s%s image id %u (%i)\n",
+		      "Failed to ", "record in DPE", image_id, err);
+	}
+
+	return err;
+}
+
+int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
+{
+	return dpe_set_signer_id(tc_dpe_metadata, pk_oid, pk_ptr, pk_len);
+}
diff --git a/plat/arm/board/tc/tc_dpe_cert.h b/plat/arm/board/tc/tc_dpe_cert.h
new file mode 100644
index 0000000..25855ec
--- /dev/null
+++ b/plat/arm/board/tc/tc_dpe_cert.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TC_DPE_CERT_H
+#define TC_DPE_CERT_H
+
+/*
+ * The certificate structure on the TC platform:
+ *   - The arrows indicate the parent/child relationships (who loads who).
+ *   - The boxes indicate the certificates.
+ *
+ *                                                                  AP FW Cert.
+ *                                                      +--------------------------------+
+ *                                                      |                                |
+ *                             Plat Cert.               |                +->SPx          |           Hyper Cert.
+ *                     +--------------------------+     |                +->SP1          |     +--------------------+
+ *     RoT Cert.       |                          |     |                +->TOS_FW_CONF  |     |                    |
+ *  +------------+     |      +->SCP_BL1    +-----+-----+-->FW_CONF      +->AP_BL32      |     |     +->PVMFW       |
+ *  |            |     |      |             |     |     |                |               |     |     |              |
+ *  | RSS_BL1_2--+-----+-->RSS_BL2------->AP_BL1--+-----+------------->AP_BL2------------+-----+-->AP_BL33          |
+ *  |            |     |      |             |     |     |                |               |     |     |              |
+ *  +------------+     |      +->RSS_S      +-----+-----+-->TB_FW_CONF   +->AP_BL31      |     |     +->HYPERVISOR  |
+ *                     |      +->RSS_NS           |     |                +->SCP_BL2      |     |                    |
+ *                     |                          |     |                +->HW_CONF      |     |                    |
+ *                     +--------------------------+     |                +---------------+-----+-->NT_FW_CONF       |
+ *                                                      |                                |     |                    |
+ *                                                      +--------------------------------+     +--------------------+
+ */
+
+#define DPE_AP_FW_CERT_ID		0x300 /* Includes: FW_CONF - SP1 */
+#define DPE_HYPERVISOR_CERT_ID		0x400 /* Includes: AP_BL33 - PVMFW */
+
+/* Common definition */
+#define DPE_CERT_ID_SAME_AS_PARENT	0xFFFFFFFF
+
+#endif /* TC_DPE_CERT_H */
diff --git a/plat/arm/board/tc/tc_trng.c b/plat/arm/board/tc/tc_trng.c
new file mode 100644
index 0000000..e5ec48a
--- /dev/null
+++ b/plat/arm/board/tc/tc_trng.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_acle.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <services/trng_svc.h>
+#include <smccc_helpers.h>
+
+DEFINE_SVC_UUID2(_plat_trng_uuid,
+	0x23523c58, 0x7448, 0x4083, 0x9d, 0x16,
+	0xe3, 0xfa, 0xb9, 0xf1, 0x73, 0xbc
+);
+uuid_t plat_trng_uuid;
+
+/* Dummy implementation */
+bool plat_get_entropy(uint64_t *out)
+{
+	*out = 0xABBAEDDAACDCDEAD;
+
+	return true;
+}
+
+void plat_entropy_setup(void)
+{
+	uint64_t dummy;
+
+	plat_trng_uuid = _plat_trng_uuid;
+
+	/* Initialise the entropy source and trigger RNG generation */
+	plat_get_entropy(&dummy);
+}
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index 5dc1115..d13be99 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -124,6 +124,150 @@
 }
 
 #if MEASURED_BOOT
+#if DICE_PROTECTION_ENVIRONMENT
+
+#include <common/desc_image_load.h>
+
+#define DTB_PROP_DPE_CTX_HANDLE		"dpe_ctx_handle"
+
+static int arm_set_dpe_context_handle(uintptr_t config_base,
+				      int *ctx_handle)
+{
+	/* As libfdt uses void *, we can't avoid this cast */
+	void *dtb = (void *)config_base;
+	const char *compatible = "arm,dpe_ctx_handle";
+	int err, node;
+
+	/*
+	 * Verify that the DTB is valid, before attempting to write to it,
+	 * and get the DTB root node.
+	 */
+
+	/* Check if the pointer to DT is correct */
+	err = fdt_check_header(dtb);
+	if (err < 0) {
+		WARN("Invalid DTB file passed\n");
+		return err;
+	}
+
+	/* Assert the node offset point to compatible property */
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
+	if (node < 0) {
+		WARN("The compatible property '%s' not%s", compatible,
+			" found in the config\n");
+		return node;
+	}
+
+	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
+
+	err = fdtw_write_inplace_cells(dtb, node,
+		DTB_PROP_DPE_CTX_HANDLE, 1, ctx_handle);
+	if (err < 0) {
+		ERROR("%sDTB property '%s'\n",
+			"Unable to write ", DTB_PROP_DPE_CTX_HANDLE);
+	} else {
+		/*
+		 * Ensure that the info written to the DTB is visible
+		 * to other images.
+		 */
+		flush_dcache_range(config_base, fdt_totalsize(dtb));
+	}
+
+	return err;
+}
+
+/*
+ * This function writes the DPE context handle value to the NT_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+int arm_set_nt_fw_info(int *ctx_handle)
+{
+	uintptr_t config_base;
+	const bl_mem_params_node_t *cfg_mem_params;
+
+	/* Get the config load address and size from NT_FW_CONFIG */
+	cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
+	assert(cfg_mem_params != NULL);
+
+	config_base = cfg_mem_params->image_info.image_base;
+
+	/* Write the context handle value in the DTB */
+	return arm_set_dpe_context_handle(config_base, ctx_handle);
+}
+
+/*
+ * This function writes the DPE context handle value to the TB_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL1.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+int arm_set_tb_fw_info(int *ctx_handle)
+{
+	/*
+	 * Read tb_fw_config device tree for Event Log properties
+	 * and write the Event Log address and its size in the DTB
+	 */
+	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
+	uintptr_t tb_fw_cfg_dtb;
+
+	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+	assert(tb_fw_config_info != NULL);
+
+	tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
+
+	/* Write the context handle value in the DTB */
+	return arm_set_dpe_context_handle(tb_fw_cfg_dtb, ctx_handle);
+}
+
+/*
+ * This function reads the initial DPE context handle from TB_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+
+int arm_get_tb_fw_info(int *ctx_handle)
+{
+	/* As libfdt uses void *, we can't avoid this cast */
+	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
+	int node, rc;
+
+	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+	assert(tb_fw_config_info != NULL);
+
+	void *dtb = (void *)tb_fw_config_info->config_addr;
+	const char *compatible = "arm,dpe_ctx_handle";
+
+	/* Assert the node offset point to compatible property */
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
+	if (node < 0) {
+		WARN("The compatible property '%s'%s", compatible,
+		     " not specified in TB_FW config.\n");
+		return node;
+	}
+
+	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
+
+	rc = fdt_read_uint32(dtb, node, DTB_PROP_DPE_CTX_HANDLE, (uint32_t *)ctx_handle);
+	if (rc != 0) {
+		ERROR("%s%s", DTB_PROP_DPE_CTX_HANDLE,
+		      " not specified in TB_FW config.\n");
+	}
+
+	return rc;
+}
+#else
 /*
  * Write the Event Log address and its size in the DTB.
  *
@@ -393,4 +537,5 @@
 
 	return rc;
 }
+#endif /* DICE_PROTECTION_ENVIRONMENT */
 #endif /* MEASURED_BOOT */
diff --git a/plat/common/aarch64/crash_console_helpers.S b/plat/common/aarch64/crash_console_helpers.S
index 75b4208..1a50091 100644
--- a/plat/common/aarch64/crash_console_helpers.S
+++ b/plat/common/aarch64/crash_console_helpers.S
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -100,7 +100,7 @@
 	 * int plat_crash_console_putc(char c)
 	 * Prints the character on all consoles registered with the console
 	 * framework that have CONSOLE_FLAG_CRASH set. Note that this is only
-	 * helpful for crashes that occur after the platform intialization code
+	 * helpful for crashes that occur after the platform initialization code
 	 * has registered a console. Platforms using this implementation need to
 	 * ensure that all console drivers they use that have the CRASH flag set
 	 * support this (i.e. are written in assembly and comply to the register
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 4d6346c..19c4e48 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -72,12 +72,19 @@
 
 const char *get_el_str(unsigned int el)
 {
-	if (el == MODE_EL3) {
+	switch (el) {
+	case MODE_EL3:
 		return "EL3";
-	} else if (el == MODE_EL2) {
+	case MODE_EL2:
 		return "EL2";
+	case MODE_EL1:
+		return "EL1";
+	case MODE_EL0:
+		return "EL0";
+	default:
+		assert(false);
+		return NULL;
 	}
-	return "EL1";
 }
 
 #if FFH_SUPPORT
diff --git a/plat/imx/imx8m/imx8m_measured_boot.c b/plat/imx/imx8m/imx8m_measured_boot.c
index bfcd6ce..159be00 100644
--- a/plat/imx/imx8m/imx8m_measured_boot.c
+++ b/plat/imx/imx8m/imx8m_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2022, Linaro.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -9,6 +9,7 @@
 
 #include "./include/imx8m_measured_boot.h"
 #include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
 #include <plat/arm/common/plat_arm.h>
 
 /* Event Log data */
@@ -16,11 +17,11 @@
 
 /* FVP table with platform specific image IDs, names and PCRs */
 static const event_log_metadata_t imx8m_event_log_metadata[] = {
-	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
-	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
-	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
-	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
-	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
+	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
+	{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
 };
 
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
index 0d4f2cc..8d3928f 100644
--- a/plat/intel/soc/agilex5/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -182,7 +182,7 @@
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
index 077f7a4..76a4da1 100644
--- a/plat/qemu/qemu/qemu_measured_boot.c
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2022-2023, Linaro.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <tools_share/tbbr_oid.h>
@@ -20,16 +21,16 @@
 
 /* QEMU table with platform specific image IDs, names and PCRs */
 static const event_log_metadata_t qemu_event_log_metadata[] = {
-	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
-	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
-	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
-	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
-	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
-	{ HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
-	{ NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
-	{ SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
-	{ SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
-	{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
+	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
+	{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
+	{ HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 },
+	{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
+	{ SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 },
+	{ SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 },
+	{ TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 },
 
 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
 };
diff --git a/plat/st/common/common.mk b/plat/st/common/common.mk
index f49112d..b9b62c0 100644
--- a/plat/st/common/common.mk
+++ b/plat/st/common/common.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
 #
@@ -183,12 +183,10 @@
 MBEDTLS_MAJOR=$(shell grep -hP "define MBEDTLS_VERSION_MAJOR" \
 ${MBEDTLS_DIR}/include/mbedtls/*.h | grep -oe '\([0-9.]*\)')
 
-ifeq (${MBEDTLS_MAJOR}, 2)
-MBEDTLS_CONFIG_FILE		?=	"<stm32mp_mbedtls_config-2.h>"
-endif
-
 ifeq (${MBEDTLS_MAJOR}, 3)
 MBEDTLS_CONFIG_FILE		?=	"<stm32mp_mbedtls_config-3.h>"
+else
+$(error Error: TF-A only supports MbedTLS versions > 3.x)
 endif
 endif
 
diff --git a/plat/st/common/include/stm32mp_mbedtls_config-2.h b/plat/st/common/include/stm32mp_mbedtls_config-2.h
deleted file mode 100644
index 66ff346..0000000
--- a/plat/st/common/include/stm32mp_mbedtls_config-2.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
-/*
- * Key algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_USE_RSA	0
-#define TF_MBEDTLS_USE_ECDSA	1
-
-/*
- * Hash algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_SHA256		1
-#define TF_MBEDTLS_SHA384		2
-#define TF_MBEDTLS_SHA512		3
-
-/*
- * Configuration file to build mbed TLS with the required features for
- * Trusted Boot
- */
-
-#define MBEDTLS_PLATFORM_MEMORY
-#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
-/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */
-#define MBEDTLS_PLATFORM_SNPRINTF_ALT
-
-#define MBEDTLS_PKCS1_V21
-
-#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
-#define MBEDTLS_X509_CHECK_KEY_USAGE
-#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
-
-#define MBEDTLS_ASN1_PARSE_C
-#define MBEDTLS_ASN1_WRITE_C
-
-#define MBEDTLS_BASE64_C
-#define MBEDTLS_BIGNUM_C
-
-#define MBEDTLS_ERROR_C
-#define MBEDTLS_MD_C
-
-#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
-#define MBEDTLS_OID_C
-
-#define MBEDTLS_PK_C
-#define MBEDTLS_PK_PARSE_C
-#define MBEDTLS_PK_WRITE_C
-
-#define MBEDTLS_PLATFORM_C
-
-#if TF_MBEDTLS_USE_ECDSA
-#define MBEDTLS_ECDSA_C
-#define MBEDTLS_ECP_C
-#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
-#define MBEDTLS_ECP_NO_INTERNAL_RNG
-#endif
-#if TF_MBEDTLS_USE_RSA
-#define MBEDTLS_RSA_C
-#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
-#endif
-
-#define MBEDTLS_SHA256_C
-#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256)
-#define MBEDTLS_SHA512_C
-#endif
-
-#define MBEDTLS_VERSION_C
-
-#define MBEDTLS_X509_USE_C
-#define MBEDTLS_X509_CRT_PARSE_C
-
-#if TF_MBEDTLS_USE_AES_GCM
-#define MBEDTLS_AES_C
-#define MBEDTLS_CIPHER_C
-#define MBEDTLS_GCM_C
-#endif
-
-/* MPI / BIGNUM options */
-#define MBEDTLS_MPI_WINDOW_SIZE			2
-
-#if TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE <= 2048
-#define MBEDTLS_MPI_MAX_SIZE			256
-#else
-#define MBEDTLS_MPI_MAX_SIZE			512
-#endif
-#else
-#define MBEDTLS_MPI_MAX_SIZE			256
-#endif
-
-/* Memory buffer allocator options */
-#define MBEDTLS_MEMORY_ALIGN_MULTIPLE		8
-
-/*
- * Prevent the use of 128-bit division which
- * creates dependency on external libraries.
- */
-#define MBEDTLS_NO_UDBL_DIVISION
-
-#ifndef __ASSEMBLER__
-/* System headers required to build mbed TLS with the current configuration */
-#include <stdlib.h>
-#include <mbedtls/check_config.h>
-#endif
-
-/*
- * Mbed TLS heap size is smal as we only use the asn1
- * parsing functions
- * digest, signature and crypto algorithm are done by
- * other library.
- */
-
-#define TF_MBEDTLS_HEAP_SIZE           U(5120)
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
index 49bac23..2d59fc9 100644
--- a/services/std_svc/errata_abi/cpu_errata_info.h
+++ b/services/std_svc/errata_abi/cpu_errata_info.h
@@ -17,6 +17,7 @@
 #include <cortex_a78c.h>
 #include <cortex_x2.h>
 #include <cortex_x3.h>
+#include <cortex_x4.h>
 #include <neoverse_n2.h>
 #include <neoverse_v1.h>
 #include <neoverse_v2.h>
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index aebaf5a..0a1d4f3 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -111,6 +111,16 @@
 },
 #endif /* CORTEX_X3_H_INC */
 
+#if CORTEX_X4_H_INC
+{
+	.cpu_partnumber = CORTEX_X4_MIDR,
+	.cpu_errata_list = {
+		[0] = {2701112, 0x00, 0x00},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_X4_H_INC */
+
 };
 
 #if ERRATA_NON_ARM_INTERCONNECT
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index fb096bc..b3b2a69 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -109,8 +109,8 @@
 
 static void rmm_el2_context_init(el2_sysregs_t *regs)
 {
-	regs->ctx_regs[CTX_SPSR_EL2 >> 3] = REALM_SPSR_EL2;
-	regs->ctx_regs[CTX_SCTLR_EL2 >> 3] = SCTLR_EL2_RES1;
+	write_el2_ctx_common(regs, spsr_el2, REALM_SPSR_EL2);
+	write_el2_ctx_common(regs, sctlr_el2, SCTLR_EL2_RES1);
 }
 
 /*******************************************************************************
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index 72bc33f..c58adba 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -13,6 +13,7 @@
 #include <arch_features.h>
 #include <bl31/ehf.h>
 #include <bl31/interrupt_mgmt.h>
+#include <bl31/sync_handle.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
@@ -237,9 +238,7 @@
 /*
  * Prepare for ERET:
  * - Set the ELR to the registered handler address
- * - Set the SPSR register as described in the SDEI documentation and
- *   the AArch64.TakeException() pseudocode function in
- *   ARM DDI 0487F.c page J1-7635
+ * - Set the SPSR register by calling the common create_spsr() function
  */
 
 static void sdei_set_elr_spsr(sdei_entry_t *se, sdei_dispatch_context_t *disp_ctx)
@@ -250,57 +249,7 @@
 
 	u_register_t interrupted_pstate = disp_ctx->spsr_el3;
 
-	/* Check the SPAN bit in the client el SCTLR */
-	u_register_t client_el_sctlr;
-
-	if (client_el == MODE_EL2) {
-		client_el_sctlr = read_sctlr_el2();
-	} else {
-		client_el_sctlr = read_sctlr_el1();
-	}
-
-	/*
-	 * Check whether to force the PAN bit or use the value in the
-	 * interrupted EL according to the check described in
-	 * TakeException. Since the client can only be Non-Secure
-	 * EL2 or El1 some of the conditions in ElIsInHost() we know
-	 * will always be True.
-	 * When the client_el is EL2 we know that there will be a SPAN
-	 * bit in SCTLR_EL2 as we have already checked for the condition
-	 * HCR_EL2.E2H = 1 and HCR_EL2.TGE = 1
-	 */
-	u_register_t hcr_el2 = read_hcr();
-	bool el_is_in_host = (read_feat_vhe_id_field() != 0U) &&
-			     (hcr_el2 & HCR_TGE_BIT) &&
-			     (hcr_el2 & HCR_E2H_BIT);
-
-	if (is_feat_pan_supported() &&
-	    ((client_el == MODE_EL1) ||
-		(client_el == MODE_EL2 && el_is_in_host)) &&
-	    ((client_el_sctlr & SCTLR_SPAN_BIT) == 0U)) {
-		sdei_spsr |=  SPSR_PAN_BIT;
-	} else {
-		sdei_spsr |= (interrupted_pstate & SPSR_PAN_BIT);
-	}
-
-	/* If SSBS is implemented, take the value from the client el SCTLR */
-	u_register_t ssbs_enabled = (read_id_aa64pfr1_el1()
-					>> ID_AA64PFR1_EL1_SSBS_SHIFT)
-					& ID_AA64PFR1_EL1_SSBS_MASK;
-	if (ssbs_enabled != SSBS_UNAVAILABLE) {
-		u_register_t  ssbs_bit = ((client_el_sctlr & SCTLR_DSSBS_BIT)
-						>> SCTLR_DSSBS_SHIFT)
-						<< SPSR_SSBS_SHIFT_AARCH64;
-		sdei_spsr |= ssbs_bit;
-	}
-
-	/* If MTE is implemented in the client el set the TCO bit */
-	if (is_feat_mte_supported()) {
-		sdei_spsr |= SPSR_TCO_BIT_AARCH64;
-	}
-
-	/* Take the DIT field from the pstate of the interrupted el */
-	sdei_spsr |= (interrupted_pstate & SPSR_DIT_BIT);
+	sdei_spsr = create_spsr(interrupted_pstate, client_el);
 
 	cm_set_elr_spsr_el3(NON_SECURE, (uintptr_t) se->ep, sdei_spsr);
 }