Merge changes from topic "xlnx_fix_gen_uniq_var" into integration

* changes:
  fix(psci): avoid altering function parameters
  fix(services): avoid altering function parameters
  fix(common): ignore the unused function return value
  fix(psci): modify variable conflicting with external function
  fix(delay-timer): create unique variable name
diff --git a/.husky/prepare-commit-msg b/.husky/prepare-commit-msg
index 617400a..e38252e 100755
--- a/.husky/prepare-commit-msg
+++ b/.husky/prepare-commit-msg
@@ -1,8 +1,5 @@
 #!/bin/sh
 
-# shellcheck source=./_/husky.sh
-. "$(dirname "$0")/_/husky.sh"
-
 if ! git config --get tf-a.disableCommitizen > /dev/null; then
     "$(dirname "$0")/prepare-commit-msg.cz" "$@"
 fi
diff --git a/Makefile b/Makefile
index 4cba2b0..aae3452 100644
--- a/Makefile
+++ b/Makefile
@@ -581,6 +581,10 @@
 	CTX_INCLUDE_AARCH32_REGS := 0
 	CTX_INCLUDE_PAUTH_REGS := 1
 
+	ifneq ($(ENABLE_FEAT_MPAM), 0)
+		CTX_INCLUDE_MPAM_REGS := 1
+	endif
+
 	# RME enables CSV2_2 extension by default.
 	ENABLE_FEAT_CSV2_2 = 1
 endif #(FEAT_RME)
@@ -615,6 +619,22 @@
 endif
 
 ################################################################################
+# Verify FEAT_RME, FEAT_SCTLR2 and FEAT_TCR2 are enabled if FEAT_MEC is enabled.
+################################################################################
+
+ifneq (${ENABLE_FEAT_MEC},0)
+    ifeq (${ENABLE_RME},0)
+        $(error FEAT_RME must be enabled when FEAT_MEC is enabled.)
+    endif
+    ifeq (${ENABLE_FEAT_TCR2},0)
+        $(error FEAT_TCR2 must be enabled when FEAT_MEC is enabled.)
+    endif
+    ifeq (${ENABLE_FEAT_SCTLR2},0)
+        $(error FEAT_SCTLR2 must be enabled when FEAT_MEC is enabled.)
+    endif
+endif
+
+################################################################################
 # Make 128-Bit sysreg read/writes availabe when FEAT_D128 is enabled.
 ################################################################################
 ifneq (${ENABLE_FEAT_D128}, 0)
@@ -1005,6 +1025,14 @@
     endif
 endif
 
+# Enabling FEAT_MOPS requires access to hcrx_el2 registers which is
+# available only when FEAT_HCX is enabled.
+ifneq (${ENABLE_FEAT_MOPS},0)
+	ifeq (${ENABLE_FEAT_HCX},0)
+		$(error "ENABLE_FEAT_MOPS requires ENABLE_FEAT_HCX")
+	endif
+endif
+
 # Enabling SVE for both the worlds typically requires the context
 # management of SVE registers. The only exception being SPMC at S-EL2.
 ifeq (${ENABLE_SVE_FOR_SWD}, 1)
@@ -1208,6 +1236,7 @@
 	HARDEN_SLS \
 	HW_ASSISTED_COHERENCY \
 	MEASURED_BOOT \
+	DISCRETE_TPM \
 	DICE_PROTECTION_ENVIRONMENT \
 	RMMD_ENABLE_EL3_TOKEN_SIGN \
 	DRTM_SUPPORT \
@@ -1297,6 +1326,7 @@
 	ENABLE_FEAT_FPMR \
 	ENABLE_FEAT_HCX \
 	ENABLE_FEAT_LS64_ACCDATA \
+	ENABLE_FEAT_MEC \
 	ENABLE_FEAT_MOPS \
 	ENABLE_FEAT_MTE2 \
 	ENABLE_FEAT_PAN \
@@ -1393,6 +1423,7 @@
 	HW_ASSISTED_COHERENCY \
 	LOG_LEVEL \
 	MEASURED_BOOT \
+	DISCRETE_TPM \
 	DICE_PROTECTION_ENVIRONMENT \
 	DRTM_SUPPORT \
 	NS_TIMER_SWITCH \
@@ -1466,6 +1497,7 @@
 	ENABLE_FEAT_CSV2_2 \
 	ENABLE_FEAT_CSV2_3 \
 	ENABLE_FEAT_LS64_ACCDATA \
+	ENABLE_FEAT_MEC \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_TCR2 \
 	ENABLE_FEAT_THE \
@@ -1658,7 +1690,7 @@
 # Add Secure Partition packages
 ifeq (${NEED_SP_PKG},yes)
 $(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | $$(@D)/
-	$(if $(host-poetry),$(q)poetry -q install)
+	$(if $(host-poetry),$(q)poetry -q install --no-root)
 	$(q)$(if $(host-poetry),poetry run )${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT} ${SP_DTS_LIST_FRAGMENT}
 sp: $(DTBS) $(BUILD_PLAT)/sp_gen.mk $(SP_PKGS)
 	$(s)echo
@@ -1778,12 +1810,12 @@
 	$(q)${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} CRYPTO_SUPPORT=${CRYPTO_SUPPORT} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES=$(call escape-shell,$(INCLUDES)) DEFINES=$(call escape-shell,$(DEFINES)) --no-print-directory -C ${ROMLIBPATH} all
 
 memmap: all
-	$(if $(host-poetry),$(q)poetry -q install)
+	$(if $(host-poetry),$(q)poetry -q install --no-root)
 	$(q)$(if $(host-poetry),poetry run )memory -sr ${BUILD_PLAT}
 
 tl: ${BUILD_PLAT}/tl.bin
 ${BUILD_PLAT}/tl.bin: ${HW_CONFIG}
-	$(if $(host-poetry),$(q)poetry -q install)
+	$(if $(host-poetry),$(q)poetry -q install --no-root)
 	$(q)$(if $(host-poetry),poetry run )tlc create --fdt $< -s ${FW_HANDOFF_SIZE} $@
 
 doc:
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
index 6d4dc7e..167a22e 100644
--- a/bl1/bl1_fwu.c
+++ b/bl1/bl1_fwu.c
@@ -170,6 +170,9 @@
 	uintptr_t checked_image_base, checked_image_end;
 
 	checked_desc = bl1_plat_get_image_desc(image_id);
+
+	assert(checked_desc != NULL);
+
 	checked_info = &checked_desc->image_info;
 
 	/* Image being checked mustn't be empty. */
diff --git a/bl2/aarch32/bl2_entrypoint.S b/bl2/aarch32/bl2_entrypoint.S
index 678d9c2..91fc682 100644
--- a/bl2/aarch32/bl2_entrypoint.S
+++ b/bl2/aarch32/bl2_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,10 +29,10 @@
 	 * use.
 	 * ---------------------------------------------
 	 */
-	mov	r9, r0
-	mov	r10, r1
-	mov	r11, r2
-	mov	r12, r3
+	mov	r8, r0
+	mov	r9, r1
+	mov	r10, r2
+	mov	r11, r3
 
 	/* ---------------------------------------------
 	 * Set the exception vector to something sane.
@@ -114,10 +114,10 @@
 	 * Perform BL2 setup
 	 * ---------------------------------------------
 	 */
-	mov	r0, r9
-	mov	r1, r10
-	mov	r2, r11
-	mov	r3, r12
+	mov	r0, r8
+	mov	r1, r9
+	mov	r2, r10
+	mov	r3, r11
 
 	bl	bl2_setup
 
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index db0ea6c..0cd0c79 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -255,7 +255,7 @@
  ******************************************************************************/
 void __init bl31_prepare_next_image_entry(void)
 {
-	entry_point_info_t *next_image_info;
+	const entry_point_info_t *next_image_info;
 	uint32_t image_type;
 
 #if CTX_INCLUDE_AARCH32_REGS
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index b1f4343..44d1e66 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -83,3 +83,7 @@
 SP_MIN_WITH_SECURE_FIQ 	?= 0
 $(eval $(call add_define,SP_MIN_WITH_SECURE_FIQ))
 $(eval $(call assert_boolean,SP_MIN_WITH_SECURE_FIQ))
+
+ifeq (${TRANSFER_LIST},1)
+BL32_SOURCES	+=	$(TRANSFER_LIST_SOURCES)
+endif
diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c
index a85b355..9add239 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -113,6 +113,7 @@
 	next_smc_ctx->r0 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R0);
 	next_smc_ctx->r1 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R1);
 	next_smc_ctx->r2 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R2);
+	next_smc_ctx->r3 = read_ctx_reg(cpu_reg_ctx, CTX_GPREG_R3);
 	next_smc_ctx->lr_mon = read_ctx_reg(cpu_reg_ctx, CTX_LR);
 	next_smc_ctx->spsr_mon = read_ctx_reg(cpu_reg_ctx, CTX_SPSR);
 	next_smc_ctx->scr = read_ctx_reg(cpu_reg_ctx, CTX_SCR);
diff --git a/changelog.yaml b/changelog.yaml
index 422b9da..b612831 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -962,6 +962,9 @@
           - drivers/scmi-msg
           - scmi-msg
 
+      - title: TPM
+        scope: tpm
+
       - title: UFS
         scope: ufs
 
@@ -1273,6 +1276,9 @@
       - title: AArch64
         scope: aarch64
 
+      - title: AArch32
+        scope: aarch32
+
       - title: Debug
         scope: debug
 
diff --git a/docs/Makefile b/docs/Makefile
index 68c0958..288cc97 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2025, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -24,5 +24,5 @@
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
 .DEFAULT: Makefile
-	$(if $(host-poetry),$(q)poetry -q install --with=docs)
+	$(if $(host-poetry),$(q)poetry -q install --no-root --with=docs)
 	$(q)$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/components/activity-monitors.rst b/docs/components/activity-monitors.rst
index 4c33d42..d25fcb1 100644
--- a/docs/components/activity-monitors.rst
+++ b/docs/components/activity-monitors.rst
@@ -21,7 +21,9 @@
 
 As a security precaution, Trusted Firmware-A does not enable these by default.
 Instead, platforms must configure their auxiliary counters through the
-``plat_amu_aux_enables`` platform hook.
+``plat_amu_aux_enables`` platform hook. This is a per-core array indexed with
+``plat_my_core_pos()``. A core's value will be written verbatim into
+``AMCNTENSET1_EL0``.
 
 --------------
 
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index f1ca031..2693e58 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -52,8 +52,8 @@
   - ``RES0``: Bit 31 of the version number is reserved 0 as to maintain
     consistency with the versioning schemes used in other parts of RMM.
 
-This document specifies the 0.4 version of Boot Interface ABI and RMM-EL3
-services specification and the 0.4 version of the Boot Manifest.
+This document specifies the 0.5 version of Boot Interface ABI and RMM-EL3
+services specification and the 0.5 version of the Boot Manifest.
 
 .. _rmm_el3_boot_interface:
 
@@ -671,6 +671,54 @@
    ``E_RMM_OK``,No errors detected
 
 
+RMM_MECID_KEY_UPDATE command
+============================
+
+This command updates the tweak for the encryption key/programs a new encryption key
+associated with a given MECID. After the execution of this command, all memory
+accesses associated with the MECID are encrypted/decrypted using the new key.
+This command is available from v0.5 of the RMM-EL3 interface.
+
+FID
+---
+
+``0xC40001B6``
+
+Input values
+------------
+
+.. csv-table:: Input values for RMM_MECID_KEY_UPDATE
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   fid,x0,[63:0],UInt64,Command FID
+   mecid,x1,[15:0],UInt64,"mecid is a 16-bit value between 0 and 65,535 that identifies the MECID for which the encryption key is to be updated. Value has to be a valid MECID as per field MECIDWidthm1 read from MECIDR_EL2. Bits [63:16] must be 0."
+
+Output values
+-------------
+
+.. csv-table:: Output values for RMM_MECID_KEY_UPDATE
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   Result,x0,[63:0],Error Code,Command return status. Valid for all opcodes listed in input values
+
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table:: Failure conditions for RMM_MECID_KEY_UPDATE
+   :header: "ID", "Condition"
+   :widths: 1 5
+
+   ``E_RMM_INVAL``,"if mecid is invalid (larger than 65,535 or than the maximum MECID width, determined by MECIDR_EL2.MECIDWidthm1)"
+   ``E_RMM_UNK``,"An unknown error occurred whilst processing the command or the SMC is not present if interface version is <0.5"
+   ``E_RMM_OK``,No errors detected
+
+
 RMM-EL3 world switch register save restore convention
 _____________________________________________________
 
@@ -720,47 +768,53 @@
 RMM-EL3 Boot Manifest structure
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The RMM-EL3 Boot Manifest v0.4 structure contains platform boot information passed
-from EL3 to RMM. The size of the Boot Manifest is 112 bytes.
+The RMM-EL3 Boot Manifest v0.5 structure contains platform boot information passed
+from EL3 to RMM. The size of the Boot Manifest is 160 bytes.
 
 The members of the RMM-EL3 Boot Manifest structure are shown in the following
 table:
 
-+--------------------+--------+-------------------+----------------------------------------------+
-|   Name             | Offset |       Type        |            Description                       |
-+====================+========+===================+==============================================+
-| version            |   0    |      uint32_t     | Boot Manifest version                        |
-+--------------------+--------+-------------------+----------------------------------------------+
-| padding            |   4    |      uint32_t     | Reserved, set to 0                           |
-+--------------------+--------+-------------------+----------------------------------------------+
-| plat_data          |   8    |     uintptr_t     | Pointer to Platform Data section             |
-+--------------------+--------+-------------------+----------------------------------------------+
-| plat_dram          |   16   |    memory_info    | NS DRAM Layout Info structure                |
-+--------------------+--------+-------------------+----------------------------------------------+
-| plat_console       |   40   |   console_list    | List of consoles available to RMM            |
-+--------------------+--------+-------------------+----------------------------------------------+
-| plat_ncoh_region   |   64   |    memory_info    | Device non-coherent ranges Info structure    |
-+--------------------+--------+-------------------+----------------------------------------------+
-| plat_coh_region    |   88   |    memory_info    | Device coherent ranges Info structure        |
-+--------------------+--------+-------------------+----------------------------------------------+
++-------------------+--------+-------------------+----------------------------------------------+
+|        Name       | Offset |       Type        |                 Description                  |
++===================+========+===================+==============================================+
+| version           |   0    |      uint32_t     | Boot Manifest version                        |
++-------------------+--------+-------------------+----------------------------------------------+
+| padding           |   4    |      uint32_t     | Reserved, set to 0                           |
++-------------------+--------+-------------------+----------------------------------------------+
+| plat_data         |   8    |      uint64_t     | Pointer to Platform Data section             |
++-------------------+--------+-------------------+----------------------------------------------+
+| plat_dram         |   16   |    memory_info    | NS DRAM Layout Info structure                |
++-------------------+--------+-------------------+----------------------------------------------+
+| plat_console      |   40   |   console_list    | List of consoles available to RMM            |
++-------------------+--------+-------------------+----------------------------------------------+
+| plat_ncoh_region  |   64   |    memory_info    | Device non-coherent ranges Info structure    |
++-------------------+--------+-------------------+----------------------------------------------+
+| plat_coh_region   |   88   |    memory_info    | Device coherent ranges Info structure        |
++-------------------+--------+-------------------+----------------------------------------------+
+| plat_smmu         |   112  |     smmu_list     | List of SMMUs available to RMM               |
+|                   |        |                   | (from Boot Manifest v0.5)                    |
++-------------------+--------+-------------------+----------------------------------------------+
+| plat_root_complex |   136  | root_complex_list | List of PCIe root complexes available to RMM |
+|                   |        |                   | (from Boot Manifest v0.5)                    |
++-------------------+--------+-------------------+----------------------------------------------+
 
 .. _memory_info_struct:
 
 Memory Info structure
-~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~
 
 Memory Info structure contains information about platform memory layout.
 The members of this structure are shown in the table below:
 
-+-----------+--------+----------------+----------------------------------------+
-|   Name    | Offset |     Type       |               Description              |
-+===========+========+================+========================================+
-| num_banks |   0    |   uint64_t     | Number of memory banks/device regions  |
-+-----------+--------+----------------+----------------------------------------+
-| banks     |   8    |  memory_bank * | Pointer to 'memory_bank'[] array       |
-+-----------+--------+----------------+----------------------------------------+
-| checksum  |   16   |   uint64_t     | Checksum                               |
-+-----------+--------+----------------+----------------------------------------+
++-----------+--------+---------------+----------------------------------------+
+|   Name    | Offset |     Type      |              Description               |
++===========+========+===============+========================================+
+| num_banks |   0    |    uint64_t   | Number of memory banks/device regions  |
++-----------+--------+---------------+----------------------------------------+
+| banks     |   8    | memory_bank * | Pointer to 'memory_bank'[] array       |
++-----------+--------+---------------+----------------------------------------+
+| checksum  |   16   |    uint64_t   | Checksum                               |
++-----------+--------+---------------+----------------------------------------+
 
 Checksum is calculated as two's complement sum of 'num_banks', 'banks' pointer
 and memory banks data array pointed by it.
@@ -772,13 +826,13 @@
 
 Memory Bank structure contains information about each memory bank/device region:
 
-+-----------+--------+----------------+--------------------------------------------+
-|   Name    | Offset |     Type       |                Description                 |
-+===========+========+================+============================================+
-|   base    |   0    |   uintptr_t    | Base address                               |
-+-----------+--------+----------------+--------------------------------------------+
-|   size    |   8    |   uint64_t     | Size of memory bank/device region in bytes |
-+-----------+--------+----------------+--------------------------------------------+
++------+--------+----------+--------------------------------------------+
+| Name | Offset |   Type   |                Description                 |
++======+========+==========+============================================+
+| base |   0    | uint64_t | Base address                               |
++------+--------+----------+--------------------------------------------+
+| size |   8    | uint64_t | Size of memory bank/device region in bytes |
++------+--------+----------+--------------------------------------------+
 
 .. _console_list_struct:
 
@@ -788,15 +842,15 @@
 Console List structure contains information about the available consoles for RMM.
 The members of this structure are shown in the table below:
 
-+--------------+--------+----------------+-------------------------------------+
-|   Name       | Offset |     Type       |               Description           |
-+==============+========+================+=====================================+
-| num_consoles |   0    |   uint64_t     | Number of consoles                  |
-+--------------+--------+----------------+-------------------------------------+
-| consoles     |   8    | console_info * | Pointer to 'console_info'[] array   |
-+--------------+--------+----------------+-------------------------------------+
-| checksum     |   16   |   uint64_t     | Checksum                            |
-+--------------+--------+----------------+-------------------------------------+
++--------------+--------+----------------+-----------------------------------+
+|   Name       | Offset |     Type       |           Description             |
++==============+========+================+===================================+
+| num_consoles |   0    |   uint64_t     | Number of consoles                |
++--------------+--------+----------------+-----------------------------------+
+| consoles     |   8    | console_info * | Pointer to 'console_info'[] array |
++--------------+--------+----------------+-----------------------------------+
+| checksum     |   16   |   uint64_t     | Checksum                          |
++--------------+--------+----------------+-----------------------------------+
 
 Checksum is calculated as two's complement sum of 'num_consoles', 'consoles'
 pointer and the consoles array pointed by it.
@@ -808,21 +862,144 @@
 
 Console Info structure contains information about each Console available to RMM.
 
++-----------+--------+----------+--------------------------------------+
+|   Name    | Offset |   Type   |             Description              |
++===========+========+==========+======================================+
+| base      |   0    | uint64_t | Console Base address                 |
++-----------+--------+----------+--------------------------------------+
+| map_pages |   8    | uint64_t | Num of pages to map for console MMIO |
++-----------+--------+----------+--------------------------------------+
+| name      |   16   | char[8]  | Name of console                      |
++-----------+--------+----------+--------------------------------------+
+| clk_in_hz |   24   | uint64_t | UART clock (in Hz) for console       |
++-----------+--------+----------+--------------------------------------+
+| baud_rate |   32   | uint64_t | Baud rate                            |
++-----------+--------+----------+--------------------------------------+
+| flags     |   40   | uint64_t | Additional flags (RES0)              |
++-----------+--------+----------+--------------------------------------+
+
+.. _smmu_list_struct:
+
+SMMU List structure
+~~~~~~~~~~~~~~~~~~~
+
+SMMU List structure contains information about SMMUs available for RMM.
+The members of this structure are shown in the table below:
+
++-----------+--------+-------------+--------------------------------+
+|    Name   | Offset |     Type    |          Description           |
++===========+========+=============+================================+
+| num_smmus |   0    |   uint64_t  | Number of SMMUs                |
++-----------+--------+-------------+--------------------------------+
+| smmus     |   8    | smmu_info * | Pointer to 'smmu_info'[] array |
++-----------+--------+-------------+--------------------------------+
+| checksum  |   16   |   uint64_t  | Checksum                       |
++-----------+--------+-------------+--------------------------------+
+
+.. _smmu_info_struct:
+
+SMMU Info structure
+~~~~~~~~~~~~~~~~~~~
+
+SMMU Info structure contains information about each SMMU available to RMM.
+
++-------------+--------+----------+-------------------------------+
+|    Name     | Offset |   Type   |          Description          |
++=============+========+==========+===============================+
+| smmu_base   |   0    | uint64_t | SMMU Base address             |
++-------------+--------+----------+-------------------------------+
+| smmu_r_base |   8    | uint64_t | SMMU Realm Pages base address |
++-------------+--------+----------+-------------------------------+
+
+.. _root_complex_list_struct:
+
+Root Complex List structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Root Complex List structure contains information about PCIe root complexes available for RMM.
+The members of this structure are shown in the table below.
+
++------------------+--------+---------------------+-------------------------------------+
+|       Name       | Offset |        Type         |           Description               |
++==================+========+=====================+=====================================+
+| num_root_complex |   0    |      uint64_t       | Number of root complexes            |
++------------------+--------+---------------------+-------------------------------------+
+| rc_info_version  |   8    |      uint32_t       | Root Complex Info structure version |
++------------------+--------+---------------------+-------------------------------------+
+| padding          |   12   |      uint32_t       | Reserved, set to 0                  |
++------------------+--------+---------------------+-------------------------------------+
+| root_complex     |   16   | root_complex_info * | Pointer to 'root_complex'[] array   |
++------------------+--------+---------------------+-------------------------------------+
+| checksum         |   24   |      uint64_t       | Checksum                            |
++------------------+--------+---------------------+-------------------------------------+
+
+The checksum calculation of Root Complex List structure includes all data structures
+referenced by 'root_complex_info' pointer.
+
+.. _root_complex_info_struct:
+
+Root Complex Info structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Root Complex Info structure contains information about each PCIe root complex available to RMM.
+The table below describes the members of this structure as per v0.1.
+
++-----------------+--------+------------------+-------------------------------------+
+|    Name         | Offset |       Type       |               Description           |
++=================+========+==================+=====================================+
+| ecam_base       |   0    |     uint64_t     | PCIe ECAM Base address              |
++-----------------+--------+------------------+-------------------------------------+
+| segment         |   8    |     uint8_t      | PCIe segment identifier             |
++-----------------+--------+------------------+-------------------------------------+
+| padding[3]      |   9    |     uint8_t      | Reserved, set to 0                  |
++-----------------+--------+------------------+-------------------------------------+
+| num_root_ports  |   12   |     uint32_t     | Number of root ports                |
++-----------------+--------+------------------+-------------------------------------+
+| root_ports      |   16   | root_port_info * | Pointer to 'root_port_info'[] array |
++-----------------+--------+------------------+-------------------------------------+
+
+The Root Complex Info structure version uses the same numbering scheme as described in
+:ref:`rmm_el3_ifc_versioning`.
+
+.. _root_port_info_struct:
+
+Root Port Info structure
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Root Complex Info structure contains information about each root port in PCIe root complex.
+
++------------------+--------+--------------------+---------------------------------------+
+|      Name        | Offset |       Type         |              Description              |
++==================+========+====================+=======================================+
+| root_port_id     |   0    |     uint16_t       | Root Port identifier                  |
++------------------+--------+--------------------+---------------------------------------+
+| padding          |   2    |     uint16_t       | Reserved, set to 0                    |
++------------------+--------+--------------------+---------------------------------------+
+| num_bdf_mappings |   4    |     uint32_t       | Number of BDF mappings                |
++------------------+--------+--------------------+---------------------------------------+
+| bdf_mappings     |   8    | bdf_mapping_info * | Pointer to 'bdf_mapping_info'[] array |
++------------------+--------+--------------------+---------------------------------------+
+
+.. _bdf_mapping_info_struct:
+
+BDF Mapping Info structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+BDF Mapping Info structure contains information about each Device-Bus-Function (BDF) mapping
+for PCIe root port.
+
-+-----------+--------+---------------+-----------------------------------------+
-|   Name    | Offset |     Type      |               Description               |
-+===========+========+===============+=========================================+
-| base      |   0    |   uintptr_t   | Console Base address                    |
-+-----------+--------+---------------+-----------------------------------------+
-| map_pages |   8    |   uint64_t    | Num of pages to map for console MMIO    |
-+-----------+--------+---------------+-----------------------------------------+
-| name      |   16   |   char[8]     | Name of console                         |
-+-----------+--------+---------------+-----------------------------------------+
-| clk_in_hz |   24   |   uint64_t    | UART clock (in Hz) for console          |
-+-----------+--------+---------------+-----------------------------------------+
-| baud_rate |   32   |   uint64_t    | Baud rate                               |
-+-----------+--------+---------------+-----------------------------------------+
-| flags     |   40   |   uint64_t    | Additional flags (RES0)                 |
-+-----------+--------+---------------+-----------------------------------------+
++--------------+--------+----------+------------------------------------------------------+
+|     Name     | Offset |   Type   |                     Description                      |
++==============+========+==========+======================================================+
+| mapping_base |   0    | uint16_t | Base of BDF mapping (inclusive)                      |
++--------------+--------+----------+------------------------------------------------------+
+| mapping_top  |   2    | uint16_t | Top of BDF mapping (exclusive)                       |
++--------------+--------+----------+------------------------------------------------------+
+| mapping_off  |   4    | uint16_t | Mapping offset, as per Arm Base System Architecture: |
+|              |        |          | StreamID = RequesterID[N-1:0] + (1<<N)*Constant_B    |
++--------------+--------+----------+------------------------------------------------------+
+| smmu_idx     |   6    | uint16_t | SMMU index in 'smmu_info'[] array                    |
++--------------+--------+----------+------------------------------------------------------+
 
 .. _el3_token_sign_request_struct:
 
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 67f29f0..117372f 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -311,10 +311,6 @@
 -  ``ERRATA_A78_1952683``: This applies errata 1952683 workaround to Cortex-A78
    CPU. This needs to be enabled for revision r0p0, it is fixed in r1p0.
 
--  ``ERRATA_A78_2132060``: This applies errata 2132060 workaround to Cortex-A78
-   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2. It
-   is still open.
-
 -  ``ERRATA_A78_2242635``: This applies errata 2242635 workaround to Cortex-A78
    CPU. This needs to be enabled for revisions r1p0, r1p1, and r1p2. The issue
    is present in r0p0 but there is no workaround. It is still open.
@@ -377,10 +373,6 @@
   Cortex-A78C CPU. This needs to be enabled for revision r0p0. The erratum is
   fixed in r0p1.
 
-- ``ERRATA_A78C_2132064`` : This applies errata 2132064 workaround to
-  Cortex-A78C CPU. This needs to be enabled for revisions r0p1, r0p2 and
-  it is still open.
-
 - ``ERRATA_A78C_2242638`` : This applies errata 2242638 workaround to
   Cortex-A78C CPU. This needs to be enabled for revisions r0p1, r0p2 and
   it is still open.
@@ -505,10 +497,6 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the
    CPU.  It is still open.
 
--  ``ERRATA_V1_2108267``: This applies errata 2108267 workaround to Neoverse-V1
-   CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU.
-   It is still open.
-
 -  ``ERRATA_V1_2216392``: This applies errata 2216392 workaround to Neoverse-V1
    CPU. This needs to be enabled for revisions r1p0 and r1p1 of the CPU, the
    issue is present in r0p0 as well but there is no workaround for that
@@ -545,10 +533,6 @@
 
 For Neoverse V2, the following errata build flags are defined :
 
--  ``ERRATA_V2_2331132``: This applies errata 2331132 workaround to Neoverse-V2
-   CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is still
-   open.
-
 -  ``ERRATA_V2_2618597``: This applies errata 2618597 workaround to Neoverse-V2
    CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in
    r0p2.
@@ -609,10 +593,6 @@
    Cortex-A710 CPU. This needs to be enabled for revision r2p0 of the CPU and
    is still open.
 
--  ``ERRATA_A710_2058056``: This applies errata 2058056 workaround to
-   Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
-   and r2p1 of the CPU and is still open.
-
 -  ``ERRATA_A710_2267065``: This applies errata 2267065 workaround to
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
@@ -686,9 +666,6 @@
 -  ``ERRATA_N2_2138956``: This applies errata 2138956 workaround to Neoverse-N2
    CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
--  ``ERRATA_N2_2138953``: This applies errata 2138953 workaround to Neoverse-N2
-   CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2, r0p3 and is still open.
-
 -  ``ERRATA_N2_2242415``: This applies errata 2242415 workaround to Neoverse-N2
    CPU. This needs to be enabled for revision r0p0 of the CPU and is fixed in r0p1.
 
@@ -752,10 +729,6 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, and r2p0 of the CPU,
    it is still open.
 
--  ``ERRATA_X2_2058056``: This applies errata 2058056 workaround to Cortex-X2
-   CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the CPU,
-   it is still open.
-
 -  ``ERRATA_X2_2083908``: This applies errata 2083908 workaround to Cortex-X2
    CPU. This needs to be enabled for revision r2p0 of the CPU, it is still open.
 
@@ -806,10 +779,6 @@
 
 For Cortex-X3, the following errata build flags are defined :
 
-- ``ERRATA_X3_2070301``: This applies errata 2070301 workaround to the Cortex-X3
-  CPU. This needs to be enabled only for revisions r0p0, r1p0, r1p1 and r1p2 of
-  the CPU and is still open.
-
 - ``ERRATA_X3_2266875``: This applies errata 2266875 workaround to the Cortex-X3
   CPU. This needs to be enabled only for revisions r0p0 and r1p0 of the CPU, it
   is fixed in r1p1.
@@ -956,6 +925,10 @@
    Cortex-A510 CPU. This needs to be applied to revision r0p0, r0p1, r0p2,
    r0p3, r1p0, r1p1 and r1p2. It is fixed in r1p3.
 
+-  ``ERRATA_A510_2971420``: This applies erratum 2971420 workaround to
+   Cortex-A510 CPU. This needs to be applied to revisions r0p1, r0p2, r0p3,
+   r1p0, r1p1, r1p2 and r1p3 and is still open.
+
 For Cortex-A520, the following errata build flags are defined :
 
 -  ``ERRATA_A520_2630792``: This applies errata 2630792 workaround to
@@ -1001,9 +974,13 @@
    Cortex-A715 CPU. This needs to be enabled for revisions r0p0, r1p0
    and r1p1. It is fixed in r1p2.
 
+-  ``ERRATA_A715_2804830``: This applies errata 2804830 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revisions r0p0, r1p0,
+   r1p1 and r1p2. It is fixed in r1p3.
+
 -  ``ERRATA_A715_3699560``: This applies errata 3699560 workaround to
    Cortex-A715 CPU. This needs to be enabled for revisions r0p0, r1p0,
-   r1p2, r1p3. It is still open.
+   r1p2 and r1p3. It is still open.
 
 For Cortex-A720, the following errata build flags are defined :
 
diff --git a/docs/design_documents/dtpm_drivers.rst b/docs/design_documents/dtpm_drivers.rst
new file mode 100644
index 0000000..324af03
--- /dev/null
+++ b/docs/design_documents/dtpm_drivers.rst
@@ -0,0 +1,119 @@
+Discrete TPM drivers
+====================
+
+This section focuses on the design and functionality of Discrete TPM drivers
+in |TF-A|. The |TPM| technology is designed to provide
+a dedicated, hardware-based solution for storing cryptographic keys and
+performing security-related operations.
+
+Discrete TPMs are separate, standalone hardware components that are physically
+isolated from the system's main processor. This isolation helps protect
+sensitive information, such as encryption keys and platform credentials, from
+being accessed or tampered with by malicious software or unauthorized users.
+When a Discrete TPM interface is implemented correctly, the risk of software
+based attacks is reduced, further reducing the attack surface.
+
+TPM measurements establish the security posture of a system and are used for
+attestation. Performing measurements using a TPM in TF-A is beneficial from
+a security standpoint because it ensures hardware-backed attestation earlier
+in the boot flow, reducing the risk of a compromised root of trust.
+
+The design implemented in TF-A supports multiple types of TPM hardware interfaces
+and hardware bus types in order to be compatible with different platforms.
+Platforms opt to use a specific messaging interface, such as |CRB| or |FIFO|,
+and a specific hardware bus interface, such as |I2C| or |SPI|.
+
+Driver architecture
+-------------------
+
+The Discrete TPM drivers are split up into four layers, each serving a distinct
+purpose in the overall architecture:
+
+   - **Command Layer**: This layer provides various TPM commands based on the
+     `TCG TPM 2.0 Library Specification`_. It allows a system to initialize the
+     TPM interface, perform a TPM startup, set up a locality for operations like
+     PCR extend and read, and release the locality when finished.
+   - **Interface Layer**: This layer handles sending and receiving TPM commands
+     via a specific TPM interface like FIFO or CRB. It also includes functions
+     such as getting information, requesting access, and relinquishing access,
+     tailored to the specific interface.
+   - **Link Layer**: Discrete TPMs may appear as a SPI, I2C, or memory mapped
+     device. The link layer maps the command passed from the interface layer to
+     the appropriate bus type. It includes hardware link read and write functions
+     that use the platform bus interface to transfer commands.
+   - **Platform Layer**: The platform layer implements the details of how to
+     communicate to the TPM chip for a specific platform. The link layer uses the
+     platform layer to read and write to the TPM.
+
+   .. note::
+      The command, interface, and link layers are implemented in common code in
+      TF-A. The platform layer is implemented in platform specific code.
+
+The following diagram illustrates the Discrete TPM driver stack for the Raspberry
+Pi 3 platform.
+
+|rpi3 dtpm driver stack|
+
+Header files
+^^^^^^^^^^^^
+- TPM Drivers: ``include/drivers/tpm``
+
+
+Source files
+^^^^^^^^^^^^
+- TPM Drivers: ``drivers/tpm``
+
+
+Build time config options
+-------------------------
+
+- ``MBOOT_TPM_HASH_ALG``: The hash algorithm to be used by the TPM, currently
+  the only supported algorithm is ``sha256``. As additional Discrete TPMs are
+  tested and integrated in TF-A, support for more algorithms will become
+  available.
+- ``DISCRETE_TPM``: Boolean flag to enable Discrete TPM support. Depending
+  on the selected TPM interface, the appropriate drivers will be built and
+  packaged into firmware.
+- ``TPM_INTERFACE``: This flag is required when ``DISCRETE_TPM=1``,
+  currently the only supported interface is ``FIFO_SPI``.
+  Ideally there should be four options:
+
+  .. code:: shell
+
+      FIFO_I2C
+      FIFO_SPI
+      FIFO_MMIO
+      CRB
+
+  .. note::
+    ``MBOOT_TPM_HASH_ALG`` will automatically overwrite ``MBOOT_EL_HASH_ALG``.
+    This is to ensure the event log and the TPM are using the same hash
+    algorithm.
+
+
+Discrete TPM Initialization
+---------------------------
+The TPM needs to be initialized based on the platform, the hardware interfaces
+need to be set up independently, and once they are setup, the TPM commands
+``tpm_interface_init()`` and subsequently ``tpm_startup()`` can be called.
+``tpm_startup()`` only needs to be called once after startup, or if the system
+is reset.
+
+An example of platform specific TPM hardware initialization for the rpi3 can be
+found in ``plat/rpi/rpi3/rpi3_bl1_setup.c`` and ``plat/rpi/rpi3/rpi3_bl1_mboot.c``
+
+
+Discrete TPM PCR Extend
+-----------------------
+Once the TPM is setup, the TPM ``pcr_extend`` operation can be used to extend
+hashes and store them in PCR 0.
+
+An example of ``pcr_extend`` that is used during rpi3 measured boot can be found
+ in ``plat/rpi/rpi3/rpi3_bl1_mboot.c`` and ``plat/rpi/rpi3/rpi3_bl2_mboot.c``.
+
+
+*Copyright (c) 2025, Arm Limited. All rights reserved.*
+
+.. |rpi3 dtpm driver stack| image::
+   ../resources/diagrams/rpi3_dtpm_driver.png
+.. _TCG TPM 2.0 Library Specification: https://trustedcomputinggroup.org/resource/tpm-library-specification/
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index f1d8386..11c1c5a 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -7,10 +7,12 @@
 
    cmake_framework
    measured_boot_poc
+   measured_boot_dtpm_poc
    drtm_poc
    rse
    psci_osi_mode
    measured_boot
+   dtpm_drivers
 
 --------------
 
diff --git a/docs/design_documents/measured_boot.rst b/docs/design_documents/measured_boot.rst
index 005903e..1f76770 100644
--- a/docs/design_documents/measured_boot.rst
+++ b/docs/design_documents/measured_boot.rst
@@ -91,6 +91,14 @@
    and the variable length crypto agile structure called TCG_PCR_EVENT2. Event
    Log driver implemented in TF-A covers later part.
 
+#. Discrete TPM
+
+   A Discrete TPM (Trusted Platform Module) can be used alongside Event Log to
+   extend measurements and validate Measured Boot functionality. The use of a
+   Discrete TPM in TF-A to extend measurements of images and other critical data
+   allows for an additional layer of security. The TPM can be used to attest the
+   integrity of the Event Log.
+
 #. |RSE|
 
    It is one of the physical backends to extend the measurements. Please refer
@@ -229,7 +237,7 @@
 
 --------------
 
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2025, Arm Limited. All rights reserved.*
 
 .. _Arm® Server Base Security Guide: https://developer.arm.com/documentation/den0086/latest
 .. _TCG EFI Protocol Specification: https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf
diff --git a/docs/design_documents/measured_boot_dtpm_poc.rst b/docs/design_documents/measured_boot_dtpm_poc.rst
new file mode 100644
index 0000000..63a12f2
--- /dev/null
+++ b/docs/design_documents/measured_boot_dtpm_poc.rst
@@ -0,0 +1,458 @@
+Measured Boot using a Discrete TPM (PoC)
+========================================
+
+Measured Boot is the process of cryptographically measuring the code and
+critical data used at boot time, for example using a TPM, so that the
+security state can be attested later.
+
+The current implementation of the driver included in |TF-A| supports several
+backends and each has a different means to store the measurements.
+This section focuses on the Discrete TPM backend, which stores measurements
+in a PCR within the TPM. This backend can be paired with the `TCG event log`_
+to provide attestation of the measurements stored in the event log. See
+details in :ref:`Measured Boot Design`.
+
+This section provides instructions to setup and build a proof of concept (PoC)
+that showcases the use of Measured Boot with a Discrete TPM interface.
+
+.. note::
+   The instructions given in this document are meant to build a PoC to
+   show how Measured Boot on TF-A can interact with a Discrete TPM interface.
+   This PoC is platform specific, and uses a SPI based Discrete TPM, the
+   Raspberry Pi communicates with the TPM via a GPIO pin bit-banged SPI interface.
+   For other platforms, different may be required to interface with the hardware
+   (e.g., different hardware communication protocols) and different TPM interfaces
+   (e.g., |FIFO| vs |CRB|).
+
+Components
+~~~~~~~~~~
+
+   - **Platform**: The PoC is developed on the Raspberry Pi 3 (rpi3), due to quick
+     driver development and the availability of GPIO pins to interface with a TPM
+     expansion module. Measured boot capabilities using the TCG Event Log are
+     ported to the Raspberry Pi 3 platform inside TF-A. This PoC specifically uses
+     the Raspberry Pi 3 Model B V1.2, but this PoC is compatible with other
+     Raspberry Pi 3 models.
+
+   - **Discrete TPM**: The TPM chip selected is a breakout board compatible with
+     the Raspberry Pi 3 GPIO pins. This PoC uses a |SPI| based LetsTrust TPM
+     breakout board equipped with a Infineon Optiga™ SLB 9670 TPM 2.0 chip. Link
+     to device: https://thepihut.com/products/letstrust-tpm-for-raspberry-pi
+
+   .. note::
+      If you have another TPM breakout board that uses the same
+      Infineon Optiga™ SLB 9670 TPM 2.0 SPI based chip, it will also work.
+      Ensure that the correct GPIO pins are utilized on the Raspberry Pi 3 to
+      avoid communication issues, and possible hardware failures.
+
+   - **TF-A TPM Drivers**: To interface with a physical (Discrete) TPM chip in
+     TF-A, the PoC uses TF-A drivers that provide the command, interface, link,
+     and platform layers required to send and receive data to and from the TPM.
+     The drivers are located in TFA, and not in a |SP|, so that they may be used
+     in early stages such as BL2, and in some cases, BL1. The design of the TPM
+     Drivers is documented here: :ref:`Discrete TPM drivers`.
+
+   - **U-boot BL33**: This PoC showcases measured boot up to BL33, and for
+     simplicity uses a U-boot image for BL33, so that the image is measured and
+     loaded. Currently U-boot does not have Discrete TPM support for the
+     Raspberry Pi 3 platform so the boot flow ends here.
+
+
+Building the PoC for the Raspberry Pi 3
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Build instructions for U-Boot.bin for Raspberry Pi 3.**
+
+First, the build requires a BL33 firmware image that can be packaged and measured
+by TF-A.
+
+U-boot can be built for the Raspberry Pi 3, but there are some changes to be made
+to allow the build to succeed. First Clone U-boot and enter the repo.
+
+.. code:: shell
+
+    git clone https://github.com/u-boot/u-boot.git
+    cd u-boot
+
+Now to switch to a specific tag ``v2024.04``  for testing purposes, and then build
+the defconfig labelled ``rpi_3_b_plus_defconfig``.
+
+.. code:: shell
+
+    git checkout tags/v2024.04 -b tfa_dtpm_poc
+    make CROSS_COMPILE=aarch64-linux-gnu- rpi_3_b_plus_defconfig
+
+Lastly open the ``.config`` and change ``CONFIG_TEXT_BASE`` and
+``CONFIG_SYS_UBOOT_START`` to ``0x11000000`` to match the BL33 starting point.
+
+.. code:: shell
+
+    vim .config
+    CONFIG_TEXT_BASE=0x11000000
+    CONFIG_SYS_UBOOT_START=0x11000000
+
+To build the u-boot binary, use the following command.
+
+.. code:: shell
+
+    make CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
+
+**Build TF-A for Raspberry Pi 3 with Discrete TPM and Measured Boot.**
+
+Copy over the ``u-boot.bin`` file over to your TF-A working directory.
+
+.. code:: shell
+
+    cp /path/to/u-boot/build/u-boot.bin /path/to/tfa/u-boot.bin
+
+TF-A build command:
+
+.. code:: shell
+
+    CROSS_COMPILE=aarch64-linux-gnu-      \
+    make PLAT=rpi3                        \
+    RPI3_PRELOADED_DTB_BASE=0x200000      \
+    BL33=u-boot.bin                       \
+    SUPPORT_VFP=1                         \
+    DEBUG=0                               \
+    MEASURED_BOOT=1                       \
+    DISCRETE_TPM=1                        \
+    MBOOT_TPM_HASH_ALG=sha256             \
+    TPM_INTERFACE=FIFO_SPI                \
+    MBEDTLS_DIR=/path/to/mbedtls/repo     \
+    LOG_LEVEL=40                          \
+    fip all
+
+This build command is similar to the one provided in the TF-A Raspberry Pi 3
+platform port, To learn more about the platform and its build options, visit
+:ref:`Raspberry Pi 3`.
+
+   - ``RPI3_PRELOADED_DTB_BASE`` is given a different address to accommodate the
+     larger BL1 and BL2 firmware sizes, this is to accommodate the TPM drivers
+     that are packaged in BL1 and BL2 for this PoC.
+   - ``BL33`` is the non trusted firmware, in this case the U-Boot binary built
+     earlier.
+   - ``SUPPORT_VFP`` is enabled, allows Vector Floating Point operations in EL3.
+   - ``MEASURED_BOOT`` is enabled to allow the Measured Boot flow.
+   - ``DISCRETE_TPM=1`` enables the build of Discrete TPM drivers.
+   - ``MBOOT_TPM_HASH_ALG=sha256`` sets the hash algorithm to sha256, this is
+     the only algorithm supported by both TF-A Measured Boot and the SLB 9670
+     TPM 2.0.
+   - ``TPM_INTERFACE=FIFO_SPI`` specifies the use of the FIFO SPI interface.
+   - ``MBEDTLS_DIR`` is the path to your local mbedtls repo.
+   - ``LOG_LEVEL=40`` ensures that eventlog is printed at the end of BL1 and BL2.
+
+
+**Hardware Setup:**
+
+   - **TPM Connection**: Connect the LetsTrust TPM board to GPIO pins 17 - 26 on
+     the 40-pin GPIO header on the Raspberry Pi board. The 2x5 header of the TPM
+     module must be aligned to the pins in a specific orientation, match the 3v3
+     and RST pins from the TPM board to pins 17 and 18 respectively on the
+     Raspberry Pi 3 header. See `rpi3 pinout`_.
+
+   - **Serial Console**: Establish a serial connection to the Raspberry Pi 3 to
+     view serial output during the boot sequence. The GND, TXD, and RXD pins,
+     which are labelled 6, 8, and 10 on the Raspberry Pi 3 header respectively,
+     are the required pins to establish a serial connection. The recommended way
+     to connect to the board from another system is to use a USB to serial TTL
+     cable to output the serial console in a easy manner.
+
+   - **SD Card Setup**: Format a SD Card as ``FAT32`` with a default Raspbian
+     installation that is similar to the default Raspberry Pi 3 boot partition,
+     this partition will utilize the default files installed in the root
+     directory with Rasbian such as:
+
+    ::
+
+        bcm2710-rpi3-b.dtb
+        bootcode.bin
+        config.txt
+        fixup.dat
+        start.elf
+
+    Open ``config.txt`` and overwrite the file with the following lines:
+
+    ::
+
+        arm_64bit=1
+        disable_commandline_tags=2
+        enable_uart=1
+        armstub=armstub8.bin
+        device_tree_address=0x200000
+        device_tree_end=0x210000
+
+    These configurations are required to enable uart, enable 64bit mode,
+    use the build TF binary, and the modified rpi3 device tree address
+    and size.
+
+    Copy ``armstub8.bin`` from the TF-A build path to the root folder of the
+    SD card.
+
+    The SD Card is now ready to be booted.
+
+Running the PoC for the Raspberry Pi 3
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Insert the SD Card into the Raspberry Pi 3 SD card port and boot the system.
+
+To access the serial console output from the Raspberry Pi 3 you can either:
+
+   - Follow `instructions`_ to use PuTTY to connect to Raspberry Pi 3 serial console.
+
+   - Use the linux ``screen`` command:
+
+      .. code:: shell
+
+        screen /dev/ttyUSB0 115200
+
+Once booted the output from the serial console will look like this:
+
+.. code:: shell
+
+    Raspberry Pi Bootcode
+
+    Read File: config.txt, 153
+
+    Read File: start.elf, 2975040 (bytes)
+
+    Read File: fixup.dat, 7265 (bytes)
+
+    MESS:00:00:01.170422:0: brfs: File read: /mfs/sd/config.txt
+    MESS:00:00:01.174630:0: brfs: File read: 153 bytes
+    MESS:00:00:01.211473:0: HDMI0:EDID error reading EDID block 0 attempt 0
+    MESS:00:00:01.217639:0: HDMI0:EDID error reading EDID block 0 attempt 1
+    MESS:00:00:01.223977:0: HDMI0:EDID error reading EDID block 0 attempt 2
+    MESS:00:00:01.230313:0: HDMI0:EDID error reading EDID block 0 attempt 3
+    MESS:00:00:01.236650:0: HDMI0:EDID error reading EDID block 0 attempt 4
+    MESS:00:00:01.242987:0: HDMI0:EDID error reading EDID block 0 attempt 5
+    MESS:00:00:01.249324:0: HDMI0:EDID error reading EDID block 0 attempt 6
+    MESS:00:00:01.255660:0: HDMI0:EDID error reading EDID block 0 attempt 7
+    MESS:00:00:01.261997:0: HDMI0:EDID error reading EDID block 0 attempt 8
+    MESS:00:00:01.268334:0: HDMI0:EDID error reading EDID block 0 attempt 9
+    MESS:00:00:01.274429:0: HDMI0:EDID giving up on reading EDID block 0
+    MESS:00:00:01.282647:0: brfs: File read: /mfs/sd/config.txt
+    MESS:00:00:01.286929:0: gpioman: gpioman_get_pin_num: pin LEDS_PWR_OK not defined
+    MESS:00:00:01.487295:0: gpioman: gpioman_get_pin_num: pin DISPLAY_DSI_PORT not defined
+    MESS:00:00:01.494853:0: gpioman: gpioman_get_pin_num: pin LEDS_PWR_OK not defined
+    MESS:00:00:01.500763:0: *** Restart logging
+    MESS:00:00:01.504638:0: brfs: File read: 153 bytes
+    MESS:00:00:01.510139:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 0
+    MESS:00:00:01.517254:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 1
+    MESS:00:00:01.524112:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 2
+    MESS:00:00:01.530970:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 3
+    MESS:00:00:01.537826:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 4
+    MESS:00:00:01.544685:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 5
+    MESS:00:00:01.551543:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 6
+    MESS:00:00:01.558399:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 7
+    MESS:00:00:01.565258:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 8
+    MESS:00:00:01.572116:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 9
+    MESS:00:00:01.578730:0: hdmi: HDMI0:EDID giving up on reading EDID block 0
+    MESS:00:00:01.584634:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 0
+    MESS:00:00:01.592427:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 1
+    MESS:00:00:01.599286:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 2
+    MESS:00:00:01.606142:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 3
+    MESS:00:00:01.613001:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 4
+    MESS:00:00:01.619858:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 5
+    MESS:00:00:01.626717:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 6
+    MESS:00:00:01.633575:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 7
+    MESS:00:00:01.640431:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 8
+    MESS:00:00:01.647288:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 9
+    MESS:00:00:01.653905:0: hdmi: HDMI0:EDID giving up on reading EDID block 0
+    MESS:00:00:01.659769:0: hdmi: HDMI:hdmi_get_state is deprecated, use hdmi_get_display_state instead
+    MESS:00:00:01.668264:0: HDMI0: hdmi_pixel_encoding: 162000000
+    MESS:00:00:01.673988:0: vec: vec_middleware_power_on: vec_base: 0x7e806000 rev-id 0x00002708 @ vec: 0x7e806100 @ 0x00000420 enc: 0x7e806060 @ 0x00000220 cgmsae: 0x7e80605c @ 0x00000000
+    MESS:00:00:01.880234:0: dtb_file 'bcm2710-rpi-3-b.dtb'
+    MESS:00:00:01.889713:0: brfs: File read: /mfs/sd/bcm2710-rpi-3-b.dtb
+    MESS:00:00:01.894375:0: Loaded 'bcm2710-rpi-3-b.dtb' to 0x200000 size 0x7cb2
+    MESS:00:00:01.915761:0: brfs: File read: 31922 bytes
+    MESS:00:00:02.007202:0: brfs: File read: /mfs/sd/config.txt
+    MESS:00:00:02.017277:0: brfs: File read: 153 bytes
+    MESS:00:00:02.020772:0: Failed to open command line file 'cmdline.txt'
+    MESS:00:00:02.042302:0: gpioman: gpioman_get_pin_num: pin EMMC_ENABLE not defined
+    MESS:00:00:02.398066:0: kernel=
+    MESS:00:00:02.455255:0: brfs: File read: /mfs/sd/armstub8.bin
+    MESS:00:00:02.459284:0: Loaded 'armstub8.bin' to 0x0 size 0xdbe74
+    MESS:00:00:02.465109:0: No compatible kernel found
+    MESS:00:00:02.469610:0: Device tree loaded to 0x200000 (size 0x823f)
+    MESS:00:00:02.476805:0: uart: Set PL011 baud rate to 103448.300000 Hz
+    MESS:00:00:02.483381:0: uart: Baud rate change done...
+    MESS:00:00:02.486793:0: uart: Baud rateNOTICE:  Booting Trusted Firmware
+    NOTICE:  BL1: v2.11.0(release):v2.11.0-187-g0cb1ddc9c-dirty
+    NOTICE:  BL1: Built : 10:57:10, Jul  9 2024
+    INFO:    BL1: RAM 0x100ee000 - 0x100f9000
+    INFO:    Using crypto library 'mbed TLS'
+    NOTICE:  TPM Chip: vendor-id 0xd1, device-id 0x0, revision-id: 0x16
+    NOTICE:  rpi3: Detected: Raspberry Pi 3 Model B (1GB, Sony, UK) [0x00a02082]
+    INFO:    BL1: Loading BL2
+    INFO:    Loading image id=1 at address 0x100b4000
+    INFO:    Image id=1 loaded: 0x100b4000 - 0x100c0281
+    INFO:    TCG_EfiSpecIDEvent:
+    INFO:      PCRIndex           : 0
+    INFO:      EventType          : 3
+    INFO:      Digest             : 00
+    INFO:          : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:          : 00 00 00
+    INFO:      EventSize          : 33
+    INFO:      Signature          : Spec ID Event03
+    INFO:      PlatformClass      : 0
+    INFO:      SpecVersion        : 2.0.2
+    INFO:      UintnSize          : 1
+    INFO:      NumberOfAlgorithms : 1
+    INFO:      DigestSizes        :
+    INFO:        #0 AlgorithmId   : SHA256
+    INFO:           DigestSize    : 32
+    INFO:      VendorInfoSize     : 0
+    INFO:    PCR_Event2:
+    INFO:      PCRIndex           : 0
+    INFO:      EventType          : 3
+    INFO:      Digests Count      : 1
+    INFO:        #0 AlgorithmId   : SHA256
+    INFO:           Digest        : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:          : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:      EventSize          : 17
+    INFO:      Signature          : StartupLocality
+    INFO:      StartupLocality    : 0
+    INFO:    PCR_Event2:
+    INFO:      PCRIndex           : 0
+    INFO:      EventType          : 1
+    INFO:      Digests Count      : 1
+    INFO:        #0 AlgorithmId   : SHA256
+    INFO:           Digest        : 55 11 51 d8 8b 7f 41 d3 18 16 f2 e8 80 bf 80 fa
+    INFO:          : b4 03 6d 96 4c a0 0a 98 45 cf 25 2f 1e a9 09 3e
+    INFO:      EventSize          : 5
+    INFO:      Event              : BL_2
+    NOTICE:  BL1: Booting BL2
+    INFO:    Entry point address = 0x100b4000
+    INFO:    SPSR = 0x3c5
+    NOTICE:  BL2: v2.11.0(release):v2.11.0-187-g0cb1ddc9c-dirty
+    NOTICE:  BL2: Built : 10:56:39, Jul  9 2024
+    INFO:    Using crypto library 'mbed TLS'
+    NOTICE:  TPM Chip: vendor-id 0xd1, device-id 0x0, revision-id: 0x16
+    INFO:    BL2: Doing platform setup
+    INFO:    BL2: Loading image id 3
+    INFO:    Loading image id=3 at address 0x100e0000
+    INFO:    Image id=3 loaded: 0x100e0000 - 0x100e706b
+    INFO:    BL2: Loading image id 5
+    INFO:    Loading image id=5 at address 0x11000000
+    INFO:    Image id=5 loaded: 0x11000000 - 0x110a8ad8
+    INFO:    TCG_EfiSpecIDEvent:
+    INFO:      PCRIndex           : 0
+    INFO:      EventType          : 3
+    INFO:      Digest             : 00
+    INFO:          : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:          : 00 00 00
+    INFO:      EventSize          : 33
+    INFO:      Signature          : Spec ID Event03
+    INFO:      PlatformClass      : 0
+    INFO:      SpecVersion        : 2.0.2
+    INFO:      UintnSize          : 1
+    INFO:      NumberOfAlgorithms : 1
+    INFO:      DigestSizes        :
+    INFO:        #0 AlgorithmId   : SHA256
+    INFO:           DigestSize    : 32
+    INFO:      VendorInfoSize     : 0
+    INFO:    PCR_Event2:
+    INFO:      PCRIndex           : 0
+    INFO:      EventType          : 3
+    INFO:      Digests Count      : 1
+    INFO:        #0 AlgorithmId   : SHA256
+    INFO:           Digest        : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:          : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:      EventSize          : 17
+    INFO:      Signature          : StartupLocality
+    INFO:      StartupLocality    : 0
+    INFO:    PCR_Event2:
+    INFO:      PCRIndex           : 0
+    INFO:      EventType          : 1
+    INFO:      Digests Count      : 1
+    INFO:        #0 AlgorithmId   : SHA256
+    INFO:           Digest        : 55 11 51 d8 8b 7f 41 d3 18 16 f2 e8 80 bf 80 fa
+    INFO:          : b4 03 6d 96 4c a0 0a 98 45 cf 25 2f 1e a9 09 3e
+    INFO:      EventSize          : 5
+    INFO:      Event              : BL_2
+    INFO:    PCR_Event2:
+    INFO:      PCRIndex           : 0
+    INFO:      EventType          : 1
+    INFO:      Digests Count      : 1
+    INFO:        #0 AlgorithmId   : SHA256
+    INFO:           Digest        : f3 00 5c ed a2 12 8b 76 b7 82 da c5 28 c3 02 52
+    INFO:          : 19 e4 3a 82 f2 3c ab 1e 0d 78 84 9c b5 fe e2 4f
+    INFO:      EventSize          : 14
+    INFO:      Event              : SECURE_RT_EL3
+    INFO:    PCR_Event2:
+    INFO:      PCRIndex           : 0
+    INFO:      EventType          : 1
+    INFO:      Digests Count      : 1
+    INFO:        #0 AlgorithmId   : SHA256
+    INFO:           Digest        : 90 28 81 42 12 b7 9b ca aa 0c 40 76 33 5a 69 71
+    INFO:          : b6 19 2b 90 f2 d2 69 b8 de 8e 6d 05 4d c2 73 f9
+    INFO:      EventSize          : 6
+    INFO:      Event              : BL_33
+    NOTICE:  BL1: Booting BL31
+    INFO:    Entry point address = 0x100e0000
+    INFO:    SPSR = 0x3cd
+    NOTICE:  BL31: v2.11.0(release):v2.11.0-187-g0cb1ddc9c-dirty
+    NOTICE:  BL31: Built : 10:56:58, Jul  9 2024
+    INFO:    rpi3: Checking DTB...
+    INFO:    rpi3: Reserved 0x10000000 - 0x10100000 in DTB
+    INFO:    BL31: Initializing runtime services
+    INFO:    BL31: Preparing for EL3 exit to normal world
+    INFO:    Entry point address = 0x11000000
+    INFO:    SPSR = 0x3c9
+
+
+    U-Boot 2024.04-g84314330-dirty (Apr 23 2024 - 15:41:54 -0500)
+
+    DRAM:  948 MiB
+    RPI 3 Model B (0xa02082)
+    Core:  68 devices, 14 uclasses, devicetree: embed
+    MMC:   mmc@7e202000: 0, mmc@7e300000: 1
+    Loading Environment from FAT... OK
+    In:    serial,usbkbd
+    Out:   serial,vidconsole
+    Err:   serial,vidconsole
+    Net:   No ethernet found.
+    starting USB...
+    Bus usb@7e980000: USB DWC2
+    scanning bus usb@7e980000 for devices...
+    Error: smsc95xx_eth No valid MAC address found.
+    2 USB Device(s) found
+          scanning usb for storage devices... 0 Storage Device(s) found
+    Hit any key to stop autoboot:  2  1  0
+    Card did not respond to voltage select! : -110
+    No EFI system partition
+    No EFI system partition
+    Failed to persist EFI variables
+    No EFI system partition
+    Failed to persist EFI variables
+    No EFI system partition
+    Failed to persist EFI variables
+    Missing TPMv2 device for EFI_TCG_PROTOCOL
+    ** Booting bootflow '<NULL>' with efi_mgr
+    Loading Boot0000 'mmc 0' failed
+    EFI boot manager: Cannot load any image
+    Boot failed (err=-14)
+    Card did not respond to voltage select! : -110
+    No ethernet found.
+    No ethernet found.
+    U-Boot>
+
+
+Next steps for Discrete TPM and Measured Boot development
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In order to automatically validate the workings of the Discrete TPM, the creation
+of test cases that compare the eventlog image hashes with what is stored in PCR0
+are a great way to test the core functionality of the Discrete TPM in Measured Boot.
+
+Development of Discrete TPM drivers such as a reference FIFO |I2C|, MMIO, and CRB
+drivers has not started, these drivers will allow a larger number of platform
+to use a Discrete TPM in TF-A.
+
+*Copyright (c) 2025, Arm Limited. All rights reserved.*
+
+.. _TCG event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/
+.. _rpi3 pinout: https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#gpio
+.. _instructions: https://www.circuitbasics.com/use-putty-to-access-the-raspberry-pi-terminal-from-a-computer/
+.. _workaround:  https://github.com/mhomran/u-boot-rpi3-b-plus
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 2b36fda..b5814bb 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -784,6 +784,20 @@
 
    This option defaults to 0.
 
+-  ``DISCRETE_TPM``: Boolean flag to include support for a Discrete TPM.
+
+   This option defaults to 0.
+
+-  ``TPM_INTERFACE``: When ``DISCRETE_TPM=1``, this is a required flag to
+   select the TPM interface. Currently only one interface is supported:
+
+   ::
+
+      FIFO_SPI
+
+-  ``MBOOT_TPM_HASH_ALG``: Build flag to select the TPM hash algorithm used during
+   Measured Boot. Currently only accepts ``sha256`` as a valid algorithm.
+
 -  ``MARCH_DIRECTIVE``: used to pass a -march option from the platform build
    options to the compiler. An example usage:
 
@@ -1382,6 +1396,12 @@
    Management Extension. This flag can take the values 0 to 2, to align with
    the ``ENABLE_FEAT`` mechanism. Default value is 0.
 
+-  ``ENABLE_FEAT_MEC``: Numeric value to enable support for the ARMv9.2 Memory
+   Encryption Contexts (MEC). This flag can take the values 0 to 2, to align
+   with the ``ENABLE_FEAT`` mechanism. MEC supports multiple encryption
+   contexts for Realm security state and only one encryption context for the
+   rest of the security states. Default value is 0.
+
 -  ``RMMD_ENABLE_EL3_TOKEN_SIGN``: Numeric value to enable support for singing
    realm attestation token signing requests in EL3. This flag can take the
    values 0 and 1. The default value is ``0``. When set to ``1``, this option
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index 23a91cd..ecf6d63 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -6,6 +6,7 @@
 .. |BTI| replace:: :term:`BTI`
 .. |CoT| replace:: :term:`CoT`
 .. |COT| replace:: :term:`COT`
+.. |CRB| replace:: :term:`CRB`
 .. |CSS| replace:: :term:`CSS`
 .. |CVE| replace:: :term:`CVE`
 .. |DICE| replace:: :term:`DICE`
@@ -19,11 +20,13 @@
 .. |FCONF| replace:: :term:`FCONF`
 .. |FDT| replace:: :term:`FDT`
 .. |FF-A| replace:: :term:`FF-A`
+.. |FIFO| replace:: :term:`FIFO`
 .. |FIP| replace:: :term:`FIP`
 .. |FVP| replace:: :term:`FVP`
 .. |FWU| replace:: :term:`FWU`
 .. |GIC| replace:: :term:`GIC`
 .. |HES| replace:: :term:`HES`
+.. |I2C| replace:: :term:`I2C`
 .. |ISA| replace:: :term:`ISA`
 .. |Linaro| replace:: :term:`Linaro`
 .. |MMU| replace:: :term:`MMU`
@@ -55,6 +58,7 @@
 .. |SP| replace:: :term:`SP`
 .. |SPD| replace:: :term:`SPD`
 .. |SPM| replace:: :term:`SPM`
+.. |SPI| replace:: :term:`SPI`
 .. |SRTM| replace:: :term:`SRTM`
 .. |SSBS| replace:: :term:`SSBS`
 .. |SVE| replace:: :term:`SVE`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 20ad21c..8bb35bc 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -36,6 +36,9 @@
    CSS
       Compute Sub-System
 
+   CRB
+      Command Response Buffer
+
    CVE
       Common Vulnerabilities and Exposures. A CVE document is commonly used to
       describe a publicly-known security vulnerability.
@@ -88,6 +91,9 @@
    FF-A
       Firmware Framework for Arm A-profile
 
+   FIFO
+      First In, First Out
+
    FIP
       Firmware Image Package
 
@@ -103,6 +109,9 @@
    HES
       Arm CCA Hardware Enforced Security
 
+   I2C
+      Inter-Integrated Circuit Protocol
+
    ISA
       Instruction Set Architecture
 
@@ -211,6 +220,9 @@
    SPM
       Secure Partition Manager
 
+   SPI
+      Serial Peripheral Interface
+
    SRTM
       Static Root of Trust for Measurement
 
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 0f0dedd..327c67b 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2350,6 +2350,24 @@
 
 When ENABLE_RME is disabled, this function is not used.
 
+Function : plat_rmm_mecid_key_update() [when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uint16_t
+    Return   : int
+
+This function is invoked by BL31's RMMD when there is a request from the RMM
+monitor to update the tweak for the encryption key associated to a MECID.
+
+The first parameter (``uint16_t mecid``) contains the MECID for which the
+encryption key is to be updated.
+
+Return value is 0 upon success and -EFAULT otherwise.
+
+This function needs to be implemented by a platform if it enables RME.
+
 Function : plat_rmmd_el3_token_sign_push_req() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/resources/diagrams/rpi3_dtpm_driver.png b/docs/resources/diagrams/rpi3_dtpm_driver.png
new file mode 100644
index 0000000..36b1843
--- /dev/null
+++ b/docs/resources/diagrams/rpi3_dtpm_driver.png
Binary files differ
diff --git a/docs/threat_model/firmware_threat_model/threat_model.rst b/docs/threat_model/firmware_threat_model/threat_model.rst
index ae0219e..c0cc3be 100644
--- a/docs/threat_model/firmware_threat_model/threat_model.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model.rst
@@ -928,6 +928,12 @@
      Measured Boot implementation in |TF-A| is that it does not extend the
      measurements into a |PCR| of a Discrete |TPM|, where measurements would
      be securely stored and protected against tampering.
+   - Discrete |TPM|: Implemented in |TF-A| as a proof of concept, the Discrete
+     |TPM| is used alongside the existing TCG-compliant Event Log. This
+     Measured Boot implementation extends measurement hashes to a |PCR| in the
+     |TPM|, which provides a hardware-backed root of trust. The measurements in
+     the Event Log can now be hashed and compared to the value of the |PCR| to
+     determine if tampering of the Event Log has taken place.
    - `CCA Measured Boot`_: Implemented by |TF-M|. Measurements are stored in
      |HES| secure on-chip memory. |HES| implements protection against tampering
      its on-chip memory. |HES| interface is available for BL1 and BL2.
@@ -942,6 +948,20 @@
  to protect or threats to defend against that could compromise |TF-A| execution
  environment's security.
 
+ When considering the implementation of Measured Boot using a TCG-compliant
+ Event Log backed by a discrete TPM, physical vulnerabilities come to mind.
+ Platforms have many different ways of integrating a discrete TPM, and these
+ implementations can be susceptible to man-in-the-middle attacks, where the
+ attacker intercepts the bus traffic between the discrete TPM and the host
+ machine. This can lead to PCR extend operations being modified, compromising
+ Measured Boot. This vulnerability requires physical access to the host machine.
+
+ TF-A does not provide any mitigations against these physical vulnerabilities,
+ it is the responsibility of the platform owners to address this based on their
+ specific threat model. Mitigation of this can be achieved through dedicated
+ hardware solutions, such as an encrypted AP/dTPM bus, or software-based
+ approaches designed to protect sensitive data such as parameter encryption.
+
  There are general security assets and threats associated with remote/delegated
  attestation. However, these are outside the |TF-A| security boundary and
  should be dealt with by the appropriate agent in the platform/system.
@@ -1192,7 +1212,7 @@
 
 --------------
 
-*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2025, Arm Limited. All rights reserved.*
 
 
 .. _STRIDE threat analysis technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
diff --git a/drivers/arm/cci/cci.c b/drivers/arm/cci/cci.c
index 40d2efd..ae2b9bb 100644
--- a/drivers/arm/cci/cci.c
+++ b/drivers/arm/cci/cci.c
@@ -143,7 +143,7 @@
 	 * rest of bits are write ignore
 	 */
 	mmio_write_32(cci_base +
-		      SLAVE_IFACE_OFFSET(slave_if_id) + SNOOP_CTRL_REG,
+		      SLAVE_IFACE_OFFSET((u_register_t)slave_if_id) + SNOOP_CTRL_REG,
 		      DVM_EN_BIT | SNOOP_EN_BIT);
 
 	/*
@@ -171,7 +171,7 @@
 	 * rest of bits are write ignore.
 	 */
 	mmio_write_32(cci_base +
-		      SLAVE_IFACE_OFFSET(slave_if_id) + SNOOP_CTRL_REG,
+		      SLAVE_IFACE_OFFSET((u_register_t)slave_if_id) + SNOOP_CTRL_REG,
 		      ~(DVM_EN_BIT | SNOOP_EN_BIT));
 
 	/*
diff --git a/drivers/arm/gic/v2/gicdv2_helpers.c b/drivers/arm/gic/v2/gicdv2_helpers.c
index db9ba87..2f3f7f8 100644
--- a/drivers/arm/gic/v2/gicdv2_helpers.c
+++ b/drivers/arm/gic/v2/gicdv2_helpers.c
@@ -8,6 +8,7 @@
 
 #include <drivers/arm/gic_common.h>
 #include <lib/mmio.h>
+#include <lib/utils_def.h>
 
 #include "../common/gic_common_private.h"
 
@@ -256,7 +257,7 @@
 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
 	unsigned int reg_val = gicd_read_igroupr(base, id);
 
-	gicd_write_igroupr(base, id, reg_val | (1U << bit_num));
+	gicd_write_igroupr(base, id, reg_val | BIT_32(bit_num));
 }
 
 void gicd_clr_igroupr(uintptr_t base, unsigned int id)
@@ -264,35 +265,35 @@
 	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
 	unsigned int reg_val = gicd_read_igroupr(base, id);
 
-	gicd_write_igroupr(base, id, reg_val & ~(1U << bit_num));
+	gicd_write_igroupr(base, id, reg_val & ~BIT_32(bit_num));
 }
 
 void gicd_set_isenabler(uintptr_t base, unsigned int id)
 {
 	unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
 
-	gicd_write_isenabler(base, id, (1U << bit_num));
+	gicd_write_isenabler(base, id, BIT_32(bit_num));
 }
 
 void gicd_set_icenabler(uintptr_t base, unsigned int id)
 {
 	unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
 
-	gicd_write_icenabler(base, id, (1U << bit_num));
+	gicd_write_icenabler(base, id, BIT_32(bit_num));
 }
 
 void gicd_set_ispendr(uintptr_t base, unsigned int id)
 {
 	unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
 
-	gicd_write_ispendr(base, id, (1U << bit_num));
+	gicd_write_ispendr(base, id, BIT_32(bit_num));
 }
 
 void gicd_set_icpendr(uintptr_t base, unsigned int id)
 {
 	unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
 
-	gicd_write_icpendr(base, id, (1U << bit_num));
+	gicd_write_icpendr(base, id, BIT_32(bit_num));
 }
 
 unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id)
@@ -307,14 +308,14 @@
 {
 	unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
 
-	gicd_write_isactiver(base, id, (1U << bit_num));
+	gicd_write_isactiver(base, id, BIT_32(bit_num));
 }
 
 void gicd_set_icactiver(uintptr_t base, unsigned int id)
 {
 	unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U);
 
-	gicd_write_icactiver(base, id, (1U << bit_num));
+	gicd_write_icactiver(base, id, BIT_32(bit_num));
 }
 
 void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
diff --git a/drivers/arm/gic/v2/gicv2_helpers.c b/drivers/arm/gic/v2/gicv2_helpers.c
index a9ae0b5..3415499 100644
--- a/drivers/arm/gic/v2/gicv2_helpers.c
+++ b/drivers/arm/gic/v2/gicv2_helpers.c
@@ -11,6 +11,7 @@
 #include <common/interrupt_props.h>
 #include <drivers/arm/gic_common.h>
 #include <drivers/arm/gicv2.h>
+#include <lib/utils_def.h>
 
 #include "../common/gic_common_private.h"
 #include "gicv2_private.h"
@@ -203,7 +204,7 @@
 		}
 
 		/* We have an SGI or a PPI. They are Group0 at reset */
-		sec_ppi_sgi_mask |= (1u << prop_desc->intr_num);
+		sec_ppi_sgi_mask |= BIT_32((uint32_t)prop_desc->intr_num);
 
 		/* Set the priority of this interrupt */
 		gicd_set_ipriorityr(gicd_base, prop_desc->intr_num,
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index 5ecbaed..59a4a86 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.c
@@ -79,8 +79,8 @@
 {
 	int ret;
 
-	if ((c == '\n') &&
-	    ((console->flags & CONSOLE_FLAG_TRANSLATE_CRLF) != 0)) {
+	if ((c == (int)'\n') &&
+	    ((console->flags & CONSOLE_FLAG_TRANSLATE_CRLF) != 0U)) {
 		ret = console->putc('\r', console);
 		if (ret < 0)
 			return ret;
diff --git a/drivers/gpio/gpio_spi.c b/drivers/gpio/gpio_spi.c
new file mode 100644
index 0000000..2913b41
--- /dev/null
+++ b/drivers/gpio/gpio_spi.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2025, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/gpio.h>
+#include <drivers/gpio_spi.h>
+#include <platform_def.h>
+
+static struct spi_plat gpio_spidev;
+
+static void gpio_spi_delay_us(void)
+{
+	udelay(gpio_spidev.gpio_data.spi_delay_us);
+}
+
+static int gpio_spi_miso(void)
+{
+	return gpio_get_value(gpio_spidev.gpio_data.miso_gpio);
+}
+
+static void gpio_spi_sclk(int bit)
+{
+	gpio_set_value(gpio_spidev.gpio_data.sclk_gpio, bit);
+}
+
+static void gpio_spi_mosi(int bit)
+{
+	gpio_set_value(gpio_spidev.gpio_data.mosi_gpio, bit);
+}
+
+static void gpio_spi_cs(int bit)
+{
+	gpio_set_value(gpio_spidev.gpio_data.cs_gpio, bit);
+}
+
+static void gpio_spi_start(void)
+{
+	gpio_spi_cs(1);
+	gpio_spi_sclk(0);
+	gpio_spi_cs(0);
+}
+
+static void gpio_spi_stop(void)
+{
+	gpio_spi_cs(1);
+}
+
+/* set sclk to a known state (0) before performing any further action */
+static void gpio_spi_get_access(void)
+{
+	gpio_spi_sclk(0);
+}
+
+static void xfer(unsigned int bytes, const void *out, void *in, int cpol, int cpha)
+{
+	for (unsigned int j = 0U; j < bytes; j++) {
+		unsigned char in_byte  = 0U;
+		unsigned char out_byte = (out != NULL) ? *(const uint8_t *)out++ : 0xFF;
+
+		for (int i = 7; i >= 0; i--) {
+			if (cpha) {
+				gpio_spi_sclk(!cpol);
+			}
+
+			gpio_spi_mosi(!!(out_byte & (1 << i)));
+
+			gpio_spi_delay_us();
+			gpio_spi_sclk(cpha ? cpol : !cpol);
+			gpio_spi_delay_us();
+
+			in_byte |= gpio_spi_miso() << i;
+
+			if (!cpha) {
+				gpio_spi_sclk(cpol);
+			}
+		}
+
+		if (in != NULL) {
+			*(uint8_t *)in++ = in_byte;
+		}
+	}
+}
+
+static int gpio_spi_xfer(unsigned int bytes, const void *out, void *in)
+{
+	if ((out == NULL) && (in == NULL)) {
+		return -1;
+	}
+
+	switch (gpio_spidev.gpio_data.spi_mode) {
+	case 0:
+		xfer(bytes, out, in, 0, 0);
+		break;
+	case 1:
+		xfer(bytes, out, in, 0, 1);
+		break;
+	case 2:
+		xfer(bytes, out, in, 1, 0);
+		break;
+	case 3:
+		xfer(bytes, out, in, 1, 1);
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+struct spi_ops gpio_spidev_ops = {
+	.get_access	= gpio_spi_get_access,
+	.start		= gpio_spi_start,
+	.stop		= gpio_spi_stop,
+	.xfer		= gpio_spi_xfer,
+};
+
+struct spi_plat *gpio_spi_init(struct gpio_spi_data *gpio_spi_data)
+{
+	gpio_spidev.gpio_data = *gpio_spi_data;
+	gpio_spidev.ops = &gpio_spidev_ops;
+
+	return &gpio_spidev;
+}
diff --git a/drivers/measured_boot/event_log/event_log.mk b/drivers/measured_boot/event_log/event_log.mk
index 5ea4c55..9e0d6c4 100644
--- a/drivers/measured_boot/event_log/event_log.mk
+++ b/drivers/measured_boot/event_log/event_log.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2025, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,15 +7,20 @@
 # Default log level to dump the event log (LOG_LEVEL_INFO)
 EVENT_LOG_LEVEL         ?= 40
 
-# Measured Boot hash algorithm.
-# SHA-256 (or stronger) is required for all devices that are TPM 2.0 compliant.
-ifdef TPM_HASH_ALG
-    $(warning "TPM_HASH_ALG is deprecated. Please use MBOOT_EL_HASH_ALG instead.")
-    MBOOT_EL_HASH_ALG		:=	${TPM_HASH_ALG}
+# When using a TPM, adopt the TPM's hash algorithm for
+# measurements through the Event Log mechanism, ensuring
+# the TPM uses the same algorithm for measurements and
+# extends the PCR accordingly, allowing for comparison
+# between PCR value and Event Log measurements required
+# for attestation.
+ifdef MBOOT_TPM_HASH_ALG
+    MBOOT_EL_HASH_ALG		:=	${MBOOT_TPM_HASH_ALG}
 else
     MBOOT_EL_HASH_ALG		:=	sha256
 endif
 
+# Measured Boot hash algorithm.
+# SHA-256 (or stronger) is required for all devices that are TPM 2.0 compliant.
 ifeq (${MBOOT_EL_HASH_ALG}, sha512)
     TPM_ALG_ID			:=	TPM_ALG_SHA512
     TCG_DIGEST_SIZE		:=	64U
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index c4f7493..387469c 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -399,7 +399,7 @@
 int load_partition_table(unsigned int image_id)
 {
 	uintptr_t dev_handle, image_handle, image_spec = 0;
-	mbr_entry_t mbr_entry;
+	mbr_entry_t mbr_entry = {0};
 	int result;
 
 	result = plat_get_image_source(image_id, &dev_handle, &image_spec);
diff --git a/drivers/tpm/tpm2.mk b/drivers/tpm/tpm2.mk
new file mode 100644
index 0000000..4418b97
--- /dev/null
+++ b/drivers/tpm/tpm2.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2025, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TPM2_SRC_DIR	:= drivers/tpm/
+
+TPM2_SOURCES	:= ${TPM2_SRC_DIR}tpm2_cmds.c \
+                   ${TPM2_SRC_DIR}tpm2_chip.c
+
+# TPM Hash algorithm, used during Measured Boot
+# currently only accepts SHA-256
+ifeq (${MBOOT_TPM_HASH_ALG}, sha256)
+    TPM_ALG_ID			:=	TPM_ALG_SHA256
+    TCG_DIGEST_SIZE		:=	32U
+else
+    $(error "The selected MBOOT_TPM_HASH_ALG is invalid.")
+endif #MBOOT_TPM_HASH_ALG
+
+ifeq (${TPM_INTERFACE}, FIFO_SPI)
+    TPM2_SOURCES += ${TPM2_SRC_DIR}tpm2_fifo.c \
+                    ${TPM2_SRC_DIR}tpm2_fifo_spi.c
+else
+    $(error "The selected TPM_INTERFACE is invalid.")
+endif #TPM_INTERFACE
diff --git a/drivers/tpm/tpm2_chip.c b/drivers/tpm/tpm2_chip.c
new file mode 100644
index 0000000..537ce92
--- /dev/null
+++ b/drivers/tpm/tpm2_chip.c
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/tpm/tpm2_chip.h>
+
+/*
+ * TPM timeout values
+ * Reference: TCG PC Client Platform TPM Profile (PTP) Specification v1.05
+ */
+struct tpm_chip_data tpm_chip_data = {
+	.locality = -1,
+	.timeout_msec_a = 750,
+	.timeout_msec_b = 2000,
+	.timeout_msec_c = 200,
+	.timeout_msec_d = 30,
+	.address = 0,
+};
diff --git a/drivers/tpm/tpm2_cmds.c b/drivers/tpm/tpm2_cmds.c
new file mode 100644
index 0000000..b6422a8
--- /dev/null
+++ b/drivers/tpm/tpm2_cmds.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/libc/endian.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/tpm/tpm2.h>
+#include <drivers/tpm/tpm2_chip.h>
+#include <drivers/tpm/tpm2_interface.h>
+
+#define CMD_SIZE_OFFSET	6
+
+#define SINGLE_BYTE	1
+#define TWO_BYTES	2
+#define FOUR_BYTES	4
+
+static struct interface_ops *interface;
+
+static int tpm_xfer(struct tpm_chip_data *chip_data, const tpm_cmd *send, tpm_cmd *receive)
+{
+	int ret;
+
+	ret = interface->send(chip_data, send);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = interface->receive(chip_data, receive);
+	if (ret < 0) {
+		return ret;
+	}
+
+	return TPM_SUCCESS;
+}
+
+int tpm_interface_init(struct tpm_chip_data *chip_data, uint8_t locality)
+{
+	int err;
+
+	interface = tpm_interface_getops(chip_data, locality);
+
+	err = interface->request_access(chip_data, locality);
+	if (err != 0) {
+		return err;
+	}
+
+	return interface->get_info(chip_data, locality);
+}
+
+int tpm_interface_close(struct tpm_chip_data *chip_data, uint8_t locality)
+{
+	return interface->release_locality(chip_data, locality);
+}
+
+static int tpm_update_buffer(tpm_cmd *buf, uint32_t new_data, size_t new_len)
+{
+	int i, j, start;
+	uint32_t command_size;
+
+	union {
+		uint8_t var8;
+		uint16_t var16;
+		uint32_t var32;
+		uint8_t array[4];
+	} tpm_new_data;
+
+	command_size = be32toh(buf->header.cmd_size);
+
+	if (command_size + new_len > MAX_SIZE_CMDBUF) {
+		ERROR("%s: buf size exceeded, increase MAX_SIZE_CMDBUF\n",
+			__func__);
+		return TPM_INVALID_PARAM;
+	}
+	/*
+	 * Subtract the cmd header size from the current command size
+	 * so the data buffer is written to starting at index 0.
+	 */
+	start = command_size - TPM_HEADER_SIZE;
+
+	/*
+	 * The TPM, according to the TCG spec, processes data in BE byte order,
+	 * in the case where the Host is LE, htobe correctly handles the byte order.
+	 * When updating the buffer, keep in mind to only pass sizeof(new_data) or
+	 * the variable type size for the new_len function parameter. This ensures
+	 * there is only the possiblility of writing 1, 2, or 4 bytes to the buffer,
+	 * and that the correct number of bytes are written to data[i].
+	 */
+	if (new_len == SINGLE_BYTE) {
+		tpm_new_data.var8 = new_data & 0xFF;
+	} else if (new_len == TWO_BYTES) {
+		tpm_new_data.var16 = htobe16(new_data & 0xFFFF);
+	} else if (new_len == FOUR_BYTES) {
+		tpm_new_data.var32 = htobe32(new_data);
+	} else {
+		ERROR("%s: Invalid data length\n", __func__);
+		return TPM_INVALID_PARAM;
+	}
+
+	for (i = start, j = 0; i < start + new_len; i++, j++) {
+		buf->data[i] = tpm_new_data.array[j];
+	}
+	buf->header.cmd_size = htobe32(command_size + new_len);
+
+	return TPM_SUCCESS;
+}
+
+
+int tpm_startup(struct tpm_chip_data *chip_data, uint16_t mode)
+{
+	tpm_cmd startup_cmd, startup_response;
+	uint32_t tpm_rc;
+	int ret;
+
+	memset(&startup_cmd, 0, sizeof(startup_cmd));
+	memset(&startup_response, 0, sizeof(startup_response));
+
+	startup_cmd.header.tag = htobe16(TPM_ST_NO_SESSIONS);
+	startup_cmd.header.cmd_size = htobe32(sizeof(tpm_cmd_hdr));
+	startup_cmd.header.cmd_code = htobe32(TPM_CMD_STARTUP);
+
+	ret = tpm_update_buffer(&startup_cmd, mode, sizeof(mode));
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = tpm_xfer(chip_data, &startup_cmd, &startup_response);
+	if (ret < 0) {
+		return ret;
+	}
+
+	tpm_rc = be32toh(startup_response.header.cmd_code);
+	if (tpm_rc != TPM_RESPONSE_SUCCESS) {
+		ERROR("%s: response code contains error = %X\n", __func__, tpm_rc);
+		return TPM_ERR_RESPONSE;
+	}
+
+	return TPM_SUCCESS;
+}
+
+int tpm_pcr_extend(struct tpm_chip_data *chip_data, uint32_t index,
+		uint16_t algorithm, const uint8_t *digest,
+		uint32_t digest_len)
+{
+	tpm_cmd pcr_extend_cmd, pcr_extend_response;
+	uint32_t tpm_rc;
+	int ret;
+
+	memset(&pcr_extend_cmd, 0, sizeof(pcr_extend_cmd));
+	memset(&pcr_extend_response, 0, sizeof(pcr_extend_response));
+
+	if (digest == NULL) {
+		return TPM_INVALID_PARAM;
+	}
+	pcr_extend_cmd.header.tag = htobe16(TPM_ST_SESSIONS);
+	pcr_extend_cmd.header.cmd_size = htobe32(sizeof(tpm_cmd_hdr));
+	pcr_extend_cmd.header.cmd_code = htobe32(TPM_CMD_PCR_EXTEND);
+
+	/* handle (PCR Index)*/
+	ret = tpm_update_buffer(&pcr_extend_cmd, index, sizeof(index));
+	if (ret < 0) {
+		return ret;
+	}
+
+	/* authorization size , session handle, nonce size, attributes*/
+	ret = tpm_update_buffer(&pcr_extend_cmd, TPM_MIN_AUTH_SIZE, sizeof(uint32_t));
+	if (ret < 0) {
+		return ret;
+	}
+	ret = tpm_update_buffer(&pcr_extend_cmd, TPM_RS_PW, sizeof(uint32_t));
+	if (ret < 0) {
+		return ret;
+	}
+	ret = tpm_update_buffer(&pcr_extend_cmd, TPM_ZERO_NONCE_SIZE, sizeof(uint16_t));
+	if (ret < 0) {
+		return ret;
+	}
+	ret = tpm_update_buffer(&pcr_extend_cmd, TPM_ATTRIBUTES_DISABLE, sizeof(uint8_t));
+	if (ret < 0) {
+		return ret;
+	}
+
+	/* hmac/password size */
+	ret = tpm_update_buffer(&pcr_extend_cmd, TPM_ZERO_HMAC_SIZE, sizeof(uint16_t));
+	if (ret < 0) {
+		return ret;
+	}
+
+	/* hashes count */
+	ret = tpm_update_buffer(&pcr_extend_cmd, TPM_SINGLE_HASH_COUNT, sizeof(uint32_t));
+	if (ret < 0) {
+		return ret;
+	}
+
+	/* hash algorithm */
+	ret = tpm_update_buffer(&pcr_extend_cmd, algorithm, sizeof(algorithm));
+	if (ret < 0) {
+		return ret;
+	}
+
+	/* digest */
+	for (int i = 0; i < digest_len; i++) {
+		ret = tpm_update_buffer(&pcr_extend_cmd, digest[i], sizeof(uint8_t));
+		if (ret < 0) {
+			return ret;
+		}
+	}
+
+	ret = tpm_xfer(chip_data, &pcr_extend_cmd, &pcr_extend_response);
+	if (ret < 0) {
+		return ret;
+	}
+
+	tpm_rc = be32toh(pcr_extend_response.header.cmd_code);
+	if (tpm_rc != TPM_RESPONSE_SUCCESS) {
+		ERROR("%s: response code contains error = %X\n", __func__, tpm_rc);
+		return TPM_ERR_RESPONSE;
+	}
+
+	return TPM_SUCCESS;
+}
diff --git a/drivers/tpm/tpm2_fifo.c b/drivers/tpm/tpm2_fifo.c
new file mode 100644
index 0000000..7c4b9d8
--- /dev/null
+++ b/drivers/tpm/tpm2_fifo.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/libc/endian.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/tpm/tpm2.h>
+#include <drivers/tpm/tpm2_chip.h>
+#include <drivers/tpm/tpm2_interface.h>
+
+#define LOCALITY_START_ADDRESS(x, y) \
+	((uint16_t)(x->address + (0x1000 * y)))
+
+static int tpm2_get_info(struct tpm_chip_data *chip_data, uint8_t locality)
+{
+	uint16_t tpm_base_addr = LOCALITY_START_ADDRESS(chip_data, locality);
+	uint32_t vid_did;
+	uint8_t revision;
+	int err;
+
+	err = tpm2_fifo_read_chunk(tpm_base_addr + TPM_FIFO_REG_VENDID, DWORD, &vid_did);
+	if (err < 0) {
+		return err;
+	}
+
+	err = tpm2_fifo_read_byte(tpm_base_addr + TPM_FIFO_REG_REVID, &revision);
+	if (err < 0) {
+		return err;
+	}
+
+	INFO("TPM Chip: vendor-id 0x%x, device-id 0x%x, revision-id: 0x%x\n",
+		0xFFFF & vid_did, vid_did >> 16, revision);
+
+	return TPM_SUCCESS;
+}
+
+static int tpm2_wait_reg_bits(uint16_t reg, uint8_t set, unsigned long timeout, uint8_t *status)
+{
+	int err;
+	uint64_t timeout_delay = timeout_init_us(timeout * 1000);
+
+	do {
+		err = tpm2_fifo_read_byte(reg, status);
+		if (err < 0) {
+			return err;
+		}
+		if ((*status & set) == set) {
+			return TPM_SUCCESS;
+		}
+	} while (!timeout_elapsed(timeout_delay));
+
+	return TPM_ERR_TIMEOUT;
+}
+
+static int tpm2_fifo_request_access(struct tpm_chip_data *chip_data, uint8_t locality)
+{
+	uint16_t tpm_base_addr = LOCALITY_START_ADDRESS(chip_data, locality);
+	uint8_t status;
+	int err;
+
+	err = tpm2_fifo_write_byte(tpm_base_addr + TPM_FIFO_REG_ACCESS, TPM_ACCESS_REQUEST_USE);
+	if (err < 0) {
+		return err;
+	}
+
+	err = tpm2_wait_reg_bits(tpm_base_addr + TPM_FIFO_REG_ACCESS,
+				TPM_ACCESS_ACTIVE_LOCALITY,
+				chip_data->timeout_msec_a, &status);
+	if (err == 0) {
+		chip_data->locality = locality;
+		return TPM_SUCCESS;
+	}
+
+	return err;
+}
+
+static int tpm2_fifo_release_locality(struct tpm_chip_data *chip_data, uint8_t locality)
+{
+	uint16_t tpm_base_addr = LOCALITY_START_ADDRESS(chip_data, locality);
+	uint8_t buf;
+	int err;
+
+	err = tpm2_fifo_read_byte(tpm_base_addr + TPM_FIFO_REG_ACCESS, &buf);
+	if (err < 0) {
+		return err;
+	}
+
+	if (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) {
+		return tpm2_fifo_write_byte(tpm_base_addr + TPM_FIFO_REG_ACCESS,
+				TPM_ACCESS_RELINQUISH_LOCALITY);
+	}
+
+	ERROR("%s: Unable to release locality\n", __func__);
+	return TPM_ERR_RESPONSE;
+}
+
+static int tpm2_fifo_prepare(struct tpm_chip_data *chip_data)
+{
+	uint16_t tpm_base_addr = LOCALITY_START_ADDRESS(chip_data, chip_data->locality);
+	uint8_t status;
+	int err;
+
+	err = tpm2_fifo_write_byte(tpm_base_addr + TPM_FIFO_REG_STATUS, TPM_STAT_COMMAND_READY);
+	if (err < 0) {
+		return err;
+	}
+
+	err = tpm2_wait_reg_bits(tpm_base_addr + TPM_FIFO_REG_STATUS,
+				TPM_STAT_COMMAND_READY,
+				chip_data->timeout_msec_b, &status);
+	if (err < 0) {
+		ERROR("%s: TPM Status Busy\n", __func__);
+		return err;
+	}
+
+	return TPM_SUCCESS;
+}
+
+static int tpm2_fifo_get_burstcount(struct tpm_chip_data *chip_data, uint16_t *burstcount)
+{
+	uint16_t tpm_base_addr = LOCALITY_START_ADDRESS(chip_data, chip_data->locality);
+	uint64_t timeout_delay = timeout_init_us(chip_data->timeout_msec_a * 1000);
+	int err;
+
+	if (burstcount == NULL) {
+		return TPM_INVALID_PARAM;
+	}
+
+	do {
+		uint8_t byte0, byte1;
+
+		err = tpm2_fifo_read_byte(tpm_base_addr + TPM_FIFO_REG_BURST_COUNT_LO, &byte0);
+		if (err < 0) {
+			return err;
+		}
+
+		err = tpm2_fifo_read_byte(tpm_base_addr + TPM_FIFO_REG_BURST_COUNT_HI, &byte1);
+		if (err < 0) {
+			return err;
+		}
+
+		*burstcount = (uint16_t)((byte1 << 8) + byte0);
+		if (*burstcount != 0U) {
+			return TPM_SUCCESS;
+		}
+	} while (!timeout_elapsed(timeout_delay));
+
+	return TPM_ERR_TIMEOUT;
+}
+
+static int tpm2_fifo_send(struct tpm_chip_data *chip_data, const tpm_cmd *buf)
+{
+	uint16_t tpm_base_addr = LOCALITY_START_ADDRESS(chip_data, chip_data->locality);
+	uint8_t status;
+	uint16_t burstcnt;
+	int err;
+	uint32_t len, index;
+
+	if (sizeof(buf->header) != TPM_HEADER_SIZE) {
+		ERROR("%s: invalid command header size.\n", __func__);
+		return TPM_INVALID_PARAM;
+	}
+
+	err = tpm2_fifo_read_byte(tpm_base_addr + TPM_FIFO_REG_STATUS, &status);
+	if (err < 0) {
+		return err;
+	}
+
+	if (!(status & TPM_STAT_COMMAND_READY)) {
+		err = tpm2_fifo_prepare(chip_data);
+		if (err < 0) {
+			return err;
+		}
+	}
+
+	/* write the command header to the TPM first */
+	const uint8_t *header_data = (const uint8_t *)&buf->header;
+
+	for (index = 0; index < TPM_HEADER_SIZE; index++) {
+		err = tpm2_fifo_write_byte(tpm_base_addr + TPM_FIFO_REG_DATA_FIFO,
+				header_data[index]);
+		if (err < 0) {
+			return err;
+		}
+	}
+
+	len =  be32toh(buf->header.cmd_size);
+
+	while (index < len) {
+		err = tpm2_fifo_get_burstcount(chip_data, &burstcnt);
+		if (err < 0) {
+			return err;
+		}
+
+		for (; burstcnt > 0U && index < len; burstcnt--) {
+			err = tpm2_fifo_write_byte(tpm_base_addr + TPM_FIFO_REG_DATA_FIFO,
+					buf->data[index - TPM_HEADER_SIZE]);
+			if (err < 0) {
+				return err;
+			}
+			index++;
+		}
+	}
+
+	err = tpm2_wait_reg_bits(tpm_base_addr + TPM_FIFO_REG_STATUS,
+				TPM_STAT_VALID,
+				chip_data->timeout_msec_c,
+				&status);
+	if (err < 0) {
+		return err;
+	}
+
+	if (status & TPM_STAT_EXPECT) {
+		ERROR("%s: TPM is still expecting data after command buffer is sent\n", __func__);
+		return TPM_ERR_TRANSFER;
+	}
+
+	err = tpm2_fifo_write_byte(tpm_base_addr + TPM_FIFO_REG_STATUS, TPM_STAT_GO);
+	if (err < 0) {
+		return err;
+	}
+
+	return TPM_SUCCESS;
+}
+
+static int tpm2_fifo_read_data(struct tpm_chip_data *chip_data, tpm_cmd *buf,
+			uint16_t tpm_base_addr, uint8_t *status, int *size, int bytes_expected)
+{
+	int err, read_size, loop_index;
+	uint16_t burstcnt;
+	uint8_t *read_data;
+
+	if (bytes_expected == TPM_READ_HEADER) {
+		/* read the response header from the TPM first */
+		read_data = (uint8_t *)&buf->header;
+		read_size = TPM_HEADER_SIZE;
+		loop_index = *size;
+	} else {
+		/* process the rest of the mssg with bytes_expected */
+		read_data = buf->data;
+		read_size = bytes_expected;
+		loop_index = *size - TPM_HEADER_SIZE;
+	}
+
+	err = tpm2_wait_reg_bits(tpm_base_addr + TPM_FIFO_REG_STATUS,
+				TPM_STAT_AVAIL,
+				chip_data->timeout_msec_c,
+				status);
+	if (err < 0) {
+		return err;
+	}
+
+	while (*size < read_size) {
+		err = tpm2_fifo_get_burstcount(chip_data, &burstcnt);
+		if (err < 0) {
+			ERROR("%s: TPM burst count error\n", __func__);
+			return err;
+		}
+
+		for (; burstcnt > 0U && loop_index < read_size;
+		    burstcnt--, loop_index++, (*size)++) {
+			err = tpm2_fifo_read_byte(
+				tpm_base_addr + TPM_FIFO_REG_DATA_FIFO,
+				(void *)&read_data[loop_index]);
+			if (err < 0) {
+				return err;
+			}
+		}
+	}
+
+	return TPM_SUCCESS;
+}
+
+static int tpm2_fifo_receive(struct tpm_chip_data *chip_data, tpm_cmd *buf)
+{
+	uint16_t tpm_base_addr = LOCALITY_START_ADDRESS(chip_data, chip_data->locality);
+	int size = 0, bytes_expected, err;
+	uint8_t status;
+
+	err = tpm2_fifo_read_data(chip_data, buf, tpm_base_addr, &status, &size, TPM_READ_HEADER);
+	if (err < 0) {
+		return err;
+	}
+
+	bytes_expected = be32toh(buf->header.cmd_size);
+	if (bytes_expected > sizeof(*buf)) {
+		ERROR("%s: tpm response buffer cannot store expected response\n", __func__);
+		return TPM_INVALID_PARAM;
+	}
+
+	if (size == bytes_expected) {
+		return size;
+	}
+
+	err = tpm2_fifo_read_data(chip_data, buf, tpm_base_addr, &status, &size, bytes_expected);
+	if (err < 0) {
+		return err;
+	}
+
+	if (size < bytes_expected) {
+		ERROR("%s: response buffer size is less than expected\n", __func__);
+		return TPM_ERR_RESPONSE;
+	}
+
+	return TPM_SUCCESS;
+}
+
+static interface_ops_t fifo_ops = {
+	.get_info = tpm2_get_info,
+	.send = tpm2_fifo_send,
+	.receive = tpm2_fifo_receive,
+	.request_access = tpm2_fifo_request_access,
+	.release_locality = tpm2_fifo_release_locality,
+};
+
+struct interface_ops *
+tpm_interface_getops(struct tpm_chip_data *chip_data,  uint8_t locality)
+{
+	return &fifo_ops;
+}
diff --git a/drivers/tpm/tpm2_fifo_spi.c b/drivers/tpm/tpm2_fifo_spi.c
new file mode 100644
index 0000000..16d87d9
--- /dev/null
+++ b/drivers/tpm/tpm2_fifo_spi.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <drivers/gpio_spi.h>
+#include <drivers/tpm/tpm2.h>
+#include <drivers/tpm/tpm2_chip.h>
+#include <drivers/tpm/tpm2_interface.h>
+
+#define ENCODE_LIMIT		128
+#define CS_ASSERT_OFFSET	0xD4
+#define RETRY_COUNT		50
+
+#define TPM_READ	false
+#define TPM_WRITE	true
+
+extern struct spi_plat *spidev;
+
+static int tpm2_spi_transfer(const void *data_out, void *data_in, uint8_t len)
+{
+	return spidev->ops->xfer(len, data_out, data_in);
+}
+
+/*
+ * Reference: TCG PC Client Platform TPM Profile (PTP) Specification v1.05
+ */
+static int tpm2_spi_start_transaction(uint16_t tpm_reg, bool write, uint8_t len)
+{
+	int rc;
+	uint8_t header[4];
+	uint8_t header_response[4];
+	uint8_t zero = 0, byte;
+	int retries;
+
+	/* check to make sure len does not exceed the encoding limit */
+	if (len > ENCODE_LIMIT) {
+		return TPM_INVALID_PARAM;
+	}
+
+	/*
+	 * 7.4.6 TPM SPI Bit protocol calls for the following header
+	 * to be sent to the TPM at the start of every attempted read/write.
+	 */
+
+	/* header[0] contains the r/w and the xfer size, if the msb is not
+	 * set, the operation is write, if it is set then it is read.
+	 * The size of the transfer is encoded, and must not overwrite
+	 * the msb, therefore an ENCODE LIMIT of 128 is present.
+	 */
+	header[0] = ((write) ? 0x00 : 0x80) | (len - 1);
+
+	/*
+	 * header[1] contains the address offset 0xD4_xxxx as defined
+	 * in the TPM spec, since the CS# is asserted.
+	 */
+	header[1] = CS_ASSERT_OFFSET;
+
+	/*
+	 * header[2] and header[3] contain the address of the register
+	 * to be read/written.
+	 */
+	header[2] = tpm_reg >> 8;
+	header[3] = tpm_reg;
+
+	rc = tpm2_spi_transfer(header, header_response, 4);
+	if (rc != 0) {
+		return TPM_ERR_TRANSFER;
+	}
+
+	/*
+	 * 7.4.5 Flow Control defines a wait state in order to accommodate
+	 * the TPM in case it needs to free its buffer.
+	 */
+	if ((header_response[3] & 0x01) != 0U) {
+		return TPM_SUCCESS;
+	}
+
+	/*
+	 * if the wait state over bit is not set in the initial header_response,
+	 * poll for the wait state over by sending a zeroed byte, if the
+	 * RETRY_COUNT is exceeded the transfer fails.
+	 */
+	for (retries = RETRY_COUNT; retries > 0; retries--) {
+		rc = tpm2_spi_transfer(&zero, &byte, 1);
+		if (rc != 0) {
+			return TPM_ERR_TRANSFER;
+		}
+		if ((byte & 0x01) != 0U) {
+			return TPM_SUCCESS;
+		}
+	}
+
+	if (retries == 0) {
+		ERROR("%s: TPM Timeout\n", __func__);
+		return TPM_ERR_TIMEOUT;
+	}
+
+	return TPM_SUCCESS;
+}
+
+static void tpm2_spi_end_transaction(void)
+{
+	spidev->ops->stop();
+}
+
+static void tpm2_spi_init(void)
+{
+	spidev->ops->get_access();
+	spidev->ops->start();
+}
+
+static int tpm2_fifo_io(uint16_t tpm_reg, bool is_write, uint8_t len, void *val)
+{
+	int rc;
+
+	tpm2_spi_init();
+	rc = tpm2_spi_start_transaction(tpm_reg, is_write, len);
+	if (rc != 0) {
+		tpm2_spi_end_transaction();
+		return rc;
+	}
+
+	rc = tpm2_spi_transfer(
+		is_write ? val : NULL,
+		is_write ? NULL : val,
+		len);
+	if (rc != 0) {
+		tpm2_spi_end_transaction();
+		return rc;
+	}
+
+	tpm2_spi_end_transaction();
+
+	return TPM_SUCCESS;
+}
+
+int tpm2_fifo_write_byte(uint16_t tpm_reg, uint8_t val)
+{
+	return tpm2_fifo_io(tpm_reg, TPM_WRITE, BYTE, &val);
+}
+
+int tpm2_fifo_read_byte(uint16_t tpm_reg, uint8_t *val)
+{
+	return tpm2_fifo_io(tpm_reg, TPM_READ, BYTE, val);
+}
+
+int tpm2_fifo_read_chunk(uint16_t tpm_reg, uint8_t len, void *val)
+{
+	if ((len != BYTE) && (len != WORD) && (len != DWORD)) {
+		return TPM_INVALID_PARAM;
+	}
+
+	return tpm2_fifo_io(tpm_reg, TPM_READ, len, val);
+}
diff --git a/drivers/tpm/tpm2_slb9670/slb9670_gpio.c b/drivers/tpm/tpm2_slb9670/slb9670_gpio.c
new file mode 100644
index 0000000..993387d
--- /dev/null
+++ b/drivers/tpm/tpm2_slb9670/slb9670_gpio.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/delay_timer.h>
+#include <drivers/gpio.h>
+#include <drivers/tpm/tpm2_slb9670/slb9670_gpio.h>
+
+/*
+ * Infineon SLB9670 Chip Reset Parameters
+ */
+#define t_WRST	2 /* Warm Reset Time (us) */
+#define t_RSTIN	60 /* Reset Inactive Time (ms) */
+
+/*
+ * RPi3 GPIO pin configuration for TPM via bit-bang SPI
+ * References: https://pinout.xyz/pinout/spi
+ * - docs/design_documents/measured_boot_dtpm_poc.rst
+ */
+const struct gpio_spi_data tpm_rpi3_gpio_data = {
+	.cs_gpio = 7,
+	.sclk_gpio = 11,
+	.mosi_gpio = 10,
+	.miso_gpio = 9,
+	.reset_gpio = 24,
+	.spi_delay_us = 0,
+	.spi_mode = 0
+};
+
+/*
+ * When RST is asserted at certain points in time, then this
+ * triggers the TPM's security functions, in the case where
+ * multiple resets need to be asserted, there must be a wait
+ * of at least t_RSTIN between the resets
+ *
+ * In most cases this is not needed since RST is only being asserted
+ * once, ie for TPM initialization at the beginning of TFA.
+ */
+void tpm2_slb9670_reset_chip(struct gpio_spi_data *tpm_gpio_data)
+{
+	/*
+	 * since we don't know the value of the pin before it was init to 1
+	 * it is best to assume the state was 0, and account for that by
+	 * adding an initial RST inactive delay
+	 */
+	mdelay(t_RSTIN);
+	/* pull #RST pin to active low for 2us */
+	gpio_set_value(tpm_gpio_data->reset_gpio, 0);
+	udelay(t_WRST);
+	/* wait 60ms after warm reset before sending TPM commands */
+	gpio_set_value(tpm_gpio_data->reset_gpio, 1);
+	mdelay(t_RSTIN);
+}
+
+/*
+ * init GPIO pins for the Infineon slb9670 TPM
+ */
+void tpm2_slb9670_gpio_init(struct gpio_spi_data *tpm_gpio_data)
+{
+	gpio_set_value(tpm_gpio_data->cs_gpio, 1);
+	gpio_set_direction(tpm_gpio_data->cs_gpio, GPIO_DIR_OUT);
+
+	gpio_set_value(tpm_gpio_data->sclk_gpio, 0);
+	gpio_set_direction(tpm_gpio_data->sclk_gpio, GPIO_DIR_OUT);
+
+	gpio_set_value(tpm_gpio_data->mosi_gpio, 1);
+	gpio_set_direction(tpm_gpio_data->mosi_gpio, GPIO_DIR_OUT);
+
+	gpio_set_direction(tpm_gpio_data->miso_gpio, GPIO_DIR_IN);
+
+	gpio_set_value(tpm_gpio_data->reset_gpio, 1);
+	gpio_set_direction(tpm_gpio_data->reset_gpio, GPIO_DIR_OUT);
+}
diff --git a/fdts/fvp-base-psci-common.dtsi b/fdts/fvp-base-psci-common.dtsi
index 95ea2a1..bdb0229 100644
--- a/fdts/fvp-base-psci-common.dtsi
+++ b/fdts/fvp-base-psci-common.dtsi
@@ -29,7 +29,8 @@
 
 	chosen {
 		stdout-path = "serial0:115200n8";
-#if (ENABLE_RME == 1)
+/* SPM_MM doesn't like this */
+#if SPM_MM == 0
 		bootargs = "console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda ip=on";
 #endif
 	};
diff --git a/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi b/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
index 674cb3d..223761f 100644
--- a/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
+++ b/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
@@ -1,21 +1,21 @@
 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
 /*
- * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2025, STMicroelectronics - All Rights Reserved
  */
 
 /*
  * STM32MP25 DDR4 board configuration
  * DDR4 2x8Gbits 2x16bits 1200MHz
  *
- * version     1
- * package     1        Package selection (14x14 and 18x18)
- * memclk      1200MHz  (2x DFI clock) + range check
- * Speed_Bin   Worse    from JEDEC
- * width       32       32: full width / 16: half width
- * ranks       1        Single or Dual rank
- * density     8Gbits   (per 16bit device)
- * Addressing  RBC      row/bank interleaving
- * RDBI        No       Read DBI
+ * version      2
+ * package      1        Package selection (14x14 and 18x18)
+ * memclk       1200MHz  (2x DFI clock) + range check
+ * Speed_Bin    Worse    from JEDEC
+ * device_width 16       x16 by default
+ * width        32       32: full width / 16: half width
+ * density      8Gbits   (per device)
+ * Addressing   RBC      row/bank interleaving
+ * RDBI         No       Read DBI
  */
 
 #define DDR_MEM_NAME	"DDR4 2x8Gbits 2x16bits 1200MHz"
@@ -49,6 +49,7 @@
 #define DDR_INIT7 0x00000C16
 #define DDR_DIMMCTL 0x00000000
 #define DDR_RANKCTL 0x0000066F
+#define DDR_RANKCTL1 0x0000000D
 #define DDR_DRAMTMG0 0x11152815
 #define DDR_DRAMTMG1 0x0004051E
 #define DDR_DRAMTMG2 0x0609060D
@@ -94,31 +95,34 @@
 #define DDR_ADDRMAP11 0x00000007
 #define DDR_ODTCFG 0x06000618
 #define DDR_ODTMAP 0x00000001
-#define DDR_SCHED 0x00000F00
+#define DDR_SCHED 0x80001B00
 #define DDR_SCHED1 0x00000000
-#define DDR_PERFHPR1 0x0F000001
-#define DDR_PERFLPR1 0x0F000080
-#define DDR_PERFWR1 0x01000200
+#define DDR_PERFHPR1 0x04000200
+#define DDR_PERFLPR1 0x08000080
+#define DDR_PERFWR1 0x08000400
+#define DDR_SCHED3 0x04040208
+#define DDR_SCHED4 0x08400810
 #define DDR_DBG0 0x00000000
 #define DDR_DBG1 0x00000000
 #define DDR_DBGCMD 0x00000000
 #define DDR_SWCTL 0x00000000
+#define DDR_SWCTLSTATIC 0x00000000
 #define DDR_POISONCFG 0x00000000
 #define DDR_PCCFG 0x00000000
-#define DDR_PCFGR_0 0x00004100
+#define DDR_PCFGR_0 0x00704100
 #define DDR_PCFGW_0 0x00004100
 #define DDR_PCTRL_0 0x00000000
-#define DDR_PCFGQOS0_0 0x00200007
-#define DDR_PCFGQOS1_0 0x01000100
-#define DDR_PCFGWQOS0_0 0x00000C07
-#define DDR_PCFGWQOS1_0 0x02000200
-#define DDR_PCFGR_1 0x00004100
+#define DDR_PCFGQOS0_0 0x0021000C
+#define DDR_PCFGQOS1_0 0x01000080
+#define DDR_PCFGWQOS0_0 0x01100C07
+#define DDR_PCFGWQOS1_0 0x04000200
+#define DDR_PCFGR_1 0x00704100
 #define DDR_PCFGW_1 0x00004100
 #define DDR_PCTRL_1 0x00000000
-#define DDR_PCFGQOS0_1 0x00200007
-#define DDR_PCFGQOS1_1 0x01000180
-#define DDR_PCFGWQOS0_1 0x00000C07
-#define DDR_PCFGWQOS1_1 0x04000400
+#define DDR_PCFGQOS0_1 0x00100007
+#define DDR_PCFGQOS1_1 0x01000080
+#define DDR_PCFGWQOS0_1 0x01100C07
+#define DDR_PCFGWQOS1_1 0x04000200
 
 #define DDR_UIB_DRAMTYPE 0x00000000
 #define DDR_UIB_DIMMTYPE 0x00000004
diff --git a/fdts/stm32mp25-lpddr4-1x16Gbits-1x32bits-1200MHz.dtsi b/fdts/stm32mp25-lpddr4-1x16Gbits-1x32bits-1200MHz.dtsi
index 3917dc6..32424d0 100644
--- a/fdts/stm32mp25-lpddr4-1x16Gbits-1x32bits-1200MHz.dtsi
+++ b/fdts/stm32mp25-lpddr4-1x16Gbits-1x32bits-1200MHz.dtsi
@@ -7,7 +7,7 @@
  * STM32MP25 LPDDR4 board configuration
  * LPDDR4 1x16Gbits 1x32bits 1200MHz
  *
- * version       1
+ * version       2
  * memclk        1200MHz  (2x DFI clock)
  * width         32       32: full width / 16: half width
  * ranks         1        Single or Dual rank
@@ -46,10 +46,11 @@
 #define DDR_INIT3 0x00C40024
 #define DDR_INIT4 0x00310008
 #define DDR_INIT5 0x00100004
-#define DDR_INIT6 0x00660050
-#define DDR_INIT7 0x00050019
+#define DDR_INIT6 0x00660047
+#define DDR_INIT7 0x00050047
 #define DDR_DIMMCTL 0x00000000
 #define DDR_RANKCTL 0x0000066F
+#define DDR_RANKCTL1 0x00000011
 #define DDR_DRAMTMG0 0x1718141A
 #define DDR_DRAMTMG1 0x00050524
 #define DDR_DRAMTMG2 0x060C1111
@@ -95,25 +96,28 @@
 #define DDR_ADDRMAP11 0x00000007
 #define DDR_ODTCFG 0x04000400
 #define DDR_ODTMAP 0x00000000
-#define DDR_SCHED 0x00001B00
+#define DDR_SCHED 0x80001B00
 #define DDR_SCHED1 0x00000000
 #define DDR_PERFHPR1 0x04000200
 #define DDR_PERFLPR1 0x08000080
 #define DDR_PERFWR1 0x08000400
+#define DDR_SCHED3 0x04040208
+#define DDR_SCHED4 0x08400810
 #define DDR_DBG0 0x00000000
 #define DDR_DBG1 0x00000000
 #define DDR_DBGCMD 0x00000000
 #define DDR_SWCTL 0x00000000
+#define DDR_SWCTLSTATIC 0x00000000
 #define DDR_POISONCFG 0x00000000
 #define DDR_PCCFG 0x00000000
-#define DDR_PCFGR_0 0x00004100
+#define DDR_PCFGR_0 0x00704100
 #define DDR_PCFGW_0 0x00004100
 #define DDR_PCTRL_0 0x00000000
 #define DDR_PCFGQOS0_0 0x0021000C
 #define DDR_PCFGQOS1_0 0x01000080
 #define DDR_PCFGWQOS0_0 0x01100C07
 #define DDR_PCFGWQOS1_0 0x04000200
-#define DDR_PCFGR_1 0x00004100
+#define DDR_PCFGR_1 0x00704100
 #define DDR_PCFGW_1 0x00004100
 #define DDR_PCTRL_1 0x00000000
 #define DDR_PCFGQOS0_1 0x00100007
@@ -148,8 +152,8 @@
 #define DDR_UIA_EXTCALRESVAL 0x00000000
 #define DDR_UIA_IS2TTIMING_0 0x00000000
 #define DDR_UIA_ODTIMPEDANCE_0 0x00000035
-#define DDR_UIA_TXIMPEDANCE_0 0x0000003C
-#define DDR_UIA_ATXIMPEDANCE 0x0000001E
+#define DDR_UIA_TXIMPEDANCE_0 0x00000028
+#define DDR_UIA_ATXIMPEDANCE 0x00000028
 #define DDR_UIA_MEMALERTEN 0x00000000
 #define DDR_UIA_MEMALERTPUIMP 0x00000000
 #define DDR_UIA_MEMALERTVREFLEVEL 0x00000000
@@ -157,7 +161,7 @@
 #define DDR_UIA_DISDYNADRTRI_0 0x00000001
 #define DDR_UIA_PHYMSTRTRAININTERVAL_0 0x0000000A
 #define DDR_UIA_PHYMSTRMAXREQTOACK_0 0x00000005
-#define DDR_UIA_WDQSEXT 0x00000000
+#define DDR_UIA_WDQSEXT 0x00000001
 #define DDR_UIA_CALINTERVAL 0x00000009
 #define DDR_UIA_CALONCE 0x00000000
 #define DDR_UIA_LP4RL_0 0x00000004
@@ -193,9 +197,9 @@
 #define DDR_UIM_MR5_0 0x00000000
 #define DDR_UIM_MR6_0 0x00000000
 #define DDR_UIM_MR11_0 0x00000066
-#define DDR_UIM_MR12_0 0x00000050
+#define DDR_UIM_MR12_0 0x00000047
 #define DDR_UIM_MR13_0 0x00000008
-#define DDR_UIM_MR14_0 0x00000019
+#define DDR_UIM_MR14_0 0x00000047
 #define DDR_UIM_MR22_0 0x00000005
 
 #define DDR_UIS_SWIZZLE_0 0x00000003
diff --git a/fdts/stm32mp25-lpddr4-1x32Gbits-1x32bits-1200MHz.dtsi b/fdts/stm32mp25-lpddr4-1x32Gbits-1x32bits-1200MHz.dtsi
index 53d6b7d..0df2a4d 100644
--- a/fdts/stm32mp25-lpddr4-1x32Gbits-1x32bits-1200MHz.dtsi
+++ b/fdts/stm32mp25-lpddr4-1x32Gbits-1x32bits-1200MHz.dtsi
@@ -161,7 +161,7 @@
 #define DDR_UIA_DISDYNADRTRI_0 0x00000001
 #define DDR_UIA_PHYMSTRTRAININTERVAL_0 0x0000000A
 #define DDR_UIA_PHYMSTRMAXREQTOACK_0 0x00000005
-#define DDR_UIA_WDQSEXT 0x00000000
+#define DDR_UIA_WDQSEXT 0x00000001
 #define DDR_UIA_CALINTERVAL 0x00000009
 #define DDR_UIA_CALONCE 0x00000000
 #define DDR_UIA_LP4RL_0 0x00000004
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index e80faf2..243ac15 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -202,5 +202,7 @@
 static inline bool is_feat_d128_present(void) { return false; }
 __attribute__((always_inline))
 static inline bool is_feat_ls64_accdata_present(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_mops_supported(void) { return false; }
 
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 85b33aa..3707520 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -410,6 +410,9 @@
 #define ID_AA64MMFR3_EL1_D128_MASK		ULL(0xf)
 #define D128_IMPLEMENTED			ULL(0x1)
 
+#define ID_AA64MMFR3_EL1_MEC_SHIFT		U(28)
+#define ID_AA64MMFR3_EL1_MEC_MASK		ULL(0xf)
+
 #define ID_AA64MMFR3_EL1_S2POE_SHIFT		U(20)
 #define ID_AA64MMFR3_EL1_S2POE_MASK		ULL(0xf)
 
@@ -617,6 +620,7 @@
 #define SCR_FGTEN2_BIT		(UL(1) << 59)
 #define SCR_NSE_BIT		(ULL(1) << SCR_NSE_SHIFT)
 #define SCR_EnFPM_BIT		(ULL(1) << 50)
+#define SCR_MECEn_BIT		(UL(1) << 49)
 #define SCR_GPF_BIT		(UL(1) << 48)
 #define SCR_D128En_BIT		(UL(1) << 47)
 #define SCR_TWEDEL_SHIFT	U(30)
@@ -693,6 +697,7 @@
 #define MDCR_TDOSA_BIT		(ULL(1) << 10)
 #define MDCR_TDA_BIT		(ULL(1) << 9)
 #define MDCR_TPM_BIT		(ULL(1) << 6)
+#define MDCR_RLTE_BIT		(ULL(1) << 0)
 #define MDCR_EL3_RESET_VAL	MDCR_MTPME_BIT
 
 /* MDCR_EL2 definitions */
@@ -1581,4 +1586,11 @@
 #define CLUSTERPMCR_N_SHIFT		U(11)
 #define CLUSTERPMCR_N_MASK		U(0x1f)
 
+/*******************************************************************************
+ * FEAT_MEC - Memory Encryption Contexts
+ ******************************************************************************/
+#define MECIDR_EL2			S3_4_C10_C8_7
+#define MECIDR_EL2_MECIDWidthm1_MASK	U(0xf)
+#define MECIDR_EL2_MECIDWidthm1_SHIFT	U(0)
+
 #endif /* ARCH_H */
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index a580213..43ff2cc 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -373,6 +373,10 @@
 CREATE_FEATURE_PRESENT(feat_sb, id_aa64isar1_el1, ID_AA64ISAR1_SB_SHIFT,
 		       ID_AA64ISAR1_SB_MASK, 1U)
 
+/* FEAT_MEC: Memory Encryption Contexts */
+CREATE_FEATURE_FUNCS(feat_mec, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_MEC_SHIFT,
+		ID_AA64MMFR3_EL1_MEC_MASK, 1U, ENABLE_FEAT_MEC)
+
 /*
  * FEAT_CSV2: Cache Speculation Variant 2. This checks bit fields[56-59]
  * of id_aa64pfr0_el1 register and can be used to check for below features:
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 7f87071..569182a 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -753,6 +753,9 @@
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(fpmr, FPMR)
 
+/* FEAT_MEC Registers */
+DEFINE_RENAME_SYSREG_READ_FUNC(mecidr_el2, MECIDR_EL2)
+
 #define IS_IN_EL(x) \
 	(GET_EL(read_CurrentEl()) == MODE_EL##x)
 
diff --git a/include/drivers/arm/css/css_scp.h b/include/drivers/arm/css/css_scp.h
index 5395546..c3ce1d6 100644
--- a/include/drivers/arm/css/css_scp.h
+++ b/include/drivers/arm/css/css_scp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2025, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,8 +45,11 @@
 CASSERT(SCP_BL2_LIMIT <= BL2_BASE, assert_scp_bl2_overwrite_bl2);
 CASSERT(SCP_BL2U_LIMIT <= BL2_BASE, assert_scp_bl2u_overwrite_bl2);
 
+#if !TRANSFER_LIST
 CASSERT(SCP_BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2_overflow);
 CASSERT(SCP_BL2U_BASE >= ARM_FW_CONFIG_LIMIT, assert_scp_bl2u_overflow);
+#endif /* !TRANSFER_LIST */
+
 #endif
 
 #endif /* CSS_SCP_H */
diff --git a/include/drivers/arm/smmu_v3.h b/include/drivers/arm/smmu_v3.h
index 37da56f..5a36e26 100644
--- a/include/drivers/arm/smmu_v3.h
+++ b/include/drivers/arm/smmu_v3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2025, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -58,6 +58,8 @@
 
 /* SMMU_ROOT_IDR0 register fields */
 #define SMMU_ROOT_IDR0_ROOT_IMPL	(1UL << 0)
+#define SMMU_ROOT_IDR0_BA_REALM_SHIFT	22U
+#define SMMU_ROOT_IDR0_BA_REALM_MASK	GENMASK_32(31U, SMMU_ROOT_IDR0_BA_REALM_SHIFT)
 
 /* SMMU_ROOT_CR0 register fields */
 #define SMMU_ROOT_CR0_GPCEN		(1UL << 1)
diff --git a/include/drivers/console.h b/include/drivers/console.h
index fa4eb94..0de2c99 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -27,7 +27,7 @@
 #define CONSOLE_FLAG_RUNTIME		(U(1) << 1)
 #define CONSOLE_FLAG_CRASH		(U(1) << 2)
 /* Bits 3 to 7 reserved for additional scopes in future expansion. */
-#define CONSOLE_FLAG_SCOPE_MASK		((U(1) << 8) - 1)
+#define CONSOLE_FLAG_SCOPE_MASK		GENMASK(7, 0)
 /* Bits 8 to 31 for non-scope use. */
 #define CONSOLE_FLAG_TRANSLATE_CRLF	(U(1) << 8)
 
diff --git a/include/drivers/gpio_spi.h b/include/drivers/gpio_spi.h
new file mode 100644
index 0000000..a926553
--- /dev/null
+++ b/include/drivers/gpio_spi.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GPIO_SPI_H
+#define GPIO_SPI_H
+
+#include <stdint.h>
+
+struct gpio_spi_data {
+	uint8_t cs_gpio, sclk_gpio, mosi_gpio, miso_gpio, reset_gpio;
+	uint32_t spi_delay_us;
+	unsigned int spi_mode;
+};
+
+struct spi_ops {
+	void (*get_access)(void);
+	void (*start)(void);
+	void (*stop)(void);
+	int (*xfer)(unsigned int bitlen, const void *dout, void *din);
+};
+
+struct spi_plat {
+	struct gpio_spi_data gpio_data;
+	const struct spi_ops *ops;
+};
+
+struct spi_plat *gpio_spi_init(struct gpio_spi_data *gpio_spi_data);
+
+#endif /* GPIO_SPI_H */
diff --git a/include/drivers/st/stpmic2.h b/include/drivers/st/stpmic2.h
index 58ba64a..d44dbfc 100644
--- a/include/drivers/st/stpmic2.h
+++ b/include/drivers/st/stpmic2.h
@@ -146,6 +146,51 @@
 #define INT_DBG_LATCH_R3	0x82
 #define INT_DBG_LATCH_R4	0x83
 
+/* NVM user control registers */
+#define NVM_SR			0x8E
+#define NVM_CR			0x8F
+
+/* NVM user shadow registers */
+#define NVM_MAIN_CTRL_SHR1	0x90
+#define NVM_MAIN_CTRL_SHR2	0x91
+#define NVM_RANK_SHR1		0x92
+#define NVM_RANK_SHR2		0x93
+#define NVM_RANK_SHR3		0x94
+#define NVM_RANK_SHR4		0x95
+#define NVM_RANK_SHR5		0x96
+#define NVM_RANK_SHR6		0x97
+#define NVM_RANK_SHR7		0x98
+#define NVM_RANK_SHR8		0x99
+#define NVM_BUCK_MODE_SHR1	0x9A
+#define NVM_BUCK_MODE_SHR2	0x9B
+#define NVM_BUCK1_VOUT_SHR	0x9C
+#define NVM_BUCK2_VOUT_SHR	0x9D
+#define NVM_BUCK3_VOUT_SHR	0x9E
+#define NVM_BUCK4_VOUT_SHR	0x9F
+#define NVM_BUCK5_VOUT_SHR	0xA0
+#define NVM_BUCK6_VOUT_SHR	0xA1
+#define NVM_BUCK7_VOUT_SHR	0xA2
+#define NVM_LDO2_SHR		0xA3
+#define NVM_LDO3_SHR		0xA4
+#define NVM_LDO5_SHR		0xA5
+#define NVM_LDO6_SHR		0xA6
+#define NVM_LDO7_SHR		0xA7
+#define NVM_LDO8_SHR		0xA8
+#define NVM_PD_SHR1		0xA9
+#define NVM_PD_SHR2		0xAA
+#define NVM_PD_SHR3		0xAB
+#define NVM_BUCKS_IOUT_SHR1	0xAC
+#define NVM_BUCKS_IOUT_SHR2	0xAD
+#define NVM_LDOS_IOUT_SHR	0xAE
+#define NVM_FS_OCP_SHR1	0xAF
+#define NVM_FS_OCP_SHR2	0xB0
+#define NVM_FS_SHR1		0xB1
+#define NVM_FS_SHR2		0xB2
+#define NVM_FS_SHR3		0xB3
+#define NVM_I2C_ADDR_SHR	0xB5
+#define NVM_USER_SHR1		0xB6
+#define NVM_USER_SHR2		0xB7
+
 /* BUCKS_MRST_CR bits definition */
 #define BUCK1_MRST		BIT(0)
 #define BUCK2_MRST		BIT(1)
@@ -237,6 +282,16 @@
 #define FS_OCP_LDO7		BIT(6)
 #define FS_OCP_LDO8		BIT(7)
 
+/* NVM_CR */
+#define NVM_CMD_MASK		GENMASK_32(1, 0)
+
+#define NVM_CMD_PROGRAM		1
+#define NVM_CMD_READ		2
+
+/* NVM_SR */
+#define NVM_BUSY		BIT(0)
+#define NVM_WRITE_FAIL		BIT(1)
+
 /* IRQ definitions */
 #define IT_PONKEY_F	0
 #define IT_PONKEY_R	1
diff --git a/include/drivers/tpm/tpm2.h b/include/drivers/tpm/tpm2.h
new file mode 100644
index 0000000..c91acf8
--- /dev/null
+++ b/include/drivers/tpm/tpm2.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TPM2_H
+#define TPM2_H
+
+#include <assert.h>
+#include <endian.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <drivers/tpm/tpm2_chip.h>
+
+/* Return values */
+enum tpm_ret_value {
+	TPM_SUCCESS = 0,
+	TPM_ERR_RESPONSE = -1,
+	TPM_INVALID_PARAM = -2,
+	TPM_ERR_TIMEOUT = -3,
+	TPM_ERR_TRANSFER = -4,
+};
+
+/*
+ * TPM FIFO register space address offsets
+ */
+#define TPM_FIFO_REG_ACCESS		0x00
+#define TPM_FIFO_REG_INTR_ENABLE	0x08
+#define TPM_FIFO_REG_INTR_VECTOR	0x0C
+#define TPM_FIFO_REG_INTR_STS		0x10
+#define TPM_FIFO_REG_INTF_CAPS		0x14
+#define TPM_FIFO_REG_STATUS		0x18
+#define TPM_FIFO_REG_BURST_COUNT_LO	0x19
+#define TPM_FIFO_REG_BURST_COUNT_HI	0x20
+#define TPM_FIFO_REG_DATA_FIFO		0x24
+#define TPM_FIFO_REG_VENDID		0xF00
+#define TPM_FIFO_REG_DEVID		0xF02
+#define TPM_FIFO_REG_REVID		0xF04
+
+#define TPM_ST_NO_SESSIONS		U(0x8001)
+#define TPM_ST_SESSIONS			U(0x8002)
+
+#define TPM_SU_CLEAR			U(0x0000)
+#define TPM_SU_STATE			U(0x0001)
+
+#define TPM_MIN_AUTH_SIZE		9
+#define TPM_RS_PW			0x40000009
+#define TPM_ZERO_NONCE_SIZE		0
+#define TPM_ATTRIBUTES_DISABLE		0
+#define TPM_ZERO_HMAC_SIZE		0
+#define TPM_SINGLE_HASH_COUNT		1
+
+
+#define TPM_CMD_STARTUP			U(0x0144)
+#define TPM_CMD_PCR_READ		U(0x017E)
+#define TPM_CMD_PCR_EXTEND		U(0x0182)
+
+#define TPM_RESPONSE_SUCCESS		U(0x0000)
+
+#define TPM_ACCESS_ACTIVE_LOCALITY	U(1 << 5)
+#define TPM_ACCESS_VALID		U(1 << 7)
+#define TPM_ACCESS_RELINQUISH_LOCALITY	U(1 << 5)
+#define TPM_ACCESS_REQUEST_USE		U(1 << 1)
+#define TPM_ACCESS_REQUEST_PENDING	U(1 << 2)
+
+#define TPM_STAT_VALID			U(1 << 7)
+#define TPM_STAT_COMMAND_READY		U(1 << 6)
+#define TPM_STAT_GO			U(1 << 5)
+#define TPM_STAT_AVAIL			U(1 << 4)
+#define TPM_STAT_EXPECT			U(1 << 3)
+
+#define TPM_READ_HEADER -1
+
+#define TPM_HEADER_SIZE			10
+#define MAX_SIZE_CMDBUF			256
+#define MAX_CMD_DATA			(MAX_SIZE_CMDBUF - TPM_HEADER_SIZE)
+
+#pragma pack(1)
+typedef struct tpm_cmd_hdr {
+	uint16_t tag;
+	uint32_t cmd_size;
+	uint32_t cmd_code;
+} tpm_cmd_hdr;
+
+typedef struct tpm_cmd {
+	tpm_cmd_hdr header;
+	uint8_t data[MAX_CMD_DATA];
+} tpm_cmd;
+#pragma pack()
+
+int tpm_interface_init(struct tpm_chip_data *chip_data, uint8_t locality);
+
+int tpm_interface_close(struct tpm_chip_data *chip_data, uint8_t locality);
+
+int tpm_startup(struct tpm_chip_data *chip_data, uint16_t mode);
+
+int tpm_pcr_extend(struct tpm_chip_data *chip_data, uint32_t index,
+		   uint16_t algorithm, const uint8_t *digest,
+		   uint32_t digest_len);
+
+#endif /* TPM2_H */
diff --git a/include/drivers/tpm/tpm2_chip.h b/include/drivers/tpm/tpm2_chip.h
new file mode 100644
index 0000000..ce052ad
--- /dev/null
+++ b/include/drivers/tpm/tpm2_chip.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifndef TPM2_CHIP_H
+#define TPM2_CHIP_H
+
+#define BYTE		U(0x1)
+#define WORD		U(0x2)
+#define DWORD		U(0x4)
+
+struct tpm_chip_data {
+	uint8_t locality;
+	unsigned long timeout_msec_a, timeout_msec_b;
+	unsigned long timeout_msec_c, timeout_msec_d;
+	uint16_t address;
+};
+
+#endif /* TPM2_CHIP_H */
diff --git a/include/drivers/tpm/tpm2_interface.h b/include/drivers/tpm/tpm2_interface.h
new file mode 100644
index 0000000..6bfbf6c
--- /dev/null
+++ b/include/drivers/tpm/tpm2_interface.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TPM2_INTERFACE_H
+#define TPM2_INTERFACE_H
+
+#include "tpm2_chip.h"
+
+typedef struct interface_ops {
+	int (*get_info)(struct tpm_chip_data *chip_data, uint8_t locality);
+	int (*send)(struct tpm_chip_data *chip_data, const tpm_cmd *buf);
+	int (*receive)(struct tpm_chip_data *chip_data, tpm_cmd *buf);
+	int (*request_access)(struct tpm_chip_data *chip_data, uint8_t locality);
+	int (*release_locality)(struct tpm_chip_data *chip_data, uint8_t locality);
+} interface_ops_t;
+
+struct interface_ops *tpm_interface_getops(struct tpm_chip_data *chip_data, uint8_t locality);
+
+int tpm2_fifo_write_byte(uint16_t tpm_reg, uint8_t val);
+
+int tpm2_fifo_read_byte(uint16_t tpm_reg, uint8_t *val);
+
+int tpm2_fifo_read_chunk(uint16_t tpm_reg, uint8_t len, void *val);
+
+#endif /* TPM2_INTERFACE_H */
diff --git a/include/drivers/tpm/tpm2_slb9670/slb9670_gpio.h b/include/drivers/tpm/tpm2_slb9670/slb9670_gpio.h
new file mode 100644
index 0000000..59ae125
--- /dev/null
+++ b/include/drivers/tpm/tpm2_slb9670/slb9670_gpio.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "drivers/gpio_spi.h"
+
+#ifndef SLB9670_GPIO_H
+#define SLB9670_GPIO_H
+
+void tpm2_slb9670_reset_chip(struct gpio_spi_data *tpm_gpio_data);
+
+void tpm2_slb9670_gpio_init(struct gpio_spi_data *tpm_gpio_data);
+
+#endif /* SLB9670_GPIO_H */
diff --git a/include/lib/cpus/aarch64/cortex_a510.h b/include/lib/cpus/aarch64/cortex_a510.h
index 337aac3..fb09411 100644
--- a/include/lib/cpus/aarch64/cortex_a510.h
+++ b/include/lib/cpus/aarch64/cortex_a510.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,4 +52,12 @@
 #define CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_SHIFT		U(18)
 #define CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_WIDTH		U(1)
 
+#ifndef __ASSEMBLER__
+
+#if ERRATA_A510_2971420
+long check_erratum_cortex_a510_2971420(long cpu_rev);
+#endif
+
+#endif /* __ASSEMBLER__ */
+
 #endif /* CORTEX_A510_H */
diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h
index 650193c..a47a47e 100644
--- a/include/lib/cpus/aarch64/cortex_a710.h
+++ b/include/lib/cpus/aarch64/cortex_a710.h
@@ -52,14 +52,6 @@
 #define CORTEX_A710_CPUACTLR5_EL1_BIT_44			(ULL(1) << 44)
 
 /*******************************************************************************
- * CPU Auxiliary Control register specific definitions.
- ******************************************************************************/
-#define CORTEX_A710_CPUECTLR2_EL1				S3_0_C15_C1_5
-#define CORTEX_A710_CPUECTLR2_EL1_PF_MODE_CNSRV			ULL(9)
-#define CPUECTLR2_EL1_PF_MODE_LSB				U(11)
-#define CPUECTLR2_EL1_PF_MODE_WIDTH				U(4)
-
-/*******************************************************************************
  * CPU Selected Instruction Private register specific definitions.
  ******************************************************************************/
 #define CORTEX_A710_CPUPSELR_EL3				S3_6_C15_C8_0
diff --git a/include/lib/cpus/aarch64/cortex_a715.h b/include/lib/cpus/aarch64/cortex_a715.h
index e9bd886..9980214 100644
--- a/include/lib/cpus/aarch64/cortex_a715.h
+++ b/include/lib/cpus/aarch64/cortex_a715.h
@@ -13,20 +13,14 @@
 #define CORTEX_A715_BHB_LOOP_COUNT				U(38)
 
 /*******************************************************************************
- * CPU Auxiliary Control register 1 specific definitions.
+ * CPU Register Mappings
  ******************************************************************************/
+#define CORTEX_A715_CPUCFR_EL1					S3_0_C15_C0_0
 #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
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
+#define CORTEX_A715_CPUACTLR3_EL1				S3_0_C15_C1_2
 #define CORTEX_A715_CPUECTLR_EL1				S3_0_C15_C1_4
-
+#define CORTEX_A715_CPUECTLR2_EL1				S3_0_C15_C1_5
 #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
diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h
index 2984f82..203bdfd 100644
--- a/include/lib/cpus/aarch64/cortex_a78.h
+++ b/include/lib/cpus/aarch64/cortex_a78.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,9 +19,6 @@
  ******************************************************************************/
 #define CORTEX_A78_CPUECTLR_EL1				S3_0_C15_C1_4
 #define CORTEX_A78_CPUECTLR_EL1_BIT_8			(ULL(1) << 8)
-#define CORTEX_A78_CPUECTLR_EL1_PF_MODE_CNSRV		ULL(3)
-#define CPUECTLR_EL1_PF_MODE_LSB			U(6)
-#define CPUECTLR_EL1_PF_MODE_WIDTH			U(2)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
diff --git a/include/lib/cpus/aarch64/cortex_a78c.h b/include/lib/cpus/aarch64/cortex_a78c.h
index d600eca..2033120 100644
--- a/include/lib/cpus/aarch64/cortex_a78c.h
+++ b/include/lib/cpus/aarch64/cortex_a78c.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,8 +24,6 @@
  * CPU Extended Control register specific definitions.
  ******************************************************************************/
 #define CORTEX_A78C_CPUECTLR_EL1		        S3_0_C15_C1_4
-#define CORTEX_A78C_CPUECTLR_EL1_BIT_6		        (ULL(1) << 6)
-#define CORTEX_A78C_CPUECTLR_EL1_BIT_7		        (ULL(1) << 7)
 #define CORTEX_A78C_CPUECTLR_EL1_MM_ASP_EN		(ULL(1) << 53)
 
 /*******************************************************************************
diff --git a/include/lib/cpus/aarch64/cortex_x2.h b/include/lib/cpus/aarch64/cortex_x2.h
index 9ec5177..4516339 100644
--- a/include/lib/cpus/aarch64/cortex_x2.h
+++ b/include/lib/cpus/aarch64/cortex_x2.h
@@ -19,15 +19,6 @@
 #define CORTEX_X2_CPUECTLR_EL1_PFSTIDIS_BIT			(ULL(1) << 8)
 
 /*******************************************************************************
- * CPU Extended Control register 2 specific definitions
- ******************************************************************************/
-#define CORTEX_X2_CPUECTLR2_EL1					S3_0_C15_C1_5
-
-#define CORTEX_X2_CPUECTLR2_EL1_PF_MODE_SHIFT			U(11)
-#define CORTEX_X2_CPUECTLR2_EL1_PF_MODE_WIDTH			U(4)
-#define CORTEX_X2_CPUECTLR2_EL1_PF_MODE_CNSRV			ULL(0x9)
-
-/*******************************************************************************
  * CPU Auxiliary Control register 3 specific definitions.
  ******************************************************************************/
 #define CORTEX_X2_CPUACTLR3_EL1				S3_0_C15_C1_2
diff --git a/include/lib/cpus/aarch64/cortex_x3.h b/include/lib/cpus/aarch64/cortex_x3.h
index 8834db1..2869ec8 100644
--- a/include/lib/cpus/aarch64/cortex_x3.h
+++ b/include/lib/cpus/aarch64/cortex_x3.h
@@ -49,15 +49,6 @@
 #define CORTEX_X3_CPUACTLR6_EL1			S3_0_C15_C8_1
 
 /*******************************************************************************
- * CPU Extended Control register 2 specific definitions.
- ******************************************************************************/
-#define CORTEX_X3_CPUECTLR2_EL1			S3_0_C15_C1_5
-
-#define CORTEX_X3_CPUECTLR2_EL1_PF_MODE_LSB	U(11)
-#define CORTEX_X3_CPUECTLR2_EL1_PF_MODE_WIDTH	U(4)
-#define CORTEX_X3_CPUECTLR2_EL1_PF_MODE_CNSRV	ULL(0x9)
-
-/*******************************************************************************
  * CPU Auxiliary Control register 3 specific definitions.
  ******************************************************************************/
 #define CORTEX_X3_CPUACTLR3_EL1			S3_0_C15_C1_2
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index f5837d4..e4487c4 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -62,9 +62,6 @@
  * CPU Auxiliary Control register specific definitions.
  ******************************************************************************/
 #define NEOVERSE_N2_CPUECTLR2_EL1			S3_0_C15_C1_5
-#define NEOVERSE_N2_CPUECTLR2_EL1_PF_MODE_CNSRV		ULL(9)
-#define CPUECTLR2_EL1_PF_MODE_LSB			U(11)
-#define CPUECTLR2_EL1_PF_MODE_WIDTH			U(4)
 #define CPUECTLR2_EL1_TXREQ_STATIC_FULL 		ULL(0)
 #define CPUECTLR2_EL1_TXREQ_LSB				U(0)
 #define CPUECTLR2_EL1_TXREQ_WIDTH			U(3)
diff --git a/include/lib/cpus/aarch64/neoverse_v1.h b/include/lib/cpus/aarch64/neoverse_v1.h
index 1e2d7ea..bbba2a7 100644
--- a/include/lib/cpus/aarch64/neoverse_v1.h
+++ b/include/lib/cpus/aarch64/neoverse_v1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,9 +22,6 @@
 #define NEOVERSE_V1_CPUPCR_EL3					S3_6_C15_C8_1
 #define NEOVERSE_V1_CPUECTLR_EL1_BIT_8				(ULL(1) << 8)
 #define NEOVERSE_V1_CPUECTLR_EL1_BIT_53				(ULL(1) << 53)
-#define NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV			ULL(3)
-#define CPUECTLR_EL1_PF_MODE_LSB				U(6)
-#define CPUECTLR_EL1_PF_MODE_WIDTH				U(2)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
diff --git a/include/lib/cpus/aarch64/neoverse_v2.h b/include/lib/cpus/aarch64/neoverse_v2.h
index 427cafa..cdbe2bb 100644
--- a/include/lib/cpus/aarch64/neoverse_v2.h
+++ b/include/lib/cpus/aarch64/neoverse_v2.h
@@ -32,9 +32,6 @@
  * CPU Extended Control register 2 specific definitions.
  ******************************************************************************/
 #define NEOVERSE_V2_CPUECTLR2_EL1			S3_0_C15_C1_5
-#define NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_CNSRV		ULL(9)
-#define NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_LSB		U(11)
-#define NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_WIDTH		U(4)
 #define NEOVERSE_V2_CPUECTLR2_EL1_TXREQ_STATIC_FULL	ULL(0)
 #define NEOVERSE_V2_CPUECTLR2_EL1_TXREQ_LSB		U(0)
 #define NEOVERSE_V2_CPUECTLR2_EL1_TXREQ_WIDTH		U(3)
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
index 9eae276..8e28d46 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.h
@@ -67,10 +67,8 @@
 }
 #endif
 
-#if ERRATA_A520_2938996 || ERRATA_X4_2726228
-unsigned int check_if_affected_core(void);
-#endif
 
+bool check_if_trbe_disable_affected_core(void);
 int check_wa_cve_2024_7881(void);
 bool errata_ich_vmcr_el2_applies(void);
 
diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h
index 8129404..bba9816 100644
--- a/include/lib/libc/string.h
+++ b/include/lib/libc/string.h
@@ -30,5 +30,7 @@
 size_t strlcpy(char * dst, const char * src, size_t dsize);
 size_t strlcat(char * dst, const char * src, size_t dsize);
 char *strtok_r(char *s, const char *delim, char **last);
+size_t strnlen_secure(const char *str, size_t maxlen);
+int strcpy_secure(char *restrict dest, size_t dest_size, const char *restrict src);
 
 #endif /* STRING_H */
diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h
index c403031..bdc6349 100644
--- a/include/lib/transfer_list.h
+++ b/include/lib/transfer_list.h
@@ -62,6 +62,8 @@
 	TL_TAG_EXEC_EP_INFO64 = 0x102,
 	TL_TAG_SRAM_LAYOUT64 = 0x104,
 	TL_TAG_MBEDTLS_HEAP_INFO = 0x105,
+	TL_TAG_EXEC_EP_INFO32 = 0x106,
+	TL_TAG_SRAM_LAYOUT32 = 0x107,
 };
 
 enum transfer_list_ops {
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index c3f767e..6d8a06a 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -218,4 +218,17 @@
  */
 #define KHZ_TICKS_PER_SEC U(1000)
 
+/**
+ * EXTRACT_FIELD - Extracts a specific bit field from a value.
+ *
+ * @val:   The input value containing the field.
+ * @mask:  A bitmask representing the maximum value of the field
+ * @shift: The starting bit position of the field.
+ *
+ * This macro shifts the input value (@val) to the right by @shift bits,
+ * aligning the target field to the least significant bits (LSB).
+ * It then applies @mask to extract only the relevant bits.
+ */
+#define EXTRACT_FIELD(val, mask, shift)   (((val) >> (shift)) & (mask))
+
 #endif /* UTILS_DEF_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 1d7a59d..396bd14 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -249,7 +249,8 @@
 void arm_bl1_plat_arch_setup(void);
 
 /* BL2 utility functions */
-void arm_bl2_early_platform_setup(uintptr_t fw_config, struct meminfo *mem_layout);
+void arm_bl2_early_platform_setup(u_register_t arg0, u_register_t arg1,
+				   u_register_t arg2, u_register_t arg3);
 void arm_bl2_platform_setup(void);
 void arm_bl2_plat_arch_setup(void);
 uint32_t arm_get_spsr_for_bl32_entry(void);
@@ -273,13 +274,8 @@
 void arm_bl2u_plat_arch_setup(void);
 
 /* BL31 utility functions */
-#if TRANSFER_LIST
 void arm_bl31_early_platform_setup(u_register_t arg0, u_register_t arg1,
 				   u_register_t arg2, u_register_t arg3);
-#else
-void arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config,
-				uintptr_t hw_config, void *plat_params_from_bl2);
-#endif
 void arm_bl31_platform_setup(void);
 void arm_bl31_plat_runtime_setup(void);
 void arm_bl31_plat_arch_setup(void);
@@ -298,8 +294,8 @@
 void arm_tsp_early_platform_setup(void);
 
 /* SP_MIN utility functions */
-void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config,
-				uintptr_t hw_config, void *plat_params_from_bl2);
+void arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
+			u_register_t arg2, u_register_t arg3);
 void arm_sp_min_plat_runtime_setup(void);
 void arm_sp_min_plat_arch_setup(void);
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index b43f131..faccf31 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -398,7 +398,8 @@
 int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp);
 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
-#endif
+int plat_rmmd_mecid_key_update(uint16_t mecid);
+#endif /* ENABLE_RME */
 
 /*******************************************************************************
  * Optional BL31 functions (may be overridden)
diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h
index eab4b60..699a8d7 100644
--- a/include/services/arm_arch_svc.h
+++ b/include/services/arm_arch_svc.h
@@ -125,6 +125,12 @@
 #define SCR_FEAT_RAS (0)
 #endif
 
+#if ENABLE_FEAT_MEC
+#define SCR_FEAT_MEC SCR_MECEn_BIT
+#else
+#define SCR_FEAT_MEC (0)
+#endif
+
 #ifndef SCR_PLAT_FEATS
 #define SCR_PLAT_FEATS (0)
 #endif
@@ -195,6 +201,7 @@
 	SCR_IRQ_BIT		|						\
 	SCR_NS_BIT		|						\
 	SCR_RES1_BITS		|						\
+	SCR_FEAT_MEC		|						\
 	SCR_PLAT_IGNORED)
 CASSERT((SCR_EL3_FEATS & SCR_EL3_IGNORED) == 0, scr_feat_is_ignored);
 CASSERT((SCR_EL3_FLIPPED & SCR_EL3_FEATS) == SCR_EL3_FLIPPED, scr_flipped_not_a_feat);
diff --git a/include/services/drtm_svc.h b/include/services/drtm_svc.h
index 3503fa4..86110db 100644
--- a/include/services/drtm_svc.h
+++ b/include/services/drtm_svc.h
@@ -14,6 +14,8 @@
 #ifndef ARM_DRTM_SVC_H
 #define ARM_DRTM_SVC_H
 
+#include <lib/utils_def.h>
+
 /*
  * SMC function IDs for DRTM Service
  * Upper word bits set: Fast call, SMC64, Standard Secure Svc. Call (OEN = 4)
@@ -239,6 +241,21 @@
 		<< ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_SHIFT));	\
 	} while (false)
 
+#define DRTM_LAUNCH_FEAT_DLME_IMG_AUTH_SHIFT		U(6)
+#define DRTM_LAUNCH_FEAT_MEM_PROTECTION_TYPE_SHIFT	U(3)
+#define DRTM_LAUNCH_FEAT_PCR_USAGE_SCHEMA_SHIFT		U(1)
+#define DRTM_LAUNCH_FEAT_HASHING_TYPE_SHIFT		U(0)
+
+#define DRTM_LAUNCH_FEAT_DLME_IMG_AUTH_MASK      	U(0x1)
+#define DRTM_LAUNCH_FEAT_MEM_PROTECTION_TYPE_MASK 	U(0x7)
+#define DRTM_LAUNCH_FEAT_PCR_USAGE_SCHEMA_MASK   	U(0x3)
+#define DRTM_LAUNCH_FEAT_HASHING_TYPE_MASK       	U(0x1)
+
+#define DLME_IMG_AUTH					U(0x1)
+#define REG_MEM_PROTECTION_TYPE				U(0x1)
+#define DLME_AUTH_SCHEMA				U(0x1)
+#define TPM_BASED_HASHING				U(0x1)
+
 /* Initialization routine for the DRTM service */
 int drtm_setup(void);
 
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
index 2d6e71f..c094f6a 100644
--- a/include/services/rmm_core_manifest.h
+++ b/include/services/rmm_core_manifest.h
@@ -14,20 +14,21 @@
 #include <lib/cassert.h>
 
 #define RMMD_MANIFEST_VERSION_MAJOR		U(0)
-#define RMMD_MANIFEST_VERSION_MINOR		U(4)
+#define RMMD_MANIFEST_VERSION_MINOR		U(5)
 
 #define RMM_CONSOLE_MAX_NAME_LEN		U(8)
 
 /*
- * Manifest version encoding:
+ * Version encoding:
  *	- Bit[31] RES0
  *	- Bits [30:16] Major version
  *	- Bits [15:0] Minor version
  */
-#define SET_RMMD_MANIFEST_VERSION(_major, _minor)		\
+#define SET_VERSION(_major, _minor)				\
 	((((_major) & 0x7FFF) << 16) | ((_minor) & 0xFFFF))
 
-#define RMMD_MANIFEST_VERSION	SET_RMMD_MANIFEST_VERSION(	\
+/* Boot Manifest version */
+#define RMMD_MANIFEST_VERSION	SET_VERSION(			\
 				RMMD_MANIFEST_VERSION_MAJOR,	\
 				RMMD_MANIFEST_VERSION_MINOR)
 
@@ -37,9 +38,17 @@
 #define RMMD_GET_MANIFEST_VERSION_MINOR(_version)		\
 	(_version & 0xFFFF)
 
+#define PCIE_RC_INFO_VERSION_MAJOR		U(0)
+#define PCIE_RC_INFO_VERSION_MINOR		U(1)
+
+/* PCIe Root Complex info structure version */
+#define PCIE_RC_INFO_VERSION	SET_VERSION(			\
+				PCIE_RC_INFO_VERSION_MAJOR,	\
+				PCIE_RC_INFO_VERSION_MINOR)
+
 /* Memory bank/device region structure */
 struct memory_bank {
-	uintptr_t base;			/* Base address */
+	uint64_t base;			/* Base address */
 	uint64_t size;			/* Size of memory bank/device region */
 };
 
@@ -64,7 +73,7 @@
 
 /* Console info structure */
 struct console_info {
-	uintptr_t base;			/* Console base address */
+	uint64_t base;			/* Console base address */
 	uint64_t map_pages;		/* Num of pages to be mapped in RMM for the console MMIO */
 	char name[RMM_CONSOLE_MAX_NAME_LEN];	/* Name of console */
 	uint64_t clk_in_hz;		/* UART clock (in Hz) for the console */
@@ -98,11 +107,105 @@
 CASSERT(offsetof(struct console_list, checksum) == 16UL,
 			rmm_manifest_console_list_checksum);
 
+/* SMMUv3 Info structure */
+struct smmu_info {
+	uint64_t smmu_base;		/* SMMUv3 base address */
+	uint64_t smmu_r_base;		/* SMMUv3 Realm Pages base address */
+};
+
+CASSERT(offsetof(struct smmu_info, smmu_base) == 0UL,
+			rmm_manifest_smmu_base);
+CASSERT(offsetof(struct smmu_info, smmu_r_base) == 8UL,
+			rmm_manifest_smmu_r_base);
+
+/* SMMUv3 Info List structure */
+struct smmu_list {
+	uint64_t num_smmus;		/* Number of smmu_info entries */
+	struct smmu_info *smmus;	/* Pointer to smmu_info[] array */
+	uint64_t checksum;		/* Checksum of smmu_list data */
+};
+
+CASSERT(offsetof(struct smmu_list, num_smmus) == 0UL,
+			rmm_manifest_num_smmus);
+CASSERT(offsetof(struct smmu_list, smmus) == 8UL,
+			rmm_manifest_smmus);
+CASSERT(offsetof(struct smmu_list, checksum) == 16UL,
+			rmm_manifest_smmu_list_checksum);
+
+/* PCIe BDF Mapping Info structure */
+struct bdf_mapping_info {
+	uint16_t mapping_base;	/* Base of BDF mapping (inclusive) */
+	uint16_t mapping_top;	/* Top of BDF mapping (exclusive) */
+	uint16_t mapping_off;	/* Mapping offset, as per Arm Base System Architecture: */
+				/* StreamID = zero_extend(RequesterID[N-1:0]) + (1<<N)*Constant_B */
+	uint16_t smmu_idx;	/* SMMU index in smmu_info[] array */
+};
+
+CASSERT(offsetof(struct bdf_mapping_info, mapping_base) == 0UL,
+			rmm_manifest_mapping_base);
+CASSERT(offsetof(struct bdf_mapping_info, mapping_top) == 2UL,
+			rmm_manifest_mapping_top);
+CASSERT(offsetof(struct bdf_mapping_info, mapping_off) == 4UL,
+			rmm_manifest_mapping_off);
+CASSERT(offsetof(struct bdf_mapping_info, smmu_idx) == 6UL,
+			rmm_manifest_smmu_ptr);
+
-/* Boot manifest core structure as per v0.4 */
+/* PCIe Root Port Info structure */
+struct root_port_info {
+	uint16_t root_port_id;			/* Root Port identifier */
+	uint16_t padding;			/* RES0 */
+	uint32_t num_bdf_mappings;		/* Number of BDF mappings */
+	struct bdf_mapping_info *bdf_mappings;	/* Pointer to bdf_mapping_info[] array */
+};
+
+CASSERT(offsetof(struct root_port_info, root_port_id) == 0UL,
+			rmm_manifest_root_port_id);
+CASSERT(offsetof(struct root_port_info, num_bdf_mappings) == 4UL,
+			rmm_manifest_num_bdf_mappingss);
+CASSERT(offsetof(struct root_port_info, bdf_mappings) == 8UL,
+			rmm_manifest_bdf_mappings);
+
+/* PCIe Root Complex info structure v0.1 */
+struct root_complex_info {
+	uint64_t ecam_base;			/* ECAM base address. Size is implicitly 256MB */
+	uint8_t segment;			/* PCIe segment identifier */
+	uint8_t padding[3];			/* RES0 */
+	uint32_t num_root_ports;		/* Number of root ports */
+	struct root_port_info *root_ports;	/* Pointer to root_port_info[] array */
+};
+
+CASSERT(offsetof(struct root_complex_info, ecam_base) == 0UL,
+			rmm_manifest_ecam_base);
+CASSERT(offsetof(struct root_complex_info, segment) == 8UL,
+			rmm_manifest_segment);
+CASSERT(offsetof(struct root_complex_info, num_root_ports) == 12UL,
+			rmm_manifest_num_root_ports);
+CASSERT(offsetof(struct root_complex_info, root_ports) == 16UL,
+			rmm_manifest_root_ports);
+
+/* PCIe Root Complex List structure */
+struct root_complex_list {
+	uint64_t num_root_complex;		/* Number of pci_rc_info entries */
+	uint32_t rc_info_version;		/* PCIe Root Complex info structure version */
+	uint32_t padding;			/* RES0 */
+	struct root_complex_info *root_complex;	/* Pointer to pci_rc_info[] array */
+	uint64_t checksum;			/* Checksum of pci_rc_list data */
+};
+
+CASSERT(offsetof(struct root_complex_list, num_root_complex) == 0UL,
+			rmm_manifest_num_root_complex);
+CASSERT(offsetof(struct root_complex_list, rc_info_version) == 8UL,
+			rmm_manifest_rc_info_version);
+CASSERT(offsetof(struct root_complex_list, root_complex) == 16UL,
+			rmm_manifest_root_complex);
+CASSERT(offsetof(struct root_complex_list, checksum) == 24UL,
+			rmm_manifest_root_complex_list_checksum);
+
+/* Boot manifest core structure as per v0.5 */
 struct rmm_manifest {
 	uint32_t version;			/* Manifest version */
 	uint32_t padding;			/* RES0 */
-	uintptr_t plat_data;			/* Manifest platform data */
+	uint64_t plat_data;			/* Manifest platform data */
 	/* Platform NS DRAM data (v0.2) */
 	struct memory_info plat_dram;
 	/* Platform console list (v0.3) */
@@ -110,6 +213,10 @@
 	/* Platform device address ranges (v0.4) */
 	struct memory_info plat_ncoh_region;
 	struct memory_info plat_coh_region;
+	/* Platform SMMUv3 list (v0.5) */
+	struct smmu_list plat_smmu;
+	/* Platform PCIe Root Complex list (v0.5) */
+	struct root_complex_list plat_root_complex;
 };
 
 CASSERT(offsetof(struct rmm_manifest, version) == 0UL,
@@ -124,5 +231,9 @@
 			rmm_manifest_plat_ncoh_region_unaligned);
 CASSERT(offsetof(struct rmm_manifest, plat_coh_region) == 88UL,
 			rmm_manifest_plat_coh_region_unaligned);
+CASSERT(offsetof(struct rmm_manifest, plat_smmu) == 112UL,
+			rmm_manifest_plat_smmu_unaligned);
+CASSERT(offsetof(struct rmm_manifest, plat_root_complex) == 136UL,
+			rmm_manifest_plat_root_complex);
 
 #endif /* RMM_CORE_MANIFEST_H */
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index 0cc8628..8bf9319 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -161,6 +161,18 @@
 #define RMM_EL3_TOKEN_SIGN_PULL_RESP_OP         U(2)
 #define RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP       U(3)
 
+/* Starting RMM-EL3 interface version 0.5 */
+
+/*
+ * Function code to support update of MEC keys.
+ * The arguments of this SMC are:
+ * 	arg0 - Function ID.
+ * 	arg1 - MECID
+ * The return arguments are:
+ * 	ret0 - Status/Error
+ */
+#define RMM_MECID_KEY_UPDATE			SMC64_RMMD_EL3_FID(U(6))
+
 /* ECC Curve types for attest key generation */
 #define ATTEST_KEY_CURVE_ECC_SECP384R1		U(0)
 
@@ -188,7 +200,7 @@
  * Increase this when a bug is fixed, or a feature is added without
  * breaking compatibility.
  */
-#define RMM_EL3_IFC_VERSION_MINOR	(U(4))
+#define RMM_EL3_IFC_VERSION_MINOR	(U(5))
 
 #define RMM_EL3_INTERFACE_VERSION				\
 	(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) |	\
diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S
index 93771df..f95fb6e 100644
--- a/lib/aarch64/misc_helpers.S
+++ b/lib/aarch64/misc_helpers.S
@@ -21,10 +21,6 @@
 	.globl	disable_mmu_icache_el1
 	.globl	disable_mmu_icache_el3
 	.globl	fixup_gdt_reloc
-#if SUPPORT_VFP
-	.globl	enable_vfp
-#endif
-
 func smc
 	smc	#0
 endfunc smc
@@ -456,24 +452,6 @@
 endfunc disable_mmu_icache_el1
 
 /* ---------------------------------------------------------------------------
- * Enable the use of VFP at EL3
- * ---------------------------------------------------------------------------
- */
-#if SUPPORT_VFP
-func enable_vfp
-	mrs	x0, cpacr_el1
-	orr	x0, x0, #CPACR_VFP_BITS
-	msr	cpacr_el1, x0
-	mrs	x0, cptr_el3
-	mov	x1, #AARCH64_CPTR_TFP
-	bic	x0, x0, x1
-	msr	cptr_el3, x0
-	isb
-	ret
-endfunc enable_vfp
-#endif
-
-/* ---------------------------------------------------------------------------
  * Helper to fixup Global Descriptor table (GDT) and dynamic relocations
  * (.rela.dyn) at runtime.
  *
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index 81a227b..6ec6742 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -178,6 +178,10 @@
 	ret
 check_erratum_custom_end cortex_a510, ERRATUM(2313941)
 
+.global check_erratum_cortex_a510_2971420
+add_erratum_entry cortex_a510, ERRATUM(2971420), ERRATA_A510_2971420
+check_erratum_range cortex_a510, ERRATUM(2971420), CPU_REV(0, 1), CPU_REV(1, 3)
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index e8f5a80..54bb453 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -31,13 +31,6 @@
 
 cpu_reset_prologue cortex_a710
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start cortex_a710, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set CORTEX_A710_CPUECTLR_EL1, BIT(46)
-workaround_reset_end cortex_a710,  CVE(2024, 5660)
-
-check_erratum_ls cortex_a710, CVE(2024, 5660), CPU_REV(2, 1)
-
 workaround_reset_start cortex_a710, ERRATUM(1987031), ERRATA_A710_1987031
 	ldr x0,=0x6
 	msr S3_6_c15_c8_0,x0
@@ -94,13 +87,6 @@
 
 check_erratum_range cortex_a710, ERRATUM(2055002), CPU_REV(1, 0), CPU_REV(2, 0)
 
-workaround_reset_start cortex_a710, ERRATUM(2058056), ERRATA_A710_2058056
-	sysreg_bitfield_insert CORTEX_A710_CPUECTLR2_EL1, CORTEX_A710_CPUECTLR2_EL1_PF_MODE_CNSRV, \
-		CPUECTLR2_EL1_PF_MODE_LSB, CPUECTLR2_EL1_PF_MODE_WIDTH
-workaround_reset_end cortex_a710, ERRATUM(2058056)
-
-check_erratum_ls cortex_a710, ERRATUM(2058056), CPU_REV(2, 1)
-
 workaround_reset_start cortex_a710, ERRATUM(2081180), ERRATA_A710_2081180
 	ldr	x0,=0x3
 	msr	S3_6_c15_c8_0,x0
@@ -213,6 +199,10 @@
 
 check_erratum_ls cortex_a710, ERRATUM(2778471), CPU_REV(2, 1)
 
+add_erratum_entry cortex_a710, ERRATUM(3701772), ERRATA_A710_3701772
+
+check_erratum_ls cortex_a710, ERRATUM(3701772), CPU_REV(2, 1)
+
 workaround_reset_start cortex_a710, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -225,9 +215,12 @@
 
 check_erratum_chosen cortex_a710, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-add_erratum_entry cortex_a710, ERRATUM(3701772), ERRATA_A710_3701772
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a710, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_A710_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a710,  CVE(2024, 5660)
 
-check_erratum_ls cortex_a710, ERRATUM(3701772), CPU_REV(2, 1)
+check_erratum_ls cortex_a710, CVE(2024, 5660), CPU_REV(2, 1)
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
diff --git a/lib/cpus/aarch64/cortex_a715.S b/lib/cpus/aarch64/cortex_a715.S
index d9c0df2..d863cc5 100644
--- a/lib/cpus/aarch64/cortex_a715.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -119,6 +119,29 @@
 
 check_erratum_ls cortex_a715, ERRATUM(2728106), CPU_REV(1, 1)
 
+workaround_reset_start cortex_a715, ERRATUM(2804830), ERRATA_A715_2804830
+	/* Workaround changes based on CORE_CACHE_PROTECTIONS field (bit 1) */
+	mrs x0, CORTEX_A715_CPUCFR_EL1
+	tbz x0, #1, wa_2804830_core_cache_prot_false
+
+	/* CORE_CACHE_PROTECTIONS==true */
+	sysreg_bit_set CORTEX_A715_CPUACTLR3_EL1, BIT(2)
+	sysreg_bit_set CORTEX_A715_CPUECTLR_EL1, BIT(23)
+	b wa_2804830_done
+
+	/* CORE_CACHE_PROTECTIONS==false */
+wa_2804830_core_cache_prot_false:
+	sysreg_bit_set CORTEX_A715_CPUECTLR2_EL1, BIT(7)
+
+wa_2804830_done:
+workaround_reset_end cortex_a715, ERRATUM(2804830)
+
+check_erratum_ls cortex_a715, ERRATUM(2804830), CPU_REV(1, 2)
+
+add_erratum_entry cortex_a715, ERRATUM(3699560), ERRATA_A715_3699560
+
+check_erratum_ls cortex_a715, ERRATUM(3699560), CPU_REV(1, 3)
+
 workaround_reset_start cortex_a715, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -131,10 +154,6 @@
 
 check_erratum_chosen cortex_a715, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-add_erratum_entry cortex_a715, ERRATUM(3699560), ERRATA_A715_3699560
-
-check_erratum_ls cortex_a715, ERRATUM(3699560), CPU_REV(1, 3)
-
 cpu_reset_func_start cortex_a715
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index 7fb964d..82a20ec 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -28,13 +28,6 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A77_BHB_LOOP_COUNT, cortex_a77
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start cortex_a77, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set CORTEX_A77_CPUECTLR_EL1, BIT(46)
-workaround_reset_end cortex_a77, CVE(2024, 5660)
-
-check_erratum_ls cortex_a77, CVE(2024, 5660), CPU_REV(1, 1)
-
 workaround_reset_start cortex_a77, ERRATUM(1508412), ERRATA_A77_1508412
 	/* move cpu revision in again and compare against r0p0 */
 	mov	x0, x7
@@ -150,6 +143,13 @@
 
 check_erratum_chosen cortex_a77, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a77, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_A77_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a77, CVE(2024, 5660)
+
+check_erratum_ls cortex_a77, CVE(2024, 5660), CPU_REV(1, 1)
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A77. Must follow AAPCS.
 	 * -------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index a66214b..b166823 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -26,13 +26,6 @@
 
 cpu_reset_prologue cortex_a78
 
-/* Disable hardware page aggregation.Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start cortex_a78, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set CORTEX_A78_CPUECTLR_EL1, BIT(46)
-workaround_reset_end cortex_a78, CVE(2024, 5660)
-
-check_erratum_ls cortex_a78, CVE(2024, 5660), CPU_REV(1, 2)
-
 workaround_reset_start cortex_a78, ERRATUM(1688305), ERRATA_A78_1688305
 	sysreg_bit_set CORTEX_A78_ACTLR2_EL1, CORTEX_A78_ACTLR2_EL1_BIT_1
 workaround_reset_end cortex_a78, ERRATUM(1688305)
@@ -106,16 +99,6 @@
 
 check_erratum_ls cortex_a78, ERRATUM(1952683), CPU_REV(0, 0)
 
-workaround_reset_start cortex_a78, ERRATUM(2132060), ERRATA_A78_2132060
-	/* Apply the workaround. */
-	mrs	x1, CORTEX_A78_CPUECTLR_EL1
-	mov	x0, #CORTEX_A78_CPUECTLR_EL1_PF_MODE_CNSRV
-	bfi	x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
-	msr	CORTEX_A78_CPUECTLR_EL1, x1
-workaround_reset_end cortex_a78, ERRATUM(2132060)
-
-check_erratum_ls cortex_a78, ERRATUM(2132060), CPU_REV(1, 2)
-
 workaround_reset_start cortex_a78, ERRATUM(2242635), ERRATA_A78_2242635
 	ldr	x0, =0x5
 	msr	S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */
@@ -176,6 +159,13 @@
 
 check_erratum_chosen cortex_a78, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+/* Disable hardware page aggregation.Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a78, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_A78_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a78, CVE(2024, 5660)
+
+check_erratum_ls cortex_a78, CVE(2024, 5660), CPU_REV(1, 2)
+
 cpu_reset_func_start cortex_a78
 #if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index c537967..63bc936 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -24,13 +24,6 @@
 
 cpu_reset_prologue cortex_a78_ae
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start cortex_a78_ae, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set CORTEX_A78_AE_CPUECTLR_EL1, BIT(46)
-workaround_reset_end cortex_a78_ae, CVE(2024, 5660)
-
-check_erratum_ls cortex_a78_ae, CVE(2024, 5660), CPU_REV(0, 3)
-
 workaround_reset_start cortex_a78_ae, ERRATUM(1941500), ERRATA_A78_AE_1941500
 	sysreg_bit_set CORTEX_A78_AE_CPUECTLR_EL1, CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
 workaround_reset_end cortex_a78_ae, ERRATUM(1941500)
@@ -105,6 +98,13 @@
 
 check_erratum_chosen cortex_a78_ae, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a78_ae, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_A78_AE_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a78_ae, CVE(2024, 5660)
+
+check_erratum_ls cortex_a78_ae, CVE(2024, 5660), CPU_REV(0, 3)
+
 cpu_reset_func_start cortex_a78_ae
 #if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index aba7d25..19d988e 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -23,13 +23,6 @@
 
 cpu_reset_prologue cortex_a78c
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start cortex_a78c, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set CORTEX_A78C_CPUECTLR_EL1, BIT(46)
-workaround_reset_end cortex_a78c, CVE(2024, 5660)
-
-check_erratum_ls cortex_a78c, CVE(2024, 5660), CPU_REV(0, 2)
-
 workaround_reset_start cortex_a78c, ERRATUM(1827430), ERRATA_A78C_1827430
 	/* Disable allocation of splintered pages in the L2 TLB */
 	sysreg_bit_set CORTEX_A78C_CPUECTLR_EL1, CORTEX_A78C_CPUECTLR_EL1_MM_ASP_EN
@@ -44,18 +37,6 @@
 
 check_erratum_ls cortex_a78c, ERRATUM(1827440), CPU_REV(0, 0)
 
-workaround_reset_start cortex_a78c, ERRATUM(2132064), ERRATA_A78C_2132064
-	/* --------------------------------------------------------
-	 * Place the data prefetcher in the most conservative mode
-	 * to reduce prefetches by writing the following bits to
-	 * the value indicated: ecltr[7:6], PF_MODE = 2'b11
-	 * --------------------------------------------------------
-	 */
-	sysreg_bit_set CORTEX_A78C_CPUECTLR_EL1, (CORTEX_A78C_CPUECTLR_EL1_BIT_6 | CORTEX_A78C_CPUECTLR_EL1_BIT_7)
-workaround_reset_end cortex_a78c, ERRATUM(2132064)
-
-check_erratum_range cortex_a78c, ERRATUM(2132064), CPU_REV(0, 1), CPU_REV(0, 2)
-
 workaround_reset_start cortex_a78c, ERRATUM(2242638), ERRATA_A78C_2242638
 	ldr	x0, =0x5
 	msr	CORTEX_A78C_IMP_CPUPSELR_EL3, x0
@@ -127,6 +108,13 @@
 #endif /* IMAGE_BL31 */
 workaround_reset_end cortex_a78c, CVE(2022, 23960)
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_a78c, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_A78C_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_a78c, CVE(2024, 5660)
+
+check_erratum_ls cortex_a78c, CVE(2024, 5660), CPU_REV(0, 2)
+
 cpu_reset_func_start cortex_a78c
 cpu_reset_func_end cortex_a78c
 
diff --git a/lib/cpus/aarch64/cortex_x1.S b/lib/cpus/aarch64/cortex_x1.S
index 27d181a..cb759cc 100644
--- a/lib/cpus/aarch64/cortex_x1.S
+++ b/lib/cpus/aarch64/cortex_x1.S
@@ -25,13 +25,6 @@
 
 cpu_reset_prologue cortex_x1
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start cortex_x1, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set CORTEX_X1_CPUECTLR_EL1, BIT(46)
-workaround_reset_end cortex_x1, CVE(2024, 5660)
-
-check_erratum_ls cortex_x1, CVE(2024, 5660), CPU_REV(1, 2)
-
 workaround_reset_start cortex_x1, ERRATUM(1688305), ERRATA_X1_1688305
 	sysreg_bit_set CORTEX_X1_ACTLR2_EL1, BIT(1)
 workaround_reset_end cortex_x1, ERRATUM(1688305)
@@ -62,6 +55,13 @@
 #endif /* IMAGE_BL31 */
 workaround_reset_end cortex_x1, CVE(2022, 23960)
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x1, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_X1_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x1, CVE(2024, 5660)
+
+check_erratum_ls cortex_x1, CVE(2024, 5660), CPU_REV(1, 2)
+
 cpu_reset_func_start cortex_x1
 cpu_reset_func_end cortex_x1
 
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index b11c37d..910a6a9 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -25,23 +25,12 @@
 
 .global check_erratum_cortex_x2_3701772
 
-add_erratum_entry cortex_x2, ERRATUM(3701772), ERRATA_X2_3701772
-
-check_erratum_ls cortex_x2, ERRATUM(3701772), CPU_REV(2, 1)
-
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X2_BHB_LOOP_COUNT, cortex_x2
 #endif /* WORKAROUND_CVE_2022_23960 */
 
 cpu_reset_prologue cortex_x2
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start cortex_x2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set CORTEX_X2_CPUECTLR_EL1, BIT(46)
-workaround_reset_end cortex_x2, CVE(2024, 5660)
-
-check_erratum_ls cortex_x2, CVE(2024, 5660), CPU_REV(2, 1)
-
 workaround_reset_start cortex_x2, ERRATUM(2002765), ERRATA_X2_2002765
 	ldr	x0, =0x6
 	msr	S3_6_C15_C8_0, x0 /* CPUPSELR_EL3 */
@@ -61,13 +50,6 @@
 
 check_erratum_ls cortex_x2, ERRATUM(2017096), CPU_REV(2, 0)
 
-workaround_reset_start cortex_x2, ERRATUM(2058056), ERRATA_X2_2058056
-	sysreg_bitfield_insert CORTEX_X2_CPUECTLR2_EL1, CORTEX_X2_CPUECTLR2_EL1_PF_MODE_CNSRV, \
-	CORTEX_X2_CPUECTLR2_EL1_PF_MODE_SHIFT, CORTEX_X2_CPUECTLR2_EL1_PF_MODE_WIDTH
-workaround_reset_end cortex_x2, ERRATUM(2058056)
-
-check_erratum_ls cortex_x2, ERRATUM(2058056), CPU_REV(2, 1)
-
 workaround_reset_start cortex_x2, ERRATUM(2081180), ERRATA_X2_2081180
 	/* Apply instruction patching sequence */
 	ldr	x0, =0x3
@@ -127,6 +109,15 @@
 
 check_erratum_ls cortex_x2, ERRATUM(2282622), CPU_REV(2, 1)
 
+workaround_reset_start cortex_x2, ERRATUM(2313941), ERRATA_DSU_2313941
+	errata_dsu_2313941_wa_impl
+workaround_reset_end cortex_x2, ERRATUM(2313941)
+
+check_erratum_custom_start cortex_x2, ERRATUM(2313941)
+	check_errata_dsu_2313941_impl
+	ret
+check_erratum_custom_end cortex_x2, ERRATUM(2313941)
+
 workaround_reset_start cortex_x2, ERRATUM(2371105), ERRATA_X2_2371105
 	/* Set bit 40 in CPUACTLR2_EL1 */
 	sysreg_bit_set CORTEX_X2_CPUACTLR2_EL1, CORTEX_X2_CPUACTLR2_EL1_BIT_40
@@ -155,6 +146,10 @@
 
 check_erratum_ls cortex_x2, ERRATUM(2778471), CPU_REV(2, 1)
 
+add_erratum_entry cortex_x2, ERRATUM(3701772), ERRATA_X2_3701772
+
+check_erratum_ls cortex_x2, ERRATUM(3701772), CPU_REV(2, 1)
+
 workaround_reset_start cortex_x2, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -167,14 +162,12 @@
 
 check_erratum_chosen cortex_x2, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-workaround_reset_start cortex_x2, ERRATUM(2313941), ERRATA_DSU_2313941
-	errata_dsu_2313941_wa_impl
-workaround_reset_end cortex_x2, ERRATUM(2313941)
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_X2_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x2, CVE(2024, 5660)
 
-check_erratum_custom_start cortex_x2, ERRATUM(2313941)
-	check_errata_dsu_2313941_impl
-	ret
-check_erratum_custom_end cortex_x2, ERRATUM(2313941)
+check_erratum_ls cortex_x2, CVE(2024, 5660), CPU_REV(2, 1)
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index 3d52dae..c4872fe 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -24,30 +24,12 @@
 
 .global check_erratum_cortex_x3_3701769
 
-add_erratum_entry cortex_x3, ERRATUM(3701769), ERRATA_X3_3701769
-
-check_erratum_ls cortex_x3, ERRATUM(3701769), CPU_REV(1, 2)
-
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table CORTEX_X3_BHB_LOOP_COUNT, cortex_x3
 #endif /* WORKAROUND_CVE_2022_23960 */
 
 cpu_reset_prologue cortex_x3
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start cortex_x3, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set CORTEX_X3_CPUECTLR_EL1, BIT(46)
-workaround_reset_end cortex_x3, CVE(2024, 5660)
-
-check_erratum_ls cortex_x3, CVE(2024, 5660), CPU_REV(1, 2)
-
-workaround_reset_start cortex_x3, ERRATUM(2070301), ERRATA_X3_2070301
-	sysreg_bitfield_insert CORTEX_X3_CPUECTLR2_EL1, CORTEX_X3_CPUECTLR2_EL1_PF_MODE_CNSRV, \
-	CORTEX_X3_CPUECTLR2_EL1_PF_MODE_LSB, CORTEX_X3_CPUECTLR2_EL1_PF_MODE_WIDTH
-workaround_reset_end cortex_x3, ERRATUM(2070301)
-
-check_erratum_ls cortex_x3, ERRATUM(2070301), CPU_REV(1, 2)
-
 workaround_reset_start cortex_x3, ERRATUM(2266875), ERRATA_X3_2266875
         sysreg_bit_set CORTEX_X3_CPUACTLR_EL1, BIT(22)
 workaround_reset_end cortex_x3, ERRATUM(2266875)
@@ -114,6 +96,10 @@
 
 check_erratum_ls cortex_x3, ERRATUM(2779509), CPU_REV(1, 1)
 
+add_erratum_entry cortex_x3, ERRATUM(3701769), ERRATA_X3_3701769
+
+check_erratum_ls cortex_x3, ERRATUM(3701769), CPU_REV(1, 2)
+
 workaround_reset_start cortex_x3, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	override_vector_table wa_cve_vbar_cortex_x3
@@ -122,6 +108,13 @@
 
 check_erratum_chosen cortex_x3, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x3, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_X3_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x3, CVE(2024, 5660)
+
+check_erratum_ls cortex_x3, CVE(2024, 5660), CPU_REV(1, 2)
+
 workaround_reset_start cortex_x3, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
 	/* ---------------------------------
 	 * Sets BIT41 of CPUACTLR6_EL1 which
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index c067981..fbbe925 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -35,13 +35,6 @@
 
 check_erratum_ls cortex_x4, ERRATUM(2726228), CPU_REV(0, 1)
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start cortex_x4, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set CORTEX_X4_CPUECTLR_EL1, BIT(46)
-workaround_reset_end cortex_x4, CVE(2024, 5660)
-
-check_erratum_ls cortex_x4, CVE(2024, 5660), CPU_REV(0, 2)
-
 workaround_runtime_start cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089
 	/* dsb before isb of power down sequence */
 	dsb	sy
@@ -100,6 +93,10 @@
 
 check_erratum_ls cortex_x4, ERRATUM(3076789), CPU_REV(0, 1)
 
+add_erratum_entry cortex_x4, ERRATUM(3701758), ERRATA_X4_3701758
+
+check_erratum_ls cortex_x4, ERRATUM(3701758), CPU_REV(0, 3)
+
 workaround_reset_start cortex_x4, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -112,6 +109,13 @@
 
 check_erratum_chosen cortex_x4, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start cortex_x4, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set CORTEX_X4_CPUECTLR_EL1, BIT(46)
+workaround_reset_end cortex_x4, CVE(2024, 5660)
+
+check_erratum_ls cortex_x4, CVE(2024, 5660), CPU_REV(0, 2)
+
 workaround_reset_start cortex_x4, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
 	/* ---------------------------------
 	 * Sets BIT41 of CPUACTLR6_EL1 which
@@ -123,10 +127,6 @@
 
 check_erratum_chosen cortex_x4, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
 
-add_erratum_entry cortex_x4, ERRATUM(3701758), ERRATA_X4_3701758
-
-check_erratum_ls cortex_x4, ERRATUM(3701758), CPU_REV(0, 3)
-
 cpu_reset_func_start cortex_x4
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 9c6f01a..7d9d7f1 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -23,34 +23,12 @@
 
 .global check_erratum_neoverse_n2_3701773
 
-add_erratum_entry neoverse_n2, ERRATUM(3701773), ERRATA_N2_3701773
-
-check_erratum_ls neoverse_n2, ERRATUM(3701773), CPU_REV(0, 3)
-
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_N2_BHB_LOOP_COUNT, neoverse_n2
 #endif /* WORKAROUND_CVE_2022_23960 */
 
 cpu_reset_prologue neoverse_n2
 
-workaround_reset_start neoverse_n2, ERRATUM(2313941), ERRATA_DSU_2313941
-	errata_dsu_2313941_wa_impl
-workaround_reset_end neoverse_n2, ERRATUM(2313941)
-
-check_erratum_custom_start neoverse_n2, ERRATUM(2313941)
-	branch_if_scu_not_present 2f /* label 1 is used in the macro */
-	check_errata_dsu_2313941_impl
-	2:
-	ret
-check_erratum_custom_end neoverse_n2, ERRATUM(2313941)
-
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start neoverse_n2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set NEOVERSE_N2_CPUECTLR_EL1, BIT(46)
-workaround_reset_end neoverse_n2, CVE(2024, 5660)
-
-check_erratum_ls neoverse_n2, CVE(2024, 5660), CPU_REV(0, 3)
-
 workaround_reset_start neoverse_n2, ERRATUM(2002655), ERRATA_N2_2002655
 	/* Apply instruction patching sequence */
 	ldr x0,=0x6
@@ -73,18 +51,6 @@
 
 check_erratum_ls neoverse_n2, ERRATUM(2002655), CPU_REV(0, 0)
 
-workaround_reset_start neoverse_n2, ERRATUM(2025414), ERRATA_N2_2025414
-	sysreg_bit_set NEOVERSE_N2_CPUECTLR_EL1, NEOVERSE_N2_CPUECTLR_EL1_PFSTIDIS_BIT
-workaround_reset_end neoverse_n2, ERRATUM(2025414)
-
-check_erratum_ls neoverse_n2, ERRATUM(2025414), CPU_REV(0, 0)
-
-workaround_reset_start neoverse_n2, ERRATUM(2067956), ERRATA_N2_2067956
-	sysreg_bit_set NEOVERSE_N2_CPUACTLR_EL1, NEOVERSE_N2_CPUACTLR_EL1_BIT_46
-workaround_reset_end neoverse_n2, ERRATUM(2067956)
-
-check_erratum_ls neoverse_n2, ERRATUM(2067956), CPU_REV(0, 0)
-
 workaround_runtime_start neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478
 	/* Stash ERRSELR_EL1 in x2 */
 	mrs     x2, ERRSELR_EL1
@@ -101,15 +67,17 @@
 
 check_erratum_ls neoverse_n2, ERRATUM(2009478), CPU_REV(0, 0)
 
-workaround_reset_start neoverse_n2, ERRATUM(2138953), ERRATA_N2_2138953
-	/* Apply instruction patching sequence */
-	mrs	x1, NEOVERSE_N2_CPUECTLR2_EL1
-	mov	x0, #NEOVERSE_N2_CPUECTLR2_EL1_PF_MODE_CNSRV
-	bfi	x1, x0, #CPUECTLR2_EL1_PF_MODE_LSB, #CPUECTLR2_EL1_PF_MODE_WIDTH
-	msr	NEOVERSE_N2_CPUECTLR2_EL1, x1
-workaround_reset_end neoverse_n2, ERRATUM(2138953)
+workaround_reset_start neoverse_n2, ERRATUM(2025414), ERRATA_N2_2025414
+	sysreg_bit_set NEOVERSE_N2_CPUECTLR_EL1, NEOVERSE_N2_CPUECTLR_EL1_PFSTIDIS_BIT
+workaround_reset_end neoverse_n2, ERRATUM(2025414)
 
-check_erratum_ls neoverse_n2, ERRATUM(2138953), CPU_REV(0, 3)
+check_erratum_ls neoverse_n2, ERRATUM(2025414), CPU_REV(0, 0)
+
+workaround_reset_start neoverse_n2, ERRATUM(2067956), ERRATA_N2_2067956
+	sysreg_bit_set NEOVERSE_N2_CPUACTLR_EL1, NEOVERSE_N2_CPUACTLR_EL1_BIT_46
+workaround_reset_end neoverse_n2, ERRATUM(2067956)
+
+check_erratum_ls neoverse_n2, ERRATUM(2067956), CPU_REV(0, 0)
 
 workaround_reset_start neoverse_n2, ERRATUM(2138956), ERRATA_N2_2138956
 	/* Apply instruction patching sequence */
@@ -175,6 +143,17 @@
 
 check_erratum_ls neoverse_n2, ERRATUM(2280757), CPU_REV(0, 0)
 
+workaround_reset_start neoverse_n2, ERRATUM(2313941), ERRATA_DSU_2313941
+	errata_dsu_2313941_wa_impl
+workaround_reset_end neoverse_n2, ERRATUM(2313941)
+
+check_erratum_custom_start neoverse_n2, ERRATUM(2313941)
+	branch_if_scu_not_present 2f /* label 1 is used in the macro */
+	check_errata_dsu_2313941_impl
+	2:
+	ret
+check_erratum_custom_end neoverse_n2, ERRATUM(2313941)
+
 .global erratum_neoverse_n2_2326639_wa
 workaround_runtime_start neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639
 	/* Set/unset bit 36 in ACTLR2_EL1. The first call will set it, applying
@@ -240,6 +219,10 @@
 
 check_erratum_ls neoverse_n2, ERRATUM(2779511), CPU_REV(0, 2)
 
+add_erratum_entry neoverse_n2, ERRATUM(3701773), ERRATA_N2_3701773
+
+check_erratum_ls neoverse_n2, ERRATUM(3701773), CPU_REV(0, 3)
+
 workaround_reset_start neoverse_n2, CVE(2022,23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -252,6 +235,13 @@
 
 check_erratum_chosen neoverse_n2, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_n2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set NEOVERSE_N2_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_n2, CVE(2024, 5660)
+
+check_erratum_ls neoverse_n2, CVE(2024, 5660), CPU_REV(0, 3)
+
 	/* -------------------------------------------
 	 * The CPU Ops reset function for Neoverse N2.
 	 * -------------------------------------------
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index e1e8214..f975be0 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -28,13 +28,6 @@
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V1_BHB_LOOP_COUNT, neoverse_v1
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start neoverse_v1, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set NEOVERSE_V1_CPUECTLR_EL1, BIT(46)
-workaround_reset_end neoverse_v1, CVE(2024, 5660)
-
-check_erratum_ls neoverse_v1, CVE(2024, 5660), CPU_REV(1, 2)
-
 workaround_reset_start neoverse_v1, ERRATUM(1618635), ERRATA_V1_1618635
 	/* Inserts a DMB SY before and after MRS PAR_EL1 */
 	ldr	x0, =0x0
@@ -163,15 +156,6 @@
 
 check_erratum_range neoverse_v1, ERRATUM(1966096), CPU_REV(1, 0), CPU_REV(1, 1)
 
-workaround_reset_start neoverse_v1, ERRATUM(2108267), ERRATA_V1_2108267
-	mrs	x1, NEOVERSE_V1_CPUECTLR_EL1
-	mov	x0, #NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV
-	bfi	x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH
-	msr	NEOVERSE_V1_CPUECTLR_EL1, x1
-workaround_reset_end neoverse_v1, ERRATUM(2108267)
-
-check_erratum_ls neoverse_v1, ERRATUM(2108267), CPU_REV(1, 2)
-
 workaround_reset_start neoverse_v1, ERRATUM(2139242), ERRATA_V1_2139242
 	mov	x0, #0x3
 	msr	S3_6_C15_C8_0, x0
@@ -252,6 +236,13 @@
 
 check_erratum_chosen neoverse_v1, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_v1, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set NEOVERSE_V1_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_v1, CVE(2024, 5660)
+
+check_erratum_ls neoverse_v1, CVE(2024, 5660), CPU_REV(1, 2)
+
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index 06521ec..ce84942 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -24,20 +24,6 @@
 
 cpu_reset_prologue neoverse_v2
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start neoverse_v2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set NEOVERSE_V2_CPUECTLR_EL1, BIT(46)
-workaround_reset_end neoverse_v2, CVE(2024, 5660)
-
-check_erratum_ls neoverse_v2, CVE(2024, 5660), CPU_REV(0, 2)
-
-workaround_reset_start neoverse_v2, ERRATUM(2331132), ERRATA_V2_2331132
-	sysreg_bitfield_insert NEOVERSE_V2_CPUECTLR2_EL1, NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_CNSRV, \
-		NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_LSB, NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_WIDTH
-workaround_reset_end neoverse_v2, ERRATUM(2331132)
-
-check_erratum_ls neoverse_v2, ERRATUM(2331132), CPU_REV(0, 2)
-
 workaround_reset_start neoverse_v2, ERRATUM(2618597), ERRATA_V2_2618597
         /* Disable retention control for WFI and WFE. */
         mrs     x0, NEOVERSE_V2_CPUPWRCTLR_EL1
@@ -95,6 +81,13 @@
 
 check_erratum_chosen neoverse_v2, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_v2, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set NEOVERSE_V2_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_v2, CVE(2024, 5660)
+
+check_erratum_ls neoverse_v2, CVE(2024, 5660), CPU_REV(0, 2)
+
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V2_BHB_LOOP_COUNT, neoverse_v2
 #endif /* WORKAROUND_CVE_2022_23960 */
diff --git a/lib/cpus/aarch64/neoverse_v3.S b/lib/cpus/aarch64/neoverse_v3.S
index 29bfd0e..2ead062 100644
--- a/lib/cpus/aarch64/neoverse_v3.S
+++ b/lib/cpus/aarch64/neoverse_v3.S
@@ -26,10 +26,6 @@
 
 .global check_erratum_neoverse_v3_3701767
 
-add_erratum_entry neoverse_v3, ERRATUM(3701767), ERRATA_V3_3701767
-
-check_erratum_ls neoverse_v3, ERRATUM(3701767), CPU_REV(0, 2)
-
 workaround_reset_start neoverse_v3, ERRATUM(2970647), ERRATA_V3_2970647
 	/* Add ISB before MRS reads of MPIDR_EL1/MIDR_EL1 */
 	ldr x0, =0x1
@@ -45,17 +41,14 @@
 
 check_erratum_ls neoverse_v3, ERRATUM(2970647), CPU_REV(0, 0)
 
+add_erratum_entry neoverse_v3, ERRATUM(3701767), ERRATA_V3_3701767
+
+check_erratum_ls neoverse_v3, ERRATUM(3701767), CPU_REV(0, 2)
+
 #if WORKAROUND_CVE_2022_23960
 	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V3_BHB_LOOP_COUNT, neoverse_v3
 #endif /* WORKAROUND_CVE_2022_23960 */
 
-/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
-workaround_reset_start neoverse_v3, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
-	sysreg_bit_set NEOVERSE_V3_CPUECTLR_EL1, BIT(46)
-workaround_reset_end neoverse_v3, CVE(2024, 5660)
-
-check_erratum_ls neoverse_v3, CVE(2024, 5660), CPU_REV(0, 1)
-
 workaround_reset_start neoverse_v3, CVE(2022,23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -69,6 +62,13 @@
 
 check_erratum_chosen neoverse_v3, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
+/* Disable hardware page aggregation. Enables mitigation for `CVE-2024-5660` */
+workaround_reset_start neoverse_v3, CVE(2024, 5660), WORKAROUND_CVE_2024_5660
+	sysreg_bit_set NEOVERSE_V3_CPUECTLR_EL1, BIT(46)
+workaround_reset_end neoverse_v3, CVE(2024, 5660)
+
+check_erratum_ls neoverse_v3, CVE(2024, 5660), CPU_REV(0, 1)
+
 workaround_reset_start neoverse_v3, CVE(2024, 7881), WORKAROUND_CVE_2024_7881
        /* ---------------------------------
         * Sets BIT41 of CPUACTLR6_EL1 which
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 8136624..4b8de00 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -315,10 +315,6 @@
 # to revision r0p0 of the A78 cpu and was fixed in the revision r1p0.
 CPU_FLAG_LIST += ERRATA_A78_1952683
 
-# Flag to apply erratum 2132060 workaround during reset. This erratum applies
-# to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
-CPU_FLAG_LIST += ERRATA_A78_2132060
-
 # Flag to apply erratum 2242635 workaround during reset. This erratum applies
 # to revisions r1p0, r1p1, and r1p2 of the A78 cpu and is open. The issue is
 # present in r0p0 as well but there is no workaround for that revision.
@@ -380,10 +376,6 @@
 # It is still open.
 CPU_FLAG_LIST += ERRATA_A78_AE_2712574
 
-# Flag to apply erratum 2132064 workaround during reset. This erratum applies
-# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
-CPU_FLAG_LIST += ERRATA_A78C_2132064
-
 # Flag to apply erratum 2242638 workaround during reset. This erratum applies
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
 CPU_FLAG_LIST += ERRATA_A78C_2242638
@@ -523,10 +515,6 @@
 # to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_V1_2139242
 
-# Flag to apply erratum 2108267 workaround during reset. This erratum applies
-# to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
-CPU_FLAG_LIST += ERRATA_V1_2108267
-
 # Flag to apply erratum 2216392 workaround during reset. This erratum applies
 # to revisions r1p0 and r1p1 of the Neoverse V1 cpu and is still open. This
 # issue exists in r0p0 as well but there is no workaround for that revision.
@@ -585,11 +573,6 @@
 # to revision r2p0 of the Cortex-A710 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_A710_2083908
 
-# Flag to apply erratum 2058056 workaround during reset. This erratum applies
-# to revisions r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is still
-# open.
-CPU_FLAG_LIST += ERRATA_A710_2058056
-
 # Flag to apply erratum 2055002 workaround during reset. This erratum applies
 # to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_A710_2055002
@@ -680,10 +663,6 @@
 # to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2138956
 
-# Flag to apply erratum 2138953 workaround during reset. This erratum applies
-# to revision r0p0, r0p1, r0p2, r0p3 of the Neoverse N2 cpu and is still open.
-CPU_FLAG_LIST += ERRATA_N2_2138953
-
 # Flag to apply erratum 2242415 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2242415
@@ -751,10 +730,6 @@
 # to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_X2_2002765
 
-# Flag to apply erratum 2058056 workaround during reset. This erratum applies
-# to revisions r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is still open.
-CPU_FLAG_LIST += ERRATA_X2_2058056
-
 # Flag to apply erratum 2083908 workaround during reset. This erratum applies
 # to revision r2p0 of the Cortex-X2 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_X2_2083908
@@ -810,11 +785,6 @@
 # of the Cortex-X2 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_X2_3701772
 
-# Flag to apply erratum 2070301 workaround on reset. This erratum applies
-# to revisions r0p0, r1p0, r1p1 and r1p2 of the Cortex-X3 cpu and is
-# still open.
-CPU_FLAG_LIST += ERRATA_X3_2070301
-
 # Flag to apply erratum 2266875 workaround during reset. This erratum applies
 # to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
 CPU_FLAG_LIST += ERRATA_X3_2266875
@@ -966,6 +936,11 @@
 # Cortex-A510 cpu and is fixed in r1p3.
 CPU_FLAG_LIST += ERRATA_A510_2684597
 
+# Flag to apply erratum 2971420 workaround during context switch. This erratum
+# applies to revisions r0p1, r0p2, r0p3, r1p0, r1p1, r1p2 and r1p3 of the
+# Cortex-A510 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_A510_2971420
+
 # Flag to apply erratum 2630792 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1 of the Cortex-A520 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_A520_2630792
@@ -978,10 +953,6 @@
 # applies to revision r0p0 and r0p1 of the Cortex-A520 cpu and is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_A520_2938996
 
-# Flag to apply erratum 2331132 workaround during reset. This erratum applies
-# to revisions r0p0, r0p1 and r0p2. It is still open.
-CPU_FLAG_LIST += ERRATA_V2_2331132
-
 # Flag to apply erratum 2618597 workaround during reset. This erratum applies
 # to revisions r0p0 and r0p1. It is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_V2_2618597
@@ -1038,6 +1009,10 @@
 # only to revision r0p0, r1p0 and r1p1. It is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_A715_2728106
 
+# Flag to apply erratum 2804830 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, r1p1 and r1p2. It is fixed in r1p3.
+CPU_FLAG_LIST += ERRATA_A715_2804830
+
 # Flag to apply erratum 3699560 workaround during context save/restore of
 # ICH_VMCR_EL2 reg. This erratum applies to revisions r0p0, r1p0, r1p2, r1p3
 # of the Cortex-A715 cpu and is still open.
diff --git a/lib/cpus/errata_common.c b/lib/cpus/errata_common.c
index a391430..0530647 100644
--- a/lib/cpus/errata_common.c
+++ b/lib/cpus/errata_common.c
@@ -9,6 +9,7 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <cortex_a75.h>
+#include <cortex_a510.h>
 #include <cortex_a520.h>
 #include <cortex_a710.h>
 #include <cortex_a715.h>
@@ -25,21 +26,26 @@
 #include <neoverse_n3.h>
 #include <neoverse_v3.h>
 
-#if ERRATA_A520_2938996 || ERRATA_X4_2726228
-unsigned int check_if_affected_core(void)
+bool check_if_trbe_disable_affected_core(void)
 {
-	uint32_t midr_val = read_midr();
-	long rev_var  = cpu_get_rev_var();
-
-	if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(CORTEX_A520_MIDR)) {
-		return check_erratum_cortex_a520_2938996(rev_var);
-	} else if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(CORTEX_X4_MIDR)) {
-		return check_erratum_cortex_x4_2726228(rev_var);
+	switch (EXTRACT_PARTNUM(read_midr())) {
+#if ERRATA_A520_2938996
+	case EXTRACT_PARTNUM(CORTEX_A520_MIDR):
+		return check_erratum_cortex_a520_2938996(cpu_get_rev_var()) == ERRATA_APPLIES;
+#endif
+#if ERRATA_X4_2726228
+	case EXTRACT_PARTNUM(CORTEX_X4_MIDR):
+		return check_erratum_cortex_x4_2726228(cpu_get_rev_var()) == ERRATA_APPLIES;
+#endif
+#if ERRATA_A510_2971420
+	case EXTRACT_PARTNUM(CORTEX_A510_MIDR):
+		return check_erratum_cortex_a510_2971420(cpu_get_rev_var()) == ERRATA_APPLIES;
+#endif
+	default:
+		break;
 	}
-
-	return ERRATA_NOT_APPLIES;
+	return false;
 }
-#endif
 
 #if ERRATA_A75_764081
 bool errata_a75_764081_applies(void)
diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c
index e0a9076..03d18ec 100644
--- a/lib/cpus/errata_report.c
+++ b/lib/cpus/errata_report.c
@@ -77,7 +77,6 @@
 	uint32_t last_erratum_id = 0;
 	uint16_t last_cve_yr = 0;
 	bool check_cve = false;
-	bool failed = false;
 #endif /* FEATURE_DETECTION */
 
 	for (; entry != end; entry += 1) {
@@ -100,30 +99,20 @@
 		if (entry->cve) {
 			if (last_cve_yr > entry->cve ||
 			   (last_cve_yr == entry->cve && last_erratum_id >= entry->id)) {
-				ERROR("CVE %u_%u was out of order!\n",
+				WARN("CVE %u_%u was out of order!\n",
 				      entry->cve, entry->id);
-				failed = true;
 			}
 			check_cve = true;
 			last_cve_yr = entry->cve;
 		} else {
 			if (last_erratum_id >= entry->id || check_cve) {
-				ERROR("Erratum %u was out of order!\n",
+				WARN("Erratum %u was out of order!\n",
 				      entry->id);
-				failed = true;
 			}
 		}
 		last_erratum_id = entry->id;
 #endif /* FEATURE_DETECTION */
 	}
-
-#if FEATURE_DETECTION
-	/*
-	 * enforce errata and CVEs are in ascending order and that CVEs are
-	 * after errata
-	 */
-	assert(!failed);
-#endif /* FEATURE_DETECTION */
 }
 
 /*
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 1e6a42e..243a372 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -75,6 +75,9 @@
  */
 #if CTX_INCLUDE_FPREGS
 func fpregs_context_save
+.arch_extension fp
+	/* Temporarily enable floating point */
+
 	/* Save x0 and pass its original value to fpregs_state_save */
 	mov	x1, x0
 
@@ -97,6 +100,7 @@
 
 	fpregs_state_save x1, x9
 
+.arch_extension nofp
 	ret
 endfunc fpregs_context_save
 
@@ -115,6 +119,9 @@
  * ------------------------------------------------------------------
  */
 func fpregs_context_restore
+.arch_extension fp
+	/* Temporarily enable floating point */
+
 	/* Save x0 and pass its original value to fpregs_state_restore */
 	mov	x1, x0
 
@@ -137,6 +144,7 @@
 
 	fpregs_state_restore x1, x9
 
+.arch_extension nofp
 	ret
 endfunc fpregs_context_restore
 #endif /* CTX_INCLUDE_FPREGS */
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 3388f1c..021d538 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -548,6 +548,10 @@
 	}
 #endif /* (IMAGE_BL31 && defined(SPD_spmd) && SPMD_SPM_AT_SEL2) */
 
+	if (is_feat_mec_supported()) {
+		scr_el3 |= SCR_MECEn_BIT;
+	}
+
 	/*
 	 * Populate EL3 state so that we've the right context
 	 * before doing ERET
@@ -901,7 +905,7 @@
 		sme_init_el2_unused();
 	}
 
-	if (is_feat_mops_supported()) {
+	if (is_feat_mops_supported() && is_feat_hcx_supported()) {
 		write_hcrx_el2(read_hcrx_el2() | HCRX_EL2_MSCEn_BIT);
 	}
 
@@ -1669,13 +1673,11 @@
 	}
 #endif
 
-#if ERRATA_A520_2938996 || ERRATA_X4_2726228
-	if (check_if_affected_core() == ERRATA_APPLIES) {
+	if (check_if_trbe_disable_affected_core()) {
 		if (is_feat_trbe_supported()) {
 			trbe_disable(ctx);
 		}
 	}
-#endif
 
 #if ENABLE_FEAT_TCR2 == FEAT_STATE_CHECK_ASYMMETRIC
 	el3_state_t *el3_state = get_el3state_ctx(ctx);
@@ -2069,8 +2071,8 @@
  ******************************************************************************/
 u_register_t cm_get_scr_el3(uint32_t security_state)
 {
-	cpu_context_t *ctx;
-	el3_state_t *state;
+	const cpu_context_t *ctx;
+	const el3_state_t *state;
 
 	ctx = cm_get_context(security_state);
 	assert(ctx != NULL);
diff --git a/lib/extensions/trf/aarch64/trf.c b/lib/extensions/trf/aarch64/trf.c
index d36853a..dbafca1 100644
--- a/lib/extensions/trf/aarch64/trf.c
+++ b/lib/extensions/trf/aarch64/trf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,8 +22,12 @@
 	 * MDCR_EL3.TTRF = b0
 	 * Allow access of trace filter control registers from NS-EL2
 	 * and NS-EL1 when NS-EL2 is implemented but not used
+	 *
+	 * MDCR_EL3.RLTE = b0
+	 * Trace prohibited in Realm state, unless overridden by the
+	 * IMPLEMENTATION DEFINED authentication interface.
 	 */
-	mdcr_el3_val &= ~(MDCR_STE_BIT | MDCR_TTRF_BIT);
+	mdcr_el3_val &= ~(MDCR_STE_BIT | MDCR_TTRF_BIT | MDCR_RLTE_BIT);
 	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
diff --git a/lib/libc/libc_common.mk b/lib/libc/libc_common.mk
index 5f44bd5..3b83216 100644
--- a/lib/libc/libc_common.mk
+++ b/lib/libc/libc_common.mk
@@ -21,9 +21,11 @@
 			snprintf.c			\
 			strchr.c			\
 			strcmp.c			\
+			strcpy_secure.c		\
 			strlcat.c			\
 			strlcpy.c			\
 			strlen.c			\
+			strnlen_secure.c	\
 			strncmp.c			\
 			strnlen.c			\
 			strrchr.c			\
diff --git a/lib/libc/strcpy_secure.c b/lib/libc/strcpy_secure.c
new file mode 100644
index 0000000..6f8de29
--- /dev/null
+++ b/lib/libc/strcpy_secure.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdint.h>
+
+int strcpy_secure(char *restrict dest, size_t dest_size, const char *restrict src)
+{
+	/* Check for null pointers */
+	if ((dest == NULL) || (src == NULL)) {
+		return -EINVAL;
+	}
+
+	/* Check the destination size valid range */
+	if (dest_size == 0) {
+		return -ERANGE;
+	}
+
+	/* Calculate the length of the source string */
+	size_t src_len = strnlen_secure(src, dest_size);
+
+	/* Check if the source string fits in the destination buffer */
+	if (src_len >= dest_size) {
+		/* Set destination to an empty string */
+		dest[0] = '\0';
+		return -ERANGE;
+	}
+
+	/* Copy the source string to the destination */
+	for (dest[src_len] = '\0'; src_len > 0; src_len--) {
+		dest[src_len - 1] = src[src_len - 1];
+	}
+
+	return 0;
+}
diff --git a/lib/libc/strnlen_secure.c b/lib/libc/strnlen_secure.c
new file mode 100644
index 0000000..36b3571
--- /dev/null
+++ b/lib/libc/strnlen_secure.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+size_t strnlen_secure(const char *str, size_t maxlen)
+{
+	size_t len = 0;
+
+	if (str == NULL) {
+		return 0;
+	}
+
+	while ((len < maxlen) && (str[len] != '\0')) {
+		len++;
+	}
+
+	return len;
+}
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 12d7b7b..17ecab8 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -546,7 +546,7 @@
 	unsigned int lvl, parent_idx;
 	unsigned int start_idx;
 	unsigned int ncpus;
-	plat_local_state_t target_state, *req_states;
+	plat_local_state_t target_state;
 
 	assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
 	parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
@@ -561,7 +561,8 @@
 
 		/* Get the requested power states for this power level */
 		start_idx = psci_non_cpu_pd_nodes[parent_idx].cpu_start_idx;
-		req_states = psci_get_req_local_pwr_states(lvl, start_idx);
+		plat_local_state_t const *req_states = psci_get_req_local_pwr_states(lvl,
+										start_idx);
 
 		/*
 		 * Let the platform coordinate amongst the requested states at
diff --git a/lib/transfer_list/transfer_list.c b/lib/transfer_list/transfer_list.c
index 3817861..4d4a167 100644
--- a/lib/transfer_list/transfer_list.c
+++ b/lib/transfer_list/transfer_list.c
@@ -176,35 +176,32 @@
 	}
 
 	if (tl->signature != TRANSFER_LIST_SIGNATURE) {
-		ERROR("Bad transfer list signature 0x%x\n", tl->signature);
+		VERBOSE("Bad transfer list signature 0x%x\n", tl->signature);
 		return TL_OPS_NON;
 	}
 
 	if (!tl->max_size) {
-		ERROR("Bad transfer list max size 0x%x\n",
-		      tl->max_size);
+		VERBOSE("Bad transfer list max size 0x%x\n", tl->max_size);
 		return TL_OPS_NON;
 	}
 
 	if (tl->size > tl->max_size) {
-		ERROR("Bad transfer list size 0x%x\n", tl->size);
+		VERBOSE("Bad transfer list size 0x%x\n", tl->size);
 		return TL_OPS_NON;
 	}
 
 	if (tl->hdr_size != sizeof(struct transfer_list_header)) {
-		ERROR("Bad transfer list header size 0x%x\n",
-		      tl->hdr_size);
+		VERBOSE("Bad transfer list header size 0x%x\n", tl->hdr_size);
 		return TL_OPS_NON;
 	}
 
 	if (!transfer_list_verify_checksum(tl)) {
-		ERROR("Bad transfer list checksum 0x%x\n",
-		      tl->checksum);
+		VERBOSE("Bad transfer list checksum 0x%x\n", tl->checksum);
 		return TL_OPS_NON;
 	}
 
 	if (tl->version == 0) {
-		ERROR("Transfer list version is invalid\n");
+		VERBOSE("Transfer list version is invalid\n");
 		return TL_OPS_NON;
 	} else if (tl->version == TRANSFER_LIST_VERSION) {
 		INFO("Transfer list version is valid for all operations\n");
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 8dec522..56bfb64 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -419,6 +419,9 @@
 # Flag to enable Floating point exception Mode Register Feature (FEAT_FPMR)
 ENABLE_FEAT_FPMR			?=	0
 
+# Flag to enable Memory Encryption Contexts (FEAT_MEC).
+ENABLE_FEAT_MEC				?=	0
+
 #----
 # 9.3
 #----
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index ec2aa1b..906e5d7 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -192,6 +192,9 @@
 # Option to build TF with Measured Boot support
 MEASURED_BOOT			:= 0
 
+# Option to build TF with Discrete TPM support
+DISCRETE_TPM			:= 0
+
 # Option to enable the DICE Protection Environmnet as a Measured Boot backend
 DICE_PROTECTION_ENVIRONMENT	:=0
 
diff --git a/package-lock.json b/package-lock.json
index 61d05bd..57b44de 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -183,19 +183,18 @@
       }
     },
     "node_modules/@commitlint/cli": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.0.0.tgz",
-      "integrity": "sha512-SVBQG6k+eOOmlejYTtxnqJGmhrzy/m0qH3bVeoHY3gtlJBK3Kb32RjJioteBYk8Vuo58x5ehAjXwsQFX58X+xw==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.8.0.tgz",
+      "integrity": "sha512-t/fCrLVu+Ru01h0DtlgHZXbHV2Y8gKocTR5elDOqIRUzQd0/6hpt2VIWOj9b3NDo7y4/gfxeR2zRtXq/qO6iUg==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/format": "^19.0.0",
-        "@commitlint/lint": "^19.0.0",
-        "@commitlint/load": "^19.0.0",
-        "@commitlint/read": "^19.0.0",
-        "@commitlint/types": "^19.0.0",
-        "execa": "^8.0.1",
-        "resolve-from": "^5.0.0",
-        "resolve-global": "^2.0.0",
+        "@commitlint/format": "^19.8.0",
+        "@commitlint/lint": "^19.8.0",
+        "@commitlint/load": "^19.8.0",
+        "@commitlint/read": "^19.8.0",
+        "@commitlint/types": "^19.8.0",
+        "tinyexec": "^0.3.0",
         "yargs": "^17.0.0"
       },
       "bin": {
@@ -205,147 +204,14 @@
         "node": ">=v18"
       }
     },
-    "node_modules/@commitlint/cli/node_modules/execa": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
-      "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^8.0.1",
-        "human-signals": "^5.0.0",
-        "is-stream": "^3.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^5.1.0",
-        "onetime": "^6.0.0",
-        "signal-exit": "^4.1.0",
-        "strip-final-newline": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=16.17"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/@commitlint/cli/node_modules/get-stream": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
-      "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
-      "dev": true,
-      "engines": {
-        "node": ">=16"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/cli/node_modules/human-signals": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
-      "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=16.17.0"
-      }
-    },
-    "node_modules/@commitlint/cli/node_modules/is-stream": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
-      "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
-      "dev": true,
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/cli/node_modules/mimic-fn": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
-      "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/cli/node_modules/npm-run-path": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
-      "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^4.0.0"
-      },
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/cli/node_modules/onetime": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
-      "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
-      "dev": true,
-      "dependencies": {
-        "mimic-fn": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/cli/node_modules/path-key": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
-      "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/cli/node_modules/signal-exit": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
-      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
-      "dev": true,
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/@commitlint/cli/node_modules/strip-final-newline": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
-      "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "node_modules/@commitlint/config-conventional": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.0.0.tgz",
-      "integrity": "sha512-d8lPm+slPUdA8Zof2Y36RqAm/MmAYx/QQIEd2gKbpfLThQK1oYLs+0C3sMPD+4LIq2kh4cnbV9WnPA0P5sN8Ig==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.8.0.tgz",
+      "integrity": "sha512-9I2kKJwcAPwMoAj38hwqFXG0CzS2Kj+SAByPUQ0SlHTfb7VUhYVmo7G2w2tBrqmOf7PFd6MpZ/a1GQJo8na8kw==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/types": "^19.0.0",
+        "@commitlint/types": "^19.8.0",
         "conventional-changelog-conventionalcommits": "^7.0.2"
       },
       "engines": {
@@ -365,12 +231,13 @@
       }
     },
     "node_modules/@commitlint/config-validator": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.0.0.tgz",
-      "integrity": "sha512-oxJ2k+jBPRyWzv1ixfxwGZO5DJ1S+v3D8u/QESMwuPh3kQmeOYBRxGI+5FDWMwiVSHpztlhvvxDAU9SFXeMqUA==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.8.0.tgz",
+      "integrity": "sha512-+r5ZvD/0hQC3w5VOHJhGcCooiAVdynFlCe2d6I9dU+PvXdV3O+fU4vipVg+6hyLbQUuCH82mz3HnT/cBQTYYuA==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/types": "^19.0.0",
+        "@commitlint/types": "^19.8.0",
         "ajv": "^8.11.0"
       },
       "engines": {
@@ -378,14 +245,15 @@
       }
     },
     "node_modules/@commitlint/cz-commitlint": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-19.0.0.tgz",
-      "integrity": "sha512-hIWExZOycAuq0fW7rBq23AuBMJAmvTuM3GSlAX5kSV8gvASwXSrHRKgxrHQCcozV/ZnLlbFEvfVgBRi+UbH8pA==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-19.8.0.tgz",
+      "integrity": "sha512-zaCKTrs+lz2UhEAHUyk9EqasYSL46//FjIt37cwDb/MJ0w6dO6MeQ4ukcaSDYTkn9dfiIJP/Qh7bl8KXEQX5fw==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/ensure": "^19.0.0",
-        "@commitlint/load": "^19.0.0",
-        "@commitlint/types": "^19.0.0",
+        "@commitlint/ensure": "^19.8.0",
+        "@commitlint/load": "^19.8.0",
+        "@commitlint/types": "^19.8.0",
         "chalk": "^5.3.0",
         "lodash.isplainobject": "^4.0.6",
         "word-wrap": "^1.2.5"
@@ -411,12 +279,13 @@
       }
     },
     "node_modules/@commitlint/ensure": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.0.0.tgz",
-      "integrity": "sha512-G0avCIwjKplTP1Oc9MlDhsYqi1yOWORtJSBpyMbQEnalQAW1tuRxG4LOLRZVKfFqlDWs2SfVQPN0Uw51Ge0f6w==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.8.0.tgz",
+      "integrity": "sha512-kNiNU4/bhEQ/wutI1tp1pVW1mQ0QbAjfPRo5v8SaxoVV+ARhkB8Wjg3BSseNYECPzWWfg/WDqQGIfV1RaBFQZg==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/types": "^19.0.0",
+        "@commitlint/types": "^19.8.0",
         "lodash.camelcase": "^4.3.0",
         "lodash.kebabcase": "^4.1.1",
         "lodash.snakecase": "^4.1.1",
@@ -428,21 +297,23 @@
       }
     },
     "node_modules/@commitlint/execute-rule": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.0.0.tgz",
-      "integrity": "sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.8.0.tgz",
+      "integrity": "sha512-fuLeI+EZ9x2v/+TXKAjplBJWI9CNrHnyi5nvUQGQt4WRkww/d95oVRsc9ajpt4xFrFmqMZkd/xBQHZDvALIY7A==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=v18"
       }
     },
     "node_modules/@commitlint/format": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.0.0.tgz",
-      "integrity": "sha512-36P4/2tpGSGQsYoSZEso5fTSTaMSArIK9fszy+5B8hwwAvOfnD4kQtrwfMhiXnf7PCgeX2lx5Jma+pY3Bq326A==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.8.0.tgz",
+      "integrity": "sha512-EOpA8IERpQstxwp/WGnDArA7S+wlZDeTeKi98WMOvaDLKbjptuHWdOYYr790iO7kTCif/z971PKPI2PkWMfOxg==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/types": "^19.0.0",
+        "@commitlint/types": "^19.8.0",
         "chalk": "^5.3.0"
       },
       "engines": {
@@ -450,10 +321,11 @@
       }
     },
     "node_modules/@commitlint/format/node_modules/chalk": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
-      "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+      "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": "^12.17.0 || ^14.13 || >=16.0.0"
       },
@@ -462,12 +334,13 @@
       }
     },
     "node_modules/@commitlint/is-ignored": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.0.0.tgz",
-      "integrity": "sha512-5b2nIrl8GEjzYAnOK2ZAUxBXvUonYrp3+8kJkUMl8QOtjt2O1gsd71jar7UtoDEqTWJhc+n7lG6lQYMXtcQJAw==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.8.0.tgz",
+      "integrity": "sha512-L2Jv9yUg/I+jF3zikOV0rdiHUul9X3a/oU5HIXhAJLE2+TXTnEBfqYP9G5yMw/Yb40SnR764g4fyDK6WR2xtpw==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/types": "^19.0.0",
+        "@commitlint/types": "^19.8.0",
         "semver": "^7.6.0"
       },
       "engines": {
@@ -475,33 +348,35 @@
       }
     },
     "node_modules/@commitlint/lint": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.0.0.tgz",
-      "integrity": "sha512-rAAisSpxhA+z4uhsveSt1CuTB+Jld5d7zyNSEK2UWjQaOxicwDP+LFiOdM32n/vwsLlOJqhrInA50UcbRSVaGg==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.8.0.tgz",
+      "integrity": "sha512-+/NZKyWKSf39FeNpqhfMebmaLa1P90i1Nrb1SrA7oSU5GNN/lksA4z6+ZTnsft01YfhRZSYMbgGsARXvkr/VLQ==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/is-ignored": "^19.0.0",
-        "@commitlint/parse": "^19.0.0",
-        "@commitlint/rules": "^19.0.0",
-        "@commitlint/types": "^19.0.0"
+        "@commitlint/is-ignored": "^19.8.0",
+        "@commitlint/parse": "^19.8.0",
+        "@commitlint/rules": "^19.8.0",
+        "@commitlint/types": "^19.8.0"
       },
       "engines": {
         "node": ">=v18"
       }
     },
     "node_modules/@commitlint/load": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.0.0.tgz",
-      "integrity": "sha512-pC/6xDjkWPWgqfILY0KMMpxz0dTZqC7fUpxyWMLRrlbZCC9S54/gsg/8UltFrUH+C+F1zz4Ip8CQgzKonpH6rg==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.8.0.tgz",
+      "integrity": "sha512-4rvmm3ff81Sfb+mcWT5WKlyOa+Hd33WSbirTVUer0wjS1Hv/Hzr07Uv1ULIV9DkimZKNyOwXn593c+h8lsDQPQ==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/config-validator": "^19.0.0",
-        "@commitlint/execute-rule": "^19.0.0",
-        "@commitlint/resolve-extends": "^19.0.0",
-        "@commitlint/types": "^19.0.0",
+        "@commitlint/config-validator": "^19.8.0",
+        "@commitlint/execute-rule": "^19.8.0",
+        "@commitlint/resolve-extends": "^19.8.0",
+        "@commitlint/types": "^19.8.0",
         "chalk": "^5.3.0",
-        "cosmiconfig": "^8.3.6",
-        "cosmiconfig-typescript-loader": "^5.0.0",
+        "cosmiconfig": "^9.0.0",
+        "cosmiconfig-typescript-loader": "^6.1.0",
         "lodash.isplainobject": "^4.0.6",
         "lodash.merge": "^4.6.2",
         "lodash.uniq": "^4.5.0"
@@ -523,21 +398,23 @@
       }
     },
     "node_modules/@commitlint/message": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.0.0.tgz",
-      "integrity": "sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.8.0.tgz",
+      "integrity": "sha512-qs/5Vi9bYjf+ZV40bvdCyBn5DvbuelhR6qewLE8Bh476F7KnNyLfdM/ETJ4cp96WgeeHo6tesA2TMXS0sh5X4A==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=v18"
       }
     },
     "node_modules/@commitlint/parse": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.0.0.tgz",
-      "integrity": "sha512-/2hT08V/2Lh+aQ5cSAw5vO74FlA3LJGYzLfsNMcx6aW8Kmrsa9W7chNNY5hMWbucCF92s/JE3eVIHnzoEBKTTA==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.8.0.tgz",
+      "integrity": "sha512-YNIKAc4EXvNeAvyeEnzgvm1VyAe0/b3Wax7pjJSwXuhqIQ1/t2hD3OYRXb6D5/GffIvaX82RbjD+nWtMZCLL7Q==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/types": "^19.0.0",
+        "@commitlint/types": "^19.8.0",
         "conventional-changelog-angular": "^7.0.0",
         "conventional-commits-parser": "^5.0.0"
       },
@@ -550,6 +427,7 @@
       "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
       "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==",
       "dev": true,
+      "license": "ISC",
       "dependencies": {
         "compare-func": "^2.0.0"
       },
@@ -562,6 +440,7 @@
       "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
       "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "is-text-path": "^2.0.0",
         "JSONStream": "^1.3.5",
@@ -580,6 +459,7 @@
       "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
       "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "text-extensions": "^2.0.0"
       },
@@ -592,6 +472,7 @@
       "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
       "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=16.10"
       },
@@ -604,6 +485,7 @@
       "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
       "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
       "dev": true,
+      "license": "ISC",
       "engines": {
         "node": ">= 10.x"
       }
@@ -613,6 +495,7 @@
       "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
       "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=8"
       },
@@ -621,15 +504,17 @@
       }
     },
     "node_modules/@commitlint/read": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.0.0.tgz",
-      "integrity": "sha512-AbK/fQjWrXGAAHl+KeOtZtWJryhzkTnynhkABF4IUFZqK71JSviSIPHYuUQjdwNrD0PJGs5f19ORjY8LOXP08w==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.8.0.tgz",
+      "integrity": "sha512-6ywxOGYajcxK1y1MfzrOnwsXO6nnErna88gRWEl3qqOOP8MDu/DTeRkGLXBFIZuRZ7mm5yyxU5BmeUvMpNte5w==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/top-level": "^19.0.0",
-        "@commitlint/types": "^19.0.0",
+        "@commitlint/top-level": "^19.8.0",
+        "@commitlint/types": "^19.8.0",
         "git-raw-commits": "^4.0.0",
-        "minimist": "^1.2.8"
+        "minimist": "^1.2.8",
+        "tinyexec": "^0.3.0"
       },
       "engines": {
         "node": ">=v18"
@@ -640,6 +525,7 @@
       "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
       "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=12"
       },
@@ -652,6 +538,7 @@
       "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
       "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "dargs": "^8.0.0",
         "meow": "^12.0.1",
@@ -669,6 +556,7 @@
       "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
       "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=16.10"
       },
@@ -681,6 +569,7 @@
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
       "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
       "dev": true,
+      "license": "MIT",
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
@@ -690,191 +579,61 @@
       "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
       "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
       "dev": true,
+      "license": "ISC",
       "engines": {
         "node": ">= 10.x"
       }
     },
     "node_modules/@commitlint/resolve-extends": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.0.0.tgz",
-      "integrity": "sha512-ej0fALn5yZQOYKH8wPZnzw5LGvD0n5gJBPvV6DnMiSYudqgwYwhdNJ//MukZCXNpLIM1yMA8KUyrCP6D4WnUbg==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.8.0.tgz",
+      "integrity": "sha512-CLanRQwuG2LPfFVvrkTrBR/L/DMy3+ETsgBqW1OvRxmzp/bbVJW0Xw23LnnExgYcsaFtos967lul1CsbsnJlzQ==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/config-validator": "^19.0.0",
-        "@commitlint/types": "^19.0.0",
-        "import-fresh": "^3.0.0",
+        "@commitlint/config-validator": "^19.8.0",
+        "@commitlint/types": "^19.8.0",
+        "global-directory": "^4.0.1",
         "import-meta-resolve": "^4.0.0",
         "lodash.mergewith": "^4.6.2",
-        "resolve-global": "^2.0.0"
+        "resolve-from": "^5.0.0"
       },
       "engines": {
         "node": ">=v18"
       }
     },
     "node_modules/@commitlint/rules": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.0.0.tgz",
-      "integrity": "sha512-uwb5Ro5vvJlEjnWPezL3AcdlbLdJz24SD5VembgA6IXqqunphZr5LFsQL1z5efP7p3MUdJEXFynIx8o62+j2lA==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.8.0.tgz",
+      "integrity": "sha512-IZ5IE90h6DSWNuNK/cwjABLAKdy8tP8OgGVGbXe1noBEX5hSsu00uRlLu6JuruiXjWJz2dZc+YSw3H0UZyl/mA==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@commitlint/ensure": "^19.0.0",
-        "@commitlint/message": "^19.0.0",
-        "@commitlint/to-lines": "^19.0.0",
-        "@commitlint/types": "^19.0.0",
-        "execa": "^8.0.1"
+        "@commitlint/ensure": "^19.8.0",
+        "@commitlint/message": "^19.8.0",
+        "@commitlint/to-lines": "^19.8.0",
+        "@commitlint/types": "^19.8.0"
       },
       "engines": {
         "node": ">=v18"
       }
     },
-    "node_modules/@commitlint/rules/node_modules/execa": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
-      "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^8.0.1",
-        "human-signals": "^5.0.0",
-        "is-stream": "^3.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^5.1.0",
-        "onetime": "^6.0.0",
-        "signal-exit": "^4.1.0",
-        "strip-final-newline": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=16.17"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/@commitlint/rules/node_modules/get-stream": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
-      "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
-      "dev": true,
-      "engines": {
-        "node": ">=16"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/rules/node_modules/human-signals": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
-      "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=16.17.0"
-      }
-    },
-    "node_modules/@commitlint/rules/node_modules/is-stream": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
-      "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
-      "dev": true,
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/rules/node_modules/mimic-fn": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
-      "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/rules/node_modules/npm-run-path": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
-      "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^4.0.0"
-      },
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/rules/node_modules/onetime": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
-      "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
-      "dev": true,
-      "dependencies": {
-        "mimic-fn": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/rules/node_modules/path-key": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
-      "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@commitlint/rules/node_modules/signal-exit": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
-      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
-      "dev": true,
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/@commitlint/rules/node_modules/strip-final-newline": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
-      "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "node_modules/@commitlint/to-lines": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.0.0.tgz",
-      "integrity": "sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.8.0.tgz",
+      "integrity": "sha512-3CKLUw41Cur8VMjh16y8LcsOaKbmQjAKCWlXx6B0vOUREplp6em9uIVhI8Cv934qiwkbi2+uv+mVZPnXJi1o9A==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=v18"
       }
     },
     "node_modules/@commitlint/top-level": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.0.0.tgz",
-      "integrity": "sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.8.0.tgz",
+      "integrity": "sha512-Rphgoc/omYZisoNkcfaBRPQr4myZEHhLPx2/vTXNLjiCw4RgfPR1wEgUpJ9OOmDCiv5ZyIExhprNLhteqH4FuQ==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "find-up": "^7.0.0"
       },
@@ -887,6 +646,7 @@
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
       "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "locate-path": "^7.2.0",
         "path-exists": "^5.0.0",
@@ -904,6 +664,7 @@
       "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
       "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "p-locate": "^6.0.0"
       },
@@ -919,6 +680,7 @@
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
       "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "yocto-queue": "^1.0.0"
       },
@@ -934,6 +696,7 @@
       "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
       "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "p-limit": "^4.0.0"
       },
@@ -949,15 +712,17 @@
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
       "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       }
     },
     "node_modules/@commitlint/top-level/node_modules/yocto-queue": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
-      "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.0.tgz",
+      "integrity": "sha512-KHBC7z61OJeaMGnF3wqNZj+GGNXOyypZviiKpQeiHirG5Ib1ImwcLBH70rbMSkKfSmUNBsdf2PwaEJtKvgmkNw==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=12.20"
       },
@@ -966,11 +731,13 @@
       }
     },
     "node_modules/@commitlint/types": {
-      "version": "19.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.0.0.tgz",
-      "integrity": "sha512-qLjLUdYXKi0TIavONrjBkxrElp7KguqDbvzIRbqTdJBV/cAAr8QEhHe1qUq8OcCM3gFWTlUrDz3ISZbkRoGsAg==",
+      "version": "19.8.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.8.0.tgz",
+      "integrity": "sha512-LRjP623jPyf3Poyfb0ohMj8I3ORyBDOwXAgxxVPbSD0unJuW2mJWeiRfaQinjtccMqC5Wy1HOMfa4btKjbNxbg==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
+        "@types/conventional-commits-parser": "^5.0.0",
         "chalk": "^5.3.0"
       },
       "engines": {
@@ -1011,6 +778,16 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/@types/conventional-commits-parser": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz",
+      "integrity": "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/minimist": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
@@ -1018,13 +795,13 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "20.11.20",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz",
-      "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==",
+      "version": "22.13.9",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.9.tgz",
+      "integrity": "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==",
       "dev": true,
-      "peer": true,
+      "license": "MIT",
       "dependencies": {
-        "undici-types": "~5.26.4"
+        "undici-types": "~6.20.0"
       }
     },
     "node_modules/@types/normalize-package-data": {
@@ -1040,15 +817,16 @@
       "dev": true
     },
     "node_modules/ajv": {
-      "version": "8.12.0",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
-      "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+      "version": "8.17.1",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "fast-deep-equal": "^3.1.1",
+        "fast-deep-equal": "^3.1.3",
+        "fast-uri": "^3.0.1",
         "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2",
-        "uri-js": "^4.2.2"
+        "require-from-string": "^2.0.2"
       },
       "funding": {
         "type": "github",
@@ -1247,6 +1025,7 @@
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
       "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=6"
       }
@@ -1391,10 +1170,11 @@
       "dev": true
     },
     "node_modules/commitizen": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.0.tgz",
-      "integrity": "sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==",
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.1.tgz",
+      "integrity": "sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "cachedir": "2.3.0",
         "cz-conventional-changelog": "3.3.0",
@@ -1920,15 +1700,16 @@
       "dev": true
     },
     "node_modules/cosmiconfig": {
-      "version": "8.3.6",
-      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
-      "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
+      "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
+        "env-paths": "^2.2.1",
         "import-fresh": "^3.3.0",
         "js-yaml": "^4.1.0",
-        "parse-json": "^5.2.0",
-        "path-type": "^4.0.0"
+        "parse-json": "^5.2.0"
       },
       "engines": {
         "node": ">=14"
@@ -1946,20 +1727,21 @@
       }
     },
     "node_modules/cosmiconfig-typescript-loader": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz",
-      "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.1.0.tgz",
+      "integrity": "sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "jiti": "^1.19.1"
+        "jiti": "^2.4.1"
       },
       "engines": {
-        "node": ">=v16"
+        "node": ">=v18"
       },
       "peerDependencies": {
         "@types/node": "*",
-        "cosmiconfig": ">=8.2",
-        "typescript": ">=4"
+        "cosmiconfig": ">=9",
+        "typescript": ">=5"
       }
     },
     "node_modules/cross-spawn": {
@@ -2274,6 +2056,16 @@
       "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
       "dev": true
     },
+    "node_modules/env-paths": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+      "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/error-ex": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -2377,7 +2169,25 @@
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/fast-uri": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
+      "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fastify"
+        },
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/fastify"
+        }
+      ],
+      "license": "BSD-3-Clause"
     },
     "node_modules/figures": {
       "version": "3.2.0",
@@ -2704,6 +2514,7 @@
       "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
       "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "ini": "4.1.1"
       },
@@ -2719,6 +2530,7 @@
       "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
       "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
       "dev": true,
+      "license": "ISC",
       "engines": {
         "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
       }
@@ -2908,12 +2720,13 @@
       }
     },
     "node_modules/husky": {
-      "version": "9.0.11",
-      "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz",
-      "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==",
+      "version": "9.1.7",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+      "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
       "dev": true,
+      "license": "MIT",
       "bin": {
-        "husky": "bin.mjs"
+        "husky": "bin.js"
       },
       "engines": {
         "node": ">=18"
@@ -2955,10 +2768,11 @@
       ]
     },
     "node_modules/import-fresh": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
-      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+      "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "parent-module": "^1.0.0",
         "resolve-from": "^4.0.0"
@@ -2975,15 +2789,17 @@
       "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
       "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=4"
       }
     },
     "node_modules/import-meta-resolve": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz",
-      "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz",
+      "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==",
       "dev": true,
+      "license": "MIT",
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/wooorm"
@@ -3238,12 +3054,13 @@
       "dev": true
     },
     "node_modules/jiti": {
-      "version": "1.21.0",
-      "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz",
-      "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
+      "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
       "dev": true,
+      "license": "MIT",
       "bin": {
-        "jiti": "bin/jiti.js"
+        "jiti": "lib/jiti-cli.mjs"
       }
     },
     "node_modules/js-tokens": {
@@ -3280,7 +3097,8 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
       "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "dev": true
+      "dev": true,
+      "license": "MIT"
     },
     "node_modules/json-stringify-safe": {
       "version": "5.0.1",
@@ -3447,7 +3265,8 @@
       "version": "4.6.2",
       "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
       "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
-      "dev": true
+      "dev": true,
+      "license": "MIT"
     },
     "node_modules/lodash.snakecase": {
       "version": "4.1.1",
@@ -3785,6 +3604,7 @@
       "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
       "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "callsites": "^3.0.0"
       },
@@ -3852,15 +3672,6 @@
       "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
       "dev": true
     },
-    "node_modules/path-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/picomatch": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
@@ -3888,15 +3699,6 @@
       "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
       "dev": true
     },
-    "node_modules/punycode": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
-      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/q": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
@@ -4095,6 +3897,7 @@
       "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
       "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=0.10.0"
       }
@@ -4134,25 +3937,11 @@
       "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
       "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=8"
       }
     },
-    "node_modules/resolve-global": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-2.0.0.tgz",
-      "integrity": "sha512-gnAQ0Q/KkupGkuiMyX4L0GaBV8iFwlmoXsMtOz+DFTaKmHhOO/dSlP1RMKhpvHv/dh6K/IQkowGJBqUG0NfBUw==",
-      "dev": true,
-      "dependencies": {
-        "global-directory": "^4.0.1"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "node_modules/restore-cursor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
@@ -4633,6 +4422,13 @@
         "readable-stream": "3"
       }
     },
+    "node_modules/tinyexec": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
+      "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/tmp": {
       "version": "0.0.33",
       "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -4691,10 +4487,11 @@
       "dev": true
     },
     "node_modules/typescript": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
-      "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+      "version": "5.8.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
+      "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
       "dev": true,
+      "license": "Apache-2.0",
       "peer": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -4718,17 +4515,18 @@
       }
     },
     "node_modules/undici-types": {
-      "version": "5.26.5",
-      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
-      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+      "version": "6.20.0",
+      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+      "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
       "dev": true,
-      "peer": true
+      "license": "MIT"
     },
     "node_modules/unicorn-magic": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
       "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=18"
       },
@@ -4745,15 +4543,6 @@
         "node": ">= 10.0.0"
       }
     },
-    "node_modules/uri-js": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
-      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
-      "dev": true,
-      "dependencies": {
-        "punycode": "^2.1.0"
-      }
-    },
     "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/plat/amd/versal2/bl31_setup.c b/plat/amd/versal2/bl31_setup.c
index 3a856cb..77838a9 100644
--- a/plat/amd/versal2/bl31_setup.c
+++ b/plat/amd/versal2/bl31_setup.c
@@ -31,6 +31,8 @@
 #include <pm_api_sys.h>
 #include <pm_client.h>
 
+#include <plat_ocm_coherency.h>
+
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
 
@@ -120,9 +122,6 @@
 		cpu_clock = 112203;
 		break;
 	case QEMU:
-		/* Random values now */
-		cpu_clock = 3333333;
-		break;
 	case SILICON:
 		cpu_clock = 100000000;
 		break;
@@ -143,6 +142,10 @@
 
 	setup_console();
 
+	if (IS_TFA_IN_OCM(BL31_BASE) && (check_ocm_coherency() < 0)) {
+		NOTICE("OCM coherency check not supported\n");
+	}
+
 	NOTICE("TF-A running on %s v%d.%d, RTL v%d.%d, PS v%d.%d, PMC v%d.%d\n",
 		board_name_decode(),
 		(platform_version >> 1), platform_version % 10U,
diff --git a/plat/amd/versal2/include/def.h b/plat/amd/versal2/include/def.h
index 938b118..9bef9d0 100644
--- a/plat/amd/versal2/include/def.h
+++ b/plat/amd/versal2/include/def.h
@@ -15,14 +15,14 @@
 #define MAX_INTR_EL3			2U
 
 /* List all consoles */
-#define VERSAL2_CONSOLE_ID_none		0
-#define VERSAL2_CONSOLE_ID_pl011	1
-#define VERSAL2_CONSOLE_ID_pl011_0       1
-#define VERSAL2_CONSOLE_ID_pl011_1       2
-#define VERSAL2_CONSOLE_ID_dcc           3
-#define VERSAL2_CONSOLE_ID_dtb           4
+#define CONSOLE_ID_none		0
+#define CONSOLE_ID_pl011	1
+#define CONSOLE_ID_pl011_0       1
+#define CONSOLE_ID_pl011_1       2
+#define CONSOLE_ID_dcc           3
+#define CONSOLE_ID_dtb           4
 
-#define CONSOLE_IS(con) (VERSAL2_CONSOLE_ID_ ## con == VERSAL2_CONSOLE)
+#define CONSOLE_IS(con) (CONSOLE_ID_ ## con == CONSOLE)
 
 /* Runtime console */
 #define RT_CONSOLE_ID_pl011   1
diff --git a/plat/amd/versal2/include/plat_ocm_coherency.h b/plat/amd/versal2/include/plat_ocm_coherency.h
new file mode 100644
index 0000000..b88c2eb
--- /dev/null
+++ b/plat/amd/versal2/include/plat_ocm_coherency.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_OCM_COHERENCY_H
+#define PLAT_OCM_COHERENCY_H
+
+#define COHERENCY_CHECK_NOT_SUPPORTED	-1
+
+#if (DEBUG == 1)
+int32_t check_ocm_coherency(void);
+#else
+static inline int32_t check_ocm_coherency(void)
+{
+	return COHERENCY_CHECK_NOT_SUPPORTED;
+}
+#endif
+
+#endif/*PLAT_OCM_COHERENCY_H*/
diff --git a/plat/amd/versal2/plat_ocm_coherency.c b/plat/amd/versal2/plat_ocm_coherency.c
new file mode 100644
index 0000000..872ee23
--- /dev/null
+++ b/plat/amd/versal2/plat_ocm_coherency.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <plat_ocm_coherency.h>
+#include <platform_def.h>
+
+/*
+ * Register non hash mem regions addresses
+ */
+#define POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12    U(0xF8168000)
+#define NON_HASH_MEM_REGION_REG0        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC08)
+#define NON_HASH_MEM_REGION_REG1        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC0C)
+#define NON_HASH_MEM_REGION_REG2        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC10)
+#define NON_HASH_MEM_REGION_REG3        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC14)
+#define NON_HASH_MEM_REGION_REG4        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC18)
+#define NON_HASH_MEM_REGION_REG5        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC1C)
+#define NON_HASH_MEM_REGION_REG6        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC20)
+#define NON_HASH_MEM_REGION_REG7        U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC24)
+
+#define REGION_BASE_ADDR_VALUE	U(0x2E)
+#define REGION_BASE_ADDR_SHIFT	9
+
+#define REGION_BASE_ADDRESS_MASK	GENMASK(30, REGION_BASE_ADDR_SHIFT)
+#define REGION_VALID_BIT		BIT(0)
+
+/*
+ * verify the register configured as non-hashed
+ */
+#define IS_NON_HASHED_REGION(reg) \
+((FIELD_GET(REGION_BASE_ADDRESS_MASK, mmio_read_32(reg)) == REGION_BASE_ADDR_VALUE) && \
+						(mmio_read_32(reg) & REGION_VALID_BIT))
+
+/*
+ * Splitter registers
+ */
+#define FPX_SPLITTER_0          U(0xECC20000)
+#define FPX_SPLITTER_1          U(0xECD20000)
+#define FPX_SPLITTER_2          U(0xECE20000)
+#define FPX_SPLITTER_3          U(0xECF20000)
+#define OCM_ADDR_DIST_MODE      BIT(16)
+
+#define OCM_COHERENT	0
+#define OCM_NOT_COHERENT	1
+#define TFA_NOT_IN_OCM	2
+
+/*
+ * Function that verifies the OCM is coherent or not with the following checks:
+ * verify that OCM is in non hashed region or not if not then verify
+ * OCM_ADDR_DIST_MODE bit in splitter registers is set.
+ */
+int32_t check_ocm_coherency(void)
+{
+	int32_t status = OCM_COHERENT;
+	/* isolation should be disabled in order to read these registers */
+	if ((IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG0) ||
+	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG1) ||
+	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG2) ||
+	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG3) ||
+	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG4) ||
+	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG5) ||
+	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG6) ||
+	     IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG7))) {
+		WARN("OCM is not configured as coherent\n");
+		status = OCM_NOT_COHERENT;
+	} else {
+		/* verify OCM_ADDR_DIST_MODE bit in splitter registers is set */
+		if (!((mmio_read_32(FPX_SPLITTER_0) & OCM_ADDR_DIST_MODE) &&
+		      (mmio_read_32(FPX_SPLITTER_1) & OCM_ADDR_DIST_MODE) &&
+		      (mmio_read_32(FPX_SPLITTER_2) & OCM_ADDR_DIST_MODE) &&
+		      (mmio_read_32(FPX_SPLITTER_3) & OCM_ADDR_DIST_MODE))) {
+			WARN("OCM is not configured as coherent\n");
+			status = OCM_NOT_COHERENT;
+		}
+	}
+	return status;
+}
+
diff --git a/plat/amd/versal2/platform.mk b/plat/amd/versal2/platform.mk
index 489a063..283ad42 100644
--- a/plat/amd/versal2/platform.mk
+++ b/plat/amd/versal2/platform.mk
@@ -71,13 +71,13 @@
 USE_COHERENT_MEM := 0
 HW_ASSISTED_COHERENCY := 1
 
-VERSAL2_CONSOLE  ?=      pl011
-ifeq (${VERSAL2_CONSOLE}, $(filter ${VERSAL2_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
+CONSOLE  ?=      pl011
+ifeq (${CONSOLE}, $(filter ${CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
 	else
-	  $(error "Please define VERSAL2_CONSOLE")
+	  $(error "Please define CONSOLE")
   endif
 
-$(eval $(call add_define_val,VERSAL2_CONSOLE,VERSAL2_CONSOLE_ID_${VERSAL2_CONSOLE}))
+$(eval $(call add_define_val,CONSOLE,CONSOLE_ID_${CONSOLE}))
 
 # Runtime console in default console in DEBUG build
 ifeq ($(DEBUG), 1)
@@ -160,6 +160,11 @@
 				${PLAT_PATH}/sip_svc_setup.c			\
 				${PLAT_PATH}/gicv3.c
 
+
+ifeq ($(DEBUG),1)
+BL31_SOURCES            +=      ${PLAT_PATH}/plat_ocm_coherency.c
+endif
+
 ifeq (${ERRATA_ABI_SUPPORT}, 1)
 # enable the cpu macros for errata abi interface
 CORTEX_A78_AE_H_INC     := 1
diff --git a/plat/arm/board/a5ds/a5ds_bl2_setup.c b/plat/arm/board/a5ds/a5ds_bl2_setup.c
index a0aa639..3e26188 100644
--- a/plat/arm/board/a5ds/a5ds_bl2_setup.c
+++ b/plat/arm/board/a5ds/a5ds_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,7 @@
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	u_register_t arg2, u_register_t arg3)
 {
-	arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
+	arm_bl2_early_platform_setup(arg0, arg1, arg2, arg3);
 }
 
 void bl2_platform_setup(void)
diff --git a/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c b/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c
index a951dc7..1b8699a 100644
--- a/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c
+++ b/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
-	arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+	arm_sp_min_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	/* enable snoop control unit */
 	enable_snoop_ctrl_unit(A5DS_SCU_BASE);
diff --git a/plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c b/plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c
index 2fc0e0d..221e132 100644
--- a/plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c
+++ b/plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,5 +9,5 @@
 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
-	arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+	arm_sp_min_early_platform_setup(arg0, arg1, arg2, arg3);
 }
diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
index 662b8a4..e0b7750 100644
--- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -343,7 +343,7 @@
 	for (unsigned long i = 0UL; i < dram_layout.num_banks; i++) {
 		int err = fdt_get_reg_props_by_index(
 				hw_config_dtb, node, (int)i,
-				&dram_layout.dram_bank[i].base,
+				(uintptr_t *)&dram_layout.dram_bank[i].base,
 				(size_t *)&dram_layout.dram_bank[i].size);
 		if (err < 0) {
 			ERROR("FCONF: Failed to read 'reg' property #%lu of 'memory' node\n", i);
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 90d9608..989f058 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -52,10 +52,7 @@
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
 {
-#if TRANSFER_LIST
-	arg0 = arg3;
-#endif
-	arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
+	arm_bl2_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	/* Initialize the platform config for future decision making */
 	fvp_config_setup();
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index e087565..aa7b875 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,10 +28,7 @@
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
-#if TRANSFER_LIST
-	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
-#else
-#if !RESET_TO_BL31 && !RESET_TO_BL2
+#if !(TRANSFER_LIST || RESET_TO_BL31 || RESET_TO_BL2)
 	const struct dyn_cfg_dtb_info_t *soc_fw_config_info;
 
 	INFO("BL31 FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
@@ -53,9 +50,9 @@
 	assert(hw_config_info != NULL);
 	assert(hw_config_info->secondary_config_addr != 0UL);
 	arg2 = hw_config_info->secondary_config_addr;
-#endif /* !RESET_TO_BL31 && !RESET_TO_BL2 */
-	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
-#endif /* TRANSFER_LIST */
+#endif /* !(TRANSFER_LIST || RESET_TO_BL31 || RESET_TO_BL2)*/
+
+	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	/* Initialize the platform config for future decision making */
 	fvp_config_setup();
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 7d76814..9d0463d 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -7,11 +7,14 @@
 #include <assert.h>
 #include <string.h>
 
+#include <arch.h>
+#include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/arm/cci.h>
 #include <drivers/arm/ccn.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/arm/sp804_delay_timer.h>
+#include <drivers/arm/smmu_v3.h>
 #include <drivers/generic_delay_timer.h>
 #include <fconf_hw_config_getter.h>
 #include <lib/mmio.h>
@@ -41,6 +44,15 @@
 #define FVP_RMM_CONSOLE_NAME		"pl011"
 #define FVP_RMM_CONSOLE_COUNT		UL(1)
 
+/* Defines for RMM PCIe ECAM */
+#define FVP_RMM_ECAM_BASE		PCIE_EXP_BASE
+#define FVP_RMM_ECAM_SEGMENT		UL(0x0)
+#define FVP_RMM_ECAM_BDF		UL(0x0)
+
+/* Defines for RMM SMMUv3 */
+#define FVP_RMM_SMMU_BASE		PLAT_FVP_SMMUV3_BASE
+#define FVP_RMM_SMMU_COUNT		UL(1)
+
 /*******************************************************************************
  * arm_config holds the characteristics of the differences between the three FVP
  * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot
@@ -561,6 +573,41 @@
 }
 
 #if ENABLE_RME
+
+/* BDF mappings for RP0 RC0 */
+const struct bdf_mapping_info rc0rp0_bdf_data[] = {
+	/* BDF0 */
+	{0U,		/* mapping_base */
+	 0x8000U,	/* mapping_top */
+	 0U,		/* mapping_off */
+	 0U		/* smmu_idx */
+	}
+};
+
+/* Root ports for RC0 */
+const struct root_port_info rc0rp_data[] = {
+	/* RP0 */
+	{0U,						/* root_port_id */
+	 0U,						/* padding */
+	 ARRAY_SIZE(rc0rp0_bdf_data),			/* num_bdf_mappings */
+	 (struct bdf_mapping_info *)rc0rp0_bdf_data	/* bdf_mappings */
+	}
+};
+
+/* Root complexes */
+const struct root_complex_info rc_data[] = {
+	/* RC0 */
+	{PCIE_EXP_BASE,				/* ecam_base */
+	 0U,					/* segment */
+	 {0U, 0U, 0U},				/* padding */
+	 ARRAY_SIZE(rc0rp_data),		/* num_root_ports */
+	 (struct root_port_info *)rc0rp_data	/* root_ports */
+	}
+};
+
+/* Number of PCIe Root Complexes */
+#define FVP_RMM_RC_COUNT	ARRAY_SIZE(rc_data)
+
 /*
  * Get a pointer to the RMM-EL3 Shared buffer and return it
  * through the pointer passed as parameter.
@@ -591,14 +638,14 @@
 	return sum;
 }
 /*
- * Boot Manifest structure illustration, with two DRAM banks,
+ * Boot Manifest v0.5 structure illustration, with two DRAM banks,
  * a single console and one device memory with two PCIe device
  * non-coherent address ranges.
  *
  * +--------------------------------------------------+
  * | offset |        field       |      comment       |
  * +--------+--------------------+--------------------+
- * |   0    |       version      |     0x00000004     |
+ * |   0    |       version      |     0x00000005     |
  * +--------+--------------------+--------------------+
  * |   4    |       padding      |     0x00000000     |
  * +--------+--------------------+--------------------+
@@ -627,42 +674,95 @@
  * |   96   |       banks        |   plat_coh_region  |  |  |  |
  * +--------+--------------------+                    |  |  |  |
  * |   104  |      checksum      |                    |  |  |  |
- * +--------+--------------------+--------------------+<-+  |  |
- * |   112  |       base 0       |                    |     |  |
- * +--------+--------------------+     mem_bank[0]    |     |  |
- * |   120  |       size 0       |                    |     |  |
- * +--------+--------------------+--------------------+     |  |
- * |   128  |       base 1       |                    |     |  |
- * +--------+--------------------+     mem_bank[1]    |     |  |
- * |   136  |       size 1       |                    |     |  |
- * +--------+--------------------+--------------------+<----+  |
- * |   144  |       base         |                    |        |
- * +--------+--------------------+                    |        |
- * |   152  |      map_pages     |                    |        |
- * +--------+--------------------+                    |        |
- * |   160  |       name         |                    |        |
- * +--------+--------------------+     consoles[0]    |        |
- * |   168  |     clk_in_hz      |                    |        |
- * +--------+--------------------+                    |        |
- * |   176  |     baud_rate      |                    |        |
- * +--------+--------------------+                    |        |
- * |   184  |       flags        |                    |        |
- * +--------+--------------------+--------------------+<-------+
- * |   192  |       base 0       |                    |
- * +--------+--------------------+   ncoh_region[0]   |
- * |   200  |       size 0       |                    |
- * +--------+--------------------+--------------------+
- * |   208  |       base 1       |                    |
- * +--------+--------------------+   ncoh_region[1]   |
- * |   216  |       size 1       |                    |
+ * +--------+--------------------+--------------------+  |  |  |
+ * |   112  |     num_smmus      |                    |  |  |  |
+ * +--------+--------------------+                    |  |  |  |
+ * |   120  |       smmus        |     plat_smmu      +--|--|--|--+
+ * +--------+--------------------+                    |  |  |  |  |
+ * |   128  |      checksum      |                    |  |  |  |  |
+ * +--------+--------------------+--------------------+  |  |  |  |
+ * |   136  |  num_root_complex  |                    |  |  |  |  |
+ * +--------+--------------------+                    |  |  |  |  |
+ * |   144  |   rc_info_version  |                    |  |  |  |  |
+ * +--------+--------------------+                    |  |  |  |  |
+ * |   148  |      padding       | plat_root_complex  +--|--|--|--|--+
+ * +--------+--------------------+                    |  |  |  |  |  |
+ * |   152  |    root_complex    |                    |  |  |  |  |  |
+ * +--------+--------------------+                    |  |  |  |  |  |
+ * |   160  |      checksum      |                    |  |  |  |  |  |
+ * +--------+--------------------+--------------------+<-+  |  |  |  |
+ * |   168  |       base 0       |                    |     |  |  |  |
+ * +--------+--------------------+     mem_bank[0]    |     |  |  |  |
+ * |   176  |       size 0       |                    |     |  |  |  |
+ * +--------+--------------------+--------------------+     |  |  |  |
+ * |   184  |       base 1       |                    |     |  |  |  |
+ * +--------+--------------------+     mem_bank[1]    |     |  |  |  |
+ * |   192  |       size 1       |                    |     |  |  |  |
+ * +--------+--------------------+--------------------+<----+  |  |  |
+ * |   200  |       base         |                    |        |  |  |
+ * +--------+--------------------+                    |        |  |  |
+ * |   208  |      map_pages     |                    |        |  |  |
+ * +--------+--------------------+                    |        |  |  |
+ * |   216  |       name         |                    |        |  |  |
+ * +--------+--------------------+     consoles[0]    |        |  |  |
+ * |   224  |     clk_in_hz      |                    |        |  |  |
+ * +--------+--------------------+                    |        |  |  |
+ * |   232  |     baud_rate      |                    |        |  |  |
+ * +--------+--------------------+                    |        |  |  |
+ * |   240  |       flags        |                    |        |  |  |
+ * +--------+--------------------+--------------------+<-------+  |  |
+ * |   248  |       base 0       |                    |           |  |
+ * +--------+--------------------+    ncoh_region[0]  |           |  |
+ * |   256  |       size 0       |                    |           |  |
+ * +--------+--------------------+--------------------+           |  |
+ * |   264  |       base 1       |                    |           |  |
+ * +--------+--------------------+    ncoh_region[1]  |           |  |
+ * |   272  |       size 1       |                    |           |  |
+ * +--------+--------------------+--------------------+<----------+  |
+ * |   280  |     smmu_base      |                    |              |
+ * +--------+--------------------+      smmus[0]      |              |
+ * |   288  |     smmu_r_base    |                    |              |
+ * +--------+--------------------+--------------------+<-------------+
+ * |   296  |     ecam_base      |                    |
+ * +--------+--------------------+                    |
+ * |   304  |      segment       |                    |
+ * +--------+--------------------+                    |
+ * |   305  |      padding       |   root_complex[0]  +--+
+ * +--------+--------------------+                    |  |
+ * |   308  |   num_root_ports   |                    |  |
+ * +--------+--------------------+                    |  |
+ * |   312  |     root_ports     |                    |  |
+ * +--------+--------------------+--------------------+<-+
+ * |   320  |    root_port_id    |                    |
+ * +--------+--------------------+                    |
+ * |   322  |      padding       |                    |
+ * +--------+--------------------+   root_ports[0]    +--+
+ * |   324  |  num_bdf_mappings  |                    |  |
+ * +--------+--------------------+                    |  |
+ * |   328  |    bdf_mappings    |                    |  |
+ * +--------+--------------------+--------------------+<-+
+ * |   336  |    mapping_base    |                    |
+ * +--------+--------------------+                    |
+ * |   338  |    mapping_top     |                    |
+ * +--------+--------------------+   bdf_mappings[0]  |
+ * |   340  |    mapping_off     |                    |
+ * +--------+--------------------+                    |
+ * |   342  |     smmu_idx       |                    |
  * +--------+--------------------+--------------------+
  */
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 {
 	uint64_t checksum, num_banks, num_consoles;
 	uint64_t num_ncoh_regions, num_coh_regions;
-	struct memory_bank *bank_ptr, *ncoh_region_ptr;
+	uint64_t num_smmus, num_root_complex;
+	unsigned int num_root_ports, num_bdf_mappings;
+	uint32_t o_realm;
+	struct memory_bank *bank_ptr, *ncoh_region_ptr, *coh_region_ptr;
 	struct console_info *console_ptr;
+	struct smmu_info *smmu_ptr;
+	struct root_complex_info *root_complex_ptr, *rc_ptr;
+	struct root_port_info *root_port_ptr, *rp_ptr;
+	struct bdf_mapping_info *bdf_mapping_ptr, *bdf_ptr;
 
 	assert(manifest != NULL);
 
@@ -676,12 +776,36 @@
 	/* Set number of device non-coherent address ranges based on DT */
 	num_ncoh_regions = FCONF_GET_PROPERTY(hw_config, pci_props, num_ncoh_regions);
 
+	/* Set number of SMMUs */
+	num_smmus = FVP_RMM_SMMU_COUNT;
+
+	/* Set number of PCIe root complexes */
+	num_root_complex = FVP_RMM_RC_COUNT;
+
+	/* Calculate and set number of all PCIe root ports and BDF mappings */
+	num_root_ports = 0U;
+	num_bdf_mappings = 0U;
+
+	/* Scan all root complex entries */
+	for (unsigned long i = 0UL; i < num_root_complex; i++) {
+		num_root_ports += rc_data[i].num_root_ports;
+
+		/* Scan all root ports entries in root complex */
+		for (unsigned int j = 0U; j < rc_data[i].num_root_ports; j++) {
+			num_bdf_mappings += rc_data[i].root_ports[j].num_bdf_mappings;
+		}
+	}
+
 	manifest->version = RMMD_MANIFEST_VERSION;
 	manifest->padding = 0U; /* RES0 */
 	manifest->plat_data = 0UL;
 	manifest->plat_dram.num_banks = num_banks;
 	manifest->plat_console.num_consoles = num_consoles;
 	manifest->plat_ncoh_region.num_banks = num_ncoh_regions;
+	manifest->plat_smmu.num_smmus = num_smmus;
+	manifest->plat_root_complex.num_root_complex = num_root_complex;
+	manifest->plat_root_complex.rc_info_version = PCIE_RC_INFO_VERSION;
+	manifest->plat_root_complex.padding = 0U; /* RES0 */
 
 	/* FVP does not support device coherent address ranges */
 	num_coh_regions = 0UL;
@@ -697,9 +821,27 @@
 	ncoh_region_ptr = (struct memory_bank *)
 			((uintptr_t)console_ptr + (num_consoles *
 						sizeof(struct console_info)));
+	coh_region_ptr = (struct memory_bank *)
+			((uintptr_t)ncoh_region_ptr + (num_ncoh_regions *
+						sizeof(struct memory_bank)));
+	smmu_ptr = (struct smmu_info *)
+			((uintptr_t)coh_region_ptr + (num_coh_regions *
+						sizeof(struct memory_bank)));
+	root_complex_ptr = (struct root_complex_info *)
+			((uintptr_t)smmu_ptr + (num_smmus *
+						sizeof(struct smmu_info)));
+	root_port_ptr = (struct	root_port_info *)
+			((uintptr_t)root_complex_ptr + (num_root_complex *
+						sizeof(struct root_complex_info)));
+	bdf_mapping_ptr = (struct bdf_mapping_info *)
+			((uintptr_t)root_port_ptr + (num_root_ports *
+						sizeof(struct root_port_info)));
+
 	manifest->plat_dram.banks = bank_ptr;
 	manifest->plat_console.consoles = console_ptr;
 	manifest->plat_ncoh_region.banks = ncoh_region_ptr;
+	manifest->plat_smmu.smmus = smmu_ptr;
+	manifest->plat_root_complex.root_complex = root_complex_ptr;
 
 	/* Ensure the manifest is not larger than the shared buffer */
 	assert((sizeof(struct rmm_manifest) +
@@ -710,7 +852,13 @@
 		(sizeof(struct memory_bank) *
 			manifest->plat_ncoh_region.num_banks) +
 		(sizeof(struct memory_bank) *
-			manifest->plat_coh_region.num_banks))
+			manifest->plat_coh_region.num_banks) +
+		(sizeof(struct smmu_info) *
+			manifest->plat_smmu.num_smmus) +
+		(sizeof(struct root_complex_info) *
+			manifest->plat_root_complex.num_root_complex) +
+		(sizeof(struct root_port_info) * num_root_ports) +
+		(sizeof(struct bdf_mapping_info) * num_bdf_mappings))
 		<= ARM_EL3_RMM_SHARED_SIZE);
 
 	/* Calculate checksum of plat_dram structure */
@@ -773,6 +921,99 @@
 	/* Checksum must be 0 */
 	manifest->plat_ncoh_region.checksum = ~checksum + 1UL;
 
+	/* Calculate the checksum of the plat_smmu structure */
+	checksum = num_smmus + (uint64_t)smmu_ptr;
+
+	smmu_ptr[0].smmu_base = FVP_RMM_SMMU_BASE;
+
+	/* Read SMMU_ROOT_IDR0.BA_REALM[31:22] register field */
+	o_realm = mmio_read_32(FVP_RMM_SMMU_BASE + SMMU_ROOT_IDR0) &
+				SMMU_ROOT_IDR0_BA_REALM_MASK;
+	/*
+	 * Calculate the base address offset of Realm Register Page 0.
+	 * O_REALM = 0x20000 + (BA_REALM * 0x10000)
+	 * SMMU_REALM_BASE = SMMU_PAGE_0_BASE + O_REALM
+	 */
+	o_realm = 0x20000 + (o_realm >> (SMMU_ROOT_IDR0_BA_REALM_SHIFT - 16U));
+
+	smmu_ptr[0].smmu_r_base = FVP_RMM_SMMU_BASE + o_realm;
+
+	/* Update checksum */
+	checksum += checksum_calc((uint64_t *)smmu_ptr,
+					sizeof(struct smmu_info) * num_smmus);
+	/* Checksum must be 0 */
+	manifest->plat_smmu.checksum = ~checksum + 1UL;
+
+	/* Calculate the checksum of the plat_root_complex structure */
+	checksum = num_root_complex + (uint64_t)root_complex_ptr;
+
+	/* Zero out PCIe root complex info structures */
+	(void)memset((void *)root_complex_ptr, 0,
+			sizeof(struct root_complex_info) * num_root_complex);
+
+	/* Set pointers for data in manifest */
+	rc_ptr = root_complex_ptr;
+	rp_ptr = root_port_ptr;
+	bdf_ptr = bdf_mapping_ptr;
+
+	/* Fill PCIe root complex info structures */
+	for (unsigned long i = 0U; i < num_root_complex; i++) {
+		const struct root_complex_info *rc_info = &rc_data[i];
+		const struct root_port_info *rp_info = rc_info->root_ports;
+
+		/* Copy root complex data, except root_ports pointer */
+		(void)memcpy((void *)rc_ptr, (void *)rc_info,
+			sizeof(struct root_complex_info) - sizeof(struct root_port_info *));
+
+		/* Set root_ports for root complex */
+		rc_ptr->root_ports = rp_ptr;
+
+		/* Scan root ports */
+		for (unsigned int j = 0U; j < rc_ptr->num_root_ports; j++) {
+			const struct bdf_mapping_info *bdf_info = rp_info->bdf_mappings;
+
+			/* Copy root port data, except bdf_mappings pointer */
+			(void)memcpy((void *)rp_ptr, (void *)rp_info,
+				sizeof(struct root_port_info) - sizeof(struct bdf_mapping_info *));
+
+			/* Set bdf_mappings for root port */
+			rp_ptr->bdf_mappings = bdf_ptr;
+
+			/* Copy all BDF mappings for root port */
+			(void)memcpy((void *)bdf_ptr, (void *)bdf_info,
+				sizeof(struct bdf_mapping_info) * rp_ptr->num_bdf_mappings);
+
+			bdf_ptr += rp_ptr->num_bdf_mappings;
+			rp_ptr++;
+			rp_info++;
+		}
+		rc_ptr++;
+	}
+
+	/* Check that all data are written in manifest */
+	assert(rc_ptr == (root_complex_ptr + num_root_complex));
+	assert(rp_ptr == (root_port_ptr + num_root_ports));
+	assert(bdf_ptr == (bdf_mapping_ptr + num_bdf_mappings));
+
+	/* Update checksum for all PCIe data */
+	checksum += checksum_calc((uint64_t *)root_complex_ptr,
+				(uintptr_t)bdf_ptr - (uintptr_t)root_complex_ptr);
+
+	/* Checksum must be 0 */
+	manifest->plat_root_complex.checksum = ~checksum + 1UL;
+
 	return 0;
 }
-#endif	/* ENABLE_RME */
+
+/*
+ * Update encryption key associated with @mecid.
+ */
+int plat_rmmd_mecid_key_update(uint16_t mecid)
+{
+	/*
+	 * FVP does not provide an interface to change the encryption key associated
+	 * with MECID. Hence always return success.
+	 */
+	return 0;
+}
+#endif /* ENABLE_RME */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 7bd2a1d..8c114e7 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -93,6 +93,10 @@
 ENABLE_FEAT_MTE2		:= 2
 ENABLE_FEAT_LS64_ACCDATA	:= 2
 
+ifeq (${ENABLE_RME},1)
+    ENABLE_FEAT_MEC		:= 2
+endif
+
 # The FVP platform depends on this macro to build with correct GIC driver.
 $(eval $(call add_define,FVP_USE_GIC_DRIVER))
 
@@ -429,7 +433,6 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
 
 ifeq (${TRANSFER_LIST}, 1)
-include lib/transfer_list/transfer_list.mk
 
 ifeq ($(RESET_TO_BL31), 1)
 FW_HANDOFF_SIZE			:=	20000
diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
index 705ec38..76ca5b5 100644
--- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
+++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,7 +34,7 @@
 	}
 #endif /* !RESET_TO_SP_MIN && !RESET_TO_BL2 */
 
-	arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+	arm_sp_min_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	/* Initialize the platform config for future decision making */
 	fvp_config_setup();
diff --git a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
index cc29f36..3209a1c 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
+++ b/plat/arm/board/fvp_ve/fvp_ve_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,7 +15,7 @@
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
 {
-	arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
+	arm_bl2_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	/* Initialize the platform config for future decision making */
 	fvp_ve_config_setup();
diff --git a/plat/arm/board/fvp_ve/sp_min/fvp_ve_sp_min_setup.c b/plat/arm/board/fvp_ve/sp_min/fvp_ve_sp_min_setup.c
index e6a1bbe..eba122f 100644
--- a/plat/arm/board/fvp_ve/sp_min/fvp_ve_sp_min_setup.c
+++ b/plat/arm/board/fvp_ve/sp_min/fvp_ve_sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,5 +11,5 @@
 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
-	arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+	arm_sp_min_early_platform_setup(arg0, arg1, arg2, arg3);
 }
diff --git a/plat/arm/board/juno/juno_bl31_setup.c b/plat/arm/board/juno/juno_bl31_setup.c
index 7a0a6d9..2eec105 100644
--- a/plat/arm/board/juno/juno_bl31_setup.c
+++ b/plat/arm/board/juno/juno_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,7 +27,7 @@
 		arg1 = soc_fw_config_info->config_addr;
 	}
 
-	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	/*
 	 * Initialize Interconnect for this cluster during cold boot.
diff --git a/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
index 2dd8b45..bb89c04 100644
--- a/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
@@ -179,7 +179,7 @@
 		arg1 = soc_fw_config_info->config_addr;
 	}
 #endif /* SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */
-	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
 }
 
 /*******************************************************************************
diff --git a/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk b/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
index 5776948..421c14e 100644
--- a/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
@@ -125,7 +125,6 @@
 ERRATA_N2_2025414	:=	1
 ERRATA_N2_2189731	:=	1
 ERRATA_N2_2138956	:=	1
-ERRATA_N2_2138953	:=	1
 ERRATA_N2_2242415	:=	1
 ERRATA_N2_2138958	:=	1
 ERRATA_N2_2242400	:=	1
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
index 1ddd0e4..c587a55 100644
--- a/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
@@ -178,5 +178,6 @@
 ifeq (${SPD},spmd)
 ifeq (${SPMD_SPM_AT_SEL2},1)
 override CTX_INCLUDE_SVE_REGS	:= 0
+override CTX_INCLUDE_FPREGS	:= 0
 endif
 endif
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
index 364bce1..ac1f893 100644
--- a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
@@ -187,6 +187,18 @@
 	return 0;
 }
 
+/*
+ * Update encryption key associated with @mecid.
+ */
+int plat_rmmd_mecid_key_update(uint16_t mecid)
+{
+	/*
+	 * RDV3 does not support FEAT_MEC.
+	 * This empty hook is for compilation to succeed.
+	 */
+	return 0;
+}
+
 int plat_rse_comms_init(void)
 {
 	struct mhu_addr mhu_addresses;
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 71f7bb3..0216000 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,6 +34,28 @@
 
 #define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00080000	/* 512 KB */
 
+#if TRANSFER_LIST
+/*
+ * Summation of data size of all Transfer Entries included in the Transfer list.
+ * Note: Update this field whenever new Transfer Entries are added in future.
+ */
+#define PLAT_ARM_FW_HANDOFF_SIZE	U(0x9000)
+#define PLAT_ARM_EL3_FW_HANDOFF_BASE	ARM_BL_RAM_BASE
+#define PLAT_ARM_EL3_FW_HANDOFF_LIMIT	PLAT_ARM_EL3_FW_HANDOFF_BASE + PLAT_ARM_FW_HANDOFF_SIZE
+#define FW_NS_HANDOFF_BASE		(PLAT_ARM_NS_IMAGE_BASE - PLAT_ARM_FW_HANDOFF_SIZE)
+
+/* Mappings for Secure and Non-secure Transfer_list */
+#define TC_MAP_EL3_FW_HANDOFF		MAP_REGION_FLAT(		\
+					PLAT_ARM_EL3_FW_HANDOFF_BASE,	\
+					PLAT_ARM_FW_HANDOFF_SIZE,	\
+					MT_MEMORY | MT_RW | EL3_PAS)
+
+#define TC_MAP_FW_NS_HANDOFF		MAP_REGION_FLAT(		\
+					FW_NS_HANDOFF_BASE,		\
+					PLAT_ARM_FW_HANDOFF_SIZE,	\
+					MT_MEMORY | MT_RW | MT_NS)
+#endif /* TRANSFER_LIST */
+
 /*
  * The top 16MB of ARM_DRAM1 is configured as secure access only using the TZC,
  * its base is ARM_AP_TZC_DRAM1_BASE.
diff --git a/plat/arm/board/tc/tc_bl2_setup.c b/plat/arm/board/tc/tc_bl2_setup.c
index 74ef569..b5d3a1a 100644
--- a/plat/arm/board/tc/tc_bl2_setup.c
+++ b/plat/arm/board/tc/tc_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2021-2025, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,17 +18,26 @@
  ******************************************************************************/
 struct bl_params *plat_get_next_bl_params(void)
 {
-	struct bl_params *arm_bl_params = arm_get_next_bl_params();
-
-	const struct dyn_cfg_dtb_info_t *fw_config_info;
+	struct bl_params *arm_bl_params;
 	bl_mem_params_node_t *param_node;
-	uintptr_t fw_config_base = 0U;
-	entry_point_info_t *ep_info;
+	const struct dyn_cfg_dtb_info_t *fw_config_info __maybe_unused;
+	uintptr_t fw_config_base __maybe_unused;
+	entry_point_info_t *ep_info __maybe_unused;
+
+	arm_bl_params = arm_get_next_bl_params();
 
 	/* Get BL31 image node */
 	param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
 	assert(param_node != NULL);
+#if TRANSFER_LIST
+	assert(arm_bl_params != NULL);
 
+	arm_bl_params->head = &param_node->params_node_mem;
+	arm_bl_params->head->ep_info = &param_node->ep_info;
+	arm_bl_params->head->image_id = param_node->image_id;
+
+	arm_bl2_setup_next_ep_info(param_node);
+#else
 	/* Get fw_config load address */
 	fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
 	assert(fw_config_info != NULL);
@@ -42,6 +51,7 @@
 	 */
 	ep_info = &param_node->ep_info;
 	ep_info->args.arg1 = (uint32_t)fw_config_base;
+#endif /* TRANSFER_LIST */
 
 	return arm_bl_params;
 }
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 5d19aeb..a358390 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -154,10 +154,15 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
-	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+	/* Initialize the console to provide early debug support */
+	arm_console_boot_init();
 
+	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
+
+#if !TRANSFER_LIST
 	/* Fill the properties struct with the info from the config dtb */
 	fconf_populate("FW_CONFIG", arg1);
+#endif
 }
 
 #ifdef PLATFORM_TESTS
@@ -202,6 +207,13 @@
 {
 	arm_bl31_plat_arch_setup();
 
+	/*
+	 * When TRANSFER_LIST is enabled, HW_CONFIG is included in Transfer List
+	 * as an entry with the tag TL_TAG_FDT. In this case, the configuration
+	 * is already available, so the fconf_populate mechanism is not needed.
+	 * The code block below is only required when TRANSFER_LIST is not used.
+	 */
+#if !TRANSFER_LIST
 	/* HW_CONFIG was also loaded by BL2 */
 	const struct dyn_cfg_dtb_info_t *hw_config_info;
 
@@ -209,6 +221,7 @@
 	assert(hw_config_info != NULL);
 
 	fconf_populate("HW_CONFIG", hw_config_info->config_addr);
+#endif
 }
 
 #if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index 1ecfdb9..fcee784 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,6 +33,9 @@
 	TC_MAP_NS_DRAM1,
 	TC_FLASH0_RO,
 	TC_MAP_DEVICE,
+#if TRANSFER_LIST
+	TC_MAP_EL3_FW_HANDOFF,
+#endif
 	{0}
 };
 #endif
@@ -59,6 +62,9 @@
 	ARM_MAP_OPTEE_CORE_MEM,
 	ARM_OPTEE_PAGEABLE_LOAD_MEM,
 #endif
+#if TRANSFER_LIST
+	TC_MAP_EL3_FW_HANDOFF,
+#endif
 	{0}
 };
 #endif
@@ -72,6 +78,10 @@
 #if SPM_MM
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
+#if TRANSFER_LIST
+	TC_MAP_FW_NS_HANDOFF,
+	TC_MAP_EL3_FW_HANDOFF,
+#endif
 	{0}
 };
 
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index b8e5027..75d6a53 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -90,7 +90,7 @@
 	bl1_tzram_layout.total_size = ARM_BL_RAM_SIZE;
 
 #if TRANSFER_LIST
-	secure_tl = transfer_list_ensure((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
+	secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
 					 PLAT_ARM_FW_HANDOFF_SIZE);
 	assert(secure_tl != NULL);
 #endif
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 17dc0ed..6418628 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -66,8 +66,8 @@
  * in x0. This memory layout is sitting at the base of the free trusted SRAM.
  * Copy it to a safe location before its reclaimed by later BL2 functionality.
  ******************************************************************************/
-void arm_bl2_early_platform_setup(uintptr_t fw_config,
-				  struct meminfo *mem_layout)
+void arm_bl2_early_platform_setup(u_register_t arg0, u_register_t arg1,
+				  u_register_t arg2, u_register_t arg3)
 {
 	struct transfer_list_entry *te __unused;
 	int __maybe_unused ret;
@@ -76,8 +76,7 @@
 	arm_console_boot_init();
 
 #if TRANSFER_LIST
-	// TODO: modify the prototype of this function fw_config != bl2_tl
-	secure_tl = (struct transfer_list_header *)fw_config;
+	secure_tl = (struct transfer_list_header *)arg3;
 
 	te = transfer_list_find(secure_tl, TL_TAG_SRAM_LAYOUT64);
 	assert(te != NULL);
@@ -85,11 +84,11 @@
 	bl2_tzram_layout = *(meminfo_t *)transfer_list_entry_data(te);
 	transfer_list_rem(secure_tl, te);
 #else
-	config_base = fw_config;
+	config_base = (uintptr_t)arg0;
 
 	/* Setup the BL2 memory layout */
-	bl2_tzram_layout = *mem_layout;
-#endif
+	bl2_tzram_layout = *(meminfo_t *)arg1;
+#endif /* TRANSFER_LIST */
 
 	/* Initialise the IO layer and register platform IO devices */
 	plat_arm_io_setup();
@@ -105,9 +104,10 @@
 #endif /* ARM_GPT_SUPPORT */
 }
 
-void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
+void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+			       u_register_t arg2, u_register_t arg3)
 {
-	arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
+	arm_bl2_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	generic_delay_timer_init();
 }
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 0503acf..bf2d8cd 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -154,10 +154,10 @@
  * while creating page tables. BL2 has flushed this information to memory, so
  * we are guaranteed to pick up good data.
  ******************************************************************************/
-#if TRANSFER_LIST
 void __init arm_bl31_early_platform_setup(u_register_t arg0, u_register_t arg1,
 					  u_register_t arg2, u_register_t arg3)
 {
+#if TRANSFER_LIST
 #if RESET_TO_BL31
 	/* Populate entry point information for BL33 */
 	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
@@ -208,18 +208,11 @@
 		}
 	}
 #endif /* RESET_TO_BL31 */
-}
-#else
-void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config,
-				uintptr_t hw_config, void *plat_params_from_bl2)
-{
-	/* Initialize the console to provide early debug support */
-	arm_console_boot_init();
-
+#else /* (!TRANSFER_LIST) */
 #if RESET_TO_BL31
 	/* There are no parameters from BL2 if BL31 is a reset vector */
-	assert(from_bl2 == NULL);
-	assert(plat_params_from_bl2 == NULL);
+	assert((void *)arg0 == NULL);
+	assert((void *)arg3 == NULL);
 
 # ifdef BL32_BASE
 	/* Populate entry point information for BL32 */
@@ -258,21 +251,18 @@
 	 */
 	rmm_image_ep_info.pc = RMM_BASE;
 #endif /* ENABLE_RME */
-
 #else /* RESET_TO_BL31 */
-
 	/*
-	 * In debug builds, we pass a special value in 'plat_params_from_bl2'
+	 * In debug builds, we pass a special value in 'arg3'
 	 * to verify platform parameters from BL2 to BL31.
 	 * In release builds, it's not used.
 	 */
-	assert(((unsigned long long)plat_params_from_bl2) ==
-		ARM_BL31_PLAT_PARAM_VAL);
+	assert(((unsigned long long)arg3) == ARM_BL31_PLAT_PARAM_VAL);
 
 	/*
 	 * Check params passed from BL2 should not be NULL,
 	 */
-	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+	bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
 	assert(params_from_bl2 != NULL);
 	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
 	assert(params_from_bl2->h.version >= VERSION_2);
@@ -325,7 +315,7 @@
 #endif
 #endif /* RESET_TO_BL31 */
 
-# if ARM_LINUX_KERNEL_AS_BL33
+#if ARM_LINUX_KERNEL_AS_BL33
 	/*
 	 * According to the file ``Documentation/arm64/booting.txt`` of the
 	 * Linux kernel tree, Linux expects the physical address of the device
@@ -339,23 +329,19 @@
 #if RESET_TO_BL31
 	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
 #else
-	bl33_image_ep_info.args.arg0 = (u_register_t)hw_config;
-#endif
+	bl33_image_ep_info.args.arg0 = arg2;
+#endif /* RESET_TO_BL31 */
 	bl33_image_ep_info.args.arg1 = 0U;
 	bl33_image_ep_info.args.arg2 = 0U;
 	bl33_image_ep_info.args.arg3 = 0U;
-# endif
+#endif /* ARM_LINUX_KERNEL_AS_BL33 */
+#endif /* TRANSFER_LIST */
 }
-#endif
 
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 		u_register_t arg2, u_register_t arg3)
 {
-#if TRANSFER_LIST
 	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
-#else
-	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
-#endif
 
 	/*
 	 * Initialize Interconnect for this cluster during cold boot.
@@ -382,8 +368,8 @@
 	struct transfer_list_entry *te __unused;
 
 #if TRANSFER_LIST && !RESET_TO_BL31
-	ns_tl = transfer_list_ensure((void *)FW_NS_HANDOFF_BASE,
-				       PLAT_ARM_FW_HANDOFF_SIZE);
+	ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE,
+				   PLAT_ARM_FW_HANDOFF_SIZE);
 	if (ns_tl == NULL) {
 		ERROR("Non-secure transfer list initialisation failed!\n");
 		panic();
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 6d59bae..3dd38cd 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -311,6 +311,7 @@
 				plat/common/plat_psci_common.c
 
 ifeq (${TRANSFER_LIST}, 1)
+	include lib/transfer_list/transfer_list.mk
 	TRANSFER_LIST_SOURCES += plat/arm/common/arm_transfer_list.c
 endif
 
@@ -502,7 +503,7 @@
 		$(q)$($(ARCH)-cpp) $(cot-dt-cpp-flags)
 
         $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.c): $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.dts) | $$(@D)/
-		$(if $(host-poetry),$(q)poetry -q install)
+		$(if $(host-poetry),$(q)poetry -q install --no-root)
 		$(q)$(if $(host-poetry),poetry run )cot-dt2c convert-to-c $< $@
 
         BL2_SOURCES += $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.c)
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index 4cd514b..78fc88e 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -61,8 +61,8 @@
 /*******************************************************************************
  * Utility function to perform early platform setup.
  ******************************************************************************/
-void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config,
-			uintptr_t hw_config, void *plat_params_from_bl2)
+void arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
+			u_register_t arg2, u_register_t arg3)
 {
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
@@ -99,7 +99,7 @@
 	/*
 	 * Check params passed from BL2 should not be NULL,
 	 */
-	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+	bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
 	assert(params_from_bl2 != NULL);
 	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
 	assert(params_from_bl2->h.version >= VERSION_2);
@@ -132,7 +132,7 @@
 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
-	arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+	arm_sp_min_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	/*
 	 * Initialize Interconnect for this cluster during cold boot.
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index 1e055c5..995ef78 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -56,7 +56,7 @@
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
-	arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
+	arm_bl2_early_platform_setup(arg0, arg1, arg2, arg3);
 
 	/* Save SCP Boot config before it gets overwritten by SCP_BL2 loading */
 	scp_boot_config = mmio_read_32(SCP_BOOT_CFG_ADDR);
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 084539e..480edb9 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
- * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -190,7 +190,8 @@
 	ret = socfpga_vab_init(image_id);
 	if (ret < 0) {
 		ERROR("SOCFPGA VAB Authentication failed\n");
-		wfi();
+		while (1)
+			wfi();
 	}
 #endif
 
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 4c10e7b..a3c3545 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
- * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -175,6 +175,16 @@
 	mmio_write_64(PLAT_CPU_RELEASE_ADDR,
 		(uint64_t)plat_secondary_cpus_bl31_entry);
 
+#if SIP_SVC_V3
+	/*
+	 * Re-initialize the mailbox to include V3 specific routines.
+	 * In V3, this re-initialize is required because prior to BL31, U-Boot
+	 * SPL has its own mailbox settings and this initialization will
+	 * override to those settings as required by the V3 framework.
+	 */
+	mailbox_init();
+#endif
+
 	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
 }
 
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index d534b2e..ee33402 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -1,7 +1,7 @@
 #
 # Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
 # Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
-# Copyright (c) 2024, Altera Corporation. All rights reserved.
+# Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -115,5 +115,9 @@
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
 USE_COHERENT_MEM		:= 1
+HANDLE_EA_EL3_FIRST_NS		:= 1
 
-HANDLE_EA_EL3_FIRST_NS			:= 1
\ No newline at end of file
+#To get the TF-A version via SMC calls
+DEFINES += -DVERSION_MAJOR=${VERSION_MAJOR}
+DEFINES += -DVERSION_MINOR=${VERSION_MINOR}
+DEFINES += -DVERSION_PATCH=${VERSION_PATCH}
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
index 17d955a..9cf1e11 100644
--- a/plat/intel/soc/agilex5/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -61,6 +61,10 @@
 	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
 			       PLAT_BAUDRATE, &console);
 
+	/* Enable TF-A BL31 logs when running from non-secure world also. */
+	console_set_scope(&console,
+		(CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH));
+
 	setup_smmu_stream_id();
 
 	/*
@@ -173,6 +177,17 @@
 	gicv3_distif_init();
 	gicv3_rdistif_init(plat_my_core_pos());
 	gicv3_cpuif_enable(plat_my_core_pos());
+
+#if SIP_SVC_V3
+	/*
+	 * Re-initialize the mailbox to include V3 specific routines.
+	 * In V3, this re-initialize is required because prior to BL31, U-Boot
+	 * SPL has its own mailbox settings and this initialization will
+	 * override to those settings as required by the V3 framework.
+	 */
+	mailbox_init();
+#endif
+
 	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
 }
 
@@ -290,7 +305,7 @@
 
 void bl31_plat_runtime_setup(void)
 {
-	console_switch_state(CONSOLE_FLAG_RUNTIME|CONSOLE_FLAG_BOOT);
+	/* Dummy override function. */
 }
 
 void bl31_plat_enable_mmu(uint32_t flags)
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
index 58d4b2e..471b86f 100644
--- a/plat/intel/soc/agilex5/platform.mk
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -142,4 +142,9 @@
 
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
-BL2_INV_DCACHE			:= 0
\ No newline at end of file
+BL2_INV_DCACHE			:= 0
+
+#To get the TF-A version via SMC calls
+DEFINES += -DVERSION_MAJOR=${VERSION_MAJOR}
+DEFINES += -DVERSION_MINOR=${VERSION_MINOR}
+DEFINES += -DVERSION_PATCH=${VERSION_PATCH}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_ddr.c b/plat/intel/soc/agilex5/soc/agilex5_ddr.c
index ef2ae57..0d60324 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_ddr.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_ddr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -370,10 +370,10 @@
 	/* DDR size queried from the IOSSM controller */
 	hw_ddr_size = (phys_size_t)io96b_ctrl.overall_size * SZ_1G / SZ_8;
 
-	/* TODO: Hard code 1GB as of now, and DDR start and end address */
-	config_ddr_size = 0x40000000;
-	ddr_info_set[0].start = 0x80000000;
-	ddr_info_set[0].size = 0x40000000;
+	/* TODO: To update config_ddr_size by using FDT in the future. */
+	config_ddr_size = 0x80000000;
+	ddr_info_set[0].start = DRAM_BASE;
+	ddr_info_set[0].size = hw_ddr_size;
 
 	if (config_ddr_size != hw_ddr_size) {
 		WARN("DDR: DDR size configured is (%lld MiB)\n", config_ddr_size >> 20);
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index e2efeb1..6325d35 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
- * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -207,6 +207,9 @@
 #define MAX_IO_DEVICES				4
 #define MAX_IO_BLOCK_DEVICES			2
 
+/* Define this, to support the SiPSVC V3 implementation. */
+#define SIP_SVC_V3				1
+
 #ifndef __ASSEMBLER__
 struct socfpga_bl31_params {
 	param_header_t h;
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
index 6bb70e0..f92678f 100644
--- a/plat/intel/soc/common/include/socfpga_fcs.h
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -88,12 +89,22 @@
 #define FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE		52U
 #define FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE			29U
 
-#define FCS_CRYPTO_ECB_BUFFER_SIZE			12U
-#define FCS_CRYPTO_CBC_CTR_BUFFER_SIZE			28U
-#define FCS_CRYPTO_BLOCK_MODE_MASK			0x07
-#define FCS_CRYPTO_ECB_MODE			0x00
-#define FCS_CRYPTO_CBC_MODE			0x01
-#define FCS_CRYPTO_CTR_MODE			0x02
+#define FCS_CRYPTO_ECB_BUFFER_SIZE				12U
+#define FCS_CRYPTO_CBC_CTR_BUFFER_SIZE				28U
+#define FCS_CRYPTO_BLOCK_MODE_MASK				0x07
+#define FCS_CRYPTO_ECB_MODE					0x00
+#define FCS_CRYPTO_CBC_MODE					0x01
+#define FCS_CRYPTO_CTR_MODE					0x02
+#define FCS_CRYPTO_GCM_MODE					0x03
+#define FCS_CRYPTO_GCM_GHASH_MODE				0x04
+
+#define FCS_HKDF_REQUEST_DATA_SIZE				512U
+#define FCS_HKDF_KEY_OBJ_MAX_SIZE				352U
+#define FCS_HKDF_KEY_DATA_SIZE					168U
+#define FCS_HKDF_STEP0_1_KEY_OBJ_SIZE_BITS			384U
+#define FCS_HKDF_STEP2_KEY_OBJ_SIZE_BITS			256U
+#define FCS_HKDF_INPUT_BLOCK_SIZE				80U
+#define FCS_HKDF_SHA2_384_KEY_DATA_SIZE				48U
 
 /* FCS Payload Structure */
 typedef struct fcs_rng_payload_t {
@@ -183,10 +194,12 @@
 				uint32_t *mbox_error);
 int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
 				uint32_t size, uint32_t *send_id);
-uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
+uint32_t intel_fcs_send_cert(uint32_t smc_fid, uint32_t trans_id,
+				uint64_t addr, uint64_t size,
 				uint32_t *send_id);
 uint32_t intel_fcs_get_provision_data(uint32_t *send_id);
-uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type,
+uint32_t intel_fcs_cntr_set_preauth(uint32_t smc_fid, uint32_t trans_id,
+				uint8_t counter_type,
 				int32_t counter_value,
 				uint32_t test_bit,
 				uint32_t *mbox_error);
@@ -198,14 +211,18 @@
 				uint32_t dst_addr, uint32_t dst_size,
 				uint32_t *send_id);
 
-int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
+int intel_fcs_encryption_ext(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint32_t dst_addr, uint32_t *dst_size,
-				uint32_t *mbox_error);
-int intel_fcs_decryption_ext(uint32_t sesion_id, uint32_t context_id,
+				uint32_t *mbox_error, uint32_t smmu_src_addr,
+				uint32_t smmu_dst_addr);
+int intel_fcs_decryption_ext(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t sesion_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint32_t dst_addr, uint32_t *dst_size,
-				uint32_t *mbox_error);
+				uint32_t *mbox_error, uint64_t owner_id,
+				uint32_t smmu_src_addr, uint32_t smmu_dst_addr);
 
 int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error);
 int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error);
@@ -218,9 +235,10 @@
 uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
 				uint32_t *mbox_error);
 
-int intel_fcs_create_cert_on_reload(uint32_t cert_request,
-				uint32_t *mbox_error);
-int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
+int intel_fcs_create_cert_on_reload(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t cert_request, uint32_t *mbox_error);
+int intel_fcs_get_attestation_cert(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t cert_request, uint64_t dst_addr,
 				uint32_t *dst_size, uint32_t *mbox_error);
 
 int intel_fcs_open_crypto_service_session(uint32_t *session_id,
@@ -242,10 +260,12 @@
 int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
 				uint32_t key_id, uint32_t param_size,
 				uint64_t param_data, uint32_t *mbox_error);
-int intel_fcs_get_digest_update_finalize(uint32_t session_id, uint32_t context_id,
+int intel_fcs_get_digest_update_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t *dst_size,
-				uint8_t is_finalised, uint32_t *mbox_error);
+				uint8_t is_finalised, uint32_t *mbox_error,
+				uint32_t smmu_src_addr);
 int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t *dst_size,
@@ -255,11 +275,12 @@
 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
 				uint32_t key_id, uint32_t param_size,
 				uint64_t param_data, uint32_t *mbox_error);
-int intel_fcs_mac_verify_update_finalize(uint32_t session_id, uint32_t context_id,
+int intel_fcs_mac_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t *dst_size,
 				uint32_t data_size, uint8_t is_finalised,
-				uint32_t *mbox_error);
+				uint32_t *mbox_error, uint64_t smmu_src_addr);
 int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t *dst_size,
@@ -269,7 +290,8 @@
 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
 				uint32_t key_id, uint32_t param_size,
 				uint64_t param_data, uint32_t *mbox_error);
-int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
+int intel_fcs_ecdsa_hash_sign_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t *dst_size,
 				uint32_t *mbox_error);
@@ -277,7 +299,8 @@
 int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
 				uint32_t key_id, uint32_t param_size,
 				uint64_t param_data, uint32_t *mbox_error);
-int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
+int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t *dst_size,
 				uint32_t *mbox_error);
@@ -286,11 +309,12 @@
 				uint32_t context_id, uint32_t key_id,
 				uint32_t param_size, uint64_t param_data,
 				uint32_t *mbox_error);
-int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id,
-				uint32_t context_id, uint32_t src_addr,
-				uint32_t src_size, uint64_t dst_addr,
-				uint32_t *dst_size, uint8_t is_finalised,
-				uint32_t *mbox_error);
+int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
+				uint32_t src_addr, uint32_t src_size,
+				uint64_t dst_addr, uint32_t *dst_size,
+				uint8_t is_finalised, uint32_t *mbox_error,
+				uint64_t smmu_src_addr);
 int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id,
 				uint32_t context_id, uint32_t src_addr,
 				uint32_t src_size, uint64_t dst_addr,
@@ -301,11 +325,12 @@
 				uint32_t context_id, uint32_t key_id,
 				uint32_t param_size, uint64_t param_data,
 				uint32_t *mbox_error);
-int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
-				uint32_t context_id, uint32_t src_addr,
-				uint32_t src_size, uint64_t dst_addr,
-				uint32_t *dst_size, uint32_t data_size,
-				uint8_t is_finalised, uint32_t *mbox_error);
+int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
+				uint32_t src_addr, uint32_t src_size,
+				uint64_t dst_addr, uint32_t *dst_size,
+				uint32_t data_size, uint8_t is_finalised,
+				uint32_t *mbox_error, uint64_t smmu_src_addr);
 int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id,
 				uint32_t context_id, uint32_t src_addr,
 				uint32_t src_size, uint64_t dst_addr,
@@ -316,14 +341,16 @@
 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
 				uint32_t key_id, uint32_t param_size,
 				uint64_t param_data, uint32_t *mbox_error);
-int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
+int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
 				uint64_t dst_addr, uint32_t *dst_size,
 				uint32_t *mbox_error);
 
 int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
 				uint32_t key_id, uint32_t param_size,
 				uint64_t param_data, uint32_t *mbox_error);
-int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
+int intel_fcs_ecdh_request_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t *dst_size,
 				uint32_t *mbox_error);
@@ -331,10 +358,16 @@
 int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
 				uint32_t key_id, uint64_t param_addr,
 				uint32_t param_size, uint32_t *mbox_error);
-int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
-				uint32_t context_id, uint64_t src_addr,
-				uint32_t src_size, uint64_t dst_addr,
-				uint32_t dst_size, uint8_t is_finalised,
-				uint32_t *send_id);
+int intel_fcs_aes_crypt_update_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
+				uint64_t src_addr, uint32_t src_size,
+				uint64_t dst_addr, uint32_t dst_size,
+				uint32_t aad_size, uint8_t is_finalised,
+				uint32_t *send_id, uint64_t smmu_src_addr,
+				uint64_t smmu_dst_addr);
 
+int intel_fcs_hkdf_request(uint32_t smc_fid, uint32_t trans_id,
+			uint32_t session_id, uint32_t step_type,
+			uint32_t mac_mode, uint32_t src_addr,
+			uint32_t key_uid, uint32_t op_key_size);
 #endif /* SOCFPGA_FCS_H */
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index e27af21..f965b7d 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
- * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,20 +23,22 @@
 #define MBOX_TEST_BIT					BIT(31)
 
 /* Mailbox Shared Memory Register Map */
-#define MBOX_CIN					0x00
-#define MBOX_ROUT					0x04
-#define MBOX_URG					0x08
-#define MBOX_INT					0x0C
-#define MBOX_COUT					0x20
-#define MBOX_RIN					0x24
-#define MBOX_STATUS					0x2C
-#define MBOX_CMD_BUFFER					0x40
-#define MBOX_RESP_BUFFER				0xC0
+#define MBOX_CIN					0x00 /* Command valid offset, to SDM */
+#define MBOX_ROUT					0x04 /* Response output offset, to SDM */
+#define MBOX_URG					0x08 /* Urgent command, to SDM */
+#define MBOX_INT					0x0C /* Interrupt enables, to SDM */
+/* 0x10 - 0x1F, Reserved */
 
-/* Mailbox SDM doorbell */
-#define MBOX_DOORBELL_TO_SDM				0x400
-#define MBOX_DOORBELL_FROM_SDM				0x480
+#define MBOX_COUT					0x20 /* Command free offset, from SDM */
+#define MBOX_RIN					0x24 /* Response valid offset, from SDM */
+#define MBOX_STATUS					0x2C /* Mailbox status from SDM to client */
+/* 0x30 - 0x3F, Reserved */
 
+#define MBOX_CMD_BUFFER					0x40 /* Circular buffer, cmds to SDM */
+#define MBOX_RESP_BUFFER				0xC0 /* Circular buffer, resp from SDM */
+
+#define MBOX_DOORBELL_TO_SDM				0x400 /* Doorbell from HPS to SDM */
+#define MBOX_DOORBELL_FROM_SDM				0x480 /* Doorbell from SDM to HPS */
 
 /* Mailbox commands */
 
@@ -61,12 +63,15 @@
 #define MBOX_HWMON_READVOLT				0x18
 #define MBOX_HWMON_READTEMP				0x19
 
-
 /* QSPI Commands */
 #define MBOX_CMD_QSPI_OPEN				0x32
 #define MBOX_CMD_QSPI_CLOSE				0x33
 #define MBOX_CMD_QSPI_SET_CS				0x34
+#define MBOX_CMD_QSPI_ERASE				0x38
+#define MBOX_CMD_QSPI_WRITE				0x39
+#define MBOX_CMD_QSPI_READ				0x3A
 #define MBOX_CMD_QSPI_DIRECT				0x3B
+#define MBOX_CMD_QSPI_GET_DEV_INFO			0x74
 
 /* SEU Commands */
 #define MBOX_CMD_SEU_ERR_READ				0x3C
@@ -94,12 +99,14 @@
 #define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY		0x87
 #define MBOX_FCS_ECDSA_GET_PUBKEY			0x88
 #define MBOX_FCS_ECDH_REQUEST				0x89
+#define MBOX_FCS_HKDF_REQUEST				0x8B
 #define MBOX_FCS_OPEN_CS_SESSION			0xA0
 #define MBOX_FCS_CLOSE_CS_SESSION			0xA1
 #define MBOX_FCS_IMPORT_CS_KEY				0xA5
 #define MBOX_FCS_EXPORT_CS_KEY				0xA6
 #define MBOX_FCS_REMOVE_CS_KEY				0xA7
 #define MBOX_FCS_GET_CS_KEY_INFO			0xA8
+#define MBOX_FCS_CREATE_CS_KEY				0xA9
 
 /* PSG SIGMA Commands */
 #define MBOX_PSG_SIGMA_TEARDOWN				0xD5
@@ -111,7 +118,9 @@
 #define MBOX_GET_MEASUREMENT				0x183
 
 /* Miscellaneous commands */
+#define MBOX_CMD_MCTP_MSG				0x194
 #define MBOX_GET_ROM_PATCH_SHA384			0x1B0
+#define MBOX_CMD_GET_DEVICEID				0x500
 
 /* Mailbox Definitions */
 
@@ -120,6 +129,18 @@
 #define CMD_CASUAL					0
 #define CMD_URGENT					1
 
+/* Mailbox command flags and related macros */
+#define MBOX_CMD_FLAG_DIRECT				BIT(0)
+#define MBOX_CMD_FLAG_INDIRECT				BIT(1)
+#define MBOX_CMD_FLAG_CASUAL				BIT(2)
+#define MBOX_CMD_FLAG_URGENT				BIT(3)
+
+#define MBOX_CMD_FLAG_CASUAL_INDIRECT			(MBOX_CMD_FLAG_CASUAL | \
+							 MBOX_CMD_FLAG_INDIRECT)
+
+#define IS_CMD_SET(cmd, _type)				((((cmd) & MBOX_CMD_FLAG_##_type) != 0) ? \
+								1 : 0)
+
 #define MBOX_WORD_BYTE					4U
 #define MBOX_RESP_BUFFER_SIZE				16
 #define MBOX_CMD_BUFFER_SIZE				32
@@ -171,22 +192,25 @@
 								+ MBOX_WORD_BYTE * (ptr))
 
 /* Mailbox interrupt flags and masks */
-#define MBOX_INT_FLAG_COE				0x1
-#define MBOX_INT_FLAG_RIE				0x2
-#define MBOX_INT_FLAG_UAE				0x100
-#define MBOX_COE_BIT(INTERRUPT)				((INTERRUPT) & 0x3)
-#define MBOX_UAE_BIT(INTERRUPT)				(((INTERRUPT) & (1<<8)))
+#define MBOX_INT_FLAG_COE				BIT(0) /* COUT update interrupt enable */
+#define MBOX_INT_FLAG_RIE				BIT(1) /* RIN update interrupt enable */
+#define MBOX_INT_FLAG_UAE				BIT(8) /* Urgent ACK interrupt enable */
+
+#define MBOX_COE_BIT(INTERRUPT)				((INTERRUPT) & MBOX_INT_FLAG_COE)
+#define MBOX_RIE_BIT(INTERRUPT)				((INTERRUPT) & MBOX_INT_FLAG_RIE)
+#define MBOX_UAE_BIT(INTERRUPT)				((INTERRUPT) & MBOX_INT_FLAG_UAE)
 
 /* Mailbox response and status */
 #define MBOX_RESP_ERR(BUFFER)				((BUFFER) & 0x000007ff)
 #define MBOX_RESP_LEN(BUFFER)				(((BUFFER) & 0x007ff000) >> 12)
 #define MBOX_RESP_CLIENT_ID(BUFFER)			(((BUFFER) & 0xf0000000) >> 28)
 #define MBOX_RESP_JOB_ID(BUFFER)			(((BUFFER) & 0x0f000000) >> 24)
+#define MBOX_RESP_TRANSACTION_ID(BUFFER)		(((BUFFER) & 0xff000000) >> 24)
 #define MBOX_STATUS_UA_MASK				(1<<8)
 
 /* Mailbox command and response */
 #define MBOX_CLIENT_ID_CMD(CLIENT_ID)			((CLIENT_ID) << 28)
-#define MBOX_JOB_ID_CMD(JOB_ID)				(JOB_ID<<24)
+#define MBOX_JOB_ID_CMD(JOB_ID)				(JOB_ID << 24)
 #define MBOX_CMD_LEN_CMD(CMD_LEN)			((CMD_LEN) << 12)
 #define MBOX_INDIRECT(val)				((val) << 11)
 #define MBOX_CMD_MASK(header)				((header) & 0x7ff)
@@ -204,6 +228,17 @@
 #define CONFIG_STATUS_FW_VER_OFFSET			1
 #define CONFIG_STATUS_FW_VER_MASK			0x00FFFFFF
 
+/* QSPI mailbox command macros */
+#define MBOX_QSPI_SET_CS_OFFSET				(28)
+#define MBOX_QSPI_SET_CS_MODE_OFFSET			(27)
+#define MBOX_QSPI_SET_CS_CA_OFFSET			(26)
+#define MBOX_QSPI_ERASE_SIZE_GRAN			(0x400)
+
+#define MBOX_4K_ALIGNED_MASK				(0xFFF)
+#define MBOX_IS_4K_ALIGNED(x)				((x) & MBOX_4K_ALIGNED_MASK)
+#define MBOX_IS_WORD_ALIGNED(x)				(!((x) & 0x3))
+#define MBOX_QSPI_RW_MAX_WORDS				(0x1000)
+
 /* Data structure */
 
 typedef struct mailbox_payload {
@@ -264,4 +299,107 @@
 
 int mailbox_send_fpga_config_comp(void);
 
+#if SIP_SVC_V3
+#define MBOX_CLIENT_ID_SHIFT				(28)
+#define MBOX_JOB_ID_SHIFT				(24)
+#define MBOX_CMD_LEN_SHIFT				(12)
+#define MBOX_INDIRECT_SHIFT				(11)
+
+#define MBOX_FRAME_CMD_HEADER(client_id, job_id, args_len, indirect, cmd)\
+				((client_id << MBOX_CLIENT_ID_SHIFT) |	 \
+				(job_id << MBOX_JOB_ID_SHIFT) |		 \
+				(args_len << MBOX_CMD_LEN_SHIFT) |	 \
+				(indirect << MBOX_CMD_LEN_SHIFT) |	 \
+				cmd)
+
+#define FLAG_SDM_RESPONSE_IS_VALID			BIT(0)
+#define FLAG_SDM_RESPONSE_IS_USED			BIT(1)
+#define FLAG_SDM_RESPONSE_IS_IN_PROGRESS		BIT(2)
+#define FLAG_SDM_RESPONSE_IS_POLL_ON_INTR		BIT(3)
+
+/*
+ * TODO: Re-visit this queue size based on the system load.
+ * 4 bits for client ID and 4 bits for job ID, total 8 bits and we can have up to
+ * 256 transactions. We can tune this based on our system load at any given time
+ */
+#define MBOX_SVC_CMD_QUEUE_SIZE				(32)
+#define MBOX_SVC_RESP_QUEUE_SIZE			(32)
+#define MBOX_SVC_MAX_JOB_ID				(16)
+#define MBOX_SVC_CMD_ARG_SIZE				(2)
+#define MBOX_SVC_CMD_IS_USED				BIT(0)
+#define MBOX_SVC_CMD_CB_ARGS_SIZE			(4)
+#define MBOX_SVC_MAX_CLIENTS				(16)
+#define MBOX_SVC_MAX_RESP_DATA_SIZE			(32)
+#define MBOX_SVC_SMC_RET_MAX_SIZE			(8)
+
+/* Client ID(4bits) + Job ID(4bits) = Transcation ID(TID - 8bits, 256 combinations) */
+#define MBOX_MAX_TIDS					(256)
+/* Each transcation ID bitmap holds 64bits */
+#define MBOX_TID_BITMAP_SIZE				(sizeof(uint64_t) * 8)
+/* Number of transcation ID bitmaps required to hold 256 combinations */
+#define MBOX_MAX_TIDS_BITMAP				(MBOX_MAX_TIDS / MBOX_TID_BITMAP_SIZE)
+
+/* SDM Response State (SRS) enums */
+typedef enum sdm_resp_state {
+	SRS_WAIT_FOR_RESP = 0x00U,
+	SRS_WAIT_FOR_HEADER,
+	SRS_WAIT_FOR_ARGUMENTS,
+	SRS_SYNC_ERROR
+} sdm_resp_state_t;
+
+/* SDM response data structure */
+typedef struct sdm_response {
+	bool is_poll_intr;
+	uint8_t client_id;
+	uint8_t job_id;
+	uint16_t resp_len;
+	uint16_t err_code;
+	uint32_t flags;
+	uint32_t header;
+	uint16_t rcvd_resp_len;
+	uint32_t resp_data[MBOX_SVC_MAX_RESP_DATA_SIZE];
+} sdm_response_t;
+
+/* SDM client callback template */
+typedef uint8_t (*sdm_command_callback)(void *resp, void *cmd,
+					uint32_t *ret_args);
+
+/* SDM command data structure */
+typedef struct sdm_command {
+	uint8_t client_id;
+	uint8_t job_id;
+	uint32_t flags;
+	sdm_command_callback cb;
+	uint32_t *cb_args;
+	uint8_t cb_args_len;
+} sdm_command_t;
+
+/* Get the transcation ID from client ID and job ID. */
+#define MBOX_GET_TRANS_ID(cid, jib)			(((cid) << 4) | (jib))
+
+/* Mailbox service data structure */
+typedef struct mailbox_service {
+	sdm_resp_state_t resp_state;
+	sdm_resp_state_t next_resp_state;
+	uint32_t flags;
+	int curr_di;
+	uint64_t received_bitmap[MBOX_MAX_TIDS_BITMAP];
+	uint64_t interrupt_bitmap[MBOX_MAX_TIDS_BITMAP];
+	sdm_command_t cmd_queue[MBOX_SVC_CMD_QUEUE_SIZE];
+	sdm_response_t resp_queue[MBOX_SVC_RESP_QUEUE_SIZE];
+} mailbox_service_t;
+
+int mailbox_send_cmd_async_v3(uint8_t client_id, uint8_t job_id, uint32_t cmd,
+			      uint32_t *args, uint32_t args_len, uint8_t cmd_flag,
+			      sdm_command_callback cb, uint32_t *cb_args,
+			      uint32_t cb_args_len);
+
+int mailbox_response_poll_v3(uint8_t client_id, uint8_t job_id, uint32_t *ret_args,
+			     uint32_t *ret_args_size);
+
+int mailbox_response_poll_on_intr_v3(uint8_t *client_id, uint8_t *job_id,
+				     uint64_t *bitmap);
+
+#endif		/* #if SIP_SVC_V3 */
+
 #endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 31474c4..7f96adb 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
- * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,6 +26,10 @@
 #define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN				0x400
 #define INTEL_SIP_SMC_CMD_V2_RANGE_END					0x4FF
 
+/* SiP V3 command code range */
+#define INTEL_SIP_SMC_CMD_V3_RANGE_BEGIN				0x00C8
+#define INTEL_SIP_SMC_CMD_V3_RANGE_END					0x01F4
+
 /* SiP V2 protocol header */
 #define INTEL_SIP_SMC_HEADER_JOB_ID_MASK				0xF
 #define INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET				0U
@@ -146,6 +150,9 @@
 #define INTEL_SIP_SMC_SEU_ERR_STATUS					0xC2000099
 #define INTEL_SIP_SMC_SAFE_INJECT_SEU_ERR				0xC200009A
 
+/* ATF build version */
+#define INTEL_SIP_SMC_ATF_BUILD_VER					0xC200009B
+
 #define INTEL_SIP_SMC_FCS_SHA_MODE_MASK					0xF
 #define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK				0xF
 #define INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET				4U
@@ -186,11 +193,11 @@
 /*
  * Increase if there is any backward compatibility impact
  */
-#define SIP_SVC_VERSION_MAJOR						2
+#define SIP_SVC_VERSION_MAJOR						3
 /*
  * Increase if there is new SMC function ID being added
  */
-#define SIP_SVC_VERSION_MINOR						2
+#define SIP_SVC_VERSION_MINOR						1
 
 
 /* Structure Definitions */
@@ -240,4 +247,103 @@
 			 void *handle,
 			 u_register_t flags);
 
+
+#if SIP_SVC_V3
+#define SMC_RET_ARGS_ONE							(1)
+#define SMC_RET_ARGS_TWO							(2)
+#define SMC_RET_ARGS_THREE							(3)
+#define SMC_RET_ARGS_FOUR							(4)
+#define SMC_RET_ARGS_FIVE							(5)
+#define SMC_RET_ARGS_SIX							(6)
+
+/*
+ * SiP SVC Version3 SMC Functions IDs
+ */
+
+/* Generic response POLL commands */
+#define ALTERA_SIP_SMC_ASYNC_RESP_POLL						(0x420000C8)
+#define ALTERA_SIP_SMC_ASYNC_RESP_POLL_ON_INTR					(0x420000C9)
+
+/* QSPI related commands */
+#define ALTERA_SIP_SMC_ASYNC_QSPI_OPEN						(0x420000CC)
+#define ALTERA_SIP_SMC_ASYNC_QSPI_CLOSE						(0x420000CD)
+#define ALTERA_SIP_SMC_ASYNC_QSPI_SET_CS					(0x420000CE)
+#define ALTERA_SIP_SMC_ASYNC_QSPI_ERASE						(0x420000CF)
+#define ALTERA_SIP_SMC_ASYNC_QSPI_WRITE						(0x420000D0)
+#define ALTERA_SIP_SMC_ASYNC_QSPI_READ						(0x420000D1)
+#define ALTERA_SIP_SMC_ASYNC_GET_DEVICE_IDENTITY				(0x420000D2)
+#define ALTERA_SIP_SMC_ASYNC_GET_IDCODE						(0x420000D3)
+#define ALTERA_SIP_SMC_ASYNC_QSPI_GET_DEV_INFO					(0x420000D4)
+
+#define ALTERA_SIP_SMC_ASYNC_HWMON_READTEMP					(0x420000E8)
+#define ALTERA_SIP_SMC_ASYNC_HWMON_READVOLT					(0x420000E9)
+
+/* FCS crypto service VAB/SDOS commands */
+#define ALTERA_SIP_SMC_ASYNC_FCS_RANDOM_NUMBER					(0x4200012C)
+#define ALTERA_SIP_SMC_ASYNC_FCS_RANDOM_NUMBER_EXT				(0x4200012D)
+#define ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION					(0x4200012E)
+#define ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT					(0x4200012F)
+#define ALTERA_SIP_SMC_ASYNC_FCS_SERVICE_REQUEST				(0x42000130)
+#define ALTERA_SIP_SMC_ASYNC_FCS_SEND_CERTIFICATE				(0x42000131)
+#define ALTERA_SIP_SMC_ASYNC_FCS_GET_PROVISION_DATA				(0x42000132)
+#define ALTERA_SIP_SMC_ASYNC_FCS_CNTR_SET_PREAUTH				(0x42000133)
+#define ALTERA_SIP_SMC_ASYNC_FCS_PSGSIGMA_TEARDOWN				(0x42000134)
+#define ALTERA_SIP_SMC_ASYNC_FCS_CHIP_ID					(0x42000135)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ATTESTATION_SUBKEY				(0x42000136)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ATTESTATION_MEASUREMENTS			(0x42000137)
+#define ALTERA_SIP_SMC_ASYNC_FCS_GET_ATTESTATION_CERT				(0x42000138)
+#define ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CERT_ON_RELOAD				(0x42000139)
+
+/* FCS crypto service session management commands */
+#define ALTERA_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION				(0x4200013A)
+#define ALTERA_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION				(0x4200013B)
+
+/* FCS crypto service key management commands */
+#define ALTERA_SIP_SMC_ASYNC_FCS_IMPORT_CS_KEY					(0x4200013C)
+#define ALTERA_SIP_SMC_ASYNC_FCS_EXPORT_CS_KEY					(0x4200013D)
+#define ALTERA_SIP_SMC_ASYNC_FCS_REMOVE_CS_KEY					(0x4200013E)
+#define ALTERA_SIP_SMC_ASYNC_FCS_GET_CS_KEY_INFO				(0x4200013F)
+#define ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CS_KEY					(0x42000167)
+
+/* FCS crypto service primitive commands */
+#define ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_INIT					(0x42000140)
+#define ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_UPDATE				(0x42000141)
+#define ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_FINALIZE				(0x42000142)
+#define ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_INIT				(0x42000143)
+#define ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_UPDATE				(0x42000144)
+#define ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_FINALIZE				(0x42000145)
+#define ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_SMMU_UPDATE				(0x42000146)
+#define ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_SMMU_FINALIZE			(0x42000147)
+#define ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_INIT				(0x42000148)
+#define ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_UPDATE				(0x42000149)
+#define ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_FINALIZE				(0x4200014A)
+#define ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_SMMU_UPDATE				(0x4200014B)
+#define ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_SMMU_FINALIZE			(0x4200014C)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_INIT				(0x4200014D)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_FINALIZE			(0x4200014E)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_INIT			(0x4200014F)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE			(0x42000150)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE			(0x42000151)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_UPDATE		(0x42000152)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_FINALIZE		(0x42000153)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_INIT			(0x42000154)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE			(0x42000155)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT		(0x42000156)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE		(0x42000157)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE		(0x42000158)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_UPDATE		(0x42000159)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_FINALIZE	(0x4200015A)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_INIT				(0x42000160)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_FINALIZE			(0x42000161)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_INIT				(0x42000162)
+#define ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_FINALIZE				(0x42000163)
+#define ALTERA_SIP_SMC_ASYNC_FCS_SDM_REMAPPER_CONFIG				(0x42000164)
+#define ALTERA_SIP_SMC_ASYNC_MCTP_MSG						(0x42000165)
+#define ALTERA_SIP_SMC_ASYNC_FCS_HKDF_REQUEST					(0x42000166)
+#define ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CS_KEY					(0x42000167)
+
+#define GET_CLIENT_ID(x)							(((x) & 0xF0) >> 4)
+#define GET_JOB_ID(x)								((x) & 0x0F)
+#endif	/* SIP_SVC_V3 */
+
 #endif /* SOCFPGA_SIP_SVC_H */
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index 91df934..b9c7b59 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -1,13 +1,15 @@
 /*
  * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
- * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
+#include <common/debug.h>
 #include <lib/mmio.h>
 
+#include "socfpga_plat_def.h"
 #include "socfpga_fcs.h"
 #include "socfpga_mailbox.h"
 #include "socfpga_sip_svc.h"
@@ -23,6 +25,267 @@
 static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
 static fcs_crypto_service_data fcs_ecdh_request_param;
 
+uint8_t fcs_send_cert_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mailbox_err 0x%x, status_word %d\n",
+		__func__, resp->err_code, resp->resp_data[0]);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->resp_data[0];
+
+	return ret_args_len;
+}
+
+uint8_t fcs_cntr_set_preauth_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mailbox_err 0x%x\n", __func__, resp->err_code);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+
+	return ret_args_len;
+}
+
+uint8_t fcs_get_attest_cert_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mailbox_err 0x%x, nbytes_ret %d\n",
+		__func__, resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
+
+	return ret_args_len;
+}
+
+uint8_t fcs_hkdf_request_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+
+	INFO("MBOX: %s: mbox_err 0x%x, hkdf_status 0x%x\n", __func__,
+		resp->err_code, resp->resp_data[0]);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->resp_data[0];
+
+	return ret_args_len;
+}
+
+uint8_t fcs_create_cert_reload_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mailbox_err 0x%x\n", __func__, resp->err_code);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+
+	return ret_args_len;
+}
+
+uint8_t fcs_cs_get_digest_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mbox_err  0x%x, nbytes_ret %d\n", __func__,
+		resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
+
+	return ret_args_len;
+}
+
+uint8_t fcs_cs_mac_verify_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d, verify_result 0x%x\n",
+		__func__, resp->err_code,
+		resp->rcvd_resp_len * MBOX_WORD_BYTE,
+		resp->resp_data[3]);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
+	ret_args[ret_args_len++] = resp->resp_data[3];
+
+	return ret_args_len;
+}
+
+uint8_t fcs_cs_hash_sign_req_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, len_words %d\n",
+			__func__, resp->resp_data[0], resp->resp_data[1],
+			resp->resp_data[2], resp->rcvd_resp_len);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
+
+	return ret_args_len;
+}
+
+uint8_t fcs_cs_hash_sig_verify_req_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, [3] 0x%x\n",
+			__func__, resp->resp_data[0], resp->resp_data[1],
+			resp->resp_data[2], resp->resp_data[3]);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
+
+	return ret_args_len;
+}
+
+uint8_t fcs_cs_aes_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+
+	INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__,
+		resp->err_code, resp->resp_data[3]);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->resp_data[3];
+
+	return ret_args_len;
+}
+
+uint8_t fcs_cs_data_sign_req_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %d\n", __func__,
+		resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
+
+	return ret_args_len;
+}
+
+uint8_t fcs_sdos_crypto_request_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mailbox_err 0x%x, nbytes_ret %d\n",
+		__func__, resp->err_code, resp->resp_data[3]);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	/* Encrypted/Decrypted data size written to the destination buffer */
+	ret_args[ret_args_len++] = resp->resp_data[3];
+
+	return ret_args_len;
+}
+
+uint8_t fcs_cs_get_public_key_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret %u\n",
+			__func__, resp->err_code,
+			resp->rcvd_resp_len * MBOX_WORD_BYTE);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
+
+	return ret_args_len;
+}
+
+uint8_t fcs_cs_data_sig_verify_req_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mbox_err 0x%x, nbytes_ret 0x%x\n",
+			__func__, resp->err_code, resp->rcvd_resp_len);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
+
+	return ret_args_len;
+}
+
+uint8_t fcs_cs_ecdh_request_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: [0] 0%x, [1] 0x%x, [2] 0x%x, len_words %d\n",
+			__func__, resp->resp_data[0], resp->resp_data[1],
+			resp->resp_data[2], resp->rcvd_resp_len);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
+
+	return ret_args_len;
+}
+
 bool is_size_4_bytes_aligned(uint32_t size)
 {
 	if ((size % MBOX_WORD_BYTE) != 0U) {
@@ -155,7 +418,8 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
-uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
+uint32_t intel_fcs_send_cert(uint32_t smc_fid, uint32_t trans_id,
+			     uint64_t addr, uint64_t size,
 					uint32_t *send_id)
 {
 	int status;
@@ -168,7 +432,17 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
+	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_SEND_CERTIFICATE) ?
+		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+					GET_JOB_ID(trans_id),
+					MBOX_CMD_VAB_SRC_CERT,
+					(uint32_t *) addr,
+					size / MBOX_WORD_BYTE,
+					MBOX_CMD_FLAG_CASUAL,
+					fcs_send_cert_cb,
+					NULL,
+					0U) :
+		mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
 				(uint32_t *)addr, size / MBOX_WORD_BYTE,
 				CMD_DIRECT);
 
@@ -195,7 +469,8 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
-uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
+uint32_t intel_fcs_cntr_set_preauth(uint32_t smc_fid, uint32_t trans_id,
+				    uint8_t counter_type, int32_t counter_value,
 					uint32_t test_bit, uint32_t *mbox_error)
 {
 	int status;
@@ -230,7 +505,18 @@
 	};
 
 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
-	status =  mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
+
+	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CNTR_SET_PREAUTH) ?
+			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+						  GET_JOB_ID(trans_id),
+						  MBOX_FCS_CNTR_SET_PREAUTH,
+						  (uint32_t *) &payload,
+						  payload_size,
+						  MBOX_CMD_FLAG_CASUAL,
+						  fcs_cntr_set_preauth_cb,
+						  NULL,
+						  0U) :
+			mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
 				  (uint32_t *) &payload, payload_size,
 				  CMD_CASUAL, NULL, NULL);
 
@@ -317,14 +603,18 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
-int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
+int intel_fcs_encryption_ext(uint32_t smc_fid, uint32_t trans_id,
+		uint32_t session_id, uint32_t context_id,
 		uint32_t src_addr, uint32_t src_size,
-		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
+		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error,
+		uint32_t smmu_src_addr, uint32_t smmu_dst_addr)
 {
 	int status;
 	uint32_t payload_size;
 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
+	uint32_t src_addr_sdm = src_addr;
+	uint32_t dst_addr_sdm = dst_addr;
 
 	if ((dst_size == NULL) || (mbox_error == NULL)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -339,19 +629,35 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	/* On the Agilex5 platform, we will use the SMMU payload address */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	src_addr_sdm = smmu_src_addr;
+	dst_addr_sdm = smmu_dst_addr;
+#endif
+
 	fcs_encrypt_ext_payload payload = {
 		session_id,
 		context_id,
 		FCS_CRYPTION_CRYPTO_HEADER,
-		src_addr,
+		src_addr_sdm,
 		src_size,
-		dst_addr,
+		dst_addr_sdm,
 		*dst_size
 	};
 
 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
 
-	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
+	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) ?
+		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+					GET_JOB_ID(trans_id),
+					MBOX_FCS_ENCRYPT_REQ,
+					(uint32_t *) &payload,
+					payload_size,
+					MBOX_CMD_FLAG_INDIRECT,
+					fcs_sdos_crypto_request_cb,
+					NULL,
+					0U) :
+		mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
 				(uint32_t *) &payload, payload_size,
 				CMD_CASUAL, resp_data, &resp_len);
 
@@ -371,15 +677,20 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
-int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
+int intel_fcs_decryption_ext(uint32_t smc_fid, uint32_t trans_id,
+		uint32_t session_id, uint32_t context_id,
 		uint32_t src_addr, uint32_t src_size,
-		uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
+		uint32_t dst_addr, uint32_t *dst_size,
+		uint32_t *mbox_error, uint64_t owner_id,
+		uint32_t smmu_src_addr, uint32_t smmu_dst_addr)
 {
 	int status;
 	uintptr_t id_offset;
 	uint32_t payload_size;
 	uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
 	uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
+	uint32_t src_addr_sdm = src_addr;
+	uint32_t dst_addr_sdm = dst_addr;
 
 	if ((dst_size == NULL) || (mbox_error == NULL)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -394,6 +705,12 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	/* On the Agilex5 platform, we will use the SMMU payload address */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	src_addr_sdm = smmu_src_addr;
+	dst_addr_sdm = smmu_dst_addr;
+#endif
+
 	inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
 	fcs_decrypt_ext_payload payload = {
@@ -402,15 +719,25 @@
 		FCS_CRYPTION_CRYPTO_HEADER,
 		{mmio_read_32(id_offset),
 		mmio_read_32(id_offset + MBOX_WORD_BYTE)},
-		src_addr,
+		src_addr_sdm,
 		src_size,
-		dst_addr,
+		dst_addr_sdm,
 		*dst_size
 	};
 
 	payload_size = sizeof(payload) / MBOX_WORD_BYTE;
 
-	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
+	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) ?
+		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+					GET_JOB_ID(trans_id),
+					MBOX_FCS_DECRYPT_REQ,
+					(uint32_t *) &payload,
+					payload_size,
+					MBOX_CMD_FLAG_INDIRECT,
+					fcs_sdos_crypto_request_cb,
+					NULL,
+					0U) :
+		mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
 				(uint32_t *) &payload, payload_size,
 				CMD_CASUAL, resp_data, &resp_len);
 
@@ -567,7 +894,8 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
-int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
+int intel_fcs_get_attestation_cert(uint32_t smc_fid, uint32_t trans_id,
+			uint32_t cert_request, uint64_t dst_addr,
 			uint32_t *dst_size, uint32_t *mbox_error)
 {
 	int status;
@@ -586,7 +914,17 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
+	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_ATTESTATION_CERT) ?
+		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+					GET_JOB_ID(trans_id),
+					MBOX_GET_ATTESTATION_CERT,
+					(uint32_t *) &cert_request,
+					1U,
+					MBOX_CMD_FLAG_CASUAL,
+					fcs_get_attest_cert_cb,
+					(uint32_t *)dst_addr,
+					2U) :
+		mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
 			(uint32_t *) dst_addr, &ret_size);
 
@@ -601,8 +939,8 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
-int intel_fcs_create_cert_on_reload(uint32_t cert_request,
-			uint32_t *mbox_error)
+int intel_fcs_create_cert_on_reload(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t cert_request, uint32_t *mbox_error)
 {
 	int status;
 
@@ -615,7 +953,17 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
+	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CERT_ON_RELOAD) ?
+		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+					GET_JOB_ID(trans_id),
+					MBOX_CREATE_CERT_ON_RELOAD,
+					(uint32_t *) &cert_request,
+					1U,
+					MBOX_CMD_FLAG_CASUAL,
+					fcs_create_cert_reload_cb,
+					NULL,
+					0U) :
+		mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
 			(uint32_t *) &cert_request, 1U, CMD_CASUAL,
 			NULL, NULL);
 
@@ -851,11 +1199,12 @@
 				mbox_error);
 }
 
-int intel_fcs_get_digest_update_finalize(uint32_t session_id,
-				uint32_t context_id, uint32_t src_addr,
-				uint32_t src_size, uint64_t dst_addr,
-				uint32_t *dst_size, uint8_t is_finalised,
-				uint32_t *mbox_error)
+int intel_fcs_get_digest_update_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
+				uint32_t src_addr, uint32_t src_size,
+				uint64_t dst_addr, uint32_t *dst_size,
+				uint8_t is_finalised, uint32_t *mbox_error,
+				uint32_t smmu_src_addr)
 {
 	int status;
 	uint32_t i;
@@ -928,12 +1277,29 @@
 		i++;
 	}
 	/* Data source address and size */
+
+	/* On the Agilex5 platform, we will use the SMMU payload address */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	payload[i] = smmu_src_addr;
+#else
 	payload[i] = src_addr;
+#endif
 	i++;
 	payload[i] = src_size;
 	i++;
 
-	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
+	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_UPDATE) ||
+		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_FINALIZE)) ?
+			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+						   GET_JOB_ID(trans_id),
+						   MBOX_FCS_GET_DIGEST_REQ,
+						   payload,
+						   i,
+						   MBOX_CMD_FLAG_CASUAL,
+						   fcs_cs_get_digest_cb,
+						   (uint32_t *)dst_addr,
+						   2U) :
+			mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
 				payload, i, CMD_CASUAL,
 				(uint32_t *) dst_addr, &resp_len);
 
@@ -1061,11 +1427,12 @@
 				mbox_error);
 }
 
-int intel_fcs_mac_verify_update_finalize(uint32_t session_id,
-				uint32_t context_id, uint32_t src_addr,
-				uint32_t src_size, uint64_t dst_addr,
-				uint32_t *dst_size, uint32_t data_size,
-				uint8_t is_finalised, uint32_t *mbox_error)
+int intel_fcs_mac_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
+				uint32_t src_addr, uint32_t src_size,
+				uint64_t dst_addr, uint32_t *dst_size,
+				uint32_t data_size, uint8_t is_finalised,
+				uint32_t *mbox_error, uint64_t smmu_src_addr)
 {
 	int status;
 	uint32_t i;
@@ -1149,8 +1516,13 @@
 				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
 		i++;
 	}
+
 	/* Data source address and size */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	payload[i] = (uint32_t)smmu_src_addr;
+#else
 	payload[i] = src_addr;
+#endif
 	i++;
 	payload[i] = data_size;
 	i++;
@@ -1171,7 +1543,18 @@
 		i += (src_size - data_size) / MBOX_WORD_BYTE;
 	}
 
-	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
+	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_UPDATE) ||
+		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_FINALIZE)) ?
+			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+						   GET_JOB_ID(trans_id),
+						   MBOX_FCS_MAC_VERIFY_REQ,
+						   payload,
+						   i,
+						   MBOX_CMD_FLAG_CASUAL,
+						   fcs_cs_mac_verify_cb,
+						   (uint32_t *)dst_addr,
+						   2U) :
+			mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
 				payload, i, CMD_CASUAL,
 				(uint32_t *) dst_addr, &resp_len);
 
@@ -1336,7 +1719,8 @@
 				mbox_error);
 }
 
-int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
+int intel_fcs_ecdsa_hash_sign_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t *dst_size,
 				uint32_t *mbox_error)
@@ -1407,7 +1791,17 @@
 
 	i += src_size / MBOX_WORD_BYTE;
 
-	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
+	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_FINALIZE) ?
+			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+						   GET_JOB_ID(trans_id),
+						   MBOX_FCS_ECDSA_HASH_SIGN_REQ,
+						   payload,
+						   i,
+						   MBOX_CMD_FLAG_CASUAL,
+						   fcs_cs_hash_sign_req_cb,
+						   (uint32_t *)dst_addr,
+						   2U) :
+			mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
 			&resp_len);
 
@@ -1435,7 +1829,8 @@
 				mbox_error);
 }
 
-int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
+int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t smc_fid, uint32_t trans_id,
+					uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t *dst_size,
 				uint32_t *mbox_error)
@@ -1451,8 +1846,8 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
-	fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
+	if ((fcs_ecdsa_hash_sig_verify_param.session_id != session_id) ||
+	    (fcs_ecdsa_hash_sig_verify_param.context_id != context_id)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
@@ -1508,7 +1903,18 @@
 
 	i += (src_size / MBOX_WORD_BYTE);
 
+	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE) ?
+		mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+					GET_JOB_ID(trans_id),
+					MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
+					payload,
+					i,
+					MBOX_CMD_FLAG_CASUAL,
+					fcs_cs_hash_sig_verify_req_cb,
+					(uint32_t *)dst_addr,
+					2U) :
+
-	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
+		mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
 			&resp_len);
 
@@ -1537,11 +1943,12 @@
 				mbox_error);
 }
 
-int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id,
-				uint32_t context_id, uint32_t src_addr,
-				uint32_t src_size, uint64_t dst_addr,
-				uint32_t *dst_size, uint8_t is_finalised,
-				uint32_t *mbox_error)
+int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
+				uint32_t src_addr, uint32_t src_size,
+				uint64_t dst_addr, uint32_t *dst_size,
+				uint8_t is_finalised, uint32_t *mbox_error,
+				uint64_t smmu_src_addr)
 {
 	int status;
 	int i;
@@ -1608,11 +2015,27 @@
 	}
 
 	/* Data source address and size */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	payload[i] = (uint32_t)smmu_src_addr;
+#else
 	payload[i] = src_addr;
+#endif
 	i++;
 	payload[i] = src_size;
 	i++;
-	status = mailbox_send_cmd(MBOX_JOB_ID,
+
+	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE) ||
+		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE)) ?
+			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+						GET_JOB_ID(trans_id),
+						MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
+						payload,
+						i,
+						MBOX_CMD_FLAG_CASUAL,
+						fcs_cs_data_sign_req_cb,
+						(uint32_t *)dst_addr,
+						2U) :
+			mailbox_send_cmd(MBOX_JOB_ID,
 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
 			i, CMD_CASUAL, (uint32_t *) dst_addr,
 			&resp_len);
@@ -1737,11 +2160,12 @@
 				mbox_error);
 }
 
-int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
-				uint32_t context_id, uint32_t src_addr,
-				uint32_t src_size, uint64_t dst_addr,
-				uint32_t *dst_size, uint32_t data_size,
-				uint8_t is_finalised, uint32_t *mbox_error)
+int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
+				uint32_t src_addr, uint32_t src_size,
+				uint64_t dst_addr, uint32_t *dst_size,
+				uint32_t data_size, uint8_t is_finalised,
+				uint32_t *mbox_error, uint64_t smmu_src_addr)
 {
 	int status;
 	uint32_t i;
@@ -1825,7 +2249,12 @@
 	}
 
 	/* Data source address and size */
+	/* On the Agilex5 platform, the SMMU remapped address is used */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	payload[i] = smmu_src_addr;
+#else
 	payload[i] = src_addr;
+#endif
 	i++;
 	payload[i] = data_size;
 	i++;
@@ -1846,7 +2275,18 @@
 		i += (src_size - data_size) / MBOX_WORD_BYTE;
 	}
 
-	status = mailbox_send_cmd(MBOX_JOB_ID,
+	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE) ||
+		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE)) ?
+			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+						GET_JOB_ID(trans_id),
+						MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
+						payload,
+						i,
+						MBOX_CMD_FLAG_CASUAL,
+						fcs_cs_data_sig_verify_req_cb,
+						(uint32_t *)dst_addr,
+						2U) :
+			mailbox_send_cmd(MBOX_JOB_ID,
 			MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
 			CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
 
@@ -2010,7 +2450,8 @@
 				mbox_error);
 }
 
-int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
+int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
 				uint64_t dst_addr, uint32_t *dst_size,
 				uint32_t *mbox_error)
 {
@@ -2054,7 +2495,18 @@
 			INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
 	i++;
 
-	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
+	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_FINALIZE) ?
+			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+						GET_JOB_ID(trans_id),
+						MBOX_FCS_ECDSA_GET_PUBKEY,
+						payload,
+						i,
+						MBOX_CMD_FLAG_CASUAL,
+						fcs_cs_get_public_key_cb,
+						(uint32_t *)dst_addr,
+						2U) :
+			mailbox_send_cmd(MBOX_JOB_ID,
+					 MBOX_FCS_ECDSA_GET_PUBKEY,
 			payload, i, CMD_CASUAL,
 			(uint32_t *) dst_addr, &ret_size);
 
@@ -2082,7 +2534,8 @@
 				mbox_error);
 }
 
-int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
+int intel_fcs_ecdh_request_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
 				uint32_t src_addr, uint32_t src_size,
 				uint64_t dst_addr, uint32_t *dst_size,
 				uint32_t *mbox_error)
@@ -2098,7 +2551,6 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-
 	if (fcs_ecdh_request_param.session_id != session_id ||
 		fcs_ecdh_request_param.context_id != context_id) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -2110,10 +2562,9 @@
 	}
 
 	dst_size_check = *dst_size;
-	if ((dst_size_check > FCS_MAX_DATA_SIZE ||
-		dst_size_check < FCS_MIN_DATA_SIZE) ||
-		(src_size > FCS_MAX_DATA_SIZE ||
-		src_size < FCS_MIN_DATA_SIZE)) {
+
+	if ((dst_size_check > FCS_MAX_DATA_SIZE || dst_size_check < FCS_MIN_DATA_SIZE) ||
+	    (src_size > FCS_MAX_DATA_SIZE || src_size < FCS_MIN_DATA_SIZE)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
@@ -2150,7 +2601,17 @@
 		(void *) pubkey, src_size / MBOX_WORD_BYTE);
 	i += src_size / MBOX_WORD_BYTE;
 
-	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
+	status = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_FINALIZE) ?
+			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+						  GET_JOB_ID(trans_id),
+						  MBOX_FCS_ECDH_REQUEST,
+						  payload,
+						  i,
+						  MBOX_CMD_FLAG_CASUAL,
+						  fcs_cs_ecdh_request_cb,
+						  (uint32_t *)dst_addr,
+						  2U) :
+			mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
 			payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
 			&resp_len);
 
@@ -2189,13 +2650,19 @@
 	}
 
 	/*
-	 * Check if not ECB, CBC and CTR mode, addr ptr is NULL.
-	 * Return "Reject" status
+	 * Check if not ECB, CBC and CTR, GCM and GCM-GHASH mode (only for Agilex5),
+	 * addr ptr is NULL. Return "Reject" status
 	 */
 	if ((param_addr_ptr == NULL) ||
-		(((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_ECB_MODE) &&
-		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CBC_MODE) &&
-		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CTR_MODE))) {
+	    (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_ECB_MODE) &&
+	    ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CBC_MODE) &&
+	    ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CTR_MODE)
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	    &&
+	    ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_GCM_MODE) &&
+	    ((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_GCM_GHASH_MODE)
+#endif
+	    )){
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
@@ -2204,7 +2671,9 @@
 	 * Check CBC/CTR here and limit to size 28 bytes
 	 */
 	if ((((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CBC_MODE) ||
-		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE)) &&
+		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_CTR_MODE) ||
+		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_GCM_MODE) ||
+		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_GCM_GHASH_MODE)) &&
 		(param_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
@@ -2235,17 +2704,21 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
-int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
-				uint32_t context_id, uint64_t src_addr,
-				uint32_t src_size, uint64_t dst_addr,
-				uint32_t dst_size, uint8_t is_finalised,
-				uint32_t *send_id)
+int intel_fcs_aes_crypt_update_finalize(uint32_t smc_fid, uint32_t trans_id,
+				uint32_t session_id, uint32_t context_id,
+				uint64_t src_addr, uint32_t src_size,
+				uint64_t dst_addr, uint32_t dst_size,
+				uint32_t aad_size, uint8_t is_finalised,
+				uint32_t *send_id, uint64_t smmu_src_addr,
+				uint64_t smmu_dst_addr)
 {
 	int status;
 	int i;
 	uint32_t flag;
 	uint32_t crypto_header;
 	uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
+	uint32_t src_addr_sdm = (uint32_t)src_addr;
+	uint32_t dst_addr_sdm = (uint32_t)dst_addr;
 
 	if (fcs_aes_init_payload.session_id != session_id ||
 		fcs_aes_init_payload.context_id != context_id) {
@@ -2297,7 +2770,7 @@
 	i++;
 
 	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
-		FCS_CS_FIELD_FLAG_INIT) {
+	    (FCS_CS_FIELD_FLAG_INIT)) {
 		fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
 		i++;
 
@@ -2314,18 +2787,41 @@
 		i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
 	}
 
-	fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
+	/* On the Agilex5 platform, we will use the SMMU payload address */
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	src_addr_sdm = (uint32_t)smmu_src_addr;
+	dst_addr_sdm = (uint32_t)smmu_dst_addr;
+#endif
+
+	fcs_aes_crypt_payload[i] = src_addr_sdm;
 	i++;
 	fcs_aes_crypt_payload[i] = src_size;
 	i++;
-	fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
+	fcs_aes_crypt_payload[i] = dst_addr_sdm;
 	i++;
 	fcs_aes_crypt_payload[i] = dst_size;
 	i++;
 
-	status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
-					fcs_aes_crypt_payload, i,
-					CMD_INDIRECT);
+	/* Additional Authenticated Data size */
+	if (aad_size > 0) {
+		fcs_aes_crypt_payload[i] = aad_size;
+		i++;
+	}
+
+	status = ((smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_UPDATE) ||
+		  (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_FINALIZE)) ?
+			mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+						   GET_JOB_ID(trans_id),
+						   MBOX_FCS_AES_CRYPT_REQ,
+						   fcs_aes_crypt_payload,
+						   i,
+						   MBOX_CMD_FLAG_INDIRECT,
+						   fcs_cs_aes_cb,
+						   NULL,
+						   0U) :
+			mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
+					fcs_aes_crypt_payload, i, CMD_INDIRECT);
+
 
 	if (is_finalised != 0U) {
 		memset((void *)&fcs_aes_init_payload, 0,
@@ -2338,3 +2834,77 @@
 
 	return INTEL_SIP_SMC_STATUS_OK;
 }
+
+int intel_fcs_hkdf_request(uint32_t smc_fid, uint32_t trans_id,
+			   uint32_t session_id, uint32_t step_type,
+			   uint32_t mac_mode, uint32_t src_addr,
+			   uint32_t key_uid, uint32_t op_key_size)
+{
+	int status;
+	uint32_t i = 0;
+	uintptr_t inputdata;
+	uint32_t payload[FCS_HKDF_REQUEST_DATA_SIZE] = {0U};
+
+	if (!is_address_in_ddr_range(src_addr, FCS_HKDF_REQUEST_DATA_SIZE)) {
+		ERROR("MBOX: %s: source addr not in the DDR range\n", __func__);
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	/* Prepare command payload */
+
+	/* Session ID */
+	payload[i] = session_id;
+	i++;
+
+	/* Reserved, 8 bytes */
+	payload[i] = 0;
+	i++;
+
+	payload[i] = 0;
+	i++;
+
+	/* HKDF step type */
+	payload[i] = step_type;
+	i++;
+
+	/* MAC mode/PRF */
+	payload[i] = mac_mode;
+	i++;
+
+	/* Complete input data, 1st input data len + its data + 2nd input data len + its data. */
+	inputdata = src_addr;
+	memcpy_s((uint8_t *)&payload[i], FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t),
+		(uint8_t *)inputdata, FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t));
+
+	i += FCS_HKDF_KEY_DATA_SIZE / sizeof(uint32_t);
+
+	/* Key UID */
+	payload[i] = key_uid;
+	i++;
+
+	/* Pointer to size of output key object */
+	inputdata = inputdata + FCS_HKDF_KEY_DATA_SIZE;
+
+	/* Output Key object */
+	memcpy_s(&payload[i], op_key_size / sizeof(uint32_t), (void *)inputdata,
+		op_key_size / sizeof(uint32_t));
+
+	i += op_key_size / sizeof(uint32_t);
+
+	status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(trans_id),
+					GET_JOB_ID(trans_id),
+					MBOX_FCS_HKDF_REQUEST,
+					payload,
+					i,
+					MBOX_CMD_FLAG_CASUAL,
+					fcs_hkdf_request_cb,
+					NULL,
+					0U);
+
+	if (status < 0) {
+		ERROR("MBOX: %s: status %d\n", __func__, status);
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 69f0008..3b3b479 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -1,11 +1,12 @@
 /*
  * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
- * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <lib/mmio.h>
+#include <lib/spinlock.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
 #include <platform_def.h>
@@ -15,6 +16,34 @@
 #include "socfpga_sip_svc.h"
 #include "socfpga_system_manager.h"
 
+#if SIP_SVC_V3
+/* Function prototypes */
+void mailbox_init_v3(void);
+static int mailbox_response_handler_fsm(void);
+static inline void mailbox_free_cmd_desc(sdm_command_t *cmd_desc);
+static sdm_response_t *mailbox_get_resp_desc(uint8_t client_id, uint8_t job_id,
+					     uint8_t *index);
+static sdm_command_t *mailbox_get_cmd_desc(uint8_t client_id, uint8_t job_id);
+static inline void mailbox_free_resp_desc(uint8_t index);
+static sdm_command_t *mailbox_get_free_cmd_desc(void);
+static sdm_response_t *mailbox_get_resp_desc_cid(uint8_t client_id,
+						 uint8_t *index);
+static int mailbox_read_response_v3(uint8_t client_id, uint8_t *job_id,
+				    uint32_t *header, uint32_t *resp,
+				    uint32_t *resp_len,
+				    uint8_t ignore_client_id);
+static int mailbox_poll_response_v3(uint8_t client_id, uint8_t job_id,
+				    uint32_t *resp, unsigned int *resp_len,
+				    uint32_t urgent);
+
+static spinlock_t mbox_db_lock;		/* Mailbox service data base lock */
+static spinlock_t mbox_write_lock;	/* Hardware mailbox FIFO write lock */
+static spinlock_t mbox_read_lock;	/* Hardware mailbox FIFO read lock */
+
+static mailbox_service_t mbox_svc;	/* Mailbox service data base */
+static uint8_t async_v1_job_id;
+#endif /* #if SIP_SVC_V3 */
+
 static mailbox_payload_t mailbox_resp_payload;
 static mailbox_container_t mailbox_resp_ctr = {0, 0, &mailbox_resp_payload};
 
@@ -34,13 +63,13 @@
 
 static int wait_for_mailbox_cmdbuf_empty(uint32_t cin)
 {
-	unsigned int timeout = 200U;
+	unsigned int timeout = 20000U;
 
 	do {
 		if (is_mailbox_cmdbuf_empty(cin)) {
 			break;
 		}
-		mdelay(10U);
+		udelay(50U);
 	} while (--timeout != 0U);
 
 	if (timeout == 0U) {
@@ -54,7 +83,9 @@
 				    uint32_t data,
 				    bool *is_doorbell_triggered)
 {
-	unsigned int timeout = 100U;
+	unsigned int timeout = 20000U;
+
+	VERBOSE("MBOX: 0x%x\n", data);
 
 	do {
 		if (is_mailbox_cmdbuf_full(*cin)) {
@@ -63,7 +94,7 @@
 					      MBOX_DOORBELL_TO_SDM, 1U);
 				*is_doorbell_triggered = true;
 			}
-			mdelay(10U);
+			udelay(50U);
 		} else {
 			mmio_write_32(MBOX_ENTRY_TO_ADDR(CMD, (*cin)++), data);
 			*cin %= MBOX_CMD_BUFFER_SIZE;
@@ -84,6 +115,11 @@
 	return MBOX_RET_OK;
 }
 
+/*
+ * Function description: Write the command header, and its payload one by one
+ * into the mailbox command buffer. Along with this, check for mailbox buffer
+ * full condition and trigger doorbell to SDM if the command buffer is full.
+ */
 static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
 					unsigned int len)
 {
@@ -92,15 +128,21 @@
 	int ret;
 	bool is_doorbell_triggered = false;
 
+#if SIP_SVC_V3
+	spin_lock(&mbox_write_lock);
+#endif
+
 	cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN);
 	sdm_read_offset = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
 
+	/* Write the command header here */
 	ret = write_mailbox_cmd_buffer(&cmd_free_offset, sdm_read_offset,
 				       header_cmd, &is_doorbell_triggered);
 	if (ret != 0) {
 		goto restart_mailbox;
 	}
 
+	/* Write the payload here w.r.to args and its len - one by one. */
 	for (i = 0U; i < len; i++) {
 		is_doorbell_triggered = false;
 		ret = write_mailbox_cmd_buffer(&cmd_free_offset,
@@ -113,6 +155,9 @@
 
 	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
 
+#if SIP_SVC_V3
+	spin_unlock(&mbox_write_lock);
+#endif
 	return MBOX_RET_OK;
 
 restart_mailbox:
@@ -129,12 +174,21 @@
 		}
 	}
 
+#if SIP_SVC_V3
+	spin_unlock(&mbox_write_lock);
+#endif
 	return MBOX_TIMEOUT;
 }
 
 int mailbox_read_response(unsigned int *job_id, uint32_t *response,
 				unsigned int *resp_len)
 {
+#if SIP_SVC_V3
+	return mailbox_read_response_v3(MBOX_ATF_CLIENT_ID,
+					(uint8_t *)job_id, NULL,
+					response, resp_len,
+					0);
+#else
 	uint32_t rin;
 	uint32_t rout;
 	uint32_t resp_data;
@@ -174,13 +228,23 @@
 
 		return MBOX_RET_OK;
 	}
+
 	return MBOX_NO_RESPONSE;
+#endif
 }
 
 int mailbox_read_response_async(unsigned int *job_id, uint32_t *header,
 				uint32_t *response, unsigned int *resp_len,
 				uint8_t ignore_client_id)
 {
+#if SIP_SVC_V3
+	/* Just to avoid the build warning */
+	(void)mailbox_resp_ctr;
+	return mailbox_read_response_v3(MBOX_ATF_CLIENT_ID,
+					(uint8_t *)job_id, header,
+					response, resp_len,
+					ignore_client_id);
+#else
 	uint32_t rin;
 	uint32_t rout;
 	uint32_t resp_data;
@@ -220,7 +284,6 @@
 					return MBOX_WRONG_ID;
 				}
 			}
-
 			*job_id = MBOX_RESP_JOB_ID(resp_data);
 			ret_resp_len = MBOX_RESP_LEN(resp_data);
 			mailbox_resp_ctr.payload->header = resp_data;
@@ -272,11 +335,16 @@
 
 	*resp_len = 0;
 	return (mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) ? MBOX_BUSY : MBOX_NO_RESPONSE;
+#endif
 }
 
 int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
-				unsigned int *resp_len)
+			  unsigned int *resp_len)
 {
+#if SIP_SVC_V3
+	return mailbox_poll_response_v3(MBOX_ATF_CLIENT_ID, (uint8_t)job_id,
+					response, resp_len, urgent);
+#else
 	unsigned int timeout = 40U;
 	unsigned int sdm_loop = 255U;
 	unsigned int ret_resp_len;
@@ -285,7 +353,6 @@
 	uint32_t resp_data;
 
 	while (sdm_loop != 0U) {
-
 		do {
 			if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)
 				== 1U) {
@@ -310,7 +377,7 @@
 			}
 
 			mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
-			INFO("Error: Mailbox did not get UA");
+			ERROR("MBOX: Mailbox did not get UA");
 			return MBOX_RET_ERROR;
 		}
 
@@ -324,13 +391,21 @@
 			rout %= MBOX_RESP_BUFFER_SIZE;
 			mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
 
-			if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID
-				|| MBOX_RESP_JOB_ID(resp_data) != job_id) {
+			if ((MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) ||
+			    (MBOX_RESP_JOB_ID(resp_data) != job_id)) {
 				continue;
 			}
 
+			/* Get the return response len from the response header. */
 			ret_resp_len = MBOX_RESP_LEN(resp_data);
 
+			/* Print the response header. */
+			VERBOSE("MBOX: RespHdr: cid %d, jid %d, len %d, err_code 0x%x\n",
+				MBOX_RESP_CLIENT_ID(resp_data),
+				MBOX_RESP_JOB_ID(resp_data),
+				MBOX_RESP_LEN(resp_data),
+				MBOX_RESP_ERR(resp_data));
+
 			if (iterate_resp(ret_resp_len, response, resp_len)
 				!= MBOX_RET_OK) {
 				return MBOX_TIMEOUT;
@@ -349,6 +424,7 @@
 
 	INFO("Timed out waiting for SDM\n");
 	return MBOX_TIMEOUT;
+#endif
 }
 
 int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
@@ -366,8 +442,7 @@
 
 		if ((resp_buf != NULL) && (resp_len != NULL)
 			&& (*resp_len != 0U)) {
-			*(resp_buf + total_resp_len)
-					= resp_data;
+			*(resp_buf + total_resp_len) = resp_data;
 			*resp_len = *resp_len - 1;
 			total_resp_len++;
 		}
@@ -417,6 +492,9 @@
 		return status;
 	}
 
+#if SIP_SVC_V3
+	async_v1_job_id = (uint8_t)*job_id;
+#endif
 	*job_id = (*job_id + 1U) % MBOX_MAX_IND_JOB_ID;
 
 	return MBOX_RET_OK;
@@ -433,9 +511,7 @@
 					MBOX_STATUS_UA_MASK;
 		mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
 		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
-	}
-
-	else {
+	} else {
 		status = fill_mailbox_circular_buffer(
 			MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
 			MBOX_JOB_ID_CMD(job_id) |
@@ -460,12 +536,12 @@
 
 void mailbox_set_int(uint32_t interrupt)
 {
-
-	mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) |
+	mmio_write_32(MBOX_OFFSET+MBOX_INT,
+			MBOX_COE_BIT(interrupt) |
+			MBOX_RIE_BIT(interrupt) |
 			MBOX_UAE_BIT(interrupt));
 }
 
-
 void mailbox_set_qspi_open(void)
 {
 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
@@ -606,6 +682,7 @@
 
 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
 			MBOX_INT_FLAG_UAE);
+
 	mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
 	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
 
@@ -616,8 +693,16 @@
 		return status;
 	}
 
+#if SIP_SVC_V3
+	/* Initialize the mailbox version3 implementation, and in V3 we
+	 * are interested in only RIE interrupt
+	 */
+	mailbox_init_v3();
+	mailbox_set_int(MBOX_INT_FLAG_RIE);
+#else
 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
 			MBOX_INT_FLAG_UAE);
+#endif
 
 	return MBOX_RET_OK;
 }
@@ -730,3 +815,693 @@
 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_SAFE_INJECT_SEU_ERR, arg, len,
 			CMD_CASUAL, NULL, NULL);
 }
+
+#if SIP_SVC_V3
+static int mailbox_fill_cmd_desc(uint8_t client_id, uint8_t job_id,
+				 uint32_t *resp_buff)
+{
+	sdm_command_t *cmd_desc = NULL;
+
+	/* Get a free command descriptor */
+	cmd_desc = mailbox_get_free_cmd_desc();
+	if (cmd_desc == NULL) {
+		return MBOX_BUFFER_FULL;
+	}
+
+	/* Record all the given values for the command. */
+	cmd_desc->client_id = client_id;
+	cmd_desc->job_id = job_id;
+	cmd_desc->cb = NULL;
+	cmd_desc->cb_args = resp_buff;
+	cmd_desc->cb_args_len = 0U;
+
+	return MBOX_RET_OK;
+}
+
+/* Returns the command descriptor based on the client and job ID. */
+static sdm_command_t *mailbox_get_cmd_desc(uint8_t client_id, uint8_t job_id)
+{
+	spin_lock(&mbox_db_lock);
+	for (uint32_t count = 0; count < MBOX_SVC_CMD_QUEUE_SIZE; count++) {
+		if ((mbox_svc.cmd_queue[count].client_id == client_id) &&
+		    (mbox_svc.cmd_queue[count].job_id == job_id) &&
+		    (mbox_svc.cmd_queue[count].flags & MBOX_SVC_CMD_IS_USED)) {
+			spin_unlock(&mbox_db_lock);
+			return &(mbox_svc.cmd_queue[count]);
+		}
+	}
+
+	spin_unlock(&mbox_db_lock);
+	VERBOSE("MBOX: Command descriptor not found for cid %d, jid %d\n",
+		client_id, job_id);
+
+	return NULL;
+}
+
+/* Returns the response descriptor based on only client ID. */
+static sdm_response_t *mailbox_get_resp_desc_cid(uint8_t client_id, uint8_t *index)
+{
+	spin_lock(&mbox_db_lock);
+
+	for (uint32_t count = 0; count < MBOX_SVC_RESP_QUEUE_SIZE; count++) {
+		if ((mbox_svc.resp_queue[count].client_id == client_id) &&
+		    (mbox_svc.resp_queue[count].flags & FLAG_SDM_RESPONSE_IS_VALID)) {
+			*index = count;
+			/*
+			 * Once we get the valid response descriptor, get the
+			 * job ID and mark up the bitmaps.
+			 */
+			uint8_t job_id = mbox_svc.resp_queue[count].job_id;
+			uint8_t transaction_id = MBOX_GET_TRANS_ID(client_id, job_id);
+
+			mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
+				~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
+			mbox_svc.interrupt_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
+				~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
+			spin_unlock(&mbox_db_lock);
+			return &(mbox_svc.resp_queue[count]);
+		}
+	}
+
+	spin_unlock(&mbox_db_lock);
+	VERBOSE("MBOX: Response descriptor not found for cid %d\n", client_id);
+
+	return NULL;
+}
+
+/* Returns the response descriptor based on the client and job ID. */
+static sdm_response_t *mailbox_get_resp_desc(uint8_t client_id, uint8_t job_id, uint8_t *index)
+{
+	spin_lock(&mbox_db_lock);
+	/*
+	 * Let's first check whether we have a response bitmap set for the given
+	 * client ID and job ID.
+	 */
+	uint8_t transaction_id = MBOX_GET_TRANS_ID(client_id, job_id);
+
+	if ((mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &
+		(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE))) == 0) {
+		spin_unlock(&mbox_db_lock);
+		VERBOSE("MBOX: Response bitmap not set for cid %d, jid %d, bitmap 0x%16lx\n",
+			client_id, job_id, mbox_svc.received_bitmap[transaction_id / 64]);
+		return NULL;
+	}
+
+	for (uint32_t count = 0; count < MBOX_SVC_RESP_QUEUE_SIZE; count++) {
+		if (mbox_svc.resp_queue[count].flags & FLAG_SDM_RESPONSE_IS_VALID) {
+			if ((mbox_svc.resp_queue[count].client_id == client_id) &&
+			    (mbox_svc.resp_queue[count].job_id == job_id)) {
+				*index = count;
+				mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
+					~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
+				mbox_svc.interrupt_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
+					~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
+				spin_unlock(&mbox_db_lock);
+				return &(mbox_svc.resp_queue[count]);
+			}
+		}
+	}
+
+	spin_unlock(&mbox_db_lock);
+	VERBOSE("MBOX: Response descriptor not found for cid %d, jid %d\n",
+		client_id, job_id);
+
+	return NULL;
+}
+
+static int32_t mailbox_get_free_resp_desc(void)
+{
+	spin_lock(&mbox_db_lock);
+	static uint32_t free_index = MBOX_SVC_RESP_QUEUE_SIZE - 1;
+	uint32_t count = 0U, try = 0U;
+
+	for (try = 0; try < MBOX_SVC_RESP_QUEUE_SIZE; try++) {
+		free_index = (free_index + 1) % MBOX_SVC_RESP_QUEUE_SIZE;
+		if ((mbox_svc.resp_queue[free_index].flags &
+			FLAG_SDM_RESPONSE_IS_USED) != 0U) {
+			count = free_index;
+			spin_unlock(&mbox_db_lock);
+			return count;
+		}
+	}
+
+	/* No free descriptors are available */
+	spin_unlock(&mbox_db_lock);
+	VERBOSE("MBOX: No free response descriptors are available\n");
+
+	return MBOX_BUFFER_FULL;
+}
+
+static sdm_command_t *mailbox_get_free_cmd_desc(void)
+{
+	spin_lock(&mbox_db_lock);
+	static uint32_t free_index;
+
+	/* Rollover the command queue free index */
+	if (free_index == (MBOX_SVC_CMD_QUEUE_SIZE - 1)) {
+		free_index = 0U;
+	}
+
+	for (; free_index < MBOX_SVC_CMD_QUEUE_SIZE; free_index++) {
+		if ((mbox_svc.cmd_queue[free_index].flags &
+			MBOX_SVC_CMD_IS_USED) != 0U) {
+			mbox_svc.cmd_queue[free_index].flags |= MBOX_SVC_CMD_IS_USED;
+			spin_unlock(&mbox_db_lock);
+			return &(mbox_svc.cmd_queue[free_index]);
+		}
+	}
+
+	/* No free command descriptors are available */
+	spin_unlock(&mbox_db_lock);
+	VERBOSE("MBOX: No free command descriptors available\n");
+
+	return NULL;
+}
+
+static inline void mailbox_free_cmd_desc(sdm_command_t *cmd_desc)
+{
+	if (cmd_desc == NULL) {
+		return;
+	}
+
+	spin_lock(&mbox_db_lock);
+	memset((void *)cmd_desc, 0, sizeof(sdm_command_t));
+	spin_unlock(&mbox_db_lock);
+}
+
+static inline void mailbox_free_resp_desc(uint8_t index)
+{
+	if (index >= MBOX_SVC_RESP_QUEUE_SIZE) {
+		return;
+	}
+
+	spin_lock(&mbox_db_lock);
+	memset((void *)&mbox_svc.resp_queue[index], 0, sizeof(sdm_response_t));
+	spin_unlock(&mbox_db_lock);
+}
+
+/*
+ * This function serves the V1 _sync_read and _async_read functionality, and it
+ * is introduced as part of V3 framework to keep backward compatible with V1
+ * clients.
+ */
+static int mailbox_read_response_v3(uint8_t client_id, uint8_t *job_id,
+				    uint32_t *header, uint32_t *resp,
+				    uint32_t *resp_len,
+				    uint8_t ignore_client_id)
+{
+	uint8_t di = 0U;
+	int status = MBOX_RET_OK;
+	sdm_response_t *resp_desc = NULL;
+	sdm_command_t *cmd_desc = NULL;
+
+	/*
+	 * In the V1, the client ID is always MBOX_ATF_CLIENT_ID and in this
+	 * routine we will collect the response which only belongs to this
+	 * client ID. So safe to ignore this input.
+	 */
+	(void)ignore_client_id;
+
+	/* Clear the SDM doorbell interrupt */
+	if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U)
+		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
+
+	/* Fill the command descriptor index and get the same */
+	status = mailbox_fill_cmd_desc(client_id, async_v1_job_id, resp);
+	if (status != MBOX_RET_OK) {
+		return status;
+	}
+
+	cmd_desc = mailbox_get_cmd_desc(client_id, async_v1_job_id);
+
+	/* Get the response from SDM, just go through one cycle */
+	status = mailbox_response_handler_fsm();
+	if (status != MBOX_RET_OK) {
+		mailbox_free_cmd_desc(cmd_desc);
+		*resp_len = 0U;
+		return status;
+	}
+
+	/* Check the local response queue with the given client ID */
+	resp_desc = mailbox_get_resp_desc_cid(client_id, &di);
+	if (resp_desc == NULL) {
+		mailbox_free_cmd_desc(cmd_desc);
+		*resp_len = 0U;
+		return MBOX_NO_RESPONSE;
+	}
+
+	/* Update the received mailbox response length, job ID and header */
+	*job_id = resp_desc->job_id;
+	*resp_len = resp_desc->rcvd_resp_len;
+	if (header != NULL) {
+		*header = resp_desc->header;
+	}
+
+	/* Check the mailbox response error code */
+	if (MBOX_RESP_ERR(resp_desc->header) > 0U) {
+		INFO("MBOX: Error in async response: %x\n", resp_desc->header);
+		status = -MBOX_RESP_ERR(resp_desc->header);
+	}
+
+	/* Free up the response and command descriptors */
+	mailbox_free_resp_desc(di);
+	mailbox_free_cmd_desc(cmd_desc);
+
+	return status;
+}
+
+int mailbox_send_cmd_async_v3(uint8_t client_id, uint8_t job_id, uint32_t cmd,
+			      uint32_t *args, uint32_t args_len, uint8_t cmd_flag,
+			      sdm_command_callback cb, uint32_t *cb_args,
+			      uint32_t cb_args_len)
+{
+	int status = 0;
+	sdm_command_t *cmd_desc = NULL;
+
+	VERBOSE("MBOX: cid: %d, jid: %d, cmd: %d, cmd_flag: %d\n",
+		client_id, job_id, cmd, cmd_flag);
+
+	if (IS_CMD_SET(cmd_flag, URGENT)) {
+		mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
+		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
+	} else {
+		/* Get a free command descriptor */
+		cmd_desc = mailbox_get_free_cmd_desc();
+		if (cmd_desc == NULL) {
+			return MBOX_BUFFER_FULL;
+		}
+
+		/* Record all the given values for the command. */
+		cmd_desc->client_id = client_id;
+		cmd_desc->job_id = job_id;
+		cmd_desc->cb = cb;
+		cmd_desc->cb_args = cb_args;
+		cmd_desc->cb_args_len = cb_args_len;
+
+		/* Push the command to mailbox FIFO */
+		status = fill_mailbox_circular_buffer(
+					MBOX_FRAME_CMD_HEADER(client_id, job_id,
+					args_len, IS_CMD_SET(cmd_flag, INDIRECT), cmd),
+					args,
+					args_len);
+
+		if (status != MBOX_RET_OK) {
+			INFO("MBOX: Failed to push the command to mailbox FIFO\n");
+			/* Free the command descriptor. */
+			mailbox_free_cmd_desc(cmd_desc);
+		}
+	}
+
+	INFO("MBOX: %s: status: %d\n", __func__, status);
+
+	return status;
+}
+
+static int mailbox_poll_response_v3(uint8_t client_id, uint8_t job_id,
+				    uint32_t *resp, unsigned int *resp_len,
+				    uint32_t urgent)
+{
+	unsigned int timeout = 40U;
+	unsigned int sdm_loop = 255U;
+	bool is_cmd_desc_fill = false;
+	uint8_t di = 0U;
+	sdm_response_t *resp_desc = NULL;
+	sdm_command_t *cmd_desc = NULL;
+
+	while (sdm_loop != 0U) {
+		do {
+			if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)
+				== 1U) {
+				break;
+			}
+			mdelay(10U);
+		} while (--timeout != 0U);
+
+		if (timeout == 0U) {
+			INFO("%s: Timed out waiting for SDM intr\n", __func__);
+			break;
+		}
+
+		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
+
+		if ((urgent & 1U) != 0U) {
+			mdelay(5U);
+			if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
+				MBOX_STATUS_UA_MASK) ^
+				(urgent & MBOX_STATUS_UA_MASK)) {
+				mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
+				return MBOX_RET_OK;
+			}
+
+			mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
+			ERROR("MBOX: Mailbox did not get UA");
+			return MBOX_RET_ERROR;
+		}
+
+		/* Fill the command descriptor index and get the same. */
+		if (!is_cmd_desc_fill) {
+			if (mailbox_fill_cmd_desc(client_id, job_id, resp) !=
+				MBOX_RET_OK) {
+				return MBOX_BUFFER_FULL;
+			}
+
+			cmd_desc = mailbox_get_cmd_desc(client_id, job_id);
+			is_cmd_desc_fill = true;
+		}
+
+		/* Since it is sync call, will try to read till it time out */
+		(void)mailbox_response_handler_fsm();
+
+		/* Check the response queue with the given client ID and job ID */
+		resp_desc = mailbox_get_resp_desc(client_id, job_id, &di);
+		if (resp_desc != NULL) {
+			VERBOSE("%s: Resp received for cid %d, jid %d\n",
+				__func__, resp_desc->client_id, resp_desc->job_id);
+
+			uint16_t header = resp_desc->header;
+
+			/* Update the return response length */
+			if (resp_len != NULL) {
+				*resp_len = resp_desc->rcvd_resp_len;
+			}
+
+			/* Free the response and command descriptor */
+			mailbox_free_resp_desc(di);
+			mailbox_free_cmd_desc(cmd_desc);
+
+			if (MBOX_RESP_ERR(header) > 0U) {
+				INFO("%s: SDM err code: 0x%x\n", __func__,
+					MBOX_RESP_ERR(header));
+				return -MBOX_RESP_ERR(header);
+			}
+
+			VERBOSE("%s: MBOX_RET_OK\n", __func__);
+			return MBOX_RET_OK;
+		}
+		sdm_loop--;
+	}
+
+	INFO("%s: Timed out waiting for SDM\n", __func__);
+	return MBOX_TIMEOUT;
+}
+
+/* SDM response parser handler state machine. */
+static void mailbox_response_parser(void)
+{
+	int di = -1;		/* Descriptor index */
+	uint32_t rin;
+	uint32_t rout;
+
+	switch (mbox_svc.next_resp_state) {
+	case SRS_WAIT_FOR_RESP:
+	{
+		mbox_svc.resp_state = SRS_WAIT_FOR_RESP;
+
+		rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
+		rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
+		if (rin != rout) {
+			mbox_svc.next_resp_state = SRS_WAIT_FOR_HEADER;
+		}
+
+		break;
+	}
+
+	case SRS_WAIT_FOR_HEADER:
+	{
+		mbox_svc.resp_state = SRS_WAIT_FOR_HEADER;
+		uint32_t resp_hdr;
+		uint8_t trans_id = 0U;
+
+		rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
+		rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
+		if (rin != rout) {
+			/* Read the header and dequeue from the queue. */
+			resp_hdr = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
+			rout %= MBOX_RESP_BUFFER_SIZE;
+			mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
+
+			/* Allocate a new response descriptor */
+			di = mailbox_get_free_resp_desc();
+			if (di != -1) {
+				mbox_svc.curr_di = di;
+				mbox_svc.resp_queue[di].header = resp_hdr;
+				mbox_svc.resp_queue[di].client_id = MBOX_RESP_CLIENT_ID(resp_hdr);
+				mbox_svc.resp_queue[di].job_id = MBOX_RESP_JOB_ID(resp_hdr);
+				mbox_svc.resp_queue[di].resp_len = MBOX_RESP_LEN(resp_hdr);
+				mbox_svc.resp_queue[di].flags |= (FLAG_SDM_RESPONSE_IS_USED |
+								  FLAG_SDM_RESPONSE_IS_IN_PROGRESS);
+				mbox_svc.resp_queue[di].err_code = MBOX_RESP_ERR(resp_hdr);
+				trans_id = MBOX_RESP_TRANSACTION_ID(resp_hdr);
+
+				VERBOSE("MBOX: Resp Hdr: cid %d, jid %d, len %d, err_code 0x%x\n",
+					mbox_svc.resp_queue[di].client_id,
+					mbox_svc.resp_queue[di].job_id,
+					mbox_svc.resp_queue[di].resp_len,
+					mbox_svc.resp_queue[di].err_code);
+
+				/* Check if the response is an argument response */
+				if (mbox_svc.resp_queue[di].resp_len > 0) {
+					mbox_svc.next_resp_state = SRS_WAIT_FOR_ARGUMENTS;
+				} else {
+					VERBOSE("MBOX: Received complete response with no args\n");
+					/* Non argument response, done */
+					mbox_svc.resp_queue[mbox_svc.curr_di].flags |=
+									FLAG_SDM_RESPONSE_IS_VALID;
+
+					/* Go back to waiting for new response */
+					mbox_svc.next_resp_state = SRS_WAIT_FOR_RESP;
+					mbox_svc.curr_di = -1;
+
+					/* Mark the transaction ID as received */
+					spin_lock(&mbox_db_lock);
+					mbox_svc.received_bitmap[trans_id / MBOX_TID_BITMAP_SIZE] |=
+							(1ULL << (trans_id % MBOX_TID_BITMAP_SIZE));
+					spin_unlock(&mbox_db_lock);
+				}
+			} else {
+				mbox_svc.next_resp_state = SRS_SYNC_ERROR;
+			}
+		}
+		break;
+	}
+
+	case SRS_WAIT_FOR_ARGUMENTS:
+	{
+		mbox_svc.resp_state = SRS_WAIT_FOR_ARGUMENTS;
+		uint16_t mbox_resp_len = mbox_svc.resp_queue[mbox_svc.curr_di].resp_len;
+		uint32_t *read_buff = NULL;
+		uint16_t read_len = 0U;
+		uint16_t read_max_len = 0U;
+		uint32_t timeout = 0U;
+
+		/* Determine where to copy the buffer. */
+		sdm_command_t *cmd_desc = mailbox_get_cmd_desc(
+						mbox_svc.resp_queue[mbox_svc.curr_di].client_id,
+						mbox_svc.resp_queue[mbox_svc.curr_di].job_id);
+		if (cmd_desc != NULL && cmd_desc->cb_args != NULL) {
+			read_buff = cmd_desc->cb_args;
+			read_max_len = mbox_resp_len;
+		} else {
+			read_buff = (uint32_t *)mbox_svc.resp_queue[mbox_svc.curr_di].resp_data;
+			read_max_len = MBOX_SVC_MAX_RESP_DATA_SIZE;
+		}
+
+		rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
+		rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
+
+		while ((read_len < mbox_resp_len) && (rin != rout) && (read_len < read_max_len)) {
+			timeout = 10000U;
+
+			/* Copy the response data to the buffer */
+			read_buff[read_len++] = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
+
+			VERBOSE("MBOX: 0x%x\n", read_buff[read_len - 1]);
+
+			/* Update the read out buffer index */
+			rout %= MBOX_RESP_BUFFER_SIZE;
+			mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
+
+			/*
+			 * The response buffer is of 16 words size, this loop checks
+			 * if the response buffer is empty and if empty trigger an
+			 * interrupt to SDM and wait for the response buffer to fill
+			 */
+			do {
+				if (read_len == mbox_resp_len)
+					break;
+
+				rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
+				if (rout == rin) {
+					mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
+					udelay(100);
+				} else {
+					break;
+				}
+				timeout--;
+			} while ((read_len < mbox_resp_len) && (timeout != 0U));
+
+			if (timeout == 0U) {
+				INFO("MBOX: Timeout waiting for response data\n");
+				mbox_svc.next_resp_state = SRS_SYNC_ERROR;
+				break;
+			}
+		}
+
+		/* Check if we have received all the arguments */
+		mbox_svc.resp_queue[mbox_svc.curr_di].rcvd_resp_len = read_len;
+		if (mbox_resp_len == read_len) {
+			uint8_t transaction_id =
+					((mbox_svc.resp_queue[mbox_svc.curr_di].client_id << 4) |
+					 (mbox_svc.resp_queue[mbox_svc.curr_di].job_id));
+			VERBOSE("MBOX: Received all the response data len %d, transaction_id %d\n",
+				read_len, transaction_id);
+
+			spin_lock(&mbox_db_lock);
+			mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] |=
+						(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
+			spin_unlock(&mbox_db_lock);
+
+			mbox_svc.resp_queue[mbox_svc.curr_di].flags |= FLAG_SDM_RESPONSE_IS_VALID;
+			mbox_svc.next_resp_state = SRS_WAIT_FOR_RESP;
+			mbox_svc.curr_di = -1;
+		} else {
+			mbox_svc.next_resp_state = SRS_SYNC_ERROR;
+			VERBOSE("MBOX: Received partial response data len %d, max len %d\n",
+				read_len, read_max_len);
+		}
+		break;
+	}
+
+	case SRS_SYNC_ERROR:
+	{
+		mbox_svc.resp_state = SRS_SYNC_ERROR;
+		INFO("MBOX: Error in response handling\n");
+		break;
+	}
+
+	default:
+		break;
+	} /* switch */
+}
+
+static int mailbox_response_handler_fsm(void)
+{
+	int status = MBOX_RET_OK;
+
+	spin_lock(&mbox_read_lock);
+	/* Mailbox peripheral response parser */
+	do {
+		/* Iterate till the state machine transition ends */
+		mailbox_response_parser();
+
+		/* Note down if there is any error in the response parsing */
+		if (mbox_svc.next_resp_state == SRS_SYNC_ERROR) {
+			status = MBOX_RET_ERROR;
+		}
+
+	} while (mbox_svc.resp_state != mbox_svc.next_resp_state);
+	spin_unlock(&mbox_read_lock);
+
+	return status;
+}
+
+int mailbox_response_poll_on_intr_v3(uint8_t *client_id, uint8_t *job_id,
+				     uint64_t *bitmap)
+{
+	uint32_t i = 0U;
+	int status = MBOX_RET_OK;
+
+	/* Clear the SDM doorbell interrupt immediately */
+	if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
+		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
+	}
+
+	/* Check mailbox FIFO for any pending responses available to read. */
+	status = mailbox_response_handler_fsm();
+	if (status != MBOX_RET_OK) {
+		return status;
+	}
+
+	/*
+	 * Once we read the complete mailbox FIFO, let's mark up the bitmap for
+	 * available responses with respect to each transcation IDs.
+	 */
+	status = MBOX_NO_RESPONSE;
+	spin_lock(&mbox_db_lock);
+	for (i = 0; i < MBOX_MAX_TIDS_BITMAP; i++) {
+		bitmap[i] = mbox_svc.interrupt_bitmap[i] ^ mbox_svc.received_bitmap[i];
+		if (bitmap[i] != 0 && status == MBOX_NO_RESPONSE) {
+			status = MBOX_RET_OK;
+		}
+
+		mbox_svc.interrupt_bitmap[i] = mbox_svc.received_bitmap[i];
+	}
+	spin_unlock(&mbox_db_lock);
+
+	return status;
+}
+
+int mailbox_response_poll_v3(uint8_t client_id, uint8_t job_id,
+			     uint32_t *ret_args, uint32_t *ret_args_len)
+{
+	sdm_command_t *cmd_desc = NULL;
+	sdm_response_t *resp_desc = NULL;
+	uint8_t di = 0U;
+	int status = MBOX_RET_OK;
+
+	/*
+	 * Let's first check the local response queue with the given
+	 * client ID and job ID
+	 */
+	resp_desc = mailbox_get_resp_desc(client_id, job_id, &di);
+	if (resp_desc == NULL) {
+		/* Not available in the local queue, let's read mailbox FIFO */
+		status = mailbox_response_handler_fsm();
+		if (status != MBOX_RET_OK) {
+			return status;
+		}
+
+		resp_desc = mailbox_get_resp_desc(client_id, job_id, &di);
+	}
+	cmd_desc = mailbox_get_cmd_desc(client_id, job_id);
+
+	if (cmd_desc != NULL && resp_desc != NULL) {
+		VERBOSE("MBOX: Resp found for cid %d, jid %d\n", client_id, job_id);
+
+		/* Command callback function */
+		*ret_args_len = cmd_desc->cb(resp_desc, cmd_desc, ret_args);
+
+		/* Free the command and response descriptors. */
+		mailbox_free_cmd_desc(cmd_desc);
+		mailbox_free_resp_desc(di);
+
+		return MBOX_RET_OK;
+	}
+
+	INFO("MBOX: No resp found for cid: %d, jid: %d\n", client_id, job_id);
+
+	return MBOX_NO_RESPONSE;
+}
+
+void mailbox_init_v3(void)
+{
+	uint32_t count;
+
+	memset((void *)&mbox_svc, 0, sizeof(mbox_svc));
+
+	mbox_svc.next_resp_state = SRS_WAIT_FOR_RESP;
+	mbox_svc.resp_state = SRS_WAIT_FOR_RESP;
+
+	/* Free all entries from the response queue. */
+	for (count = 0; count < MBOX_SVC_RESP_QUEUE_SIZE; count++) {
+		mbox_svc.resp_queue[count].flags = 0;
+	}
+
+	/* Free all entries from the command queue. */
+	for (count = 0; count < MBOX_SVC_CMD_QUEUE_SIZE; count++) {
+		mbox_svc.cmd_queue[count].flags = 0;
+	}
+
+	mbox_svc.curr_di = -1;
+}
+#endif /* #if SIP_SVC_V3 */
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index d64ead7..f4a3ea0 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -801,6 +801,837 @@
 }
 #endif
 
+#if SIP_SVC_V3
+uint8_t sip_smc_cmd_cb_ret2(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	/* Returns 3 SMC arguments for SMC_RET3 */
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+
+	return ret_args_len;
+}
+
+uint8_t sip_smc_cmd_cb_ret3(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	/* Returns 3 SMC arguments for SMC_RET3 */
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->resp_data[0];
+
+	return ret_args_len;
+}
+
+uint8_t sip_smc_ret_nbytes_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mailbox_err 0%x, nbytes_ret %d\n",
+		__func__, resp->err_code, resp->rcvd_resp_len * MBOX_WORD_BYTE);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->rcvd_resp_len * MBOX_WORD_BYTE;
+
+	return ret_args_len;
+}
+
+uint8_t sip_smc_get_chipid_cb(void *resp_desc, void *cmd_desc, uint32_t *ret_args)
+{
+	uint8_t ret_args_len = 0U;
+	sdm_response_t *resp = (sdm_response_t *)resp_desc;
+	sdm_command_t *cmd = (sdm_command_t *)cmd_desc;
+
+	(void)cmd;
+	INFO("MBOX: %s: mailbox_err 0%x, data[0] 0x%x, data[1] 0x%x\n",
+		__func__, resp->err_code, resp->resp_data[0], resp->resp_data[1]);
+
+	ret_args[ret_args_len++] = INTEL_SIP_SMC_STATUS_OK;
+	ret_args[ret_args_len++] = resp->err_code;
+	ret_args[ret_args_len++] = resp->resp_data[0];
+	ret_args[ret_args_len++] = resp->resp_data[1];
+
+	return ret_args_len;
+}
+
+static uintptr_t smc_ret(void *handle, uint32_t *ret_args, uint32_t ret_args_len)
+{
+	switch (ret_args_len) {
+	case SMC_RET_ARGS_ONE:
+		SMC_RET1(handle, ret_args[0]);
+		break;
+
+	case SMC_RET_ARGS_TWO:
+		SMC_RET2(handle, ret_args[0], ret_args[1]);
+		break;
+
+	case SMC_RET_ARGS_THREE:
+		SMC_RET3(handle, ret_args[0], ret_args[1], ret_args[2]);
+		break;
+
+	case SMC_RET_ARGS_FOUR:
+		SMC_RET4(handle, ret_args[0], ret_args[1], ret_args[2], ret_args[3]);
+		break;
+
+	case SMC_RET_ARGS_FIVE:
+		SMC_RET5(handle, ret_args[0], ret_args[1], ret_args[2], ret_args[3], ret_args[4]);
+		break;
+
+	default:
+		SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR);
+		break;
+	}
+}
+
+/*
+ * This function is responsible for handling all SiP SVC V3 calls from the
+ * non-secure world.
+ */
+static uintptr_t sip_smc_handler_v3(uint32_t smc_fid,
+				    u_register_t x1,
+				    u_register_t x2,
+				    u_register_t x3,
+				    u_register_t x4,
+				    void *cookie,
+				    void *handle,
+				    u_register_t flags)
+{
+	int status = 0;
+	uint32_t mbox_error = 0U;
+	u_register_t x5, x6, x7, x8, x9, x10, x11;
+
+	/* Get all the SMC call arguments */
+	x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+	x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+	x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+	x8 = SMC_GET_GP(handle, CTX_GPREG_X8);
+	x9 = SMC_GET_GP(handle, CTX_GPREG_X9);
+	x10 = SMC_GET_GP(handle, CTX_GPREG_X10);
+	x11 = SMC_GET_GP(handle, CTX_GPREG_X11);
+
+	INFO("MBOX: SVC_V3: x0 0x%x, x1 0x%lx, x2 0x%lx, x3 0x%lx, x4 0x%lx, x5 0x%lx\n",
+		smc_fid, x1, x2, x3, x4, x5);
+	INFO("MBOX: SVC_V3: x6 0x%lx, x7 0x%lx, x8 0x%lx, x9 0x%lx, x10 0x%lx x11 0x%lx\n",
+		x6, x7, x8, x9, x10, x11);
+
+	switch (smc_fid) {
+	case ALTERA_SIP_SMC_ASYNC_RESP_POLL:
+	{
+		uint32_t ret_args[8] = {0};
+		uint32_t ret_args_len;
+
+		status = mailbox_response_poll_v3(GET_CLIENT_ID(x1),
+						  GET_JOB_ID(x1),
+						  ret_args,
+						  &ret_args_len);
+		/* Always reserve [0] index for command status. */
+		ret_args[0] = status;
+
+		/* Return SMC call based on the number of return arguments */
+		return smc_ret(handle, ret_args, ret_args_len);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_RESP_POLL_ON_INTR:
+	{
+		/* TBD: Here now we don't need these CID and JID?? */
+		uint8_t client_id = 0U;
+		uint8_t job_id = 0U;
+		uint64_t trans_id_bitmap[4] = {0U};
+
+		status = mailbox_response_poll_on_intr_v3(&client_id,
+							  &job_id,
+							  trans_id_bitmap);
+
+		SMC_RET5(handle, status, trans_id_bitmap[0], trans_id_bitmap[1],
+			 trans_id_bitmap[2], trans_id_bitmap[3]);
+		break;
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_GET_DEVICE_IDENTITY:
+	{
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_GET_DEVICEID,
+						   NULL,
+						   0U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_ret_nbytes_cb,
+						   (uint32_t *)x2,
+						   2);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_GET_IDCODE:
+	{
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_GET_IDCODE,
+						   NULL,
+						   0U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret3,
+						   NULL,
+						   0);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_QSPI_OPEN:
+	{
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_QSPI_OPEN,
+						   NULL,
+						   0U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret2,
+						   NULL,
+						   0U);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_QSPI_CLOSE:
+	{
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_QSPI_CLOSE,
+						   NULL,
+						   0U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret2,
+						   NULL,
+						   0U);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_QSPI_SET_CS:
+	{
+		uint32_t cmd_data = 0U;
+		uint32_t chip_sel = (uint32_t)x2;
+		uint32_t comb_addr_mode = (uint32_t)x3;
+		uint32_t ext_dec_mode = (uint32_t)x4;
+
+		cmd_data = (chip_sel << MBOX_QSPI_SET_CS_OFFSET) |
+			   (comb_addr_mode << MBOX_QSPI_SET_CS_CA_OFFSET) |
+			   (ext_dec_mode << MBOX_QSPI_SET_CS_MODE_OFFSET);
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_QSPI_SET_CS,
+						   &cmd_data,
+						   1U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret2,
+						   NULL,
+						   0U);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_QSPI_ERASE:
+	{
+		uint32_t qspi_addr = (uint32_t)x2;
+		uint32_t qspi_nwords = (uint32_t)x3;
+
+		/* QSPI address offset to start erase, must be 4K aligned */
+		if (MBOX_IS_4K_ALIGNED(qspi_addr)) {
+			ERROR("MBOX: 0x%x: QSPI address not 4K aligned\n",
+				smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		/* Number of words to erase, multiples of 0x400 or 4K */
+		if (qspi_nwords % MBOX_QSPI_ERASE_SIZE_GRAN) {
+			ERROR("MBOX: 0x%x: Given words not in multiples of 4K\n",
+				smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		uint32_t cmd_data[2] = {qspi_addr, qspi_nwords};
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_QSPI_ERASE,
+						   cmd_data,
+						   sizeof(cmd_data) / MBOX_WORD_BYTE,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret2,
+						   NULL,
+						   0U);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_QSPI_WRITE:
+	{
+		uint32_t *qspi_payload = (uint32_t *)x2;
+		uint32_t qspi_total_nwords = (((uint32_t)x3) / MBOX_WORD_BYTE);
+		uint32_t qspi_addr = qspi_payload[0];
+		uint32_t qspi_nwords = qspi_payload[1];
+
+		if (!MBOX_IS_WORD_ALIGNED(qspi_addr)) {
+			ERROR("MBOX: 0x%x: Given address is not WORD aligned\n",
+				smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		if (qspi_nwords > MBOX_QSPI_RW_MAX_WORDS) {
+			ERROR("MBOX: 0x%x: Number of words exceeds max limit\n",
+				smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_QSPI_WRITE,
+						   qspi_payload,
+						   qspi_total_nwords,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret2,
+						   NULL,
+						   0U);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_QSPI_READ:
+	{
+		uint32_t qspi_addr = (uint32_t)x2;
+		uint32_t qspi_nwords = (((uint32_t)x4) / MBOX_WORD_BYTE);
+
+		if (qspi_nwords > MBOX_QSPI_RW_MAX_WORDS) {
+			ERROR("MBOX: 0x%x: Number of words exceeds max limit\n",
+				smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		uint32_t cmd_data[2] = {qspi_addr, qspi_nwords};
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_QSPI_READ,
+						   cmd_data,
+						   sizeof(cmd_data) / MBOX_WORD_BYTE,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_ret_nbytes_cb,
+						   (uint32_t *)x3,
+						   2);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_QSPI_GET_DEV_INFO:
+	{
+		uint32_t *dst_addr = (uint32_t *)x2;
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_QSPI_GET_DEV_INFO,
+						   NULL,
+						   0U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_ret_nbytes_cb,
+						   (uint32_t *)dst_addr,
+						   2);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_HWMON_READVOLT:
+	case ALTERA_SIP_SMC_ASYNC_HWMON_READTEMP:
+	{
+		uint32_t channel = (uint32_t)x2;
+		uint32_t mbox_cmd = ((smc_fid == ALTERA_SIP_SMC_ASYNC_HWMON_READVOLT) ?
+					MBOX_HWMON_READVOLT : MBOX_HWMON_READTEMP);
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   mbox_cmd,
+						   &channel,
+						   1U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret3,
+						   NULL,
+						   0);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_RANDOM_NUMBER_EXT:
+	{
+		uint32_t session_id = (uint32_t)x2;
+		uint32_t context_id = (uint32_t)x3;
+		uint64_t ret_random_addr = (uint64_t)x4;
+		uint32_t random_len = (uint32_t)SMC_GET_GP(handle, CTX_GPREG_X5);
+		uint32_t crypto_header = 0U;
+
+		if ((random_len > (FCS_RANDOM_EXT_MAX_WORD_SIZE * MBOX_WORD_BYTE)) ||
+		    (random_len == 0U) ||
+		    (!is_size_4_bytes_aligned(random_len))) {
+			ERROR("MBOX: 0x%x is rejected\n", smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		crypto_header = ((FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
+				  FCS_CS_FIELD_FLAG_OFFSET);
+		fcs_rng_payload payload = {session_id, context_id,
+					   crypto_header, random_len};
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_FCS_RANDOM_GEN,
+						   (uint32_t *)&payload,
+						   sizeof(payload) / MBOX_WORD_BYTE,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_ret_nbytes_cb,
+						   (uint32_t *)ret_random_addr,
+						   2);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_GET_PROVISION_DATA:
+	{
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_FCS_GET_PROVISION,
+						   NULL,
+						   0U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_ret_nbytes_cb,
+						   (uint32_t *)x2,
+						   2);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_CNTR_SET_PREAUTH:
+	{
+		status = intel_fcs_cntr_set_preauth(smc_fid, x1, x2, x3,
+					x4, &mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_CHIP_ID:
+	{
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_GET_CHIPID,
+						   NULL,
+						   0U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_get_chipid_cb,
+						   NULL,
+						   0);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_GET_ATTESTATION_CERT:
+	{
+		status = intel_fcs_get_attestation_cert(smc_fid, x1, x2, x3,
+					(uint32_t *) &x4, &mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CERT_ON_RELOAD:
+	{
+		status = intel_fcs_create_cert_on_reload(smc_fid, x1,
+					x2, &mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT:
+	{
+		if (x4 == FCS_MODE_ENCRYPT) {
+			status = intel_fcs_encryption_ext(smc_fid, x1, x2, x3,
+					x5, x6, x7, (uint32_t *) &x8,
+					&mbox_error, x10, x11);
+		} else if (x4 == FCS_MODE_DECRYPT) {
+			status = intel_fcs_decryption_ext(smc_fid, x1, x2, x3,
+					x5, x6, x7, (uint32_t *) &x8,
+					&mbox_error, x9, x10, x11);
+		} else {
+			ERROR("MBOX: 0x%x: Wrong crypto mode\n", smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+		}
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_SEND_CERTIFICATE:
+	{
+		status = intel_fcs_send_cert(smc_fid, x1, x2, x3, &mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION:
+	{
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_FCS_OPEN_CS_SESSION,
+						   NULL,
+						   0U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret3,
+						   NULL,
+						   0);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION:
+	{
+		uint32_t session_id = (uint32_t)x2;
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_FCS_CLOSE_CS_SESSION,
+						   &session_id,
+						   1U,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret2,
+						   NULL,
+						   0);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_IMPORT_CS_KEY:
+	{
+		uint64_t key_addr = x2;
+		uint32_t key_len_words = (uint32_t)x3 / MBOX_WORD_BYTE;
+
+		if ((key_len_words > FCS_CS_KEY_OBJ_MAX_WORD_SIZE) ||
+		    (!is_address_in_ddr_range(key_addr, key_len_words * 4))) {
+			ERROR("MBOX: 0x%x: Addr not in DDR range or key len exceeds\n",
+				smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_FCS_IMPORT_CS_KEY,
+						   (uint32_t *)key_addr,
+						   key_len_words,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret3,
+						   NULL,
+						   0);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CS_KEY:
+	{
+		uint64_t key_addr = x2;
+		uint32_t key_len_words = (uint32_t)x3 / MBOX_WORD_BYTE;
+
+		if (!is_address_in_ddr_range(key_addr, key_len_words * 4)) {
+			ERROR("MBOX: 0x%x: Addr not in DDR range\n", smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_FCS_CREATE_CS_KEY,
+						   (uint32_t *)key_addr,
+						   key_len_words,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret3,
+						   NULL,
+						   0);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_EXPORT_CS_KEY:
+	{
+		uint32_t session_id = (uint32_t)x2;
+		uint32_t key_uid = (uint32_t)x3;
+		uint64_t ret_key_addr = (uint64_t)x4;
+		uint32_t key_len = (uint32_t)SMC_GET_GP(handle, CTX_GPREG_X5);
+
+		if (!is_address_in_ddr_range(ret_key_addr, key_len)) {
+			ERROR("MBOX: 0x%x: Addr not in DDR range\n", smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		fcs_cs_key_payload payload = {session_id, RESERVED_AS_ZERO,
+					      RESERVED_AS_ZERO, key_uid};
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_FCS_EXPORT_CS_KEY,
+						   (uint32_t *)&payload,
+						   sizeof(payload) / MBOX_WORD_BYTE,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_ret_nbytes_cb,
+						   (uint32_t *)ret_key_addr,
+						   2);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_REMOVE_CS_KEY:
+	{
+		uint32_t session_id = (uint32_t)x2;
+		uint32_t key_uid = (uint32_t)x3;
+
+		fcs_cs_key_payload payload = {session_id, RESERVED_AS_ZERO,
+					      RESERVED_AS_ZERO, key_uid};
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_FCS_REMOVE_CS_KEY,
+						   (uint32_t *)&payload,
+						   sizeof(payload) / MBOX_WORD_BYTE,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_cmd_cb_ret3,
+						   NULL,
+						   0);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_GET_CS_KEY_INFO:
+	{
+		uint32_t session_id = (uint32_t)x2;
+		uint32_t key_uid = (uint32_t)x3;
+		uint64_t ret_key_addr = (uint64_t)x4;
+		uint32_t key_len = (uint32_t)SMC_GET_GP(handle, CTX_GPREG_X5);
+
+		if (!is_address_in_ddr_range(ret_key_addr, key_len)) {
+			ERROR("MBOX: 0x%x: Addr not in DDR range\n", smc_fid);
+			status = INTEL_SIP_SMC_STATUS_REJECTED;
+			SMC_RET1(handle, status);
+		}
+
+		fcs_cs_key_payload payload = {session_id, RESERVED_AS_ZERO,
+					      RESERVED_AS_ZERO, key_uid};
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_FCS_GET_CS_KEY_INFO,
+						   (uint32_t *)&payload,
+						   sizeof(payload) / MBOX_WORD_BYTE,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_ret_nbytes_cb,
+						   (uint32_t *)ret_key_addr,
+						   2);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_INIT:
+	{
+		status = intel_fcs_aes_crypt_init(x2, x3, x4, x5,
+					x6, &mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_FINALIZE:
+	{
+		uint32_t job_id = 0U;
+		bool is_final = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_FINALIZE) ?
+				true : false;
+
+		status = intel_fcs_aes_crypt_update_finalize(smc_fid, x1, x2,
+					x3, x4, x5, x6, x7, x8, is_final,
+					&job_id, x9, x10);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_INIT:
+	{
+		status = intel_fcs_get_digest_init(x2, x3, x4, x5, x6,
+					&mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_FINALIZE:
+	{
+		bool is_final = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_FINALIZE) ?
+				true : false;
+
+		status = intel_fcs_get_digest_update_finalize(smc_fid, x1, x2,
+					x3, x4, x5, x6, (uint32_t *) &x7,
+					is_final, &mbox_error, x8);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_INIT:
+	{
+		status = intel_fcs_mac_verify_init(x2, x3, x4, x5, x6,
+					&mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_FINALIZE:
+	{
+		bool is_final = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_FINALIZE) ?
+				true : false;
+
+		status = intel_fcs_mac_verify_update_finalize(smc_fid, x1, x2,
+					x3, x4, x5, x6, (uint32_t *) &x7, x8,
+					is_final, &mbox_error, x9);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_INIT:
+	{
+		status = intel_fcs_ecdsa_hash_sign_init(x2, x3, x4, x5, x6,
+					&mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_FINALIZE:
+	{
+		status = intel_fcs_ecdsa_hash_sign_finalize(smc_fid, x1, x2, x3,
+					x4, x5, x6, (uint32_t *) &x7,
+					&mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_INIT:
+	{
+		status = intel_fcs_ecdsa_sha2_data_sign_init(x2, x3, x4, x5, x6,
+					&mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE:
+	{
+		bool is_final = (smc_fid == ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE)
+				? true : false;
+
+		status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(smc_fid,
+					x1, x2, x3, x4, x5, x6, (uint32_t *) &x7,
+					is_final, &mbox_error, x8);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_INIT:
+	{
+		status = intel_fcs_ecdsa_hash_sig_verify_init(x2, x3, x4, x5,
+					x6, &mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE:
+	{
+		status = intel_fcs_ecdsa_hash_sig_verify_finalize(smc_fid, x1,
+					x2, x3, x4, x5, x6, (uint32_t *) &x7,
+					&mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT:
+	{
+		status = intel_fcs_ecdsa_sha2_data_sig_verify_init(x2, x3, x4,
+					x5, x6, &mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE:
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE:
+	{
+		bool is_final = (smc_fid ==
+				ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE) ?
+				true : false;
+
+		status = intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(
+					smc_fid, x1, x2, x3, x4, x5, x6,
+					(uint32_t *) &x7, x8, is_final,
+					&mbox_error, x9);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_INIT:
+	{
+		status = intel_fcs_ecdsa_get_pubkey_init(x2, x3, x4, x5, x6,
+					&mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_FINALIZE:
+	{
+		status = intel_fcs_ecdsa_get_pubkey_finalize(smc_fid, x1, x2, x3,
+					x4, (uint32_t *) &x5, &mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_INIT:
+	{
+		status = intel_fcs_ecdh_request_init(x2, x3, x4, x5, x6,
+					&mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_FINALIZE:
+	{
+		uint32_t dest_size = (uint32_t)x7;
+
+		NOTICE("MBOX: %s, %d: x7 0x%x, dest_size 0x%x\n",
+			__func__, __LINE__, (uint32_t)x7, dest_size);
+
+		status = intel_fcs_ecdh_request_finalize(smc_fid, x1, x2, x3,
+					x4, x5, x6, (uint32_t *) &dest_size,
+					&mbox_error);
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_MCTP_MSG:
+	{
+		uint32_t *src_addr = (uint32_t *)x2;
+		uint32_t src_size = (uint32_t)x3;
+		uint32_t *dst_addr = (uint32_t *)x4;
+
+		status = mailbox_send_cmd_async_v3(GET_CLIENT_ID(x1),
+						   GET_JOB_ID(x1),
+						   MBOX_CMD_MCTP_MSG,
+						   src_addr,
+						   src_size / MBOX_WORD_BYTE,
+						   MBOX_CMD_FLAG_CASUAL,
+						   sip_smc_ret_nbytes_cb,
+						   dst_addr,
+						   2);
+
+		SMC_RET1(handle, status);
+	}
+
+	case ALTERA_SIP_SMC_ASYNC_FCS_HKDF_REQUEST:
+	{
+		status = intel_fcs_hkdf_request(smc_fid, x1, x2, x3, x4, x5, x6,
+					x7);
+		SMC_RET1(handle, status);
+	}
+
+	default:
+		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
+					   cookie, handle, flags);
+	} /* switch (smc_fid) */
+}
+#endif
+
 /*
  * This function is responsible for handling all SiP calls from the NS world
  */
@@ -995,11 +1826,11 @@
 		x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
 
 		if (x3 == FCS_MODE_DECRYPT) {
-			status = intel_fcs_decryption_ext(x1, x2, x4, x5, x6,
-					(uint32_t *) &x7, &mbox_error);
+			status = intel_fcs_decryption_ext(smc_fid, 0, x1, x2, x4, x5, x6,
+					(uint32_t *) &x7, &mbox_error, 0, 0, 0);
 		} else if (x3 == FCS_MODE_ENCRYPT) {
-			status = intel_fcs_encryption_ext(x1, x2, x4, x5, x6,
-					(uint32_t *) &x7, &mbox_error);
+			status = intel_fcs_encryption_ext(smc_fid, 0, x1, x2, x4, x5, x6,
+					(uint32_t *) &x7, &mbox_error, 0, 0);
 		} else {
 			status = INTEL_SIP_SMC_STATUS_REJECTED;
 		}
@@ -1017,7 +1848,7 @@
 		SMC_RET1(handle, status);
 
 	case INTEL_SIP_SMC_FCS_SEND_CERTIFICATE:
-		status = intel_fcs_send_cert(x1, x2, &send_id);
+		status = intel_fcs_send_cert(smc_fid, 0, x1, x2, &send_id);
 		SMC_RET1(handle, status);
 
 	case INTEL_SIP_SMC_FCS_GET_PROVISION_DATA:
@@ -1025,7 +1856,7 @@
 		SMC_RET1(handle, status);
 
 	case INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH:
-		status = intel_fcs_cntr_set_preauth(x1, x2, x3,
+		status = intel_fcs_cntr_set_preauth(smc_fid, 0, x1, x2, x3,
 							&mbox_error);
 		SMC_RET2(handle, status, mbox_error);
 
@@ -1060,12 +1891,12 @@
 		SMC_RET4(handle, status, mbox_error, x3, x4);
 
 	case INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT:
-		status = intel_fcs_get_attestation_cert(x1, x2,
+		status = intel_fcs_get_attestation_cert(smc_fid, 0, x1, x2,
 					(uint32_t *) &x3, &mbox_error);
 		SMC_RET4(handle, status, mbox_error, x2, x3);
 
 	case INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD:
-		status = intel_fcs_create_cert_on_reload(x1, &mbox_error);
+		status = intel_fcs_create_cert_on_reload(smc_fid, 0, x1, &mbox_error);
 		SMC_RET2(handle, status, mbox_error);
 
 	case INTEL_SIP_SMC_FCS_OPEN_CS_SESSION:
@@ -1104,17 +1935,17 @@
 	case INTEL_SIP_SMC_FCS_GET_DIGEST_UPDATE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-		status = intel_fcs_get_digest_update_finalize(x1, x2, x3,
-					x4, x5, (uint32_t *) &x6, false,
-					&mbox_error);
+		status = intel_fcs_get_digest_update_finalize(smc_fid, 0, x1, x2,
+					x3, x4, x5, (uint32_t *) &x6, false,
+					&mbox_error, 0);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
 	case INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-		status = intel_fcs_get_digest_update_finalize(x1, x2, x3,
-					x4, x5, (uint32_t *) &x6, true,
-					&mbox_error);
+		status = intel_fcs_get_digest_update_finalize(smc_fid, 0, x1, x2,
+					x3, x4, x5, (uint32_t *) &x6, true,
+					&mbox_error, 0);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
 	case INTEL_SIP_SMC_FCS_GET_DIGEST_SMMU_UPDATE:
@@ -1143,18 +1974,18 @@
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
 		x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-		status = intel_fcs_mac_verify_update_finalize(x1, x2, x3,
-					x4, x5, (uint32_t *) &x6, x7,
-					false, &mbox_error);
+		status = intel_fcs_mac_verify_update_finalize(smc_fid, 0, x1, x2,
+					x3, x4, x5, (uint32_t *) &x6, x7, false,
+					&mbox_error, 0);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
 	case INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
 		x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-		status = intel_fcs_mac_verify_update_finalize(x1, x2, x3,
-					x4, x5, (uint32_t *) &x6, x7,
-					true, &mbox_error);
+		status = intel_fcs_mac_verify_update_finalize(smc_fid, 0, x1, x2,
+					x3, x4, x5, (uint32_t *) &x6, x7, true,
+					&mbox_error, 0);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
 	case INTEL_SIP_SMC_FCS_MAC_VERIFY_SMMU_UPDATE:
@@ -1184,17 +2015,17 @@
 	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-		status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(x1, x2,
-					x3, x4, x5, (uint32_t *) &x6, false,
-					&mbox_error);
+		status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(smc_fid,
+					0, x1, x2, x3, x4, x5, (uint32_t *) &x6,
+					false, &mbox_error, 0);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
 	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-		status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(x1, x2,
-					x3, x4, x5, (uint32_t *) &x6, true,
-					&mbox_error);
+		status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(smc_fid,
+					0, x1, x2, x3, x4, x5, (uint32_t *) &x6,
+					true, &mbox_error, 0);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
 	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_UPDATE:
@@ -1222,8 +2053,9 @@
 	case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_FINALIZE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-		status = intel_fcs_ecdsa_hash_sign_finalize(x1, x2, x3,
-					 x4, x5, (uint32_t *) &x6, &mbox_error);
+		status = intel_fcs_ecdsa_hash_sign_finalize(smc_fid, 0, x1, x2,
+					x3, x4, x5, (uint32_t *) &x6,
+					&mbox_error);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
 	case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_INIT:
@@ -1235,8 +2067,9 @@
 	case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-		status = intel_fcs_ecdsa_hash_sig_verify_finalize(x1, x2, x3,
-					 x4, x5, (uint32_t *) &x6, &mbox_error);
+		status = intel_fcs_ecdsa_hash_sig_verify_finalize(smc_fid, 0, x1,
+					x2, x3, x4, x5, (uint32_t *) &x6,
+					&mbox_error);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
 	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT:
@@ -1250,8 +2083,9 @@
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
 		x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
 		status = intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(
-					x1, x2, x3, x4, x5, (uint32_t *) &x6,
-					x7, false, &mbox_error);
+					smc_fid, 0, x1, x2, x3, x4, x5,
+					(uint32_t *) &x6, x7, false,
+					&mbox_error, 0);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
 	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_UPDATE:
@@ -1277,8 +2111,9 @@
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
 		x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
 		status = intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(
-					x1, x2, x3, x4, x5, (uint32_t *) &x6,
-					x7, true, &mbox_error);
+					smc_fid, 0, x1, x2, x3, x4, x5,
+					(uint32_t *) &x6, x7, true,
+					&mbox_error, 0);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
 	case INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT:
@@ -1288,8 +2123,9 @@
 		SMC_RET2(handle, status, mbox_error);
 
 	case INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE:
-		status = intel_fcs_ecdsa_get_pubkey_finalize(x1, x2, x3,
-					(uint32_t *) &x4, &mbox_error);
+		status = intel_fcs_ecdsa_get_pubkey_finalize(
+				INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE, 0,
+				x1, x2, x3, (uint32_t *) &x4, &mbox_error);
 		SMC_RET4(handle, status, mbox_error, x3, x4);
 
 	case INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT:
@@ -1301,7 +2137,7 @@
 	case INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-		status = intel_fcs_ecdh_request_finalize(x1, x2, x3,
+		status = intel_fcs_ecdh_request_finalize(smc_fid, 0, x1, x2, x3,
 					 x4, x5, (uint32_t *) &x6, &mbox_error);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
@@ -1314,15 +2150,15 @@
 	case INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-		status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4,
-					x5, x6, false, &send_id);
+		status = intel_fcs_aes_crypt_update_finalize(smc_fid, 0, x1, x2,
+					x3, x4, x5, x6, 0, false, &send_id, 0, 0);
 		SMC_RET1(handle, status);
 
 	case INTEL_SIP_SMC_FCS_AES_CRYPT_FINALIZE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-		status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4,
-					x5, x6, true, &send_id);
+		status = intel_fcs_aes_crypt_update_finalize(smc_fid, 0, x1, x2,
+					x3, x4, x5, x6, 0, true, &send_id, 0, 0);
 		SMC_RET1(handle, status);
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
@@ -1354,6 +2190,10 @@
 		status = intel_sdm_safe_inject_seu_err((uint32_t *)&x1, (uint32_t)x2);
 		SMC_RET1(handle, status);
 
+	case INTEL_SIP_SMC_ATF_BUILD_VER:
+		SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, VERSION_MAJOR,
+			 VERSION_MINOR, VERSION_PATCH);
+
 	default:
 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
 			cookie, handle, flags);
@@ -1375,7 +2215,16 @@
 	    cmd <= INTEL_SIP_SMC_CMD_V2_RANGE_END) {
 		return sip_smc_handler_v2(smc_fid, x1, x2, x3, x4,
 			cookie, handle, flags);
-	} else {
+	}
+#if SIP_SVC_V3
+	else if ((cmd >= INTEL_SIP_SMC_CMD_V3_RANGE_BEGIN) &&
+		(cmd <= INTEL_SIP_SMC_CMD_V3_RANGE_END)) {
+		uintptr_t ret = sip_smc_handler_v3(smc_fid, x1, x2, x3, x4,
+						   cookie, handle, flags);
+		return ret;
+	}
+#endif
+	else {
 		return sip_smc_handler_v1(smc_fid, x1, x2, x3, x4,
 			cookie, handle, flags);
 	}
diff --git a/plat/intel/soc/common/socfpga_vab.c b/plat/intel/soc/common/socfpga_vab.c
index 969abb3..3b7be5b 100644
--- a/plat/intel/soc/common/socfpga_vab.c
+++ b/plat/intel/soc/common/socfpga_vab.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
- * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -113,10 +113,10 @@
 
 	VERBOSE("mbox_data_addr = %lx    mbox_data_sz = %d\n", mbox_data_addr, mbox_data_sz);
 
-	memcpy_s(mbox_relocate_data_addr, mbox_data_sz * sizeof(uint32_t),
-		(uint8_t *)mbox_data_addr, mbox_data_sz * sizeof(uint32_t));
+	memcpy_s(mbox_relocate_data_addr, (mbox_data_sz * sizeof(uint32_t)) / MBOX_WORD_BYTE,
+		(uint8_t *)mbox_data_addr, (mbox_data_sz * sizeof(uint32_t)) / MBOX_WORD_BYTE);
 
-	*((unsigned int *)mbox_relocate_data_addr) = CCERT_CMD_TEST_PGM_MASK;
+	*((unsigned int *)mbox_relocate_data_addr) = 0;
 
 	do {
 		/* Invoke SMC call to ATF to send the VAB certificate to SDM */
diff --git a/plat/intel/soc/n5x/bl31_plat_setup.c b/plat/intel/soc/n5x/bl31_plat_setup.c
index cb5ced6..65de036 100644
--- a/plat/intel/soc/n5x/bl31_plat_setup.c
+++ b/plat/intel/soc/n5x/bl31_plat_setup.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -115,6 +116,16 @@
 	mmio_write_64(PLAT_CPU_RELEASE_ADDR,
 		(uint64_t)plat_secondary_cpus_bl31_entry);
 
+#if SIP_SVC_V3
+	/*
+	 * Re-initialize the mailbox to include V3 specific routines.
+	 * In V3, this re-initialize is required because prior to BL31, U-Boot
+	 * SPL has its own mailbox settings and this initialization will
+	 * override to those settings as required by the V3 framework.
+	 */
+	mailbox_init();
+#endif
+
 	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
 }
 
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index 4770f8d..4caafc5 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -1,6 +1,6 @@
 #
 # Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
-# Copyright (c) 2024, Altera Corporation. All rights reserved.
+# Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -75,3 +75,8 @@
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
 USE_COHERENT_MEM		:= 1
+
+#To get the TF-A version via SMC calls
+DEFINES += -DVERSION_MAJOR=${VERSION_MAJOR}
+DEFINES += -DVERSION_MINOR=${VERSION_MINOR}
+DEFINES += -DVERSION_PATCH=${VERSION_PATCH}
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index d0aa972..5c25e43 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2025, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -122,6 +123,16 @@
 	mmio_write_64(PLAT_CPU_RELEASE_ADDR,
 		(uint64_t)plat_secondary_cpus_bl31_entry);
 
+#if SIP_SVC_V3
+	/*
+	 * Re-initialize the mailbox to include V3 specific routines.
+	 * In V3, this re-initialize is required because prior to BL31, U-Boot
+	 * SPL has its own mailbox settings and this initialization will
+	 * override to those settings as required by the V3 framework.
+	 */
+	mailbox_init();
+#endif
+
 	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
 }
 
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index 4cd7032..9946db8 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -1,7 +1,7 @@
 #
 # Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
 # Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
-# Copyright (c) 2024, Altera Corporation. All rights reserved.
+# Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -105,3 +105,8 @@
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 USE_COHERENT_MEM		:= 1
+
+#To get the TF-A version via SMC calls
+DEFINES += -DVERSION_MAJOR=${VERSION_MAJOR}
+DEFINES += -DVERSION_MINOR=${VERSION_MINOR}
+DEFINES += -DVERSION_PATCH=${VERSION_PATCH}
diff --git a/plat/mediatek/drivers/gicv3/mt_gic_v3.c b/plat/mediatek/drivers/gicv3/mt_gic_v3.c
index 659ca9c..e9bbbe1 100644
--- a/plat/mediatek/drivers/gicv3/mt_gic_v3.c
+++ b/plat/mediatek/drivers/gicv3/mt_gic_v3.c
@@ -23,7 +23,7 @@
 
 uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
 
-static gicv3_redist_ctx_t rdist_ctx;
+static gicv3_redist_ctx_t rdist_ctx[PLATFORM_CORE_COUNT];
 static gicv3_dist_ctx_t dist_ctx;
 
 /* Configure Secure IRQs */
@@ -112,7 +112,7 @@
 	 * before the Distributor context.
 	 */
 	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
-		gicv3_rdistif_save(cpu, &rdist_ctx);
+		gicv3_rdistif_save(cpu, &rdist_ctx[cpu]);
 }
 
 void mt_gic_rdistif_restore(void)
@@ -126,7 +126,7 @@
 	 * the SYSTEM SUSPEND call.
 	 */
 	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
-		gicv3_rdistif_init_restore(cpu, &rdist_ctx);
+		gicv3_rdistif_init_restore(cpu, &rdist_ctx[cpu]);
 }
 
 void mt_gic_redistif_on(void)
diff --git a/plat/mediatek/mt8188/plat_config.mk b/plat/mediatek/mt8188/plat_config.mk
index 82ef7e8..3f7d187 100644
--- a/plat/mediatek/mt8188/plat_config.mk
+++ b/plat/mediatek/mt8188/plat_config.mk
@@ -27,7 +27,6 @@
 ERRATA_A78_1941498 := 1
 ERRATA_A78_1951500 := 1
 ERRATA_A78_1821534 := 1
-ERRATA_A78_2132060 := 1
 ERRATA_A78_2242635 := 1
 ERRATA_A78_2376745 := 1
 ERRATA_A78_2395406 := 1
diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk
index 48dafa3..e604d4f 100644
--- a/plat/mediatek/mt8195/platform.mk
+++ b/plat/mediatek/mt8195/platform.mk
@@ -99,7 +99,6 @@
 ERRATA_A78_1941498 := 1
 ERRATA_A78_1951500 := 1
 ERRATA_A78_1821534 := 1
-ERRATA_A78_2132060 := 1
 ERRATA_A78_2242635 := 1
 
 # indicate the reset vector address can be programmed
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index a88297d..4a79a90 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -400,6 +400,18 @@
 
 	return 0;
 }
+
+/*
+ * Update encryption key associated with @mecid.
+ */
+int plat_rmmd_mecid_key_update(uint16_t mecid)
+{
+	/*
+	 * QEMU does not provide an interface to change the encryption key
+	 * associated with MECID. Hence always return success.
+	 */
+	return 0;
+}
 #endif  /* ENABLE_RME */
 
 /**
diff --git a/plat/qti/sc7280/platform.mk b/plat/qti/sc7280/platform.mk
index 3d7d728..0b5ae52 100644
--- a/plat/qti/sc7280/platform.mk
+++ b/plat/qti/sc7280/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -20,7 +20,6 @@
 ERRATA_A55_1530923 		:=	1
 ERRATA_A78_1941498 		:=	1
 ERRATA_A78_1951500 		:=	1
-ERRATA_A78_2132060 		:=	1
 
 # Disable the PSCI platform compatibility layer
 ENABLE_PLAT_COMPAT		:=	0
diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c
index 4e3c9f2..4908354 100644
--- a/plat/rpi/common/rpi3_common.c
+++ b/plat/rpi/common/rpi3_common.c
@@ -75,6 +75,9 @@
 #endif
 	MAP_DEVICE0,
 	MAP_FIP,
+#if MEASURED_BOOT
+	RPI3_MAP_BL1_RW,
+#endif
 	MAP_NS_DRAM0,
 #ifdef BL32_BASE
 	MAP_BL32_MEM,
diff --git a/plat/rpi/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h
index 757c64a..eb2914a 100644
--- a/plat/rpi/rpi3/include/platform_def.h
+++ b/plat/rpi/rpi3/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -172,6 +172,14 @@
 #define BL1_RW_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE)
 
 /*
+ * In order to access the TCG Event Log in BL2, we need to expose the BL1_RW region
+ * where the log resides.
+ */
+#define RPI3_MAP_BL1_RW		MAP_REGION_FLAT(BL1_RW_BASE,		\
+					BL1_RW_LIMIT - BL1_RW_BASE,	\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
+/*
  * BL2 specific defines.
  *
  * Put BL2 just below BL31. BL2_BASE is calculated using the current BL2 debug
@@ -261,4 +269,15 @@
  */
 #define SYS_COUNTER_FREQ_IN_TICKS	ULL(19200000)
 
+/*
+ * TCG Event Log
+ */
+#define PLAT_ARM_EVENT_LOG_MAX_SIZE UL(0x400)
+
+/*
+ * NT_FW_CONFIG magic dram addr and max size
+ */
+#define PLAT_RPI3_DTO_BASE          ULL(0x11530000)
+#define PLAT_RPI3_DTO_MAX_SIZE      ULL(0x001000)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/rpi/rpi3/include/rpi3_measured_boot.h b/plat/rpi/rpi3/include/rpi3_measured_boot.h
new file mode 100644
index 0000000..67ad479
--- /dev/null
+++ b/plat/rpi/rpi3/include/rpi3_measured_boot.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPI3_MEASURED_BOOT_H
+#define RPI3_MEASURED_BOOT_H
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+
+void rpi3_mboot_fetch_eventlog_info(uint8_t **eventlog_addr, size_t *eventlog_size);
+
+int rpi3_set_nt_fw_info(size_t log_size, uintptr_t *ns_log_addr);
+
+#endif /* RPI3_MEASURED_BOOT_H */
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index fc51bec..5297177 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,8 @@
 include lib/xlat_tables_v2/xlat_tables.mk
 
 PLAT_INCLUDES		:=	-Iplat/rpi/common/include		\
-				-Iplat/rpi/rpi3/include
+				-Iplat/rpi/rpi3/include			\
+				-Iinclude/lib/libfdt
 
 PLAT_BL_COMMON_SOURCES	:=	drivers/ti/uart/aarch64/16550_console.S	\
 				drivers/arm/pl011/aarch64/pl011_console.S \
@@ -20,6 +21,40 @@
 				plat/rpi/common/rpi3_console_dual.c	\
 				${XLAT_TABLES_LIB_SRCS}
 
+ifeq (${DISCRETE_TPM},1)
+TPM2_MK := drivers/tpm/tpm2.mk
+$(info Including ${TPM2_MK})
+include ${TPM2_MK}
+endif
+
+ifeq (${TPM_INTERFACE},FIFO_SPI)
+PLAT_BL_COMMON_SOURCES	+=	drivers/gpio/gpio_spi.c		\
+				drivers/tpm/tpm2_slb9670/slb9670_gpio.c
+endif
+
+ifeq (${MEASURED_BOOT},1)
+MEASURED_BOOT_MK := drivers/measured_boot/event_log/event_log.mk
+$(info Including ${MEASURED_BOOT_MK})
+include ${MEASURED_BOOT_MK}
+
+PLAT_BL_COMMON_SOURCES	+=	$(TPM2_SOURCES)				\
+				${EVENT_LOG_SOURCES}
+
+BL1_SOURCES		+= 	plat/rpi/rpi3/rpi3_bl1_mboot.c
+BL2_SOURCES		+= 	plat/rpi/rpi3/rpi3_bl2_mboot.c		\
+				plat/rpi/rpi3/rpi3_dyn_cfg_helpers.c	\
+				common/fdt_wrappers.c			\
+				common/fdt_fixup.c
+
+CRYPTO_SOURCES		:=	drivers/auth/crypto_mod.c
+
+BL1_SOURCES		+=	${CRYPTO_SOURCES}
+BL2_SOURCES		+=	${CRYPTO_SOURCES}
+
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+
+endif
+
 BL1_SOURCES		+=	drivers/io/io_fip.c			\
 				drivers/io/io_memmap.c			\
 				drivers/io/io_storage.c			\
diff --git a/plat/rpi/rpi3/rpi3_bl1_mboot.c b/plat/rpi/rpi3/rpi3_bl1_mboot.c
new file mode 100644
index 0000000..4294365
--- /dev/null
+++ b/plat/rpi/rpi3/rpi3_bl1_mboot.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <common/ep_info.h>
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/gpio_spi.h>
+#include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/tpm/tpm2.h>
+#include <drivers/tpm/tpm2_chip.h>
+#include <drivers/tpm/tpm2_slb9670/slb9670_gpio.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <rpi_shared.h>
+
+/* Event Log data */
+uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE];
+
+/* RPI3 table with platform specific image IDs, names and PCRs */
+const event_log_metadata_t rpi3_event_log_metadata[] = {
+	{ 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 */
+};
+
+#if DISCRETE_TPM
+extern struct tpm_chip_data tpm_chip_data;
+#if (TPM_INTERFACE == FIFO_SPI)
+extern struct gpio_spi_data tpm_rpi3_gpio_data;
+struct spi_plat *spidev;
+#endif
+
+static void rpi3_bl1_tpm_early_interface_setup(void)
+{
+#if (TPM_INTERFACE == FIFO_SPI)
+	tpm2_slb9670_gpio_init(&tpm_rpi3_gpio_data);
+
+	tpm2_slb9670_reset_chip(&tpm_rpi3_gpio_data);
+
+	spidev = gpio_spi_init(&tpm_rpi3_gpio_data);
+#endif
+}
+#endif
+
+void bl1_plat_mboot_init(void)
+{
+#if DISCRETE_TPM
+	int rc;
+
+	rpi3_bl1_tpm_early_interface_setup();
+	rc = tpm_interface_init(&tpm_chip_data, 0);
+	if (rc != 0) {
+		ERROR("BL1: TPM interface init failed\n");
+		panic();
+	}
+	rc = tpm_startup(&tpm_chip_data, TPM_SU_CLEAR);
+	if (rc != 0) {
+		ERROR("BL1: TPM Startup failed\n");
+		panic();
+	}
+#endif
+
+	event_log_init(event_log, event_log + sizeof(event_log));
+	event_log_write_header();
+}
+
+void bl1_plat_mboot_finish(void)
+{
+	size_t event_log_cur_size;
+	image_desc_t *image_desc;
+	entry_point_info_t *ep_info;
+
+	event_log_cur_size = event_log_get_cur_size(event_log);
+	image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+	assert(image_desc != NULL);
+
+	/* Get the entry point info */
+	ep_info = &image_desc->ep_info;
+	ep_info->args.arg2 = (uint64_t) event_log;
+	ep_info->args.arg3 = (uint32_t) event_log_cur_size;
+
+#if DISCRETE_TPM
+	int rc;
+
+	/* relinquish control of TPM locality 0 and close interface */
+	rc = tpm_interface_close(&tpm_chip_data, 0);
+	if (rc != 0) {
+		ERROR("BL1: TPM interface close failed\n");
+		panic();
+	}
+#endif
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	int rc = 0;
+	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
+	const event_log_metadata_t *metadata_ptr = rpi3_event_log_metadata;
+
+	rc = event_log_measure(image_data->image_base, image_data->image_size, hash_data);
+	if (rc != 0) {
+		return rc;
+	}
+
+#if DISCRETE_TPM
+	rc = tpm_pcr_extend(&tpm_chip_data, 0, TPM_ALG_ID, hash_data, TCG_DIGEST_SIZE);
+	if (rc != 0) {
+		ERROR("BL1: TPM PCR-0 extend failed\n");
+		panic();
+	}
+#endif
+
+	while ((metadata_ptr->id != EVLOG_INVALID_ID) &&
+		(metadata_ptr->id != image_id)) {
+		metadata_ptr++;
+	}
+	assert(metadata_ptr->id != EVLOG_INVALID_ID);
+
+	event_log_record(hash_data, EV_POST_CODE, metadata_ptr);
+
+	/* Dump Event Log for user view */
+	dump_event_log((uint8_t *)event_log, event_log_get_cur_size(event_log));
+
+	return rc;
+}
diff --git a/plat/rpi/rpi3/rpi3_bl2_mboot.c b/plat/rpi/rpi3/rpi3_bl2_mboot.c
new file mode 100644
index 0000000..55c6923
--- /dev/null
+++ b/plat/rpi/rpi3/rpi3_bl2_mboot.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+#include "./include/rpi3_measured_boot.h"
+
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/gpio_spi.h>
+#include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/tpm/tpm2.h>
+#include <drivers/tpm/tpm2_chip.h>
+#include <drivers/tpm/tpm2_slb9670/slb9670_gpio.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <tools_share/tbbr_oid.h>
+
+/* RPI3 table with platform specific image IDs, names and PCRs */
+const event_log_metadata_t rpi3_event_log_metadata[] = {
+	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
+	{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
+
+	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
+};
+
+#if DISCRETE_TPM
+extern struct tpm_chip_data tpm_chip_data;
+#if (TPM_INTERFACE == FIFO_SPI)
+extern struct gpio_spi_data tpm_rpi3_gpio_data;
+struct spi_plat *spidev;
+#endif
+
+static void rpi3_bl2_tpm_early_interface_setup(void)
+{
+#if (TPM_INTERFACE == FIFO_SPI)
+	tpm2_slb9670_gpio_init(&tpm_rpi3_gpio_data);
+
+	spidev = gpio_spi_init(&tpm_rpi3_gpio_data);
+#endif
+}
+#endif
+
+static uint8_t *event_log_start;
+static size_t event_log_size;
+
+void bl2_plat_mboot_init(void)
+{
+	uint8_t *bl2_event_log_start;
+	uint8_t *bl2_event_log_finish;
+
+#if DISCRETE_TPM
+	int rc;
+
+	rpi3_bl2_tpm_early_interface_setup();
+	rc = tpm_interface_init(&tpm_chip_data, 0);
+	if (rc != 0) {
+		ERROR("BL2: TPM interface init failed\n");
+		panic();
+	}
+#endif
+
+	rpi3_mboot_fetch_eventlog_info(&event_log_start, &event_log_size);
+	bl2_event_log_start = event_log_start + event_log_size;
+	bl2_event_log_finish = event_log_start + PLAT_ARM_EVENT_LOG_MAX_SIZE;
+	event_log_init(bl2_event_log_start, bl2_event_log_finish);
+}
+
+void bl2_plat_mboot_finish(void)
+{
+	int rc;
+
+	/* Event Log address in Non-Secure memory */
+	uintptr_t ns_log_addr;
+
+	/* Event Log filled size */
+	size_t event_log_cur_size;
+
+	event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_start);
+
+	/* write the eventlog addr and size to NT_FW_CONFIG TPM entry */
+	rc = rpi3_set_nt_fw_info(event_log_cur_size, &ns_log_addr);
+	if (rc != 0) {
+		ERROR("%s(): Unable to update %s_FW_CONFIG\n",
+			__func__, "NT");
+		/*
+		 * fatal error due to Bl33 maintaining the assumption
+		 * that the eventlog is successfully passed via
+		 * NT_FW_CONFIG.
+		 */
+		panic();
+	}
+
+	/* Copy Event Log to Non-secure memory */
+	(void)memcpy((void *)ns_log_addr, (const void *)event_log_start,
+		     event_log_cur_size);
+
+	/* Ensure that the Event Log is visible in Non-secure memory */
+	flush_dcache_range(ns_log_addr, event_log_cur_size);
+
+	/* Dump Event Log for user view */
+	dump_event_log((uint8_t *)event_log_start, event_log_cur_size);
+
+#if DISCRETE_TPM
+	/* relinquish control of TPM locality 0 and close interface */
+	rc = tpm_interface_close(&tpm_chip_data, 0);
+	if (rc != 0) {
+		ERROR("BL2: TPM interface close failed\n");
+		panic();
+	}
+#endif
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	int rc = 0;
+
+	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
+	const event_log_metadata_t *metadata_ptr = rpi3_event_log_metadata;
+
+	/* Measure the payload with algorithm selected by EventLog driver */
+	rc = event_log_measure(image_data->image_base, image_data->image_size, hash_data);
+	if (rc != 0) {
+		return rc;
+	}
+
+#if DISCRETE_TPM
+	rc = tpm_pcr_extend(&tpm_chip_data, 0, TPM_ALG_ID, hash_data, TCG_DIGEST_SIZE);
+	if (rc != 0) {
+		ERROR("BL2: TPM PCR-0 extend failed\n");
+		panic();
+	}
+#endif
+
+	while ((metadata_ptr->id != EVLOG_INVALID_ID) &&
+		(metadata_ptr->id != image_id)) {
+		metadata_ptr++;
+	}
+	assert(metadata_ptr->id != EVLOG_INVALID_ID);
+
+	event_log_record(hash_data, EV_POST_CODE, metadata_ptr);
+
+	return rc;
+}
diff --git a/plat/rpi/rpi3/rpi3_bl2_setup.c b/plat/rpi/rpi3/rpi3_bl2_setup.c
index 80e4d8d..2f57b32 100644
--- a/plat/rpi/rpi3/rpi3_bl2_setup.c
+++ b/plat/rpi/rpi3/rpi3_bl2_setup.c
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 
-#include <platform_def.h>
+#include "./include/rpi3_measured_boot.h"
 
 #include <arch_helpers.h>
 #include <common/bl_common.h>
@@ -18,6 +18,7 @@
 #include <drivers/generic_delay_timer.h>
 #include <drivers/rpi3/gpio/rpi3_gpio.h>
 #include <drivers/rpi3/sdhost/rpi3_sdhost.h>
+#include <platform_def.h>
 
 #include <rpi_shared.h>
 
@@ -27,6 +28,10 @@
 /* Data structure which holds the MMC info */
 static struct mmc_device_info mmc_info;
 
+/* Variables that hold the eventlog addr and size for use in BL2 Measured Boot */
+static uint8_t *event_log_start;
+static size_t event_log_size;
+
 static void rpi3_sdhost_setup(void)
 {
 	struct rpi3_sdhost_params params;
@@ -41,6 +46,12 @@
 	rpi3_sdhost_init(&params, &mmc_info);
 }
 
+void rpi3_mboot_fetch_eventlog_info(uint8_t **eventlog_addr, size_t *eventlog_size)
+{
+	*eventlog_addr = event_log_start;
+	*eventlog_size = event_log_size;
+}
+
 /*******************************************************************************
  * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
  * in x0. This memory layout is sitting at the base of the free trusted SRAM.
@@ -67,6 +78,10 @@
 	/* Setup SDHost driver */
 	rpi3_sdhost_setup();
 
+	/* populate eventlog addr and size for use in bl2 mboot */
+	event_log_start = (uint8_t *)(uintptr_t)arg2;
+	event_log_size = arg3;
+
 	plat_rpi3_io_setup();
 }
 
diff --git a/plat/rpi/rpi3/rpi3_dyn_cfg_helpers.c b/plat/rpi/rpi3/rpi3_dyn_cfg_helpers.c
new file mode 100644
index 0000000..7c2e6e7
--- /dev/null
+++ b/plat/rpi/rpi3/rpi3_dyn_cfg_helpers.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2025, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/desc_image_load.h>
+#include <common/fdt_wrappers.h>
+#include <libfdt.h>
+#include <platform_def.h>
+
+#define DTB_PROP_HW_LOG_ADDR	"tpm_event_log_addr"
+#define DTB_PROP_HW_LOG_SIZE	"tpm_event_log_size"
+
+static int rpi3_event_log_fdt_init_overlay(uintptr_t dt_base, int dt_size)
+{
+	int ret;
+	int offset;
+	void *dtb = (void *)dt_base;
+
+	ret = fdt_create_empty_tree(dtb, dt_size);
+	if (ret < 0) {
+		ERROR("cannot create empty dtb tree: %s\n",
+		       fdt_strerror(ret));
+		return ret;
+	}
+
+	offset = fdt_path_offset(dtb, "/");
+	if (offset < 0) {
+		ERROR("cannot find root of the tree: %s\n",
+		       fdt_strerror(offset));
+		return offset;
+	}
+
+	offset = fdt_add_subnode(dtb, offset, "fragment@0");
+	if (offset < 0) {
+		ERROR("cannot add fragment node: %s\n",
+		       fdt_strerror(offset));
+		return offset;
+	}
+
+	ret = fdt_setprop_string(dtb, offset, "target-path", "/");
+	if (ret < 0) {
+		ERROR("cannot set target-path property: %s\n",
+		       fdt_strerror(ret));
+		return ret;
+	}
+
+	offset = fdt_add_subnode(dtb, offset, "__overlay__");
+	if (offset < 0) {
+		ERROR("cannot add __overlay__ node: %s\n",
+		       fdt_strerror(offset));
+		return ret;
+	}
+
+	offset = fdt_add_subnode(dtb, offset, "tpm_event_log");
+	if (offset < 0) {
+		ERROR("cannot add tpm_event_log node: %s\n",
+		       fdt_strerror(offset));
+		return offset;
+	}
+
+	ret = fdt_setprop_string(dtb, offset, "compatible",
+				 "arm,tpm_event_log");
+	if (ret < 0) {
+		ERROR("cannot set compatible property: %s\n",
+		       fdt_strerror(ret));
+		return ret;
+	}
+
+	ret = fdt_setprop_u64(dtb, offset, "tpm_event_log_addr", 0);
+	if (ret < 0) {
+		ERROR("cannot set tpm_event_log_addr property: %s\n",
+		       fdt_strerror(ret));
+		return ret;
+	}
+
+	ret = fdt_setprop_u32(dtb, offset, "tpm_event_log_size", 0);
+	if (ret < 0) {
+		ERROR("cannot set tpm_event_log_size property: %s\n",
+		       fdt_strerror(ret));
+		return ret;
+	}
+
+	return ret;
+}
+
+/*
+ * Write the Event Log address and its size in the DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+static int rpi3_set_event_log_info(uintptr_t config_base,
+				  uintptr_t log_addr, size_t log_size)
+{
+	/* As libfdt uses void *, we can't avoid this cast */
+	void *dtb = (void *)config_base;
+	/* compatible is set based on the following tpm_tis_spi guidelines from
+	 * https://www.kernel.org/doc/Documentation/devicetree/bindings
+	 * /security/tpm/tpm_tis_spi.txt
+	 */
+	const char *compatible_tpm = "arm,tpm_event_log";
+	uint64_t base = cpu_to_fdt64(log_addr);
+	uint32_t sz = cpu_to_fdt32(log_size);
+	int err, node;
+
+	err = fdt_open_into(dtb, dtb, PLAT_RPI3_DTO_MAX_SIZE);
+	if (err < 0) {
+		ERROR("Invalid Device Tree at %p: error %d\n", dtb, err);
+		return err;
+	}
+
+	/*
+	 * 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;
+	}
+
+	/*
+	 * Find the TPM node in device tree.
+	 */
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible_tpm);
+	if (node < 0) {
+		ERROR("The compatible property '%s' not%s", compatible_tpm,
+			" found in the config\n");
+		return node;
+	}
+
+	err = fdt_setprop(dtb, node, DTB_PROP_HW_LOG_ADDR, &base, 8);
+	if (err < 0) {
+		ERROR("Failed to add log addr err %d\n", err);
+		return err;
+	}
+
+	err = fdt_setprop(dtb, node, DTB_PROP_HW_LOG_SIZE, &sz, 4);
+	if (err < 0) {
+		ERROR("Failed to add log size err %d\n", err);
+		return err;
+	}
+
+	err = fdt_pack(dtb);
+	if (err < 0) {
+		ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, err);
+		return err;
+	}
+
+	/*
+	 * 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 Event Log address and its size
+ * in the RPi3 DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+int rpi3_set_nt_fw_info(size_t log_size, uintptr_t *ns_log_addr)
+{
+	uintptr_t ns_addr;
+	int err;
+
+	assert(ns_log_addr != NULL);
+
+	ns_addr = PLAT_RPI3_DTO_BASE + PLAT_RPI3_DTO_MAX_SIZE;
+
+	rpi3_event_log_fdt_init_overlay(PLAT_RPI3_DTO_BASE,
+					  PLAT_RPI3_DTO_MAX_SIZE);
+
+	/* Write the Event Log address and its size in the DTB */
+	err = rpi3_set_event_log_info(PLAT_RPI3_DTO_BASE,
+					ns_addr, log_size);
+
+	/* Return Event Log address in Non-secure memory */
+	*ns_log_addr = (err < 0) ? 0UL : ns_addr;
+	return err;
+}
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index 9af8bb2..679f935 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -56,8 +56,7 @@
 
 	for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
 		uint32_t base_irq = reg_num << ISENABLER_SHIFT;
-		isenabler1 += (reg_num << 2);
-		uint32_t reg = mmio_read_32((uint64_t)isenabler1);
+		uint32_t reg = mmio_read_32((uint64_t)(isenabler1 + (reg_num << 2)));
 
 		if (reg == 0U) {
 			continue;
diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index 8cf8de0..a3886a4 100644
--- a/plat/xilinx/versal/include/platform_def.h
+++ b/plat/xilinx/versal/include/platform_def.h
@@ -64,6 +64,12 @@
 #endif
 
 /*******************************************************************************
+ * HIGH and LOW DDR MAX definitions
+ ******************************************************************************/
+#define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
+#define PLAT_DDR_HIGHMEM_MAX		U(0x100000000)
+
+/*******************************************************************************
  * TSP  specific defines.
  ******************************************************************************/
 #define TSP_SEC_MEM_BASE		BL32_BASE
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index b976267..396d7c7 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -194,6 +194,18 @@
 	}
 }
 
+static int32_t versal_validate_ns_entrypoint(uint64_t ns_entrypoint)
+{
+	int32_t ret = PSCI_E_SUCCESS;
+
+	if (((ns_entrypoint >= PLAT_DDR_LOWMEM_MAX) && (ns_entrypoint <= PLAT_DDR_HIGHMEM_MAX)) ||
+		((ns_entrypoint >= BL31_BASE) && (ns_entrypoint <= BL31_LIMIT))) {
+		ret = PSCI_E_INVALID_ADDRESS;
+	}
+
+	return ret;
+}
+
 /**
  * versal_pwr_domain_off() - This function performs actions to turn off core.
  * @target_state: Targated state.
@@ -291,6 +303,7 @@
 	.pwr_domain_suspend_finish	= versal_pwr_domain_suspend_finish,
 	.system_off			= versal_system_off,
 	.system_reset			= versal_system_reset,
+	.validate_ns_entrypoint		= versal_validate_ns_entrypoint,
 	.validate_power_state		= versal_validate_power_state,
 	.get_sys_suspend_power_state	= versal_get_sys_suspend_power_state,
 };
diff --git a/plat/xilinx/versal_net/include/platform_def.h b/plat/xilinx/versal_net/include/platform_def.h
index a7ff84e..ae49450 100644
--- a/plat/xilinx/versal_net/include/platform_def.h
+++ b/plat/xilinx/versal_net/include/platform_def.h
@@ -73,6 +73,12 @@
 #endif
 
 /*******************************************************************************
+ * HIGH and LOW DDR MAX definitions
+ ******************************************************************************/
+#define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
+#define PLAT_DDR_HIGHMEM_MAX		U(0x100000000)
+
+/*******************************************************************************
  * TSP  specific defines.
  ******************************************************************************/
 #define TSP_SEC_MEM_BASE		BL32_BASE
@@ -84,7 +90,6 @@
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
  ******************************************************************************/
-#define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32U)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32U)
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index a76832e..eb926ee 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -103,6 +103,18 @@
 	return;
 }
 
+static int32_t versal_net_validate_ns_entrypoint(uint64_t ns_entrypoint)
+{
+	int32_t ret = PSCI_E_SUCCESS;
+
+	if (((ns_entrypoint >= PLAT_DDR_LOWMEM_MAX) && (ns_entrypoint <= PLAT_DDR_HIGHMEM_MAX)) ||
+		((ns_entrypoint >= BL31_BASE) && (ns_entrypoint <= BL31_LIMIT))) {
+		ret = PSCI_E_INVALID_ADDRESS;
+	}
+
+	return ret;
+}
+
 /**
  * versal_net_system_reset() - This function sends the reset request to firmware
  *                             for the system to reset. This function does not
@@ -303,6 +315,7 @@
 	.pwr_domain_suspend_finish      = versal_net_pwr_domain_suspend_finish,
 	.system_off                     = versal_net_system_off,
 	.system_reset                   = versal_net_system_reset,
+	.validate_ns_entrypoint		= versal_net_validate_ns_entrypoint,
 	.validate_power_state           = versal_net_validate_power_state,
 	.get_sys_suspend_power_state    = versal_net_get_sys_suspend_power_state,
 };
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 412238d..822919b 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -406,7 +406,7 @@
 	uint32_t ret = 0U;
 
 	if (ver == ZYNQMP_CSU_VERSION_QEMU) {
-		ret = 65000000U;
+		ret = 62500000U;
 	} else {
 		ret = mmio_read_32((uint64_t)IOU_SCNTRS_BASEFREQ);
 	}
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 9a9c8d1..bf6ed58 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -75,6 +75,12 @@
 #endif
 
 /*******************************************************************************
+ * HIGH and LOW DDR MAX definitions.
+ ******************************************************************************/
+#define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
+#define PLAT_DDR_HIGHMEM_MAX		U(0x100000000)
+
+/*******************************************************************************
  * TSP  specific defines.
  ******************************************************************************/
 #define TSP_SEC_MEM_BASE		BL32_BASE
@@ -87,7 +93,6 @@
  * Platform specific page table and MMU setup constants
  ******************************************************************************/
 #define XILINX_OF_BOARD_DTB_MAX_SIZE	U(0x200000)
-#define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
 #define PLAT_OCM_BASE			U(0xFFFC0000)
 #define PLAT_OCM_LIMIT			U(0xFFFFFFFF)
 
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index 3fae407..d2faa37 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -193,6 +193,18 @@
 	}
 }
 
+static int32_t zynqmp_validate_ns_entrypoint(uint64_t ns_entrypoint)
+{
+	int32_t ret = PSCI_E_SUCCESS;
+
+	if (((ns_entrypoint >= PLAT_DDR_LOWMEM_MAX) && (ns_entrypoint <= PLAT_DDR_HIGHMEM_MAX)) ||
+		((ns_entrypoint >= BL31_BASE) && (ns_entrypoint <= BL31_LIMIT))) {
+		ret = PSCI_E_INVALID_ADDRESS;
+	}
+
+	return ret;
+}
+
 static int32_t zynqmp_validate_power_state(uint32_t power_state,
 				psci_power_state_t *req_state)
 {
@@ -235,6 +247,7 @@
 	.pwr_domain_suspend_finish	= zynqmp_pwr_domain_suspend_finish,
 	.system_off			= zynqmp_system_off,
 	.system_reset			= zynqmp_system_reset,
+	.validate_ns_entrypoint		= zynqmp_validate_ns_entrypoint,
 	.validate_power_state		= zynqmp_validate_power_state,
 	.get_sys_suspend_power_state	= zynqmp_get_sys_suspend_power_state,
 };
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 5ffd9ef..849e38a 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -123,7 +123,7 @@
 		.name = "qspi0",
 		.regval = 0x02,
 		.group_base = PINCTRL_GRP_QSPI0_0,
-		.group_size = PINCTRL_GRP_QSPI0_0 - PINCTRL_GRP_QSPI0_0 + 1U,
+		.group_size = PINCTRL_GRP_QSPI0_1 - PINCTRL_GRP_QSPI0_0 + 1U,
 	},
 	[PINCTRL_FUNC_QSPI_FBCLK] = {
 		.name = "qspi_fbclk",
@@ -135,7 +135,7 @@
 		.name = "qspi_ss",
 		.regval = 0x02,
 		.group_base = PINCTRL_GRP_QSPI_SS,
-		.group_size = PINCTRL_GRP_QSPI_SS - PINCTRL_GRP_QSPI_SS + 1U,
+		.group_size = PINCTRL_GRP_QSPI_SS_1 - PINCTRL_GRP_QSPI_SS + 1U,
 	},
 	[PINCTRL_FUNC_SPI0] = {
 		.name = "spi0",
@@ -383,6 +383,7 @@
 	[PINCTRL_PIN_0] = {
 		.groups = &((uint16_t []) {
 			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_QSPI0_1,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_TESTSCAN0_0,
@@ -401,6 +402,7 @@
 	[PINCTRL_PIN_1] = {
 		.groups = &((uint16_t []) {
 			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_QSPI0_1,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_TESTSCAN0_0,
@@ -419,6 +421,7 @@
 	[PINCTRL_PIN_2] = {
 		.groups = &((uint16_t []) {
 			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_QSPI0_1,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_TESTSCAN0_0,
@@ -437,6 +440,7 @@
 	[PINCTRL_PIN_3] = {
 		.groups = &((uint16_t []) {
 			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_QSPI0_1,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_TESTSCAN0_0,
@@ -455,6 +459,7 @@
 	[PINCTRL_PIN_4] = {
 		.groups = &((uint16_t []) {
 			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_QSPI0_1,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_TESTSCAN0_0,
@@ -473,6 +478,7 @@
 	[PINCTRL_PIN_5] = {
 		.groups = &((uint16_t []) {
 			PINCTRL_GRP_QSPI_SS,
+			PINCTRL_GRP_QSPI_SS_1,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_RESERVED,
 			PINCTRL_GRP_TESTSCAN0_0,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
index 277af4b..cb3b62e 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -184,7 +185,9 @@
 	PINCTRL_GRP_MDIO2_0,
 	PINCTRL_GRP_MDIO3_0,
 	PINCTRL_GRP_QSPI0_0,
+	PINCTRL_GRP_QSPI0_1,
 	PINCTRL_GRP_QSPI_SS,
+	PINCTRL_GRP_QSPI_SS_1,
 	PINCTRL_GRP_QSPI_FBCLK,
 	PINCTRL_GRP_SPI0_0,
 	PINCTRL_GRP_SPI0_1,
diff --git a/poetry.lock b/poetry.lock
index d05e199..6bfbc43 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand.
+# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
 
 [[package]]
 name = "alabaster"
@@ -6,6 +6,7 @@
 description = "A configurable sidebar-enabled Sphinx theme"
 optional = false
 python-versions = ">=3.6"
+groups = ["docs"]
 files = [
     {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
     {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
@@ -17,6 +18,7 @@
 description = "Powerful and Lightweight Python Tree Data Structure with various plugins"
 optional = false
 python-versions = ">=3.7.2,<4"
+groups = ["main"]
 files = [
     {file = "anytree-2.12.1-py3-none-any.whl", hash = "sha256:5ea9e61caf96db1e5b3d0a914378d2cd83c269dfce1fb8242ce96589fa3382f0"},
     {file = "anytree-2.12.1.tar.gz", hash = "sha256:244def434ccf31b668ed282954e5d315b4e066c4940b94aff4a7962d85947830"},
@@ -31,6 +33,7 @@
 description = "Internationalization utilities"
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
 files = [
     {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"},
     {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"},
@@ -48,6 +51,7 @@
 description = "A simple, correct Python build frontend"
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
 files = [
     {file = "build-1.2.2-py3-none-any.whl", hash = "sha256:277ccc71619d98afdd841a0e96ac9fe1593b823af481d3b0cea748e8894e0613"},
     {file = "build-1.2.2.tar.gz", hash = "sha256:119b2fb462adef986483438377a13b2f42064a2a3a4161f24a0cca698a07ac8c"},
@@ -62,20 +66,21 @@
 
 [package.extras]
 docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"]
-test = ["build[uv,virtualenv]", "filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "setuptools (>=56.0.0)", "setuptools (>=67.8.0)", "wheel (>=0.36.0)"]
+test = ["build[uv,virtualenv]", "filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0) ; python_version < \"3.10\"", "setuptools (>=56.0.0) ; python_version == \"3.10\"", "setuptools (>=56.0.0) ; python_version == \"3.11\"", "setuptools (>=67.8.0) ; python_version >= \"3.12\"", "wheel (>=0.36.0)"]
 typing = ["build[uv]", "importlib-metadata (>=5.1)", "mypy (>=1.9.0,<1.10.0)", "tomli", "typing-extensions (>=3.7.4.3)"]
 uv = ["uv (>=0.1.18)"]
 virtualenv = ["virtualenv (>=20.0.35)"]
 
 [[package]]
 name = "cachetools"
-version = "5.5.0"
+version = "5.5.2"
 description = "Extensible memoizing collections and decorators"
 optional = false
 python-versions = ">=3.7"
+groups = ["main"]
 files = [
-    {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"},
-    {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"},
+    {file = "cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a"},
+    {file = "cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4"},
 ]
 
 [[package]]
@@ -84,6 +89,7 @@
 description = "Python package for providing Mozilla's CA Bundle."
 optional = false
 python-versions = ">=3.6"
+groups = ["docs"]
 files = [
     {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
     {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
@@ -95,6 +101,7 @@
 description = "Universal encoding detector for Python 3"
 optional = false
 python-versions = ">=3.7"
+groups = ["main"]
 files = [
     {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
     {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
@@ -106,6 +113,7 @@
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
 optional = false
 python-versions = ">=3.7.0"
+groups = ["docs"]
 files = [
     {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
     {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
@@ -201,13 +209,14 @@
 
 [[package]]
 name = "click"
-version = "8.1.7"
+version = "8.1.8"
 description = "Composable command line interface toolkit"
 optional = false
 python-versions = ">=3.7"
+groups = ["main", "ci", "docs"]
 files = [
-    {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
-    {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
+    {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"},
+    {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"},
 ]
 
 [package.dependencies]
@@ -219,10 +228,12 @@
 description = "Cross-platform colored terminal text."
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+groups = ["main", "ci", "docs"]
 files = [
     {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
     {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
 ]
+markers = {ci = "platform_system == \"Windows\"", docs = "platform_system == \"Windows\" or sys_platform == \"win32\" or os_name == \"nt\""}
 
 [[package]]
 name = "commonmark"
@@ -230,6 +241,7 @@
 description = "Python parser for the CommonMark Markdown spec"
 optional = false
 python-versions = "*"
+groups = ["main"]
 files = [
     {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
     {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
@@ -244,6 +256,7 @@
 description = "CoT-dt2c Tool is a python script to convert CoT DT file into corresponding C file"
 optional = false
 python-versions = "^3.8"
+groups = ["main"]
 files = []
 develop = true
 
@@ -264,6 +277,7 @@
 description = "Distribution utilities"
 optional = false
 python-versions = "*"
+groups = ["main"]
 files = [
     {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"},
     {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"},
@@ -275,6 +289,7 @@
 description = "Docutils -- Python Documentation Utilities"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+groups = ["docs"]
 files = [
     {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"},
     {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"},
@@ -286,6 +301,7 @@
 description = "Flattened Device Tree Python Module"
 optional = false
 python-versions = ">=3.5"
+groups = ["ci"]
 files = [
     {file = "fdt-0.3.3-py3-none-any.whl", hash = "sha256:6b2fae2e8dfa38e9b0f9666aa001dd25be74e893d293a8d60001438f732e9e47"},
     {file = "fdt-0.3.3.tar.gz", hash = "sha256:81a215930fef2ab8894913c4f474105bb53e14f07129fe07cb6eff2d5fdf26d2"},
@@ -293,19 +309,20 @@
 
 [[package]]
 name = "filelock"
-version = "3.16.0"
+version = "3.16.1"
 description = "A platform independent file lock."
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
-    {file = "filelock-3.16.0-py3-none-any.whl", hash = "sha256:f6ed4c963184f4c84dd5557ce8fece759a3724b37b80c6c4f20a2f63a4dc6609"},
-    {file = "filelock-3.16.0.tar.gz", hash = "sha256:81de9eb8453c769b63369f87f11131a7ab04e367f8d97ad39dc230daa07e3bec"},
+    {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"},
+    {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"},
 ]
 
 [package.extras]
-docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
-testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.1.1)", "pytest (>=8.3.2)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.3)"]
-typing = ["typing-extensions (>=4.12.2)"]
+docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"]
+typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""]
 
 [[package]]
 name = "idna"
@@ -313,6 +330,7 @@
 description = "Internationalized Domain Names in Applications (IDNA)"
 optional = false
 python-versions = ">=3.6"
+groups = ["docs"]
 files = [
     {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"},
     {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"},
@@ -320,50 +338,51 @@
 
 [[package]]
 name = "igraph"
-version = "0.11.6"
+version = "0.11.8"
 description = "High performance graph data structures and algorithms"
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
-    {file = "igraph-0.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3f8b837181e8e87676be3873ce87cc92cc234efd58a2da2f6b4e050db150fcf4"},
-    {file = "igraph-0.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:245c4b7d7657849eff80416f5df4525c8fc44c74a981ee4d44f0ef2612c3bada"},
-    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdb7be3d165073c0136295c0808e9edc57ba096cdb26e94086abb04561f7a292"},
-    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58974e20df2986a1ae52a16e51ecb387cc0cbeb41c5c0ddff4d373a1bbf1d9c5"},
-    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bef14de5e8ab70724a43808b1ed14aaa6fe1002f87e592289027a3827a8f44a"},
-    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:86c1e98de2e32d074df8510bf18abfa1f4c5fda4cb28a009985a5d746b0c0125"},
-    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ebc5b3d702158abeb2e4d2414374586a2b932e1a07e48352b470600e1733d528"},
-    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0efe6d0fb22d3987a800eb3857ed04df9eb4c5dddd0998be05232cb646f1c337"},
-    {file = "igraph-0.11.6-cp38-cp38-win32.whl", hash = "sha256:f4e68b27497b1c8ada2fb2bc35ef3fa7b0d72e84306b3d648d3de240fc618c32"},
-    {file = "igraph-0.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:5665b33dfbfca5f54ce9b4fea6b97903bd0e99fb1b02acf5e57e600bdfa5a355"},
-    {file = "igraph-0.11.6-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8aabef03d787b519d1075dfc0da4a1109fb113b941334883e3e7947ac30a459e"},
-    {file = "igraph-0.11.6-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1f2cc4a518d99cdf6cae514f85e93e56852bc8c325b3abb96037d1d690b5975f"},
-    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1e859238be52ab8ccc614d18f9362942bc88ce543afc12548f81ae99b10801d"},
-    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d61fbe5e85eb4ae9efe08c461f9bdeedb02a2b5739fbc223d324a71f40a28be2"},
-    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6620ba39df29fd42151becf82309b54e57148233c9c3ef890eed62e25eed8a5"},
-    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59666589bb3d07f310cda2c5106a8adeeb77c2ef27fecf1c6438b6091f4ca69d"},
-    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:8750b6d6caebf199cf7dc41c931f58e330153779707391e30f0a29f02666fb6e"},
-    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:967d6f2c30fe94317da15e459374d0fb8ca3e56020412f201ecd07dd5b5352f2"},
-    {file = "igraph-0.11.6-cp39-abi3-win32.whl", hash = "sha256:9744f95a67319eb6cb487ceabf30f5d7940de34bada51f0ba63adbd23e0f94ad"},
-    {file = "igraph-0.11.6-cp39-abi3-win_amd64.whl", hash = "sha256:b80e69eb11faa9c57330a9ffebdde5808966efe1c1f638d4d4827ea04df7aca8"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0329c16092e2ea7930d5f8368666ce7cb704900cc0ea04e4afe9ea1dd46e44af"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:21752313f449bd8688e5688e95ea7231cea5e9199c7162535029be0d9af848ac"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea25e136c6c4161f53ff58868b23ff6c845193050ab0e502236d68e5d4174e32"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac84433a03aef15e4b810010b08882b09854a3669450ccf31e392dbe295d2a66"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac697a44e3573169fa2b28c9c37dcf9cf01e0f558b845dd7123860d4c7c8fb89"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bdeae8bf35316eb1fb27bf667dcf5ecf5fcfb0b8f51831bc1b00c39c09c2d73b"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ad7e4aa442935de72554b96733bf6d7f09eac5cee97988a2562bdd3ca173cfa3"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d2818780358a686178866d01568b9df1f29678581734ad7a78882bab54df004"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2352276a20d979f1dea360af4202bb9f0c9a7d2c77f51815c0e625165e82013d"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:687fdab543b507d622fa3043f4227e5b26dc61dcf8ff8c0919fccddcc655f8b8"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57f7f8214cd48c9a4d97f7346a4152ba2d4ac95fb5ee0df4ecf224fce4ba3d14"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2b9cc69ede53f76ffae03b066609aa90184dd68ef15da8c104a97cebb9210838"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:591e1e447c3f0092daf7613a3eaedab83f9a0b0adbaf7702724c5117ded038a5"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ca558eb331bc687bc33e5cd23717e22676e9412f8cda3a31d30c996a0487610d"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf43c30e08debb087c9e3da69aa5cf1b6732968da34d55a614e3421b9a452146"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d38e8d7db72b187d9d2211d0d06b3271fa9f32b04d49d789e2859b5480db0d0"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a318b059051ff78144a1c3cb880f4d933c812bcdb3d833a49cd7168d0427672"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2c54027add809b3c5b6685b8deca4ea4763fd000b9ea45c7ee46b7c9d61ff15e"},
-    {file = "igraph-0.11.6.tar.gz", hash = "sha256:837f233256c3319f2a35a6a80d94eafe47b43791ef4c6f9e9871061341ac8e28"},
+    {file = "igraph-0.11.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9a7aa8e65e7b9ddfe66f9473ce93863f40fccac26b24dc3f56e63159641c9946"},
+    {file = "igraph-0.11.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9e953e1c5e9c5712a48df5cea93963be84aa26618cdae341b4a6b07761f56a45"},
+    {file = "igraph-0.11.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9baf699fdd10491e9a0842e546e630165c49c78d21ac4aaa9fb434ab4a817458"},
+    {file = "igraph-0.11.8-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:434e35d935675caddac3221863b43a02085c7f66030eda542f0dd9fc36e1f8ff"},
+    {file = "igraph-0.11.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:745e5d7aebca7e9c16f882041718c8ceeb404a5c7201cb8685f57b0e19ebe24d"},
+    {file = "igraph-0.11.8-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:24c97ce9f40a358a8d6ff9c27fab0e4617068aaeeb5448247308c67519b91fa2"},
+    {file = "igraph-0.11.8-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c89ab68f076528736d4ed56a01983d7fd433f50b08c58bee7ded2326a4eacda1"},
+    {file = "igraph-0.11.8-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d964fc35d65ce67b121e4dcfd7d3479fb3eeb232b6a346a217e397c7d5c5f124"},
+    {file = "igraph-0.11.8-cp38-cp38-win32.whl", hash = "sha256:511b036c876fdbfc919a6a4c72b0335fd2a6a3249e5e4312b660390213875afb"},
+    {file = "igraph-0.11.8-cp38-cp38-win_amd64.whl", hash = "sha256:417b8375c1c9adbb431f7481a6cae6f9e440db81d8d4ee6fa5d2c2983148930a"},
+    {file = "igraph-0.11.8-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:92c47ceb9f4c95ff7461cd94eaec55e901dbc59f6e51f4244d2dd064f31c5491"},
+    {file = "igraph-0.11.8-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:3a2afdb046b602fea71ca18aff6c72165de5002ec38d0dcf1275e34ecd0d9d02"},
+    {file = "igraph-0.11.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7870fb72fd9e9218940262671fb79baf281ef066aa1cd35adc092ce9ad39a038"},
+    {file = "igraph-0.11.8-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8108138ad605714761bc6d526feab54074904a99c47dcaabc269ed7b45e7650"},
+    {file = "igraph-0.11.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2e3abe641622cd9c95eb152c97caa22e68257a524cc1851a099b066f8f5c5f3"},
+    {file = "igraph-0.11.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b546eaa9461473a65bb56a51672c6aeb898b737d5e86c3efa1b1bf520ee4b031"},
+    {file = "igraph-0.11.8-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:178ef859135ac5075a7159e6826a546b7340cf45a01a928c2a0c24c32e3dfa63"},
+    {file = "igraph-0.11.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a68ae7b6324e9c4cb1d04ce75b6e0f67974433fc7667895f1e25bf4f4c6fd530"},
+    {file = "igraph-0.11.8-cp39-abi3-win32.whl", hash = "sha256:cc93d2f97f93bf30c2027c31e9e1aa088a3c60cdfeb6b33e0259e4b40b4c5597"},
+    {file = "igraph-0.11.8-cp39-abi3-win_amd64.whl", hash = "sha256:248831a6162130f16909c1f776cc246b48f692339ea4baca489cad4ed8dc0e13"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f0a8cad10406fba28c4b0199dfb491bcfdf1cdd3a56feeb52bb3b1cd724d04b4"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1c11127a58ac2fc8062dac9f20ef612aff1b09f5f9d3e90800c4817229d0a0bc"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17d79bfb170b8c195fe6bacfa1c906817e8e812417c7e6a8e15f0bcf9b0775a8"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9de09a26d7aae4d83338497cfd2d107d3ee3a2e9335b9db4b6c73a089e8cf47"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6559e2c925ed2ac608103adfd1dec9ccb9a04ddc7ad1d9d2a7db46dda6b1955"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6c17658b367be4f725a253678bfe799d9fe4d4e5c01ad82449cf8f2e9917937c"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d4971b4fcb005ed72f630a5f4c9bb80f10153471fe30846810f63beb3e282a19"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d7b1eaa3563c1e2dda940c1f154fefe9b3b257da8e8251af443cdc69a039480"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35438d6d69a73288949a80f1eb84597e783486cd71a5cdf5862c0db7a7cbd5c5"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09c609c5d6a844582a10085c18c1c15d14b2f9fd3be59fed3feaa4be091d671f"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9b836baa221027f1781ebcff05f1b23339a51a63eb70948ebaba5641efc060a"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:caf4a178f7fb7890195c9fb358dbef0ed4a4f5323f529ea14a0f64da4c05f564"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e702a436935d3e127f6affff397ebbab48b522434bd8d6f15cfb1ab5d940e7d5"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bcad4d052785fe9b076f5aca6e870e2fae35373b09867477adc7307f2692a36"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d420cd48353e7c138bc39a118c3a01dc41aeba38486cca1524a960a755016171"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ae9486a52da72d2ab634b92e17a969dc4e8e83303384329b903830ad67315e5"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4e36a4f8a40bb4ffc8aa08c1cfe6fa3dfa78393cf65165bd9d59e6ac24a2468"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f4048b843be54a77bc7206ce8c58825a9b1b42748c1713699034dc4f7df36f73"},
+    {file = "igraph-0.11.8.tar.gz", hash = "sha256:d7dc1404567ba3b0ea1bf8b5fa6e101617915c8ad11ea5a9f925a40bf4adad7d"},
 ]
 
 [package.dependencies]
@@ -372,10 +391,10 @@
 [package.extras]
 cairo = ["cairocffi (>=1.2.0)"]
 doc = ["Sphinx (>=7.0.0)", "pydoctor (>=23.4.0)", "sphinx-gallery (>=0.14.0)", "sphinx-rtd-theme (>=1.3.0)"]
-matplotlib = ["matplotlib (>=3.6.0)"]
+matplotlib = ["matplotlib (>=3.6.0) ; platform_python_implementation != \"PyPy\""]
 plotly = ["plotly (>=5.3.0)"]
 plotting = ["cairocffi (>=1.2.0)"]
-test = ["Pillow (>=9)", "cairocffi (>=1.2.0)", "matplotlib (>=3.6.0)", "networkx (>=2.5)", "numpy (>=1.19.0)", "pandas (>=1.1.0)", "plotly (>=5.3.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)", "scipy (>=1.5.0)"]
+test = ["Pillow (>=9) ; platform_python_implementation != \"PyPy\"", "cairocffi (>=1.2.0)", "matplotlib (>=3.6.0) ; platform_python_implementation != \"PyPy\"", "networkx (>=2.5)", "numpy (>=1.19.0) ; platform_python_implementation != \"PyPy\"", "pandas (>=1.1.0) ; platform_python_implementation != \"PyPy\"", "plotly (>=5.3.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)", "scipy (>=1.5.0) ; platform_python_implementation != \"PyPy\""]
 test-musl = ["cairocffi (>=1.2.0)", "networkx (>=2.5)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)"]
 
 [[package]]
@@ -384,6 +403,7 @@
 description = "Getting image size from png/jpeg/jpeg2000/gif file"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+groups = ["docs"]
 files = [
     {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
     {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
@@ -395,6 +415,8 @@
 description = "Read metadata from Python packages"
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
+markers = "python_full_version < \"3.10.2\""
 files = [
     {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"},
     {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"},
@@ -406,17 +428,18 @@
 [package.extras]
 doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
 perf = ["ipython"]
-test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"]
+test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
 
 [[package]]
 name = "jinja2"
-version = "3.1.5"
+version = "3.1.6"
 description = "A very fast and expressive template engine."
 optional = false
 python-versions = ">=3.7"
+groups = ["main", "docs"]
 files = [
-    {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"},
-    {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"},
+    {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"},
+    {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"},
 ]
 
 [package.dependencies]
@@ -431,6 +454,7 @@
 description = "Python port of markdown-it. Markdown parsing, done right!"
 optional = false
 python-versions = ">=3.7"
+groups = ["docs"]
 files = [
     {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"},
     {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"},
@@ -455,6 +479,7 @@
 description = "Safely add untrusted strings to HTML/XML markup."
 optional = false
 python-versions = ">=3.7"
+groups = ["main", "docs"]
 files = [
     {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
     {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
@@ -524,6 +549,7 @@
 description = "Collection of plugins for markdown-it-py"
 optional = false
 python-versions = ">=3.7"
+groups = ["docs"]
 files = [
     {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"},
     {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"},
@@ -543,6 +569,7 @@
 description = "Markdown URL utilities"
 optional = false
 python-versions = ">=3.7"
+groups = ["docs"]
 files = [
     {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
     {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
@@ -554,6 +581,7 @@
 description = "A tool for analysis of static memory consumption by TF-A images"
 optional = false
 python-versions = "^3.8.0"
+groups = ["main"]
 files = []
 develop = true
 
@@ -573,6 +601,7 @@
 description = "An extended commonmark compliant parser, with bridges to docutils & sphinx."
 optional = false
 python-versions = ">=3.7"
+groups = ["docs"]
 files = [
     {file = "myst-parser-0.18.1.tar.gz", hash = "sha256:79317f4bb2c13053dd6e64f9da1ba1da6cd9c40c8a430c447a7b146a594c246d"},
     {file = "myst_parser-0.18.1-py3-none-any.whl", hash = "sha256:61b275b85d9f58aa327f370913ae1bec26ebad372cc99f3ab85c8ec3ee8d9fb8"},
@@ -595,13 +624,14 @@
 
 [[package]]
 name = "packaging"
-version = "24.1"
+version = "24.2"
 description = "Core utilities for Python packages"
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "docs"]
 files = [
-    {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
-    {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
+    {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
+    {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
 ]
 
 [[package]]
@@ -610,6 +640,7 @@
 description = "The PyPA recommended tool for installing Python packages."
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
 files = [
     {file = "pip-24.2-py3-none-any.whl", hash = "sha256:2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2"},
     {file = "pip-24.2.tar.gz", hash = "sha256:5b5e490b5e9cb275c879595064adce9ebd31b854e3e803740b72f9ccf34a45b8"},
@@ -621,6 +652,7 @@
 description = "pip-tools keeps your pinned dependencies fresh."
 optional = false
 python-versions = ">=3.7"
+groups = ["docs"]
 files = [
     {file = "pip-tools-6.14.0.tar.gz", hash = "sha256:06366be0e08d86b416407333e998b4d305d5bd925151b08942ed149380ba3e47"},
     {file = "pip_tools-6.14.0-py3-none-any.whl", hash = "sha256:c5ad042cd27c0b343b10db1db7f77a7d087beafbec59ae6df1bba4d3368dfe8c"},
@@ -640,13 +672,14 @@
 
 [[package]]
 name = "platformdirs"
-version = "4.3.2"
+version = "4.3.6"
 description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
-    {file = "platformdirs-4.3.2-py3-none-any.whl", hash = "sha256:eb1c8582560b34ed4ba105009a4badf7f6f85768b30126f351328507b2beb617"},
-    {file = "platformdirs-4.3.2.tar.gz", hash = "sha256:9e5e27a08aa095dd127b9f2e764d74254f482fef22b0970773bfba79d091ab8c"},
+    {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
+    {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
 ]
 
 [package.extras]
@@ -656,13 +689,14 @@
 
 [[package]]
 name = "plotly"
-version = "5.24.0"
+version = "5.24.1"
 description = "An open-source, interactive data visualization library for Python"
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
-    {file = "plotly-5.24.0-py3-none-any.whl", hash = "sha256:0e54efe52c8cef899f7daa41be9ed97dfb6be622613a2a8f56a86a0634b2b67e"},
-    {file = "plotly-5.24.0.tar.gz", hash = "sha256:eae9f4f54448682442c92c1e97148e3ad0c52f0cf86306e1b76daba24add554a"},
+    {file = "plotly-5.24.1-py3-none-any.whl", hash = "sha256:f67073a1e637eb0dc3e46324d9d51e2fe76e9727c892dde64ddf1e1b51f29089"},
+    {file = "plotly-5.24.1.tar.gz", hash = "sha256:dbc8ac8339d248a4bcc36e08a5659bacfe1b079390b8953533f4eb22169b4bae"},
 ]
 
 [package.dependencies]
@@ -675,6 +709,7 @@
 description = "plugin and hook calling mechanisms for python"
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
     {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
     {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
@@ -690,6 +725,7 @@
 description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format"
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
     {file = "prettytable-3.11.0-py3-none-any.whl", hash = "sha256:aa17083feb6c71da11a68b2c213b04675c4af4ce9c541762632ca3f2cb3546dd"},
     {file = "prettytable-3.11.0.tar.gz", hash = "sha256:7e23ca1e68bbfd06ba8de98bf553bf3493264c96d5e8a615c0471025deeba722"},
@@ -707,6 +743,7 @@
 description = "A library for parsing Devicetree Source v1"
 optional = false
 python-versions = ">=3.5"
+groups = ["main"]
 files = [
     {file = "pydevicetree-0.0.13-py3-none-any.whl", hash = "sha256:d61c695cec925b90a8b5740053f4b604e51154a9b36e62a2f12ed9ceaf2f8c38"},
     {file = "pydevicetree-0.0.13.tar.gz", hash = "sha256:5700c05df89bad8fd729c11aa6f764a3323bcb3796f13b32481ae34445cfc1b7"},
@@ -721,6 +758,7 @@
 description = "Library for analyzing ELF files and DWARF debugging information"
 optional = false
 python-versions = "*"
+groups = ["main"]
 files = [
     {file = "pyelftools-0.29-py2.py3-none-any.whl", hash = "sha256:519f38cf412f073b2d7393aa4682b0190fa901f7c3fa0bff2b82d537690c7fc1"},
     {file = "pyelftools-0.29.tar.gz", hash = "sha256:ec761596aafa16e282a31de188737e5485552469ac63b60cfcccf22263fd24ff"},
@@ -732,6 +770,7 @@
 description = "Pygments is a syntax highlighting package written in Python."
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "docs"]
 files = [
     {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
     {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
@@ -746,6 +785,7 @@
 description = "pyparsing module - Classes and methods to define and execute parsing grammars"
 optional = false
 python-versions = ">=3.6.8"
+groups = ["main"]
 files = [
     {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"},
     {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"},
@@ -756,13 +796,14 @@
 
 [[package]]
 name = "pyproject-api"
-version = "1.7.1"
+version = "1.8.0"
 description = "API to interact with the python pyproject.toml based projects"
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
-    {file = "pyproject_api-1.7.1-py3-none-any.whl", hash = "sha256:2dc1654062c2b27733d8fd4cdda672b22fe8741ef1dde8e3a998a9547b071eeb"},
-    {file = "pyproject_api-1.7.1.tar.gz", hash = "sha256:7ebc6cd10710f89f4cf2a2731710a98abce37ebff19427116ff2174c9236a827"},
+    {file = "pyproject_api-1.8.0-py3-none-any.whl", hash = "sha256:3d7d347a047afe796fd5d1885b1e391ba29be7169bd2f102fcd378f04273d228"},
+    {file = "pyproject_api-1.8.0.tar.gz", hash = "sha256:77b8049f2feb5d33eefcc21b57f1e279636277a8ac8ad6b5871037b243778496"},
 ]
 
 [package.dependencies]
@@ -770,8 +811,8 @@
 tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
 
 [package.extras]
-docs = ["furo (>=2024.5.6)", "sphinx-autodoc-typehints (>=2.2.1)"]
-testing = ["covdefaults (>=2.3)", "pytest (>=8.2.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "setuptools (>=70.1)"]
+docs = ["furo (>=2024.8.6)", "sphinx-autodoc-typehints (>=2.4.1)"]
+testing = ["covdefaults (>=2.3)", "pytest (>=8.3.3)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "setuptools (>=75.1)"]
 
 [[package]]
 name = "pyproject-hooks"
@@ -779,6 +820,7 @@
 description = "Wrappers to call pyproject.toml-based build backend hooks."
 optional = false
 python-versions = ">=3.7"
+groups = ["docs"]
 files = [
     {file = "pyproject_hooks-1.1.0-py3-none-any.whl", hash = "sha256:7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2"},
     {file = "pyproject_hooks-1.1.0.tar.gz", hash = "sha256:4b37730834edbd6bd37f26ece6b44802fb1c1ee2ece0e54ddff8bfc06db86965"},
@@ -790,6 +832,8 @@
 description = "World timezone definitions, modern and historical"
 optional = false
 python-versions = "*"
+groups = ["docs"]
+markers = "python_version < \"3.9\""
 files = [
     {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"},
     {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
@@ -801,6 +845,7 @@
 description = "YAML parser and emitter for Python"
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "docs"]
 files = [
     {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
     {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
@@ -863,6 +908,7 @@
 description = "Python HTTP for Humans."
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
 files = [
     {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
     {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
@@ -884,6 +930,7 @@
 description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
 optional = false
 python-versions = ">=3.6.2,<4.0.0"
+groups = ["main"]
 files = [
     {file = "rich-10.16.2-py3-none-any.whl", hash = "sha256:c59d73bd804c90f747c8d7b1d023b88f2a9ac2454224a4aeaf959b21eeb42d03"},
     {file = "rich-10.16.2.tar.gz", hash = "sha256:720974689960e06c2efdb54327f8bf0cdbdf4eae4ad73b6c94213cad405c371b"},
@@ -903,19 +950,20 @@
 description = "Easily download, build, install, upgrade, and uninstall Python packages"
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
 files = [
     {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"},
     {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"},
 ]
 
 [package.extras]
-check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
-core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.5.2) ; sys_platform != \"cygwin\""]
+core = ["importlib-metadata (>=6) ; python_version < \"3.10\"", "importlib-resources (>=5.10.2) ; python_version < \"3.9\"", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"]
 cover = ["pytest-cov"]
 doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
 enabler = ["pytest-enabler (>=2.2)"]
-test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
-type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"]
+test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
+type = ["importlib-metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.12.*)", "pytest-mypy"]
 
 [[package]]
 name = "shellingham"
@@ -923,6 +971,7 @@
 description = "Tool to Detect Surrounding Shell"
 optional = false
 python-versions = ">=3.7"
+groups = ["main"]
 files = [
     {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
     {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
@@ -934,6 +983,7 @@
 description = "Python 2 and 3 compatibility utilities"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+groups = ["main"]
 files = [
     {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
     {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
@@ -945,6 +995,7 @@
 description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
 optional = false
 python-versions = "*"
+groups = ["docs"]
 files = [
     {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
     {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
@@ -956,6 +1007,7 @@
 description = "Python documentation generator"
 optional = false
 python-versions = ">=3.6"
+groups = ["docs"]
 files = [
     {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"},
     {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"},
@@ -983,7 +1035,7 @@
 [package.extras]
 docs = ["sphinxcontrib-websupport"]
 lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"]
-test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"]
+test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast ; python_version < \"3.8\""]
 
 [[package]]
 name = "sphinx-rtd-theme"
@@ -991,6 +1043,7 @@
 description = "Read the Docs theme for Sphinx"
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
+groups = ["docs"]
 files = [
     {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"},
     {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"},
@@ -1010,6 +1063,7 @@
 description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
 files = [
     {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"},
     {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"},
@@ -1025,6 +1079,7 @@
 description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
 optional = false
 python-versions = ">=3.5"
+groups = ["docs"]
 files = [
     {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
     {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
@@ -1040,6 +1095,7 @@
 description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
 files = [
     {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"},
     {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"},
@@ -1055,6 +1111,7 @@
 description = "Extension to include jQuery on newer Sphinx releases"
 optional = false
 python-versions = ">=2.7"
+groups = ["docs"]
 files = [
     {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"},
     {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"},
@@ -1069,6 +1126,7 @@
 description = "A sphinx extension which renders display math in HTML via JavaScript"
 optional = false
 python-versions = ">=3.5"
+groups = ["docs"]
 files = [
     {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
     {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
@@ -1083,6 +1141,7 @@
 description = "Sphinx \"plantuml\" extension"
 optional = false
 python-versions = "*"
+groups = ["docs"]
 files = [
     {file = "sphinxcontrib-plantuml-0.24.1.tar.gz", hash = "sha256:39d2e4bc40d5e093126129a144f56b6ee15f58cfa5048b5948e63a11aff3b586"},
 ]
@@ -1099,6 +1158,7 @@
 description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
 optional = false
 python-versions = ">=3.5"
+groups = ["docs"]
 files = [
     {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
     {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
@@ -1114,6 +1174,7 @@
 description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
 optional = false
 python-versions = ">=3.5"
+groups = ["docs"]
 files = [
     {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
     {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
@@ -1125,13 +1186,14 @@
 
 [[package]]
 name = "sphinxcontrib-svg2pdfconverter"
-version = "1.2.2"
+version = "1.3.0"
 description = "Sphinx SVG to PDF converter extension"
 optional = false
-python-versions = "~=3.4"
+python-versions = ">=3.6"
+groups = ["docs"]
 files = [
-    {file = "sphinxcontrib-svg2pdfconverter-1.2.2.tar.gz", hash = "sha256:80a55ca61f70eae93efc65f3814f2f177c86ba55934a9f6c5022f1778b62146b"},
-    {file = "sphinxcontrib_svg2pdfconverter-1.2.2-py3-none-any.whl", hash = "sha256:04ec767b55780a6b18d89cc1a8ada6d900c6efde9d1683abdb98a49b144465ca"},
+    {file = "sphinxcontrib_svg2pdfconverter-1.3.0-py3-none-any.whl", hash = "sha256:5df6b0895e2e2101d720bfd08841bb56d74c57b1f86229a7c18b771dfdf4ffbb"},
+    {file = "sphinxcontrib_svg2pdfconverter-1.3.0.tar.gz", hash = "sha256:6411a4cc2f57eed96a0d7bbfa139f68cbe7983018881e1e6d7c46053cd69911f"},
 ]
 
 [package.dependencies]
@@ -1146,6 +1208,7 @@
 description = "Retry code until it succeeds"
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
     {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"},
     {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"},
@@ -1161,6 +1224,7 @@
 description = "module to create simple ASCII tables"
 optional = false
 python-versions = "*"
+groups = ["main"]
 files = [
     {file = "texttable-1.7.0-py2.py3-none-any.whl", hash = "sha256:72227d592c82b3d7f672731ae73e4d1f88cd8e2ef5b075a7a7f01a23a3743917"},
     {file = "texttable-1.7.0.tar.gz", hash = "sha256:2d2068fb55115807d3ac77a4ca68fa48803e84ebb0ee2340f858107a36522638"},
@@ -1172,6 +1236,7 @@
 description = "Transfer List Compiler (TLC) is a Python-based CLI for efficiently handling transfer lists."
 optional = false
 python-versions = "^3.8"
+groups = ["main"]
 files = []
 develop = true
 
@@ -1189,41 +1254,74 @@
 
 [[package]]
 name = "tomli"
-version = "2.0.1"
+version = "2.2.1"
 description = "A lil' TOML parser"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
+groups = ["main", "docs"]
+markers = "python_version < \"3.11\""
 files = [
-    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
-    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+    {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
+    {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
+    {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
+    {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
+    {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
+    {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
+    {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
+    {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
+    {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
+    {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
+    {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
+    {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
+    {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
+    {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
 ]
 
 [[package]]
 name = "tox"
-version = "4.18.1"
+version = "4.24.2"
 description = "tox is a generic virtualenv management and test command line tool"
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
-    {file = "tox-4.18.1-py3-none-any.whl", hash = "sha256:35d472032ee1f73fe20c3e0e73d7073a4e85075c86ff02c576f9fc7c6a15a578"},
-    {file = "tox-4.18.1.tar.gz", hash = "sha256:3c0c96bc3a568a5c7e66387a4cfcf8c875b52e09f4d47c9f7a277ec82f1a0b11"},
+    {file = "tox-4.24.2-py3-none-any.whl", hash = "sha256:92e8290e76ad4e15748860a205865696409a2d014eedeb796a34a0f3b5e7336e"},
+    {file = "tox-4.24.2.tar.gz", hash = "sha256:d5948b350f76fae436d6545a5e87c2b676ab7a0d7d88c1308651245eadbe8aea"},
 ]
 
 [package.dependencies]
-cachetools = ">=5.5"
+cachetools = ">=5.5.1"
 chardet = ">=5.2"
 colorama = ">=0.4.6"
-filelock = ">=3.15.4"
-packaging = ">=24.1"
-platformdirs = ">=4.2.2"
+filelock = ">=3.16.1"
+packaging = ">=24.2"
+platformdirs = ">=4.3.6"
 pluggy = ">=1.5"
-pyproject-api = ">=1.7.1"
-tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
-virtualenv = ">=20.26.3"
+pyproject-api = ">=1.8"
+tomli = {version = ">=2.2.1", markers = "python_version < \"3.11\""}
+typing-extensions = {version = ">=4.12.2", markers = "python_version < \"3.11\""}
+virtualenv = ">=20.29.1"
 
 [package.extras]
-docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-argparse-cli (>=1.17)", "sphinx-autodoc-typehints (>=2.4)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=24.8)"]
-testing = ["build[virtualenv] (>=1.2.2)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.2)", "devpi-process (>=1)", "diff-cover (>=9.1.1)", "distlib (>=0.3.8)", "flaky (>=3.8.1)", "hatch-vcs (>=0.4)", "hatchling (>=1.25)", "psutil (>=6)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-xdist (>=3.6.1)", "re-assert (>=1.1)", "setuptools (>=74.1.2)", "time-machine (>=2.15)", "wheel (>=0.44)"]
+test = ["devpi-process (>=1.0.2)", "pytest (>=8.3.4)", "pytest-mock (>=3.14)"]
 
 [[package]]
 name = "typer"
@@ -1231,6 +1329,7 @@
 description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
 optional = false
 python-versions = ">=3.6"
+groups = ["main"]
 files = [
     {file = "typer-0.4.2-py3-none-any.whl", hash = "sha256:023bae00d1baf358a6cc7cea45851639360bb716de687b42b0a4641cd99173f1"},
     {file = "typer-0.4.2.tar.gz", hash = "sha256:b8261c6c0152dd73478b5ba96ba677e5d6948c715c310f7c91079f311f62ec03"},
@@ -1253,10 +1352,12 @@
 description = "Backported and Experimental Type Hints for Python 3.8+"
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "docs"]
 files = [
     {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
     {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
 ]
+markers = {main = "python_version < \"3.11\""}
 
 [[package]]
 name = "urllib3"
@@ -1264,26 +1365,28 @@
 description = "HTTP library with thread-safe connection pooling, file post, and more."
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
 files = [
     {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"},
     {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"},
 ]
 
 [package.extras]
-brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
+brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""]
 h2 = ["h2 (>=4,<5)"]
 socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
 zstd = ["zstandard (>=0.18.0)"]
 
 [[package]]
 name = "virtualenv"
-version = "20.26.6"
+version = "20.29.3"
 description = "Virtual Python Environment builder"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
+groups = ["main"]
 files = [
-    {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"},
-    {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"},
+    {file = "virtualenv-20.29.3-py3-none-any.whl", hash = "sha256:3e3d00f5807e83b234dfb6122bf37cfadf4be216c53a49ac059d02414f819170"},
+    {file = "virtualenv-20.29.3.tar.gz", hash = "sha256:95e39403fcf3940ac45bc717597dba16110b74506131845d9b687d5e73d947ac"},
 ]
 
 [package.dependencies]
@@ -1293,7 +1396,7 @@
 
 [package.extras]
 docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
-test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
+test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""]
 
 [[package]]
 name = "wcwidth"
@@ -1301,6 +1404,7 @@
 description = "Measures the displayed width of unicode strings in a terminal"
 optional = false
 python-versions = "*"
+groups = ["main"]
 files = [
     {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
     {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
@@ -1312,6 +1416,7 @@
 description = "A built-package format for Python"
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
 files = [
     {file = "wheel-0.44.0-py3-none-any.whl", hash = "sha256:2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f"},
     {file = "wheel-0.44.0.tar.gz", hash = "sha256:a29c3f2817e95ab89aa4660681ad547c0e9547f20e75b0562fe7723c9a2a9d49"},
@@ -1326,20 +1431,22 @@
 description = "Backport of pathlib-compatible object wrapper for zip files"
 optional = false
 python-versions = ">=3.8"
+groups = ["docs"]
+markers = "python_full_version < \"3.10.2\""
 files = [
     {file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"},
     {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"},
 ]
 
 [package.extras]
-check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
 cover = ["pytest-cov"]
 doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
 enabler = ["pytest-enabler (>=2.2)"]
-test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
+test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
 type = ["pytest-mypy"]
 
 [metadata]
-lock-version = "2.0"
+lock-version = "2.1"
 python-versions = "^3.8"
 content-hash = "c78729d7072714d77b4a69d6aabccab35dcf0548f08aa440ff178bc7bf2824be"
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c
index 117934f..c302863 100644
--- a/services/std_svc/drtm/drtm_main.c
+++ b/services/std_svc/drtm/drtm_main.c
@@ -34,6 +34,8 @@
 
 /* DRTM-formatted memory map. */
 static drtm_memory_region_descriptor_table_t *plat_drtm_mem_map;
+static const plat_drtm_dma_prot_features_t *plat_dma_prot_feat;
+static const plat_drtm_tpm_features_t *plat_tpm_feat;
 
 /* DLME header */
 struct_dlme_data_header dlme_data_hdr_init;
@@ -44,8 +46,6 @@
 int drtm_setup(void)
 {
 	bool rc;
-	const plat_drtm_tpm_features_t *plat_tpm_feat;
-	const plat_drtm_dma_prot_features_t *plat_dma_prot_feat;
 
 	INFO("DRTM service setup\n");
 
@@ -322,6 +322,43 @@
 	return SUCCESS;
 }
 
+/* Function to check if the value is valid for each bit field */
+static int drtm_dl_check_features_sanity(uint32_t val)
+{
+	/**
+	 * Ensure that if DLME Authorities Schema (Bits [2:1]) is set, then
+	 * DLME image authentication (Bit[6]) must also be set
+	 */
+	if ((EXTRACT_FIELD(val, DRTM_LAUNCH_FEAT_PCR_USAGE_SCHEMA_MASK,
+			   DRTM_LAUNCH_FEAT_PCR_USAGE_SCHEMA_SHIFT) == DLME_AUTH_SCHEMA) &&
+	    (EXTRACT_FIELD(val, DRTM_LAUNCH_FEAT_DLME_IMG_AUTH_MASK,
+			    DRTM_LAUNCH_FEAT_DLME_IMG_AUTH_SHIFT) != DLME_IMG_AUTH)) {
+		return INVALID_PARAMETERS;
+	}
+
+	/**
+	 * Check if Bits [5:3] (Memory protection type) matches with platform's
+	 * memory protection type
+	 */
+	if (EXTRACT_FIELD(val, DRTM_LAUNCH_FEAT_MEM_PROTECTION_TYPE_MASK,
+			  DRTM_LAUNCH_FEAT_MEM_PROTECTION_TYPE_SHIFT) !=
+	    __builtin_ctz(plat_dma_prot_feat->dma_protection_support)) {
+		return INVALID_PARAMETERS;
+	}
+
+	/**
+	 * Check if Bits [0] (Type of hashing) matches with platform's
+	 * supported hash type.
+	 */
+	if (EXTRACT_FIELD(val, DRTM_LAUNCH_FEAT_HASHING_TYPE_MASK,
+			  DRTM_LAUNCH_FEAT_HASHING_TYPE_SHIFT) !=
+	    plat_tpm_feat->tpm_based_hash_support) {
+		return INVALID_PARAMETERS;
+	}
+
+	return 0;
+}
+
 /*
  * Note: accesses to the dynamic launch args, and to the DLME data are
  * little-endian as required, thanks to TF-A BL31 init requirements.
@@ -369,7 +406,7 @@
 	args_buf = *a;
 
 	rc = mmap_remove_dynamic_region(va_mapping, va_mapping_size);
-	if (rc) {
+	if (rc != 0) {
 		ERROR("%s(): mmap_remove_dynamic_region() failed unexpectedly"
 		      " rc=%d\n", __func__, rc);
 		panic();
@@ -383,6 +420,13 @@
 		return NOT_SUPPORTED;
 	}
 
+	rc = drtm_dl_check_features_sanity(a->features);
+	if (rc != 0) {
+		ERROR("%s(): drtm_dl_check_features_sanity() failed.\n"
+				" rc=%d\n", __func__, rc);
+		return rc;
+	}
+
 	if (!(a->dlme_img_off < a->dlme_size &&
 	      a->dlme_data_off < a->dlme_size)) {
 		ERROR("DRTM: argument offset is outside of the DLME region\n");
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 10a2c42..19c8373 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,6 +19,7 @@
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/el3_runtime/pubsub.h>
+#include <lib/extensions/mpam.h>
 #include <lib/extensions/pmuv3.h>
 #include <lib/extensions/sys_reg_trace.h>
 #include <lib/gpt_rme/gpt_rme.h>
@@ -169,6 +170,16 @@
 	if (is_feat_sme_supported()) {
 		sme_enable_per_world(&per_world_context[CPU_CONTEXT_REALM]);
 	}
+
+	/*
+	 * If FEAT_MPAM is supported and enabled, then disable trapping access
+	 * to the MPAM registers for Realm world. Instead, RMM will configure
+	 * the access to be trapped by itself so it can inject undefined aborts
+	 * back to the Realm.
+	 */
+	if (is_feat_mpam_supported()) {
+		mpam_enable_per_world(&per_world_context[CPU_CONTEXT_REALM]);
+	}
 }
 
 /*******************************************************************************
@@ -470,6 +481,41 @@
 	return E_RMM_OK;
 }
 
+/*
+ * Update encryption key associated with @mecid.
+ */
+static int rmmd_mecid_key_update(uint64_t mecid)
+{
+	uint64_t mecid_width, mecid_width_mask;
+	int ret;
+
+	/*
+	 * Check whether FEAT_MEC is supported by the hardware. If not, return
+	 * unknown SMC.
+	 */
+	if (is_feat_mec_supported() == false) {
+		return E_RMM_UNK;
+	}
+
+	/*
+	 * Check whether the mecid parameter is at most MECIDR_EL2.MECIDWidthm1 + 1
+	 * in length.
+	 */
+	mecid_width = ((read_mecidr_el2() >> MECIDR_EL2_MECIDWidthm1_SHIFT) &
+		MECIDR_EL2_MECIDWidthm1_MASK) + 1;
+	mecid_width_mask = ((1 << mecid_width) - 1);
+	if ((mecid & ~mecid_width_mask) != 0U) {
+		return E_RMM_INVAL;
+	}
+
+	ret = plat_rmmd_mecid_key_update(mecid);
+
+	if (ret != 0) {
+		return E_RMM_UNK;
+	}
+	return E_RMM_OK;
+}
+
 /*******************************************************************************
  * This function handles RMM-EL3 interface SMCs
  ******************************************************************************/
@@ -502,12 +548,12 @@
 	case RMM_GTSI_UNDELEGATE:
 		ret = gpt_undelegate_pas(x1, PAGE_SIZE_4KB, SMC_FROM_REALM);
 		SMC_RET1(handle, gpt_to_gts_error(ret, smc_fid, x1));
-	case RMM_ATTEST_GET_PLAT_TOKEN:
-		ret = rmmd_attest_get_platform_token(x1, &x2, x3, &remaining_len);
-		SMC_RET3(handle, ret, x2, remaining_len);
 	case RMM_ATTEST_GET_REALM_KEY:
 		ret = rmmd_attest_get_signing_key(x1, &x2, x3);
 		SMC_RET2(handle, ret, x2);
+	case RMM_ATTEST_GET_PLAT_TOKEN:
+		ret = rmmd_attest_get_platform_token(x1, &x2, x3, &remaining_len);
+		SMC_RET3(handle, ret, x2, remaining_len);
 	case RMM_EL3_FEATURES:
 		ret = rmm_el3_ifc_get_feat_register(x1, &x2);
 		SMC_RET2(handle, ret, x2);
@@ -519,6 +565,9 @@
 		VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
 		rmmd_rmm_sync_exit(x1);
 
+	case RMM_MECID_KEY_UPDATE:
+		ret = rmmd_mecid_key_update(x1);
+		SMC_RET1(handle, ret);
 	default:
 		WARN("RMMD: Unsupported RMM-EL3 call 0x%08x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index bddfe96..c67a6fc 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -1359,6 +1359,16 @@
 		/* Execution stops here. */
 
 	/* Supported ABIs only from the secure world. */
+	case FFA_MEM_PERM_GET_SMC32:
+	case FFA_MEM_PERM_GET_SMC64:
+	case FFA_MEM_PERM_SET_SMC32:
+	case FFA_MEM_PERM_SET_SMC64:
+	/* these ABIs are only supported from S-EL0 SPs */
+	#if !(SPMC_AT_EL3_SEL0_SP)
+		return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+	#endif
+	/* fall through */
+
 	case FFA_SECONDARY_EP_REGISTER_SMC64:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
@@ -1367,7 +1377,6 @@
 	case FFA_MSG_WAIT:
 	case FFA_CONSOLE_LOG_SMC32:
 	case FFA_CONSOLE_LOG_SMC64:
-
 		if (!secure_origin) {
 			return spmc_ffa_error_return(handle,
 				FFA_ERROR_NOT_SUPPORTED);
diff --git a/tools/cot_dt2c/poetry.lock b/tools/cot_dt2c/poetry.lock
index eea96cd..cfcebe6 100644
--- a/tools/cot_dt2c/poetry.lock
+++ b/tools/cot_dt2c/poetry.lock
@@ -1,14 +1,15 @@
-# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
 
 [[package]]
 name = "click"
-version = "8.1.7"
+version = "8.1.8"
 description = "Composable command line interface toolkit"
 optional = false
 python-versions = ">=3.7"
+groups = ["main"]
 files = [
-    {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
-    {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
+    {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"},
+    {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"},
 ]
 
 [package.dependencies]
@@ -20,10 +21,12 @@
 description = "Cross-platform colored terminal text."
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+groups = ["main", "dev"]
 files = [
     {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
     {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
 ]
+markers = {main = "platform_system == \"Windows\"", dev = "sys_platform == \"win32\""}
 
 [[package]]
 name = "exceptiongroup"
@@ -31,6 +34,8 @@
 description = "Backport of PEP 654 (exception groups)"
 optional = false
 python-versions = ">=3.7"
+groups = ["dev"]
+markers = "python_version < \"3.11\""
 files = [
     {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
     {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
@@ -41,50 +46,51 @@
 
 [[package]]
 name = "igraph"
-version = "0.11.6"
+version = "0.11.8"
 description = "High performance graph data structures and algorithms"
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
-    {file = "igraph-0.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3f8b837181e8e87676be3873ce87cc92cc234efd58a2da2f6b4e050db150fcf4"},
-    {file = "igraph-0.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:245c4b7d7657849eff80416f5df4525c8fc44c74a981ee4d44f0ef2612c3bada"},
-    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdb7be3d165073c0136295c0808e9edc57ba096cdb26e94086abb04561f7a292"},
-    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58974e20df2986a1ae52a16e51ecb387cc0cbeb41c5c0ddff4d373a1bbf1d9c5"},
-    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bef14de5e8ab70724a43808b1ed14aaa6fe1002f87e592289027a3827a8f44a"},
-    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:86c1e98de2e32d074df8510bf18abfa1f4c5fda4cb28a009985a5d746b0c0125"},
-    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ebc5b3d702158abeb2e4d2414374586a2b932e1a07e48352b470600e1733d528"},
-    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0efe6d0fb22d3987a800eb3857ed04df9eb4c5dddd0998be05232cb646f1c337"},
-    {file = "igraph-0.11.6-cp38-cp38-win32.whl", hash = "sha256:f4e68b27497b1c8ada2fb2bc35ef3fa7b0d72e84306b3d648d3de240fc618c32"},
-    {file = "igraph-0.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:5665b33dfbfca5f54ce9b4fea6b97903bd0e99fb1b02acf5e57e600bdfa5a355"},
-    {file = "igraph-0.11.6-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8aabef03d787b519d1075dfc0da4a1109fb113b941334883e3e7947ac30a459e"},
-    {file = "igraph-0.11.6-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1f2cc4a518d99cdf6cae514f85e93e56852bc8c325b3abb96037d1d690b5975f"},
-    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1e859238be52ab8ccc614d18f9362942bc88ce543afc12548f81ae99b10801d"},
-    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d61fbe5e85eb4ae9efe08c461f9bdeedb02a2b5739fbc223d324a71f40a28be2"},
-    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6620ba39df29fd42151becf82309b54e57148233c9c3ef890eed62e25eed8a5"},
-    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59666589bb3d07f310cda2c5106a8adeeb77c2ef27fecf1c6438b6091f4ca69d"},
-    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:8750b6d6caebf199cf7dc41c931f58e330153779707391e30f0a29f02666fb6e"},
-    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:967d6f2c30fe94317da15e459374d0fb8ca3e56020412f201ecd07dd5b5352f2"},
-    {file = "igraph-0.11.6-cp39-abi3-win32.whl", hash = "sha256:9744f95a67319eb6cb487ceabf30f5d7940de34bada51f0ba63adbd23e0f94ad"},
-    {file = "igraph-0.11.6-cp39-abi3-win_amd64.whl", hash = "sha256:b80e69eb11faa9c57330a9ffebdde5808966efe1c1f638d4d4827ea04df7aca8"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0329c16092e2ea7930d5f8368666ce7cb704900cc0ea04e4afe9ea1dd46e44af"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:21752313f449bd8688e5688e95ea7231cea5e9199c7162535029be0d9af848ac"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea25e136c6c4161f53ff58868b23ff6c845193050ab0e502236d68e5d4174e32"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac84433a03aef15e4b810010b08882b09854a3669450ccf31e392dbe295d2a66"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac697a44e3573169fa2b28c9c37dcf9cf01e0f558b845dd7123860d4c7c8fb89"},
-    {file = "igraph-0.11.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bdeae8bf35316eb1fb27bf667dcf5ecf5fcfb0b8f51831bc1b00c39c09c2d73b"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ad7e4aa442935de72554b96733bf6d7f09eac5cee97988a2562bdd3ca173cfa3"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d2818780358a686178866d01568b9df1f29678581734ad7a78882bab54df004"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2352276a20d979f1dea360af4202bb9f0c9a7d2c77f51815c0e625165e82013d"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:687fdab543b507d622fa3043f4227e5b26dc61dcf8ff8c0919fccddcc655f8b8"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57f7f8214cd48c9a4d97f7346a4152ba2d4ac95fb5ee0df4ecf224fce4ba3d14"},
-    {file = "igraph-0.11.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2b9cc69ede53f76ffae03b066609aa90184dd68ef15da8c104a97cebb9210838"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:591e1e447c3f0092daf7613a3eaedab83f9a0b0adbaf7702724c5117ded038a5"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ca558eb331bc687bc33e5cd23717e22676e9412f8cda3a31d30c996a0487610d"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf43c30e08debb087c9e3da69aa5cf1b6732968da34d55a614e3421b9a452146"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d38e8d7db72b187d9d2211d0d06b3271fa9f32b04d49d789e2859b5480db0d0"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a318b059051ff78144a1c3cb880f4d933c812bcdb3d833a49cd7168d0427672"},
-    {file = "igraph-0.11.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2c54027add809b3c5b6685b8deca4ea4763fd000b9ea45c7ee46b7c9d61ff15e"},
-    {file = "igraph-0.11.6.tar.gz", hash = "sha256:837f233256c3319f2a35a6a80d94eafe47b43791ef4c6f9e9871061341ac8e28"},
+    {file = "igraph-0.11.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9a7aa8e65e7b9ddfe66f9473ce93863f40fccac26b24dc3f56e63159641c9946"},
+    {file = "igraph-0.11.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9e953e1c5e9c5712a48df5cea93963be84aa26618cdae341b4a6b07761f56a45"},
+    {file = "igraph-0.11.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9baf699fdd10491e9a0842e546e630165c49c78d21ac4aaa9fb434ab4a817458"},
+    {file = "igraph-0.11.8-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:434e35d935675caddac3221863b43a02085c7f66030eda542f0dd9fc36e1f8ff"},
+    {file = "igraph-0.11.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:745e5d7aebca7e9c16f882041718c8ceeb404a5c7201cb8685f57b0e19ebe24d"},
+    {file = "igraph-0.11.8-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:24c97ce9f40a358a8d6ff9c27fab0e4617068aaeeb5448247308c67519b91fa2"},
+    {file = "igraph-0.11.8-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c89ab68f076528736d4ed56a01983d7fd433f50b08c58bee7ded2326a4eacda1"},
+    {file = "igraph-0.11.8-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d964fc35d65ce67b121e4dcfd7d3479fb3eeb232b6a346a217e397c7d5c5f124"},
+    {file = "igraph-0.11.8-cp38-cp38-win32.whl", hash = "sha256:511b036c876fdbfc919a6a4c72b0335fd2a6a3249e5e4312b660390213875afb"},
+    {file = "igraph-0.11.8-cp38-cp38-win_amd64.whl", hash = "sha256:417b8375c1c9adbb431f7481a6cae6f9e440db81d8d4ee6fa5d2c2983148930a"},
+    {file = "igraph-0.11.8-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:92c47ceb9f4c95ff7461cd94eaec55e901dbc59f6e51f4244d2dd064f31c5491"},
+    {file = "igraph-0.11.8-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:3a2afdb046b602fea71ca18aff6c72165de5002ec38d0dcf1275e34ecd0d9d02"},
+    {file = "igraph-0.11.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7870fb72fd9e9218940262671fb79baf281ef066aa1cd35adc092ce9ad39a038"},
+    {file = "igraph-0.11.8-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8108138ad605714761bc6d526feab54074904a99c47dcaabc269ed7b45e7650"},
+    {file = "igraph-0.11.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2e3abe641622cd9c95eb152c97caa22e68257a524cc1851a099b066f8f5c5f3"},
+    {file = "igraph-0.11.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b546eaa9461473a65bb56a51672c6aeb898b737d5e86c3efa1b1bf520ee4b031"},
+    {file = "igraph-0.11.8-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:178ef859135ac5075a7159e6826a546b7340cf45a01a928c2a0c24c32e3dfa63"},
+    {file = "igraph-0.11.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a68ae7b6324e9c4cb1d04ce75b6e0f67974433fc7667895f1e25bf4f4c6fd530"},
+    {file = "igraph-0.11.8-cp39-abi3-win32.whl", hash = "sha256:cc93d2f97f93bf30c2027c31e9e1aa088a3c60cdfeb6b33e0259e4b40b4c5597"},
+    {file = "igraph-0.11.8-cp39-abi3-win_amd64.whl", hash = "sha256:248831a6162130f16909c1f776cc246b48f692339ea4baca489cad4ed8dc0e13"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f0a8cad10406fba28c4b0199dfb491bcfdf1cdd3a56feeb52bb3b1cd724d04b4"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1c11127a58ac2fc8062dac9f20ef612aff1b09f5f9d3e90800c4817229d0a0bc"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17d79bfb170b8c195fe6bacfa1c906817e8e812417c7e6a8e15f0bcf9b0775a8"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9de09a26d7aae4d83338497cfd2d107d3ee3a2e9335b9db4b6c73a089e8cf47"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6559e2c925ed2ac608103adfd1dec9ccb9a04ddc7ad1d9d2a7db46dda6b1955"},
+    {file = "igraph-0.11.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6c17658b367be4f725a253678bfe799d9fe4d4e5c01ad82449cf8f2e9917937c"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d4971b4fcb005ed72f630a5f4c9bb80f10153471fe30846810f63beb3e282a19"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d7b1eaa3563c1e2dda940c1f154fefe9b3b257da8e8251af443cdc69a039480"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35438d6d69a73288949a80f1eb84597e783486cd71a5cdf5862c0db7a7cbd5c5"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09c609c5d6a844582a10085c18c1c15d14b2f9fd3be59fed3feaa4be091d671f"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9b836baa221027f1781ebcff05f1b23339a51a63eb70948ebaba5641efc060a"},
+    {file = "igraph-0.11.8-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:caf4a178f7fb7890195c9fb358dbef0ed4a4f5323f529ea14a0f64da4c05f564"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e702a436935d3e127f6affff397ebbab48b522434bd8d6f15cfb1ab5d940e7d5"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bcad4d052785fe9b076f5aca6e870e2fae35373b09867477adc7307f2692a36"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d420cd48353e7c138bc39a118c3a01dc41aeba38486cca1524a960a755016171"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ae9486a52da72d2ab634b92e17a969dc4e8e83303384329b903830ad67315e5"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4e36a4f8a40bb4ffc8aa08c1cfe6fa3dfa78393cf65165bd9d59e6ac24a2468"},
+    {file = "igraph-0.11.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f4048b843be54a77bc7206ce8c58825a9b1b42748c1713699034dc4f7df36f73"},
+    {file = "igraph-0.11.8.tar.gz", hash = "sha256:d7dc1404567ba3b0ea1bf8b5fa6e101617915c8ad11ea5a9f925a40bf4adad7d"},
 ]
 
 [package.dependencies]
@@ -93,10 +99,10 @@
 [package.extras]
 cairo = ["cairocffi (>=1.2.0)"]
 doc = ["Sphinx (>=7.0.0)", "pydoctor (>=23.4.0)", "sphinx-gallery (>=0.14.0)", "sphinx-rtd-theme (>=1.3.0)"]
-matplotlib = ["matplotlib (>=3.6.0)"]
+matplotlib = ["matplotlib (>=3.6.0) ; platform_python_implementation != \"PyPy\""]
 plotly = ["plotly (>=5.3.0)"]
 plotting = ["cairocffi (>=1.2.0)"]
-test = ["Pillow (>=9)", "cairocffi (>=1.2.0)", "matplotlib (>=3.6.0)", "networkx (>=2.5)", "numpy (>=1.19.0)", "pandas (>=1.1.0)", "plotly (>=5.3.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)", "scipy (>=1.5.0)"]
+test = ["Pillow (>=9) ; platform_python_implementation != \"PyPy\"", "cairocffi (>=1.2.0)", "matplotlib (>=3.6.0) ; platform_python_implementation != \"PyPy\"", "networkx (>=2.5)", "numpy (>=1.19.0) ; platform_python_implementation != \"PyPy\"", "pandas (>=1.1.0) ; platform_python_implementation != \"PyPy\"", "plotly (>=5.3.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)", "scipy (>=1.5.0) ; platform_python_implementation != \"PyPy\""]
 test-musl = ["cairocffi (>=1.2.0)", "networkx (>=2.5)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)"]
 
 [[package]]
@@ -105,6 +111,7 @@
 description = "brain-dead simple config-ini parsing"
 optional = false
 python-versions = ">=3.7"
+groups = ["dev"]
 files = [
     {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
     {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
@@ -116,6 +123,7 @@
 description = "Optional static typing for Python"
 optional = false
 python-versions = ">=3.5"
+groups = ["dev"]
 files = [
     {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"},
     {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"},
@@ -157,6 +165,7 @@
 description = "Experimental type system extensions for programs checked with the mypy typechecker."
 optional = false
 python-versions = ">=2.7"
+groups = ["dev"]
 files = [
     {file = "mypy_extensions-0.4.4.tar.gz", hash = "sha256:c8b707883a96efe9b4bb3aaf0dcc07e7e217d7d8368eec4db4049ee9e142f4fd"},
 ]
@@ -167,6 +176,7 @@
 description = "Core utilities for Python packages"
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
     {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
     {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
@@ -174,13 +184,14 @@
 
 [[package]]
 name = "plotly"
-version = "5.23.0"
+version = "5.24.1"
 description = "An open-source, interactive data visualization library for Python"
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
-    {file = "plotly-5.23.0-py3-none-any.whl", hash = "sha256:76cbe78f75eddc10c56f5a4ee3e7ccaade7c0a57465546f02098c0caed6c2d1a"},
-    {file = "plotly-5.23.0.tar.gz", hash = "sha256:89e57d003a116303a34de6700862391367dd564222ab71f8531df70279fc0193"},
+    {file = "plotly-5.24.1-py3-none-any.whl", hash = "sha256:f67073a1e637eb0dc3e46324d9d51e2fe76e9727c892dde64ddf1e1b51f29089"},
+    {file = "plotly-5.24.1.tar.gz", hash = "sha256:dbc8ac8339d248a4bcc36e08a5659bacfe1b079390b8953533f4eb22169b4bae"},
 ]
 
 [package.dependencies]
@@ -193,6 +204,7 @@
 description = "plugin and hook calling mechanisms for python"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
     {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
@@ -208,6 +220,7 @@
 description = "A library for parsing Devicetree Source v1"
 optional = false
 python-versions = ">=3.5"
+groups = ["main"]
 files = [
     {file = "pydevicetree-0.0.13-py3-none-any.whl", hash = "sha256:d61c695cec925b90a8b5740053f4b604e51154a9b36e62a2f12ed9ceaf2f8c38"},
     {file = "pydevicetree-0.0.13.tar.gz", hash = "sha256:5700c05df89bad8fd729c11aa6f764a3323bcb3796f13b32481ae34445cfc1b7"},
@@ -218,13 +231,14 @@
 
 [[package]]
 name = "pyparsing"
-version = "3.1.2"
+version = "3.1.4"
 description = "pyparsing module - Classes and methods to define and execute parsing grammars"
 optional = false
 python-versions = ">=3.6.8"
+groups = ["main"]
 files = [
-    {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"},
-    {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"},
+    {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"},
+    {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"},
 ]
 
 [package.extras]
@@ -232,13 +246,14 @@
 
 [[package]]
 name = "pytest"
-version = "8.3.4"
+version = "8.3.5"
 description = "pytest: simple powerful testing with Python"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
-    {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"},
-    {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"},
+    {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"},
+    {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"},
 ]
 
 [package.dependencies]
@@ -258,6 +273,7 @@
 description = "Retry code until it succeeds"
 optional = false
 python-versions = ">=3.8"
+groups = ["main"]
 files = [
     {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"},
     {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"},
@@ -273,6 +289,7 @@
 description = "module to create simple ASCII tables"
 optional = false
 python-versions = "*"
+groups = ["main"]
 files = [
     {file = "texttable-1.7.0-py2.py3-none-any.whl", hash = "sha256:72227d592c82b3d7f672731ae73e4d1f88cd8e2ef5b075a7a7f01a23a3743917"},
     {file = "texttable-1.7.0.tar.gz", hash = "sha256:2d2068fb55115807d3ac77a4ca68fa48803e84ebb0ee2340f858107a36522638"},
@@ -284,6 +301,7 @@
 description = "Python Library for Tom's Obvious, Minimal Language"
 optional = false
 python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+groups = ["dev"]
 files = [
     {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
     {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
@@ -295,6 +313,8 @@
 description = "A lil' TOML parser"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
+markers = "python_version < \"3.11\""
 files = [
     {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
     {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
@@ -336,12 +356,13 @@
 description = "Backported and Experimental Type Hints for Python 3.8+"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
     {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
 ]
 
 [metadata]
-lock-version = "2.0"
+lock-version = "2.1"
 python-versions = "^3.8"
 content-hash = "0f5b2b008bb5de8545881eaeacfdd1a6fe50e5271feea4635d622ffce9e550dc"
diff --git a/tools/marvell/doimage/doimage.c b/tools/marvell/doimage/doimage.c
index 1f0985c..12e1327 100644
--- a/tools/marvell/doimage/doimage.c
+++ b/tools/marvell/doimage/doimage.c
@@ -421,7 +421,7 @@
 	char			*ptmp = (char *)&tv;
 	unsigned char		digest[32];
 	unsigned char		IV[AES_BLOCK_SZ];
-	int			i, k;
+	size_t			i, k;
 	mbedtls_aes_context	aes_ctx;
 	int			rval = -1;
 	uint8_t			*test_img = 0;
@@ -516,7 +516,8 @@
 	for (i = 0; i < blen; i++) {
 		if (buf[i] != test_img[i]) {
 			fprintf(stderr, "Failed to compare the image after");
-			fprintf(stderr, " decryption! Byte count is %d\n", i);
+			fprintf(stderr, " decryption! Byte count is %lu\n",
+				(unsigned long)i);
 			rval = -1;
 			goto encrypt_exit;
 		}
@@ -614,11 +615,11 @@
 int verify_and_copy_file_name_entry(const char *element_name,
 				    const char *element, char *copy_to)
 {
-	int element_length = strlen(element);
+	size_t element_length = strlen(element);
 
 	if (element_length >= MAX_FILENAME) {
-		fprintf(stderr, "The file name %s for %s is too long (%d). ",
-			element, element_name, element_length);
+		fprintf(stderr, "The file name %s for %s is too long (%lu). ",
+			element, element_name, (unsigned long)element_length);
 		fprintf(stderr, "Maximum allowed %d characters!\n",
 			MAX_FILENAME);
 		return -1;
diff --git a/tools/nxp/create_pbl/Makefile b/tools/nxp/create_pbl/Makefile
index 965cc51..9285b72 100644
--- a/tools/nxp/create_pbl/Makefile
+++ b/tools/nxp/create_pbl/Makefile
@@ -44,7 +44,7 @@
 	$(s)echo "Built $@ successfully"
 	$(s)echo
 
-%.o: %.c %.h Makefile
+${OBJECTS_1} ${OBJECTS_2}: %.o: %.c Makefile
 	$(s)echo "  CC      $<"
 	$(q)$(host-cc) -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
 
diff --git a/tools/tlc/poetry.lock b/tools/tlc/poetry.lock
index ea1b750..3562de9 100644
--- a/tools/tlc/poetry.lock
+++ b/tools/tlc/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
+# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
 
 [[package]]
 name = "astroid"
@@ -6,6 +6,7 @@
 description = "An abstract syntax tree for Python with inference support."
 optional = false
 python-versions = ">=3.7.2"
+groups = ["dev"]
 files = [
     {file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"},
     {file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"},
@@ -21,13 +22,15 @@
 
 [[package]]
 name = "bandit"
-version = "1.7.9"
+version = "1.7.10"
 description = "Security oriented static analyser for python code."
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
+markers = "python_version < \"3.11\""
 files = [
-    {file = "bandit-1.7.9-py3-none-any.whl", hash = "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec"},
-    {file = "bandit-1.7.9.tar.gz", hash = "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61"},
+    {file = "bandit-1.7.10-py3-none-any.whl", hash = "sha256:665721d7bebbb4485a339c55161ac0eedde27d51e638000d91c8c2d68343ad02"},
+    {file = "bandit-1.7.10.tar.gz", hash = "sha256:59ed5caf5d92b6ada4bf65bc6437feea4a9da1093384445fed4d472acc6cff7b"},
 ]
 
 [package.dependencies]
@@ -40,15 +43,42 @@
 baseline = ["GitPython (>=3.1.30)"]
 sarif = ["jschema-to-python (>=1.2.3)", "sarif-om (>=1.0.4)"]
 test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)"]
-toml = ["tomli (>=1.1.0)"]
+toml = ["tomli (>=1.1.0) ; python_version < \"3.11\""]
 yaml = ["PyYAML"]
 
 [[package]]
+name = "bandit"
+version = "1.8.3"
+description = "Security oriented static analyser for python code."
+optional = false
+python-versions = ">=3.9"
+groups = ["dev"]
+markers = "python_version >= \"3.11\""
+files = [
+    {file = "bandit-1.8.3-py3-none-any.whl", hash = "sha256:28f04dc0d258e1dd0f99dee8eefa13d1cb5e3fde1a5ab0c523971f97b289bcd8"},
+    {file = "bandit-1.8.3.tar.gz", hash = "sha256:f5847beb654d309422985c36644649924e0ea4425c76dec2e89110b87506193a"},
+]
+
+[package.dependencies]
+colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""}
+PyYAML = ">=5.3.1"
+rich = "*"
+stevedore = ">=1.20.0"
+
+[package.extras]
+baseline = ["GitPython (>=3.1.30)"]
+sarif = ["jschema-to-python (>=1.2.3)", "sarif-om (>=1.0.4)"]
+test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)"]
+toml = ["tomli (>=1.1.0) ; python_version < \"3.11\""]
+yaml = ["PyYAML"]
+
+[[package]]
 name = "black"
 version = "24.8.0"
 description = "The uncompromising code formatter."
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"},
     {file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"},
@@ -85,19 +115,20 @@
 
 [package.extras]
 colorama = ["colorama (>=0.4.3)"]
-d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"]
+d = ["aiohttp (>=3.7.4) ; sys_platform != \"win32\" or implementation_name != \"pypy\"", "aiohttp (>=3.7.4,!=3.9.0) ; sys_platform == \"win32\" and implementation_name == \"pypy\""]
 jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
 uvloop = ["uvloop (>=0.15.2)"]
 
 [[package]]
 name = "cachetools"
-version = "5.5.0"
+version = "5.5.2"
 description = "Extensible memoizing collections and decorators"
 optional = false
 python-versions = ">=3.7"
+groups = ["main", "dev"]
 files = [
-    {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"},
-    {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"},
+    {file = "cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a"},
+    {file = "cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4"},
 ]
 
 [[package]]
@@ -106,6 +137,7 @@
 description = "Python package for providing Mozilla's CA Bundle."
 optional = false
 python-versions = ">=3.6"
+groups = ["dev"]
 files = [
     {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
     {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
@@ -117,6 +149,7 @@
 description = "Validate configuration and produce human readable error messages."
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"},
     {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
@@ -128,6 +161,7 @@
 description = "Universal encoding detector for Python 3"
 optional = false
 python-versions = ">=3.7"
+groups = ["main", "dev"]
 files = [
     {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
     {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
@@ -139,6 +173,7 @@
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
 optional = false
 python-versions = ">=3.7.0"
+groups = ["dev"]
 files = [
     {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
     {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
@@ -234,13 +269,14 @@
 
 [[package]]
 name = "click"
-version = "8.1.7"
+version = "8.1.8"
 description = "Composable command line interface toolkit"
 optional = false
 python-versions = ">=3.7"
+groups = ["main", "dev"]
 files = [
-    {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
-    {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
+    {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"},
+    {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"},
 ]
 
 [package.dependencies]
@@ -252,6 +288,7 @@
 description = "Cross-platform colored terminal text."
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+groups = ["main", "dev"]
 files = [
     {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
     {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
@@ -263,6 +300,7 @@
 description = "Python parser for the CommonMark Markdown spec"
 optional = false
 python-versions = "*"
+groups = ["main", "dev"]
 files = [
     {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
     {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
@@ -277,6 +315,7 @@
 description = "Code coverage measurement for Python"
 optional = false
 python-versions = ">=3.7"
+groups = ["dev"]
 files = [
     {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"},
     {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"},
@@ -334,7 +373,7 @@
 tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
 
 [package.extras]
-toml = ["tomli"]
+toml = ["tomli ; python_full_version <= \"3.11.0a6\""]
 
 [[package]]
 name = "coverage-badge"
@@ -342,6 +381,7 @@
 description = "Generate coverage badges for Coverage.py."
 optional = false
 python-versions = "*"
+groups = ["dev"]
 files = [
     {file = "coverage_badge-1.1.2-py2.py3-none-any.whl", hash = "sha256:d8413ce51c91043a1692b943616b450868cbeeb0ea6a0c54a32f8318c9c96ff7"},
     {file = "coverage_badge-1.1.2.tar.gz", hash = "sha256:fe7ed58a3b72dad85a553b64a99e963dea3847dcd0b8ddd2b38a00333618642c"},
@@ -357,6 +397,7 @@
 description = "A utility for ensuring Google-style docstrings stay up to date with the source code."
 optional = false
 python-versions = ">=3.6,<4.0"
+groups = ["dev"]
 files = [
     {file = "darglint-1.8.1-py3-none-any.whl", hash = "sha256:5ae11c259c17b0701618a20c3da343a3eb98b3bc4b5a83d31cdd94f5ebdced8d"},
     {file = "darglint-1.8.1.tar.gz", hash = "sha256:080d5106df149b199822e7ee7deb9c012b49891538f14a11be681044f0bb20da"},
@@ -368,6 +409,7 @@
 description = "serialize all of Python"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"},
     {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"},
@@ -383,6 +425,7 @@
 description = "Distribution utilities"
 optional = false
 python-versions = "*"
+groups = ["main", "dev"]
 files = [
     {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"},
     {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"},
@@ -394,6 +437,7 @@
 description = "A parser for Python dependency files"
 optional = false
 python-versions = ">=3.6"
+groups = ["dev"]
 files = [
     {file = "dparse-0.6.3-py3-none-any.whl", hash = "sha256:0d8fe18714056ca632d98b24fbfc4e9791d4e47065285ab486182288813a5318"},
     {file = "dparse-0.6.3.tar.gz", hash = "sha256:27bb8b4bcaefec3997697ba3f6e06b2447200ba273c0b085c3d012a04571b528"},
@@ -413,6 +457,8 @@
 description = "Backport of PEP 654 (exception groups)"
 optional = false
 python-versions = ">=3.7"
+groups = ["dev"]
+markers = "python_version < \"3.11\""
 files = [
     {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
     {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
@@ -427,6 +473,7 @@
 description = "A platform independent file lock."
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
     {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"},
     {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"},
@@ -435,7 +482,7 @@
 [package.extras]
 docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"]
 testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"]
-typing = ["typing-extensions (>=4.12.2)"]
+typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""]
 
 [[package]]
 name = "identify"
@@ -443,6 +490,7 @@
 description = "File identification library for Python"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"},
     {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"},
@@ -457,6 +505,7 @@
 description = "Internationalized Domain Names in Applications (IDNA)"
 optional = false
 python-versions = ">=3.6"
+groups = ["dev"]
 files = [
     {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
     {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
@@ -471,6 +520,7 @@
 description = "brain-dead simple config-ini parsing"
 optional = false
 python-versions = ">=3.7"
+groups = ["dev"]
 files = [
     {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
     {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
@@ -482,6 +532,7 @@
 description = "A Python utility / library to sort Python imports."
 optional = false
 python-versions = ">=3.8.0"
+groups = ["dev"]
 files = [
     {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"},
     {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"},
@@ -495,13 +546,14 @@
 
 [[package]]
 name = "jinja2"
-version = "3.1.5"
+version = "3.1.6"
 description = "A very fast and expressive template engine."
 optional = false
 python-versions = ">=3.7"
+groups = ["main", "dev"]
 files = [
-    {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"},
-    {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"},
+    {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"},
+    {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"},
 ]
 
 [package.dependencies]
@@ -516,6 +568,7 @@
 description = "A fast and thorough lazy object proxy."
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"},
     {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"},
@@ -562,6 +615,7 @@
 description = "Safely add untrusted strings to HTML/XML markup."
 optional = false
 python-versions = ">=3.7"
+groups = ["main", "dev"]
 files = [
     {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
     {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
@@ -631,6 +685,7 @@
 description = "McCabe checker, plugin for flake8"
 optional = false
 python-versions = ">=3.6"
+groups = ["dev"]
 files = [
     {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
     {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
@@ -642,6 +697,7 @@
 description = "Optional static typing for Python"
 optional = false
 python-versions = ">=3.5"
+groups = ["dev"]
 files = [
     {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"},
     {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"},
@@ -683,6 +739,7 @@
 description = "Experimental type system extensions for programs checked with the mypy typechecker."
 optional = false
 python-versions = ">=2.7"
+groups = ["dev"]
 files = [
     {file = "mypy_extensions-0.4.4.tar.gz", hash = "sha256:c8b707883a96efe9b4bb3aaf0dcc07e7e217d7d8368eec4db4049ee9e142f4fd"},
 ]
@@ -693,6 +750,7 @@
 description = "Node.js virtual environment builder"
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+groups = ["dev"]
 files = [
     {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"},
     {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"},
@@ -700,13 +758,14 @@
 
 [[package]]
 name = "packaging"
-version = "24.1"
+version = "24.2"
 description = "Core utilities for Python packages"
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
-    {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
-    {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
+    {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
+    {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
 ]
 
 [[package]]
@@ -715,6 +774,7 @@
 description = "Utility library for gitignore style pattern matching of file paths."
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
     {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
@@ -726,6 +786,7 @@
 description = "Python Build Reasonableness"
 optional = false
 python-versions = ">=2.6"
+groups = ["dev"]
 files = [
     {file = "pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"},
     {file = "pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24"},
@@ -737,6 +798,7 @@
 description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
     {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
     {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
@@ -753,6 +815,7 @@
 description = "plugin and hook calling mechanisms for python"
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
     {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
     {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
@@ -768,6 +831,7 @@
 description = "A framework for managing and maintaining multi-language pre-commit hooks."
 optional = false
 python-versions = ">=3.7"
+groups = ["dev"]
 files = [
     {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"},
     {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"},
@@ -786,6 +850,7 @@
 description = "Python docstring style checker"
 optional = false
 python-versions = ">=3.6"
+groups = ["dev"]
 files = [
     {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"},
     {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"},
@@ -795,7 +860,7 @@
 snowballstemmer = ">=2.2.0"
 
 [package.extras]
-toml = ["tomli (>=1.2.3)"]
+toml = ["tomli (>=1.2.3) ; python_version < \"3.11\""]
 
 [[package]]
 name = "pygments"
@@ -803,6 +868,7 @@
 description = "Pygments is a syntax highlighting package written in Python."
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
     {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
     {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
@@ -817,6 +883,7 @@
 description = "python code static checker"
 optional = false
 python-versions = ">=3.7.2"
+groups = ["dev"]
 files = [
     {file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"},
     {file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"},
@@ -846,6 +913,7 @@
 description = "API to interact with the python pyproject.toml based projects"
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
     {file = "pyproject_api-1.8.0-py3-none-any.whl", hash = "sha256:3d7d347a047afe796fd5d1885b1e391ba29be7169bd2f102fcd378f04273d228"},
     {file = "pyproject_api-1.8.0.tar.gz", hash = "sha256:77b8049f2feb5d33eefcc21b57f1e279636277a8ac8ad6b5871037b243778496"},
@@ -861,13 +929,14 @@
 
 [[package]]
 name = "pytest"
-version = "8.3.3"
+version = "8.3.5"
 description = "pytest: simple powerful testing with Python"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
-    {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"},
-    {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"},
+    {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"},
+    {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"},
 ]
 
 [package.dependencies]
@@ -887,6 +956,7 @@
 description = "Pytest plugin for measuring coverage."
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"},
     {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"},
@@ -905,6 +975,7 @@
 description = "pytest plugin for generating HTML reports"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "pytest_html-4.1.1-py3-none-any.whl", hash = "sha256:c8152cea03bd4e9bee6d525573b67bbc6622967b72b9628dda0ea3e2a0b5dd71"},
     {file = "pytest_html-4.1.1.tar.gz", hash = "sha256:70a01e8ae5800f4a074b56a4cb1025c8f4f9b038bba5fe31e3c98eb996686f07"},
@@ -925,6 +996,7 @@
 description = "pytest plugin for test session metadata"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "pytest_metadata-3.1.1-py3-none-any.whl", hash = "sha256:c8e0844db684ee1c798cfa38908d20d67d0463ecb6137c72e91f418558dd5f4b"},
     {file = "pytest_metadata-3.1.1.tar.gz", hash = "sha256:d2a29b0355fbc03f168aa96d41ff88b1a3b44a3b02acbe491801c98a048017c8"},
@@ -942,6 +1014,7 @@
 description = "A tool to automatically upgrade syntax for newer versions."
 optional = false
 python-versions = ">=3.7"
+groups = ["dev"]
 files = [
     {file = "pyupgrade-2.38.4-py2.py3-none-any.whl", hash = "sha256:944ff993c396ddc2b9012eb3de4cda138eb4c149b22c6c560d4c8bfd0e180982"},
     {file = "pyupgrade-2.38.4.tar.gz", hash = "sha256:1eb43a49f416752929741ba4d706bf3f33593d3cac9bdc217fc1ef55c047c1f4"},
@@ -956,6 +1029,7 @@
 description = "YAML parser and emitter for Python"
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
     {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
     {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
@@ -1018,6 +1092,7 @@
 description = "Python HTTP for Humans."
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
     {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
@@ -1039,6 +1114,7 @@
 description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
 optional = false
 python-versions = ">=3.6.2,<4.0.0"
+groups = ["main", "dev"]
 files = [
     {file = "rich-10.16.2-py3-none-any.whl", hash = "sha256:c59d73bd804c90f747c8d7b1d023b88f2a9ac2454224a4aeaf959b21eeb42d03"},
     {file = "rich-10.16.2.tar.gz", hash = "sha256:720974689960e06c2efdb54327f8bf0cdbdf4eae4ad73b6c94213cad405c371b"},
@@ -1058,6 +1134,7 @@
 description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
 optional = false
 python-versions = ">=3.7"
+groups = ["dev"]
 files = [
     {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"},
     {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"},
@@ -1076,6 +1153,8 @@
 description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
 optional = false
 python-versions = ">=3.6"
+groups = ["dev"]
+markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""
 files = [
     {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"},
     {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"},
@@ -1135,6 +1214,7 @@
 description = "Checks installed dependencies for known vulnerabilities and licenses."
 optional = false
 python-versions = "*"
+groups = ["dev"]
 files = [
     {file = "safety-2.3.4-py3-none-any.whl", hash = "sha256:6224dcd9b20986a2b2c5e7acfdfba6bca42bb11b2783b24ed04f32317e5167ea"},
     {file = "safety-2.3.4.tar.gz", hash = "sha256:b9e74e794e82f54d11f4091c5d820c4d2d81de9f953bf0b4f33ac8bc402ae72c"},
@@ -1158,19 +1238,20 @@
 description = "Easily download, build, install, upgrade, and uninstall Python packages"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"},
     {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"},
 ]
 
 [package.extras]
-check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
-core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.5.2) ; sys_platform != \"cygwin\""]
+core = ["importlib-metadata (>=6) ; python_version < \"3.10\"", "importlib-resources (>=5.10.2) ; python_version < \"3.9\"", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"]
 cover = ["pytest-cov"]
 doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
 enabler = ["pytest-enabler (>=2.2)"]
-test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
-type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"]
+test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
+type = ["importlib-metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.11.*)", "pytest-mypy"]
 
 [[package]]
 name = "shellingham"
@@ -1178,6 +1259,7 @@
 description = "Tool to Detect Surrounding Shell"
 optional = false
 python-versions = ">=3.7"
+groups = ["main"]
 files = [
     {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
     {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
@@ -1189,6 +1271,7 @@
 description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
 optional = false
 python-versions = "*"
+groups = ["dev"]
 files = [
     {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
     {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
@@ -1200,6 +1283,7 @@
 description = "Manage dynamic plugins for Python applications"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "stevedore-5.3.0-py3-none-any.whl", hash = "sha256:1efd34ca08f474dad08d9b19e934a22c68bb6fe416926479ba29e5013bcc8f78"},
     {file = "stevedore-5.3.0.tar.gz", hash = "sha256:9a64265f4060312828151c204efbe9b7a9852a0d9228756344dbc7e4023e375a"},
@@ -1214,6 +1298,7 @@
 description = "A wrapper around the stdlib `tokenize` which roundtrips."
 optional = false
 python-versions = ">=3.6.1"
+groups = ["dev"]
 files = [
     {file = "tokenize_rt-4.2.1-py2.py3-none-any.whl", hash = "sha256:08a27fa032a81cf45e8858d0ac706004fcd523e8463415ddf1442be38e204ea8"},
     {file = "tokenize_rt-4.2.1.tar.gz", hash = "sha256:0d4f69026fed520f8a1e0103aa36c406ef4661417f20ca643f913e33531b3b94"},
@@ -1225,6 +1310,7 @@
 description = "Python Library for Tom's Obvious, Minimal Language"
 optional = false
 python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+groups = ["dev"]
 files = [
     {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
     {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
@@ -1232,13 +1318,45 @@
 
 [[package]]
 name = "tomli"
-version = "2.0.1"
+version = "2.2.1"
 description = "A lil' TOML parser"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
+groups = ["main", "dev"]
+markers = "python_version < \"3.11\""
 files = [
-    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
-    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+    {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
+    {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
+    {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
+    {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
+    {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
+    {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
+    {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
+    {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
+    {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
+    {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
+    {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
+    {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
+    {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
+    {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
+    {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
+    {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
+    {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
+    {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
+    {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
+    {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
 ]
 
 [[package]]
@@ -1247,6 +1365,7 @@
 description = "Style preserving TOML library"
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"},
     {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"},
@@ -1254,30 +1373,31 @@
 
 [[package]]
 name = "tox"
-version = "4.20.0"
+version = "4.24.2"
 description = "tox is a generic virtualenv management and test command line tool"
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
-    {file = "tox-4.20.0-py3-none-any.whl", hash = "sha256:21a8005e3d3fe5658a8e36b8ca3ed13a4230429063c5cc2a2fdac6ee5aa0de34"},
-    {file = "tox-4.20.0.tar.gz", hash = "sha256:5b78a49b6eaaeab3ae4186415e7c97d524f762ae967c63562687c3e5f0ec23d5"},
+    {file = "tox-4.24.2-py3-none-any.whl", hash = "sha256:92e8290e76ad4e15748860a205865696409a2d014eedeb796a34a0f3b5e7336e"},
+    {file = "tox-4.24.2.tar.gz", hash = "sha256:d5948b350f76fae436d6545a5e87c2b676ab7a0d7d88c1308651245eadbe8aea"},
 ]
 
 [package.dependencies]
-cachetools = ">=5.5"
+cachetools = ">=5.5.1"
 chardet = ">=5.2"
 colorama = ">=0.4.6"
-filelock = ">=3.15.4"
-packaging = ">=24.1"
-platformdirs = ">=4.2.2"
+filelock = ">=3.16.1"
+packaging = ">=24.2"
+platformdirs = ">=4.3.6"
 pluggy = ">=1.5"
-pyproject-api = ">=1.7.1"
-tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
-virtualenv = ">=20.26.3"
+pyproject-api = ">=1.8"
+tomli = {version = ">=2.2.1", markers = "python_version < \"3.11\""}
+typing-extensions = {version = ">=4.12.2", markers = "python_version < \"3.11\""}
+virtualenv = ">=20.29.1"
 
 [package.extras]
-docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-argparse-cli (>=1.17)", "sphinx-autodoc-typehints (>=2.4)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=24.8)"]
-testing = ["build[virtualenv] (>=1.2.2)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.2)", "devpi-process (>=1)", "diff-cover (>=9.1.1)", "distlib (>=0.3.8)", "flaky (>=3.8.1)", "hatch-vcs (>=0.4)", "hatchling (>=1.25)", "psutil (>=6)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-xdist (>=3.6.1)", "re-assert (>=1.1)", "setuptools (>=74.1.2)", "time-machine (>=2.15)", "wheel (>=0.44)"]
+test = ["devpi-process (>=1.0.2)", "pytest (>=8.3.4)", "pytest-mock (>=3.14)"]
 
 [[package]]
 name = "typer"
@@ -1285,6 +1405,7 @@
 description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
 optional = false
 python-versions = ">=3.6"
+groups = ["main"]
 files = [
     {file = "typer-0.4.2-py3-none-any.whl", hash = "sha256:023bae00d1baf358a6cc7cea45851639360bb716de687b42b0a4641cd99173f1"},
     {file = "typer-0.4.2.tar.gz", hash = "sha256:b8261c6c0152dd73478b5ba96ba677e5d6948c715c310f7c91079f311f62ec03"},
@@ -1307,10 +1428,12 @@
 description = "Backported and Experimental Type Hints for Python 3.8+"
 optional = false
 python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
     {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
     {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
 ]
+markers = {main = "python_version < \"3.11\""}
 
 [[package]]
 name = "urllib3"
@@ -1318,26 +1441,28 @@
 description = "HTTP library with thread-safe connection pooling, file post, and more."
 optional = false
 python-versions = ">=3.8"
+groups = ["dev"]
 files = [
     {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"},
     {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"},
 ]
 
 [package.extras]
-brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
+brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""]
 h2 = ["h2 (>=4,<5)"]
 socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
 zstd = ["zstandard (>=0.18.0)"]
 
 [[package]]
 name = "virtualenv"
-version = "20.26.6"
+version = "20.29.3"
 description = "Virtual Python Environment builder"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
+groups = ["main", "dev"]
 files = [
-    {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"},
-    {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"},
+    {file = "virtualenv-20.29.3-py3-none-any.whl", hash = "sha256:3e3d00f5807e83b234dfb6122bf37cfadf4be216c53a49ac059d02414f819170"},
+    {file = "virtualenv-20.29.3.tar.gz", hash = "sha256:95e39403fcf3940ac45bc717597dba16110b74506131845d9b687d5e73d947ac"},
 ]
 
 [package.dependencies]
@@ -1347,7 +1472,7 @@
 
 [package.extras]
 docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
-test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
+test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""]
 
 [[package]]
 name = "wrapt"
@@ -1355,6 +1480,7 @@
 description = "Module for decorators, wrappers and monkey patching."
 optional = false
 python-versions = ">=3.6"
+groups = ["dev"]
 files = [
     {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"},
     {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"},
@@ -1429,6 +1555,6 @@
 ]
 
 [metadata]
-lock-version = "2.0"
+lock-version = "2.1"
 python-versions = "^3.8"
 content-hash = "a4b9c3bababadba14f49a8de0ccee1f5a141b6cea23d02a19ab8bf4f8c45533f"