Merge "refactor(trng): discarding the used entropy bits" into integration
diff --git a/.gitignore b/.gitignore
index b005fab..1f4efb6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,3 +43,9 @@
 
 # Node.js
 node_modules/
+
+# common python virtual environment directories
+.env/
+env/
+.venv/
+venv/
diff --git a/Makefile b/Makefile
index f574130..c4350dc 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@
 # Trusted Firmware Version
 #
 VERSION_MAJOR			:= 2
-VERSION_MINOR			:= 7
+VERSION_MINOR			:= 8
 VERSION				:= ${VERSION_MAJOR}.${VERSION_MINOR}
 
 # Default goal is build all images
@@ -526,9 +526,7 @@
         SPD_DIR := std_svc
 
         ifeq ($(SPMD_SPM_AT_SEL2),1)
-            ifeq ($(CTX_INCLUDE_EL2_REGS),0)
-                $(error SPMD with SPM at S-EL2 requires CTX_INCLUDE_EL2_REGS option)
-            endif
+            CTX_INCLUDE_EL2_REGS := 1
 	    ifeq ($(SPMC_AT_EL3),1)
                 $(error SPM cannot be enabled in both S-EL2 and EL3.)
             endif
@@ -574,6 +572,14 @@
     # over the sources.
 endif
 
+ifeq (${CTX_INCLUDE_EL2_REGS}, 1)
+ifeq (${SPD},none)
+ifeq (${ENABLE_RME},0)
+    $(error CTX_INCLUDE_EL2_REGS is available only when SPD or RME is enabled)
+endif
+endif
+endif
+
 ################################################################################
 # Include rmmd Makefile if RME is enabled
 ################################################################################
@@ -1080,6 +1086,7 @@
         SIMICS_BUILD \
         FEATURE_DETECTION \
 	TRNG_SUPPORT \
+	CONDITIONAL_CMO \
 )))
 
 $(eval $(call assert_numerics,\
@@ -1241,6 +1248,7 @@
         FEATURE_DETECTION \
         TWED_DELAY \
         ENABLE_FEAT_TWED \
+	CONDITIONAL_CMO \
 )))
 
 ifeq (${SANITIZE_UB},trap)
@@ -1468,7 +1476,7 @@
 certtool: ${CRTTOOL}
 
 ${CRTTOOL}: FORCE
-	${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} --no-print-directory -C ${CRTTOOLPATH}
+	${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${CRTTOOLPATH} all
 	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@${ECHO_BLANK_LINE}
@@ -1513,7 +1521,7 @@
 
 ${FIPTOOL}: FORCE
 ifdef UNIX_MK
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} --no-print-directory -C ${FIPTOOLPATH}
+	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${FIPTOOLPATH} all
 else
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
@@ -1534,7 +1542,7 @@
 enctool: ${ENCTOOL}
 
 ${ENCTOOL}: FORCE
-	${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} --no-print-directory -C ${ENCTOOLPATH}
+	${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${ENCTOOLPATH} all
 	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@${ECHO_BLANK_LINE}
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 0283553..614ea71 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -493,15 +493,16 @@
 	msr	spsel, #MODE_SP_EL0
 
 	/*
-	 * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there is a world
+	 * Save the SPSR_EL3 and ELR_EL3 in case there is a world
 	 * switch during SMC handling.
 	 * TODO: Revisit if all system registers can be saved later.
 	 */
 	mrs	x16, spsr_el3
 	mrs	x17, elr_el3
-	mrs	x18, scr_el3
 	stp	x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-	str	x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+
+	/* Load SCR_EL3 */
+	mrs	x18, scr_el3
 
 	/* Clear flag register */
 	mov	x7, xzr
diff --git a/bl32/tsp/ffa_helpers.c b/bl32/tsp/ffa_helpers.c
index 3639c22..ad70c2b 100644
--- a/bl32/tsp/ffa_helpers.c
+++ b/bl32/tsp/ffa_helpers.c
@@ -149,13 +149,15 @@
 {
 	smc_args_t ret;
 	uint32_t descriptor_size;
-	struct ffa_mtd *memory_region = (struct ffa_mtd *)mb->tx_buffer;
+	struct ffa_mtd *memory_region;
 
 	if (retrieved == NULL || mb == NULL) {
 		ERROR("Invalid parameters!\n");
 		return false;
 	}
 
+	memory_region = (struct ffa_mtd *)mb->tx_buffer;
+
 	/* Clear TX buffer. */
 	memset(memory_region, 0, PAGE_SIZE);
 
diff --git a/bl32/tsp/tsp_ffa_main.c b/bl32/tsp/tsp_ffa_main.c
index 53dbd03..2c53977 100644
--- a/bl32/tsp/tsp_ffa_main.c
+++ b/bl32/tsp/tsp_ffa_main.c
@@ -216,10 +216,10 @@
 				(uint64_t)composite->address_range_array[i].address,
 				size, mem_attrs);
 
-			/* Remove mappings created in this transaction. */
-			for (i--; i >= 0U; i--) {
+			/* Remove mappings previously created in this transaction. */
+			for (i--; i >= 0; i--) {
 				ret = mmap_remove_dynamic_region(
-					(uint64_t)ptr,
+					(uint64_t)composite->address_range_array[i].address,
 					composite->address_range_array[i].page_count * PAGE_SIZE);
 
 				if (ret != 0) {
@@ -227,6 +227,7 @@
 					panic();
 				}
 			}
+
 			return FFA_ERROR_NO_MEMORY;
 		}
 
@@ -298,8 +299,8 @@
 	tsp_stats[linear_id].eret_count++;
 	tsp_stats[linear_id].cpu_off_count++;
 
-	INFO("TSP: cpu 0x%lx off request\n", read_mpidr());
-	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n",
+	VERBOSE("TSP: cpu 0x%lx off request\n", read_mpidr());
+	VERBOSE("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n",
 		read_mpidr(),
 		tsp_stats[linear_id].smc_count,
 		tsp_stats[linear_id].eret_count,
@@ -336,7 +337,7 @@
 	tsp_stats[linear_id].eret_count++;
 	tsp_stats[linear_id].cpu_suspend_count++;
 
-	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n",
+	VERBOSE("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n",
 		read_mpidr(),
 		tsp_stats[linear_id].smc_count,
 		tsp_stats[linear_id].eret_count,
@@ -369,9 +370,9 @@
 	tsp_stats[linear_id].eret_count++;
 	tsp_stats[linear_id].cpu_resume_count++;
 
-	INFO("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n",
+	VERBOSE("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n",
 	     read_mpidr(), max_off_pwrlvl);
-	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n",
+	VERBOSE("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n",
 		read_mpidr(),
 		tsp_stats[linear_id].smc_count,
 		tsp_stats[linear_id].eret_count,
@@ -611,7 +612,7 @@
 	tsp_stats[linear_id].eret_count++;
 	tsp_stats[linear_id].cpu_on_count++;
 
-	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
+	VERBOSE("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
 			read_mpidr(),
 			tsp_stats[linear_id].smc_count,
 			tsp_stats[linear_id].eret_count,
@@ -640,8 +641,8 @@
 	tsp_stats[linear_id].smc_count++;
 	tsp_stats[linear_id].eret_count++;
 	tsp_stats[linear_id].cpu_on_count++;
-	INFO("TSP: cpu 0x%lx turned on\n", read_mpidr());
-	INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
+	VERBOSE("TSP: cpu 0x%lx turned on\n", read_mpidr());
+	VERBOSE("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
 			read_mpidr(),
 			tsp_stats[linear_id].smc_count,
 			tsp_stats[linear_id].eret_count,
diff --git a/docs/about/index.rst b/docs/about/index.rst
index 3a10266..06973ef 100644
--- a/docs/about/index.rst
+++ b/docs/about/index.rst
@@ -4,7 +4,6 @@
 .. toctree::
    :maxdepth: 1
    :caption: Contents
-   :numbered:
 
    features
    release-information
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 1d20d8b..9a2ae73 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -51,6 +51,17 @@
 :|M|: Manish Badarkhe <manish.badarkhe@arm.com>
 :|G|: `ManishVB-Arm`_
 
+LTS Maintainers
+---------------
+
+:|M|: Bipin Ravi <bipin.ravi@arm.com>
+:|G|: `bipinravi-arm`_
+:|M|: Joanna Farley <joanna.farley@arm.com>
+:|G|: `joannafarley-arm`_
+:|M|: Okash Khawaja <okash@google.com>
+:|G|: `bytefire`_
+:|M|: Varun Wadekar <vwadekar@nvidia.com>
+:|G|: `vwadekar`_
 
 .. _code owners:
 
@@ -944,5 +955,6 @@
 .. _marcone: https://github.com/marcone
 .. _marcbonnici: https://github.com/marcbonnici
 .. _jayanthchidanand-arm: https://github.com/jayanthchidanand-arm
+.. _bytefire: https://github.com/bytefire
 
 .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index c0875b6..ddfc081 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -52,6 +52,8 @@
 +-----------------+---------------------------+------------------------------+
 | v2.8            | 5th week of Nov '22       | 3rd week of Nov '22          |
 +-----------------+---------------------------+------------------------------+
+| v2.9            | 1st week of May '23       | 3rd week of Apr '23          |
++-----------------+---------------------------+------------------------------+
 
 Removal of Deprecated Interfaces
 --------------------------------
@@ -65,7 +67,7 @@
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
-| STM32MP_USE_STM32IMAGE macro   |   Dec '21   |   2.7   | FIP is the recommended boot method for STM32MP          |
+| plat_convert_pk() function     |   Nov'22    |   2.9   | Platform conversion to manage specific PK hash          |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
 --------------
diff --git a/docs/change-log.md b/docs/change-log.md
index 8a555ec..bb05afb 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -3,6 +3,920 @@
 This document contains a summary of the new features, changes, fixes and known
 issues in each release of Trusted Firmware-A.
 
+## [2.8.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.7.0..refs/tags/v2.8.0) (2022-11-15)
+
+### ⚠ BREAKING CHANGES
+
+- **Drivers**
+
+  - **Arm**
+
+    - **Ethos-N**
+
+      - add support for SMMU streams
+
+        **See:** add support for SMMU streams ([b139f1c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b139f1cf975f9968eb8bd1182a173b976ecf06f9))
+
+### New Features
+
+- **Architecture**
+
+  - pass SMCCCv1.3 SVE hint bit to dispatchers ([0fe7b9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0fe7b9f2bcdf754c483399c841e5f0ec71e53ef3))
+
+  - **Branch Record Buffer Extension (FEAT_BRBE)**
+
+    - add brbe under feature detection mechanism ([1298f2f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1298f2f13d6d97dfcac120a2ee68d5eea3797068))
+
+  - **Confidential Compute Architecture (CCA)**
+
+    - introduce new "cca" chain of trust ([56b741d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56b741d3e41cd6b2f6863a372a9489c819e2b0e9))
+
+  - **Pointer Authentication Extension**
+
+    - add/modify helpers to support QARMA3 ([9ff5f75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9ff5f754aea00d0e86ba5191839fc0faef949fe0))
+
+  - **Trapping support for RNDR/RNDRRS (FEAT_RNG_TRAP)**
+
+    - add EL3 support for FEAT_RNG_TRAP ([ff86e0b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff86e0b4e6c34d28b8642dd8eb9cbdd517bad195))
+
+  - **Scalable Matrix Extension (FEAT_SME)**
+
+    - fall back to SVE if SME is not there ([26a3351](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/26a3351edab1501d7e19ae96540c34b2700ac32f))
+
+  - **Scalable Vector Extension (FEAT_SVE)**
+
+    - support full SVE vector length ([bebcf27](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bebcf27f1c75f48cc129e8608cba113d0db32ef8))
+
+  - **Trace Buffer Extension (FEAT_TRBE)**
+
+    - add trbe under feature detection mechanism ([47c681b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47c681b7d7f03e77f6cdd7b5d116ae64671ab8ca))
+
+- **Platforms**
+
+  - **Arm**
+
+    - add support for cca CoT ([f242379](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f24237921e3fa61e64fa1ec845e14e2748d04a2b))
+    - forbid running RME-enlightened BL31 from DRAM ([1164a59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1164a59cb16a9bbc672fa6d07895bc6fa0361bcb))
+    - provide some swd rotpk files ([98662a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/98662a73c903b06f53c9f9da6a9404187fc10352))
+    - retrieve the right ROTPK for cca ([50b4497](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/50b449776df11cac06347e8ef1af5dae701a0e3a))
+
+    - **CSS**
+
+      - add interrupt handler for reboot request ([f1fe144](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f1fe1440db197d514b5484e780cfb90f504c62b9))
+      - add per-cpu power down support for warm reset ([158ed58](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/158ed580bdf5736abfa9f16f61be1ca1609e0e41))
+
+    - **FVP**
+
+      - add example manifest for TSP ([3cf080e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3cf080ed61e90668f0c44ca7f577e51c081e5c7c))
+      - add crypto support in BL31 ([c9bd1ba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c9bd1bacffd9697ec4ebac77e45588cf6c261a3b))
+      - add plat API to set and get the DRTM error ([586f60c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/586f60cc571f0f3b6d20eb5033717e9b0cc66af4))
+      - add plat API to validate that passed region is non-secure ([d5f225d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5f225d95d3dc7473340ffebfcb9068b54f91a17))
+      - add platform hooks for DRTM DMA protection ([d72c486](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d72c486b52dc654e4216d41dcc1b0f87bdbdf3e9))
+      - build delegated attestation in BL31 ([0271edd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0271eddb0c00b01033bf651f0eeaf659c0c2dd39))
+      - dts: drop 32-bit .dts files ([b920330](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b92033075aa27031091e184b54f4dc278ecb27bc))
+      - fdts: update rtsm_ve DT files from the Linux kernel ([2716bd3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2716bd33e318821c373b3d4dce88110a340a740d))
+      - increase BL31's stack size for DRTM support ([44df105](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44df105ff867aeb2aa5d20faa3e8389866099956))
+      - increase MAX_XLAT_TABLES entries for DRTM support ([8a8dace](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8a8dace5a5cd3a51d67df3cea86628f29cc96013))
+      - support building RSS comms driver ([29e6fc5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/29e6fc5cc7d0c8bc4ba615fd97df4cb65d3c7ba3))
+
+    - **RD**
+
+      - **RD-N2**
+
+        - add a new 'isolated-cpu-list' property ([afa4157](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/afa41571b856509c25c66c331737b895144b681b))
+        - add SPI ID ranges for RD-N2 multichip platform ([9f0835e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9f0835e9156f13b56336a47a4b51e90719a852ff))
+        - enable extended SPI support ([108488f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/108488f9ac026f036c0de2b824b339a30f9a0cbb))
+
+    - **SGI**
+
+      - increase memory reserved for bl31 image ([a62cc91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a62cc91aeedbdcfb3396983ed165eb35b8d4c3fa))
+      - read isolated cpu mpid list from sds ([4243ef4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4243ef41d480fd8e870f74defe263156a6c02c8d))
+      - add page table translation entry for secure uart ([2a7e080](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2a7e080cc50be5739afcfb3b7db59e4d610a7d53))
+      - bump bl1 rw size ([94df8da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/94df8da3ab520330b2e7d276603f33e284c27b3f))
+      - configure SRAM and BL31 size for sgi platform ([8fd820f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8fd820ffb918ad8fdc1f2c72cc64dad5eaff77aa))
+      - deviate from arm css common uart related definitions ([173674a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/173674ae428aa23e8f2a38d5542d0ea52eed7e80))
+      - enable css implementation of warm reset ([18884c0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18884c002e6c298f27d6e4792eab2c9f4d89bddb))
+      - remove override for `ARM_BL31_IN_DRAM` build-option ([a371327](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a371327ba9fc2e1c5988ac1436b29c42aab8dfd8))
+      - route TF-A logs via secure uart ([0601083](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0601083f0ce0045bd957c1343d2196be0887973b))
+
+    - **TC**
+
+      - add MHU addresses for AP-RSS comms on TC2 ([6299c3a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6299c3a0f7c8220b0bf15723ec8995b72bf97677))
+      - add RSS-AP message size macro ([445130b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/445130b127f411bdf4958fa10f292a930c9ae57d))
+      - add RTC PL031 device tree node ([a816de5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a816de564f927ebb72ab7692b8b3f46073179310))
+      - enable RSS backend based measured boot ([6cb5d32](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cb5d3268fa41d15480c4e070a51577b333767fe))
+      - increase maximum BL1/BL2/BL31 sizes ([e6c1316](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6c131655fa168ffd1ae738a74ba25e5f850036c))
+      - introduce TC2 platform ([eebd2c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eebd2c3f61c90942fb186fa43fbb4c4a543d8b55))
+      - move start address for BL1 to 0x1000 ([9335c28](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9335c28a019ee2d9ab7a0f9276b91415f3c9f1bc))
+
+  - **HiSilicon**
+
+    - **HiKey960**
+
+      - add a FF-A logical partition ([25a357f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/25a357f1932cf2b0d125dd98b82eeacad14005ea))
+      - add memory sharing hooks for SPMC_AT_EL3 ([5f905a2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5f905a249839e9e20ebf44c22d95caaf3a2e5611))
+      - add plat-defines for SPMC_AT_EL3 ([feebd4c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/feebd4c7a86b6f0fcc1eb5008ba5f7d44e75beaf))
+      - add SP manifest for SPMC_AT_EL3 ([6971642](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6971642d23d0c5e33e507eb78b7c569045e2f85d))
+      - define a datastore for SPMC_AT_EL3 ([e618c62](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e618c621b3ece7a0262ff9245027132982e6207c))
+      - increase secure workspace to 64MB ([e0eea33](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0eea337b32e37bbef9bad1310b96b9c0d86f7b9))
+      - read serial number from UFS ([c371b83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c371b83f0c5b503c21bd1b6092bc0230032329ce))
+      - upgrade to xlat_tables_v2 ([6cfc807](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cfc8078d032d278e09523e236ab5b36f69f2ec0))
+
+  - **MediaTek**
+
+    - add more flexibility of mtk_pm.c ([6ca2046](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6ca2046ef15dcf19fbda5f12cbfe1004d340c969))
+    - add more options for build helper ([5b95e43](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5b95e439c745dcf94899238b82826d8f1d32acbe))
+    - add smcc call for MSDC ([4dbe24c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4dbe24cf7d2b04c552f394062f42c30fee7e26a6))
+    - extend SiP vendor subscription events ([99d30b7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99d30b72c02502731ecf116acfda44ee3c2c9e5e))
+    - implement generic platform port ([394b920](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/394b92084d53e2bf8960731be7a79c999871f127))
+    - introduce mtk init framework ([52035de](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52035dee1ae7b0f2f0d5f16c734ca7a5cea127b7))
+    - move dp drivers to common folder ([d150b62](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d150b6296e6960f2548b265b8b23e6cdb502d3b7))
+    - move lpm drivers back to common ([cd7890d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd7890d79e9d508e82f3078f02e8277f8c8df181))
+    - move mtk_cirq.c drivers to cirq folder ([cc76896](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc76896d9e416b15548b2d6bf068e5d3f9b4064a))
+    - support coreboot BL31 loading ([ef988ae](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef988aed9e09a4108b87decb14dee5f2d23230a4))
+
+    - **MT8186**
+
+      - add EMI MPU support for SCP and DSP ([3d4b6f9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d4b6f932444c7b0f70f8654b92193b294527056))
+
+    - **MT8188**
+
+      - add armv8.2 support ([45711e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/45711e4e1614fbed75ea645777cc2bb11d4be96f))
+      - add audio support ([c70f567](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c70f567ad75c30a990cb60c71b6c0b02538366fd))
+      - add cpu_pm driver ([4fe7e6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fe7e6a8d9f09c40d087167432cb07621c175b3f))
+      - add DCM driver ([bc9410e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc9410e2376e0b6355ea6440aa90ad968fc5f3b3))
+      - add DFD control in SiP service ([7079a94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7079a942bd9705fd9e0cd220324f7dfd9c53dcad))
+      - add display port control in SiP service ([a4e5023](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4e502319d136d8854ef2ed4aaa6d5368541e551))
+      - add EMI MPU basic drivers ([8454f0d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8454f0d65eeb85b72f454376faa0f7a15226e240))
+      - add IOMMU enable control in SiP service ([be45724](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be457248c6b0a7f3c61bd95af58372938d13decd))
+      - add LPM driver support ([f604e4e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f604e4ef6e306c6d87e17e77e50a68aad0510110))
+      - add MCUSYS support ([4cc1ff7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4cc1ff7ef2c3544ef1aabeb2973a2d8f7800776b))
+      - add pinctrl support ([ec4cfb9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ec4cfb91fc197a024d1edb9fae5e9ce100e5b200))
+      - add pmic and pwrap support ([e9310c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9310c34b018944a6c29a8f408f0a34b43a0df6d))
+      - add reset and poweroff functions ([a72b9e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a72b9e7754a27e6ebccf79f0cc4fb7cc5a0a8a5e))
+      - add RTC support ([af5d8e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af5d8e07955ddef9000c64de94deb2703e6ffcf0))
+      - add support for PTP3 ([44a1051](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44a10511c9e5a66b3a33abba44856a7a5dc5e655))
+      - apply ERRATA for CA-78 ([abb995a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/abb995abbe45874a397351cbb134ae32d4cc545b))
+      - enable MTK_PUBEVENT_ENABLE ([0b1186a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0b1186a3e6fd6daffaef3f6cf59650bb9121191c))
+      - initialize GIC ([cfb0516](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cfb0516f3cc36e3d0ec9b0bdabf1eb6ea2b275c1))
+      - initialize platform for MediaTek MT8188 ([de310e1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de310e1e5f0b76b9de2b93759344540e0109c8eb))
+      - initialize systimer ([215869c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/215869c693c136192505a004ec368f503f146505))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - **i.MX 8M**
+
+        - add dram retention flow for imx8m family ([c71793c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c71793c6476fa2828f866b8d7b272289f0d9a15c))
+        - add support for high assurance boot ([720e7b6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/720e7b66f2353ef7ed32a8f85f8396fbc0766ffc))
+        - add the anamix pll override setting ([66d399e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66d399e454b160ce358346cfa9142a24d8493a41))
+        - add the ddr frequency change support for imx8m family ([9c336f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c336f6118a94970f4045641a971fd1e24dba462))
+        - add the PU power domain support on imx8mm/mn ([44dea54](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44dea5444b087acd758b1c8370999be635e17e43))
+        - keep pu domains in default state during boot stage ([9d3249d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9d3249de8078e33b90193d8f91f4914acc36c6ec))
+        - make psci common code pie compatible ([5d2d332](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5d2d3328db88846accd179c96d71bab79a150937))
+
+        - **i.MX 8M Nano**
+
+          - add BL31 PIE support ([62d37a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62d37a4362456694bdae6d8921c2c7572a0d99a4))
+          - add hab and map required memory blocks ([b5f06d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b5f06d3dfad8c27bdf528b083ef919ce4022c52d))
+          - enable dram retention suuport on imx8mn ([2003fa9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2003fa94dc9b9eda575ebfd686308c6f87c366f0))
+
+        - **i.MX 8M Mini**
+
+          - add BL31 PIE support ([a8e6a2c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8e6a2c83ce511dad88eb68f98a3191fa93564d4))
+          - add hab and map required memory blocks ([5941f37](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5941f37288a5ceac495cbdbd3e3d02f1a3c55e0a))
+          - enable dram retention suuport on imx8mm ([b7abf48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7abf485ee15c3e5b16522bb91dd6b0c24bfbfc0))
+
+        - **i.MX 8M Plus**
+
+          - add BL31 PIE support ([7a443fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7a443fefa4eaef65332a38c8189573b5b4b4a1e3))
+          - add hab and map required memory blocks ([62a93aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62a93aa7afcd022f06d322c36979f0aa02713beb))
+
+        - **i.MX 8Q**
+
+          - add 100us delay after USB OTG SRC bit 0 clear ([66345b8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66345b8b13dc32bcd9f6af3c04f60532e7d82858))
+
+    - **Layerscape**
+
+      - **LS1043A**
+
+        - **LS1043ARDB**
+
+          - update ddr configure for ls1043ardb-pd ([18af644](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18af644279b36e841068db0e1c857dedf1456b38))
+
+  - **QEMU**
+
+    - increase size of bl31 ([0e6977e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e6977eee178a6436e4a7e1503ea854989316ff4))
+
+  - **QTI**
+
+    - fix to support cpu errata ([6cc743c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cc743cf0fa9b216f2af8ff87c716dcc0bb6f6a0))
+    - updated soc version for sc7180 and sc7280 ([39fdd3d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/39fdd3d85d1165cd1b876288532000c5c6eb1ecb))
+
+  - **Socionext**
+
+    - **Synquacer**
+
+      - add BL2 support ([48ab390](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/48ab390444e1dabb669430ace9b8e5a80348eed0))
+      - add FWU Multi Bank Update support ([a193825](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a19382521c583b3dde89df14678b011960097f6c))
+      - add TBBR support ([19aaeea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19aaeea00bc4fba94af7aca508af878136930f4a))
+
+  - **ST**
+
+    - add trace for early console ([00606df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/00606df01201fcad509ea9ddff89d5f176bee793))
+    - enable MMC_FLAG_SD_CMD6 for SD-cards ([53d5b8f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/53d5b8ff50d322f764b1f5a8c882b9ee1ba952c9))
+    - properly manage early console ([5223d88](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5223d88032dcecb880d620e63bfa70799dc6cc1a))
+    - search pinctrl node by compatible ([b14d3e2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b14d3e22b4964ce589d107e7fd68601bf070f44c))
+
+    - **STM32MP1**
+
+      - add a check on TRUSTED_BOARD_BOOT with secure chip ([54007c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/54007c37d560dd170efa52a79feb206aefb90ed4))
+      - add a stm32mp crypto library ([ad3e46a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ad3e46a35cb208e16adfe3d753214739583dca10))
+      - add define for external scratch buffer for nand devices ([9ee2510](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9ee2510b62ef9428d767523ddb9c5a39b7a2b954))
+      - add early console in SP_min ([14a0704](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/14a070408d9231dc1c487dfe36058b93faf5915c))
+      - add plat_report_*_abort functions ([0423868](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0423868373026a667f0c004e4d365fa12fd734ef))
+      - add RNG initialization in BL2 for STM32MP13 ([2742374](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2742374414c5891ac37fd4d42ba62c3cff1474c6))
+      - add the decryption support ([cd79116](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd791164a9ad2f42d25d24012715bbe763b41e1c))
+      - add the platform specific build for tools ([461d631](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/461d631acae9daec77c9668216280cbf66240249))
+      - add the TRUSTED_BOARD_BOOT support ([beb625f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/beb625f90bfd1858b9d413cae67457e57c79a118))
+      - allow to override MTD base offset ([e0bbc19](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0bbc190d500e53ee0566af85639d3cdbbe7177d))
+      - configure the serial boot load address ([4b2f23e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4b2f23e55f27b6baccf3e858234e69685d51fcf4))
+      - extend STM32MP_EMMC_BOOT support to FIP format ([95e4908](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/95e4908e17fbb44aed1f8612fefdd6d21fef8f49))
+      - manage second NAND OTP on STM32MP13 ([d3434dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d3434dca0b3acb902fe3a6cf39065ba917f69b1c))
+      - manage STM32MP13 rev.Y ([a3f97f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a3f97f66c36e987a6617f1f39c3b9e64b763212c))
+      - optionally use paged OP-TEE ([c4dbcb8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c4dbcb885201c89a44df203661af007945782993))
+      - remove unused function from boot API ([f30034a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f30034a298a8d7260464cbcf2d2306bff533d6dd))
+      - retrieve FIP partition by type UUID ([1dab28f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1dab28f99dfa03dc11538056a90f00f37bfb1085))
+      - save boot auth status and partition info ([ab2b325](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab2b325c1ab895e626d4e11a9f26b9e7c968f8d8))
+      - update ROM code API for header v2 management ([89c0774](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/89c07747d0396b92c83af8736ff49ef8c09bc176))
+
+      - **STM32MP13**
+
+        - change BL33 memory mapping ([10f6dc7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10f6dc789350ed5915a474b2d411890261b741ae))
+
+      - **STM32MP15**
+
+        - manage OP-TEE shared memory ([722ca35](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/722ca35ecc1c5de8682ca8df315a6369d0c21946))
+
+  - **Texas Instruments**
+
+    - **K3**
+
+      - add support for J784S4 SoCs ([4a566b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a566b26ae6135d4c13deab9d3f1c40c1cb8960a))
+
+  - **Xilinx**
+
+    - **Versal**
+
+      - add infrastructure to handle multiple interrupts ([e497421](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e497421d7f1e13d15313d1ca71a8e91f370cce1e))
+      - get the handoff params using IPI ([205c7ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/205c7ad4cd73e5c091b03f23a3a3be74da5c8aea))
+      - resolve the misra 10.1 warnings ([b86e1aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b86e1aade1c0953bd60ae0b35f1c3571ee8bae3f))
+      - update macro name to generic and move to common place ([f99306d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f99306d49ba074279c5402a0a34e6bc9797d77de))
+
+      - **Versal NET**
+
+        - add support for QEMU COSIM platform ([6a079ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a079efd909b459448f561618df24fa94038dbad))
+        - add documentation for Versal NET SoC ([4efdc48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4efdc488961502033262613b6f20abcee68bbf84))
+        - add SMP support for Versal NET ([8529c76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8529c7694f8d614e76dcc80b394ec8a6751df44c))
+        - add support for IPI ([0bf622d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0bf622de68cd353a8406f76647b6afd8791d675d))
+        - add support for platform management ([0654ab7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0654ab7f75449307c79789e12be7aab2338edcc3))
+        - add support for Xilinx Versal NET platform ([1d333e6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1d333e69091f0c71854a224e8cfec08695b7d1f3))
+
+    - **ZynqMP**
+
+      - optimization on pinctrl_functions ([314f9f7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/314f9f7957fbab12dc8d073cf054b99520372e0e))
+      - add support for ProvenCore ([358aa6b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/358aa6b21118ae4eedf816f663aa950b58f7fd4e))
+      - add support for xck24 silicon ([86869f9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/86869f99d0c144ed18fb947866554a4a56b67741))
+      - protect eFuses from non-secure access ([d0b7286](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0b7286e48f0a34e7e9a8db3948caf1809193430))
+      - resolve the misra 10.1 warnings ([bfd7c88](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bfd7c881905702082e3c2a56d5228ccf5fe98f11))
+
+- **Bootloader Images**
+
+  - add interface to query TF-A semantic ver ([dddf428](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dddf4283b043ad0a81d27bd5bb2f0c647c511e11))
+
+  - **BL32**
+
+    - **TSP**
+
+      - add FF-A support to the TSP ([4a8bfdb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a8bfdb90956ecec02ba5e189fe5452817a65179))
+      - add ffa_helpers to enable more FF-A functionality ([e9b1f30](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9b1f300a974a7e82190b95899c3128b73088488))
+      - enable test cases for EL3 SPMC ([15ca1ee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15ca1ee342a4dcd8a73a4ae158d245cd4266c832))
+      - increase stack size for tsp ([5b7bd2a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5b7bd2af0b2972dfffeaa674947c0082d6b5126b))
+
+- **Services**
+
+  - add a SPD for ProvenCore ([b0980e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0980e584398fc5adc908cd68f1a6deefa943d29))
+
+  - **RME**
+
+    - **RMMD**
+
+      - add support for RMM Boot interface ([8c980a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c980a4a468aeabb9e49875fec395c625a0c2b2b))
+      - add support to create a boot manifest ([1d0ca40](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1d0ca40e9084903d21e570bb312646626aaf574b))
+
+  - **SPM**
+
+    - add tpm event log node to spmc manifest ([054f0fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/054f0fe1361ba0cb339fb0902470988a82a24cf7))
+
+    - **SPMD**
+
+      - avoid spoofing in FF-A direct request ([5519f07](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5519f07cd46a4139615a3e8f5e57d1834b23a6f8))
+
+  - **DRTM**
+
+    - add a few DRTM DMA protection APIs ([2b13a98](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2b13a985994213f766ada197427f96e064f1b59b))
+    - add DRTM parameters structure version check ([c503ded](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c503ded2c5d9ceec9fba4cc0901805307a14af3d))
+    - add Event Log driver support for DRTM ([4081426](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40814266d53b7154daf5d212de481b397db43823))
+    - add PCR entries for DRTM ([ff1e42e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff1e42e20aa247ba11cf81742abff07ece376ba8))
+    - add platform functions for DRTM ([2a1cdee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2a1cdee4f5e6fe0b90399e442075880acad1869e))
+    - add remediation driver support in DRTM ([1436e37](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1436e37dcb894a539a22da48a34ef01566ae728b))
+    - add standard DRTM service ([e62748e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e62748e3f1f16934f0ef2d5742f3ca0b125eaea2))
+    - check drtm arguments during dynamic launch ([40e1fad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40e1fad69b9f28ab5e57cea33261bf629b05519c))
+    - ensure that no SDEI event registered during dynamic launch ([b1392f4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b1392f429cdd368ea2b8e183a1ac0fb31deaf694))
+    - ensure that passed region lies within Non-Secure region of DRAM ([764aa95](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/764aa951b2ca451694c74791964a712d423d8206))
+    - flush dcache before DLME launch ([67471e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/67471e75b3cf48c361e71894a666bce4395bbb35))
+    - introduce drtm dynamic launch function ([bd6cc0b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bd6cc0b2388c52f2b232427be61ff52c042d724a))
+    - invalidate icache before DLME launch ([2c26597](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c265975a76977c6373636f5f28e114d1b73e10e))
+    - prepare DLME data for DLME launch ([d42119c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d42119cc294fbca2afc263fe5e44538a0ca5e7b8))
+    - prepare EL state during dynamic launch ([d1747e1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d1747e1b8e617ad024456791ce0ab8950bb282ca))
+    - retrieve DRTM features ([e9467af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9467afb2d483ccec8f816902624d848e8f21d86))
+    - take DRTM components measurements before DLME launch ([2090e55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2090e55283c4bf85c7a61735ca0e872745c55896))
+    - update drtm setup function ([d54792b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d54792bd93f76b943bf0559c8373b898e0e3b93c))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - add library support for Hunter ELP ([8c87bec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c87becbc64f2e233ac905aa006d5e15a63a9a8b))
+    - add a64fx cpu to tf-a ([74ec90e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/74ec90e69bbd0e932a61f5461eedc4abd1b99d44))
+    - make cache ops conditional ([04c7303](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04c7303b9c3d2215eebc3d59431519990abe03d0))
+    - remove plat_can_cmo check for aarch32 ([92f8be8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/92f8be8fd1e77be67e9c9711afa8705204758304))
+    - update doc and check for plat_can_cmo ([a2e0123](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a2e0123484e62df8ed9f2943dbd158471bf31221))
+
+  - **OP-TEE**
+
+    - check paged_image_info ([c0a11cd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0a11cd8698394e1d3d3d7c9cedb19846ba59223))
+
+  - **PSCI**
+
+    - add a helper function to ensure that non-boot PEs are offline ([ce14a12](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ce14a12f8b8f02b7221f37c7c4b46f909c1a4346))
+
+  - **C Standard Library**
+
+    - introduce __maybe_unused ([351f9cd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/351f9cd8897fd3ea52db2421721a152494b16328))
+
+  - **PSA**
+
+    - add delegated attestation partition API ([4b09ffe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4b09ffef49663ebc8c8f5c3da19636208fe2fa06))
+    - remove initial attestation partition API ([420deb5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/420deb5a0dbbd35962e5449f82434c703e7a1179))
+
+- **Drivers**
+
+  - **Authentication**
+
+    - allow to verify PublicKey with platform format PK ([40f9f64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40f9f644e8af34e745dbaec73d7128c0a4902e54))
+    - enable MBEDTLS_CHECK_RETURN_WARNING ([a4e485d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4e485d7bf1c428d64e90e9821e4b1a109d10626))
+
+    - **Crypto**
+
+      - update crypto module for DRTM support ([e43caf3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e43caf3890817e91b3d35b5ae1149a208f1a4016))
+
+    - **mbedTLS**
+
+      - update mbedTLS driver for DRTM support ([8b65390](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8b653909b7e2371c6dcddbeac112b9671c886f34))
+
+  - **I/O**
+
+    - **MTD**
+
+      - add platform function to allow using external buffer ([f29c070](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f29c0702d2e7a67327b67766f91793d8ae6d0f73))
+
+  - **MMC**
+
+    - get boot partition size ([f462c12](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f462c1249ac41f43423011bb12ace38cbeb0af4c))
+    - manage SD Switch Function for high speed mode ([e5b267b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e5b267bba14c55e7906d120c52d4e8e8bbb68df6))
+
+  - **MTD**
+
+    - add platform function to allow using external buffer ([f29c070](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f29c0702d2e7a67327b67766f91793d8ae6d0f73))
+
+  - **GUID Partition Tables Support**
+
+    - allow to find partition by type UUID ([564f5d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/564f5d477663bc007916a11c48bdd8b9be4ad369))
+
+  - **SCMI**
+
+    - send powerdown request to online secondary cpus ([14a2892](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/14a289230918b23b0985e215d38614dc7480bd02))
+    - set warm reboot entry point ([5cf9cc1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5cf9cc130a90fd8c4503c57ec4af235b469fd473))
+
+  - **Arm**
+
+    - **Ethos-N**
+
+      - add support for SMMU streams ([b139f1c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b139f1cf975f9968eb8bd1182a173b976ecf06f9))
+
+    - **GIC**
+
+      - add APIs to raise NS and S-EL1 SGIs ([dcb31ff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dcb31ff79096fc88b45df8068e5de83b93f833ed))
+
+      - **GICv3**
+
+        - validate multichip data for GIC-700 ([a78b3b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a78b3b382b07675a89a66ddffe926ed225eeb245))
+
+    - **RSS**
+
+      - add new comms protocols ([3125901](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/31259019235aebf7aa533d5c893940f597fb1a8b))
+
+  - **ST**
+
+    - **Crypto**
+
+      - add AES decrypt/auth by SAES IP ([4bb4e83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4bb4e836498b0131feefbba3f857a0bf3b89e543))
+      - add ECDSA signature check with PKA ([b0fbc02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0fbc02aea76d31e749444da63b084e6b2bd089b))
+      - add STM32 RNG driver ([af8dee2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af8dee20d5fee29f34ccd9b9556e0c23655ff549))
+      - remove BL32 HASH driver usage ([6b5fc19](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6b5fc19227ff8935b1352c0e4c0d716ebee60aa2))
+      - update HASH for new hardware version used in STM32MP13 ([68039f2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68039f2d14626adce09512871d6cde20ff45e1d9))
+
+    - **SDMMC2**
+
+      - define FIFO size ([b46f74d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b46f74d4e68ee08b6e912cd7f855a16cc5e79a6a))
+      - make reset property optional ([8324b16](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8324b16cd5e0b1ae2f85264a74f879e8fb1bca2a))
+      - manage CMD6 ([3deebd4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3deebd4ccf39904d7fe777f53e9dbaa86691d653))
+
+    - **UART**
+
+      - add initialization with the device tree ([d99998f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d99998f76ed2e8676be25e31e9479a90c16c7098))
+      - manage STM32MP_RECONFIGURE_CONSOLE ([ea69dcd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ea69dcdc737d8b48fec769042922914e988153ef))
+
+- **Miscellaneous**
+
+  - **Debug**
+
+    - add AARCH32 CP15 fault registers ([bb22891](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb2289142cbf0f3546c1034e0500b5dc32aef740))
+    - add helpers for aborts on AARCH32 ([6dc5979](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6dc5979a6cb2121e4c16e7bd62e24030e0f42755))
+
+  - **FDTs**
+
+    - **STM32MP1**
+
+      - add CoT and fuse references for authentication ([928fa66](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/928fa66272a0985c900c996912b54904c64d0520))
+      - change pin-controller to pinctrl ([44fea93](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44fea93bf729f631f6ae47e06ac7b6012a795791))
+
+      - **STM32MP13**
+
+        - use STM32MP_DDR_S_SIZE in fw-config ([936f29f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/936f29f6b51b3c7f37fd34e30a7f1f7c3944b361))
+
+      - **STM32MP15**
+
+        - add Avenger96 board with STM32MP157A DHCOR SoM ([51e2230](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/51e223058fe70b311542178f1865514745fa7874))
+        - add support for STM32MP157C based DHCOM SoM on PDK2 board ([eef485a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eef485abb13b6df9a94137edd82904aab0ecf02d))
+
+  - **SDEI**
+
+    - add a function to return total number of events registered ([e6381f9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6381f9cf8c0c62c32d5a4765aaf166f50786914))
+
+  - **TBBR**
+
+    - increase PK_DER_LEN size ([1ef303f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1ef303f9f79020330bbd8e48ac652e8f2121a41b))
+
+- **Tools**
+
+  - **Firmware Image Package Tool**
+
+    - add cca, core_swd, plat cert in FIP ([147f52f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/147f52f3e81f7ccf1dae90bc5687ec137feeb46c))
+
+  - **Certificate Creation Tool**
+
+    - define the cca chain of trust ([0a6bf81](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a6bf811d7f873a180ef4b9f96f5596b26d270c6))
+    - update for ECDSA brainpoolP256r/t1 support ([e78ba69](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e78ba69e3525c968118eb91f443b1e9db9eee5f5))
+
+- **Dependencies**
+
+  - **Compiler runtime libraries**
+
+    - update compiler-rt source files ([8a6a956](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8a6a9560b5dcccfb68064c0c8c9b4b47981c6ac7))
+
+  - **libfdt**
+
+    - add function to set MAC addresses ([1aa7e30](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1aa7e302a84bbf46a97bcfbb54b6b6d57de76cee))
+    - upgrade libfdt source files ([94b2f94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/94b2f94bd63258c300b53ad421488c3c4455712b))
+
+  - **zlib**
+
+    - update zlib source files ([a194255](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a194255d75ed9e2ef56bd6e14349a3e7d86af934))
+
+### Resolved Issues
+
+- **Architecture**
+
+  - **Performance Monitors Extension (FEAT_PMUv3)**
+
+    - add sensible default for MDCR_EL2 ([7f85619](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f8561985778cbe5cdc7d57984c818119e87adaf))
+
+  - **Scalable Matrix Extension (FEAT_SME)**
+
+    - add missing ISBs ([46e92f2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/46e92f2862326cbe57acecb2d0f3c2ffbcc176d2))
+
+- **Platforms**
+
+  - **Arm**
+
+    - **FVP**
+
+      - fdts: Fix idle-states entry method ([0e3d880](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e3d88070f69c6aa7cc51a2847cbba3535992397))
+      - fdts: fix memtimer subframe addressing ([3fd12bb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3fd12bb8c622917d8491082b1472c39efb89c0cf))
+      - fdts: unify and fix PSCI nodes ([6b2721c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6b2721c01691743a65475e82944e2f8868bf0159))
+
+    - **FVP Versatile Express**
+
+      - fdts: Fix vexpress,config-bus subnode names ([60da130](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/60da130a8c5ac29bc35870180c35ca04db506e0f))
+
+    - **Morello**
+
+      - dts: add model names ([30df890](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30df8904d0f6973bbce1ecb51f14c1e4725ddf0b))
+      - dts: fix DP SMMU IRQ ordering ([fba729b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fba729b0ca22be379792ce677296cda075036753))
+      - dts: fix DT node naming ([41c310b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/41c310b4f691c1eefcd0234619bc751966389297))
+      - dts: fix GICv3 compatible string ([982f258](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/982f2585bb27b58c017af70d852a433f36711db1))
+      - dts: fix SCMI shmem/mboxes grouping ([8aeb1fc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8aeb1fcf832d4e06157a1bed1d18ba244c1fe9ee))
+      - dts: fix SMMU IRQ ordering ([5016ee4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5016ee44a740127f7865dc26ed0efbbff1481c7e))
+      - dts: fix stdout-path target ([67a8a5c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/67a8a5c92e7c65108b3cdf6f4f9dd2de7e22f3cd))
+      - dts: remove #a-c and #s-c from memory node ([f33e113](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f33e113c7a7dffd8ed219f25191907fd64bcf19f))
+      - dts: use documented DPU compatible string ([3169572](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3169572ed1bf0de17bb813583cab7ea295a8ec8d))
+      - move BL31 to run from DRAM space ([05330a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/05330a49cd91c346a8b9dc3aff35d0032db4d413))
+
+    - **N1SDP**
+
+      - add numa node id for pcie controllers ([2974d2f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2974d2f2d03e842ed5e01e2e04dd3de6c1d07277))
+      - mapping Run-time UART to IOFPGA UART0 ([4a81e91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a81e91f2752a817364e1fccedb08bb453ad5a56))
+      - replace non-inclusive terms from dts file ([e6ffafb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6ffafbeeae8c78abac37475f19899f0c98523ca))
+
+    - **TC**
+
+      - resolve the static-checks errors ([066450a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/066450abf326f1a68a21cdddf29f62eff95041a9))
+      - tc2 bl1 start address shifted by one page ([8597a8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8597a8cbc23f0f03a15d013dd44a4ed59c991872))
+
+  - **Intel**
+
+    - fix asynchronous read response by copying data to input buffer ([dd7adcf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dd7adcf3a89a75973a88118eeb867d1c212c4ad0))
+    - fix Mac verify update and finalize for return response data ([fbf7aef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fbf7aef408a9f67fabc712bbfd52438290364879))
+
+  - **MediaTek**
+
+    - remove unused cold_boot.[c|h] ([8cd3b69](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8cd3b693d6d5d3db2433a96c5f2905d92a387cc4))
+    - switch console to runtime state before leaving BL31 ([fcf4dd9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fcf4dd9f794b28bbfff3ee7d66bac8d5e260f46a))
+    - use uppercase for definition ([810d568](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/810d568141050db7d500c5f5ad91efaff93d2036))
+    - wrap cold_boot.h with MTK_SIP_KERNEL_BOOT_ENABLE ([24476b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/24476b2e6128dae2ca2ac46344e18f6f02eae7bf))
+
+    - **MT8186**
+
+      - fix SCP permission ([8a998b5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8a998b5aca3ca895a7722e7496a7fd18cd838f94))
+      - fix EMI_MPU domain setting for DSP ([28a8b73](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/28a8b738feaade74f23af0e889005e687fde38b5))
+      - fix the DRAM voltage after the system resumes ([600f168](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/600f168172a9281a0061f84e4da5318e08762aa1))
+      - move SSPM base register definition to platform_def.h ([2a2b51d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2a2b51d8f76e2acdabb431e928beb90e0a30c87c))
+
+    - **MT8188**
+
+      - add mmap entry for CPU idle SRAM ([32071c0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32071c0263899e0e7a4b7f2c754e6363547f33b1))
+      - refine c-state power domain for extensibility ([e35f4cb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e35f4cbf80ba671c42644c1ac7f8f6541042c6e5))
+      - refine gic init flow after system resume ([210ebbb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/210ebbb0a6a0520cb3a5930c4fefa94baee33462))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - **i.MX 8M**
+
+        - correct serial output for HAB JR0 ([6e24d79](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6e24d795094e7fac1edc13336ce0bfd39d98e66f))
+        - fix dram retention fsp_table access ([6c8f523](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c8f523138cd94bc0608708e821a09b02c8c2f5a))
+        - move caam init after serial init ([901d74b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/901d74b2d46cbd8b1d27477fa16388520fdabab1))
+        - update poweroff related SNVS_LPCR bits only ([ad6eb19](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ad6eb1951b986f30635025bbdf29e257b6b1e362))
+
+        - **i.MX 8Q**
+
+          - correct architected counter frequency ([21189b8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21189b8e21062b71c9056ac1cf60d25bb018007c))
+
+  - **QEMU**
+
+    - enable SVE and SME ([337ff4f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/337ff4f1dd6604738d79fd3fa275ae74d74256b2))
+
+  - **QTI**
+
+    - adding secure rm flag ([b5959ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b5959ab029fb0a8a271967b0bd7ef438d59061bd))
+
+  - **Raspberry Pi**
+
+    - **Raspberry Pi 3**
+
+      - tighten platform pwr_domain_pwr_down_wfi behaviour ([028c4e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/028c4e42d8f632d40081b88f66d0d05c7d7c9b23))
+
+  - **Renesas**
+
+    - **R-Car**
+
+      - **R-Car 3**
+
+        - fix RPC-IF device node name ([08ae247](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/08ae2471b1417f1d8083a79771338aa2a00b6711))
+
+  - **Rockchip**
+
+    - align fdt buffer on 8 bytes ([621acbd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/621acbd055d712ab8bf79054911155598fdb74d0))
+
+    - **RK3399**
+
+      - explicitly define the sys_sleep_flag_sram type ([7a5e90a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7a5e90a89d91d6662d3e468893e07c91b3a165ee))
+
+  - **Socionext**
+
+    - **Synquacer**
+
+      - increase size of BL33 ([a12a66d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a12a66d0d6d4732d41a27b1ecbc8874731c78101))
+
+  - **ST**
+
+    - add max size for FIP in eMMC boot part ([e7cb4a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e7cb4a86b884d2922984d3cd4651fb905650cfd6))
+    - add missing string.h include ([0d33d38](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0d33d38334cae909a66c74187a36b5833afb8093))
+
+    - **STM32MP1**
+
+      - enable crash console in FIQ handler ([484e846](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/484e846a03a1af5f88e2e28835b6349cc5977935))
+      - fdts: stm32mp1: align DDR regulators with new driver ([9eed71b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9eed71b7221c5fc7ed887f1087e42c9f1a62f581))
+      - update the FIP load address for serial boot ([32f2ca0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32f2ca04bfd2d93329f2f17d9c9d134f339710f9))
+
+      - **STM32MP13**
+
+        - correct USART addresses ([de1ab9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de1ab9fe052deba06a0904b10a6e0312ca49658e))
+
+  - **Xilinx**
+
+    - include missing header ([28ba140](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/28ba1400216d7c7195929d1bd53f059a440a89a2))
+    - miscellaneous fixes for xilinx platforms ([bfc514f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bfc514f10393fb7f4641ad5e75049f3acc246dd2))
+    - remove unnecessary header include ([0ee2dc1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ee2dc118c34ceacc921fee196a4ba9102bdfbea))
+    - update define for ZynqMP specific functions ([24b5b53](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/24b5b53a5922de40e53f0a7ecf65d3d0acc30a0d))
+
+    - **Versal**
+
+      - add SGI register call version check ([5897e13](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5897e135445e2bf3345297fbe9971a113506d714))
+      - enable a72 erratum 859971 and 1319367 ([769446a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/769446a6899d840df8aa5746ec32bf7530fc9826))
+      - fix code indentation issues ([72583f9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/72583f92e6cc1d691b709e05c3ae280dce016fef))
+      - fix macro coding style issues ([80806aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/80806aa1234606bb55af40ae0667cdf4d44423be))
+      - fix Misra-C violations in bl31_setup and pm_svc_main ([68ffcd1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68ffcd1bb22f2c2eac6c3329a1974b3e8ec6f515))
+      - remove clock related macros ([47f8145](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47f8145324181b86b6f460fb0c92144ef43e4e14))
+      - resolve misra 10.1 warnings ([19f92c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19f92c4cfe014c5495f3073917119385b0014eda))
+      - resolve misra 15.6 warnings ([1117a16](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1117a16e0379986ea68581c02fb2fee40937452b))
+      - resolve misra 8.13 warnings ([3d2ebe7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d2ebe756a50c27a00a03ae7f0109ed04681ac96))
+      - resolve the misra 4.6 warnings ([f7c48d9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f7c48d9e30e9444f1fdb808ae5d06ed675e335fa))
+      - resolve the misra 4.6 warnings ([912b7a6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/912b7a6fe46619e5df55dbd0b95d306f7bb2695c))
+      - route GIC IPI interrupts during setup ([04cc91b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04cc91b43c1d10fcba563e18f06336987e6e3a24))
+      - use only one space for indentation ([dee5885](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dee588591328b96d9b9ef908869c8b42bd2632f2))
+
+      - **Versal NET**
+
+        - Enable a78 errata workarounds ([bcc6e4a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcc6e4a02a88056b9c45ff28f405e09444433528))
+        - add default values for silicon ([faa22d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/faa22d48d9929d57975b84ab76cb595afdcf57f4))
+        - use api_id directly without FUNCID_MASK ([b0eb6d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0eb6d124b1764264778d17b1519bfe62b7b9337))
+
+    - **ZynqMP**
+
+      - fix coverity scan warnings ([1ac6af1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1ac6af1199e2d14492a9d75aaba69bc775e55bd8))
+      - ensure memory write finish with dsb() ([ac6c135](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ac6c135c83fe4efa4d6e9b9c06e899b57ce5647a))
+      - fix for incorrect afi write mask value ([4264bd3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4264bd33e718023c62a2776e3ca40db88fce8b08))
+      - move bl31 with DEBUG=1 back to OCM ([389594d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/389594dfa7e60a720d60f0d55296f91ba1610de5))
+      - move debug bl31 based address back to OCM ([0ba3d7a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ba3d7a4ca04486f45d062fab54238d9a554a682))
+      - remove additional 0x in %p print ([05a6107](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/05a6107ff18b03f4ca33496268398133abf04aaa))
+      - resolve misra 4.6 warnings ([cdb6211](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cdb62114cfcdaeb85e64bcde459342a0a95f58e3))
+      - resolve misra 8.13 warnings ([8695ffc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8695ffcfcb3801ea287fae7652ba1c350636831f))
+      - resolve MISRA-C:2012 R.10.1 warnings ([c889088](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c889088386432af69e3ca853825c4219884c1cc1))
+      - resolve the misra 4.6 warnings ([15dc3e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15dc3e4f8d9730ce58cc599fb9970d486c8b9202))
+      - resolve the misra 4.6 warnings ([ffa9103](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ffa910312c371080f4d0d50eb1354ad05b7be7a8))
+      - resolve the misra 8.6 warnings ([7b1a6a0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7b1a6a08ccc7522687f66e6e989bbc597d08ab06))
+
+- **Bootloader Images**
+
+  - **BL31**
+
+    - allow use of EHF with S-EL2 SPMC ([7c2fe62](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c2fe62f1347bb94d82e9fdd3bc5eaebedaf0bc7))
+    - harden check in delegate_async_ea ([d435238](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d435238dc364f0c9f0e41661365f83d83899829d))
+    - pass the EA bit to 'delegate_sync_ea' ([df56e9d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/df56e9d199939c571b3fd8f539d213fc36e14494))
+
+- **Services**
+
+  - **RME**
+
+    - refactor RME fid macros ([fb00dc4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fb00dc4a7b208cf416d082bb4367b54286bc8e3b))
+    - relax RME compiler requirements ([7670ddb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7670ddb1fb5d4fa5e2e234375f7a4c0763f1c57a))
+    - update FVP platform token ([364b4cd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/364b4cddbab859a56e63813aab4e983433187191))
+    - use RMM shared buffer for attest SMCs ([dc65ae4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dc65ae46439f4d1be06e3a016fe76319d7a62954))
+    - xlat table setup fails for bl2 ([e516ba6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e516ba6de5e248e93156b5261cedbff811226e0e))
+
+    - **RMMD**
+
+      - return X4 output value ([8e51ccc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e51cccaefc1e0e79ac2f0667ffec1cc46cf7665))
+
+  - **SPM**
+
+    - **EL3 SPMC**
+
+      - check descriptor size for overflow ([eed15e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eed15e4310a7bcd90bf6d66b00037e05186329bb))
+      - compute full FF-A V1.1 desc size ([be075c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be075c3edf634a2df1065597266c3e41d284287b))
+      - deadlock when relinquishing memory ([ac568b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ac568b2bccb9da71f2bd7f1c7204189d1ff678d9))
+      - error handling in allocation ([cee8bb3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cee8bb3b38ea266a5008719548965352ec695cae))
+      - fix detection of overlapping memory regions ([0dc3518](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0dc35186669ddaedb3a932e103c3976bc3bf75d6))
+      - fix incomplete reclaim validation ([c4adbe6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c4adbe6e67617bb2d4f0ffb1c1daa3395f7ac227))
+      - fix location of fragment length check ([21ed9ea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21ed9ea32325fc556fa7e907e4995888bd3a3b45))
+      - fix relinquish validation check ([b4c3621](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b4c3621e0dc8e7ec6d3229253e0326f12c8fe5a9))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - fix cpu version check for Neoverse N2, V1 ([03ebf40](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03ebf409c711e9f2006cedded7dc415dfe566975))
+    - workaround for Cortex-A510 erratum 2666669 ([afb5d06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/afb5d069a6fa049f18e90fa50e714b8a4acc55f4))
+    - workaround for Cortex-A710 2216384 ([b781fcf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b781fcf139c3a609f1adffb8097a23eadbed53a9))
+    - workaround for Cortex-A710 erratum 2291219 ([888eafa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/888eafa00b99aa06b4ff688407336811a7ff439a))
+    - workaround for Cortex-A76 erratum 2743102 ([4927309](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49273098a5ccd87a2084a85f9e47d74fa3ecfc90))
+    - workaround for Cortex-A77 erratum 2743100 ([4fdeaff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fdeaffe860a998e8503b847ecceec60dcddcdc5))
+    - workaround for Cortex-A78C erratum 2376749 ([5d3c1f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5d3c1f58905d3b7350e02c4687dceaf0971700b3))
+    - workaround for Cortex-X3 erratum 2313909 ([7954412](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/79544126943a90d31d81177655be11f75330ffed))
+    - workaround for Neoverse N1 erratum 2743102 ([8ce4050](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ce40503ad00fe0dd35de6e51551da2b4f08a848))
+    - workaround for Neoverse-N2 erratum 2326639 ([43438ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/43438ad1ad6651964e9ae75d35f40aed8d86d088))
+    - workaround for Neoverse-N2 erratum 2388450 ([884d515](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/884d515625aa09b22245c32db2fcc9222c7f34fd))
+    - workaround for Cortex A78C erratum 2242638 ([6979f47](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6979f47fecfd34ac1405117c23f2e36ecb552a20))
+    - workaround for Cortex-A510 erratum 2347730 ([11d448c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11d448c93463180d03b46e9ba204124ff7ad5116))
+    - workaround for Cortex-A510 erratum 2371937 ([a67c1b1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a67c1b1b2b521c888790c68e4201ecce0836a0e9))
+    - workaround for Cortex-A710 erratum 2147715 ([3280e5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3280e5e655ad64b6e299e18624d9c586e6b37cb1))
+    - workaround for Cortex-A710 erratum 2371105 ([3220f05](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3220f05ef900addccb6e444d6746e4ed28c9804f))
+    - workaround for Cortex-A77 erratum 2356587 ([7bf1a7a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7bf1a7aaaa41034587e43d5805b42da83090b85b))
+    - workaround for Cortex-A78C 2132064 ([8008bab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8008babd58f60c91a88ad79df3d32f63596b433a))
+    - workaround for Cortex-A78C erratum 2395411 ([4b6f002](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4b6f0026ea2622b3f46cdef5b468853ddd281b39))
+    - workaround for Cortex-X2 erratum 2371105 ([bc0f84d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc0f84de40d4f1efddfb50071fff09d32f0ea9b2))
+    - workaround for Neoverse-N2 erratum 2376738 ([e6602d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6602d4b153b81b49b39c22e70f052f9018687b7))
+    - workaround for Neoverse-V1 erratum 1618635 ([14a6fed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/14a6fed5ac14035f578a75a9758f9df7ba4d7496))
+    - workaround for Neoverse-V1 erratum 2294912 ([39eb5dd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/39eb5ddbbf98bdb6c012a9d852f489f2f8e15c05))
+    - workaround for Neoverse-V1 erratum 2372203 ([57b73d5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/57b73d553305d89da7098f9b53b0a2356ca7ff8b))
+
+  - **EL3 Runtime**
+
+    - **RAS**
+
+      - restrict RAS support for NS world ([46cc41d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/46cc41d5592a16f702f7f0c0c41f8948a3e11cda))
+      - trap "RAS error record" accesses only for NS ([00e8f79](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/00e8f79c15d36f65f6c7f127177105e02177cbc0))
+
+  - **FCONF**
+
+    - fix type error displaying disable_auth ([381f465](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/381f465ca92f7c9759e85c1bfb4c95ceda26581e))
+
+  - **PSCI**
+
+    - fix MISRA failure - Memory - illegal accesses ([0551aac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0551aac5637a638d4b9d8865a2c20ec5153de3bf))
+
+  - **GPT**
+
+    - correct the GPC enable sequence ([14cddd7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/14cddd7a58799c8a9d349a4adc0136c1ab5d0b6c))
+
+  - **C Standard Library**
+
+    - pri*ptr macros for aarch64 ([d307229](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d307229d754ae4d833ed50be50420aaf070065bf))
+
+  - **PSA**
+
+    - fix Null pointer dereference error ([c32ab75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c32ab75c41adfe28a60f1ff159012a7d78e72fdc))
+    - update measured boot handle ([4d879e1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4d879e1e5a40cefae5b5e13086a16741bf3f6d67))
+    - add missing semicolon ([d219ead](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d219ead1db5ca02ec7c7905ac01d7b268c5026ae))
+    - align with original API in tf-m-extras ([471c989](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/471c9895a630560561717067113e4c4d7127bb9f))
+    - extend measured boot logging ([901b0a3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/901b0a3015a652d9eb66c063b0984fade9adf08f))
+
+  - **Context Management**
+
+    - remove explicit ICC_SRE_EL2 register read ([2b28727](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2b28727e6dafdaa08a517b5a97bda5de26cc8919))
+
+  - **Semihosting**
+
+    - fix seek call failure check ([7c49438](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c4943887477754024f0f736461d9543d502efcc))
+
+- **Drivers**
+
+  - **Authentication**
+
+    - correct sign-compare warning ([ed38366](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ed38366f1dfeb0b0789fd69b400728598ae3c64e))
+
+  - **Measured Boot**
+
+    - add SP entries to event_log_metadata ([e637a5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e637a5e19da72599229fd2c70e793c123aaf14ca))
+    - clear the entire digest array of Startup Locality event ([70b1c02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70b1c025003452602f68feb13402c705e44145aa))
+    - fix verbosity level of RSS digests traces ([2abd317](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2abd317d27a26bbfa3da7fe3fe709da3fa0f09af))
+
+  - **MMC**
+
+    - remove broken, unsecure, unused eMMC RPMB handling ([86b015e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/86b015eb1be57439c2a01cb35d800c7f1b5c8467))
+    - resolve the build error ([ccf8392](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ccf8392ccb105638fe710901d3c7ed6594d9450e))
+
+  - **SCMI**
+
+    - base: fix protocol list querying ([cad90b5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cad90b569db7c547470cca922bd93207adcadfad))
+    - base: fix protocol list response size ([d323f0c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d323f0cf000f1d999bf78d89c0037af76b6bf8d8))
+
+  - **UFS**
+
+    - add retries to ufs_read_capacity ([28645eb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/28645ebd706fe6ac9f34db9f7be5657fe4cffc1a))
+    - fix slot base address computation ([7d9648d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d9648dd6cf3b1dcd90b6917d9d0b545b1c4c975))
+    - init utrlba/utrlbau with desc_base ([9d6d1a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9d6d1a94c99c3a0e89792c5cc118a1d8c8a9dbb7))
+    - point utrlbau to header instead of upiu ([9d3f6c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9d3f6c4b6068b3a4747f5d1dc650607876eff583))
+    - removes dp and run-stop polling loops ([660c208](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/660c208d9bd2770f295005fc26a9b6f788567f41))
+    - retry commands on unit attention ([3d30955](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d309556c75bcdb59fd4e4178fa2b79aa472dc90))
+
+  - **Arm**
+
+    - **GIC**
+
+      - **GICv3**
+
+        - fix overflow caused by left shift ([6aea762](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6aea7624a01cc39c19d4237c4b108659270a61c5))
+        - update the affinity mask to 8 bit ([e689048](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e689048e20af70983e0d384301c408fc725cb5eb))
+
+        - **GIC-600**
+
+          - implement workaround to forward highest priority interrupt ([e1b15b0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e1b15b09a530f2a0b0edc4384e977452d6b389eb))
+
+    - **RSS**
+
+      - clear the message buffer ([e3a6fb8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e3a6fb84f523e68d2f1398348d1ae2635f3e57bc))
+      - determine the size of sw_type in RSS mboot metadata ([2c8f2a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c8f2a9ad45023354516d419dc9fda2a4f02812b))
+      - fix build issues with comms protocol ([ab545ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab545efddcdbf5d08ad3b1e8f4ea15a0faf168a7))
+      - reduce input validation for measured boot ([13a129e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/13a129e8dcea358033f3c83b2d81b25129e02d43))
+      - remove dependency on attestation header ([6aa7154](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6aa71542f35047ea0b537e3a6016de6c579c9d6b))
+      - rename AP-RSS message size macro ([70247dd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70247ddbbd0a55a1ddf1d02f2a35b5cad3949dd1))
+
+  - **NXP**
+
+    - **DDR**
+
+      - fix firmware buffer re-mapping issue ([742c23a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/742c23aab79a21803472c5b4314b43057f1d3e84))
+
+  - **ST**
+
+    - **Clock**
+
+      - correct MISRA C2012 15.6 ([56f895e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56f895ede3a2a4a97c0e4f8270050aff20a167bc))
+      - correctly check ready bit ([3b06a53](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b06a53044e754979cb0608fd93a137a5879a6a0))
+
+- **Miscellaneous**
+
+  - **AArch64**
+
+    - make AArch64 FGT feature detection more robust ([c687776](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c6877763cd3a286983df160c8207368174c1b820))
+
+  - **Debug**
+
+    - backtrace stack unwind misses lr adjustment ([a149eb4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a149eb4d87453f58418ad32c570090739a3e0dd6))
+    - decouple "get_el_str()" from backtrace ([0ae4a3a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ae4a3a3f0cd841b83f2944dde9837ea67f08813))
+
+  - **FDTs**
+
+    - **STM32MP1**
+
+      - **STM32MP13**
+
+        - align sdmmc pins with kernel ([c7ac7d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c7ac7d65a7d1ee1b656bf1260ede6b8e2226bbac))
+        - cleanup DT files ([4c07deb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c07deb53e0e7daafc93bc67fdcbb3de7b73d730))
+        - correct PLL nodes name ([93ed4f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/93ed4f0801f5b3571abdd7e039d09d508c987063))
+        - remove secure status ([8ef8e0e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ef8e0e30e301e6b2595d571f004ae86b1a1ce06))
+        - update SDMMC max frequency ([c9a4cb5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c9a4cb552cdd168fcab2c0383b8fbe30dc99092f))
+
+  - **Security**
+
+    - optimisations for CVE-2022-23960 ([e74d658](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e74d658181e5e69b6b5e16b40adc1ffef4c1efb9))
+
+- **Documentation**
+
+  - document missing RMM-EL3 runtime services ([e50fedb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e50fedbc869341d044d4cb3479a0ab3d4edaf225))
+  - add LTS maintainers ([ab0d4d9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab0d4d9d44fe54535a0ae647092a3cfff368f126))
+  - update maintainers list ([f23ce63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f23ce639050481cda939b9e4738ed01d46481ee3))
+
+  - **Changelog**
+
+    - fix the broken link to commitlintrc.js ([c1284a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c1284a7f93309c88fd781d2b4720f742e147284e))
+
+- **Build System**
+
+  - disable default PIE when linking ([7b59241](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7b5924184566bcdcc01966905ffdcabcd6ea4b32))
+  - discard sections also with SEPARATE_NOBITS_REGION ([64207f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/64207f858f5cbf44aa6528be19a863acc4444568))
+  - ensure that the correct rule is called for tools ([598b166](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/598b166bbc2f09fc219d44ecff0c870854bfa093))
+  - fix arch32 build issue for clang ([94eb127](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/94eb127719881f39c7f235c887fb2c0b82341696))
+  - make TF-A use provided OpenSSL binary ([e95abc4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e95abc4c01822ef43e9e874d63d6596dc0b57279))
+
+- **Tools**
+
+  - **Secure Partition Tool**
+
+    - fix concurrency issue for SP packages ([0aaa382](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0aaa382fe2395c82c9491b199b6b82819afd368f))
+    - operators "is/is not" in sp_mk_gen.py ([1a28f29](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1a28f290b8224eb1d78a2476faaedc5154f82208))
+    - 'sp_mk_generator.py' reference to undef var ([0be2475](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0be2475f6990a37d2d54b7ed06bac9cb46f4660d))
+
+- **Dependencies**
+
+  - add missing aeabi_memcpy.S ([93cec69](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/93cec697deb654303379cae8f25a31dc8b90cd31))
+
 ## [2.7.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.6..refs/tags/v2.7.0) (2022-05-20)
 
 ### New Features
diff --git a/docs/components/ffa-manifest-binding.rst b/docs/components/ffa-manifest-binding.rst
index 6d2f905..7483c90 100644
--- a/docs/components/ffa-manifest-binding.rst
+++ b/docs/components/ffa-manifest-binding.rst
@@ -114,6 +114,19 @@
 - managed-exit
    - value type: <empty>
    - Specifies if managed exit is supported.
+   - This field is deprecated in favor of ns-interrupts-action field in the FF-A
+     v1.1 EAC0 spec.
+
+- ns-interrupts-action [mandatory]
+   - value type: <u32>
+   - Specifies the action that the SPMC must take in response to a Non-secure
+     physical interrupt.
+
+      - 0x0: Non-secure interrupt is queued
+      - 0x1: Non-secure interrupt is signaled after a managed exit
+      - 0x2: Non-secure interrupt is signaled
+
+   - This field supersedes the managed-exit field in the FF-A v1.0 spec.
 
 - has-primary-scheduler
    - value type: <empty>
diff --git a/docs/components/index.rst b/docs/components/index.rst
index 0972a68..30d80fc 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -4,7 +4,6 @@
 .. toctree::
    :maxdepth: 1
    :caption: Contents
-   :numbered:
 
    spd/index
    activity-monitors
diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst
index 6fc0c2e..2ea8012 100644
--- a/docs/components/realm-management-extension.rst
+++ b/docs/components/realm-management-extension.rst
@@ -196,7 +196,7 @@
  -C bp.refcounter.use_real_time=0                               \
  -C bp.ve_sysregs.exit_on_shutdown=1                            \
  -C cache_state_modelled=1                                      \
- -C bp.dram_size=2                                              \
+ -C bp.dram_size=4                                              \
  -C bp.secure_memory=1                                          \
  -C pci.pci_smmuv3.mmu.SMMU_ROOT_IDR0=3                         \
  -C pci.pci_smmuv3.mmu.SMMU_ROOT_IIDR=0x43B                     \
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 8070ff4..25c4269 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -101,7 +101,7 @@
    x2,Maximum number of CPUs to be supported at runtime. RMM should ensure that it can support this maximum number.
    x3,Base address for the shared buffer used for communication between EL3 firmware and RMM. This buffer must be of 4KB size (1 page). The boot manifest must be present at the base of this shared buffer during cold boot.
 
-During cold boot, EL3 firmware needs to allocate a 4K page that will be
+During cold boot, EL3 firmware needs to allocate a 4KB page that will be
 passed to RMM in x3. This memory will be used as shared buffer for communication
 between EL3 and RMM. It must be assigned to Realm world and must be mapped with
 Normal memory attributes (IWB-OWB-ISH) at EL3. At boot, this memory will be
@@ -522,8 +522,8 @@
 
 .. _rmm_el3_manifest_struct:
 
-RMM-EL3 Boot Manifest Version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+RMM-EL3 Boot Manifest structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The RMM-EL3 Boot Manifest structure contains platform boot information passed
 from EL3 to RMM. The width of the Boot Manifest is 128 bits
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index 18d870b..f0caf89 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -150,9 +150,6 @@
   at EL3.
 - If neither ``SPMD_SPM_AT_SEL2`` or ``SPMC_AT_EL3`` are enabled the SPMC
   exception level is set to S-EL1.
-- **CTX_INCLUDE_EL2_REGS**: this option permits saving (resp.
-  restoring) the EL2 system register context before entering (resp.
-  after leaving) the SPMC. It is mandatorily enabled when
   ``SPMD_SPM_AT_SEL2`` is enabled. The context save/restore routine
   and exhaustive list of registers is visible at `[4]`_.
 - **SP_LAYOUT_FILE**: this option specifies a text description file
@@ -161,16 +158,16 @@
   is required when ``SPMD_SPM_AT_SEL2`` is enabled hence when multiple
   secure partitions are to be loaded by BL2 on behalf of the SPMC.
 
-+---------------+----------------------+------------------+-------------+
-|               | CTX_INCLUDE_EL2_REGS | SPMD_SPM_AT_SEL2 | SPMC_AT_EL3 |
-+---------------+----------------------+------------------+-------------+
-| SPMC at S-EL1 |         0            |        0         |      0      |
-+---------------+----------------------+------------------+-------------+
-| SPMC at S-EL2 |         1            | 1 (default when  |      0      |
-|               |                      |    SPD=spmd)     |             |
-+---------------+----------------------+------------------+-------------+
-| SPMC at EL3   |         0            |        0         |      1      |
-+---------------+----------------------+------------------+-------------+
++---------------+------------------+-------------+-------------------------+
+|               | SPMD_SPM_AT_SEL2 | SPMC_AT_EL3 | CTX_INCLUDE_EL2_REGS(*) |
++---------------+------------------+-------------+-------------------------+
+| SPMC at S-EL1 |        0         |      0      |             0           |
++---------------+------------------+-------------+-------------------------+
+| SPMC at S-EL2 | 1 (default when  |      0      |             1           |
+|               |    SPD=spmd)     |             |                         |
++---------------+------------------+-------------+-------------------------+
+| SPMC at EL3   |        0         |      1      |             0           |
++---------------+------------------+-------------+-------------------------+
 
 Other combinations of such build options either break the build or are not
 supported.
@@ -181,9 +178,9 @@
   stack.
 - When ``SPMD_SPM_AT_SEL2=1``, the reference software stack assumes enablement
   of FEAT_PAuth, FEAT_BTI and FEAT_MTE architecture extensions.
-- The ``CTX_INCLUDE_EL2_REGS`` option provides the generic support for
-  barely saving/restoring EL2 registers from an Arm arch perspective. As such
-  it is decoupled from the ``SPD=spmd`` option.
+- ``(*) CTX_INCLUDE_EL2_REGS``, this flag is |TF-A| internal and informational
+  in this table. When set, it provides the generic support for saving/restoring
+  EL2 registers required when S-EL2 firmware is present.
 - BL32 option is re-purposed to specify the SPMC image. It can specify either
   the Hafnium binary path (built for the secure world) or the path to a TEE
   binary implementing FF-A interfaces.
@@ -212,7 +209,6 @@
     CROSS_COMPILE=aarch64-none-elf- \
     PLAT=fvp \
     SPD=spmd \
-    CTX_INCLUDE_EL2_REGS=1 \
     ARM_ARCH_MINOR=5 \
     BRANCH_PROTECTION=1 \
     CTX_INCLUDE_PAUTH_REGS=1 \
@@ -230,7 +226,6 @@
     CROSS_COMPILE=aarch64-none-elf- \
     PLAT=fvp \
     SPD=spmd \
-    CTX_INCLUDE_EL2_REGS=1 \
     ARM_ARCH_MINOR=5 \
     BRANCH_PROTECTION=1 \
     CTX_INCLUDE_PAUTH_REGS=1 \
@@ -794,6 +789,8 @@
  - ``FFA_SECONDARY_EP_REGISTER``
  - ``FFA_MEM_PERM_GET``
  - ``FFA_MEM_PERM_SET``
+ - ``FFA_MSG_SEND2``
+ - ``FFA_RX_ACQUIRE``
 
 FFA_VERSION
 ~~~~~~~~~~~
@@ -827,7 +824,11 @@
 
 When invoked from the Hypervisor or OS kernel, the buffers are mapped into the
 SPMC EL2 Stage-1 translation regime and marked as NS buffers in the MMU
-descriptors.
+descriptors. The provided addresses may be owned by a VM in the normal world,
+which is expected to receive messages from the secure world. The SPMC will in
+this case allocate internal state structures to facilitate RX buffer access
+synchronization (through FFA_RX_ACQUIRE interface), and to permit SPs to send
+messages.
 
 The FFA_RXTX_UNMAP unmaps the RX/TX pair from the translation regime of the
 caller, either it being the Hypervisor or OS kernel, as well as a secure
@@ -969,6 +970,53 @@
 A secondary EC is first resumed either upon invocation of PSCI_CPU_ON from
 the NWd or by invocation of FFA_RUN.
 
+FFA_RX_ACQUIRE/FFA_RX_RELEASE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The RX buffers can be used to pass information to an FF-A endpoint in the
+following scenarios:
+
+ - When it was targetted by a FFA_MSG_SEND2 invokation from another endpoint.
+ - Return the result of calling ``FFA_PARTITION_INFO_GET``.
+ - In a memory share operation, as part of the ``FFA_MEM_RETRIEVE_RESP``,
+   with the memory descriptor of the shared memory.
+
+If a normal world VM is expected to exchange messages with secure world,
+its RX/TX buffer addresses are forwarded to the SPMC via FFA_RXTX_MAP ABI,
+and are from this moment owned by the SPMC.
+The hypervisor must call the FFA_RX_ACQUIRE interface before attempting
+to use the RX buffer, in any of the aforementioned scenarios. A successful
+call to FFA_RX_ACQUIRE transfers ownership of RX buffer to hypervisor, such
+that it can be safely used.
+
+The FFA_RX_RELEASE interface is used after the FF-A endpoint is done with
+processing the data received in its RX buffer. If the RX buffer has been
+acquired by the hypervisor, the FFA_RX_RELEASE call must be forwarded to
+the SPMC to reestablish SPMC's RX ownership.
+
+An attempt from an SP to send a message to a normal world VM whose RX buffer
+was acquired by the hypervisor fails with error code FFA_BUSY, to preserve
+the RX buffer integrity.
+The operation could then be conducted after FFA_RX_RELEASE.
+
+FFA_MSG_SEND2
+~~~~~~~~~~~~~
+
+Hafnium copies a message from the sender TX buffer into receiver's RX buffer.
+For messages from SPs to VMs, operation is only possible if the SPMC owns
+the receiver's RX buffer.
+
+Both receiver and sender need to enable support for indirect messaging,
+in their respective partition manifest. The discovery of support
+of such feature can be done via FFA_PARTITION_INFO_GET.
+
+On a successful message send, Hafnium pends an RX buffer full framework
+notification for the receiver, to inform it about a message in the RX buffer.
+
+The handling of framework notifications is similar to that of
+global notifications. Binding of these is not necessary, as these are
+reserved to be used by the hypervisor or SPMC.
+
 SPMC-SPMD direct requests/responses
 -----------------------------------
 
@@ -1009,6 +1057,40 @@
 For S-EL0 partitions with VHE enabled, a single secure EL2&0 Stage-1 translation
 regime is used for both Hafnium and the partition.
 
+Schedule modes and SP Call chains
+---------------------------------
+
+An SP execution context is said to be in SPMC scheduled mode if CPU cycles are
+allocated to it by SPMC. Correspondingly, an SP execution context is said to be
+in Normal world scheduled mode if CPU cycles are allocated by the normal world.
+
+A call chain represents all SPs in a sequence of invocations of a direct message
+request. When execution on a PE is in the secure state, only a single call chain
+that runs in the Normal World scheduled mode can exist. FF-A v1.1 spec allows
+any number of call chains to run in the SPMC scheduled mode but the Hafnium
+SPMC restricts the number of call chains in SPMC scheduled mode to only one for
+keeping the implementation simple.
+
+Partition runtime models
+------------------------
+
+The runtime model of an endpoint describes the transitions permitted for an
+execution context between various states. These are the four partition runtime
+models supported (refer to `[1]`_ section 7):
+
+  - RTM_FFA_RUN: runtime model presented to an execution context that is
+    allocated CPU cycles through FFA_RUN interface.
+  - RTM_FFA_DIR_REQ: runtime model presented to an execution context that is
+    allocated CPU cycles through FFA_MSG_SEND_DIRECT_REQ interface.
+  - RTM_SEC_INTERRUPT: runtime model presented to an execution context that is
+    allocated CPU cycles by SPMC to handle a secure interrupt.
+  - RTM_SP_INIT: runtime model presented to an execution context that is
+    allocated CPU cycles by SPMC to initialize its state.
+
+If an endpoint execution context attempts to make an invalid transition or a
+valid transition that could lead to a loop in the call chain, SPMC denies the
+transition with the help of above runtime models.
+
 Interrupt management
 --------------------
 
@@ -1020,44 +1102,58 @@
 IDs based on SP manifests. The SPMC acknowledges physical interrupts and injects
 virtual interrupts by setting the use of vIRQ/vFIQ bits before resuming a SP.
 
-Non-secure interrupt handling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Abbreviations:
 
-The following illustrate the scenarios of non secure physical interrupts trapped
-by the SPMC:
+  - NS-Int: A non-secure physical interrupt. It requires a switch to the normal
+    world to be handled if it triggers while execution is in secure world.
+  - Other S-Int: A secure physical interrupt targeted to an SP different from
+    the one that is currently running.
+  - Self S-Int: A secure physical interrupt targeted to the SP that is currently
+    running.
 
-- The SP handles a managed exit operation:
+Non-secure interrupt handling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. image:: ../resources/diagrams/ffa-ns-interrupt-handling-managed-exit.png
+This section documents the actions supported in SPMC in response to a non-secure
+interrupt as per the guidance provided by FF-A v1.1 EAC0 specification.
+An SP specifies one of the following actions in its partition manifest:
 
-- The SP is pre-empted without managed exit:
+  - Non-secure interrupt is signaled.
+  - Non-secure interrupt is signaled after a managed exit.
+  - Non-secure interrupt is queued.
 
-.. image:: ../resources/diagrams/ffa-ns-interrupt-handling-sp-preemption.png
+An SP execution context in a call chain could specify a less permissive action
+than subsequent SP execution contexts in the same call chain. The less
+permissive action takes precedence over the more permissive actions specified
+by the subsequent execution contexts. Please refer to FF-A v1.1 EAC0 section
+8.3.1 for further explanation.
 
 Secure interrupt handling
--------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
 This section documents the support implemented for secure interrupt handling in
-SPMC as per the guidance provided by FF-A v1.1 Beta0 specification.
+SPMC as per the guidance provided by FF-A v1.1 EAC0 specification.
 The following assumptions are made about the system configuration:
 
   - In the current implementation, S-EL1 SPs are expected to use the para
-    virtualized ABIs for interrupt management rather than accessing virtual GIC
-    interface.
+    virtualized ABIs for interrupt management rather than accessing the virtual
+    GIC interface.
   - Unless explicitly stated otherwise, this support is applicable only for
     S-EL1 SPs managed by SPMC.
   - Secure interrupts are configured as G1S or G0 interrupts.
   - All physical interrupts are routed to SPMC when running a secure partition
     execution context.
+  - All endpoints with multiple execution contexts have their contexts pinned
+    to corresponding CPUs. Hence, a secure virtual interrupt cannot be signaled
+    to a target vCPU that is currently running or blocked on a different
+    physical CPU.
 
-A physical secure interrupt could preempt normal world execution. Moreover, when
-the execution is in secure world, it is highly likely that the target of a
-secure interrupt is not the currently running execution context of an SP. It
-could be targeted to another FF-A component. Consequently, secure interrupt
-management depends on the state of the target execution context of the SP that
-is responsible for handling the interrupt. Hence, the spec provides guidance on
-how to signal start and completion of secure interrupt handling as discussed in
-further sections.
+A physical secure interrupt could trigger while CPU is executing in normal world
+or secure world.
+The action of SPMC for a secure interrupt depends on: the state of the target
+execution context of the SP that is responsible for handling the interrupt;
+whether the interrupt triggered while execution was in normal world or secure
+world.
 
 Secure interrupt signaling mechanisms
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1100,47 +1196,46 @@
   - ``FFA_MSG_WAIT`` ABI if it was in WAITING state.
   - ``FFA_RUN`` ABI if its was in BLOCKED state.
 
-In the current implementation, S-EL1 SPs use para-virtualized HVC interface
-implemented by SPMC to perform priority drop and interrupt deactivation (we
-assume EOImode = 0, i.e. priority drop and deactivation are done together).
-
-If normal world execution was preempted by secure interrupt, SPMC uses
-FFA_NORMAL_WORLD_RESUME ABI to indicate completion of secure interrupt handling
-and further return execution to normal world. If the current SP execution
-context was preempted by a secure interrupt to be handled by execution context
-of target SP, SPMC resumes current SP after signal completion by target SP
-execution context.
+This is a remnant of SPMC implementation based on the FF-A v1.0 specification.
+In the current implementation, S-EL1 SPs use the para-virtualized HVC interface
+implemented by SPMC to perform priority drop and interrupt deactivation (SPMC
+configures EOImode = 0, i.e. priority drop and deactivation are done together).
+The SPMC performs checks to deny the state transition upon invocation of
+either FFA_MSG_WAIT or FFA_RUN interface if the SP didn't perform the
+deactivation of the secure virtual interrupt.
 
-An action is broadly a set of steps taken by the SPMC in response to a physical
-interrupt. In order to simplify the design, the current version of secure
-interrupt management support in SPMC (Hafnium) does not fully implement the
-Scheduling models and Partition runtime models. However, the current
-implementation loosely maps to the following actions that are legally allowed
-by the specification. Please refer to the Table 8.4 in the spec for further
-description of actions. The action specified for a type of interrupt when the
-SP is in the message processing running state cannot be less permissive than the
-action specified for the same type of interrupt when the SP is in the interrupt
-handling running state.
+If the current SP execution context was preempted by a secure interrupt to be
+handled by execution context of target SP, SPMC resumes current SP after signal
+completion by target SP execution context.
 
-+--------------------+--------------------+------------+-------------+
-| Runtime Model      | NS-Int             | Self S-Int | Other S-Int |
-+--------------------+--------------------+------------+-------------+
-| Message Processing | Signalable with ME | Signalable | Signalable  |
-+--------------------+--------------------+------------+-------------+
-| Interrupt Handling | Queued             | Queued     | Queued      |
-+--------------------+--------------------+------------+-------------+
+Actions for a secure interrupt triggered while execution is in normal world
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Abbreviations:
++-------------------+----------+-----------------------------------------------+
+| State of target   | Action   | Description                                   |
+| execution context |          |                                               |
++-------------------+----------+-----------------------------------------------+
+| WAITING           | Signaled | This starts a new call chain in SPMC scheduled|
+|                   |          | mode.                                         |
++-------------------+----------+-----------------------------------------------+
+| PREEMPTED         | Queued   | The target execution must have been preempted |
+|                   |          | by a non-secure interrupt. SPMC queues the    |
+|                   |          | secure virtual interrupt now. It is signaled  |
+|                   |          | when the target execution context next enters |
+|                   |          | the RUNNING state.                            |
++-------------------+----------+-----------------------------------------------+
+| BLOCKED, RUNNING  | NA       | The target execution context is blocked or    |
+|                   |          | running on a different CPU. This is not       |
+|                   |          | supported by current SPMC implementation and  |
+|                   |          | execution hits panic.                         |
++-------------------+----------+-----------------------------------------------+
 
-  - NS-Int: A Non-secure physical interrupt. It requires a switch to the Normal
-    world to be handled.
-  - Other S-Int: A secure physical interrupt targeted to an SP different from
-    the one that is currently running.
-  - Self S-Int: A secure physical interrupt targeted to the SP that is currently
-    running.
+If normal world execution was preempted by a secure interrupt, SPMC uses
+FFA_NORMAL_WORLD_RESUME ABI to indicate completion of secure interrupt handling
+and further returns execution to normal world.
 
-The following figure describes interrupt handling flow when secure interrupt
-triggers while in normal world:
+The following figure describes interrupt handling flow when a secure interrupt
+triggers while execution is in normal world:
 
 .. image:: ../resources/diagrams/ffa-secure-interrupt-handling-nwd.png
 
@@ -1151,40 +1246,78 @@
   - 3) SPMD signals secure interrupt to SPMC at S-EL2 using FFA_INTERRUPT ABI.
   - 4) SPMC identifies target vCPU of SP and injects virtual interrupt (pends
        vIRQ).
-  - 5) Since SP1 vCPU is in WAITING state, SPMC signals using FFA_INTERRUPT with
-       interrupt id as argument and resume it using ERET.
-  - 6) Execution traps to vIRQ handler in SP1 provided that interrupt is not
-       masked i.e., PSTATE.I = 0
-  - 7) SP1 services the interrupt and invokes the de-activation HVC call.
-  - 8) SPMC does internal state management and further de-activates the physical
-       interrupt and resumes SP vCPU.
-  - 9) SP performs secure interrupt completion through FFA_MSG_WAIT ABI.
+  - 5) Assuming SP1 vCPU is in WAITING state, SPMC signals virtual interrupt
+       using FFA_INTERRUPT with interrupt id as an argument and resumes the SP1
+       vCPU using ERET in SPMC scheduled mode.
+  - 6) Execution traps to vIRQ handler in SP1 provided that the virtual
+       interrupt is not masked i.e., PSTATE.I = 0
+  - 7) SP1 queries for the pending virtual interrupt id using a paravirtualized
+       HVC call. SPMC clears the pending virtual interrupt state management
+       and returns the pending virtual interrupt id.
+  - 8) SP1 services the virtual interrupt and invokes the paravirtualized
+       de-activation HVC call. SPMC de-activates the physical interrupt,
+       clears the fields tracking the secure interrupt and resumes SP1 vCPU.
+  - 9) SP1 performs secure interrupt completion through FFA_MSG_WAIT ABI.
   - 10) SPMC returns control to EL3 using FFA_NORMAL_WORLD_RESUME.
   - 11) EL3 resumes normal world execution.
 
-The following figure describes interrupt handling flow when secure interrupt
-triggers while in secure world:
+Actions for a secure interrupt triggered while execution is in secure world
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++-------------------+----------+------------------------------------------------+
+| State of target   | Action   | Description                                    |
+| execution context |          |                                                |
++-------------------+----------+------------------------------------------------+
+| WAITING           | Signaled | This starts a new call chain in SPMC scheduled |
+|                   |          | mode.                                          |
++-------------------+----------+------------------------------------------------+
+| PREEMPTED by Self | Signaled | The target execution context reenters the      |
+| S-Int             |          | RUNNING state to handle the secure virtual     |
+|                   |          | interrupt.                                     |
++-------------------+----------+------------------------------------------------+
+| PREEMPTED by      | Queued   | SPMC queues the secure virtual interrupt now.  |
+| NS-Int            |          | It is signaled when the target execution       |
+|                   |          | context next enters the RUNNING state.         |
++-------------------+----------+------------------------------------------------+
+| BLOCKED           | Signaled | Both preempted and target execution contexts   |
+|                   |          | must have been part of the Normal world        |
+|                   |          | scheduled call chain. Refer scenario 1 of      |
+|                   |          | Table 8.4 in the FF-A v1.1 EAC0 spec.          |
++-------------------+----------+------------------------------------------------+
+| RUNNING           | NA       | The target execution context is running on a   |
+|                   |          | different CPU. This scenario is not supported  |
+|                   |          | by current SPMC implementation and execution   |
+|                   |          | hits panic.                                    |
++-------------------+----------+------------------------------------------------+
+
+The following figure describes interrupt handling flow when a secure interrupt
+triggers while execution is in secure world. We assume OS kernel sends a direct
+request message to SP1. Further, SP1 sends a direct request message to SP2. SP1
+enters BLOCKED state and SPMC resumes SP2.
 
 .. image:: ../resources/diagrams/ffa-secure-interrupt-handling-swd.png
 
 A brief description of the events:
 
-  - 1) Secure interrupt triggers while SP2 is running and SP1 is blocked.
-  - 2) Gets trapped to SPMC as IRQ.
+  - 1) Secure interrupt triggers while SP2 is running.
+  - 2) SP2 gets preempted and execution traps to SPMC as IRQ.
   - 3) SPMC finds the target vCPU of secure partition responsible for handling
        this secure interrupt. In this scenario, it is SP1.
   - 4) SPMC pends vIRQ for SP1 and signals through FFA_INTERRUPT interface.
-       SPMC further resumes SP1 through ERET conduit.
-  - 5) Execution traps to vIRQ handler in SP1 provided that interrupt is not
-       masked i.e., PSTATE.I = 0
-  - 6) SP1 services the secure interrupt and invokes the de-activation HVC call.
-  - 7) SPMC does internal state management, de-activates the physical interrupt
-       and resumes SP1 vCPU.
-  - 8) Assuming SP1 is in BLOCKED state, SP1 performs secure interrupt completion
-       through FFA_RUN ABI.
+       SPMC further resumes SP1 through ERET conduit. Note that SP1 remains in
+       Normal world schedule mode.
+  - 6) Execution traps to vIRQ handler in SP1 provided that the virtual
+       interrupt is not masked i.e., PSTATE.I = 0
+  - 7) SP1 queries for the pending virtual interrupt id using a paravirtualized
+       HVC call. SPMC clears the pending virtual interrupt state management
+       and returns the pending virtual interrupt id.
+  - 8) SP1 services the virtual interrupt and invokes the paravirtualized
+       de-activation HVC call. SPMC de-activates the physical interrupt and
+       clears the fields tracking the secure interrupt and resumes SP1 vCPU.
+  - 9) Since SP1 direct request completed with FFA_INTERRUPT, it resumes the
+       direct request to SP2 by invoking FFA_RUN.
   - 9) SPMC resumes the pre-empted vCPU of SP2.
 
-
 Power management
 ----------------
 
@@ -1374,13 +1507,13 @@
 capable of migrating, and the SPMC enforces this requirement. The SPMC allows
 a S-EL0 partition to accept a direct message from secure world and normal world,
 and generate direct responses to them.
+All S-EL0 partitions must use AArch64. AArch32 S-EL0 partitions are not supported.
 
-Memory sharing between and with S-EL0 partitions is supported.
-Indirect messaging, Interrupt handling and Notifications are not supported with
-S-EL0 partitions and is work in progress, planned for future releases.
-All S-EL0 partitions must use AArch64. AArch32 S-EL0 partitions are not
-supported.
+Memory sharing, indirect messaging, and notifications functionality with S-EL0
+partitions is supported.
 
+Interrupt handling is not supported with S-EL0 partitions and is work in
+progress.
 
 References
 ==========
diff --git a/docs/conf.py b/docs/conf.py
index ef77f6b..371632a 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -36,12 +36,13 @@
 #
 # This is also used if you do content translation via gettext catalogs.
 # Usually you set "language" from the command line for these cases.
-language = None
+language = "en"
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
 # This pattern also affects html_static_path and html_extra_path .
-exclude_patterns = []
+# Don't try to build the venv in case it's placed with the sources
+exclude_patterns = [".env", "env", ".venv", "venv"]
 
 # The name of the Pygments (syntax highlighting) style to use.
 pygments_style = 'sphinx'
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 55e265c..9311420 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -317,6 +317,10 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
    it is still open.
 
+-  ``ERRATA_A78_2772019``: This applies errata 2772019 workaround to Cortex-A78
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
+   it is still open.
+
 For Cortex-A78 AE, the following errata build flags are defined :
 
 - ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to
@@ -460,6 +464,10 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0 and r1p1 of the CPU.
    It is still open.
 
+-  ``ERRATA_V1_2743093``: This applies errata 2743093 workaround to Neoverse-V1
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 of the
+   CPU. It is still open.
+
 For Cortex-A710, the following errata build flags are defined :
 
 -  ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -518,6 +526,10 @@
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
 
+-  ``ERRATA_A710_2768515``: This applies errata 2768515 workaround to
+   Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and
+   r2p1 of the CPU and is still open.
+
 For Neoverse N2, the following errata build flags are defined :
 
 -  ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
@@ -562,6 +574,10 @@
    CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
    r0p1.
 
+-  ``ERRATA_N2_2743089``: This applies errata 2743089 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is fixed
+   in r0p3.
+
 For Cortex-X2, the following errata build flags are defined :
 
 -  ``ERRATA_X2_2002765``: This applies errata 2002765 workaround to Cortex-X2
@@ -595,12 +611,20 @@
    Cortex-X2 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
 
+-  ``ERRATA_X2_2768515``: This applies errata 2768515 workaround to
+   Cortex-X2 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0
+   and r2p1 of the CPU and is still open.
+
 For Cortex-X3, the following errata build flags are defined :
 
 - ``ERRATA_X3_2313909``: This applies errata 2313909 workaround to
   Cortex-X3 CPU. This needs to be enabled only for revisions r0p0 and r1p0
   of the CPU, it is fixed in r1p1.
 
+- ``ERRATA_X3_2615812``: This applies errata 2615812 workaround to Cortex-X3
+  CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1 of the
+  CPU, it is still open.
+
 For Cortex-A510, the following errata build flags are defined :
 
 -  ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
diff --git a/docs/design/index.rst b/docs/design/index.rst
index e3b8f74..17ef756 100644
--- a/docs/design/index.rst
+++ b/docs/design/index.rst
@@ -4,7 +4,6 @@
 .. toctree::
    :maxdepth: 1
    :caption: Contents
-   :numbered:
 
    alt-boot-flows
    auth-framework
diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst
index c3f3a2f..caf367b 100644
--- a/docs/design/trusted-board-boot-build.rst
+++ b/docs/design/trusted-board-boot-build.rst
@@ -42,7 +42,7 @@
    are loaded from that path instead of the default OS path. Export this
    variable if necessary.
 
-   In the case of Arm platforms, the location of the ROTPK hash must also be
+   In the case of Arm platforms, the location of the ROTPK must also be
    specified at build time. The following locations are currently supported (see
    ``ARM_ROTPK_LOCATION`` build option):
 
@@ -62,6 +62,9 @@
       ``plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin``. Enforce
       generation of the new hash if ``ROT_KEY`` is specified.
 
+   -  ``ARM_ROTPK_LOCATION=devel_full_dev_rsa_key``: use the key located in
+      ``plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S``.
+
    Example of command line using RSA development keys:
 
    .. code:: shell
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index 765efe6..3e20c07 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -4,7 +4,6 @@
 .. toctree::
    :maxdepth: 1
    :caption: Contents
-   :numbered:
 
    cmake_framework
    context_mgmt_rework
diff --git a/docs/getting_started/build-internals.rst b/docs/getting_started/build-internals.rst
new file mode 100644
index 0000000..a015d71
--- /dev/null
+++ b/docs/getting_started/build-internals.rst
@@ -0,0 +1,14 @@
+Internal Build Options
+======================
+
+|TF-A| internally uses certain options that are not exposed directly through
+:ref:`build-options <build options>` but enabled or disabled indirectly and
+depends on certain options to be enabled or disabled.
+
+.. _build_options_internal:
+
+-  ``CTX_INCLUDE_EL2_REGS``: This boolean option provides context save/restore
+   operations when entering/exiting an EL2 execution context. This is of primary
+   interest when Armv8.4-SecEL2 or RME extension is implemented.
+   Default is 0 (disabled). This option will be set to 1 (enabled) when ``SPD=spmd``
+   and ``SPMD_SPM_AT_SEL2`` is set or when ``ENABLE_RME`` is set to 1 (enabled).
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index eba31da..e54ff41 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -164,12 +164,6 @@
    is on hardware that does not implement AArch32, or at least not at EL1 and
    higher ELs). Default value is 1.
 
--  ``CTX_INCLUDE_EL2_REGS`` : This boolean option provides context save/restore
-   operations when entering/exiting an EL2 execution context. This is of primary
-   interest when Armv8.4-SecEL2 extension is implemented. Default is 0 (disabled).
-   This option must be equal to 1 (enabled) when ``SPD=spmd`` and
-   ``SPMD_SPM_AT_SEL2`` is set.
-
 -  ``CTX_INCLUDE_FPREGS``: Boolean option that, when set to 1, will cause the FP
    registers to be included when saving and restoring the CPU context. Default
    is 0.
@@ -610,22 +604,28 @@
 
 -  ``KEY_ALG``: This build flag enables the user to select the algorithm to be
    used for generating the PKCS keys and subsequent signing of the certificate.
-   It accepts 3 values: ``rsa``, ``rsa_1_5`` and ``ecdsa``. The option
-   ``rsa_1_5`` is the legacy PKCS#1 RSA 1.5 algorithm which is not TBBR
-   compliant and is retained only for compatibility. The default value of this
-   flag is ``rsa`` which is the TBBR compliant PKCS#1 RSA 2.1 scheme.
+   It accepts 5 values: ``rsa``, ``rsa_1_5``, ``ecdsa``, ``ecdsa-brainpool-regular``
+   and ``ecdsa-brainpool-twisted``. The option ``rsa_1_5`` is the legacy PKCS#1
+   RSA 1.5 algorithm which is not TBBR compliant and is retained only for
+   compatibility. The default value of this flag is ``rsa`` which is the TBBR
+   compliant PKCS#1 RSA 2.1 scheme.
 
 -  ``KEY_SIZE``: This build flag enables the user to select the key size for
    the algorithm specified by ``KEY_ALG``. The valid values for ``KEY_SIZE``
    depend on the chosen algorithm and the cryptographic module.
 
+   +---------------------------+------------------------------------+
+   |         KEY_ALG           |        Possible key sizes          |
+   +===========================+====================================+
+   |           rsa             | 1024 , 2048 (default), 3072, 4096* |
+   +---------------------------+------------------------------------+
+   |          ecdsa            |            unavailable             |
+   +---------------------------+------------------------------------+
+   |  ecdsa-brainpool-regular  |            unavailable             |
+   +---------------------------+------------------------------------+
+   |  ecdsa-brainpool-twisted  |            unavailable             |
+   +---------------------------+------------------------------------+
+
-   +-----------+------------------------------------+
-   |  KEY_ALG  |        Possible key sizes          |
-   +===========+====================================+
-   |    rsa    | 1024 , 2048 (default), 3072, 4096* |
-   +-----------+------------------------------------+
-   |   ecdsa   |            unavailable             |
-   +-----------+------------------------------------+
 
    * Only 2048 bits size is available with CryptoCell 712 SBROM release 1.
      Only 3072 bits size is available with CryptoCell 712 SBROM release 2.
@@ -818,6 +818,11 @@
    disabled). This configuration supports pre-Armv8.4 platforms (aka not
    implementing the ``FEAT_SEL2`` extension). This is an experimental feature.
 
+-  ``SPMC_OPTEE`` : This boolean option is used jointly with the SPM
+   Dispatcher option (``SPD=spmd``) and with ``SPMD_SPM_AT_SEL2=0`` to
+   indicate that the SPMC at S-EL1 is OP-TEE and an OP-TEE specific loading
+   mechanism should be used.
+
 -  ``SPMD_SPM_AT_SEL2`` : This boolean option is used jointly with the SPM
    Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC
    component runs at the S-EL2 exception level provided by the ``FEAT_SEL2``
@@ -1032,6 +1037,12 @@
   functionalities). When enabled (``1``), a mocked version of the APIs are used.
   The default value is 0.
 
+- ``CONDITIONAL_CMO``: Boolean option to enable call to platform-defined routine
+  ``plat_can_cmo`` which will return zero if cache management operations should
+  be skipped and non-zero otherwise. By default, this option is disabled which
+  means platform hook won't be checked and CMOs will always be performed when
+  related functions are called.
+
 GICv3 driver options
 --------------------
 
diff --git a/docs/getting_started/docs-build.rst b/docs/getting_started/docs-build.rst
index 87c677f..4a48059 100644
--- a/docs/getting_started/docs-build.rst
+++ b/docs/getting_started/docs-build.rst
@@ -17,22 +17,28 @@
 Prerequisites
 -------------
 
-For building a local copy of the |TF-A| documentation you will need, at minimum:
+For building a local copy of the |TF-A| documentation you will need:
 
 - Python 3 (3.5 or later)
 - PlantUML (1.2017.15 or later)
+- Python modules specified in ``docs/requirements.txt``
 
-Optionally, the `Dia`_ application can be installed if you need to edit
-existing ``.dia`` diagram files, or create new ones.
+   You can install these with ``pip3`` (the Python Package Installer) by
+   passing it the requirements file above (with ``-r``). An optional ``--user``
+   argument will install them locally, but you have to add their location to
+   $PATH (pip will emit a warning). Alternatively, they can be installed
+   globally (but will probably require root privileges).
 
-You must also install the Python modules that are specified in the
-``requirements.txt`` file in the root of the ``docs`` directory. These modules
-can be installed using ``pip3`` (the Python Package Installer). Passing this
-requirements file as an argument to ``pip3`` automatically installs the specific
-module versions required by |TF-A|.
+   .. note::
+      Although not necessary, it is recommended you use a virtual environment.
+      More advanced usage instructions for *pip* are beyond the scope of this
+      document but you can refer to the `pip homepage`_ for detailed guides.
 
-An example set of installation commands for Ubuntu 18.04 LTS follows, assuming
-that the working directory is ``docs``:
+- Optionally, the `Dia`_ application can be installed if you need to edit
+  existing ``.dia`` diagram files, or create new ones.
+
+An example set of installation commands for Ubuntu follows, assuming that the
+working directory is ``docs``:
 
 .. code:: shell
 
@@ -44,15 +50,6 @@
    the list to ensure that there will be no conflicts with other modules already
    installed in your environment.
 
-Passing the optional ``--user`` argument to ``pip3`` will install the Python
-packages only for the current user. Omitting this argument will attempt to
-install the packages globally and this will likely require the command to be run
-as root or using ``sudo``.
-
-.. note::
-   More advanced usage instructions for *pip* are beyond the scope of this
-   document but you can refer to the `pip homepage`_ for detailed guides.
-
 Building rendered documentation
 -------------------------------
 
diff --git a/docs/getting_started/image-terminology.rst b/docs/getting_started/image-terminology.rst
index a90ec0b..66f47e8 100644
--- a/docs/getting_started/image-terminology.rst
+++ b/docs/getting_started/image-terminology.rst
@@ -4,8 +4,8 @@
 This page contains the current name, abbreviated name and purpose of the various
 images referred to in the Trusted Firmware project.
 
-General Notes
--------------
+Common Image Features
+---------------------
 
 - Some of the names and abbreviated names have changed to accommodate new
   requirements. The changed names are as backward compatible as possible to
@@ -40,6 +40,15 @@
 Trusted Firmware Images
 -----------------------
 
+Firmware Image Package: ``FIP``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is a packaging format used by TF-A to package firmware images in a single
+binary. The number and type of images that should be packed in a FIP is
+platform-specific and may include TF-A images and other firmware images
+required by the platform. For example, most platforms require a BL33 image
+which corresponds to the normal world bootloader (e.g. UEFI or U-Boot).
+
 AP Boot ROM: ``AP_BL1``
 ~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst
index 817beaf..5ebabea 100644
--- a/docs/getting_started/index.rst
+++ b/docs/getting_started/index.rst
@@ -4,13 +4,13 @@
 .. toctree::
    :maxdepth: 1
    :caption: Contents
-   :numbered:
 
    prerequisites
    docs-build
-   tools-build
    initial-build
+   tools-build
    build-options
+   build-internals
    image-terminology
    porting-guide
    psci-lib-integration-guide
diff --git a/docs/getting_started/initial-build.rst b/docs/getting_started/initial-build.rst
index 62f1941..4f41be4 100644
--- a/docs/getting_started/initial-build.rst
+++ b/docs/getting_started/initial-build.rst
@@ -2,7 +2,7 @@
 ===========================
 
 -  Before building TF-A, the environment variable ``CROSS_COMPILE`` must point
-   to the Linaro cross compiler.
+   to your cross compiler.
 
    For AArch64:
 
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index d216d81..aa57e1d 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -809,6 +809,34 @@
 either could not be updated or the authentication image descriptor indicates
 that it is not allowed to be updated.
 
+Function: plat_convert_pk()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void *, unsigned int, void **, unsigned int *
+    Return   : int
+
+This function is optional when Trusted Board Boot is enabled, and only
+used if the platform saves a hash of the ROTPK.
+First argument is the Distinguished Encoding Rules (DER) ROTPK.
+Second argument is its size.
+Third argument is used to return a pointer to a buffer, which hash should
+be the one saved in OTP.
+Fourth argument is a pointer to return its size.
+
+Most platforms save the hash of the ROTPK, but some may save slightly different
+information - e.g the hash of the ROTPK plus some related information.
+Defining this function allows to transform the ROTPK used to verify
+the signature to the buffer (a platform specific public key) which
+hash is saved in OTP.
+
+The default implementation copies the input key and length to the output without
+modification.
+
+The function returns 0 on success. Any other value means the expected
+public key buffer cannot be extracted.
+
 Dynamic Root of Trust for Measurement support (in BL31)
 -------------------------------------------------------
 
@@ -1461,6 +1489,22 @@
 
 When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
 
+Function : plat_can_cmo()
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint64_t
+
+When CONDITIONAL_CMO flag is enabled:
+
+- This function indicates whether cache management operations should be
+  performed. It returns 0 if CMOs should be skipped and non-zero
+  otherwise.
+- The function must not clobber x1, x2 and x3. It's also not safe to rely on
+  stack. Otherwise obey AAPCS.
+
 Modifications specific to a Boot Loader stage
 ---------------------------------------------
 
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 9496576..3723294 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -14,7 +14,7 @@
 |TF-A| can be built using either a Linux or a Windows machine as the build host.
 
 A relatively recent Linux distribution is recommended for building |TF-A|. We
-have performed tests using Ubuntu 16.04 LTS (64-bit) but other distributions
+have performed tests using Ubuntu 20.04 LTS (64-bit) but other distributions
 should also work fine as a base, provided that the necessary tools and libraries
 can be installed.
 
@@ -27,6 +27,10 @@
 target the Armv7-A or Armv8-A architectures:
 
 - GCC >= 11.3.Rel1 (from the `Arm Developer website`_)
+
+   You will need the targets ``arm-none-eabi`` and ``aarch64-none-elf`` for
+   AArch32 and AArch64 builds respectively.
+
 - Clang >= 14.0.0
 - Arm Compiler >= 6.18
 
@@ -54,15 +58,15 @@
 The following libraries must be available to build one or more components or
 supporting tools:
 
-- OpenSSL >= 3.0
+- OpenSSL >= 1.1.1 (v3.0.0 to v3.0.6 highly discouraged due to security issues)
 
-   Required to build the cert_create tool.
+   Required to build the cert_create, encrypt_fw, and fiptool tools.
 
    .. note::
 
-    OpenSSL 3.0 has to be built from source code, as it's not available in
-    the default package repositories in recent Ubuntu versions. Please refer
-    to the OpenSSL project documentation for more information.
+    If using OpenSSL 3, older Linux versions may require it to be built from
+    source code, as it may not be available in the default package repositories.
+    Please refer to the OpenSSL project documentation for more information.
 
 The following libraries are required for Trusted Board Boot and Measured Boot
 support:
diff --git a/docs/getting_started/tools-build.rst b/docs/getting_started/tools-build.rst
index daf7e06..166b527 100644
--- a/docs/getting_started/tools-build.rst
+++ b/docs/getting_started/tools-build.rst
@@ -14,12 +14,11 @@
 Building and using the FIP tool
 -------------------------------
 
-Firmware Image Package (FIP) is a packaging format used by TF-A to package
-firmware images in a single binary. The number and type of images that should
-be packed in a FIP is platform specific and may include TF-A images and other
-firmware images required by the platform. For example, most platforms require
-a BL33 image which corresponds to the normal world bootloader (e.g. UEFI or
-U-Boot).
+The following snippets build a :ref:`FIP<Image Terminology>` for the FVP
+platform. While it is not an intrinsic part of the FIP format, a BL33 image is
+required for these examples. For the purposes of experimentation, `Trusted
+Firmware-A Tests`_ (`tftf.bin``) may be used. Refer to to the `TFTF
+documentation`_ for instructions on building a TFTF binary.
 
 The TF-A build system provides the make target ``fip`` to create a FIP file
 for the specified platform using the FIP creation tool included in the TF-A
@@ -175,3 +174,6 @@
 --------------
 
 *Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+
+.. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/
+.. _TFTF documentation: https://trustedfirmware-a-tests.readthedocs.io/en/latest/
diff --git a/docs/index.rst b/docs/index.rst
index edc2535..3860199 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -3,7 +3,7 @@
 
 .. toctree::
    :maxdepth: 1
-   :hidden:
+   :numbered:
 
    Home<self>
    about/index
diff --git a/docs/perf/index.rst b/docs/perf/index.rst
index 1482b80..bccad00 100644
--- a/docs/perf/index.rst
+++ b/docs/perf/index.rst
@@ -4,7 +4,6 @@
 .. toctree::
    :maxdepth: 1
    :caption: Contents
-   :numbered:
 
    psci-performance-juno
    tsp
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index 407c04b..68eb3ec 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -49,7 +49,7 @@
    field of power-state parameter.
 
 -  ``ARM_ROTPK_LOCATION``: used when ``TRUSTED_BOARD_BOOT=1``. It specifies the
-   location of the ROTPK hash returned by the function ``plat_get_rotpk_info()``
+   location of the ROTPK returned by the function ``plat_get_rotpk_info()``
    for Arm platforms. Depending on the selected option, the proper private key
    must be specified using the ``ROT_KEY`` option when building the Trusted
    Firmware. This private key will be used by the certificate generation tool
@@ -68,12 +68,16 @@
       ``arm_rotpk_ecdsa.der``, located in ``plat/arm/board/common/rotpk``. To
       use this option, ``arm_rotprivk_ecdsa.pem`` must be specified as
       ``ROT_KEY`` when creating the certificates.
+   -  ``devel_full_dev_rsa_key`` : returns a development public key embedded in
+      the BL1 and BL2 binaries. This key has been obtained from the RSA public
+      key ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``.
 
--  ``ARM_ROTPK_HASH``: used when ``ARM_ROTPK_LOCATION=devel_*``. Specifies the
-   location of the ROTPK hash. Not expected to be a build option. This defaults to
-   ``plat/arm/board/common/rotpk/*_sha256.bin`` depending on the specified algorithm.
-   Providing ``ROT_KEY`` enforces generation of the hash from the ``ROT_KEY`` and
-   overwrites the default hash file.
+-  ``ARM_ROTPK_HASH``: used when ``ARM_ROTPK_LOCATION=devel_*``, excluding
+   ``devel_full_dev_rsa_key``. Specifies the location of the ROTPK hash. Not
+   expected to be a build option. This defaults to
+   ``plat/arm/board/common/rotpk/*_sha256.bin`` depending on the specified
+   algorithm. Providing ``ROT_KEY`` enforces generation of the hash from the
+   ``ROT_KEY`` and overwrites the default hash file.
 
 -  ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options:
 
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index f1b97f8..a4e2067 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -4,7 +4,6 @@
 .. toctree::
    :maxdepth: 1
    :caption: Contents
-   :numbered:
    :hidden:
 
    allwinner
@@ -75,6 +74,8 @@
 +----------------+----------------+--------------------+--------------------+
 |    rdn1edge    |      Arm       |        2.8         |       3.0          |
 +----------------+----------------+--------------------+--------------------+
+|    tc0         |      Arm       |        2.8         |       3.0          |
++----------------+----------------+--------------------+--------------------+
 
 --------------
 
diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst
index ff7b573..8cb3fdf 100644
--- a/docs/plat/marvell/armada/build.rst
+++ b/docs/plat/marvell/armada/build.rst
@@ -26,7 +26,7 @@
 
        *u-boot.bin* should be used and not *u-boot-spl.bin*
 
-Set MSS/SCP image path (mandatory only for A7K/8K/CN913x when MSS_SUPPORT=1)
+Set MSS/SCP image path (mandatory only for A7K/A8K/CN913x when MSS_SUPPORT=1)
 
     .. code:: shell
 
@@ -109,7 +109,7 @@
 - MV_DDR_PATH
 
         This parameter is required for ``mrvl_flash`` and ``mrvl_uart`` targets.
-        For A7K/8K/CN913x it is used for BLE build and for Armada37x0 it used
+        For A7K/A8K/CN913x it is used for BLE build and for Armada37x0 it used
         for ddr_tool build.
 
         Specify path to the full checkout of Marvell mv-ddr-marvell git
@@ -131,7 +131,7 @@
         values with CP_NUM are in a range of 1 to 3.
 
 
-A7K/8K/CN913x specific build options:
+A7K/A8K/CN913x specific build options:
 
 - BLE_PATH
 
@@ -387,7 +387,7 @@
 - PLAT_RECOVERY_IMAGE_ENABLE
     When set this option to enable secondary recovery function when build atf.
     In order to build UART recovery image this operation should be disabled for
-    A7K/8K/CN913x because of hardware limitation (boot from secondary image
+    A7K/A8K/CN913x because of hardware limitation (boot from secondary image
     can interrupt UART recovery process). This MACRO definition is set in
     ``plat/marvell/armada/a8k/common/include/platform_def.h`` file.
 
diff --git a/docs/plat/marvell/armada/uart-booting.rst b/docs/plat/marvell/armada/uart-booting.rst
index 06601d1..04ce464 100644
--- a/docs/plat/marvell/armada/uart-booting.rst
+++ b/docs/plat/marvell/armada/uart-booting.rst
@@ -79,10 +79,10 @@
 bootrom during transferring of image files. This mini terminal can be quit by CTRL-\\ + C keypress.
 
 
-A7K/8K/CN913x UART image downloading
-------------------------------------
+A7K/A8K/CN913x UART image downloading
+-------------------------------------
 
-A7K/8K/CN913x uses same image ``flash-image.bin`` for both flashing and booting over UART.
+A7K/A8K/CN913x uses same image ``flash-image.bin`` for both flashing and booting over UART.
 For downloading image over UART it is possible to use mvebu64boot tool.
 
 Compilation:
diff --git a/docs/plat/qemu.rst b/docs/plat/qemu.rst
index 66b8247..6986326 100644
--- a/docs/plat/qemu.rst
+++ b/docs/plat/qemu.rst
@@ -136,3 +136,37 @@
         -append 'console=ttyAMA0,38400 keep_bootcon'  \
         -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios flash.bin   \
         -d unimp
+
+Running QEMU in OpenCI
+-----------------------
+
+Linaro's continuous integration platform OpenCI supports running emulated tests
+on QEMU. The tests are kicked off on Jenkins and deployed through the Linaro
+Automation and Validation Architecture `LAVA`_.
+
+There are a set of Linux boot tests provided in OpenCI. They rely on prebuilt
+`binaries`_ for UEFI, the kernel, root file system, as well as, any other TF-A
+dependencies, and are run as part of the OpenCI TF-A `daily job`_. To run them
+manually, a `builder`_ job may be triggered with the test configuration
+``qemu-boot-tests``.
+
+
+You may see the following warning repeated several times in the boot logs:
+
+.. code:: shell
+
+    pflash_write: Write to buffer emulation is flawed
+
+Please ignore this as it is an unresolved `issue in QEMU`_, it is an internal
+QEMU warning that logs flawed use of "write to buffer".
+
+.. note::
+    For more information on how to trigger jobs in OpenCI, please refer to
+    Linaro's CI documentation, which explains how to trigger a `manual job`_.
+
+.. _binaries: https://downloads.trustedfirmware.org/tf-a/linux_boot/
+.. _daily job: https://ci.trustedfirmware.org/view/TF-A/job/tf-a-main/
+.. _builder: https://ci.trustedfirmware.org/view/TF-A/job/tf-a-builder/
+.. _LAVA: https://tf.validation.linaro.org/
+.. _manual job: https://tf-ci-users-guide.readthedocs.io/en/latest/#manual-job-trigger
+.. _issue in QEMU: https://git.qemu.org/?p=qemu.git;a=blob;f=hw/block/pflash_cfi01.c;h=0cbc2fb4cbf62c9a033b8dd89012374ff74ed610;hb=refs/heads/master#l500
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index fff86a8..23ea25a 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -63,15 +63,6 @@
 inside the FIP binary: BL32 (SP_min or OP-TEE), U-Boot and their respective
 device tree blobs.
 
-STM32IMAGE bootchain
-~~~~~~~~~~~~~~~~~~~~
-Although still supported, this way of booting is not recommended.
-Pease use FIP instead.
-At compilation step, BL2, BL32 and DTB file are linked together in a single
-binary. The stm32image tool is also generated and the header is added to TF-A
-binary. This binary file with header is named tf-a-stm32mp157c-ev1.stm32.
-It can then be copied in the first partition of the boot device.
-
 
 Memory mapping
 ~~~~~~~~~~~~~~
@@ -235,44 +226,40 @@
         BL32_EXTRA2=<optee_directory>/tee-pageable_v2.bin
         fip
 
-
-STM32IMAGE bootchain
-~~~~~~~~~~~~~~~~~~~~
-You need to add the following flag to the make command:
-``STM32MP_USE_STM32IMAGE=1``
-
-To build with SP_min and support for SD-card boot:
-
-.. code:: bash
-
-    make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
-        AARCH32_SP=sp_min STM32MP_SDMMC=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb \
-        STM32MP_USE_STM32IMAGE=1
-
-    cd <u-boot_directory>
-    make stm32mp15_trusted_defconfig
-    make DEVICE_TREE=stm32mp157c-ev1 all
-
-To build TF-A with OP-TEE support for SD-card boot:
-
-.. code:: bash
-
-    make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
-        AARCH32_SP=optee STM32MP_SDMMC=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb \
-        STM32MP_USE_STM32IMAGE=1
-
-    cd <optee_directory>
-    make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 \
-        CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts
+Trusted Boot Board
+__________________
 
-    cd <u-boot_directory>
-    make stm32mp15_trusted_defconfig
-    make DEVICE_TREE=stm32mp157c-ev1 all
+.. code:: shell
 
+    tools/cert_create/cert_create -n --rot-key "build/stm32mp1/debug/rot_key.pem" \
+        --tfw-nvctr 0 \
+        --ntfw-nvctr 0 \
+        --key-alg ecdsa --hash-alg sha256 \
+        --trusted-key-cert build/stm32mp1/cert_images/trusted-key-cert.key-crt \
+        --tos-fw <optee_directory>/tee-header_v2.bin \
+        --tos-fw-extra1 <optee_directory>/tee-pager_v2.bin \
+        --tos-fw-extra2 <optee_directory>/tee-pageable_v2.bin \
+        --tos-fw-cert build/stm32mp1/cert_images/tee-header_v2.bin.crt \
+        --tos-fw-key-cert build/stm32mp1/cert_images/tee-header_v2.bin.key-crt \
+        --nt-fw <u-boot_directory>/u-boot-nodtb.bin \
+        --nt-fw-cert build/stm32mp1/cert_images/u-boot.bin.crt \
+        --nt-fw-key-cert build/stm32mp1/cert_images/u-boot.bin.key-crt \
+        --hw-config <u-boot_directory>/u-boot.dtb \
+        --fw-config build/stm32mp1/debug/fdts/fw-config.dtb \
+        --stm32mp-cfg-cert build/stm32mp1/cert_images/stm32mp_cfg_cert.crt
 
-The following build options are supported:
+    tools/fiptool/fiptool create --tos-fw <optee_directory>/tee-header_v2.bin \
+        --tos-fw-extra1 <optee_directory>/tee-pager_v2.bin \
+        --tos-fw-extra2 <optee_directory>/tee-pageable_v2.bin \
+        --nt-fw <u-boot_directory>/u-boot-nodtb.bin \
+        --hw-config <u-boot_directory>/u-boot.dtb \
+        --fw-config build/stm32mp1/debug/fdts/fw-config.dtb \
+        --tos-fw-cert build/stm32mp1/cert_images/tee-header_v2.bin.crt \
+        --tos-fw-key-cert build/stm32mp1/cert_images/tee-header_v2.bin.key-crt \
+        --nt-fw-cert build/stm32mp1/cert_images/u-boot.bin.crt \
+        --nt-fw-key-cert build/stm32mp1/cert_images/u-boot.bin.key-crt \
+        --stm32mp-cfg-cert build/stm32mp1/cert_images/stm32mp_cfg_cert.crt stm32mp1.fip
 
-- ``ENABLE_STACK_PROTECTOR``: To enable the stack protection.
 
 
 Populate SD-card
@@ -288,22 +275,6 @@
 
 Usually, two copies of fsbl are used (fsbl1 and fsbl2) instead of one partition fsbl.
 
-STM32IMAGE bootchain
-~~~~~~~~~~~~~~~~~~~~
-The SD-card has to be formatted with GPT.
-It should contain at least those partitions:
-
-- fsbl: to copy the tf-a-stm32mp157c-ev1.stm32 binary
-- ssbl: to copy the u-boot.stm32 binary
-
-Usually, two copies of fsbl are used (fsbl1 and fsbl2) instead of one partition fsbl.
-
-OP-TEE artifacts go into separate partitions as follows:
-
-- teeh: tee-header_v2.stm32
-- teed: tee-pageable_v2.stm32
-- teex: tee-pager_v2.stm32
-
 
 .. _STM32MP1 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp1-series.html
 .. _STM32MP1 part number codification: https://wiki.st.com/stm32mpu/wiki/STM32MP15_microprocessor#Part_number_codification
diff --git a/docs/process/index.rst b/docs/process/index.rst
index 422ab28..7914a4e 100644
--- a/docs/process/index.rst
+++ b/docs/process/index.rst
@@ -4,7 +4,6 @@
 .. toctree::
    :maxdepth: 1
    :caption: Contents
-   :numbered:
 
    security
    platform-ports-policy
diff --git a/docs/resources/diagrams/plantuml/tfa_rss_dfd.puml b/docs/resources/diagrams/plantuml/tfa_rss_dfd.puml
new file mode 100644
index 0000000..23f5b17
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/tfa_rss_dfd.puml
@@ -0,0 +1,77 @@
+/'
+ ' Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ '
+ ' SPDX-License-Identifier: BSD-3-Clause
+ '/
+
+/'
+TF-A Data Flow Diagram including RSS
+'/
+
+@startuml
+digraph tfa_dfd {
+
+    # Arrange nodes from left to right
+    rankdir="LR"
+
+    # Allow arrows to end on cluster boundaries
+    compound=true
+
+    # Default settings for edges and nodes
+    edge [minlen=2 color="#8c1b07"]
+    node [fillcolor="#ffb866" style=filled shape=box fixedsize=true width=1.6 height=0.7]
+
+    # Nodes outside of the trust boundary
+    nsec [label="Non-secure\nClients"]
+    sec [label="Secure\nClients"]
+    dbg [label="Debug & Trace"]
+    logs [label="Logs\n(UART)"]
+    nvm [label="Non-volatile\nMemory"]
+
+
+    # Trust boundary cluster
+    subgraph cluster_trusted{
+        graph [style=dashed color="#f22430"]
+
+        # HW IPs cluster
+        subgraph cluster_ip{
+            label ="Hardware IPs";
+            graph [style=filled color="#000000" fillcolor="#ffd29e"]
+
+            rank="same"
+            gic [label="GIC" width=1.2 height=0.5]
+            tzc [label="TZ\nController" width=1.2 height=0.5]
+            etc [label="..." shape=none style=none height=0.5]
+        }
+
+        # TF-A cluster
+        subgraph cluster_tfa{
+            label ="TF-A";
+            graph [style=filled color="#000000" fillcolor="#faf9cd"]
+
+            bl1 [label="Boot ROM\n(BL1)" fillcolor="#ddffb3"];
+            bl2 [label="Trusted Boot\nFirmware\n(BL2)" fillcolor="#ddffb3" height=1]
+            bl31 [label="TF-A Runtime\n(BL31)" fillcolor="#ddffb3"]
+        }
+
+        # RSS cluster
+        subgraph cluster_rss{
+            label ="RSS";
+            graph [style=filled color="#000000" fillcolor="#faf9cd"]
+
+            rss [label="Runtime Security\n\ Subsystem\n\ (RSS)" fillcolor="#ddffb3"]
+        }
+    }
+
+    # Interactions between nodes
+    nvm -> bl31 [lhead=cluster_tfa label="DF1"]
+    logs -> bl31 [dir="back" lhead=cluster_tfa label="DF2"]
+    dbg -> bl2 [dir="both" lhead=cluster_tfa label="DF3"]
+    sec -> bl2 [dir="both" lhead=cluster_tfa label="DF4"]
+    nsec -> bl1 [dir="both" lhead=cluster_tfa, label="DF5"]
+    bl2 ->  tzc [dir="both" ltail=cluster_tfa lhead=cluster_ip label="DF6" minlen=1]
+    bl31 -> rss [dir="both" ltail=cluster_tfa lhead=cluster_rss label="DF7" minlen=1]
+
+}
+
+@enduml
diff --git a/docs/security_advisories/index.rst b/docs/security_advisories/index.rst
index 887b06a..b80ba34 100644
--- a/docs/security_advisories/index.rst
+++ b/docs/security_advisories/index.rst
@@ -4,7 +4,6 @@
 .. toctree::
    :maxdepth: 1
    :caption: Contents
-   :numbered:
 
    security-advisory-tfv-1.rst
    security-advisory-tfv-2.rst
diff --git a/docs/threat_model/index.rst b/docs/threat_model/index.rst
index 9d84f5b..9fd55a9 100644
--- a/docs/threat_model/index.rst
+++ b/docs/threat_model/index.rst
@@ -11,13 +11,13 @@
 .. toctree::
    :maxdepth: 1
    :caption: Contents
-   :numbered:
 
    threat_model
    threat_model_spm
    threat_model_el3_spm
    threat_model_fvp_r
+   threat_model_rss_interface
 
 --------------
 
-*Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 38e5c87..99bbb3a 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -170,7 +170,7 @@
 
 For each threat identified, a risk rating that ranges
 from *informational* to *critical* is given based on the likelihood of the
-threat occuring if a mitigation is not in place, and the impact of the
+threat occurring if a mitigation is not in place, and the impact of the
 threat (i.e. how severe the consequences could be). Table 4 explains each
 rating in terms of score, impact and likelihood.
 
@@ -778,8 +778,9 @@
 +========================+====================================================+
 | Threat                 | | **Misconfiguration of the Memory Management Unit |
 |                        |   (MMU) may allow a normal world software to       |
-|                        |   access sensitive data or execute arbitrary       |
-|                        |   code**                                           |
+|                        |   access sensitive data, execute arbitrary         |
+|                        |   code or access otherwise restricted HW           |
+|                        |   interface**                                      |
 |                        |                                                    |
 |                        | | A misconfiguration of the MMU could              |
 |                        |   lead to an open door for software running in the |
@@ -853,6 +854,8 @@
 +------------------------+-----------------------------------------------------+
 | Threat Type            | Information Disclosure                              |
 +------------------------+-------------------+----------------+----------------+
+| Application            | Server            | IoT            | Mobile         |
++------------------------+-------------------+----------------+----------------+
 | Impact                 | Medium (3)        | Medium (3)     | Medium (3)     |
 +------------------------+-------------------+----------------+----------------+
 | Likelihood             | Low (2)           | Low (2)        | Low (2)        |
@@ -880,6 +883,41 @@
 |                        |   mitigated.                                        |
 +------------------------+-----------------------------------------------------+
 
++------------------------+-----------------------------------------------------+
+| ID                     | 13                                                  |
++========================+=====================================================+
+| Threat                 | | **Leaving sensitive information in the memory,    |
+|                        |   can allow an attacker to retrieve them.**         |
+|                        |                                                     |
+|                        | | Accidentally leaving not-needed sensitive data in |
+|                        |   internal buffers can leak them if an attacker     |
+|                        |   gains access to memory due to a vulnerability.    |
++------------------------+-----------------------------------------------------+
+| Diagram Elements       | DF4, DF5                                            |
++------------------------+-----------------------------------------------------+
+| Affected TF-A          | BL1, BL2, BL31                                      |
+| Components             |                                                     |
++------------------------+-----------------------------------------------------+
+| Assets                 | Sensitive Data                                      |
++------------------------+-----------------------------------------------------+
+| Threat Agent           | NSCode, SecCode                                     |
++------------------------+-----------------------------------------------------+
+| Threat Type            | Information Disclosure                              |
++------------------------+-------------------+----------------+----------------+
+| Application            | Server            | IoT            | Mobile         |
++------------------------+-------------------+----------------+----------------+
+| Impact                 |  Critical (5)     | Critical (5)   | Critical (5)   |
++------------------------+-------------------+----------------+----------------+
+| Likelihood             |  Medium (3)       | Medium (3)     | Medium (3)     |
++------------------------+-------------------+----------------+----------------+
+| Total Risk Rating      |  High (15)        | High (15)      | High (15)      |
++------------------------+-------------------+----------------+----------------+
+| Mitigations            |   Clear the sensitive data from internal buffers as |
+|                        |   soon as they are not needed anymore.              |
++------------------------+-----------------------------------------------------+
+| Mitigations            | | Yes / Platform specific                           |
++------------------------+-----------------------------------------------------+
+
 --------------
 
 *Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
diff --git a/docs/threat_model/threat_model_rss_interface.rst b/docs/threat_model/threat_model_rss_interface.rst
new file mode 100644
index 0000000..4bceb63
--- /dev/null
+++ b/docs/threat_model/threat_model_rss_interface.rst
@@ -0,0 +1,59 @@
+Threat Model for RSS - AP interface
+***********************************
+
+************
+Introduction
+************
+This document is an extension for the general TF-A threat-model. It considers
+those platforms where a Runtime Security Subsystem (RSS) is included in the SoC
+next to the Application Processor (AP).
+
+********************
+Target of Evaluation
+********************
+The scope of this threat model only includes the interface between the RSS and
+AP. Otherwise, the TF-A :ref:`Generic Threat Model` document is applicable for
+the AP core. The threat model for the RSS firmware will be provided by the RSS
+firmware project in the future.
+
+
+Data Flow Diagram
+=================
+This diagram is different only from the general TF-A data flow diagram in that
+it includes the RSS and highlights the interface between the AP and the RSS
+cores. The interface description only focuses on the AP-RSS interface the rest
+is the same as in the general TF-A threat-model document.
+
+.. uml:: ../resources/diagrams/plantuml/tfa_rss_dfd.puml
+  :caption: Figure 1: TF-A Data Flow Diagram including RSS
+
+.. table:: Table 1: TF-A - RSS data flow diagram
+
+  +-----------------+--------------------------------------------------------+
+  | Diagram Element | Description                                            |
+  +=================+========================================================+
+  |       DF7       | | Boot images interact with RSS over a communication   |
+  |                 |   channel to record boot measurements and get image    |
+  |                 |   verification keys. At runtime, BL31 obtains the      |
+  |                 |   realm world attestation signing key from RSS.        |
+  +-----------------+--------------------------------------------------------+
+
+Threat Assessment
+=================
+For this section, please reference the Threat Assessment under the general TF-A
+threat-model document, :ref:`Generic Threat Model`. All the threats listed there
+are applicable for the AP core, here only the differences are highlighted.
+
+    - ID 11: The access to the communication interface between AP and RSS is
+      allowed only for firmware running at EL3. Accidentally exposing this
+      interface to NSCode can allow malicious code to interact with RSS and
+      gain access to sensitive data.
+    - ID 13: Relevant in the context of the realm attestation key, which can be
+      retrieved by BL31 through DF7. The RSS communication protocol layer
+      mitigates against this by clearing its internal buffer when reply is
+      received. The caller of the API must do the same if data is not needed
+      anymore.
+
+--------------
+
+*Copyright (c) 2022, Arm Limited. All rights reserved.*
\ No newline at end of file
diff --git a/docs/threat_model/threat_model_spm.rst b/docs/threat_model/threat_model_spm.rst
index a7bc2a9..98dbf76 100644
--- a/docs/threat_model/threat_model_spm.rst
+++ b/docs/threat_model/threat_model_spm.rst
@@ -258,7 +258,7 @@
 |                        | invocations.                                       |
 |                        | This can also be an endpoint emitting              |
 |                        | FF-A function invocations to another endpoint while|
-|                        | the latter in not in a state to receive it (e.g. a |
+|                        | the latter is not in a state to receive it (e.g. a |
 |                        | SP sends a direct request to the normal world early|
 |                        | while the normal world is not booted yet).         |
 |                        | - the SPMC state itself by employing unexpected    |
@@ -286,14 +286,12 @@
 +------------------------+------------------+-----------------+---------------+
 | ``Total Risk Rating``  | High (12)        | High (12)       |               |
 +------------------------+------------------+-----------------+---------------+
-| ``Mitigations``        | The SPMC may be vulnerable to invalid state        |
-|                        | transitions for itself or while handling an SP     |
-|                        | state. The FF-A v1.1 specification provides a      |
-|                        | guidance on those state transitions (run-time      |
-|                        | model). The TF-A SPMC will be hardened in future   |
-|                        | releases to follow this guidance.                  |
-|                        | Additionally The TF-A SPMC mitigates the threat by |
-|                        | runs of the Arm `FF-A ACS`_ compliance test suite. |
+| ``Mitigations``        | The TF-A SPMC provides mitigation against such     |
+|                        | threat by following the guidance for partition     |
+|                        | runtime models as described in FF-A v1.1 EAC0 spec.|
+|                        | The SPMC performs numerous checks in runtime to    |
+|                        | prevent illegal state transitions by adhering to   |
+|                        | the partition runtime model.                       |
 +------------------------+----------------------------------------------------+
 
 +------------------------+----------------------------------------------------+
@@ -482,9 +480,11 @@
 |                        | the SPMC, the latter is hardened to prevent        |
 |                        | its internal state or the state of an SP to be     |
 |                        | revealed through a direct message response.        |
-|                        | Further FF-A v1.1 guidance about run time models   |
-|                        | and partition states will be implemented in future |
-|                        | TF-A SPMC releases.                                |
+|                        | Further, SPMC performs numerous checks in runtime  |
+|                        | on the basis of the rules established by partition |
+|                        | runtime models to stop  any malicious attempts by  |
+|                        | an endpoint to extract internal state of another   |
+|                        | endpoint.                                          |
 +------------------------+----------------------------------------------------+
 
 +------------------------+----------------------------------------------------+
@@ -882,9 +882,278 @@
 |                        | execution context.                                 |
 +------------------------+----------------------------------------------------+
 
++------------------------+----------------------------------------------------+
+| ID                     | 19                                                 |
++========================+====================================================+
+| ``Threat``             | **A malicious endpoint may abuse FFA_RUN call to   |
+|                        | resume or turn on other endpoint execution         |
+|                        | contexts, attempting to alter the internal state of|
+|                        | SPMC and SPs, potentially leading to illegal state |
+|                        | transitions and deadlocks.**                       |
+|                        | An endpoint can call into another endpoint         |
+|                        | execution context using FFA_MSG_SEND_DIRECT_REQ    |
+|                        | ABI to create a call chain. A malicious endpoint   |
+|                        | could abuse this to form loops in a call chain that|
+|                        | could lead to potential deadlocks.                 |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2, DF4                                      |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC, SPMD                                         |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC state, SP state, Scheduling cycles            |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Tampering, Denial of Service                       |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (9)       | Medium (9)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC provides mitigation against such     |
+|                        | threats by following the guidance for partition    |
+|                        | runtime models as described in FF-A v1.1 EAC0 spec.|
+|                        | The SPMC performs numerous checks in runtime to    |
+|                        | prevent illegal state transitions by adhering to   |
+|                        | the partition runtime model. Further, if the       |
+|                        | receiver endpoint is a predecessor of current      |
+|                        | endpoint in the present call chain, the SPMC denies|
+|                        | any attempts to form loops by returning FFA_DENIED |
+|                        | error code. Only the primary scheduler is allowed  |
+|                        | to turn on execution contexts of other partitions  |
+|                        | though SPMC does not have the ability to           |
+|                        | scrutinize its identity. Secure partitions have    |
+|                        | limited ability to resume execution contexts of    |
+|                        | other partitions based on the runtime model. Such  |
+|                        | attempts cannot compromise the integrity of the    |
+|                        | SPMC.                                              |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 20                                                 |
++========================+====================================================+
+| ``Threat``             | **A malicious endpoint can perform a               |
+|                        | denial-of-service attack by using FFA_INTERRUPT    |
+|                        | call that could attempt to cause the system to     |
+|                        | crash or enter into an unknown state as no physical|
+|                        | interrupt could be pending for it to be handled in |
+|                        | the SPMC.**                                        |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2, DF5                                      |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC, SPMD                                         |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC state, SP state, Scheduling cycles            |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Tampering, Denial of Service                       |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (9)       | Medium (9)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC provides mitigation against such     |
+|                        | attack by detecting invocations from partitions    |
+|                        | and simply returning FFA_ERROR status interface.   |
+|                        | SPMC only allows SPMD to use FFA_INTERRUPT ABI to  |
+|                        | communicate a pending secure interrupt triggered   |
+|                        | while execution was in normal world.               |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 21                                                 |
++========================+====================================================+
+| ``Threat``             | **A malicious secure endpoint might deactivate a   |
+|                        | (virtual) secure interrupt that was not originally |
+|                        | signaled by SPMC, thereby attempting to alter the  |
+|                        | state of the SPMC and potentially lead to system   |
+|                        | crash.**                                           |
+|                        | SPMC maps the virtual interrupt ids to the physical|
+|                        | interrupt ids to keep the implementation of virtual|
+|                        | interrupt driver simple.                           |
+|                        | Similarly, a malicious secure endpoint might invoke|
+|                        | the deactivation ABI more than once for a secure   |
+|                        | interrupt. Moreover, a malicious secure endpoint   |
+|                        | might attempt to deactivate a (virtual) secure     |
+|                        | interrupt that was signaled to another endpoint    |
+|                        | execution context by the SPMC even before secure   |
+|                        | interrupt was handled.                             |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF5                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC state, SP state                               |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | S-Endpoint                                         |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Tampering                                          |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (9)       | Medium (9)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | At initialization, the TF-A SPMC parses the        |
+|                        | partition manifests to find the target execution   |
+|                        | context responsible for handling the various       |
+|                        | secure physical interrupts. The TF-A SPMC provides |
+|                        | mitigation against above mentioned threats by:     |
+|                        |                                                    |
+|                        | - Keeping track of each pending virtual interrupt  |
+|                        |   signaled to an execution context of a secure     |
+|                        |   secure partition.                                |
+|                        | - Denying any deactivation call from SP if there is|
+|                        |   no pending physical interrupt  mapped to the     |
+|                        |   given virtual interrupt.                         |
+|                        | - Denying any deactivation call from SP if the     |
+|                        |   virtual interrupt has not been signaled to the   |
+|                        |   current execution context.                       |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 22                                                 |
++========================+====================================================+
+| ``Threat``             | **A malicious secure endpoint might not deactivate |
+|                        | a virtual interrupt signaled to it by the SPMC but |
+|                        | perform secure interrupt signal completion. This   |
+|                        | attempt to corrupt the internal state of the SPMC  |
+|                        | could lead to an unknown state and further lead to |
+|                        | system crash.**                                    |
+|                        | Similarly, a malicious secure endpoint could       |
+|                        | deliberately not perform either interrupt          |
+|                        | deactivation or interrupt completion signal. Since,|
+|                        | the SPMC can only process one secure interrupt at a|
+|                        | time, this could choke the system where all        |
+|                        | interrupts are indefinitely masked which could     |
+|                        | potentially lead to system crash or reboot.        |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF5                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC state, SP state, Scheduling cycles            |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | S-Endpoint                                         |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Tampering, Denial of Service                       |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (9)       | Medium (9)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC does not provide mitigation against  |
+|                        | such threat. This is a limitation of the current   |
+|                        | SPMC implementation and needs to be handled in the |
+|                        | future releases.                                   |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 23                                                 |
++========================+====================================================+
+| ``Threat``             | **A malicious endpoint could leverage non-secure   |
+|                        | interrupts to preempt a secure endpoint, thereby   |
+|                        | attempting to render it unable to handle a secure  |
+|                        | virtual interrupt targetted for it. This could lead|
+|                        | to priority inversion as secure virtual interrupts |
+|                        | are kept pending while non-secure interrupts are   |
+|                        | handled by normal world VMs.**                     |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2, DF3, DF5                                 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC, SPMD                                         |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC state, SP state, Scheduling cycles            |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint                                        |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of Service                                  |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (9)       | Medium (9)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC alone does not provide mitigation    |
+|                        | against such threats. System integrators must take |
+|                        | necessary high level design decisions that takes   |
+|                        | care of interrupt prioritization. The SPMC performs|
+|                        | its role of enabling SPs to specify appropriate    |
+|                        | action towards non-secure interrupt with the help  |
+|                        | of partition manifest based on the guidance in the |
+|                        | FF-A v1.1 EAC0 specification.                      |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 24                                                 |
++========================+====================================================+
+| ``Threat``             | **A secure endpoint depends on primary scheduler   |
+|                        | for CPU cycles. A malicious endpoint could delay   |
+|                        | the secure endpoint from being scheduled. Secure   |
+|                        | interrupts, if not handled timely, could compromise|
+|                        | the state of SP and SPMC, thereby rendering the    |
+|                        | system unresponsive.**                             |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2, DF3, DF5                                 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC, SPMD                                         |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC state, SP state, Scheduling cycles            |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint                                        |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of Service                                  |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (9)       | Medium (9)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC does not provide full mitigation     |
+|                        | against such threats. However, based on the        |
+|                        | guidance provided in the FF-A v1.1 EAC0 spec, SPMC |
+|                        | provisions CPU cycles to run a secure endpoint     |
+|                        | execution context in SPMC schedule mode which      |
+|                        | cannot be preempted by a non-secure interrupt.     |
+|                        | This reduces the dependency on primary scheduler   |
+|                        | for cycle allocation. Moreover, all further        |
+|                        | interrupts are masked until pending secure virtual |
+|                        | interrupt on current CPU is handled. This allows SP|
+|                        | execution context to make progress even upon being |
+|                        | interrupted.                                       |
++------------------------+----------------------------------------------------+
+
----------------
+--------------
 
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
 
 .. _Arm Firmware Framework for Arm A-profile: https://developer.arm.com/docs/den0077/latest
 .. _Secure Partition Manager: ../components/secure-partition-manager.html
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index bc93f93..f6c251d 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -12,6 +12,7 @@
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/spinlock.h>
+#include <plat/common/platform.h>
 
 #include "gicv3_private.h"
 
@@ -1287,12 +1288,14 @@
 
 	assert(gicv3_driver_data->gicr_base == 0U);
 
+	if (plat_can_cmo()) {
 	/* Ensure this function is called with Data Cache enabled */
 #ifndef __aarch64__
-	assert((read_sctlr() & SCTLR_C_BIT) != 0U);
+		assert((read_sctlr() & SCTLR_C_BIT) != 0U);
 #else
-	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
+		assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
 #endif /* !__aarch64__ */
+	}
 
 	mpidr_self = read_mpidr_el1() & MPIDR_AFFINITY_MASK;
 	rdistif_base = gicr_frame;
diff --git a/drivers/arm/rss/rss_comms.c b/drivers/arm/rss/rss_comms.c
index 5e224e1..4622af9 100644
--- a/drivers/arm/rss/rss_comms.c
+++ b/drivers/arm/rss/rss_comms.c
@@ -156,14 +156,22 @@
 
 	err = mhu_init_sender(mhu_sender_base);
 	if (err != MHU_ERR_NONE) {
-		ERROR("[RSS-COMMS] Host to RSS MHU driver initialization failed: %d\n", err);
-		return -1;
+		if (err == MHU_ERR_ALREADY_INIT) {
+			INFO("[RSS-COMMS] Host to RSS MHU driver already initialized\n");
+		} else {
+			ERROR("[RSS-COMMS] Host to RSS MHU driver initialization failed: %d\n", err);
+			return -1;
+		}
 	}
 
 	err = mhu_init_receiver(mhu_receiver_base);
 	if (err != MHU_ERR_NONE) {
-		ERROR("[RSS-COMMS] RSS to Host MHU driver initialization failed: %d\n", err);
-		return -1;
+		if (err == MHU_ERR_ALREADY_INIT) {
+			INFO("[RSS-COMMS] RSS to Host MHU driver already initialized\n");
+		} else {
+			ERROR("[RSS-COMMS] RSS to Host MHU driver initialization failed: %d\n", err);
+			return -1;
+		}
 	}
 
 	return 0;
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index a99a2c7..fa9509a 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -31,6 +31,7 @@
 	} while (0)
 
 #pragma weak plat_set_nv_ctr2
+#pragma weak plat_convert_pk
 
 
 static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a,
@@ -202,6 +203,10 @@
 			NOTICE("ROTPK is not deployed on platform. "
 				"Skipping ROTPK verification.\n");
 		} else {
+			/* platform may store the hash of a prefixed, suffixed or modified pk */
+			rc = plat_convert_pk(pk_ptr, pk_len, &pk_ptr, &pk_len);
+			return_if_error(rc);
+
 			/* Ask the crypto-module to verify the key hash */
 			rc = crypto_mod_verify_hash(pk_ptr, pk_len,
 				    pk_hash_ptr, pk_hash_len);
@@ -301,6 +306,15 @@
 	return plat_set_nv_ctr(cookie, nv_ctr);
 }
 
+int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+		    void **hashed_pk_ptr, unsigned int *hashed_pk_len)
+{
+	*hashed_pk_ptr = full_pk_ptr;
+	*hashed_pk_len = full_pk_len;
+
+	return 0;
+}
+
 /*
  * Return the parent id in the output parameter '*parent_id'
  *
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 16ce65f..ae4b067 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -22,7 +22,7 @@
 MBEDTLS_SOURCES	+=		drivers/auth/mbedtls/mbedtls_common.c
 
 
-LIBMBEDTLS_SRCS		:= $(addprefix ${MBEDTLS_DIR}/library/,	\
+LIBMBEDTLS_SRCS		+= $(addprefix ${MBEDTLS_DIR}/library/,	\
 					aes.c 					\
 					asn1parse.c 				\
 					asn1write.c 				\
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index d231179..42a0925 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -115,7 +115,7 @@
 	end = (unsigned char *)(p + sig_len);
 	signature.tag = *p;
 	rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len);
-	if (rc != 0) {
+	if ((rc != 0) || ((size_t)(end - p) != signature.len)) {
 		rc = CRYPTO_ERR_SIGNATURE;
 		goto end1;
 	}
@@ -170,12 +170,15 @@
 	size_t len;
 	int rc;
 
-	/* Digest info should be an MBEDTLS_ASN1_SEQUENCE */
+	/*
+	 * Digest info should be an MBEDTLS_ASN1_SEQUENCE
+	 * and consume all bytes.
+	 */
 	p = (unsigned char *)digest_info_ptr;
 	end = p + digest_info_len;
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
 				  MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0) {
+	if (rc != 0 || ((size_t)(end - p) != len)) {
 		return CRYPTO_ERR_HASH;
 	}
 
@@ -195,9 +198,9 @@
 		return CRYPTO_ERR_HASH;
 	}
 
-	/* Hash should be octet string type */
+	/* Hash should be octet string type and consume all bytes */
 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
-	if (rc != 0) {
+	if ((rc != 0) || ((size_t)(end - p) != len)) {
 		return CRYPTO_ERR_HASH;
 	}
 
diff --git a/drivers/auth/mbedtls/mbedtls_x509_parser.c b/drivers/auth/mbedtls/mbedtls_x509_parser.c
index 129566b..44b25ba 100644
--- a/drivers/auth/mbedtls/mbedtls_x509_parser.c
+++ b/drivers/auth/mbedtls/mbedtls_x509_parser.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -85,9 +85,6 @@
 	p = v3_ext.p;
 	end = v3_ext.p + v3_ext.len;
 
-	mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
-			     MBEDTLS_ASN1_SEQUENCE);
-
 	while (p < end) {
 		zeromem(&extn_oid, sizeof(extn_oid));
 		is_critical = 0; /* DEFAULT FALSE */
@@ -114,10 +111,10 @@
 		oid_len = mbedtls_oid_get_numeric_string(oid_str,
 							 MAX_OID_STR_LEN,
 							 &extn_oid);
-		if (oid_len == MBEDTLS_ERR_OID_BUF_TOO_SMALL) {
+		if ((oid_len == MBEDTLS_ERR_OID_BUF_TOO_SMALL) || (oid_len < 0)) {
 			return IMG_PARSER_ERR;
 		}
-		if ((oid_len == strlen(oid_str)) && !strcmp(oid, oid_str)) {
+		if (((size_t)oid_len == strlen(oid_str)) && !strcmp(oid, oid_str)) {
 			*ext = (void *)p;
 			*ext_len = (unsigned int)len;
 			return IMG_PARSER_OK;
@@ -144,8 +141,23 @@
 {
 	int ret, is_critical;
 	size_t len;
-	unsigned char *p, *end, *crt_end;
-	mbedtls_asn1_buf sig_alg1, sig_alg2;
+	unsigned char *p, *end, *crt_end, *pk_end;
+	mbedtls_asn1_buf sig_alg1;
+	/*
+	 * The unique ASN.1 DER encoding of [0] EXPLICIT INTEGER { v3(2} }.
+	 */
+	static const char v3[] = {
+		/* The outer CONTEXT SPECIFIC 0 tag */
+		MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0,
+		/* The number bytes used to encode the inner INTEGER */
+		3,
+		/* The tag of the inner INTEGER */
+		MBEDTLS_ASN1_INTEGER,
+		/* The number of bytes needed to represent 2 */
+		1,
+		/* The actual value 2 */
+		2,
+	};
 
 	p = (unsigned char *)img;
 	len = img_len;
@@ -163,7 +175,7 @@
 		return IMG_PARSER_ERR_FORMAT;
 	}
 
-	if (len > (size_t)(end - p)) {
+	if (len != (size_t)(end - p)) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
 	crt_end = p + len;
@@ -181,15 +193,14 @@
 	tbs.len = end - tbs.p;
 
 	/*
-	 * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+	 * Version  ::=  [0] EXPLICIT INTEGER {  v1(0), v2(1), v3(2)  }
+	 * -- only v3 accepted
 	 */
-	ret = mbedtls_asn1_get_tag(&p, end, &len,
-				   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
-				   MBEDTLS_ASN1_CONSTRUCTED | 0);
-	if (ret != 0) {
+	if (((end - p) <= (ptrdiff_t)sizeof(v3)) ||
+	    (memcmp(p, v3, sizeof(v3)) != 0)) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
-	p += len;
+	p += sizeof(v3);
 
 	/*
 	 * CertificateSerialNumber  ::=  INTEGER
@@ -257,9 +268,24 @@
 	if (ret != 0) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
-	pk.len = (p + len) - pk.p;
+	pk_end = p + len;
+	pk.len = pk_end - pk.p;
+
+	/* algorithm */
+	ret = mbedtls_asn1_get_tag(&p, pk_end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+				   MBEDTLS_ASN1_SEQUENCE);
+	if (ret != 0) {
+		return IMG_PARSER_ERR_FORMAT;
+	}
 	p += len;
 
+	/* Key is a BIT STRING and must use all bytes in SubjectPublicKeyInfo */
+	ret = mbedtls_asn1_get_bitstring_null(&p, pk_end, &len);
+	if ((ret != 0) || (p + len != pk_end)) {
+		return IMG_PARSER_ERR_FORMAT;
+	}
+	p = pk_end;
+
 	/*
 	 * issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
 	 */
@@ -290,29 +316,45 @@
 
 	/*
 	 * extensions      [3]  EXPLICIT Extensions OPTIONAL
+	 * }
+	 *
+	 * X.509 and RFC5280 allow omitting the extensions entirely.
+	 * However, in TF-A, a certificate with no extensions would
+	 * always fail later on, as the extensions contain the
+	 * information needed to authenticate the next stage in the
+	 * boot chain.  Furthermore, get_ext() assumes that the
+	 * extensions have been parsed into v3_ext, and allowing
+	 * there to be no extensions would pointlessly complicate
+	 * the code.  Therefore, just reject certificates without
+	 * extensions.  This is also why version 1 and 2 certificates
+	 * are rejected above.
 	 */
 	ret = mbedtls_asn1_get_tag(&p, end, &len,
 				   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
 				   MBEDTLS_ASN1_CONSTRUCTED | 3);
-	if (ret != 0) {
+	if ((ret != 0) || (len != (size_t)(end - p))) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
 
 	/*
 	 * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
+	 * -- must use all remaining bytes in TBSCertificate
 	 */
-	v3_ext.p = p;
 	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
 				   MBEDTLS_ASN1_SEQUENCE);
-	if (ret != 0) {
+	if ((ret != 0) || (len != (size_t)(end - p))) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
-	v3_ext.len = (p + len) - v3_ext.p;
+	v3_ext.p = p;
+	v3_ext.len = len;
 
 	/*
-	 * Check extensions integrity
+	 * Check extensions integrity.  At least one extension is
+	 * required: the ASN.1 specifies a minimum size of 1, and at
+	 * least one extension is needed to authenticate the next stage
+	 * in the boot chain.
 	 */
-	while (p < end) {
+	do {
 		ret = mbedtls_asn1_get_tag(&p, end, &len,
 					   MBEDTLS_ASN1_CONSTRUCTED |
 					   MBEDTLS_ASN1_SEQUENCE);
@@ -340,7 +382,7 @@
 			return IMG_PARSER_ERR_FORMAT;
 		}
 		p += len;
-	}
+	} while (p < end);
 
 	if (p != end) {
 		return IMG_PARSER_ERR_FORMAT;
@@ -353,33 +395,22 @@
 	 *  -- end of TBSCertificate
 	 *
 	 *  signatureAlgorithm   AlgorithmIdentifier
+	 *  -- Does not need to be parsed.  Ensuring it is bitwise
+	 *  -- identical (including the tag!) with the first signature
+	 *  -- algorithm is sufficient.
 	 */
-	sig_alg2.p = p;
-	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
-				   MBEDTLS_ASN1_SEQUENCE);
-	if (ret != 0) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
-	if ((end - p) < 1) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
-	sig_alg2.len = (p + len) - sig_alg2.p;
-	p += len;
-
-	/* Compare both signature algorithms */
-	if (sig_alg1.len != sig_alg2.len) {
-		return IMG_PARSER_ERR_FORMAT;
-	}
-	if (0 != memcmp(sig_alg1.p, sig_alg2.p, sig_alg1.len)) {
+	if ((sig_alg1.len >= (size_t)(end - p)) ||
+	    (0 != memcmp(sig_alg1.p, p, sig_alg1.len))) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
+	p += sig_alg1.len;
 	memcpy(&sig_alg, &sig_alg1, sizeof(sig_alg));
 
 	/*
 	 * signatureValue       BIT STRING
 	 */
 	signature.p = p;
-	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_BIT_STRING);
+	ret = mbedtls_asn1_get_bitstring_null(&p, end, &len);
 	if (ret != 0) {
 		return IMG_PARSER_ERR_FORMAT;
 	}
diff --git a/drivers/measured_boot/event_log/event_log.c b/drivers/measured_boot/event_log/event_log.c
index d661c35..6f2898d 100644
--- a/drivers/measured_boot/event_log/event_log.c
+++ b/drivers/measured_boot/event_log/event_log.c
@@ -14,8 +14,6 @@
 #include <drivers/auth/crypto_mod.h>
 #include <drivers/measured_boot/event_log/event_log.h>
 
-#include <plat/common/platform.h>
-
 #if TPM_ALG_ID == TPM_ALG_SHA512
 #define	CRYPTO_MD_ID	CRYPTO_MD_SHA512
 #elif TPM_ALG_ID == TPM_ALG_SHA384
@@ -32,9 +30,6 @@
 /* Pointer to the first byte past end of the Event Log buffer */
 static uintptr_t log_end;
 
-/* Pointer to event_log_metadata_t */
-static const event_log_metadata_t *plat_metadata_ptr;
-
 /* TCG_EfiSpecIdEvent */
 static const id_event_headers_t id_event_header = {
 	.header = {
@@ -173,10 +168,6 @@
 void event_log_init(uint8_t *event_log_start, uint8_t *event_log_finish)
 {
 	event_log_buf_init(event_log_start, event_log_finish);
-
-	/* Get pointer to platform's event_log_metadata_t structure */
-	plat_metadata_ptr = plat_event_log_get_metadata();
-	assert(plat_metadata_ptr != NULL);
 }
 
 void event_log_write_specid_event(void)
@@ -276,16 +267,19 @@
  * @param[in] data_base		Address of data
  * @param[in] data_size		Size of data
  * @param[in] data_id		Data ID
+ * @param[in] metadata_ptr	Event Log metadata
  * @return:
  *	0 = success
  *    < 0 = error
  */
 int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size,
-				 uint32_t data_id)
+				 uint32_t data_id,
+				 const event_log_metadata_t *metadata_ptr)
 {
 	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
 	int rc;
-	const event_log_metadata_t *metadata_ptr = plat_metadata_ptr;
+
+	assert(metadata_ptr != NULL);
 
 	/* Get the metadata associated with this image. */
 	while ((metadata_ptr->id != EVLOG_INVALID_ID) &&
diff --git a/drivers/nxp/auth/csf_hdr_parser/csf_hdr_parser.c b/drivers/nxp/auth/csf_hdr_parser/csf_hdr_parser.c
index b878082..4f31c6e 100644
--- a/drivers/nxp/auth/csf_hdr_parser/csf_hdr_parser.c
+++ b/drivers/nxp/auth/csf_hdr_parser/csf_hdr_parser.c
@@ -38,7 +38,7 @@
 
 /* Flag to indicate if values are there in rotpk_hash_table */
 bool rotpk_not_dpld =  true;
-uint8_t rotpk_hash_table[MAX_KEY_ENTRIES][SHA256_BYTES];
+uint8_t rotpk_hash_table[MAX_KEY_ENTRIES][SHA256_BYTES] __aligned(CACHE_WRITEBACK_GRANULE);
 uint32_t num_rotpk_hash_entries;
 
 /*
diff --git a/drivers/nxp/crypto/caam/src/jobdesc.c b/drivers/nxp/crypto/caam/src/jobdesc.c
index f559c4b..92fcb74 100644
--- a/drivers/nxp/crypto/caam/src/jobdesc.c
+++ b/drivers/nxp/crypto/caam/src/jobdesc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2020 NXP
+ * Copyright 2017-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -11,13 +11,13 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <assert.h>
 #include "caam.h"
 #include <common/debug.h>
 #include "jobdesc.h"
 #include "rsa.h"
 #include "sec_hw_specific.h"
 
-
 /* Return Length of desctiptr from first word */
 uint32_t desc_length(uint32_t *desc)
 {
@@ -41,6 +41,8 @@
 {
 	uint32_t len = desc_length(desc);
 
+	assert((len + 1) < MAX_DESC_SIZE_WORDS);
+
 	/* Add Word at Last */
 	uint32_t *last = desc + len;
 	*last = word;
@@ -54,6 +56,9 @@
 {
 	uint32_t len = desc_length(desc);
 
+	assert((len + (uint32_t) (sizeof(phys_addr_t) / sizeof(uint32_t)))
+		< MAX_DESC_SIZE_WORDS);
+
 	/* Add Word at Last */
 	phys_addr_t *last = (phys_addr_t *) (desc + len);
 
diff --git a/drivers/nxp/ddr/nxp-ddr/regs.c b/drivers/nxp/ddr/nxp-ddr/regs.c
index cedd7ca..26155ab 100644
--- a/drivers/nxp/ddr/nxp-ddr/regs.c
+++ b/drivers/nxp/ddr/nxp-ddr/regs.c
@@ -1302,7 +1302,7 @@
 		return 0;
 	}
 
-	if ((bin[i].taamin_ps[j] == 0) ||
+	if (((bin[i].taamin_ps[j] == 0) && j > 0) ||
 	    (bin[i].taamin_ps[j] > taamin_ps && j > 0)) {
 		j--;
 	}
diff --git a/drivers/nxp/ddr/phy-gen2/phy.c b/drivers/nxp/ddr/phy-gen2/phy.c
index 9e52145..2006c04 100644
--- a/drivers/nxp/ddr/phy-gen2/phy.c
+++ b/drivers/nxp/ddr/phy-gen2/phy.c
@@ -241,12 +241,6 @@
 				rwmax = tmp;
 			}
 
-			tmp = wrmax;
-			wrmax = cdd[56];
-			if (tmp > wrmax) {
-				wrmax = tmp;
-			}
-
 			break;
 
 		case 2U:
@@ -276,15 +270,7 @@
 				rwmax = tmp;
 			}
 
-			buf[0] = cdd[56];
-			buf[1] = cdd[55];
-			buf[2] = cdd[52];
-			buf[3] = cdd[51];
-			tmp = wrmax;
-			wrmax = findmax(buf, 4U);
-			if (tmp > wrmax) {
-				wrmax = tmp;
-			}
+			wrmax = wwmax;
 
 			break;
 
@@ -310,12 +296,7 @@
 				rwmax = tmp;
 			}
 
-			tmp = wrmax;
-			c = &cdd[41];
-			wrmax = findmax(c, 16U);
-			if (tmp > wrmax) {
-				wrmax = tmp;
-			}
+			wrmax = wwmax;
 
 			break;
 
@@ -390,7 +371,12 @@
 
 #ifdef NXP_WARM_BOOT
 int save_phy_training_values(uint16_t **phy_ptr, uint32_t address_to_store,
-		uint32_t num_of_phy, int train2d)
+		uint32_t num_of_phy, int train2d
+#ifdef NXP_APPLY_MAX_CDD
+			, struct ddr_ctrl_reg_values *ddrctrl_regs
+#endif
+		)
+
 {
 	uint16_t *phy = NULL, value = 0x0;
 	uint32_t size = 1U, num_of_regs = 1U, phy_store = 0U;
@@ -457,6 +443,15 @@
 			ret = xspi_write(phy_store, training_2D_values,
 					size);
 		}
+
+#ifdef NXP_APPLY_MAX_CDD
+		/* Save DDR control register Timing CFG 0 and 4 */
+		phy_store  += size;
+		size = sizeof(ddrctrl_regs);
+		if (ret != 0) {
+			ret = xspi_write(phy_store, ddrctrl_regs, size);
+		}
+#endif
 		/* Disable clocks in case they were disabled. */
 		phy_io_write16(phy, t_drtub |
 				csr_ucclk_hclk_enables_addr, 0x0);
@@ -472,7 +467,11 @@
 }
 
 int restore_phy_training_values(uint16_t **phy_ptr, uint32_t address_to_restore,
-		uint32_t num_of_phy, int train2d)
+		uint32_t num_of_phy, int train2d
+#ifdef NXP_APPLY_MAX_CDD
+		, struct ddr_ctrl_reg_values *ddrctrl_regs
+#endif
+		)
 {
 	uint16_t *phy = NULL;
 	uint32_t size = 1U, num_of_regs = 1U, phy_store = 0U;
@@ -504,6 +503,14 @@
 		/* Reading 1D training values from flash*/
 		ret = xspi_read(phy_store, (uint32_t *)training_1D_values,
 				size);
+		if (ret != 0) {
+#ifdef DEBUG_WARM_RESET
+			debug("Unable to Read 1D training values %d\n",
+					ret);
+#endif
+			return -EINVAL;
+		}
+
 		debug("Restoring 1D Training reg val at:%08x\n", phy_store);
 		for (i = 0; i < num_of_regs; i++) {
 			phy_io_write16(phy, training_1D_values[i].addr,
@@ -523,6 +530,15 @@
 			/* Reading 2D training values from flash */
 			ret = xspi_read(phy_store,
 					(uint32_t *)training_2D_values,	size);
+
+			if (ret != 0) {
+#ifdef DEBUG_WARM_RESET
+				debug("Unable to Read 2D training values %d\n",
+						ret);
+#endif
+				return -EINVAL;
+			}
+
 			debug("Restoring 2D Training reg val at:%08x\n",
 					phy_store);
 			for (i = 0; i < num_of_regs; i++) {
@@ -537,6 +553,11 @@
 #endif
 			}
 		}
+#ifdef NXP_APPLY_MAX_CDD
+		phy_store = phy_store + size;
+		size = sizeof(ddrctrl_regs);
+		ret = xspi_read(phy_store, (uint32_t *)ddrctrl_regs, size);
+#endif
 		/* Disable clocks in case they were disabled. */
 		phy_io_write16(phy, t_drtub |
 				csr_ucclk_hclk_enables_addr, 0x0);
@@ -2292,6 +2313,7 @@
 
 	if (i < 0 || i > 3) {
 		printf("Error: invalid chip-select value\n");
+		return;
 	}
 	switch (val) {
 	case DDR_ODT_CS:
@@ -2473,6 +2495,9 @@
 	__unused const soc_info_t *soc_info;
 #ifdef NXP_APPLY_MAX_CDD
 	unsigned int tcfg0, tcfg4, rank;
+#ifdef NXP_WARM_BOOT
+	struct ddr_ctrl_reg_values ddrctrl_regs;
+#endif
 #endif
 
 	if (dimm_param == NULL) {
@@ -2577,11 +2602,19 @@
 		ret = restore_phy_training_values(priv->phy,
 						  PHY_TRAINING_REGS_ON_FLASH,
 						  priv->num_ctlrs,
-						  input.basic.train2d);
+						  input.basic.train2d
+#ifdef NXP_APPLY_MAX_CDD
+						, &ddrctrl_regs
+#endif
+						);
 		if (ret != 0) {
 			ERROR("Restoring of training data failed %d\n", ret);
 			return ret;
 		}
+#ifdef NXP_APPLY_MAX_CDD
+		regs->timing_cfg[0] = ddrctrl_regs.timing_cfg0;
+		regs->timing_cfg[4] = ddrctrl_regs.timing_cfg4;
+#endif
 	} else {
 #endif
 		/* Mapping IMG buffer firstly */
@@ -2644,12 +2677,20 @@
 #ifdef NXP_WARM_BOOT
 		if (priv->warm_boot_flag != DDR_WRM_BOOT_NT_SUPPORTED &&
 		    ret == 0) {
+#ifdef NXP_APPLY_MAX_CDD
+			ddrctrl_regs.timing_cfg0 = regs->timing_cfg[0];
+			ddrctrl_regs.timing_cfg4 = regs->timing_cfg[4];
+#endif
 			debug("save the phy training data\n");
 			//Save training data TBD
 			ret = save_phy_training_values(priv->phy,
 						PHY_TRAINING_REGS_ON_FLASH,
 						priv->num_ctlrs,
-						input.basic.train2d);
+						input.basic.train2d
+#ifdef NXP_APPLY_MAX_CDD
+						, &ddrctrl_regs
+#endif
+						);
 			if (ret != 0) {
 				ERROR("Saving training data failed.");
 				ERROR("Warm boot will fail. Error=%d.\n", ret);
diff --git a/drivers/nxp/ddr/phy-gen2/phy.h b/drivers/nxp/ddr/phy-gen2/phy.h
index 15e80d1..5e80f36 100644
--- a/drivers/nxp/ddr/phy-gen2/phy.h
+++ b/drivers/nxp/ddr/phy-gen2/phy.h
@@ -11,11 +11,18 @@
 /* To store sector size to be erase on flash*/
 #define PHY_ERASE_SIZE F_SECTOR_ERASE_SZ
 
+/*Structure to save DDR controller timing register 0 and 4 values*/
+struct ddr_ctrl_reg_values {
+	uint32_t timing_cfg0;
+	uint32_t timing_cfg4;
+};
+
 /*Structure to implement address-data map tuples to store PHY training values*/
 struct phy_training_values {
 	uint32_t addr;
 	uint16_t data;
 };
+
 /* Saves PHY Training Register values after cold reset
  *@param[in] phy_ptr array to store addresses of PHYs
  *@param[in] address_to_store address to save PHY training register values
@@ -24,6 +31,8 @@
  *to be saved
  *@param[in] train2d flag to store whether 2D training registers are to
  *be saved or not
+ *@param[in] ddrctrl_regs to save ddr controller registers in case
+ *NXP_APPLY_MAX_CDD is applied
  *
  *PHY training values will be stored on flash at contigous memory in the order:
  *1D training registers, 2D training registers
@@ -31,9 +40,13 @@
  *
  *if train2d is false saving 2D training registers will be skipped
  */
-int save_phy_training_values(uint16_t **phy_ptr, uint32_t address_to_store,
-		uint32_t num_of_phy, int train2d);
 
+int save_phy_training_values(uint16_t **phy_ptr, uint32_t address_to_store,
+		uint32_t num_of_phy, int train2d
+#ifdef NXP_APPLY_MAX_CDD
+		, struct ddr_ctrl_reg_values *ddrctrl_regs
+#endif
+		);
 /*Restores PHY Training Register values after warm reset
  *@param[in] phy_ptr array to store addresses of PHYs
  *@param[in] address_to_store address to retrieve PHY training register
@@ -42,12 +55,17 @@
  *to be restored
  *@param[in] train2d flag to store whether 2D training registers are
  *to be restored or not
- *
+ *@param[in] ddrctrl_regs to restore  ddr controller registers in case
+ *NXP_APPLY_MAX_CDD is applied
  *if train2d is false saving 2D training registers will be skipped
  */
 
 int restore_phy_training_values(uint16_t **phy_ptr, uint32_t address_to_restore,
-		uint32_t num_of_phy, int train2d);
+		uint32_t num_of_phy, int train2d
+#ifdef NXP_APPLY_MAX_CDD
+		, struct ddr_ctrl_reg_values *ddrctrl_regs
+#endif
+		);
 
 /*
  * Address data tuples to store the PHY 1D
diff --git a/drivers/nxp/flexspi/nor/fspi.c b/drivers/nxp/flexspi/nor/fspi.c
index 7c919b8..1e8c5a2 100644
--- a/drivers/nxp/flexspi/nor/fspi.c
+++ b/drivers/nxp/flexspi/nor/fspi.c
@@ -123,6 +123,9 @@
 		cmd_id1 = FSPI_NOR_CMD_RDSR;
 		cmd_id2 = FSPI_NOR_CMD_RDSR;
 		break;
+	default:
+		ERROR("Unsupported command\n");
+		return;
 	}
 
 	x_addr = FSPI_LUTREG_OFFSET + (uint32_t)(0x10 * fspi_op_seq_id);
diff --git a/drivers/nxp/tzc/plat_tzc380.c b/drivers/nxp/tzc/plat_tzc380.c
index 13cf3b9..5b27563 100644
--- a/drivers/nxp/tzc/plat_tzc380.c
+++ b/drivers/nxp/tzc/plat_tzc380.c
@@ -91,20 +91,37 @@
 	}
 	/* Continue with list entries for index > 0 */
 	if (dram_idx == 0) {
-		/* TZC Region 1 on DRAM0 for Secure Memory*/
+		/*
+		 * Region 1: Secure Region on DRAM 1 for  2MB out of  2MB,
+		 * excluding 0 sub-region(=256KB).
+		 */
 		tzc380_reg_list[list_idx].secure = TZC_ATTR_SP_S_RW;
 		tzc380_reg_list[list_idx].enabled = TZC_ATTR_REGION_ENABLE;
 		tzc380_reg_list[list_idx].addr = dram_start_addr + dram_size;
-		tzc380_reg_list[list_idx].size = secure_dram_sz;
+		tzc380_reg_list[list_idx].size = TZC_REGION_SIZE_2M;
 		tzc380_reg_list[list_idx].sub_mask = 0x0; /* all enabled */
 		list_idx++;
 
-		/* TZC Region 2 on DRAM0 for Shared Memory*/
+		/*
+		 * Region 2: Secure Region on DRAM 1 for 54MB out of 64MB,
+		 * excluding 1 sub-rgion(=8MB) of 8MB.
+		 */
 		tzc380_reg_list[list_idx].secure = TZC_ATTR_SP_S_RW;
 		tzc380_reg_list[list_idx].enabled = TZC_ATTR_REGION_ENABLE;
+		tzc380_reg_list[list_idx].addr = dram_start_addr + dram_size + shrd_dram_sz;
+		tzc380_reg_list[list_idx].size = TZC_REGION_SIZE_64M;
+		tzc380_reg_list[list_idx].sub_mask = 0x80; /* Disable sub-region 7 */
+		list_idx++;
+
+		/*
+		 * Region 3: Secure Region on DRAM 1 for  6MB out of  8MB,
+		 * excluding 2 sub-rgion(=1MB) of 2MB.
+		 */
+		tzc380_reg_list[list_idx].secure = TZC_ATTR_SP_S_RW;
+		tzc380_reg_list[list_idx].enabled = TZC_ATTR_REGION_ENABLE;
 		tzc380_reg_list[list_idx].addr = dram_start_addr + dram_size + secure_dram_sz;
-		tzc380_reg_list[list_idx].size = shrd_dram_sz;
-		tzc380_reg_list[list_idx].sub_mask = 0x0; /* all enabled */
+		tzc380_reg_list[list_idx].size = TZC_REGION_SIZE_8M;
+		tzc380_reg_list[list_idx].sub_mask = 0xC0; /* Disable sub-region 6 & 7 */
 		list_idx++;
 
 	}
diff --git a/drivers/st/clk/clk-stm32-core.c b/drivers/st/clk/clk-stm32-core.c
index bb03125..9fe8c8c 100644
--- a/drivers/st/clk/clk-stm32-core.c
+++ b/drivers/st/clk/clk-stm32-core.c
@@ -466,10 +466,9 @@
 {
 	const struct clk_stm32 *clk = _clk_get(priv, id);
 	int parent;
-	unsigned long rate = 0UL;
 
 	if ((unsigned int)id >= priv->num) {
-		return rate;
+		return 0UL;
 	}
 
 	parent = _clk_stm32_get_parent(priv, id);
@@ -484,21 +483,14 @@
 			prate = _clk_stm32_get_rate(priv, parent);
 		}
 
-		rate = clk->ops->recalc_rate(priv, id, prate);
-
-		return rate;
+		return clk->ops->recalc_rate(priv, id, prate);
 	}
 
-	switch (parent) {
-	case CLK_IS_ROOT:
+	if (parent == CLK_IS_ROOT) {
 		panic();
-
-	default:
-		rate = _clk_stm32_get_rate(priv, parent);
-		break;
 	}
-	return rate;
 
+	return _clk_stm32_get_rate(priv, parent);
 }
 
 unsigned long _clk_stm32_get_parent_rate(struct stm32_clk_priv *priv, int id)
@@ -519,7 +511,7 @@
 
 bool _stm32_clk_is_flags(struct stm32_clk_priv *priv, int id, uint8_t flag)
 {
-	if (_stm32_clk_get_flags(priv, id) & flag) {
+	if ((_stm32_clk_get_flags(priv, id) & flag) != 0U) {
 		return true;
 	}
 
@@ -549,7 +541,7 @@
 		}
 		if (parent != CLK_IS_ROOT) {
 			ret = _clk_stm32_enable_core(priv, parent);
-			if (ret) {
+			if (ret != 0) {
 				return ret;
 			}
 		}
diff --git a/drivers/st/clk/clk-stm32mp13.c b/drivers/st/clk/clk-stm32mp13.c
index c960928..db427ad 100644
--- a/drivers/st/clk/clk-stm32mp13.c
+++ b/drivers/st/clk/clk-stm32mp13.c
@@ -456,7 +456,7 @@
 	},\
 }
 
-static const struct parent_cfg parent_mp13[] = {
+static const struct parent_cfg parent_mp13[MUX_MAX] = {
 	MUX_CFG(MUX_ADC1,	ADC1_src,	RCC_ADC12CKSELR, 0, 2),
 	MUX_CFG(MUX_ADC2,	ADC2_src,	RCC_ADC12CKSELR, 2, 2),
 	MUX_RDY_CFG(MUX_AXI,	AXI_src,	RCC_ASSCKSELR, 0, 3),
@@ -841,7 +841,7 @@
 		.bitrdy	= _bitrdy,\
 }
 
-static const struct div_cfg dividers_mp13[] = {
+static const struct div_cfg dividers_mp13[DIV_MAX] = {
 	DIV_CFG(DIV_PLL1DIVP, RCC_PLL1CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
 	DIV_CFG(DIV_PLL2DIVP, RCC_PLL2CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
 	DIV_CFG(DIV_PLL2DIVQ, RCC_PLL2CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY),
@@ -1119,7 +1119,7 @@
 		return ret;
 	}
 
-	if (enable) {
+	if (enable != 0) {
 		clk_stm32_enable_call_ops(priv, clk_id);
 	} else {
 		clk_stm32_disable_call_ops(priv, clk_id);
@@ -1450,7 +1450,7 @@
 
 	/* Configure PLLs source */
 	ret = stm32_clk_configure_mux(priv, pll_conf->vco.src);
-	if (ret) {
+	if (ret != 0) {
 		return ret;
 	}
 
@@ -1485,7 +1485,7 @@
 {
 	struct stm32_pll_dt_cfg *pll_conf = clk_stm32_pll_get_pdata(pll_idx);
 
-	if (pll_conf->vco.status) {
+	if (pll_conf->vco.status != 0U) {
 		return _clk_stm32_pll_init(priv, pll_idx, pll_conf);
 	}
 
@@ -1497,22 +1497,22 @@
 	int err = 0;
 
 	err = clk_stm32_pll_init(priv, _PLL1);
-	if (err) {
+	if (err != 0) {
 		return err;
 	}
 
 	err = clk_stm32_pll_init(priv, _PLL2);
-	if (err) {
+	if (err != 0) {
 		return err;
 	}
 
 	err = clk_stm32_pll_init(priv, _PLL3);
-	if (err) {
+	if (err != 0) {
 		return err;
 	}
 
 	err = clk_stm32_pll_init(priv, _PLL4);
-	if (err) {
+	if (err != 0) {
 		return err;
 	}
 
@@ -2242,7 +2242,7 @@
 	size_t i = 0U;
 
 	for (i = _PLL1; i < pdata->npll; i++) {
-		struct stm32_pll_dt_cfg *pll = pdata->pll + i;
+		struct stm32_pll_dt_cfg *pll = &pdata->pll[i];
 		char name[RCC_PLL_NAME_SIZE];
 		int subnode = 0;
 		int err = 0;
diff --git a/drivers/st/crypto/stm32_hash.c b/drivers/st/crypto/stm32_hash.c
index 6a1d476..e92f980 100644
--- a/drivers/st/crypto/stm32_hash.c
+++ b/drivers/st/crypto/stm32_hash.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,10 +8,6 @@
 #include <errno.h>
 #include <stdint.h>
 
-#include <libfdt.h>
-
-#include <platform_def.h>
-
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/clk.h>
@@ -20,9 +16,17 @@
 #include <drivers/st/stm32mp_reset.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
+#include <libfdt.h>
 #include <plat/common/platform.h>
 
+#include <platform_def.h>
+
+#if STM32_HASH_VER == 2
 #define DT_HASH_COMPAT			"st,stm32f756-hash"
+#endif
+#if STM32_HASH_VER == 4
+#define DT_HASH_COMPAT			"st,stm32mp13-hash"
+#endif
 
 #define HASH_CR				0x00U
 #define HASH_DIN			0x04U
@@ -33,11 +37,22 @@
 /* Control Register */
 #define HASH_CR_INIT			BIT(2)
 #define HASH_CR_DATATYPE_SHIFT		U(4)
-
+#if STM32_HASH_VER == 2
 #define HASH_CR_ALGO_SHA1		0x0U
 #define HASH_CR_ALGO_MD5		BIT(7)
 #define HASH_CR_ALGO_SHA224		BIT(18)
 #define HASH_CR_ALGO_SHA256		(BIT(18) | BIT(7))
+#endif
+#if STM32_HASH_VER == 4
+#define HASH_CR_ALGO_SHIFT		U(17)
+#define HASH_CR_ALGO_SHA1		(0x0U << HASH_CR_ALGO_SHIFT)
+#define HASH_CR_ALGO_SHA224		(0x2U << HASH_CR_ALGO_SHIFT)
+#define HASH_CR_ALGO_SHA256		(0x3U << HASH_CR_ALGO_SHIFT)
+#define HASH_CR_ALGO_SHA384		(0xCU << HASH_CR_ALGO_SHIFT)
+#define HASH_CR_ALGO_SHA512_224		(0xDU << HASH_CR_ALGO_SHIFT)
+#define HASH_CR_ALGO_SHA512_256		(0xEU << HASH_CR_ALGO_SHIFT)
+#define HASH_CR_ALGO_SHA512		(0xFU << HASH_CR_ALGO_SHIFT)
+#endif
 
 /* Status Flags */
 #define HASH_SR_DCIS			BIT(1)
@@ -51,6 +66,10 @@
 #define SHA1_DIGEST_SIZE		20U
 #define SHA224_DIGEST_SIZE		28U
 #define SHA256_DIGEST_SIZE		32U
+#define SHA384_DIGEST_SIZE		48U
+#define SHA512_224_DIGEST_SIZE		28U
+#define SHA512_256_DIGEST_SIZE		32U
+#define SHA512_DIGEST_SIZE		64U
 
 #define RESET_TIMEOUT_US_1MS		1000U
 #define HASH_TIMEOUT_US			10000U
@@ -131,10 +150,12 @@
 	reg = HASH_CR_INIT | (HASH_DATA_8_BITS << HASH_CR_DATATYPE_SHIFT);
 
 	switch (mode) {
+#if STM32_HASH_VER == 2
 	case HASH_MD5SUM:
 		reg |= HASH_CR_ALGO_MD5;
 		stm32_hash.digest_size = MD5_DIGEST_SIZE;
 		break;
+#endif
 	case HASH_SHA1:
 		reg |= HASH_CR_ALGO_SHA1;
 		stm32_hash.digest_size = SHA1_DIGEST_SIZE;
@@ -143,6 +164,16 @@
 		reg |= HASH_CR_ALGO_SHA224;
 		stm32_hash.digest_size = SHA224_DIGEST_SIZE;
 		break;
+#if STM32_HASH_VER == 4
+	case HASH_SHA384:
+		reg |= HASH_CR_ALGO_SHA384;
+		stm32_hash.digest_size = SHA384_DIGEST_SIZE;
+		break;
+	case HASH_SHA512:
+		reg |= HASH_CR_ALGO_SHA512;
+		stm32_hash.digest_size = SHA512_DIGEST_SIZE;
+		break;
+#endif
 	/* Default selected algo is SHA256 */
 	case HASH_SHA256:
 	default:
@@ -171,13 +202,12 @@
 		memcpy(digest + (i * sizeof(uint32_t)), &dsg, sizeof(uint32_t));
 	}
 
-#if defined(IMAGE_BL2)
 	/*
 	 * Clean hardware context as HASH could be used later
 	 * by non-secure software
 	 */
 	hash_hw_init(HASH_SHA256);
-#endif
+
 	return 0;
 }
 
@@ -298,17 +328,9 @@
 	for (node = dt_get_node(&hash_info, -1, DT_HASH_COMPAT);
 	     node != -FDT_ERR_NOTFOUND;
 	     node = dt_get_node(&hash_info, node, DT_HASH_COMPAT)) {
-#if defined(IMAGE_BL2)
 		if (hash_info.status != DT_DISABLED) {
 			break;
 		}
-#else
-		/* BL32 uses hash if it is assigned only to secure world */
-		if (hash_info.status == DT_SECURE) {
-			stm32mp_register_secure_periph_iomem(hash_info.base);
-			break;
-		}
-#endif
 	}
 
 	if (node == -FDT_ERR_NOTFOUND) {
diff --git a/drivers/st/crypto/stm32_pka.c b/drivers/st/crypto/stm32_pka.c
new file mode 100644
index 0000000..2bbb31d
--- /dev/null
+++ b/drivers/st/crypto/stm32_pka.c
@@ -0,0 +1,697 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <drivers/clk.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32_pka.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/*
+ * For our comprehension in this file
+ *  _len are in BITs
+ *  _size are in BYTEs
+ *  _nbw are in number of PKA_word (PKA_word = u64)
+ */
+
+#define UINT8_LEN			8U
+#define UINT64_LEN			(UINT8_LEN * sizeof(uint64_t))
+#define WORD_SIZE			(sizeof(uint64_t))
+#define OP_NBW_FROM_LEN(len)		(DIV_ROUND_UP_2EVAL((len), UINT64_LEN) + 1)
+#define OP_NBW_FROM_SIZE(s)		OP_NBW_FROM_LEN((s) * UINT8_LEN)
+#define OP_SIZE_FROM_SIZE(s)		(OP_NBW_FROM_SIZE(s) * WORD_SIZE)
+
+#define DT_PKA_COMPAT			"st,stm32-pka64"
+
+#define MAX_ECC_SIZE_LEN		640U
+#define MAX_EO_NBW			OP_NBW_FROM_LEN(MAX_ECC_SIZE_LEN)
+
+/* PKA registers */
+/* PKA control register */
+#define _PKA_CR				0x0U
+/* PKA status register */
+#define _PKA_SR				0x4U
+/* PKA clear flag register */
+#define _PKA_CLRFR			0x8U
+/* PKA version register */
+#define _PKA_VERR			0x1FF4U
+/* PKA identification register */
+#define _PKA_IPIDR			0x1FF8U
+
+/* PKA control register fields */
+#define _PKA_CR_MODE_MASK		GENMASK(13, 8)
+#define _PKA_CR_MODE_SHIFT		8U
+#define _PKA_CR_MODE_ADD		0x9U
+#define _PKA_CR_MODE_ECDSA_VERIF	0x26U
+#define _PKA_CR_START			BIT(1)
+#define _PKA_CR_EN			BIT(0)
+
+/* PKA status register fields */
+#define _PKA_SR_BUSY			BIT(16)
+#define _PKA_SR_LMF			BIT(1)
+#define _PKA_SR_INITOK			BIT(0)
+
+/* PKA it flag fields (used in CR, SR and CLRFR) */
+#define _PKA_IT_MASK			(GENMASK(21, 19) | BIT(17))
+#define _PKA_IT_SHIFT			17U
+#define _PKA_IT_OPERR			BIT(21)
+#define _PKA_IT_ADDRERR			BIT(20)
+#define _PKA_IT_RAMERR			BIT(19)
+#define _PKA_IT_PROCEND			BIT(17)
+
+/* PKA version register fields */
+#define _PKA_VERR_MAJREV_MASK		GENMASK(7, 4)
+#define _PKA_VERR_MAJREV_SHIFT		4U
+#define _PKA_VERR_MINREV_MASK		GENMASK(3, 0)
+#define _PKA_VERR_MINREV_SHIFT		0U
+
+/* RAM magic offset */
+#define _PKA_RAM_START			0x400U
+#define _PKA_RAM_SIZE			5336U
+
+/* ECDSA verification */
+#define _PKA_RAM_N_LEN			0x408U /* 64 */
+#define _PKA_RAM_P_LEN			0x4C8U /* 64 */
+#define _PKA_RAM_A_SIGN			0x468U /* 64 */
+#define _PKA_RAM_A			0x470U /* EOS */
+#define _PKA_RAM_P			0x4D0U /* EOS */
+#define _PKA_RAM_XG			0x678U /* EOS */
+#define _PKA_RAM_YG			0x6D0U /* EOS */
+#define _PKA_RAM_XQ			0x12F8U /* EOS */
+#define _PKA_RAM_YQ			0x1350U /* EOS */
+#define _PKA_RAM_SIGN_R			0x10E0U /* EOS */
+#define _PKA_RAM_SIGN_S			0xC68U /* EOS */
+#define _PKA_RAM_HASH_Z			0x13A8U /* EOS */
+#define _PKA_RAM_PRIME_N		0x1088U /* EOS */
+#define _PKA_RAM_ECDSA_VERIFY		0x5D0U /* 64 */
+#define _PKA_RAM_ECDSA_VERIFY_VALID	0xD60DULL
+#define _PKA_RAM_ECDSA_VERIFY_INVALID	0xA3B7ULL
+
+#define PKA_TIMEOUT_US			1000000U
+#define TIMEOUT_US_1MS			1000U
+#define PKA_RESET_DELAY			20U
+
+struct curve_parameters {
+	uint32_t a_sign;  /* 0 positive, 1 negative */
+	uint8_t *a;    /* Curve coefficient |a| */
+	size_t a_size;
+	uint8_t *p;    /* Curve modulus value */
+	uint32_t p_len;
+	uint8_t *xg;   /* Curve base point G coordinate x */
+	size_t xg_size;
+	uint8_t *yg;   /* Curve base point G coordinate y */
+	size_t yg_size;
+	uint8_t *n;    /* Curve prime order n */
+	uint32_t n_len;
+};
+
+static const struct curve_parameters curve_def[] = {
+#if PKA_USE_NIST_P256
+	[PKA_NIST_P256] = {
+		.p_len = 256U,
+		.n_len = 256U,
+		.p  = (uint8_t[]){0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
+				  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+				  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+		.n  = (uint8_t[]){0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+				  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				  0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
+				  0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51},
+		.a_sign = 1U,
+		.a = (uint8_t[]){0x03},
+		.a_size = 1U,
+		.xg = (uint8_t[]){0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47,
+				  0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2,
+				  0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
+				  0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96},
+		.xg_size = 32U,
+		.yg = (uint8_t[]){0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B,
+				  0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16,
+				  0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,
+				  0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5},
+		.yg_size = 32U,
+	},
+#endif
+#if PKA_USE_BRAINPOOL_P256R1
+	[PKA_BRAINPOOL_P256R1] = {
+		.p_len = 256,
+		.n_len = 256,
+		.p  = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC,
+				  0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72,
+				  0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28,
+				  0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77},
+		.n  = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC,
+				  0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71,
+				  0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7,
+				  0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7},
+		.a  = (uint8_t[]){0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57,
+				  0xEE, 0xF6, 0x75, 0x30, 0x41, 0x7A, 0xFF, 0xE7,
+				  0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C,
+				  0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9},
+		.a_size = 32U,
+		.xg = (uint8_t[]){0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB,
+				  0x2C, 0x4B, 0x48, 0x2F, 0xFC, 0x81, 0xB7, 0xAF,
+				  0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2,
+				  0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62},
+		.xg_size = 32U,
+		.yg = (uint8_t[]){0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD,
+				  0x97, 0xF8, 0x46, 0x1A, 0x14, 0x61, 0x1D, 0xC9,
+				  0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54,
+				  0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97},
+		.yg_size = 32U,
+	},
+#endif
+#if PKA_USE_BRAINPOOL_P256T1
+	[PKA_BRAINPOOL_P256T1] = {
+		.p_len = 256,
+		.n_len = 256,
+		.p  = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC,
+				  0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72,
+				  0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28,
+				  0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77},
+		.n  = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC,
+				  0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71,
+				  0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7,
+				  0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7},
+		.a  = (uint8_t[]){0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC,
+				  0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72,
+				  0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28,
+				  0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x74},
+		.a_size = 32U,
+		.xg = (uint8_t[]){0xA3, 0xE8, 0xEB, 0x3C, 0xC1, 0xCF, 0xE7, 0xB7,
+				  0x73, 0x22, 0x13, 0xB2, 0x3A, 0x65, 0x61, 0x49,
+				  0xAF, 0xA1, 0x42, 0xC4, 0x7A, 0xAF, 0xBC, 0x2B,
+				  0x79, 0xA1, 0x91, 0x56, 0x2E, 0x13, 0x05, 0xF4},
+		.xg_size = 32U,
+		.yg = (uint8_t[]){0x2D, 0x99, 0x6C, 0x82, 0x34, 0x39, 0xC5, 0x6D,
+				  0x7F, 0x7B, 0x22, 0xE1, 0x46, 0x44, 0x41, 0x7E,
+				  0x69, 0xBC, 0xB6, 0xDE, 0x39, 0xD0, 0x27, 0x00,
+				  0x1D, 0xAB, 0xE8, 0xF3, 0x5B, 0x25, 0xC9, 0xBE},
+		.yg_size = 32U,
+	},
+#endif
+#if PKA_USE_NIST_P521
+	[PKA_NIST_P521] = {
+		.p_len = 521,
+		.n_len = 521,
+		.p  = (uint8_t[]){                                    0x01, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		.n  = (uint8_t[]){                                    0x01, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
+				  0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b,
+				  0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09, 0xa5, 0xd0,
+				  0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
+				  0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09},
+		.a_sign = 1,
+		.a  = (uint8_t[]){0x03},
+		.a_size = 1U,
+		.xg = (uint8_t[]){                                          0xc6,
+				  0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd,
+				  0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42,
+				  0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21,
+				  0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba,
+				  0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28,
+				  0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde,
+				  0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b,
+				  0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66},
+		.xg_size = 65U,
+		.yg = (uint8_t[]){                                    0x01, 0x18,
+				  0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04,
+				  0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
+				  0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68,
+				  0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c,
+				  0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
+				  0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
+				  0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40,
+				  0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50},
+		.yg_size = 66U,
+	},
+#endif
+};
+
+static struct stm32_pka_platdata pka_pdata;
+
+static int stm32_pka_parse_fdt(void)
+{
+	int node;
+	struct dt_node_info info;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	node = dt_get_node(&info, -1, DT_PKA_COMPAT);
+	if (node < 0) {
+		ERROR("No PKA entry in DT\n");
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if (info.status == DT_DISABLED) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if ((info.base == 0) || (info.clock < 0) || (info.reset < 0)) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	pka_pdata.base = (uintptr_t)info.base;
+	pka_pdata.clock_id = (unsigned long)info.clock;
+	pka_pdata.reset_id = (unsigned int)info.reset;
+
+	return 0;
+}
+
+static int pka_wait_bit(uintptr_t base, uint32_t bit)
+{
+	uint64_t timeout = timeout_init_us(PKA_TIMEOUT_US);
+
+	while ((mmio_read_32(base + _PKA_SR) & bit) != bit) {
+		if (timeout_elapsed(timeout)) {
+			WARN("timeout waiting %x\n", bit);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+
+}
+
+static void pka_disable(uintptr_t base)
+{
+	mmio_clrbits_32(base + _PKA_CR, _PKA_CR_EN);
+}
+
+static int pka_enable(uintptr_t base, uint32_t mode)
+{
+	/* Set mode and disable interrupts */
+	mmio_clrsetbits_32(base + _PKA_CR, _PKA_IT_MASK | _PKA_CR_MODE_MASK,
+			   _PKA_CR_MODE_MASK & (mode << _PKA_CR_MODE_SHIFT));
+
+	mmio_setbits_32(base + _PKA_CR, _PKA_CR_EN);
+
+	return pka_wait_bit(base, _PKA_SR_INITOK);
+}
+
+/*
+ * Data are already loaded in PKA internal RAM
+ * MODE is set
+ * We start process, and wait for its end.
+ */
+static int stm32_pka_process(uintptr_t base)
+{
+	mmio_setbits_32(base + _PKA_CR, _PKA_CR_START);
+
+	return pka_wait_bit(base, _PKA_IT_PROCEND);
+}
+
+/**
+ * @brief Write ECC operand to PKA RAM.
+ * @note  PKA expect to write u64 word, each u64 are: the least significant bit is
+ *        bit 0; the most significant bit is bit 63.
+ *        We write eo_nbw (ECC operand Size) u64, value that depends of the chosen
+ *        prime modulus length in bits.
+ *        First less signicant u64 is written to low address
+ *        Most significant u64 to higher address.
+ *        And at last address we write a u64(0x0)
+ * @note  This function doesn't only manage endianness (as bswap64 do), but also
+ *        complete most significant incomplete u64 with 0 (if data is not a u64
+ *        multiple), and fill u64 last address with 0.
+ * @param addr: PKA_RAM address to write the buffer 'data'
+ * @param data: is a BYTE list with most significant bytes first
+ * @param data_size: nb of byte in data
+ * @param eo_nbw: is ECC Operand size in 64bits word (including the extra 0)
+ *                (note it depends of the prime modulus length, not the data size)
+ * @retval 0 if OK.
+ *         -EINVAL if data_size and eo_nbw are inconsistent, ie data doesn't
+ *         fit in defined eo_nbw, or eo_nbw bigger than hardware limit.
+ */
+static int write_eo_data(uintptr_t addr, uint8_t *data, unsigned int data_size,
+			 unsigned int eo_nbw)
+{
+	uint32_t word_index;
+	int data_index;
+
+	if ((eo_nbw < OP_NBW_FROM_SIZE(data_size)) || (eo_nbw > MAX_EO_NBW)) {
+		return -EINVAL;
+	}
+
+	/* Fill value */
+	data_index = (int)data_size - 1;
+	for (word_index = 0U; word_index < eo_nbw; word_index++) {
+		uint64_t tmp = 0ULL;
+		unsigned int i = 0U;  /* index in the tmp U64 word */
+
+		/* Stop if end of tmp or end of data */
+		while ((i < sizeof(tmp)) && (data_index >= 0)) {
+			tmp |= (uint64_t)(data[data_index]) << (UINT8_LEN * i);
+			i++; /* Move byte index in current (u64)tmp */
+			data_index--; /* Move to just next most significat byte */
+		}
+
+		mmio_write_64(addr + word_index * sizeof(tmp), tmp);
+	}
+
+	return 0;
+}
+
+static unsigned int get_ecc_op_nbword(enum stm32_pka_ecdsa_curve_id cid)
+{
+	if (cid >= ARRAY_SIZE(curve_def)) {
+		ERROR("CID %u is out of boundaries\n", cid);
+		panic();
+	}
+
+	return OP_NBW_FROM_LEN(curve_def[cid].n_len);
+}
+
+static int stm32_pka_ecdsa_verif_configure_curve(uintptr_t base, enum stm32_pka_ecdsa_curve_id cid)
+{
+	int ret;
+	unsigned int eo_nbw = get_ecc_op_nbword(cid);
+
+	mmio_write_64(base + _PKA_RAM_N_LEN, curve_def[cid].n_len);
+	mmio_write_64(base + _PKA_RAM_P_LEN, curve_def[cid].p_len);
+	mmio_write_64(base + _PKA_RAM_A_SIGN, curve_def[cid].a_sign);
+
+	ret = write_eo_data(base + _PKA_RAM_A, curve_def[cid].a, curve_def[cid].a_size, eo_nbw);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = write_eo_data(base + _PKA_RAM_PRIME_N,
+			    curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN),
+			    eo_nbw);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = write_eo_data(base + _PKA_RAM_P, curve_def[cid].p,
+			    div_round_up(curve_def[cid].p_len, UINT8_LEN), eo_nbw);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = write_eo_data(base + _PKA_RAM_XG, curve_def[cid].xg, curve_def[cid].xg_size, eo_nbw);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = write_eo_data(base + _PKA_RAM_YG, curve_def[cid].yg, curve_def[cid].yg_size, eo_nbw);
+	if (ret < 0) {
+		return ret;
+	}
+
+	return 0;
+}
+
+static int stm32_pka_ecdsa_verif_check_return(uintptr_t base)
+{
+	uint64_t value;
+	uint32_t sr;
+
+	sr = mmio_read_32(base + _PKA_SR);
+	if ((sr & (_PKA_IT_OPERR | _PKA_IT_ADDRERR | _PKA_IT_RAMERR)) != 0) {
+		WARN("Detected error(s): %s%s%s\n",
+		     (sr & _PKA_IT_OPERR) ? "Operation " : "",
+		     (sr & _PKA_IT_ADDRERR) ? "Address " : "",
+		     (sr & _PKA_IT_RAMERR) ? "RAM" : "");
+		return -EINVAL;
+	}
+
+	value = mmio_read_64(base + _PKA_RAM_ECDSA_VERIFY);
+	if (value == _PKA_RAM_ECDSA_VERIFY_VALID) {
+		return 0;
+	}
+
+	if (value == _PKA_RAM_ECDSA_VERIFY_INVALID) {
+		return -EAUTH;
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * @brief Check if BigInt stored in data is 0
+ *
+ * @param data: a BYTE array with most significant bytes first
+ * @param size: data size
+ *
+ * @retval: true: if data represents a 0 value (ie all bytes == 0)
+ *          false: if data represents a non-zero value.
+ */
+static bool is_zero(uint8_t *data, unsigned int size)
+{
+	unsigned int i;
+
+	for (i = 0U; i < size; i++) {
+		if (data[i] != 0U) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/**
+ * @brief Compare two BigInt:
+ * @param xdata_a: a BYTE array with most significant bytes first
+ * @param size_a: nb of Byte of 'a'
+ * @param data_b: a BYTE array with most significant bytes first
+ * @param size_b: nb of Byte of 'b'
+ *
+ * @retval: true if data_a < data_b
+ *          false if data_a >= data_b
+ */
+static bool is_smaller(uint8_t *data_a, unsigned int size_a,
+		       uint8_t *data_b, unsigned int size_b)
+{
+	unsigned int i;
+
+	i = MAX(size_a, size_b) + 1U;
+	do {
+		uint8_t a, b;
+
+		i--;
+		if (size_a < i) {
+			a = 0U;
+		} else {
+			a = data_a[size_a - i];
+		}
+
+		if (size_b < i) {
+			b = 0U;
+		} else {
+			b = data_b[size_b - i];
+		}
+
+		if (a < b) {
+			return true;
+		}
+
+		if (a > b) {
+			return false;
+		}
+	} while (i != 0U);
+
+	return false;
+}
+
+static int stm32_pka_ecdsa_check_param(void *sig_r_ptr, unsigned int sig_r_size,
+				       void *sig_s_ptr, unsigned int sig_s_size,
+				       void *pk_x_ptr, unsigned int pk_x_size,
+				       void *pk_y_ptr, unsigned int pk_y_size,
+				       enum stm32_pka_ecdsa_curve_id cid)
+{
+	/* Public Key check */
+	/* Check Xq < p */
+	if (!is_smaller(pk_x_ptr, pk_x_size,
+			curve_def[cid].p, div_round_up(curve_def[cid].p_len, UINT8_LEN))) {
+		WARN("%s Xq < p inval\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Check Yq < p */
+	if (!is_smaller(pk_y_ptr, pk_y_size,
+			curve_def[cid].p, div_round_up(curve_def[cid].p_len, UINT8_LEN))) {
+		WARN("%s Yq < p inval\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Signature check */
+	/* Check 0 < r < n */
+	if (!is_smaller(sig_r_ptr, sig_r_size,
+			curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN)) &&
+	    !is_zero(sig_r_ptr, sig_r_size)) {
+		WARN("%s 0< r < n inval\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Check 0 < s < n */
+	if (!is_smaller(sig_s_ptr, sig_s_size,
+			curve_def[cid].n, div_round_up(curve_def[cid].n_len, UINT8_LEN)) &&
+	    !is_zero(sig_s_ptr, sig_s_size)) {
+		WARN("%s 0< s < n inval\n", __func__);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * @brief  Initialize the PKA driver.
+ * @param  None.
+ * @retval 0 if OK, negative value else.
+ */
+int stm32_pka_init(void)
+{
+	int err;
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+	uint32_t ver;
+	uint32_t id;
+#endif
+
+	err = stm32_pka_parse_fdt();
+	if (err != 0) {
+		return err;
+	}
+
+	clk_enable(pka_pdata.clock_id);
+
+	if (stm32mp_reset_assert((unsigned long)pka_pdata.reset_id, TIMEOUT_US_1MS) != 0) {
+		panic();
+	}
+
+	udelay(PKA_RESET_DELAY);
+	if (stm32mp_reset_deassert((unsigned long)pka_pdata.reset_id, TIMEOUT_US_1MS) != 0) {
+		panic();
+	}
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+	id = mmio_read_32(pka_pdata.base + _PKA_IPIDR);
+	ver = mmio_read_32(pka_pdata.base + _PKA_VERR);
+
+	VERBOSE("STM32 PKA[%x] V%u.%u\n", id,
+		(ver & _PKA_VERR_MAJREV_MASK) >> _PKA_VERR_MAJREV_SHIFT,
+		(ver & _PKA_VERR_MINREV_MASK) >> _PKA_VERR_MINREV_SHIFT);
+#endif
+	return 0;
+}
+
+int stm32_pka_ecdsa_verif(void *hash, unsigned int hash_size,
+			  void *sig_r_ptr, unsigned int sig_r_size,
+			  void *sig_s_ptr, unsigned int sig_s_size,
+			  void *pk_x_ptr, unsigned int pk_x_size,
+			  void *pk_y_ptr, unsigned int pk_y_size,
+			  enum stm32_pka_ecdsa_curve_id cid)
+{
+	int ret;
+	uintptr_t base = pka_pdata.base;
+	unsigned int eo_nbw = get_ecc_op_nbword(cid);
+
+	if ((hash == NULL) || (sig_r_ptr == NULL) || (sig_s_ptr == NULL) ||
+	    (pk_x_ptr == NULL) || (pk_y_ptr == NULL)) {
+		INFO("%s invalid input param\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = stm32_pka_ecdsa_check_param(sig_r_ptr, sig_r_size,
+					  sig_s_ptr, sig_s_size,
+					  pk_x_ptr, pk_x_size,
+					  pk_y_ptr, pk_y_size,
+					  cid);
+	if (ret < 0) {
+		INFO("%s check param error %d\n", __func__, ret);
+		goto out;
+	}
+
+	if ((mmio_read_32(base + _PKA_SR) & _PKA_SR_BUSY) == _PKA_SR_BUSY) {
+		INFO("%s busy\n", __func__);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/* Fill PKA RAM */
+	/* With curve id values */
+	ret = stm32_pka_ecdsa_verif_configure_curve(base, cid);
+	if (ret < 0) {
+		goto out;
+	}
+
+	/* With pubkey */
+	ret = write_eo_data(base + _PKA_RAM_XQ, pk_x_ptr, pk_x_size, eo_nbw);
+	if (ret < 0) {
+		goto out;
+	}
+
+	ret = write_eo_data(base + _PKA_RAM_YQ, pk_y_ptr, pk_y_size, eo_nbw);
+	if (ret < 0) {
+		goto out;
+	}
+
+	/* With hash */
+	ret = write_eo_data(base + _PKA_RAM_HASH_Z, hash, hash_size, eo_nbw);
+	if (ret < 0) {
+		goto out;
+	}
+
+	/* With signature */
+	ret = write_eo_data(base + _PKA_RAM_SIGN_R, sig_r_ptr, sig_r_size, eo_nbw);
+	if (ret < 0) {
+		goto out;
+	}
+
+	ret = write_eo_data(base + _PKA_RAM_SIGN_S, sig_s_ptr, sig_s_size, eo_nbw);
+	if (ret < 0) {
+		goto out;
+	}
+
+	/* Set mode to ecdsa signature verification */
+	ret = pka_enable(base, _PKA_CR_MODE_ECDSA_VERIF);
+	if (ret < 0) {
+		WARN("%s set mode pka error %d\n", __func__, ret);
+		goto out;
+	}
+
+	/* Start processing and wait end */
+	ret = stm32_pka_process(base);
+	if (ret < 0) {
+		WARN("%s process error %d\n", __func__, ret);
+		goto out;
+	}
+
+	/* Check return status */
+	ret = stm32_pka_ecdsa_verif_check_return(base);
+
+	/* Unset end proc */
+	mmio_setbits_32(base + _PKA_CLRFR, _PKA_IT_PROCEND);
+
+out:
+	/* Disable PKA (will stop all pending proccess and reset RAM) */
+	pka_disable(base);
+
+	return ret;
+}
diff --git a/drivers/st/crypto/stm32_rng.c b/drivers/st/crypto/stm32_rng.c
new file mode 100644
index 0000000..a9dc43f
--- /dev/null
+++ b/drivers/st/crypto/stm32_rng.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <drivers/clk.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32_rng.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#if STM32_RNG_VER == 2
+#define DT_RNG_COMPAT		"st,stm32-rng"
+#endif
+#if STM32_RNG_VER == 4
+#define DT_RNG_COMPAT		"st,stm32mp13-rng"
+#endif
+#define RNG_CR			0x00U
+#define RNG_SR			0x04U
+#define RNG_DR			0x08U
+
+#define RNG_CR_RNGEN		BIT(2)
+#define RNG_CR_IE		BIT(3)
+#define RNG_CR_CED		BIT(5)
+#define RNG_CR_CLKDIV		GENMASK(19, 16)
+#define RNG_CR_CLKDIV_SHIFT	16U
+#define RNG_CR_CONDRST		BIT(30)
+
+#define RNG_SR_DRDY		BIT(0)
+#define RNG_SR_CECS		BIT(1)
+#define RNG_SR_SECS		BIT(2)
+#define RNG_SR_CEIS		BIT(5)
+#define RNG_SR_SEIS		BIT(6)
+
+#define RNG_TIMEOUT_US		100000U
+#define RNG_TIMEOUT_STEP_US	10U
+
+#define TIMEOUT_US_1MS		1000U
+
+#define RNG_NIST_CONFIG_A	0x00F40F00U
+#define RNG_NIST_CONFIG_B	0x01801000U
+#define RNG_NIST_CONFIG_C	0x00F00D00U
+#define RNG_NIST_CONFIG_MASK	GENMASK(25, 8)
+
+#define RNG_MAX_NOISE_CLK_FREQ	48000000U
+
+struct stm32_rng_instance {
+	uintptr_t base;
+	unsigned long clock;
+};
+
+static struct stm32_rng_instance stm32_rng;
+
+static void seed_error_recovery(void)
+{
+	uint8_t i __maybe_unused;
+
+	/* Recommended by the SoC reference manual */
+	mmio_clrbits_32(stm32_rng.base + RNG_SR, RNG_SR_SEIS);
+	dmbsy();
+
+#if STM32_RNG_VER == 2
+	/* No Auto-reset on version 2, need to clean FIFO */
+	for (i = 12U; i != 0U; i--) {
+		(void)mmio_read_32(stm32_rng.base + RNG_DR);
+	}
+
+	dmbsy();
+#endif
+
+	if ((mmio_read_32(stm32_rng.base + RNG_SR) & RNG_SR_SEIS) != 0U) {
+		ERROR("RNG noise\n");
+		panic();
+	}
+}
+
+static uint32_t stm32_rng_clock_freq_restrain(void)
+{
+	unsigned long clock_rate;
+	uint32_t clock_div = 0U;
+
+	clock_rate = clk_get_rate(stm32_rng.clock);
+
+	/*
+	 * Get the exponent to apply on the CLKDIV field in RNG_CR register
+	 * No need to handle the case when clock-div > 0xF as it is physically
+	 * impossible
+	 */
+	while ((clock_rate >> clock_div) > RNG_MAX_NOISE_CLK_FREQ) {
+		clock_div++;
+	}
+
+	VERBOSE("RNG clk rate : %lu\n", clk_get_rate(stm32_rng.clock) >> clock_div);
+
+	return clock_div;
+}
+
+static int stm32_rng_enable(void)
+{
+	uint32_t sr;
+	uint64_t timeout;
+	uint32_t clock_div __maybe_unused;
+
+#if STM32_RNG_VER == 2
+	mmio_write_32(stm32_rng.base + RNG_CR, RNG_CR_RNGEN | RNG_CR_CED);
+#endif
+#if STM32_RNG_VER == 4
+	/* Reset internal block and disable CED bit */
+	clock_div = stm32_rng_clock_freq_restrain();
+
+	/* Update configuration fields */
+	mmio_clrsetbits_32(stm32_rng.base + RNG_CR, RNG_NIST_CONFIG_MASK,
+			   RNG_NIST_CONFIG_A | RNG_CR_CONDRST | RNG_CR_CED);
+
+	mmio_clrsetbits_32(stm32_rng.base + RNG_CR, RNG_CR_CLKDIV,
+			   (clock_div << RNG_CR_CLKDIV_SHIFT));
+
+	mmio_clrsetbits_32(stm32_rng.base + RNG_CR, RNG_CR_CONDRST, RNG_CR_RNGEN);
+#endif
+	timeout = timeout_init_us(RNG_TIMEOUT_US);
+	sr = mmio_read_32(stm32_rng.base + RNG_SR);
+	while ((sr & RNG_SR_DRDY) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			WARN("Timeout waiting\n");
+			return -ETIMEDOUT;
+		}
+
+		if ((sr & (RNG_SR_SECS | RNG_SR_SEIS)) != 0U) {
+			seed_error_recovery();
+			timeout = timeout_init_us(RNG_TIMEOUT_US);
+		}
+
+		udelay(RNG_TIMEOUT_STEP_US);
+		sr = mmio_read_32(stm32_rng.base + RNG_SR);
+	}
+
+	VERBOSE("Init RNG done\n");
+
+	return 0;
+}
+
+/*
+ * stm32_rng_read - Read a number of random bytes from RNG
+ * out: pointer to the output buffer
+ * size: number of bytes to be read
+ * Return 0 on success, non-0 on failure
+ */
+int stm32_rng_read(uint8_t *out, uint32_t size)
+{
+	uint8_t *buf = out;
+	size_t len = size;
+	int nb_tries;
+	uint32_t data32;
+	int rc = 0;
+	unsigned int count;
+
+	if (stm32_rng.base == 0U) {
+		return -EPERM;
+	}
+
+	while (len != 0U) {
+		nb_tries = RNG_TIMEOUT_US / RNG_TIMEOUT_STEP_US;
+		do {
+			uint32_t status = mmio_read_32(stm32_rng.base + RNG_SR);
+
+			if ((status & (RNG_SR_SECS | RNG_SR_SEIS)) != 0U) {
+				seed_error_recovery();
+			}
+
+			udelay(RNG_TIMEOUT_STEP_US);
+			nb_tries--;
+			if (nb_tries == 0) {
+				rc = -ETIMEDOUT;
+				goto bail;
+			}
+		} while ((mmio_read_32(stm32_rng.base + RNG_SR) &
+			  RNG_SR_DRDY) == 0U);
+
+		count = 4U;
+		while (len != 0U) {
+			data32 = mmio_read_32(stm32_rng.base + RNG_DR);
+			count--;
+
+			memcpy(buf, &data32, MIN(len, sizeof(uint32_t)));
+			buf += MIN(len, sizeof(uint32_t));
+			len -= MIN(len, sizeof(uint32_t));
+
+			if (count == 0U) {
+				break;
+			}
+		}
+	}
+
+bail:
+	if (rc != 0) {
+		memset(out, 0, buf - out);
+	}
+
+	return rc;
+}
+
+/*
+ * stm32_rng_init: Initialize rng from DT
+ * return 0 on success, negative value on failure
+ */
+int stm32_rng_init(void)
+{
+	void *fdt;
+	struct dt_node_info dt_rng;
+	int node;
+
+	if (stm32_rng.base != 0U) {
+		/* Driver is already initialized */
+		return 0;
+	}
+
+	if (fdt_get_address(&fdt) == 0) {
+		panic();
+	}
+
+	node = dt_get_node(&dt_rng, -1, DT_RNG_COMPAT);
+	if (node < 0) {
+		return 0;
+	}
+
+	if (dt_rng.status == DT_DISABLED) {
+		return 0;
+	}
+
+	assert(dt_rng.base != 0U);
+
+	stm32_rng.base = dt_rng.base;
+
+	if (dt_rng.clock < 0) {
+		panic();
+	}
+
+	stm32_rng.clock = (unsigned long)dt_rng.clock;
+	clk_enable(stm32_rng.clock);
+
+	if (dt_rng.reset >= 0) {
+		int ret;
+
+		ret = stm32mp_reset_assert((unsigned long)dt_rng.reset,
+					   TIMEOUT_US_1MS);
+		if (ret != 0) {
+			panic();
+		}
+
+		udelay(20);
+
+		ret = stm32mp_reset_deassert((unsigned long)dt_rng.reset,
+					     TIMEOUT_US_1MS);
+		if (ret != 0) {
+			panic();
+		}
+	}
+
+	return stm32_rng_enable();
+}
diff --git a/drivers/st/crypto/stm32_saes.c b/drivers/st/crypto/stm32_saes.c
new file mode 100644
index 0000000..f4da571
--- /dev/null
+++ b/drivers/st/crypto/stm32_saes.c
@@ -0,0 +1,903 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <endian.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <drivers/clk.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32_saes.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#define UINT8_BIT			8U
+#define AES_BLOCK_SIZE_BIT		128U
+#define AES_BLOCK_SIZE			(AES_BLOCK_SIZE_BIT / UINT8_BIT)
+
+#define AES_KEYSIZE_128			16U
+#define AES_KEYSIZE_256			32U
+#define AES_IVSIZE			16U
+
+/* SAES control register */
+#define _SAES_CR			0x0U
+/* SAES status register */
+#define _SAES_SR			0x04U
+/* SAES data input register */
+#define _SAES_DINR			0x08U
+/* SAES data output register */
+#define _SAES_DOUTR			0x0CU
+/* SAES key registers [0-3] */
+#define _SAES_KEYR0			0x10U
+#define _SAES_KEYR1			0x14U
+#define _SAES_KEYR2			0x18U
+#define _SAES_KEYR3			0x1CU
+/* SAES initialization vector registers [0-3] */
+#define _SAES_IVR0			0x20U
+#define _SAES_IVR1			0x24U
+#define _SAES_IVR2			0x28U
+#define _SAES_IVR3			0x2CU
+/* SAES key registers [4-7] */
+#define _SAES_KEYR4			0x30U
+#define _SAES_KEYR5			0x34U
+#define _SAES_KEYR6			0x38U
+#define _SAES_KEYR7			0x3CU
+/* SAES suspend registers [0-7] */
+#define _SAES_SUSPR0			0x40U
+#define _SAES_SUSPR1			0x44U
+#define _SAES_SUSPR2			0x48U
+#define _SAES_SUSPR3			0x4CU
+#define _SAES_SUSPR4			0x50U
+#define _SAES_SUSPR5			0x54U
+#define _SAES_SUSPR6			0x58U
+#define _SAES_SUSPR7			0x5CU
+/* SAES Interrupt Enable Register */
+#define _SAES_IER			0x300U
+/* SAES Interrupt Status Register */
+#define _SAES_ISR			0x304U
+/* SAES Interrupt Clear Register */
+#define _SAES_ICR			0x308U
+
+/* SAES control register fields */
+#define _SAES_CR_RESET_VALUE		0x0U
+#define _SAES_CR_IPRST			BIT(31)
+#define _SAES_CR_KEYSEL_MASK		GENMASK(30, 28)
+#define _SAES_CR_KEYSEL_SHIFT		28U
+#define _SAES_CR_KEYSEL_SOFT		0x0U
+#define _SAES_CR_KEYSEL_DHUK		0x1U
+#define _SAES_CR_KEYSEL_BHK		0x2U
+#define _SAES_CR_KEYSEL_BHU_XOR_BH_K	0x4U
+#define _SAES_CR_KEYSEL_TEST		0x7U
+#define _SAES_CR_KSHAREID_MASK		GENMASK(27, 26)
+#define _SAES_CR_KSHAREID_SHIFT		26U
+#define _SAES_CR_KSHAREID_CRYP		0x0U
+#define _SAES_CR_KEYMOD_MASK		GENMASK(25, 24)
+#define _SAES_CR_KEYMOD_SHIFT		24U
+#define _SAES_CR_KEYMOD_NORMAL		0x0U
+#define _SAES_CR_KEYMOD_WRAPPED		0x1U
+#define _SAES_CR_KEYMOD_SHARED		0x2U
+#define _SAES_CR_NPBLB_MASK		GENMASK(23, 20)
+#define _SAES_CR_NPBLB_SHIFT		20U
+#define _SAES_CR_KEYPROT		BIT(19)
+#define _SAES_CR_KEYSIZE		BIT(18)
+#define _SAES_CR_GCMPH_MASK		GENMASK(14, 13)
+#define _SAES_CR_GCMPH_SHIFT		13U
+#define _SAES_CR_GCMPH_INIT		0U
+#define _SAES_CR_GCMPH_HEADER		1U
+#define _SAES_CR_GCMPH_PAYLOAD		2U
+#define _SAES_CR_GCMPH_FINAL		3U
+#define _SAES_CR_DMAOUTEN		BIT(12)
+#define _SAES_CR_DMAINEN		BIT(11)
+#define _SAES_CR_CHMOD_MASK		(BIT(16) | GENMASK(6, 5))
+#define _SAES_CR_CHMOD_SHIFT		5U
+#define _SAES_CR_CHMOD_ECB		0x0U
+#define _SAES_CR_CHMOD_CBC		0x1U
+#define _SAES_CR_CHMOD_CTR		0x2U
+#define _SAES_CR_CHMOD_GCM		0x3U
+#define _SAES_CR_CHMOD_GMAC		0x3U
+#define _SAES_CR_CHMOD_CCM		0x800U
+#define _SAES_CR_MODE_MASK		GENMASK(4, 3)
+#define _SAES_CR_MODE_SHIFT		3U
+#define _SAES_CR_MODE_ENC		0U
+#define _SAES_CR_MODE_KEYPREP		1U
+#define _SAES_CR_MODE_DEC		2U
+#define _SAES_CR_DATATYPE_MASK		GENMASK(2, 1)
+#define _SAES_CR_DATATYPE_SHIFT		1U
+#define _SAES_CR_DATATYPE_NONE		0U
+#define _SAES_CR_DATATYPE_HALF_WORD	1U
+#define _SAES_CR_DATATYPE_BYTE		2U
+#define _SAES_CR_DATATYPE_BIT		3U
+#define _SAES_CR_EN			BIT(0)
+
+/* SAES status register fields */
+#define _SAES_SR_KEYVALID		BIT(7)
+#define _SAES_SR_BUSY			BIT(3)
+#define _SAES_SR_WRERR			BIT(2)
+#define _SAES_SR_RDERR			BIT(1)
+#define _SAES_SR_CCF			BIT(0)
+
+/* SAES interrupt registers fields */
+#define _SAES_I_RNG_ERR			BIT(3)
+#define _SAES_I_KEY_ERR			BIT(2)
+#define _SAES_I_RW_ERR			BIT(1)
+#define _SAES_I_CC			BIT(0)
+
+#define SAES_TIMEOUT_US			100000U
+#define TIMEOUT_US_1MS			1000U
+#define SAES_RESET_DELAY		20U
+
+#define IS_CHAINING_MODE(mod, cr) \
+	(((cr) & _SAES_CR_CHMOD_MASK) == (_SAES_CR_CHMOD_##mod << _SAES_CR_CHMOD_SHIFT))
+
+#define SET_CHAINING_MODE(mod, cr) \
+	mmio_clrsetbits_32((cr), _SAES_CR_CHMOD_MASK, _SAES_CR_CHMOD_##mod << _SAES_CR_CHMOD_SHIFT)
+
+static struct stm32_saes_platdata saes_pdata;
+
+static int stm32_saes_parse_fdt(struct stm32_saes_platdata *pdata)
+{
+	int node;
+	struct dt_node_info info;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	node = dt_get_node(&info, -1, DT_SAES_COMPAT);
+	if (node < 0) {
+		ERROR("No SAES entry in DT\n");
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if (info.status == DT_DISABLED) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if ((info.base == 0U) || (info.clock < 0) || (info.reset < 0)) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	pdata->base = (uintptr_t)info.base;
+	pdata->clock_id = (unsigned long)info.clock;
+	pdata->reset_id = (unsigned int)info.reset;
+
+	return 0;
+}
+
+static bool does_chaining_mode_need_iv(uint32_t cr)
+{
+	return !(IS_CHAINING_MODE(ECB, cr));
+}
+
+static bool is_encrypt(uint32_t cr)
+{
+	return (cr & _SAES_CR_MODE_MASK) == (_SAES_CR_MODE_ENC << _SAES_CR_MODE_SHIFT);
+}
+
+static bool is_decrypt(uint32_t cr)
+{
+	return (cr & _SAES_CR_MODE_MASK) == (_SAES_CR_MODE_DEC << _SAES_CR_MODE_SHIFT);
+}
+
+static int wait_computation_completed(uintptr_t base)
+{
+	uint64_t timeout = timeout_init_us(SAES_TIMEOUT_US);
+
+	while ((mmio_read_32(base + _SAES_SR) & _SAES_SR_CCF) != _SAES_SR_CCF) {
+		if (timeout_elapsed(timeout)) {
+			WARN("%s: timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void clear_computation_completed(uintptr_t base)
+{
+	mmio_setbits_32(base + _SAES_ICR, _SAES_I_CC);
+}
+
+static int saes_start(struct stm32_saes_context *ctx)
+{
+	uint64_t timeout;
+
+	/* Reset IP */
+	mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_IPRST);
+	udelay(SAES_RESET_DELAY);
+	mmio_clrbits_32(ctx->base + _SAES_CR, _SAES_CR_IPRST);
+
+	timeout = timeout_init_us(SAES_TIMEOUT_US);
+	while ((mmio_read_32(ctx->base + _SAES_SR) & _SAES_SR_BUSY) == _SAES_SR_BUSY) {
+		if (timeout_elapsed(timeout)) {
+			WARN("%s: timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void saes_end(struct stm32_saes_context *ctx, int prev_error)
+{
+	if (prev_error != 0) {
+		/* Reset IP */
+		mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_IPRST);
+		udelay(SAES_RESET_DELAY);
+		mmio_clrbits_32(ctx->base + _SAES_CR, _SAES_CR_IPRST);
+	}
+
+	/* Disable the SAES peripheral */
+	mmio_clrbits_32(ctx->base + _SAES_CR, _SAES_CR_EN);
+}
+
+static void saes_write_iv(struct stm32_saes_context *ctx)
+{
+	/* If chaining mode need to restore IV */
+	if (does_chaining_mode_need_iv(ctx->cr)) {
+		uint8_t i;
+
+		/* Restore the _SAES_IVRx */
+		for (i = 0U; i < AES_IVSIZE / sizeof(uint32_t); i++) {
+			mmio_write_32(ctx->base + _SAES_IVR0 + i * sizeof(uint32_t), ctx->iv[i]);
+		}
+	}
+
+}
+
+static void saes_write_key(struct stm32_saes_context *ctx)
+{
+	/* Restore the _SAES_KEYRx if SOFTWARE key */
+	if ((ctx->cr & _SAES_CR_KEYSEL_MASK) == (_SAES_CR_KEYSEL_SOFT << _SAES_CR_KEYSEL_SHIFT)) {
+		uint8_t i;
+
+		for (i = 0U; i < AES_KEYSIZE_128 / sizeof(uint32_t); i++) {
+			mmio_write_32(ctx->base + _SAES_KEYR0 + i * sizeof(uint32_t), ctx->key[i]);
+		}
+
+		if ((ctx->cr & _SAES_CR_KEYSIZE) == _SAES_CR_KEYSIZE) {
+			for (i = 0U; i < (AES_KEYSIZE_256 / 2U) / sizeof(uint32_t); i++) {
+				mmio_write_32(ctx->base + _SAES_KEYR4 + i * sizeof(uint32_t),
+					      ctx->key[i + 4U]);
+			}
+		}
+	}
+}
+
+static int saes_prepare_key(struct stm32_saes_context *ctx)
+{
+	/* Disable the SAES peripheral */
+	mmio_clrbits_32(ctx->base + _SAES_CR, _SAES_CR_EN);
+
+	/* Set key size */
+	if ((ctx->cr & _SAES_CR_KEYSIZE) != 0U) {
+		mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_KEYSIZE);
+	} else {
+		mmio_clrbits_32(ctx->base + _SAES_CR, _SAES_CR_KEYSIZE);
+	}
+
+	saes_write_key(ctx);
+
+	/* For ECB/CBC decryption, key preparation mode must be selected to populate the key */
+	if ((IS_CHAINING_MODE(ECB, ctx->cr) || IS_CHAINING_MODE(CBC, ctx->cr)) &&
+	    is_decrypt(ctx->cr)) {
+		int ret;
+
+		/* Select Mode 2 */
+		mmio_clrsetbits_32(ctx->base + _SAES_CR, _SAES_CR_MODE_MASK,
+				   _SAES_CR_MODE_KEYPREP << _SAES_CR_MODE_SHIFT);
+
+		/* Enable SAES */
+		mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_EN);
+
+		/* Wait Computation completed */
+		ret = wait_computation_completed(ctx->base);
+		if (ret != 0) {
+			return ret;
+		}
+
+		clear_computation_completed(ctx->base);
+
+		/* Set Mode 3 */
+		mmio_clrsetbits_32(ctx->base + _SAES_CR, _SAES_CR_MODE_MASK,
+				   _SAES_CR_MODE_DEC << _SAES_CR_MODE_SHIFT);
+	}
+
+	return 0;
+}
+
+static int save_context(struct stm32_saes_context *ctx)
+{
+	if ((mmio_read_32(ctx->base + _SAES_SR) & _SAES_SR_CCF) != 0U) {
+		/* Device should not be in a processing phase */
+		return -EINVAL;
+	}
+
+	/* Save CR */
+	ctx->cr = mmio_read_32(ctx->base + _SAES_CR);
+
+	/* If chaining mode need to save current IV */
+	if (does_chaining_mode_need_iv(ctx->cr)) {
+		uint8_t i;
+
+		/* Save IV */
+		for (i = 0U; i < AES_IVSIZE / sizeof(uint32_t); i++) {
+			ctx->iv[i] = mmio_read_32(ctx->base + _SAES_IVR0 + i * sizeof(uint32_t));
+		}
+	}
+
+	/* Disable the SAES peripheral */
+	mmio_clrbits_32(ctx->base + _SAES_CR, _SAES_CR_EN);
+
+	return 0;
+}
+
+/* To resume the processing of a message */
+static int restore_context(struct stm32_saes_context *ctx)
+{
+	int ret;
+
+	/* IP should be disabled */
+	if ((mmio_read_32(ctx->base + _SAES_CR) & _SAES_CR_EN) != 0U) {
+		VERBOSE("%s: Device is still enabled\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Reset internal state */
+	mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_IPRST);
+
+	/* Restore the _SAES_CR */
+	mmio_write_32(ctx->base + _SAES_CR, ctx->cr);
+
+	/* Preparation decrypt key */
+	ret = saes_prepare_key(ctx);
+	if (ret != 0) {
+		return ret;
+	}
+
+	saes_write_iv(ctx);
+
+	/* Enable the SAES peripheral */
+	mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_EN);
+
+	return 0;
+}
+
+/**
+ * @brief Initialize SAES driver.
+ * @param None.
+ * @retval 0 if OK; negative value else.
+ */
+int stm32_saes_driver_init(void)
+{
+	int err;
+
+	err = stm32_saes_parse_fdt(&saes_pdata);
+	if (err != 0) {
+		return err;
+	}
+
+	clk_enable(saes_pdata.clock_id);
+	if (stm32mp_reset_assert(saes_pdata.reset_id, TIMEOUT_US_1MS) != 0) {
+		panic();
+	}
+
+	udelay(SAES_RESET_DELAY);
+	if (stm32mp_reset_deassert(saes_pdata.reset_id, TIMEOUT_US_1MS) != 0) {
+		panic();
+	}
+
+	return 0;
+}
+
+/**
+ * @brief Start a AES computation.
+ * @param ctx: SAES process context
+ * @param is_dec: true if decryption, false if encryption
+ * @param ch_mode: define the chaining mode
+ * @param key_select: define where the key comes from.
+ * @param key: pointer to key (if key_select is KEY_SOFT, else unused)
+ * @param key_size: key size
+ * @param iv: pointer to initialization vectore (unsed if ch_mode is ECB)
+ * @param iv_size: iv size
+ * @note this function doesn't access to hardware but store in ctx the values
+ *
+ * @retval 0 if OK; negative value else.
+ */
+int stm32_saes_init(struct stm32_saes_context *ctx, bool is_dec,
+		    enum stm32_saes_chaining_mode ch_mode, enum stm32_saes_key_selection key_select,
+		    const void *key, size_t key_size, const void *iv, size_t iv_size)
+{
+	unsigned int i;
+	const uint32_t *iv_u32;
+	const uint32_t *key_u32;
+
+	ctx->assoc_len = 0U;
+	ctx->load_len = 0U;
+
+	ctx->base = saes_pdata.base;
+	ctx->cr = _SAES_CR_RESET_VALUE;
+
+	/* We want buffer to be u32 aligned */
+	assert((uintptr_t)key % __alignof__(uint32_t) == 0);
+	assert((uintptr_t)iv % __alignof__(uint32_t) == 0);
+
+	iv_u32 = iv;
+	key_u32 = key;
+
+	if (is_dec) {
+		/* Save Mode 3 = decrypt */
+		mmio_clrsetbits_32((uintptr_t)&(ctx->cr), _SAES_CR_MODE_MASK,
+				   _SAES_CR_MODE_DEC << _SAES_CR_MODE_SHIFT);
+	} else {
+		/* Save Mode 1 = crypt */
+		mmio_clrsetbits_32((uintptr_t)&(ctx->cr), _SAES_CR_MODE_MASK,
+				   _SAES_CR_MODE_ENC << _SAES_CR_MODE_SHIFT);
+	}
+
+	/* Save chaining mode */
+	switch (ch_mode) {
+	case STM32_SAES_MODE_ECB:
+		SET_CHAINING_MODE(ECB, (uintptr_t)&(ctx->cr));
+		break;
+	case STM32_SAES_MODE_CBC:
+		SET_CHAINING_MODE(CBC, (uintptr_t)&(ctx->cr));
+		break;
+	case STM32_SAES_MODE_CTR:
+		SET_CHAINING_MODE(CTR, (uintptr_t)&(ctx->cr));
+		break;
+	case STM32_SAES_MODE_GCM:
+		SET_CHAINING_MODE(GCM, (uintptr_t)&(ctx->cr));
+		break;
+	case STM32_SAES_MODE_CCM:
+		SET_CHAINING_MODE(CCM, (uintptr_t)&(ctx->cr));
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* We will use HW Byte swap (_SAES_CR_DATATYPE_BYTE) for data.
+	 * so we won't need to
+	 * htobe32(data) before write to DINR
+	 * nor
+	 * be32toh after reading from DOUTR
+	 *
+	 * But note that wrap key only accept _SAES_CR_DATATYPE_NONE
+	 */
+	mmio_clrsetbits_32((uintptr_t)&(ctx->cr), _SAES_CR_DATATYPE_MASK,
+			   _SAES_CR_DATATYPE_BYTE << _SAES_CR_DATATYPE_SHIFT);
+
+	/* Configure keysize */
+	switch (key_size) {
+	case AES_KEYSIZE_128:
+		mmio_clrbits_32((uintptr_t)&(ctx->cr), _SAES_CR_KEYSIZE);
+		break;
+	case AES_KEYSIZE_256:
+		mmio_setbits_32((uintptr_t)&(ctx->cr), _SAES_CR_KEYSIZE);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Configure key */
+	switch (key_select) {
+	case STM32_SAES_KEY_SOFT:
+		mmio_clrsetbits_32((uintptr_t)&(ctx->cr), _SAES_CR_KEYSEL_MASK,
+				   _SAES_CR_KEYSEL_SOFT << _SAES_CR_KEYSEL_SHIFT);
+		/* Save key */
+		switch (key_size) {
+		case AES_KEYSIZE_128:
+			/* First 16 bytes == 4 u32 */
+			for (i = 0U; i < AES_KEYSIZE_128 / sizeof(uint32_t); i++) {
+				mmio_write_32((uintptr_t)(ctx->key + i), htobe32(key_u32[3 - i]));
+				/* /!\ we save the key in HW byte order
+				 * and word order : key[i] is for _SAES_KEYRi
+				 */
+			}
+			break;
+		case AES_KEYSIZE_256:
+			for (i = 0U; i < AES_KEYSIZE_256 / sizeof(uint32_t); i++) {
+				mmio_write_32((uintptr_t)(ctx->key + i), htobe32(key_u32[7 - i]));
+				/* /!\ we save the key in HW byte order
+				 * and word order : key[i] is for _SAES_KEYRi
+				 */
+			}
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		break;
+	case STM32_SAES_KEY_DHU:
+		mmio_clrsetbits_32((uintptr_t)&(ctx->cr), _SAES_CR_KEYSEL_MASK,
+				   _SAES_CR_KEYSEL_DHUK << _SAES_CR_KEYSEL_SHIFT);
+		break;
+	case STM32_SAES_KEY_BH:
+		mmio_clrsetbits_32((uintptr_t)&(ctx->cr), _SAES_CR_KEYSEL_MASK,
+				   _SAES_CR_KEYSEL_BHK << _SAES_CR_KEYSEL_SHIFT);
+		break;
+	case STM32_SAES_KEY_BHU_XOR_BH:
+		mmio_clrsetbits_32((uintptr_t)&(ctx->cr), _SAES_CR_KEYSEL_MASK,
+				   _SAES_CR_KEYSEL_BHU_XOR_BH_K << _SAES_CR_KEYSEL_SHIFT);
+		break;
+	case STM32_SAES_KEY_WRAPPED:
+		mmio_clrsetbits_32((uintptr_t)&(ctx->cr), _SAES_CR_KEYSEL_MASK,
+				   _SAES_CR_KEYSEL_SOFT << _SAES_CR_KEYSEL_SHIFT);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	/* Save IV */
+	if (ch_mode != STM32_SAES_MODE_ECB) {
+		if ((iv == NULL) || (iv_size != AES_IVSIZE)) {
+			return -EINVAL;
+		}
+
+		for (i = 0U; i < AES_IVSIZE / sizeof(uint32_t); i++) {
+			mmio_write_32((uintptr_t)(ctx->iv + i), htobe32(iv_u32[3 - i]));
+			/* /!\ We save the iv in HW byte order */
+		}
+	}
+
+	return saes_start(ctx);
+}
+
+/**
+ * @brief Update (or start) a AES authentificate process of associated data (CCM or GCM).
+ * @param ctx: SAES process context
+ * @param last_block: true if last assoc data block
+ * @param data: pointer to associated data
+ * @param data_size: data size
+ *
+ * @retval 0 if OK; negative value else.
+ */
+int stm32_saes_update_assodata(struct stm32_saes_context *ctx, bool last_block,
+			       uint8_t *data, size_t data_size)
+{
+	int ret;
+	uint32_t *data_u32;
+	unsigned int i = 0U;
+
+	/* We want buffers to be u32 aligned */
+	assert((uintptr_t)data % __alignof__(uint32_t) == 0);
+	data_u32 = (uint32_t *)data;
+
+	/* Init phase */
+	ret = restore_context(ctx);
+	if (ret != 0) {
+		goto out;
+	}
+
+	ret = wait_computation_completed(ctx->base);
+	if (ret != 0) {
+		return ret;
+	}
+
+	clear_computation_completed(ctx->base);
+
+	if ((data == NULL) || (data_size == 0U)) {
+		/* No associated data */
+		/* ret already = 0 */
+		goto out;
+	}
+
+	/* There is an header/associated data phase */
+	mmio_clrsetbits_32(ctx->base + _SAES_CR, _SAES_CR_GCMPH_MASK,
+			   _SAES_CR_GCMPH_HEADER << _SAES_CR_GCMPH_SHIFT);
+
+	/* Enable the SAES peripheral */
+	mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_EN);
+
+	while (i < round_down(data_size, AES_BLOCK_SIZE)) {
+		unsigned int w; /* Word index */
+
+		w = i / sizeof(uint32_t);
+		/* No need to htobe() as we configure the HW to swap bytes */
+		mmio_write_32(ctx->base + _SAES_DINR, data_u32[w + 0U]);
+		mmio_write_32(ctx->base + _SAES_DINR, data_u32[w + 1U]);
+		mmio_write_32(ctx->base + _SAES_DINR, data_u32[w + 2U]);
+		mmio_write_32(ctx->base + _SAES_DINR, data_u32[w + 3U]);
+
+		ret = wait_computation_completed(ctx->base);
+		if (ret != 0) {
+			goto out;
+		}
+
+		clear_computation_completed(ctx->base);
+
+		/* Process next block */
+		i += AES_BLOCK_SIZE;
+		ctx->assoc_len += AES_BLOCK_SIZE_BIT;
+	}
+
+	/* Manage last block if not a block size multiple */
+	if ((last_block) && (i < data_size)) {
+		/* We don't manage unaligned last block yet */
+		ret = -ENODEV;
+		goto out;
+	}
+
+out:
+	if (ret != 0) {
+		saes_end(ctx, ret);
+	}
+
+	return ret;
+}
+
+/**
+ * @brief Update (or start) a AES authenticate and de/encrypt with payload data (CCM or GCM).
+ * @param ctx: SAES process context
+ * @param last_block: true if last payload data block
+ * @param data_in: pointer to payload
+ * @param data_out: pointer where to save de/encrypted payload
+ * @param data_size: payload size
+ *
+ * @retval 0 if OK; negative value else.
+ */
+int stm32_saes_update_load(struct stm32_saes_context *ctx, bool last_block,
+			   uint8_t *data_in, uint8_t *data_out, size_t data_size)
+{
+	int ret = 0;
+	uint32_t *data_in_u32;
+	uint32_t *data_out_u32;
+	unsigned int i = 0U;
+	uint32_t prev_cr;
+
+	/* We want buffers to be u32 aligned */
+	assert((uintptr_t)data_in % __alignof__(uint32_t) == 0);
+	assert((uintptr_t)data_out % __alignof__(uint32_t) == 0);
+	data_in_u32 = (uint32_t *)data_in;
+	data_out_u32 = (uint32_t *)data_out;
+
+	prev_cr = mmio_read_32(ctx->base + _SAES_CR);
+
+	if ((data_in == NULL) || (data_size == 0U)) {
+		/* there is no data */
+		goto out;
+	}
+
+	/* There is a load phase */
+	mmio_clrsetbits_32(ctx->base + _SAES_CR, _SAES_CR_GCMPH_MASK,
+			   _SAES_CR_GCMPH_PAYLOAD << _SAES_CR_GCMPH_SHIFT);
+
+	if ((prev_cr & _SAES_CR_GCMPH_MASK) ==
+	    (_SAES_CR_GCMPH_INIT << _SAES_CR_GCMPH_SHIFT)) {
+		/* Still in initialization phase, no header
+		 * We need to enable the SAES peripheral
+		 */
+		mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_EN);
+	}
+
+	while (i < round_down(data_size, AES_BLOCK_SIZE)) {
+		unsigned int w; /* Word index */
+
+		w = i / sizeof(uint32_t);
+		/* No need to htobe() as we configure the HW to swap bytes */
+		mmio_write_32(ctx->base + _SAES_DINR, data_in_u32[w + 0U]);
+		mmio_write_32(ctx->base + _SAES_DINR, data_in_u32[w + 1U]);
+		mmio_write_32(ctx->base + _SAES_DINR, data_in_u32[w + 2U]);
+		mmio_write_32(ctx->base + _SAES_DINR, data_in_u32[w + 3U]);
+
+		ret = wait_computation_completed(ctx->base);
+		if (ret != 0) {
+			goto out;
+		}
+
+		/* No need to htobe() as we configure the HW to swap bytes */
+		data_out_u32[w + 0U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+		data_out_u32[w + 1U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+		data_out_u32[w + 2U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+		data_out_u32[w + 3U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+
+		clear_computation_completed(ctx->base);
+
+		/* Process next block */
+		i += AES_BLOCK_SIZE;
+		ctx->load_len += AES_BLOCK_SIZE_BIT;
+	}
+	/* Manage last block if not a block size multiple */
+	if ((last_block) && (i < data_size)) {
+		uint32_t block_in[AES_BLOCK_SIZE / sizeof(uint32_t)] = {0};
+		uint32_t block_out[AES_BLOCK_SIZE / sizeof(uint32_t)] = {0};
+
+		memcpy(block_in, data_in + i, data_size - i);
+
+		/* No need to htobe() as we configure the HW to swap bytes */
+		mmio_write_32(ctx->base + _SAES_DINR, block_in[0U]);
+		mmio_write_32(ctx->base + _SAES_DINR, block_in[1U]);
+		mmio_write_32(ctx->base + _SAES_DINR, block_in[2U]);
+		mmio_write_32(ctx->base + _SAES_DINR, block_in[3U]);
+
+		ret = wait_computation_completed(ctx->base);
+		if (ret != 0) {
+			VERBOSE("%s %d\n", __func__, __LINE__);
+			goto out;
+		}
+
+		/* No need to htobe() as we configure the HW to swap bytes */
+		block_out[0U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+		block_out[1U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+		block_out[2U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+		block_out[3U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+
+		clear_computation_completed(ctx->base);
+
+		memcpy(data_out + i, block_out, data_size - i);
+
+		ctx->load_len += (data_size - i) * UINT8_BIT;
+	}
+
+out:
+	if (ret != 0) {
+		saes_end(ctx, ret);
+	}
+
+	return ret;
+}
+
+/**
+ * @brief Get authentication tag for AES authenticated algorithms (CCM or GCM).
+ * @param ctx: SAES process context
+ * @param tag: pointer where to save the tag
+ * @param data_size: tag size
+ *
+ * @retval 0 if OK; negative value else.
+ */
+int stm32_saes_final(struct stm32_saes_context *ctx, uint8_t *tag,
+		     size_t tag_size)
+{
+	int ret;
+	uint32_t tag_u32[4];
+	uint32_t prev_cr;
+
+	prev_cr = mmio_read_32(ctx->base + _SAES_CR);
+
+	mmio_clrsetbits_32(ctx->base + _SAES_CR, _SAES_CR_GCMPH_MASK,
+			   _SAES_CR_GCMPH_FINAL << _SAES_CR_GCMPH_SHIFT);
+
+	if ((prev_cr & _SAES_CR_GCMPH_MASK) == (_SAES_CR_GCMPH_INIT << _SAES_CR_GCMPH_SHIFT)) {
+		/* Still in initialization phase, no header
+		 * We need to enable the SAES peripheral
+		 */
+		mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_EN);
+	}
+
+	/* No need to htobe() as we configure the HW to swap bytes */
+	mmio_write_32(ctx->base + _SAES_DINR, 0);
+	mmio_write_32(ctx->base + _SAES_DINR, ctx->assoc_len);
+	mmio_write_32(ctx->base + _SAES_DINR, 0);
+	mmio_write_32(ctx->base + _SAES_DINR, ctx->load_len);
+
+	ret = wait_computation_completed(ctx->base);
+	if (ret != 0) {
+		goto out;
+	}
+
+	/* No need to htobe() as we configure the HW to swap bytes */
+	tag_u32[0] = mmio_read_32(ctx->base + _SAES_DOUTR);
+	tag_u32[1] = mmio_read_32(ctx->base + _SAES_DOUTR);
+	tag_u32[2] = mmio_read_32(ctx->base + _SAES_DOUTR);
+	tag_u32[3] = mmio_read_32(ctx->base + _SAES_DOUTR);
+
+	clear_computation_completed(ctx->base);
+
+	memcpy(tag, tag_u32, MIN(sizeof(tag_u32), tag_size));
+
+out:
+	saes_end(ctx, ret);
+
+	return ret;
+}
+
+/**
+ * @brief Update (or start) a AES de/encrypt process (ECB, CBC or CTR).
+ * @param ctx: SAES process context
+ * @param last_block: true if last payload data block
+ * @param data_in: pointer to payload
+ * @param data_out: pointer where to save de/encrypted payload
+ * @param data_size: payload size
+ *
+ * @retval 0 if OK; negative value else.
+ */
+int stm32_saes_update(struct stm32_saes_context *ctx, bool last_block,
+		      uint8_t *data_in, uint8_t *data_out, size_t data_size)
+{
+	int ret;
+	uint32_t *data_in_u32;
+	uint32_t *data_out_u32;
+	unsigned int i = 0U;
+
+	/* We want buffers to be u32 aligned */
+	assert((uintptr_t)data_in % __alignof__(uint32_t) == 0);
+	assert((uintptr_t)data_out % __alignof__(uint32_t) == 0);
+	data_in_u32 = (uint32_t *)data_in;
+	data_out_u32 = (uint32_t *)data_out;
+
+	if ((!last_block) &&
+	    (round_down(data_size, AES_BLOCK_SIZE) != data_size)) {
+		ERROR("%s: non last block must be multiple of 128 bits\n",
+		      __func__);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* In CBC encryption we need to manage specifically last 2 128bits
+	 * blocks if total size in not a block size aligned
+	 * work TODO. Currently return ENODEV.
+	 * Morevoer as we need to know last 2 block, if unaligned and
+	 * call with less than two block, return -EINVAL.
+	 */
+	if (last_block && IS_CHAINING_MODE(CBC, ctx->cr) && is_encrypt(ctx->cr) &&
+	    (round_down(data_size, AES_BLOCK_SIZE) != data_size)) {
+		if (data_size < AES_BLOCK_SIZE * 2U) {
+			ERROR("if CBC, last part size should be at least 2 * AES_BLOCK_SIZE\n");
+			ret = -EINVAL;
+			goto out;
+		}
+		/* Moreover the CBC specific padding for encrypt is not yet implemented */
+		ret = -ENODEV;
+		goto out;
+	}
+
+	ret = restore_context(ctx);
+	if (ret != 0) {
+		goto out;
+	}
+
+	while (i < round_down(data_size, AES_BLOCK_SIZE)) {
+		unsigned int w; /* Word index */
+
+		w = i / sizeof(uint32_t);
+		/* No need to htobe() as we configure the HW to swap bytes */
+		mmio_write_32(ctx->base + _SAES_DINR, data_in_u32[w + 0U]);
+		mmio_write_32(ctx->base + _SAES_DINR, data_in_u32[w + 1U]);
+		mmio_write_32(ctx->base + _SAES_DINR, data_in_u32[w + 2U]);
+		mmio_write_32(ctx->base + _SAES_DINR, data_in_u32[w + 3U]);
+
+		ret = wait_computation_completed(ctx->base);
+		if (ret != 0) {
+			goto out;
+		}
+
+		/* No need to htobe() as we configure the HW to swap bytes */
+		data_out_u32[w + 0U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+		data_out_u32[w + 1U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+		data_out_u32[w + 2U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+		data_out_u32[w + 3U] = mmio_read_32(ctx->base + _SAES_DOUTR);
+
+		clear_computation_completed(ctx->base);
+
+		/* Process next block */
+		i += AES_BLOCK_SIZE;
+	}
+	/* Manage last block if not a block size multiple */
+
+	if ((last_block) && (i < data_size)) {
+		/* In and out buffer have same size so should be AES_BLOCK_SIZE multiple */
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (!last_block) {
+		ret = save_context(ctx);
+	}
+
+out:
+	/* If last block or error, end of SAES process */
+	if (last_block || (ret != 0)) {
+		saes_end(ctx, ret);
+	}
+
+	return ret;
+}
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
index 708989f..a4a64ca 100644
--- a/drivers/st/gpio/stm32_gpio.c
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -234,27 +234,27 @@
 	clk_enable(clock);
 
 	mmio_clrsetbits_32(base + GPIO_MODE_OFFSET,
-			   (uint32_t)GPIO_MODE_MASK << (pin << 1),
-			   mode << (pin << 1));
+			   (uint32_t)GPIO_MODE_MASK << (pin << 1U),
+			   mode << (pin << 1U));
 
 	mmio_clrsetbits_32(base + GPIO_TYPE_OFFSET,
 			   (uint32_t)GPIO_TYPE_MASK << pin,
 			   type << pin);
 
 	mmio_clrsetbits_32(base + GPIO_SPEED_OFFSET,
-			   (uint32_t)GPIO_SPEED_MASK << (pin << 1),
-			   speed << (pin << 1));
+			   (uint32_t)GPIO_SPEED_MASK << (pin << 1U),
+			   speed << (pin << 1U));
 
 	mmio_clrsetbits_32(base + GPIO_PUPD_OFFSET,
-			   (uint32_t)GPIO_PULL_MASK << (pin << 1),
-			   pull << (pin << 1));
+			   (uint32_t)GPIO_PULL_MASK << (pin << 1U),
+			   pull << (pin << 1U));
 
 	if (pin < GPIO_ALT_LOWER_LIMIT) {
 		mmio_clrsetbits_32(base + GPIO_AFRL_OFFSET,
-				   (uint32_t)GPIO_ALTERNATE_MASK << (pin << 2),
-				   alternate << (pin << 2));
+				   (uint32_t)GPIO_ALTERNATE_MASK << (pin << 2U),
+				   alternate << (pin << 2U));
 	} else {
-		size_t shift = (pin - GPIO_ALT_LOWER_LIMIT) << 2;
+		uint32_t shift = (pin - GPIO_ALT_LOWER_LIMIT) << 2U;
 
 		mmio_clrsetbits_32(base + GPIO_AFRH_OFFSET,
 				   (uint32_t)GPIO_ALTERNATE_MASK << shift,
diff --git a/drivers/st/io/io_stm32image.c b/drivers/st/io/io_stm32image.c
deleted file mode 100644
index 9fa0c50..0000000
--- a/drivers/st/io/io_stm32image.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <drivers/io/io_driver.h>
-#include <drivers/io/io_storage.h>
-#include <drivers/st/io_stm32image.h>
-#include <lib/utils.h>
-#include <plat/common/platform.h>
-
-static uintptr_t backend_dev_handle;
-static uintptr_t backend_image_spec;
-static uint32_t *stm32_img;
-static uint8_t first_lba_buffer[MAX_LBA_SIZE] __aligned(4);
-static struct stm32image_part_info *current_part;
-
-/* STM32 Image driver functions */
-static int stm32image_dev_open(const uintptr_t init_params,
-			       io_dev_info_t **dev_info);
-static int stm32image_partition_open(io_dev_info_t *dev_info,
-				     const uintptr_t spec, io_entity_t *entity);
-static int stm32image_partition_size(io_entity_t *entity, size_t *length);
-static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
-				     size_t length, size_t *length_read);
-static int stm32image_partition_close(io_entity_t *entity);
-static int stm32image_dev_init(io_dev_info_t *dev_info,
-			       const uintptr_t init_params);
-static int stm32image_dev_close(io_dev_info_t *dev_info);
-
-/* Identify the device type as a virtual driver */
-static io_type_t device_type_stm32image(void)
-{
-	return IO_TYPE_STM32IMAGE;
-}
-
-static const io_dev_connector_t stm32image_dev_connector = {
-	.dev_open = stm32image_dev_open
-};
-
-static const io_dev_funcs_t stm32image_dev_funcs = {
-	.type = device_type_stm32image,
-	.open = stm32image_partition_open,
-	.size = stm32image_partition_size,
-	.read = stm32image_partition_read,
-	.close = stm32image_partition_close,
-	.dev_init = stm32image_dev_init,
-	.dev_close = stm32image_dev_close,
-};
-
-static io_dev_info_t stm32image_dev_info = {
-	.funcs = &stm32image_dev_funcs,
-	.info = (uintptr_t)0,
-};
-
-static struct stm32image_device_info stm32image_dev;
-
-static int get_part_idx_by_binary_type(uint32_t binary_type)
-{
-	int i;
-
-	for (i = 0; i < STM32_PART_NUM; i++) {
-		if (stm32image_dev.part_info[i].binary_type == binary_type) {
-			return i;
-		}
-	}
-
-	return -EINVAL;
-}
-
-/* Open a connection to the STM32IMAGE device */
-static int stm32image_dev_open(const uintptr_t init_params,
-			       io_dev_info_t **dev_info)
-{
-	int i;
-	struct stm32image_device_info *device_info =
-		(struct stm32image_device_info *)init_params;
-
-	assert(dev_info != NULL);
-	*dev_info = (io_dev_info_t *)&stm32image_dev_info;
-
-	stm32image_dev.device_size = device_info->device_size;
-	stm32image_dev.lba_size = device_info->lba_size;
-
-	for (i = 0; i < STM32_PART_NUM; i++) {
-		memcpy(stm32image_dev.part_info[i].name,
-		       device_info->part_info[i].name, MAX_PART_NAME_SIZE);
-		stm32image_dev.part_info[i].binary_type =
-			device_info->part_info[i].binary_type;
-		stm32image_dev.part_info[i].part_offset =
-			device_info->part_info[i].part_offset;
-		stm32image_dev.part_info[i].bkp_offset =
-			device_info->part_info[i].bkp_offset;
-	}
-
-	return 0;
-}
-
-/* Do some basic package checks */
-static int stm32image_dev_init(io_dev_info_t *dev_info,
-			       const uintptr_t init_params)
-{
-	int result;
-
-	if ((backend_dev_handle != 0U) || (backend_image_spec != 0U)) {
-		ERROR("STM32 Image io supports only one session\n");
-		return -ENOMEM;
-	}
-
-	/* Obtain a reference to the image by querying the platform layer */
-	result = plat_get_image_source(STM32_IMAGE_ID, &backend_dev_handle,
-				       &backend_image_spec);
-	if (result != 0) {
-		ERROR("STM32 image error (%i)\n", result);
-		return -EINVAL;
-	}
-
-	return result;
-}
-
-/* Close a connection to the STM32 Image device */
-static int stm32image_dev_close(io_dev_info_t *dev_info)
-{
-	backend_dev_handle = 0U;
-	backend_image_spec = 0U;
-	stm32_img = NULL;
-
-	return 0;
-}
-
-/* Open a partition */
-static int stm32image_partition_open(io_dev_info_t *dev_info,
-				     const uintptr_t spec, io_entity_t *entity)
-{
-	const struct stm32image_part_info *partition_spec;
-	int idx;
-
-	assert(entity != NULL);
-
-	partition_spec = (struct stm32image_part_info *)spec;
-	assert(partition_spec != NULL);
-
-	idx = get_part_idx_by_binary_type(partition_spec->binary_type);
-	if ((idx < 0) || (idx > STM32_PART_NUM)) {
-		ERROR("Wrong partition index (%d)\n", idx);
-		return -EINVAL;
-	}
-
-	current_part = &stm32image_dev.part_info[idx];
-	stm32_img = (uint32_t *)&current_part->part_offset;
-
-	return 0;
-}
-
-/* Return the size of a partition */
-static int stm32image_partition_size(io_entity_t *entity, size_t *length)
-{
-	int result;
-	uintptr_t backend_handle;
-	size_t bytes_read;
-	boot_api_image_header_t *header =
-		(boot_api_image_header_t *)first_lba_buffer;
-
-	assert(entity != NULL);
-	assert(length != NULL);
-
-	/* Attempt to access the image */
-	result = io_open(backend_dev_handle, backend_image_spec,
-			 &backend_handle);
-
-	if (result < 0) {
-		ERROR("%s: io_open (%i)\n", __func__, result);
-		return result;
-	}
-
-	/* Reset magic header value */
-	header->magic = 0;
-
-	while (header->magic == 0U) {
-		result = io_seek(backend_handle, IO_SEEK_SET, *stm32_img);
-		if (result != 0) {
-			ERROR("%s: io_seek (%i)\n", __func__, result);
-			break;
-		}
-
-		result = io_read(backend_handle, (uintptr_t)header,
-				 MAX_LBA_SIZE, (size_t *)&bytes_read);
-		if (result != 0) {
-			if (current_part->bkp_offset == 0U) {
-				ERROR("%s: io_read (%i)\n", __func__, result);
-			}
-			header->magic = 0;
-		}
-
-		if ((header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) ||
-		    (header->binary_type != current_part->binary_type) ||
-		    (header->image_length >= stm32image_dev.device_size)) {
-			VERBOSE("%s: partition %s not found at %x\n",
-				__func__, current_part->name, *stm32_img);
-
-			if (current_part->bkp_offset == 0U) {
-				result = -ENOMEM;
-				break;
-			}
-
-			/* Header not correct, check next offset for backup */
-			*stm32_img += current_part->bkp_offset;
-			if (*stm32_img > stm32image_dev.device_size) {
-				/* No backup found, end of device reached */
-				WARN("%s : partition %s not found\n",
-				     __func__, current_part->name);
-				result = -ENOMEM;
-				break;
-			}
-			header->magic = 0;
-		}
-	}
-
-	io_close(backend_handle);
-
-	if (result != 0) {
-		return result;
-	}
-
-	if (header->image_length < stm32image_dev.lba_size) {
-		*length = stm32image_dev.lba_size;
-	} else {
-		*length = header->image_length;
-	}
-
-	INFO("STM32 Image size : %lu\n", (unsigned long)*length);
-
-	return 0;
-}
-
-/* Read data from a partition */
-static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
-				     size_t length, size_t *length_read)
-{
-	int result = -EINVAL;
-	uint8_t *local_buffer;
-	boot_api_image_header_t *header =
-		(boot_api_image_header_t *)first_lba_buffer;
-	size_t hdr_sz = sizeof(boot_api_image_header_t);
-
-	assert(entity != NULL);
-	assert(buffer != 0U);
-	assert(length_read != NULL);
-
-	local_buffer = (uint8_t *)buffer;
-	*length_read = 0U;
-
-	while (*length_read == 0U) {
-		int offset;
-		int local_length;
-		uintptr_t backend_handle;
-
-		if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) {
-			/* Check for backup as image is corrupted */
-			if (current_part->bkp_offset == 0U) {
-				result = -ENOMEM;
-				break;
-			}
-
-			*stm32_img += current_part->bkp_offset;
-			if (*stm32_img >= stm32image_dev.device_size) {
-				/* End of device reached */
-				result = -ENOMEM;
-				break;
-			}
-
-			local_buffer = (uint8_t *)buffer;
-
-			result = stm32image_partition_size(entity, &length);
-			if (result != 0) {
-				break;
-			}
-		}
-
-		/* Part of image already loaded with the header */
-		memcpy(local_buffer, (uint8_t *)first_lba_buffer + hdr_sz,
-		       MAX_LBA_SIZE - hdr_sz);
-		local_buffer += MAX_LBA_SIZE - hdr_sz;
-		offset = MAX_LBA_SIZE;
-
-		/* New image length to be read */
-		local_length = round_up(length - ((MAX_LBA_SIZE) - hdr_sz),
-					stm32image_dev.lba_size);
-
-		if ((header->load_address != 0U) &&
-		    (header->load_address != buffer)) {
-			ERROR("Wrong load address\n");
-			panic();
-		}
-
-		result = io_open(backend_dev_handle, backend_image_spec,
-				 &backend_handle);
-
-		if (result != 0) {
-			ERROR("%s: io_open (%i)\n", __func__, result);
-			break;
-		}
-
-		result = io_seek(backend_handle, IO_SEEK_SET,
-				 *stm32_img + offset);
-
-		if (result != 0) {
-			ERROR("%s: io_seek (%i)\n", __func__, result);
-			*length_read = 0;
-			io_close(backend_handle);
-			break;
-		}
-
-		result = io_read(backend_handle, (uintptr_t)local_buffer,
-				 local_length, length_read);
-
-		/* Adding part of size already read from header */
-		*length_read += MAX_LBA_SIZE - hdr_sz;
-
-		if (result != 0) {
-			ERROR("%s: io_read (%i)\n", __func__, result);
-			*length_read = 0;
-			header->magic = 0;
-			continue;
-		}
-
-		result = stm32mp_check_header(header, buffer);
-		if (result != 0) {
-			ERROR("Header check failed\n");
-			*length_read = 0;
-			header->magic = 0;
-		}
-
-		result = stm32mp_auth_image(header, buffer);
-		if (result != 0) {
-			ERROR("Authentication Failed (%i)\n", result);
-			return result;
-		}
-
-		inv_dcache_range(round_up((uintptr_t)(local_buffer + length - hdr_sz),
-					  CACHE_WRITEBACK_GRANULE), *length_read - length + hdr_sz);
-
-		io_close(backend_handle);
-	}
-
-	return result;
-}
-
-/* Close a partition */
-static int stm32image_partition_close(io_entity_t *entity)
-{
-	current_part = NULL;
-
-	return 0;
-}
-
-/* Register the stm32image driver with the IO abstraction */
-int register_io_dev_stm32image(const io_dev_connector_t **dev_con)
-{
-	int result;
-
-	assert(dev_con != NULL);
-
-	result = io_register_device(&stm32image_dev_info);
-	if (result == 0) {
-		*dev_con = &stm32image_dev_connector;
-	}
-
-	return result;
-}
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index 6bdd782..1ee3580 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -528,12 +528,12 @@
 	uint32_t data_ctrl = SDMMC_DCTRLR_DTDIR;
 	uint32_t arg_size;
 
-	assert(size != 0U);
+	assert((size != 0U) && (size <= UINT32_MAX));
 
 	if (size > MMC_BLOCK_SIZE) {
 		arg_size = MMC_BLOCK_SIZE;
 	} else {
-		arg_size = size;
+		arg_size = (uint32_t)size;
 	}
 
 	sdmmc2_params.use_dma = plat_sdmmc2_use_dma(base, buf);
diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c
index 5b43760..1e16287 100644
--- a/drivers/st/pmic/stm32mp_pmic.c
+++ b/drivers/st/pmic/stm32mp_pmic.c
@@ -20,6 +20,7 @@
 #include <platform_def.h>
 
 #define PMIC_NODE_NOT_FOUND	1
+#define NB_REG			14U
 
 static struct i2c_handle_s i2c_handle;
 static uint32_t pmic_i2c_addr;
@@ -454,13 +455,13 @@
 };
 
 #define DEFINE_REGU(name) { \
-	.node_name = name, \
+	.node_name = (name), \
 	.ops = &pmic_ops, \
 	.driver_data = NULL, \
 	.enable_ramp_delay = 1000, \
 }
 
-static const struct regul_description pmic_regs[] = {
+static const struct regul_description pmic_regs[NB_REG] = {
 	[STPMIC1_BUCK1] = DEFINE_REGU("buck1"),
 	[STPMIC1_BUCK2] = DEFINE_REGU("buck2"),
 	[STPMIC1_BUCK3] = DEFINE_REGU("buck3"),
@@ -477,8 +478,6 @@
 	[STPMIC1_SW_OUT] = DEFINE_REGU("pwr_sw2"),
 };
 
-#define NB_REG ARRAY_SIZE(pmic_regs)
-
 static int register_pmic(void)
 {
 	void *fdt;
@@ -506,7 +505,7 @@
 		unsigned int i;
 		int ret;
 
-		for (i = 0; i < NB_REG; i++) {
+		for (i = 0U; i < NB_REG; i++) {
 			desc = &pmic_regs[i];
 			if (strcmp(desc->node_name, reg_name) == 0) {
 				break;
diff --git a/drivers/st/regulator/regulator_core.c b/drivers/st/regulator/regulator_core.c
index 5cc8329..2a5d0f7 100644
--- a/drivers/st/regulator/regulator_core.c
+++ b/drivers/st/regulator/regulator_core.c
@@ -17,14 +17,16 @@
 
 #define MAX_PROPERTY_LEN 64
 
+CASSERT(PLAT_NB_RDEVS >= 1U, plat_nb_rdevs_must_be_higher);
+
 static struct rdev rdev_array[PLAT_NB_RDEVS];
 
 #define for_each_rdev(rdev) \
-	for (rdev = rdev_array; rdev < (rdev_array + PLAT_NB_RDEVS); rdev++)
+	for ((rdev) = rdev_array; (rdev) <= &rdev_array[PLAT_NB_RDEVS - 1U]; (rdev)++)
 
 #define for_each_registered_rdev(rdev) \
-	for (rdev = rdev_array; \
-	     (rdev < (rdev_array + PLAT_NB_RDEVS)) && (rdev->desc != NULL); rdev++)
+	for ((rdev) = rdev_array; \
+	     ((rdev) <= &rdev_array[PLAT_NB_RDEVS - 1U]) && ((rdev)->desc != NULL); (rdev)++)
 
 static void lock_driver(const struct rdev *rdev)
 {
@@ -86,7 +88,7 @@
 	char prop_name[MAX_PROPERTY_LEN];
 
 	len = snprintf(prop_name, MAX_PROPERTY_LEN - 1, "%s-supply", name);
-	assert((len >= 0) && (len < MAX_PROPERTY_LEN - 1));
+	assert((len >= 0) && (len < (MAX_PROPERTY_LEN - 1)));
 
 	cuint = fdt_getprop(fdt, node, prop_name, NULL);
 	if (cuint != NULL) {
@@ -156,7 +158,7 @@
 
 	assert(rdev != NULL);
 
-	if (rdev->flags & REGUL_ALWAYS_ON) {
+	if ((rdev->flags & REGUL_ALWAYS_ON) != 0U) {
 		return 0;
 	}
 
@@ -525,7 +527,7 @@
 		}
 	}
 
-	if (rdev == rdev_array + PLAT_NB_RDEVS) {
+	if (rdev > &rdev_array[PLAT_NB_RDEVS - 1U]) {
 		WARN("Not enough place for regulators, PLAT_NB_RDEVS should be increased.\n");
 		return -ENOMEM;
 	}
diff --git a/fdts/fvp-base-psci-common.dtsi b/fdts/fvp-base-psci-common.dtsi
index 6018f0c..7838fde 100644
--- a/fdts/fvp-base-psci-common.dtsi
+++ b/fdts/fvp-base-psci-common.dtsi
@@ -28,7 +28,7 @@
 	#size-cells = <2>;
 
 #if (ENABLE_RME == 1)
-	chosen { bootargs = "mem=1G console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda ip=on";};
+	chosen { bootargs = "console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda ip=on";};
 #else
 	chosen {};
 #endif
diff --git a/fdts/stm32mp1-cot-descriptors.dtsi b/fdts/stm32mp1-cot-descriptors.dtsi
new file mode 100644
index 0000000..eb632ff
--- /dev/null
+++ b/fdts/stm32mp1-cot-descriptors.dtsi
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2020-2022, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/nv_cntr_ids.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <tools_share/tbbr_oid.h>
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		stm32mp_cfg_cert: stm32mp_cfg_cert {
+			root-certificate;
+			image-id = <STM32MP_CONFIG_CERT_ID>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			hw_config_hash: hw_config_hash {
+				oid = HW_CONFIG_HASH_OID;
+			};
+
+			fw_config_hash: fw_config_hash {
+				oid = FW_CONFIG_HASH_OID;
+			};
+		};
+
+		trusted_key_cert: trusted_key_cert {
+			root-certificate;
+			image-id = <TRUSTED_KEY_CERT_ID>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			trusted_world_pk: trusted_world_pk {
+				oid = TRUSTED_WORLD_PK_OID;
+			};
+			non_trusted_world_pk: non_trusted_world_pk {
+				oid = NON_TRUSTED_WORLD_PK_OID;
+			};
+		};
+
+		trusted_os_fw_key_cert: trusted_os_fw_key_cert {
+			image-id = <TRUSTED_OS_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			tos_fw_content_pk: tos_fw_content_pk {
+				oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		trusted_os_fw_content_cert: trusted_os_fw_content_cert {
+			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
+			parent = <&trusted_os_fw_key_cert>;
+			signing-key = <&tos_fw_content_pk>;
+			antirollback-counter = <&trusted_nv_counter>;
+
+			tos_fw_hash: tos_fw_hash {
+				oid = TRUSTED_OS_FW_HASH_OID;
+			};
+			tos_fw_extra1_hash: tos_fw_extra1_hash {
+				oid = TRUSTED_OS_FW_EXTRA1_HASH_OID;
+			};
+			tos_fw_extra2_hash: tos_fw_extra2_hash {
+				oid = TRUSTED_OS_FW_EXTRA2_HASH_OID;
+			};
+			tos_fw_config_hash: tos_fw_config_hash {
+				oid = TRUSTED_OS_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		non_trusted_fw_key_cert: non_trusted_fw_key_cert {
+			image-id = <NON_TRUSTED_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&non_trusted_world_pk>;
+			antirollback-counter = <&non_trusted_nv_counter>;
+
+			nt_fw_content_pk: nt_fw_content_pk {
+				oid = NON_TRUSTED_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+			parent = <&non_trusted_fw_key_cert>;
+			signing-key = <&nt_fw_content_pk>;
+			antirollback-counter = <&non_trusted_nv_counter>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
+			};
+		};
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		hw_config {
+			image-id = <HW_CONFIG_ID>;
+			parent = <&stm32mp_cfg_cert>;
+			hash = <&hw_config_hash>;
+		};
+
+		fw_config {
+			image-id = <FW_CONFIG_ID>;
+			parent = <&stm32mp_cfg_cert>;
+			hash = <&fw_config_hash>;
+		};
+
+		bl32_image {
+			image-id = <BL32_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_hash>;
+		};
+
+		bl32_extra1_image {
+			image-id = <BL32_EXTRA1_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_extra1_hash>;
+		};
+
+		bl32_extra2_image {
+			image-id = <BL32_EXTRA2_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_extra2_hash>;
+		};
+
+		tos_fw_config {
+			image-id = <TOS_FW_CONFIG_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <BL33_IMAGE_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	trusted_nv_counter: trusted_nv_counter {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = TRUSTED_FW_NVCOUNTER_OID;
+	};
+
+	non_trusted_nv_counter: non_trusted_nv_counter {
+		id  = <NON_TRUSTED_NV_CTR_ID>;
+		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
+	};
+};
diff --git a/fdts/stm32mp13-bl2.dtsi b/fdts/stm32mp13-bl2.dtsi
index 4e3701c..836e9ae 100644
--- a/fdts/stm32mp13-bl2.dtsi
+++ b/fdts/stm32mp13-bl2.dtsi
@@ -56,7 +56,30 @@
 			bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
 			hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
 			tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
-			nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
+#if TRUSTED_BOARD_BOOT
+			stm32mp_cfg_cert_uuid = "501d8dd2-8bce-49a5-84eb-559a9f2eaeaf";
+			t_key_cert_uuid = "827ee890-f860-e411-a1b4-777a21b4f94c";
+			tos_fw_key_cert_uuid = "9477d603-fb60-e411-85dd-b7105b8cee04";
+			nt_fw_key_cert_uuid = "8ad5832a-fb60-e411-8aaf-df30bbc49859";
+			tos_fw_content_cert_uuid = "a49f4411-5e63-e411-8728-3f05722af33d";
+			nt_fw_content_cert_uuid = "8ec4c1f3-5d63-e411-a7a9-87ee40b23fa7";
+#endif
 		};
 	};
+
+#if TRUSTED_BOARD_BOOT
+	tb_fw-config {
+		compatible = "arm,tb_fw";
+
+		/* Disable authentication for development */
+		disable_auth = <0x0>;
+
+		/* Use SRAM2 to manage the mbedTLS heap */
+		mbedtls_heap_addr = <0x0 0x30004000>; /* SRAM2_BASE */
+		mbedtls_heap_size = <0x2000>; /* SRAM2_SIZE */
+	};
+
+#include "stm32mp1-cot-descriptors.dtsi"
+#endif
+
 };
diff --git a/fdts/stm32mp131.dtsi b/fdts/stm32mp131.dtsi
index 2c62408..543afa5 100644
--- a/fdts/stm32mp131.dtsi
+++ b/fdts/stm32mp131.dtsi
@@ -455,6 +455,9 @@
 				reg = <0xe4 0xc>;
 				st,non-secure-otp;
 			};
+			enckey_otp: enckey_otp@170 {
+				reg = <0x170 0x10>;
+			};
 		};
 		/*
 		 * Break node order to solve dependency probe issue between
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
index aa1dd01..0f06b67 100644
--- a/fdts/stm32mp135f-dk.dts
+++ b/fdts/stm32mp135f-dk.dts
@@ -176,7 +176,7 @@
 };
 
 &pka {
-	secure-status = "okay";
+	status = "okay";
 };
 
 &pwr_regulators {
@@ -298,7 +298,7 @@
 };
 
 &saes {
-	secure-status = "okay";
+	status = "okay";
 };
 
 &sdmmc1 {
diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi
index 501b092..5489a62 100644
--- a/fdts/stm32mp15-bl2.dtsi
+++ b/fdts/stm32mp15-bl2.dtsi
@@ -69,7 +69,6 @@
 		};
 	};
 
-#if !STM32MP_USE_STM32IMAGE
 	/*
 	 * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in
 	 * network order (big endian)
@@ -85,8 +84,32 @@
 			bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
 			hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
 			tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
-			nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
+#if TRUSTED_BOARD_BOOT
+			stm32mp_cfg_cert_uuid = "501d8dd2-8bce-49a5-84eb-559a9f2eaeaf";
+			t_key_cert_uuid = "827ee890-f860-e411-a1b4-777a21b4f94c";
+			tos_fw_key_cert_uuid = "9477d603-fb60-e411-85dd-b7105b8cee04";
+			nt_fw_key_cert_uuid = "8ad5832a-fb60-e411-8aaf-df30bbc49859";
+			tos_fw_content_cert_uuid = "a49f4411-5e63-e411-8728-3f05722af33d";
+			nt_fw_content_cert_uuid = "8ec4c1f3-5d63-e411-a7a9-87ee40b23fa7";
+#endif
 		};
 	};
-#endif /* !STM32MP_USE_STM32IMAGE */
+
+#if TRUSTED_BOARD_BOOT
+	tb_fw-config {
+		compatible = "arm,tb_fw";
+
+		/* Disable authentication for development */
+		disable_auth = <0x0>;
+
+		/*
+		 * The following two entries are placeholders for Mbed TLS
+		 * heap information.
+		 */
+		mbedtls_heap_addr = <0x0 0x0>;
+		mbedtls_heap_size = <0x0>;
+	};
+
+#include "stm32mp1-cot-descriptors.dtsi"
+#endif
 };
diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi
index bb16fda..a938edc 100644
--- a/fdts/stm32mp151.dtsi
+++ b/fdts/stm32mp151.dtsi
@@ -487,6 +487,9 @@
 			ts_cal2: calib@5e {
 				reg = <0x5e 0x2>;
 			};
+			pkh_otp: pkh_otp@60 {
+				reg = <0x60 0x20>;
+			};
 			mac_addr: mac_addr@e4 {
 				reg = <0xe4 0x8>;
 				st,non-secure-otp;
diff --git a/fdts/tc.dts b/fdts/tc.dts
index 5a8792e..fdde015 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.dts
@@ -214,8 +214,8 @@
 		};
 
 		optee@0xfce00000 {
+			compatible = "restricted-dma-pool";
 			reg = <0x00000000 0xfce00000 0 0x00200000>;
-			no-map;
 		};
 	};
 
@@ -463,17 +463,18 @@
 		interrupt-names = "JOB", "MMU", "GPU";
 		clocks = <&soc_refclk100mhz>;
 		clock-names = "clk_mali";
+		iommus = <&smmu_700 0x200>;
 		operating-points = <
 			/* KHz uV */
 			50000 820000
 		>;
 	};
 
-	smmu: smmu@2ce00000 {
+	smmu_700: smmu_700@3f000000 {
 		#iommu-cells = <1>;
 		compatible = "arm,smmu-v3";
-		reg = <0x0 0x2ce00000 0x0 0x20000>;
-		status = "okay";
+		reg = <0x0 0x3f000000 0x0 0x5000000>;
+		dma-coherent;
 	};
 
 	dp0: display@2cc00000 {
@@ -485,9 +486,7 @@
 		interrupt-names = "DPU";
 		clocks = <&scmi_clk 0>;
 		clock-names = "aclk";
-		iommus = <&smmu 0>, <&smmu 1>, <&smmu 2>, <&smmu 3>,
-			<&smmu 4>, <&smmu 5>, <&smmu 6>, <&smmu 7>,
-			<&smmu 8>, <&smmu 9>;
+		iommus = <&smmu_700 0x100>;
 		pl0: pipeline@0 {
 			reg = <0>;
 			clocks = <&scmi_clk 1>;
diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h
index e0c2212..60dfb8a 100644
--- a/include/common/tbbr/cot_def.h
+++ b/include/common/tbbr/cot_def.h
@@ -41,7 +41,7 @@
 #error "Invalid value for TF_MBEDTLS_KEY_SIZE"
 #endif
 #else /* Only using ECDSA keys. */
-#define PK_DER_LEN                      91
+#define PK_DER_LEN                      92
 #endif
 
 #if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256
diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h
index 9dd08e5..356012b 100644
--- a/include/drivers/arm/css/scmi.h
+++ b/include/drivers/arm/css/scmi.h
@@ -168,7 +168,7 @@
 int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr);
 
 /* API to get the platform specific SCMI channel information. */
-scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id);
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id);
 
 /* API to override default PSCI callbacks for platforms that support SCMI. */
 const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops);
diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h
index f2d641c..8f30ed0 100644
--- a/include/drivers/io/io_storage.h
+++ b/include/drivers/io/io_storage.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,6 @@
 	IO_TYPE_BLOCK,
 	IO_TYPE_MTD,
 	IO_TYPE_MMC,
-	IO_TYPE_STM32IMAGE,
 	IO_TYPE_ENCRYPTED,
 	IO_TYPE_MAX
 } io_type_t;
diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h
index eb0e2b1..794d613 100644
--- a/include/drivers/measured_boot/event_log/event_log.h
+++ b/include/drivers/measured_boot/event_log/event_log.h
@@ -115,13 +115,13 @@
 void event_log_write_specid_event(void);
 void event_log_write_header(void);
 void dump_event_log(uint8_t *log_addr, size_t log_size);
-const event_log_metadata_t *plat_event_log_get_metadata(void);
 int event_log_measure(uintptr_t data_base, uint32_t data_size,
 		      unsigned char hash_data[CRYPTO_MD_MAX_SIZE]);
 void event_log_record(const uint8_t *hash, uint32_t event_type,
 		      const event_log_metadata_t *metadata_ptr);
 int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size,
-				 uint32_t data_id);
+				 uint32_t data_id,
+				 const event_log_metadata_t *metadata_ptr);
 size_t event_log_get_cur_size(uint8_t *event_log_start);
 
 #endif /* EVENT_LOG_H */
diff --git a/include/drivers/nxp/smmu/nxp_smmu.h b/include/drivers/nxp/smmu/nxp_smmu.h
index d64c33b..bc17703 100644
--- a/include/drivers/nxp/smmu/nxp_smmu.h
+++ b/include/drivers/nxp/smmu/nxp_smmu.h
@@ -10,10 +10,13 @@
 
 #define SMMU_SCR0		(0x0)
 #define SMMU_NSCR0		(0x400)
+#define SMMU_SACR		(0x10)
 
 #define SCR0_CLIENTPD_MASK	0x00000001
 #define SCR0_USFCFG_MASK	0x00000400
 
+#define SMMU_SACR_CACHE_LOCK_ENABLE_BIT      (1ULL << 26U)
+
 static inline void bypass_smmu(uintptr_t smmu_base_addr)
 {
 	uint32_t val;
@@ -27,4 +30,13 @@
 	mmio_write_32((smmu_base_addr + SMMU_NSCR0), val);
 }
 
+static inline void smmu_cache_unlock(uintptr_t smmu_base_addr)
+{
+	uint32_t val;
+
+	val = mmio_read_32((smmu_base_addr + SMMU_SACR));
+	val &= (uint32_t)~SMMU_SACR_CACHE_LOCK_ENABLE_BIT;
+	mmio_write_32((smmu_base_addr + SMMU_SACR), val);
+}
+
 #endif
diff --git a/include/drivers/st/io_stm32image.h b/include/drivers/st/io_stm32image.h
deleted file mode 100644
index f9fa363..0000000
--- a/include/drivers/st/io_stm32image.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef IO_STM32IMAGE_H
-#define IO_STM32IMAGE_H
-
-#include <drivers/io/io_driver.h>
-#include <drivers/partition/partition.h>
-
-#define MAX_LBA_SIZE		512
-#define MAX_PART_NAME_SIZE	(EFI_NAMELEN + 1)
-#define STM32_PART_NUM		(PLAT_PARTITION_MAX_ENTRIES - STM32_TF_A_COPIES)
-
-struct stm32image_part_info {
-	char name[MAX_PART_NAME_SIZE];
-	uint32_t binary_type;
-	uintptr_t part_offset;
-	uint32_t bkp_offset;
-};
-
-struct stm32image_device_info {
-	struct stm32image_part_info part_info[STM32_PART_NUM];
-	unsigned long long device_size;
-	uint32_t lba_size;
-};
-
-int register_io_dev_stm32image(const io_dev_connector_t **dev_con);
-
-#endif /* IO_STM32IMAGE_H */
diff --git a/include/drivers/st/stm32_hash.h b/include/drivers/st/stm32_hash.h
index df04730..bebb4af 100644
--- a/include/drivers/st/stm32_hash.h
+++ b/include/drivers/st/stm32_hash.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,11 +7,19 @@
 #ifndef STM32_HASH_H
 #define STM32_HASH_H
 
+#include <stdint.h>
+
 enum stm32_hash_algo_mode {
+#if STM32_HASH_VER == 2
 	HASH_MD5SUM,
+#endif
 	HASH_SHA1,
 	HASH_SHA224,
-	HASH_SHA256
+	HASH_SHA256,
+#if STM32_HASH_VER == 4
+	HASH_SHA384,
+	HASH_SHA512,
+#endif
 };
 
 int stm32_hash_update(const uint8_t *buffer, size_t length);
diff --git a/include/drivers/st/stm32_pka.h b/include/drivers/st/stm32_pka.h
new file mode 100644
index 0000000..ad4690a
--- /dev/null
+++ b/include/drivers/st/stm32_pka.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32_PKA_H
+#define STM32_PKA_H
+
+#include <stdint.h>
+
+#if !PKA_USE_NIST_P256 && !PKA_USE_BRAINPOOL_P256R1 && !PKA_USE_BRAINPOOL_P256T1 && \
+	!PKA_USE_NIST_P521
+#error "At least one ECDSA curve needs to be selected"
+#endif
+
+enum stm32_pka_ecdsa_curve_id {
+#if PKA_USE_NIST_P256
+	PKA_NIST_P256,
+#endif
+#if PKA_USE_BRAINPOOL_P256R1
+	PKA_BRAINPOOL_P256R1,
+#endif
+#if PKA_USE_BRAINPOOL_P256T1
+	PKA_BRAINPOOL_P256T1,
+#endif
+#if PKA_USE_NIST_P521
+	PKA_NIST_P521,
+#endif
+};
+
+struct stm32_pka_platdata {
+	uintptr_t base;
+	unsigned long clock_id;
+	unsigned int reset_id;
+};
+
+int stm32_pka_init(void);
+int stm32_pka_ecdsa_verif(void *hash, unsigned int hash_size,
+			  void *sig_r_ptr, unsigned int sig_r_size,
+			  void *sig_s_ptr, unsigned int sig_s_size,
+			  void *pk_x_ptr, unsigned int pk_x_size,
+			  void *pk_y_ptr, unsigned int pk_y_size,
+			  enum stm32_pka_ecdsa_curve_id cid);
+
+#endif /* STM32_PKA_H */
diff --git a/include/drivers/st/stm32_rng.h b/include/drivers/st/stm32_rng.h
new file mode 100644
index 0000000..6ac064d
--- /dev/null
+++ b/include/drivers/st/stm32_rng.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32_RNG_H
+#define STM32_RNG_H
+
+#include <stdint.h>
+
+int stm32_rng_read(uint8_t *out, uint32_t size);
+int stm32_rng_init(void);
+
+#endif /* STM32_RNG_H */
diff --git a/include/drivers/st/stm32_saes.h b/include/drivers/st/stm32_saes.h
new file mode 100644
index 0000000..0a50438
--- /dev/null
+++ b/include/drivers/st/stm32_saes.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32_SAES_H
+#define STM32_SAES_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#define DT_SAES_COMPAT		"st,stm32-saes"
+
+struct stm32_saes_platdata {
+	uintptr_t base;
+	unsigned long clock_id;
+	unsigned int reset_id;
+};
+
+enum stm32_saes_chaining_mode {
+	STM32_SAES_MODE_ECB,
+	STM32_SAES_MODE_CBC,
+	STM32_SAES_MODE_CTR,
+	STM32_SAES_MODE_GCM,
+	STM32_SAES_MODE_CCM, /* Not use in TF-A */
+};
+
+enum stm32_saes_key_selection {
+	STM32_SAES_KEY_SOFT,
+	STM32_SAES_KEY_DHU,           /* Derived HW unique key */
+	STM32_SAES_KEY_BH,            /* Boot HW key */
+	STM32_SAES_KEY_BHU_XOR_BH,    /* XOR of DHUK and BHK */
+	STM32_SAES_KEY_WRAPPED
+};
+
+struct stm32_saes_context {
+	uintptr_t base;
+	uint32_t cr;
+	uint32_t assoc_len;
+	uint32_t load_len;
+	uint32_t key[8]; /* In HW byte order */
+	uint32_t iv[4];  /* In HW byte order */
+};
+
+int stm32_saes_driver_init(void);
+
+int stm32_saes_init(struct stm32_saes_context *ctx, bool is_decrypt,
+		    enum stm32_saes_chaining_mode ch_mode, enum stm32_saes_key_selection key_select,
+		    const void *key, size_t key_len, const void *iv, size_t iv_len);
+int stm32_saes_update(struct stm32_saes_context *ctx, bool last_block,
+		      uint8_t *data_in, uint8_t *data_out, size_t data_len);
+int stm32_saes_update_assodata(struct stm32_saes_context *ctx, bool last_block,
+			       uint8_t *data, size_t data_len);
+int stm32_saes_update_load(struct stm32_saes_context *ctx, bool last_block,
+			   uint8_t *data_in, uint8_t *data_out, size_t data_len);
+int stm32_saes_final(struct stm32_saes_context *ctx, uint8_t *tag, size_t tag_len);
+#endif
diff --git a/include/lib/cpus/aarch64/cortex_x3.h b/include/lib/cpus/aarch64/cortex_x3.h
index 076a87b..ceafe66 100644
--- a/include/lib/cpus/aarch64/cortex_x3.h
+++ b/include/lib/cpus/aarch64/cortex_x3.h
@@ -10,7 +10,7 @@
 #define CORTEX_X3_MIDR				U(0x410FD4E0)
 
 /* Cortex-X3 loop count for CVE-2022-23960 mitigation */
-#define CORTEX_X3_BHB_LOOP_COUNT			U(132)
+#define CORTEX_X3_BHB_LOOP_COUNT		U(132)
 
 /*******************************************************************************
  * CPU Extended Control register specific definitions
@@ -20,8 +20,10 @@
 /*******************************************************************************
  * CPU Power Control register specific definitions
  ******************************************************************************/
-#define CORTEX_X3_CPUPWRCTLR_EL1			S3_0_C15_C2_7
-#define CORTEX_X3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+#define CORTEX_X3_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_X3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT			U(1)
+#define CORTEX_X3_CPUPWRCTLR_EL1_WFI_RET_CTRL_BITS_SHIFT	U(4)
+#define CORTEX_X3_CPUPWRCTLR_EL1_WFE_RET_CTRL_BITS_SHIFT	U(7)
 
 /*******************************************************************************
  * CPU Auxiliary Control register 2 specific definitions.
diff --git a/include/lib/psa/measured_boot.h b/include/lib/psa/measured_boot.h
index bdb79d5..231da2c 100644
--- a/include/lib/psa/measured_boot.h
+++ b/include/lib/psa/measured_boot.h
@@ -34,14 +34,14 @@
  *
  * index			Slot number in which measurement is to be stored
  * signer_id			Pointer to signer_id buffer.
- * signer_id_size		Size of the signer_id buffer in bytes.
+ * signer_id_size		Size of the signer_id in bytes.
  * version			Pointer to version buffer.
- * version_size			Size of the version buffer in bytes.
+ * version_size			Size of the version string in bytes (with \0).
  * measurement_algo		Algorithm identifier used for measurement.
  * sw_type			Pointer to sw_type buffer.
- * sw_type_size			Size of the sw_type buffer in bytes.
+ * sw_type_size			Size of the sw_type string in bytes (with \0).
  * measurement_value		Pointer to measurement_value buffer.
- * measurement_value_size	Size of the measurement_value buffer in bytes.
+ * measurement_value_size	Size of the measurement_value in bytes.
  * lock_measurement		Boolean flag requesting whether the measurement
  *				is to be locked.
  *
@@ -74,4 +74,53 @@
 				     size_t measurement_value_size,
 				     bool lock_measurement);
 
+/**
+ * Retrieves a measurement from the requested slot.
+ *
+ * index			Slot number from which measurement is to be
+ *				retrieved.
+ * signer_id			Pointer to signer_id buffer.
+ * signer_id_size		Size of the signer_id buffer in bytes.
+ * signer_id_len		On success, number of bytes that make up
+ * 				signer_id.
+ * version			Pointer to version buffer.
+ * version_size			Size of the version buffer in bytes.
+ * version_len			On success, number of bytes that makeup the
+ * 				version.
+ * measurement_algo		Pointer to measurement_algo.
+ * sw_type			Pointer to sw_type buffer.
+ * sw_type_size			Size of the sw_type buffer in bytes.
+ * sw_type_len			On success, number of bytes that makeup the
+ * 				sw_type.
+ * measurement_value		Pointer to measurement_value buffer.
+ * measurement_value_size	Size of the measurement_value buffer in bytes.
+ * measurement_value_len	On success, number of bytes that make up the
+ * 				measurement_value.
+ * is_locked			Pointer to lock status of requested measurement
+ * 				slot.
+ *
+ * PSA_SUCCESS
+ *	- Success.
+ * PSA_ERROR_INVALID_ARGUMENT
+ *	- The size of at least one of the output buffers is incorrect or the
+ *	  requested slot index is invalid.
+ * PSA_ERROR_DOES_NOT_EXIST
+ *	- The requested slot is empty, does not contain a measurement.
+ */
+psa_status_t rss_measured_boot_read_measurement(uint8_t index,
+					uint8_t *signer_id,
+					size_t signer_id_size,
+					size_t *signer_id_len,
+					uint8_t *version,
+					size_t version_size,
+					size_t *version_len,
+					uint32_t *measurement_algo,
+					uint8_t *sw_type,
+					size_t sw_type_size,
+					size_t *sw_type_len,
+					uint8_t *measurement_value,
+					size_t measurement_value_size,
+					size_t *measurement_value_len,
+					bool *is_locked);
+
 #endif /* PSA_MEASURED_BOOT_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index ab0e4ff..36b1bdb 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -20,10 +20,12 @@
  *****************************************************************************/
 
 /*
- * Root of trust key hash lengths
+ * Root of trust key lengths
  */
 #define ARM_ROTPK_HEADER_LEN		19
 #define ARM_ROTPK_HASH_LEN		32
+/* ARM_ROTPK_KEY_LEN includes DER header + raw key material */
+#define ARM_ROTPK_KEY_LEN		294
 
 /* Special value used to verify platform parameters from BL2 to BL31 */
 #define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
diff --git a/include/plat/arm/common/arm_pas_def.h b/include/plat/arm/common/arm_pas_def.h
index c199302..fba8d2c 100644
--- a/include/plat/arm/common/arm_pas_def.h
+++ b/include/plat/arm/common/arm_pas_def.h
@@ -21,24 +21,30 @@
  * ============================================================================
  * 0GB      | 1GB         |L0 GPT|ANY   |TBROM (EL3 code)        |Fixed mapping
  *          |             |      |      |TSRAM (EL3 data)        |
- *          |             |      |      |IO (incl.UARTs & GIC)   |
+ * 00000000 |             |      |      |IO (incl.UARTs & GIC)   |
  * ----------------------------------------------------------------------------
  * 1GB      | 1GB         |L0 GPT|ANY   |IO                      |Fixed mapping
+ * 40000000 |             |      |      |                        |
  * ----------------------------------------------------------------------------
- * 2GB      | 1GB         |L1 GPT|NS    |DRAM (NS Kernel)        |Use T.Descrip
+ * 2GB      |2GB-64MB     |L1 GPT|NS    |DRAM (NS Kernel)        |Use T.Descrip
+ * 80000000 |             |      |      |                        |
  * ----------------------------------------------------------------------------
- * 3GB      |1GB-64MB     |L1 GPT|NS    |DRAM (NS Kernel)        |Use T.Descrip
- * ----------------------------------------------------------------------------
- * 4GB-64MB |64MB-32MB    |      |      |                        |
- *          | -4MB        |L1 GPT|SECURE|DRAM TZC                |Use T.Descrip
+ * 4GB-64MB |64MB-32MB-4MB|L1 GPT|SECURE|DRAM TZC                |Use T.Descrip
+ * FC000000 |             |      |      |                        |
  * ----------------------------------------------------------------------------
  * 4GB-32MB |             |      |      |                        |
  * -3MB-1MB |32MB         |L1 GPT|REALM |RMM                     |Use T.Descrip
+ * FDC00000 |             |      |      |                        |
  * ----------------------------------------------------------------------------
  * 4GB-3MB  |             |      |      |                        |
  * -1MB     |3MB          |L1 GPT|ROOT  |EL3 DRAM data           |Use T.Descrip
+ * FFC00000 |             |      |      |                        |
  * ----------------------------------------------------------------------------
  * 4GB-1MB  |1MB          |L1 GPT|ROOT  |DRAM (L1 GPTs, SCP TZC) |Fixed mapping
+ * FFF00000 |             |      |      |                        |
+ * ----------------------------------------------------------------------------
+ * 34GB     |2GB          |L1 GPT|NS    |DRAM (NS Kernel)        |Use T.Descrip
+ * 880000000|             |      |      |                        |
  * ============================================================================
  *
  * - 4KB of L0 GPT reside in TSRAM, on top of the CONFIG section.
@@ -55,7 +61,7 @@
 
 /* Device memory 0 to 2GB */
 #define ARM_PAS_1_BASE			(U(0))
-#define ARM_PAS_1_SIZE			((ULL(1)<<31)) /* 2GB */
+#define ARM_PAS_1_SIZE			((ULL(1) << 31)) /* 2GB */
 
 /* NS memory 2GB to (end - 64MB) */
 #define ARM_PAS_2_BASE			(ARM_PAS_1_BASE + ARM_PAS_1_SIZE)
@@ -69,9 +75,14 @@
 #define ARM_PAS_3_BASE			(ARM_AP_TZC_DRAM1_BASE)
 #define ARM_PAS_3_SIZE			(ARM_AP_TZC_DRAM1_SIZE)
 
+/* NS memory 2GB */
+#define	ARM_PAS_4_BASE			ARM_DRAM2_BASE
+#define	ARM_PAS_4_SIZE			((ULL(1) << 31)) /* 2GB */
+
 #define ARM_PAS_GPI_ANY			MAP_GPT_REGION(ARM_PAS_1_BASE, \
 						       ARM_PAS_1_SIZE, \
 						       GPT_GPI_ANY)
+
 #define	ARM_PAS_KERNEL			GPT_MAP_REGION_GRANULE(ARM_PAS_2_BASE, \
 							       ARM_PAS_2_SIZE, \
 							       GPT_GPI_NS)
@@ -80,6 +91,9 @@
 							       ARM_PAS_3_SIZE, \
 							       GPT_GPI_SECURE)
 
+#define	ARM_PAS_KERNEL_1		GPT_MAP_REGION_GRANULE(ARM_PAS_4_BASE, \
+							       ARM_PAS_4_SIZE, \
+							       GPT_GPI_NS)
 /*
  * REALM and Shared area share the same PAS, so consider them a single
  * PAS region to configure in GPT.
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 6c0d91d..494e470 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -159,7 +159,7 @@
 #define ARM_ROTPK_REGS_ID		1
 #define ARM_ROTPK_DEVEL_RSA_ID		2
 #define ARM_ROTPK_DEVEL_ECDSA_ID	3
-
+#define ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID	4
 
 /* IO storage utility functions */
 int arm_io_setup(void);
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index c7b7908..3351036 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -344,6 +344,8 @@
 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr);
 int plat_set_nv_ctr2(void *cookie, const struct auth_img_desc_s *img_desc,
 		unsigned int nv_ctr);
+int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+		    void **hashed_pk_ptr, unsigned int *hash_pk_len);
 int get_mbedtls_heap_helper(void **heap_addr, size_t *heap_size);
 int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key,
 			  size_t *key_len, unsigned int *flags,
@@ -419,4 +421,17 @@
 void plat_fwu_set_images_source(const struct fwu_metadata *metadata);
 uint32_t plat_fwu_get_boot_idx(void);
 
+/*
+ * Optional function to indicate if cache management operations can be
+ * performed.
+ */
+#if CONDITIONAL_CMO
+uint64_t plat_can_cmo(void);
+#else
+static inline uint64_t plat_can_cmo(void)
+{
+	return 1;
+}
+#endif /* CONDITIONAL_CMO */
+
 #endif /* PLATFORM_H */
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
index 2f25858..7edef46 100644
--- a/include/services/rmm_core_manifest.h
+++ b/include/services/rmm_core_manifest.h
@@ -38,6 +38,7 @@
 /* Boot manifest core structure as per v0.1 */
 typedef struct rmm_manifest {
 	uint32_t version;	/* Manifest version */
+	uint32_t padding;	/* RES0 */
 	uintptr_t plat_data;	/* Manifest platform data */
 } rmm_manifest_t;
 
diff --git a/include/services/trp/trp_helpers.h b/include/services/trp/trp_helpers.h
index 8e786e2..83ec740 100644
--- a/include/services/trp/trp_helpers.h
+++ b/include/services/trp/trp_helpers.h
@@ -39,5 +39,12 @@
 
 __dead2 void trp_boot_abort(uint64_t err);
 
+/* TRP SMC result registers X0-X4 */
+#define TRP_SMC_RESULT_REGS	5
+
+struct trp_smc_result {
+	unsigned long long x[TRP_SMC_RESULT_REGS];
+};
+
 #endif /* __ASSEMBLER __ */
 #endif /* TRP_HELPERS_H */
diff --git a/lib/aarch64/cache_helpers.S b/lib/aarch64/cache_helpers.S
index 6faf545..314ed6e 100644
--- a/lib/aarch64/cache_helpers.S
+++ b/lib/aarch64/cache_helpers.S
@@ -36,12 +36,26 @@
 exit_loop_\op:
 	ret
 .endm
+
+.macro check_plat_can_cmo
+#if CONDITIONAL_CMO
+	mov	x3, x30
+	mov	x2, x0
+	bl	plat_can_cmo
+	mov	x30, x3
+	cbnz	x0, 1f
+	ret
+1:
+	mov	 x0, x2
+#endif
+.endm
 	/* ------------------------------------------
 	 * Clean+Invalidate from base address till
 	 * size. 'x0' = addr, 'x1' = size
 	 * ------------------------------------------
 	 */
 func flush_dcache_range
+	check_plat_can_cmo
 	do_dcache_maintenance_by_mva civac
 endfunc flush_dcache_range
 
@@ -51,6 +65,7 @@
 	 * ------------------------------------------
 	 */
 func clean_dcache_range
+	check_plat_can_cmo
 	do_dcache_maintenance_by_mva cvac
 endfunc clean_dcache_range
 
@@ -60,6 +75,7 @@
 	 * ------------------------------------------
 	 */
 func inv_dcache_range
+	check_plat_can_cmo
 	do_dcache_maintenance_by_mva ivac
 endfunc inv_dcache_range
 
@@ -79,6 +95,7 @@
 func flush_dcache_to_popa_range
 	/* Exit early if size is zero */
 	cbz	x1, exit_loop_dc_cipapa
+	check_plat_can_cmo
 	dcache_line_size x2, x3
 	sub	x3, x2, #1
 	bic	x0, x0, x3
@@ -200,11 +217,13 @@
 
 
 func dcsw_op_louis
+	check_plat_can_cmo
 	dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
 endfunc dcsw_op_louis
 
 
 func dcsw_op_all
+	check_plat_can_cmo
 	dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
 endfunc dcsw_op_all
 
@@ -228,6 +247,7 @@
 	 * ---------------------------------------------------------------
 	 */
 func dcsw_op_level1
+	check_plat_can_cmo
 	dcsw_op_level #(1 << LEVEL_SHIFT)
 endfunc dcsw_op_level1
 
@@ -239,6 +259,7 @@
 	 * ---------------------------------------------------------------
 	 */
 func dcsw_op_level2
+	check_plat_can_cmo
 	dcsw_op_level #(2 << LEVEL_SHIFT)
 endfunc dcsw_op_level2
 
@@ -250,5 +271,6 @@
 	 * ---------------------------------------------------------------
 	 */
 func dcsw_op_level3
+	check_plat_can_cmo
 	dcsw_op_level #(3 << LEVEL_SHIFT)
 endfunc dcsw_op_level3
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index fed3f33..3ea55df 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -482,6 +482,30 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2371105
 
+/* ----------------------------------------------------
+ * Errata Workaround for Cortex-A710 Errata #2768515
+ * This applies to revisions <= r2p1 and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ----------------------------------------------------
+ */
+func errata_a710_2768515_wa
+	mov	x17, x30
+	bl	check_errata_2768515
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_a710_2768515_wa
+
+func check_errata_2768515
+	/* Applies to all revisions <= r2p1 */
+	mov	x1, #0x21
+	b	cpu_rev_var_ls
+endfunc check_errata_2768515
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -518,6 +542,12 @@
 	mrs	x0, CORTEX_A710_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A710_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	msr	CORTEX_A710_CPUPWRCTLR_EL1, x0
+#if ERRATA_A710_2768515
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_a710_2768515_wa
+	mov	x30, x15
+#endif /* ERRATA_A710_2768515 */
 	isb
 	ret
 endfunc cortex_a710_core_pwr_dwn
@@ -550,6 +580,7 @@
 	report_errata ERRATA_A710_2216384, cortex_a710, 2216384
 	report_errata ERRATA_A710_2291219, cortex_a710, 2291219
 	report_errata ERRATA_A710_2371105, cortex_a710, 2371105
+	report_errata ERRATA_A710_2768515, cortex_a710, 2768515
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a710, cve_2022_23960
 	report_errata ERRATA_DSU_2313941, cortex_a710, dsu_2313941
 
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index dd3487a..38f58bb 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -326,6 +326,31 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2395406
 
+/* ----------------------------------------------------
+ * Errata Workaround for Cortex-A78 Errata 2772019
+ * This applies to revisions <= r1p2 and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ----------------------------------------------------
+ */
+func errata_a78_2772019_wa
+	mov	x17, x30
+	bl	check_errata_2772019
+	cbz	x0, 1f
+
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_a78_2772019_wa
+
+func check_errata_2772019
+	/* Applies to all revisions <= r1p2 */
+	mov	x1, #0x12
+	b	cpu_rev_var_ls
+endfunc check_errata_2772019
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -434,6 +459,12 @@
 	mrs	x0, CORTEX_A78_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 	msr	CORTEX_A78_CPUPWRCTLR_EL1, x0
+#if ERRATA_A78_2772019
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_a78_2772019_wa
+	mov	x30, x15
+#endif /* ERRATA_A78_2772019 */
 	isb
 	ret
 endfunc cortex_a78_core_pwr_dwn
@@ -461,6 +492,7 @@
 	report_errata ERRATA_A78_2242635, cortex_a78, 2242635
 	report_errata ERRATA_A78_2376745, cortex_a78, 2376745
 	report_errata ERRATA_A78_2395406, cortex_a78, 2395406
+	report_errata ERRATA_A78_2772019, cortex_a78, 2772019
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a78, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index c810be6..f56d50a 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -295,6 +295,30 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2371105
 
+/* ----------------------------------------------------
+ * Errata Workaround for Cortex-X2 Errata #2768515
+ * This applies to revisions <= r2p1 and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ----------------------------------------------------
+ */
+func errata_x2_2768515_wa
+	mov	x17, x30
+	bl	check_errata_2768515
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_x2_2768515_wa
+
+func check_errata_2768515
+	/* Applies to all revisions <= r2p1 */
+	mov	x1, #0x21
+	b	cpu_rev_var_ls
+endfunc check_errata_2768515
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -307,6 +331,12 @@
 	mrs	x0, CORTEX_X2_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	msr	CORTEX_X2_CPUPWRCTLR_EL1, x0
+#if ERRATA_X2_2768515
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_x2_2768515_wa
+	mov	x30, x15
+#endif /* ERRATA_X2_2768515 */
 	isb
 	ret
 endfunc cortex_x2_core_pwr_dwn
@@ -333,6 +363,7 @@
 	report_errata ERRATA_X2_2147715, cortex_x2, 2147715
 	report_errata ERRATA_X2_2216384, cortex_x2, 2216384
 	report_errata ERRATA_X2_2371105, cortex_x2, 2371105
+	report_errata ERRATA_X2_2768515, cortex_x2, 2768515
 	report_errata WORKAROUND_CVE_2022_23960, cortex_x2, cve_2022_23960
 	report_errata ERRATA_DSU_2313941, cortex_x2, dsu_2313941
 
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index bf1b6ec..f104b48 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -59,6 +59,7 @@
 endfunc check_errata_cve_2022_23960
 
 func cortex_x3_reset_func
+	mov	x19, x30
 	/* Disable speculative loads */
 	msr	SSBS, xzr
 
@@ -71,8 +72,14 @@
 	msr	vbar_el3, x0
 #endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
 
+	bl	cpu_get_rev_var
+
+#if ERRATA_X3_2615812
+	bl	errata_cortex_x3_2615812_wa
+#endif /* ERRATA_X3_2615812 */
+
 	isb
-	ret
+	ret	x19
 endfunc cortex_x3_reset_func
 
 /* ----------------------------------------------------------------------
@@ -103,6 +110,35 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2313909
 
+/* ----------------------------------------------------------------------
+ * Errata Workaround for Cortex-X3 Erratum 2615812 on power-on.
+ * This applies to revision r0p0, r1p0, r1p1 of Cortex-X3. Open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * ----------------------------------------------------------------------
+ */
+func errata_cortex_x3_2615812_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2615812
+	cbz	x0, 1f
+
+	/* Disable retention control for WFI and WFE. */
+	mrs	x0, CORTEX_X3_CPUPWRCTLR_EL1
+	bfi	x0, xzr, #CORTEX_X3_CPUPWRCTLR_EL1_WFI_RET_CTRL_BITS_SHIFT, #3
+	bfi	x0, xzr, #CORTEX_X3_CPUPWRCTLR_EL1_WFE_RET_CTRL_BITS_SHIFT, #3
+	msr	CORTEX_X3_CPUPWRCTLR_EL1, x0
+1:
+	ret	x17
+endfunc errata_cortex_x3_2615812_wa
+
+func check_errata_2615812
+	/* Applies to r1p1 and below. */
+	mov	x1, #0x11
+	b	cpu_rev_var_ls
+endfunc check_errata_2615812
+
 #if REPORT_ERRATA
 	/*
 	 * Errata printing function for Cortex-X3. Must follow AAPCS.
@@ -118,6 +154,7 @@
 	 * checking functions of each errata.
 	 */
 	report_errata ERRATA_X3_2313909, cortex_x3, 2313909
+	report_errata ERRATA_X3_2615812, cortex_x3, 2615812
 	report_errata WORKAROUND_CVE_2022_23960, cortex_x3, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 5861dec..dbf5941 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -428,6 +428,30 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2388450
 
+/* -------------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2743089.
+ * This applies to revisions <= r0p2 and is fixed in r0p3.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * -------------------------------------------------------
+ */
+func errata_n2_2743089_wa
+	mov	x17, x30
+	bl	check_errata_2743089
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_n2_2743089_wa
+
+func check_errata_2743089
+	/* Applies to all revisions <= r0p2 */
+	mov	x1, #0x02
+	b	cpu_rev_var_ls
+endfunc check_errata_2743089
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -576,6 +600,12 @@
 	mrs	x0, NEOVERSE_N2_CPUPWRCTLR_EL1
 	orr	x0, x0, #NEOVERSE_N2_CORE_PWRDN_EN_BIT
 	msr	NEOVERSE_N2_CPUPWRCTLR_EL1, x0
+#if ERRATA_N2_2743089
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_n2_2743089_wa
+	mov	x30, x15
+#endif /* ERRATA_N2_2743089 */
 	isb
 	ret
 endfunc neoverse_n2_core_pwr_dwn
@@ -607,6 +637,7 @@
 	report_errata ERRATA_N2_2326639, neoverse_n2, 2326639
 	report_errata ERRATA_N2_2376738, neoverse_n2, 2376738
 	report_errata ERRATA_N2_2388450, neoverse_n2, 2388450
+	report_errata ERRATA_N2_2743089, neoverse_n2, 2743089
 	report_errata WORKAROUND_CVE_2022_23960, neoverse_n2, cve_2022_23960
 	report_errata ERRATA_DSU_2313941, neoverse_n2, dsu_2313941
 
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 3282fbc..c3a70ca 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -462,6 +462,30 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2372203
 
+	/* ----------------------------------------------------
+	 * Errata Workaround for Neoverse V1 Errata #2743093.
+	 * This applies to revisions <= r1p2 and is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * ----------------------------------------------------
+	 */
+func errata_neoverse_v1_2743093_wa
+	mov	x17, x30
+	bl	check_errata_2743093
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_neoverse_v1_2743093_wa
+
+func check_errata_2743093
+	/* Applies to all revisions <= r1p2 */
+	mov	x1, #0x12
+	b	cpu_rev_var_ls
+endfunc check_errata_2743093
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -483,6 +507,12 @@
 	mrs	x0, NEOVERSE_V1_CPUPWRCTLR_EL1
 	orr	x0, x0, #NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	msr	NEOVERSE_V1_CPUPWRCTLR_EL1, x0
+#if ERRATA_V1_2743093
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_neoverse_v1_2743093_wa
+	mov	x30, x15
+#endif /* ERRATA_V1_2743093 */
 	isb
 	ret
 endfunc neoverse_v1_core_pwr_dwn
@@ -513,6 +543,7 @@
 	report_errata ERRATA_V1_2216392, neoverse_v1, 2216392
 	report_errata ERRATA_V1_2294912, neoverse_v1, 2294912
 	report_errata ERRATA_V1_2372203, neoverse_v1, 2372203
+	report_errata ERRATA_V1_2743093, neoverse_v1, 2743093
 	report_errata WORKAROUND_CVE_2022_23960, neoverse_v1, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index f19c16e..b1f7d27 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -357,6 +357,11 @@
 # to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
 ERRATA_A78_2395406	?=0
 
+# Flag to apply erratum 2772019 workaround during powerdown. This erratum
+# applies to revisions r0p0, r1p0, r1p1 and r1p2 of the A78 cpu. It is still
+# open.
+ERRATA_A78_2772019	?=0
+
 # Flag to apply erratum 1941500 workaround during reset. This erratum applies
 # to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
 ERRATA_A78_AE_1941500	?=0
@@ -462,10 +467,6 @@
 # applies to all revisions <= r4p1 of the Neoverse N1 cpu and is still open.
 ERRATA_N1_2743102	?=0
 
-# Flag to apply erratum 2002655 workaround during reset. This erratum applies
-# to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
-ERRATA_N2_2002655	?=0
-
 # Flag to apply erratum 1618635 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse V1 cpu and was fixed in the revision r1p0.
 ERRATA_V1_1618635	?=0
@@ -516,6 +517,11 @@
 # to revisions r0p0, r1p0 and r1p1 of the Neoverse V1 cpu and is still open.
 ERRATA_V1_2372203	?=0
 
+# Flag to apply erratum 2743093 workaround during powerdown. This erratum
+# applies to revisions r0p0, r1p0, r1p1 and r1p2  of the Neoverse V1 cpu and is
+# still open.
+ERRATA_V1_2743093	?=0
+
 # Flag to apply erratum 1987031 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
 ERRATA_A710_1987031	?=0
@@ -572,6 +578,15 @@
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
 ERRATA_A710_2371105	?=0
 
+# Flag to apply erratum 2768515 workaround during power down. This erratum
+# applies to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is
+# still open.
+ERRATA_A710_2768515	?=0
+
+# Flag to apply erratum 2002655 workaround during reset. This erratum applies
+# to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
+ERRATA_N2_2002655	?=0
+
 # Flag to apply erratum 2067956 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
 ERRATA_N2_2067956	?=0
@@ -620,6 +635,10 @@
 # to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
 ERRATA_N2_2388450	?=0
 
+# Flag to apply erratum 2743089 workaround during during powerdown. This erratum
+# applies to all revisions <= r0p2 of the Neoverse N2 cpu, it is fixed in r0p3.
+ERRATA_N2_2743089	?=0
+
 # Flag to apply erratum 2002765 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
 ERRATA_X2_2002765	?=0
@@ -655,10 +674,19 @@
 # to revision r0p0, r1p0 and r2p0 of the Cortex-X2 cpu and is fixed in r2p1.
 ERRATA_X2_2371105	?=0
 
+# Flag to apply erratum 2768515 workaround during power down. This erratum
+# applies to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is
+# still open.
+ERRATA_X2_2768515	?=0
+
 # Flag to apply erratum 2313909 workaround on powerdown. This erratum applies
 # to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
 ERRATA_X3_2313909	?=0
 
+# Flag to apply erratum 2615812 workaround on powerdown. This erratum applies
+# to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is still open.
+ERRATA_X3_2615812	?=0
+
 # Flag to apply erratum 1922240 workaround during reset. This erratum applies
 # to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
 ERRATA_A510_1922240	?=0
@@ -992,6 +1020,10 @@
 $(eval $(call assert_boolean,ERRATA_A78_2395406))
 $(eval $(call add_define,ERRATA_A78_2395406))
 
+# Process ERRATA_A78_2772019 flag
+$(eval $(call assert_boolean,ERRATA_A78_2772019))
+$(eval $(call add_define,ERRATA_A78_2772019))
+
 # Process ERRATA_A78_AE_1941500 flag
 $(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
 $(eval $(call add_define,ERRATA_A78_AE_1941500))
@@ -1095,10 +1127,6 @@
 # Process ERRATA_N1_2743102 flag
 $(eval $(call assert_boolean,ERRATA_N1_2743102))
 $(eval $(call add_define,ERRATA_N1_2743102))
-#
-# Process ERRATA_N2_2002655 flag
-$(eval $(call assert_boolean,ERRATA_N2_2002655))
-$(eval $(call add_define,ERRATA_N2_2002655))
 
 # Process ERRATA_V1_1618635 flag
 $(eval $(call assert_boolean,ERRATA_V1_1618635))
@@ -1148,6 +1176,10 @@
 $(eval $(call assert_boolean,ERRATA_V1_2372203))
 $(eval $(call add_define,ERRATA_V1_2372203))
 
+# Process ERRATA_V1_2743093 flag
+$(eval $(call assert_boolean,ERRATA_V1_2743093))
+$(eval $(call add_define,ERRATA_V1_2743093))
+
 # Process ERRATA_A710_1987031 flag
 $(eval $(call assert_boolean,ERRATA_A710_1987031))
 $(eval $(call add_define,ERRATA_A710_1987031))
@@ -1204,6 +1236,14 @@
 $(eval $(call assert_boolean,ERRATA_A710_2371105))
 $(eval $(call add_define,ERRATA_A710_2371105))
 
+# Process ERRATA_A710_2768515 flag
+$(eval $(call assert_boolean,ERRATA_A710_2768515))
+$(eval $(call add_define,ERRATA_A710_2768515))
+
+# Process ERRATA_N2_2002655 flag
+$(eval $(call assert_boolean,ERRATA_N2_2002655))
+$(eval $(call add_define,ERRATA_N2_2002655))
+
 # Process ERRATA_N2_2067956 flag
 $(eval $(call assert_boolean,ERRATA_N2_2067956))
 $(eval $(call add_define,ERRATA_N2_2067956))
@@ -1252,6 +1292,10 @@
 $(eval $(call assert_boolean,ERRATA_N2_2388450))
 $(eval $(call add_define,ERRATA_N2_2388450))
 
+# Process ERRATA_N2_2743089 flag
+$(eval $(call assert_boolean,ERRATA_N2_2743089))
+$(eval $(call add_define,ERRATA_N2_2743089))
+
 # Process ERRATA_X2_2002765 flag
 $(eval $(call assert_boolean,ERRATA_X2_2002765))
 $(eval $(call add_define,ERRATA_X2_2002765))
@@ -1284,10 +1328,18 @@
 $(eval $(call assert_boolean,ERRATA_X2_2371105))
 $(eval $(call add_define,ERRATA_X2_2371105))
 
+# Process ERRATA_X2_2768515 flag
+$(eval $(call assert_boolean,ERRATA_X2_2768515))
+$(eval $(call add_define,ERRATA_X2_2768515))
+
 # Process ERRATA_X3_2313909 flag
 $(eval $(call assert_boolean,ERRATA_X3_2313909))
 $(eval $(call add_define,ERRATA_X3_2313909))
 
+# Process ERRATA_X3_2615812 flag
+$(eval $(call assert_boolean,ERRATA_X3_2615812))
+$(eval $(call add_define,ERRATA_X3_2615812))
+
 # Process ERRATA_A510_1922240 flag
 $(eval $(call assert_boolean,ERRATA_A510_1922240))
 $(eval $(call add_define,ERRATA_A510_1922240))
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 6b88a90..60501f6 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -788,6 +788,15 @@
 #endif /* CTX_INCLUDE_FPREGS */
 
 	/*
+	 * Set SCR_EL3.EA bit to enable SErrors at EL3
+	 */
+	.macro enable_serror_at_el3
+	mrs     x8, scr_el3
+	orr     x8, x8, #SCR_EA_BIT
+	msr     scr_el3, x8
+	.endm
+
+	/*
 	 * Set the PSTATE bits not set when the exception was taken as
 	 * described in the AArch64.TakeException() pseudocode function
 	 * in ARM DDI 0487F.c page J1-7635 to a default value.
@@ -917,6 +926,7 @@
  */
 func prepare_el3_entry
 	save_gp_pmcr_pauth_regs
+	enable_serror_at_el3
 	/*
 	 * Set the PSTATE bits not described in the Aarch64.TakeException
 	 * pseudocode to their default values.
@@ -1064,16 +1074,6 @@
 	msr	spsel, #MODE_SP_ELX
 	str	x17, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
 
-	/* ----------------------------------------------------------
-	 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
-	 * ----------------------------------------------------------
-	 */
-	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
-	ldp	x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-	msr	scr_el3, x18
-	msr	spsr_el3, x16
-	msr	elr_el3, x17
-
 #if IMAGE_BL31
 	/* ----------------------------------------------------------
 	 * Restore CPTR_EL3.
@@ -1103,17 +1103,6 @@
 1:
 #endif /* IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 */
 
-	restore_ptw_el1_sys_regs
-
-	/* ----------------------------------------------------------
-	 * Restore general purpose (including x30), PMCR_EL0 and
-	 * ARMv8.3-PAuth registers.
-	 * Exit EL3 via ERET to a lower exception level.
- 	 * ----------------------------------------------------------
- 	 */
-	bl	restore_gp_pmcr_pauth_regs
-	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-
 #if IMAGE_BL31 && RAS_EXTENSION
 	/* ----------------------------------------------------------
 	 * Issue Error Synchronization Barrier to synchronize SErrors
@@ -1127,6 +1116,27 @@
 	dsb	sy
 #endif /* IMAGE_BL31 && RAS_EXTENSION */
 
+	/* ----------------------------------------------------------
+	 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
+	 * ----------------------------------------------------------
+	 */
+	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+	ldp	x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+	msr	scr_el3, x18
+	msr	spsr_el3, x16
+	msr	elr_el3, x17
+
+	restore_ptw_el1_sys_regs
+
+	/* ----------------------------------------------------------
+	 * Restore general purpose (including x30), PMCR_EL0 and
+	 * ARMv8.3-PAuth registers.
+	 * Exit EL3 via ERET to a lower exception level.
+ 	 * ----------------------------------------------------------
+ 	 */
+	bl	restore_gp_pmcr_pauth_regs
+	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+
 #ifdef IMAGE_BL31
 	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
 #endif /* IMAGE_BL31 */
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 8c6798b..866ac41 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -254,6 +254,16 @@
 				   ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
 	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_ICC_SRE_EL2,
 			icc_sre_el2);
+
+	/*
+	 * Initialize MDCR_EL2.HPMN to its hardware reset value so we don't
+	 * throw anyone off who expects this to be sensible.
+	 * TODO: A similar thing happens in cm_prepare_el3_exit. They should be
+	 * unified with the proper PMU implementation
+	 */
+	u_register_t mdcr_el2 = ((read_pmcr_el0() >> PMCR_EL0_N_SHIFT) &
+			PMCR_EL0_N_MASK);
+	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2, mdcr_el2);
 #endif /* CTX_INCLUDE_EL2_REGS */
 }
 
diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c
index 6f043e6..c3b4b7e 100644
--- a/lib/fconf/fconf_tbbr_getter.c
+++ b/lib/fconf/fconf_tbbr_getter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -44,8 +44,8 @@
 	/* Check if the value is boolean */
 	if ((tbbr_dyn_config.disable_auth != 0U) &&
 	    (tbbr_dyn_config.disable_auth != 1U)) {
-		WARN("Invalid value for `%s` cell %d\n",
-			"disable_auth", tbbr_dyn_config.disable_auth);
+		WARN("Invalid value for `%s` cell %u\n",
+		     "disable_auth", tbbr_dyn_config.disable_auth);
 		return -1;
 	}
 
@@ -71,7 +71,7 @@
 	}
 	tbbr_dyn_config.mbedtls_heap_size = val32;
 
-	VERBOSE("%s%s%s %d\n", "FCONF: `tbbr.", "disable_auth",
+	VERBOSE("%s%s%s %u\n", "FCONF: `tbbr.", "disable_auth",
 		"` cell found with value =", tbbr_dyn_config.disable_auth);
 	VERBOSE("%s%s%s %p\n", "FCONF: `tbbr.", "mbedtls_heap_addr",
 		"` cell found with value =", tbbr_dyn_config.mbedtls_heap_addr);
diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c
index a6e17a3..f5353cb 100644
--- a/lib/gpt_rme/gpt_rme.c
+++ b/lib/gpt_rme/gpt_rme.c
@@ -762,7 +762,7 @@
  * Return
  *   Negative Linux error code in the event of a failure, 0 for success.
  */
-int gpt_init_l0_tables(unsigned int pps, uintptr_t l0_mem_base,
+int gpt_init_l0_tables(gpccr_pps_e pps, uintptr_t l0_mem_base,
 		       size_t l0_mem_size)
 {
 	int ret;
diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c
index 6e9ff78..10c43f1 100644
--- a/lib/psa/measured_boot.c
+++ b/lib/psa/measured_boot.c
@@ -80,22 +80,24 @@
 		.lock_measurement = lock_measurement,
 		.measurement_algo = measurement_algo,
 		.sw_type = {0},
-		.sw_type_size = sw_type_size,
+		/* Removing \0 */
+		.sw_type_size = (sw_type_size > 0) ? (sw_type_size - 1) : 0,
 	};
 
 	psa_invec in_vec[] = {
 		{.base = &extend_iov,
 			.len = sizeof(struct measured_boot_extend_iovec_t)},
 		{.base = signer_id, .len = signer_id_size},
-		{.base = version, .len = version_size},
+		{.base = version,
+			.len = (version_size > 0) ? (version_size - 1) : 0},
 		{.base = measurement_value, .len = measurement_value_size}
 	};
 
 	if (sw_type != NULL) {
-		if (sw_type_size > SW_TYPE_MAX_SIZE) {
+		if (extend_iov.sw_type_size > SW_TYPE_MAX_SIZE) {
 			return PSA_ERROR_INVALID_ARGUMENT;
 		}
-		memcpy(extend_iov.sw_type, sw_type, sw_type_size);
+		memcpy(extend_iov.sw_type, sw_type, extend_iov.sw_type_size);
 	}
 
 	log_measurement(index, signer_id, signer_id_size,
@@ -109,6 +111,61 @@
 			NULL, 0);
 }
 
+psa_status_t rss_measured_boot_read_measurement(uint8_t index,
+					uint8_t *signer_id,
+					size_t signer_id_size,
+					size_t *signer_id_len,
+					uint8_t *version,
+					size_t version_size,
+					size_t *version_len,
+					uint32_t *measurement_algo,
+					uint8_t *sw_type,
+					size_t sw_type_size,
+					size_t *sw_type_len,
+					uint8_t *measurement_value,
+					size_t measurement_value_size,
+					size_t *measurement_value_len,
+					bool *is_locked)
+{
+	psa_status_t status;
+	struct measured_boot_read_iovec_in_t read_iov_in = {
+		.index = index,
+		.sw_type_size = sw_type_size,
+		.version_size = version_size,
+	};
+
+	struct measured_boot_read_iovec_out_t read_iov_out;
+
+	psa_invec in_vec[] = {
+		{.base = &read_iov_in,
+		 .len = sizeof(struct measured_boot_read_iovec_in_t)},
+	};
+
+	psa_outvec out_vec[] = {
+		{.base = &read_iov_out,
+		 .len = sizeof(struct measured_boot_read_iovec_out_t)},
+		{.base = signer_id, .len = signer_id_size},
+		{.base = measurement_value, .len = measurement_value_size}
+	};
+
+	status = psa_call(RSS_MEASURED_BOOT_HANDLE, RSS_MEASURED_BOOT_READ,
+					  in_vec, IOVEC_LEN(in_vec),
+					  out_vec, IOVEC_LEN(out_vec));
+
+	if (status == PSA_SUCCESS) {
+		*is_locked = read_iov_out.is_locked;
+		*measurement_algo = read_iov_out.measurement_algo;
+		*sw_type_len = read_iov_out.sw_type_len;
+		*version_len = read_iov_out.version_len;
+		memcpy(sw_type, read_iov_out.sw_type, read_iov_out.sw_type_len);
+		memcpy(version, read_iov_out.version, read_iov_out.version_len);
+		*signer_id_len = out_vec[1].len;
+		*measurement_value_len = out_vec[2].len;
+	}
+
+	return status;
+}
+
 #else /* !PLAT_RSS_NOT_SUPPORTED */
 
 psa_status_t
@@ -131,4 +188,24 @@
 
 	return PSA_SUCCESS;
 }
+
+psa_status_t rss_measured_boot_read_measurement(uint8_t index,
+					uint8_t *signer_id,
+					size_t signer_id_size,
+					size_t *signer_id_len,
+					uint8_t *version,
+					size_t version_size,
+					size_t *version_len,
+					uint32_t *measurement_algo,
+					uint8_t *sw_type,
+					size_t sw_type_size,
+					size_t *sw_type_len,
+					uint8_t *measurement_value,
+					size_t measurement_value_size,
+					size_t *measurement_value_len,
+					bool *is_locked)
+{
+	return PSA_SUCCESS;
+}
+
 #endif /* !PLAT_RSS_NOT_SUPPORTED */
diff --git a/lib/psa/measured_boot_private.h b/lib/psa/measured_boot_private.h
index 649c3f6..80d2c19 100644
--- a/lib/psa/measured_boot_private.h
+++ b/lib/psa/measured_boot_private.h
@@ -11,8 +11,24 @@
 #include <stdint.h>
 
 /* Measured boot message types that distinguish its services */
+#define RSS_MEASURED_BOOT_READ		1001U
 #define RSS_MEASURED_BOOT_EXTEND	1002U
 
+struct measured_boot_read_iovec_in_t {
+    uint8_t index;
+    uint8_t sw_type_size;
+    uint8_t version_size;
+};
+
+struct measured_boot_read_iovec_out_t {
+    uint8_t  is_locked;
+    uint32_t measurement_algo;
+    uint8_t  sw_type[SW_TYPE_MAX_SIZE];
+    uint8_t  sw_type_len;
+    uint8_t  version[VERSION_MAX_SIZE];
+    uint8_t  version_len;
+};
+
 struct measured_boot_extend_iovec_t {
 	uint8_t  index;
 	uint8_t  lock_measurement;
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index abdd4d0..426e344 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -238,6 +238,20 @@
 	$(check_$(1)_cmd)
 endef
 
+# SELECT_OPENSSL_API_VERSION selects the OpenSSL API version to be used to
+# build the host tools by checking the version of OpenSSL located under
+# the path defined by the OPENSSL_DIR variable. It receives no parameters.
+define SELECT_OPENSSL_API_VERSION
+    # Set default value for USING_OPENSSL3 macro to 0
+    $(eval USING_OPENSSL3 = 0)
+    # Obtain the OpenSSL version for the build located under OPENSSL_DIR
+    $(eval OPENSSL_INFO := $(shell LD_LIBRARY_PATH=${OPENSSL_DIR}:${OPENSSL_DIR}/lib ${OPENSSL_BIN_PATH}/openssl version))
+    $(eval OPENSSL_CURRENT_VER = $(word 2, ${OPENSSL_INFO}))
+    $(eval OPENSSL_CURRENT_VER_MAJOR = $(firstword $(subst ., ,$(OPENSSL_CURRENT_VER))))
+    # If OpenSSL version is 3.x, then set USING_OPENSSL3 flag to 1
+    $(if $(filter 3,$(OPENSSL_CURRENT_VER_MAJOR)), $(eval USING_OPENSSL3 = 1))
+endef
+
 ################################################################################
 # Generic image processing filters
 ################################################################################
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 2aa84ff..a66123a 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -400,9 +400,10 @@
 # Enable Link Time Optimization
 ENABLE_LTO			:= 0
 
-# Build flag to include EL2 registers in cpu context save and restore during
-# S-EL2 firmware entry/exit. This flag is to be used with SPD=spmd option.
-# Default is 0.
+# This option will include EL2 registers in cpu context save and restore during
+# EL2 firmware entry/exit. Internal flag not meant for direct setting.
+# Use SPD=spmd and SPMD_SPM_AT_SEL2=1 or ENABLE_RME=1 to enable
+# CTX_INCLUDE_EL2_REGS.
 CTX_INCLUDE_EL2_REGS		:= 0
 
 # Enable Memory tag extension which is supported for architecture greater
@@ -419,7 +420,7 @@
 # Build option to create cot descriptors using fconf
 COT_DESC_IN_DTB			:= 0
 
-# Build option to provide openssl directory path
+# Build option to provide OpenSSL directory path
 OPENSSL_DIR			:= /usr
 
 # Select the openssl binary provided in OPENSSL_DIR variable
@@ -480,3 +481,7 @@
 
 # Dynamic Root of Trust for Measurement support
 DRTM_SUPPORT			:= 0
+
+# Check platform if cache management operations should be performed.
+# Disabled by default.
+CONDITIONAL_CMO			:= 0
diff --git a/package-lock.json b/package-lock.json
index bc86b9b..a3e0ff9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.7.0",
+  "version": "2.8.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "trusted-firmware-a",
-      "version": "2.7.0",
+      "version": "2.8.0",
       "hasInstallScript": true,
       "license": "BSD-3-Clause",
       "devDependencies": {
diff --git a/package.json b/package.json
index 0284e6f..8d4dd54 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.7.0",
+  "version": "2.8.0",
   "license": "BSD-3-Clause",
   "private": true,
   "scripts": {
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 714c444..24d88ee 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -47,7 +47,8 @@
 #pragma weak plat_get_nv_ctr
 #pragma weak plat_set_nv_ctr
 
-extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[];
+extern unsigned char arm_rotpk_header[], arm_rotpk_key[], arm_rotpk_hash_end[],
+       arm_rotpk_key_end[];
 
 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) || ARM_CRYPTOCELL_INTEG
 static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
@@ -93,16 +94,20 @@
 #endif
 
 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
-    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
-/*
- * Return development ROTPK hash generated from ROT_KEY.
- */
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) || \
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID)
 int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
 			unsigned int *flags)
 {
-	*key_ptr = arm_rotpk_header;
-	*key_len = arm_rotpk_hash_end - arm_rotpk_header;
-	*flags = ROTPK_IS_HASH;
+	if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID) {
+		*key_ptr = arm_rotpk_key;
+		*key_len = arm_rotpk_key_end - arm_rotpk_key;
+		*flags = 0;
+	} else {
+		*key_ptr = arm_rotpk_header;
+		*key_len = arm_rotpk_hash_end - arm_rotpk_header;
+		*flags = ROTPK_IS_HASH;
+	}
 	return 0;
 }
 #endif
@@ -130,7 +135,7 @@
 #endif
 
 /*
- * Wrapper function for most Arm platforms to get ROTPK hash.
+ * Wrapper function for most Arm platforms to get ROTPK info.
  */
 static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
 				unsigned int *flags)
@@ -140,7 +145,8 @@
 #else
 
 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
-    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) || \
+    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID)
 	return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
 	return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 1d0eb13..d73c2e3 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -12,6 +12,7 @@
 BL2_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c
 
 ifneq (${TRUSTED_BOARD_BOOT},0)
+ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_dev_rotpk.S
 ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
 # ROTPK hash location
 ifeq (${ARM_ROTPK_LOCATION}, regs)
@@ -32,6 +33,12 @@
 $(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
 $(warning Development keys support for FVP is deprecated. Use `regs` \
 option instead)
+else ifeq (${ARM_ROTPK_LOCATION}, devel_full_dev_rsa_key)
+	CRYPTO_ALG=rsa
+	ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_FULL_DEV_RSA_KEY_ID
+	ARM_ROTPK_S = plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
 else
 $(error "Unsupported ARM_ROTPK_LOCATION value")
 endif
@@ -67,9 +74,9 @@
 NTFW_NVCTR_VAL	?=	0
 endif
 BL1_SOURCES		+=	plat/arm/board/common/board_arm_trusted_boot.c \
-				plat/arm/board/common/rotpk/arm_dev_rotpk.S
+				${ARM_ROTPK_S}
 BL2_SOURCES		+=	plat/arm/board/common/board_arm_trusted_boot.c \
-				plat/arm/board/common/rotpk/arm_dev_rotpk.S
+				${ARM_ROTPK_S}
 
 # Allows platform code to provide implementation variants depending on the
 # selected chain of trust.
diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
index 06e2a06..a7fadf6 100644
--- a/plat/arm/board/common/rotpk/arm_dev_rotpk.S
+++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
@@ -14,7 +14,6 @@
 #endif
 
 	.global arm_rotpk_header
-	.global arm_rotpk_header_end
 	.section .rodata.arm_rotpk_hash, "a"
 
 arm_rotpk_header:
diff --git a/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S b/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
new file mode 100644
index 0000000..4bb04dc
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* corstone1000 platform provides custom values for the macros defined in
+ * arm_def.h , so only platform_def.h needs to be included
+ */
+#if !defined(TARGET_PLATFORM_FVP) && !defined(TARGET_PLATFORM_FPGA)
+#include "plat/arm/common/arm_def.h"
+#else
+#include <platform_def.h>
+#endif
+
+	.global arm_rotpk_key
+	.global arm_rotpk_key_end
+
+	.section .rodata.arm_rotpk_key, "a"
+
+arm_rotpk_key:
+	.byte 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01
+	.byte 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01
+	.byte 0x00, 0xCB, 0x2C, 0x60, 0xD5, 0x8D, 0x63, 0xD4, 0x07, 0x79, 0x7E, 0xC7, 0x16, 0x96, 0xBD, 0x4D, 0x24, 0x4E, 0xAC, 0x86, 0xE6, 0xB7, 0x71, 0xE3, 0xC5, 0x54, 0x0B, 0xE7, 0x14, 0x1C, 0xBD, 0x29, 0x1A, 0xC1, 0x3F, 0x7A, 0xB6, 0x02, 0xAA, 0xAB, 0x36, 0xC4, 0xD9, 0x36, 0x69, 0x6C, 0xE2, 0x65, 0xC3, 0x9B, 0xB1, 0xBF, 0x3D, 0xA8, 0x56, 0x26, 0xCB, 0xFD, 0x04, 0x01, 0xBA, 0xAC, 0x3E, 0x54, 0x32, 0xCA, 0x79, 0x5E, 0xBB, 0xB2, 0x05, 0xEA, 0x06, 0x58, 0xF2, 0x74, 0xBA, 0xE1, 0xF4, 0x87, 0xC0, 0x19, 0x0A, 0x1F, 0x66, 0x07, 0x77, 0x84, 0x83, 0xA1, 0x1C, 0xEF, 0xFF, 0x28, 0x59, 0xE7, 0xC3, 0x68, 0x7D, 0x26, 0x20, 0x43, 0xEB, 0x56, 0x63, 0xF3, 0x39, 0x31, 0xD8, 0x2B, 0x51, 0xA9, 0xBC, 0x4F, 0xD0, 0xF6, 0xDE, 0x95, 0xDC, 0x5F, 0x5B, 0xC1, 0xED, 0x90, 0x6F, 0xEC, 0x28, 0x91, 0x7E, 0x17, 0xED, 0x78, 0x90, 0xF4, 0x60, 0xA7, 0xC4, 0xC7, 0x4F, 0x50, 0xED, 0x5D, 0x13, 0x3A, 0x21, 0x2B, 0x70, 0xC5, 0x61, 0x7B, 0x08, 0x21, 0x65, 0x3A, 0xCD, 0x82, 0x56, 0x8C, 0x7A, 0x47, 0xAC, 0x89, 0xE8, 0xA5, 0x48, 0x48
+	.byte 0x31, 0xD9, 0x1D, 0x46, 0xE5, 0x85, 0x86, 0x98, 0xA0, 0xE5, 0xC0, 0xA6, 0x6A, 0xBD, 0x07, 0xE4, 0x92, 0x57, 0x61, 0x07, 0x8F, 0x7D, 0x5A, 0x4D, 0xCA, 0xAE, 0x36, 0xB9, 0x56, 0x04, 0x10, 0xF2, 0x6C, 0xBE, 0xF6, 0x3B, 0x6C, 0x80, 0x3E, 0xBE , 0x0E, 0xA3, 0x4D , 0xC7 , 0xD4, 0x7E , 0xA7  , 0x49, 0xD4, 0xF2, 0xD2, 0xBC, 0xCF, 0x30, 0xA8, 0xE7, 0x74, 0x8F, 0x64, 0xDF, 0xBC, 0x5C, 0x47, 0x68, 0xCC, 0x40, 0x4C, 0xF8, 0x83, 0xCC, 0xCB, 0x40, 0x35, 0x04, 0x60, 0xCA, 0xB3, 0xA4, 0x17, 0x9F, 0x03, 0xCA, 0x1D, 0x5A, 0xFA, 0xD1, 0xAF, 0x21, 0x57, 0x10, 0xD3, 0x02, 0x03, 0x01, 0x00, 0x01
+
+arm_rotpk_key_end:
+
+.if ARM_ROTPK_KEY_LEN != arm_rotpk_key_end - arm_rotpk_key
+.error "Invalid ROTPK length."
+.endif
+
diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
index e938e24..29b6619 100644
--- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
@@ -125,7 +125,8 @@
 
 	/* Calculate image hash and record data in Event Log */
 	int err = event_log_measure_and_record((uintptr_t)base, (uint32_t)size,
-					       critical_data_id);
+					       critical_data_id,
+					       fvp_event_log_metadata);
 	if (err != 0) {
 		ERROR("%s%s critical data (%i)\n",
 		      "Failed to ", "record",  err);
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index f8463f1..f5d9940 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -536,6 +536,7 @@
 	assert(manifest != NULL);
 
 	manifest->version = RMMD_MANIFEST_VERSION;
+	manifest->padding = 0U; /* RES0 */
 	manifest->plat_data = (uintptr_t)NULL;
 
 	return 0;
diff --git a/plat/arm/board/fvp/fvp_common_measured_boot.c b/plat/arm/board/fvp/fvp_common_measured_boot.c
index 93aa055..b5b8f10 100644
--- a/plat/arm/board/fvp/fvp_common_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_common_measured_boot.c
@@ -16,11 +16,6 @@
 extern event_log_metadata_t fvp_event_log_metadata[];
 extern struct rss_mboot_metadata fvp_rss_mboot_metadata[];
 
-const event_log_metadata_t *plat_event_log_get_metadata(void)
-{
-	return fvp_event_log_metadata;
-}
-
 struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void)
 {
 	return fvp_rss_mboot_metadata;
@@ -34,7 +29,8 @@
 	/* Calculate image hash and record data in Event Log */
 	err = event_log_measure_and_record(image_data->image_base,
 					   image_data->image_size,
-					   image_id);
+					   image_id,
+					   fvp_event_log_metadata);
 	if (err != 0) {
 		ERROR("%s%s image id %u (%i)\n",
 		      "Failed to ", "record in event log", image_id, err);
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
index 075f512..768741e 100644
--- a/plat/arm/board/juno/juno_topology.c
+++ b/plat/arm/board/juno/juno_topology.c
@@ -20,7 +20,7 @@
 		.ring_doorbell = &mhu_ring_doorbell,
 };
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
 {
 	return &juno_scmi_plat_info;
 }
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
index a044212..e04587d 100644
--- a/plat/arm/board/morello/morello_bl31_setup.c
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -19,7 +19,7 @@
 	.ring_doorbell = &mhu_ring_doorbell
 };
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
 {
 	return &morello_scmi_plat_info;
 }
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index 5e897fe..ad6c1f8 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -62,7 +62,7 @@
 	0
 };
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
 {
 	return &n1sdp_scmi_plat_info;
 }
diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c
index 1dbbf26..045c316 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_plat.c
+++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c
@@ -65,7 +65,8 @@
 #if defined(IMAGE_BL31)
 void bl31_platform_setup(void)
 {
-	int i, ret;
+	unsigned int i;
+	int ret;
 
 	if (plat_arm_sgi_get_multi_chip_mode() == 0 && CSS_SGI_CHIP_COUNT > 1) {
 		ERROR("Chip Count is set to %d but multi-chip mode not enabled\n",
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index bc4f254..0fe4a0a 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -101,7 +101,7 @@
  * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
  * plus a little space for growth.
  */
-#define PLAT_ARM_MAX_BL1_RW_SIZE	0xD000
+#define PLAT_ARM_MAX_BL1_RW_SIZE	0x12000
 
 /*
  * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
@@ -129,7 +129,7 @@
  * BL2 and BL1-RW. Current size is considering that TRUSTED_BOARD_BOOT and
  * MEASURED_BOOT is enabled.
  */
-#define PLAT_ARM_MAX_BL31_SIZE		0x47000
+#define PLAT_ARM_MAX_BL31_SIZE		0x60000
 
 /*
  * Size of cacheable stacks
@@ -152,7 +152,7 @@
 # if SPM_MM
 #  define PLATFORM_STACK_SIZE		0x500
 # else
-#  define PLATFORM_STACK_SIZE		0x400
+#  define PLATFORM_STACK_SIZE		0xa00
 # endif
 #elif defined(IMAGE_BL32)
 # define PLATFORM_STACK_SIZE		0x440
diff --git a/plat/arm/board/tc/include/tc_plat.h b/plat/arm/board/tc/include/tc_plat.h
index 28c0308..f7ce2fe 100644
--- a/plat/arm/board/tc/include/tc_plat.h
+++ b/plat/arm/board/tc/include/tc_plat.h
@@ -9,4 +9,8 @@
 
 void tc_bl31_common_platform_setup(void);
 
+#ifdef PLATFORM_TEST
+void run_platform_tests(void);
+#endif
+
 #endif /* TC_PLAT_H */
diff --git a/plat/arm/board/tc/plat_tc_mbedtls_config.h b/plat/arm/board/tc/plat_tc_mbedtls_config.h
new file mode 100644
index 0000000..d776b63
--- /dev/null
+++ b/plat/arm/board/tc/plat_tc_mbedtls_config.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_TC_MBEDTLS_CONFIG_H
+#define PLAT_TC_MBEDTLS_CONFIG_H
+
+#include <mbedtls_config.h>
+#include <export/lib/utils_def_exp.h>
+
+#ifndef TF_MBEDTLS_HEAP_SIZE
+#error TF_MBEDTLS_HEAP_SIZE is not defined
+#else
+#define PLATFORM_TEST_MIN_MBEDTLS_HEAP_SIZE	(8 * 1024)
+/* Only change heap size if it is less then the minimum required. */
+#if TF_MBEDTLS_HEAP_SIZE < PLATFORM_TEST_MIN_MBEDTLS_HEAP_SIZE
+#undef TF_MBEDTLS_HEAP_SIZE
+#define TF_MBEDTLS_HEAP_SIZE	PLATFORM_TEST_MIN_MBEDTLS_HEAP_SIZE
+#endif
+#endif
+
+#define MBEDTLS_PSA_CRYPTO_C
+#define MBEDTLS_HMAC_DRBG_C
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+#define MBEDTLS_TEST_NULL_ENTROPY
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+
+#endif /* PLAT_TC_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 4955479..74c0f17 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -5,6 +5,11 @@
 
 include common/fdt_wrappers.mk
 
+ifeq ($(TARGET_PLATFORM), 0)
+$(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
+Some of the features might not work as expected)
+endif
+
 ifeq ($(shell expr $(TARGET_PLATFORM) \<= 2), 0)
         $(error TARGET_PLATFORM must be less than or equal to 2)
 endif
@@ -188,6 +193,11 @@
 
 endif
 
+# Add this include as first, before arm_common.mk. This is necessary because
+# arm_common.mk builds Mbed TLS, and platform_test.mk can change the list of
+# Mbed TLS files that are to be compiled (LIBMBEDTLS_SRCS).
+include plat/arm/board/tc/platform_test.mk
+
 include plat/arm/common/arm_common.mk
 include plat/arm/css/common/css_common.mk
 include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/board/tc/platform_test.mk b/plat/arm/board/tc/platform_test.mk
new file mode 100644
index 0000000..c2ee69e
--- /dev/null
+++ b/plat/arm/board/tc/platform_test.mk
@@ -0,0 +1,80 @@
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifeq (${PLATFORM_TEST},1)
+
+    # The variables need to be set to compile the platform test:
+    ifeq (${TF_M_TESTS_PATH},)
+        # Example: ../rss/tf-m-tests
+        $(error Error: TF_M_TESTS_PATH not set)
+    endif
+    ifeq (${TF_M_EXTRAS_PATH},)
+        # Example: ../rss/tf-m-extras
+        $(error Error: TF_M_EXTRAS_PATH not set)
+    endif
+    ifeq (${MEASUREMENT_VALUE_SIZE},)
+        MEASUREMENT_VALUE_SIZE	:=	32
+    endif
+    ifeq (${MEASURED_BOOT_HASH_ALG},)
+        MEASURED_BOOT_HASH_ALG	:=	"PSA_ALG_SHA_256"
+    endif
+
+    DELEGATED_ATTEST_TESTS_PATH	=	$(TF_M_EXTRAS_PATH)/partitions/delegated_attestation/test
+    MEASURED_BOOT_TESTS_PATH	=	$(TF_M_EXTRAS_PATH)/partitions/measured_boot/test
+
+    MBEDTLS_CONFIG_FILE		=	"<plat_tc_mbedtls_config.h>"
+
+    LIBMBEDTLS_SRCS		+= 	$(addprefix ${MBEDTLS_DIR}/library/,	\
+					entropy.c				\
+					entropy_poll.c				\
+					hmac_drbg.c				\
+					psa_crypto.c				\
+					psa_crypto_client.c			\
+					psa_crypto_driver_wrappers.c		\
+					psa_crypto_hash.c			\
+					psa_crypto_rsa.c			\
+					psa_crypto_ecp.c			\
+					psa_crypto_slot_management.c		\
+					)
+
+    BL31_SOURCES	+=	${RSS_COMMS_SOURCES} 				\
+				plat/arm/common/arm_dyn_cfg.c 			\
+				${TC_BASE}/rss_ap_tests.c 			\
+				${TC_BASE}/rss_ap_testsuites.c 			\
+				${TC_BASE}/rss_ap_test_stubs.c			\
+				$(TF_M_TESTS_PATH)/test/framework/test_framework.c \
+				$(MEASURED_BOOT_TESTS_PATH)/measured_boot_common.c \
+				$(MEASURED_BOOT_TESTS_PATH)/measured_boot_tests_common.c \
+				$(DELEGATED_ATTEST_TESTS_PATH)/delegated_attest_test.c \
+				drivers/auth/mbedtls/mbedtls_common.c 		\
+				lib/psa/measured_boot.c 			\
+				lib/psa/delegated_attestation.c
+
+    PLAT_INCLUDES	+=	-I$(TF_M_EXTRAS_PATH)/partitions/measured_boot/interface/include \
+				-I$(TF_M_EXTRAS_PATH)/partitions/delegated_attestation/interface/include \
+				-I$(TF_M_TESTS_PATH)/test/framework 		\
+				-I$(TF_M_TESTS_PATH)/log 			\
+				-I$(TF_M_TESTS_PATH)/test/secure_fw/suites/extra \
+				-I$(MEASURED_BOOT_TESTS_PATH)/non_secure 	\
+				-I$(DELEGATED_ATTEST_TESTS_PATH) 		\
+				-I$(DELEGATED_ATTEST_TESTS_PATH)/non_secure \
+				-Iplat/arm/board/tc 				\
+				-Iinclude/drivers/auth/mbedtls 			\
+				-Iinclude/drivers/arm
+
+    # Some of the PSA functions are declared in multiple header files, that
+    # triggers this warning.
+    TF_CFLAGS		+=	-Wno-error=redundant-decls
+
+    # TODO: Created patch for warning in tf-m-tests
+    TF_CFLAGS		+=	-Wno-error=return-type
+
+    # Define macros that are used by the code coming from the tf-m-extras repo.
+    $(eval $(call add_define,MEASUREMENT_VALUE_SIZE))
+    $(eval $(call add_define,MEASURED_BOOT_HASH_ALG))
+    $(eval $(call add_define,DELEG_ATTEST_DUMP_TOKEN_AND_KEY))
+
+    $(eval $(call add_define,PLATFORM_TEST))
+endif
diff --git a/plat/arm/board/tc/region_defs.h b/plat/arm/board/tc/region_defs.h
new file mode 100644
index 0000000..d3dfd13
--- /dev/null
+++ b/plat/arm/board/tc/region_defs.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef REGION_DEFS_H
+#define REGION_DEFS_H
+
+#define PSA_INITIAL_ATTEST_TOKEN_MAX_SIZE   0x800
+
+#endif /* REGION_DEFS_H */
diff --git a/plat/arm/board/tc/rss_ap_test_stubs.c b/plat/arm/board/tc/rss_ap_test_stubs.c
new file mode 100644
index 0000000..aa97476
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_test_stubs.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <delegated_attestation.h>
+#include <measured_boot.h>
+#include <psa/error.h>
+
+
+psa_status_t
+tfm_measured_boot_extend_measurement(uint8_t index,
+				     const uint8_t *signer_id,
+				     size_t signer_id_size,
+				     const uint8_t *version,
+				     size_t version_size,
+				     uint32_t measurement_algo,
+				     const uint8_t *sw_type,
+				     size_t sw_type_size,
+				     const uint8_t *measurement_value,
+				     size_t measurement_value_size,
+				     bool lock_measurement)
+{
+	return rss_measured_boot_extend_measurement(index,
+						    signer_id,
+						    signer_id_size,
+						    version,
+						    version_size,
+						    measurement_algo,
+						    sw_type,
+						    sw_type_size,
+						    measurement_value,
+						    measurement_value_size,
+						    lock_measurement);
+}
+
+psa_status_t
+tfm_measured_boot_read_measurement(uint8_t index,
+				   uint8_t *signer_id,
+				   size_t signer_id_size,
+				   size_t *signer_id_len,
+				   uint8_t *version,
+				   size_t version_size,
+				   size_t *version_len,
+				   uint32_t *measurement_algo,
+				   uint8_t *sw_type,
+				   size_t sw_type_size,
+				   size_t *sw_type_len,
+				   uint8_t *measurement_value,
+				   size_t measurement_value_size,
+				   size_t *measurement_value_len,
+				   bool *is_locked)
+{
+	return rss_measured_boot_read_measurement(index,
+						  signer_id,
+						  signer_id_size,
+						  signer_id_len,
+						  version,
+						  version_size,
+						  version_len,
+						  measurement_algo,
+						  sw_type,
+						  sw_type_size,
+						  sw_type_len,
+						  measurement_value,
+						  measurement_value_size,
+						  measurement_value_len,
+						  is_locked);
+}
+
+psa_status_t
+tfm_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+			       size_t         dak_pub_hash_size,
+			       uint8_t       *token_buf,
+			       size_t         token_buf_size,
+			       size_t        *token_size)
+{
+	return rss_delegated_attest_get_token(dak_pub_hash,
+					      dak_pub_hash_size,
+					      token_buf,
+					      token_buf_size,
+					      token_size);
+}
+
+psa_status_t
+tfm_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+				       uint32_t  key_bits,
+				       uint8_t  *key_buf,
+				       size_t    key_buf_size,
+				       size_t   *key_size,
+				       uint32_t  hash_algo)
+{
+	return rss_delegated_attest_get_delegated_key(ecc_curve,
+						      key_bits,
+						      key_buf,
+						      key_buf_size,
+						      key_size,
+						      hash_algo);
+}
+
+int tfm_log_printf(const char *fmt, ...)
+{
+	int count;
+	va_list ap;
+
+	va_start(ap, fmt);
+	count = vprintf(fmt, ap);
+	va_end(ap);
+
+	return count;
+}
+
+void printf_set_color(int color_id)
+{
+	(void)color_id;
+}
diff --git a/plat/arm/board/tc/rss_ap_tests.c b/plat/arm/board/tc/rss_ap_tests.c
new file mode 100644
index 0000000..b62043e
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_tests.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <mbedtls_common.h>
+#include <plat/common/platform.h>
+#include <psa/crypto.h>
+#include <rss_comms.h>
+
+#include "rss_ap_testsuites.h"
+
+static struct test_suite_t test_suites[] = {
+	{.freg = register_testsuite_delegated_attest},
+	{.freg = register_testsuite_measured_boot},
+};
+
+static void run_tests(void)
+{
+	enum test_suite_err_t ret;
+	psa_status_t status;
+	size_t i;
+
+	rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+	mbedtls_init();
+	status = psa_crypto_init();
+	if (status != PSA_SUCCESS) {
+		printf("\n\npsa_crypto_init failed (status = %d)\n", status);
+		assert(false);
+		plat_error_handler(-1);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(test_suites); ++i) {
+		struct test_suite_t *suite = &(test_suites[i]);
+
+		suite->freg(suite);
+		ret = run_testsuite(suite);
+		if (ret != TEST_SUITE_ERR_NO_ERROR) {
+			printf("\n\nError during executing testsuite '%s'.\n", suite->name);
+			assert(false);
+			plat_error_handler(-1);
+		}
+	}
+	printf("\nAll tests are run.\n");
+}
+
+void run_platform_tests(void)
+{
+	size_t i;
+
+	run_tests();
+
+	printf("\n\n");
+
+	/* Print a summary of all the tests that had been run. */
+	printf("SUMMARY:\n");
+	for (i = 0; i < ARRAY_SIZE(test_suites); ++i) {
+
+		struct test_suite_t *suite = &(test_suites[i]);
+
+		switch (suite->val) {
+		case TEST_PASSED:
+			printf("    %s PASSED.\n", suite->name);
+			break;
+		case TEST_FAILED:
+			printf("    %s FAILED.\n", suite->name);
+			break;
+		case TEST_SKIPPED:
+			printf("    %s SKIPPED.\n", suite->name);
+			break;
+		default:
+			assert(false);
+			break;
+		}
+	}
+
+	printf("\n\n");
+}
diff --git a/plat/arm/board/tc/rss_ap_testsuites.c b/plat/arm/board/tc/rss_ap_testsuites.c
new file mode 100644
index 0000000..aa47d4c
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_testsuites.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * `delegated_attest_ns_interface_testsuite.c` and
+ * `measured_boot_ns_interface_testsuite.c` are not added to the build directly.
+ * but are included in this file, and this file is added to the build. This is
+ * necessary because both files define the function `extra_tests_init`, so a
+ * linker error occurs when both are linked to BL31. This file defines a macro
+ * that renames the colliding function names to something unique.
+ * `plat/arm/board/tc/rss_ap_tests.c` can call the test init functions with
+ * their new name.
+ */
+
+#define register_testsuite_extra_ns_interface \
+	register_testsuite_delegated_attest
+#include <delegated_attest_ns_interface_testsuite.c>
+
+#undef register_testsuite_extra_ns_interface
+#define register_testsuite_extra_ns_interface \
+	register_testsuite_measured_boot
+#include <measured_boot_ns_interface_testsuite.c>
\ No newline at end of file
diff --git a/plat/arm/board/tc/rss_ap_testsuites.h b/plat/arm/board/tc/rss_ap_testsuites.h
new file mode 100644
index 0000000..58502ab
--- /dev/null
+++ b/plat/arm/board/tc/rss_ap_testsuites.h
@@ -0,0 +1,16 @@
+
+/*
+ * Copyright (c) 2022, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RSS_AP_TESTSUITES_H
+#define RSS_AP_TESTSUITES_H
+
+#include <test_framework.h>
+
+void register_testsuite_measured_boot(struct test_suite_t *p_test_suite);
+void register_testsuite_delegated_attest(struct test_suite_t *p_test_suite);
+
+#endif /* RSS_AP_TESTSUITES_H */
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 0523ef8..c79558d 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,7 +33,7 @@
 	tc_bl31_common_platform_setup();
 }
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
 {
 
 	return &tc_scmi_plat_info[channel_id];
@@ -52,6 +52,12 @@
 void tc_bl31_common_platform_setup(void)
 {
 	arm_bl31_platform_setup();
+#ifdef PLATFORM_TEST
+	run_platform_tests();
+
+	/* Suspend booting */
+	plat_error_handler(-1);
+#endif
 }
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 08c014d..02e419a 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -143,11 +143,12 @@
 		ARM_PAS_SECURE,
 		ARM_PAS_REALM,
 		ARM_PAS_EL3_DRAM,
-		ARM_PAS_GPTS
+		ARM_PAS_GPTS,
+		ARM_PAS_KERNEL_1
 	};
 
 	/* Initialize entire protected space to GPT_GPI_ANY. */
-	if (gpt_init_l0_tables(GPCCR_PPS_4GB, ARM_L0_GPT_ADDR_BASE,
+	if (gpt_init_l0_tables(GPCCR_PPS_64GB, ARM_L0_GPT_ADDR_BASE,
 		ARM_L0_GPT_SIZE) < 0) {
 		ERROR("gpt_init_l0_tables() failed!\n");
 		panic();
diff --git a/plat/arm/common/trp/arm_trp_setup.c b/plat/arm/common/trp/arm_trp_setup.c
index 59b4c06..aeacd10 100644
--- a/plat/arm/common/trp/arm_trp_setup.c
+++ b/plat/arm/common/trp/arm_trp_setup.c
@@ -28,6 +28,9 @@
 
 static int arm_trp_process_manifest(rmm_manifest_t *manifest)
 {
+	/* padding field on the manifest must be RES0 */
+	assert(manifest->padding == 0U);
+
 	/* Verify the Boot Manifest Version. Only the Major is considered */
 	if (RMMD_MANIFEST_VERSION_MAJOR !=
 		RMMD_GET_MANIFEST_VERSION_MAJOR(manifest->version)) {
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 27cf183..9adcb7c 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -74,7 +74,7 @@
 	#endif
 };
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
 {
 	if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
diff --git a/plat/common/aarch64/crash_console_helpers.S b/plat/common/aarch64/crash_console_helpers.S
index e2950f5..75b4208 100644
--- a/plat/common/aarch64/crash_console_helpers.S
+++ b/plat/common/aarch64/crash_console_helpers.S
@@ -68,12 +68,12 @@
 	mov	x4, x30		/* x3 and x4 are not clobbered by spin_lock() */
 	mov	x3, #0		/* return value */
 
+	adrp	x0, crash_console_spinlock
+	add	x0, x0, :lo12:crash_console_spinlock
+
 	mrs	x1, sctlr_el3
 	tst	x1, #SCTLR_C_BIT
 	beq	skip_spinlock	/* can't synchronize when cache disabled */
-
-	adrp	x0, crash_console_spinlock
-	add	x0, x0, :lo12:crash_console_spinlock
 	bl	spin_lock
 
 skip_spinlock:
diff --git a/plat/imx/imx8m/imx8m_measured_boot.c b/plat/imx/imx8m/imx8m_measured_boot.c
index ec61606..e9ea2d8 100644
--- a/plat/imx/imx8m/imx8m_measured_boot.c
+++ b/plat/imx/imx8m/imx8m_measured_boot.c
@@ -24,17 +24,13 @@
 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
 };
 
-const event_log_metadata_t *plat_event_log_get_metadata(void)
-{
-	return imx8m_event_log_metadata;
-}
-
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
 {
 	/* Calculate image hash and record data in Event Log */
 	int err = event_log_measure_and_record(image_data->image_base,
 					       image_data->image_size,
-					       image_id);
+					       image_id,
+					       imx8m_event_log_metadata);
 	if (err != 0) {
 		ERROR("%s%s image id %u (%i)\n",
 		      "Failed to ", "record", image_id, err);
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index 59c3779..4706c20 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -124,6 +124,7 @@
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
+	static console_t console;
 	int i;
 	/* enable CSU NS access permission */
 	for (i = 0; i < 64; i++) {
@@ -132,12 +133,10 @@
 
 	imx_aipstz_init(aipstz);
 
-#if DEBUG_CONSOLE
-	static console_t console;
-
 	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
-#endif
+	/* This console is only used for boot stage */
+	console_set_scope(&console, CONSOLE_FLAG_BOOT);
 
 	imx8m_caam_init();
 
@@ -176,23 +175,22 @@
 
 void bl31_plat_arch_setup(void)
 {
-	mmap_add_region(BL31_BASE, BL31_BASE, (BL31_LIMIT - BL31_BASE),
-		MT_MEMORY | MT_RW | MT_SECURE);
-	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, (BL_CODE_END - BL_CODE_BASE),
-		MT_MEMORY | MT_RO | MT_SECURE);
-
-	/* Map TEE memory */
-	mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW);
-
-	mmap_add(imx_mmap);
-
+	const mmap_region_t bl_regions[] = {
+		MAP_REGION_FLAT(BL31_START, BL31_SIZE,
+				MT_MEMORY | MT_RW | MT_SECURE),
+		MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
+				MT_MEMORY | MT_RO | MT_SECURE),
 #if USE_COHERENT_MEM
-	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
-		BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
-		MT_DEVICE | MT_RW | MT_SECURE);
+		MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
+				BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+				MT_DEVICE | MT_RW | MT_SECURE),
 #endif
-	/* setup xlat table */
-	init_xlat_tables();
+		/* Map TEE memory */
+		MAP_REGION_FLAT(BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW),
+		{0},
+	};
+
+	setup_page_tables(bl_regions, imx_mmap);
 	/* enable the MMU */
 	enable_mmu_el3(0);
 }
@@ -227,11 +225,6 @@
 	return COUNTER_FREQUENCY;
 }
 
-void bl31_plat_runtime_setup(void)
-{
-	return;
-}
-
 #ifdef SPD_trusty
 void plat_trusty_set_boot_args(aapcs64_params_t *args)
 {
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_psci.c b/plat/imx/imx8m/imx8mq/imx8mq_psci.c
index 662017d..01582af 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_psci.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_psci.c
@@ -41,7 +41,7 @@
 
 void imx_domain_suspend(const psci_power_state_t *target_state)
 {
-	uint64_t base_addr = BL31_BASE;
+	uint64_t base_addr = BL31_START;
 	uint64_t mpidr = read_mpidr_el1();
 	unsigned int core_id = MPIDR_AFFLVL0_VAL(mpidr);
 
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index 1dd22d9..bb57074 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -4,6 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <plat/common/common_def.h>
+
 #define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
 #define PLATFORM_LINKER_ARCH		aarch64
 
@@ -31,7 +33,8 @@
 #define PLAT_STOP_OFF_STATE		U(3)
 
 #define BL31_BASE			U(0x910000)
-#define BL31_LIMIT			U(0x920000)
+#define BL31_SIZE			SZ_64K
+#define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
 
 /* non-secure uboot base */
 #define PLAT_NS_IMAGE_OFFSET		U(0x40200000)
@@ -54,7 +57,6 @@
 
 #define HAB_RVT_BASE			U(0x00000880) /* HAB_RVT for i.MX8MQ */
 
-#define IMX_BOOT_UART_BASE		U(0x30860000)
 #define IMX_BOOT_UART_CLK_IN_HZ		25000000 /* Select 25Mhz oscillator */
 #define PLAT_CRASH_UART_BASE		IMX_BOOT_UART_BASE
 #define PLAT_CRASH_UART_CLK_IN_HZ	25000000
@@ -128,5 +130,4 @@
 
 #define COUNTER_FREQUENCY		8333333 /* 25MHz / 3 */
 
-#define DEBUG_CONSOLE			0
 #define IMX_WDOG_B_RESET
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 7b6df92..901a974 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -38,6 +38,7 @@
 				${XLAT_TABLES_LIB_SRCS}				\
 				${IMX_GIC_SOURCES}
 
+ENABLE_PIE		:=	1
 USE_COHERENT_MEM	:=	1
 RESET_TO_BL31		:=	1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
@@ -52,6 +53,9 @@
 BL32_SIZE		?=	0x2000000
 $(eval $(call add_define,BL32_SIZE))
 
+IMX_BOOT_UART_BASE	?=	0x30860000
+$(eval $(call add_define,IMX_BOOT_UART_BASE))
+
 ifeq (${SPD},trusty)
 	BL31_CFLAGS    +=      -DPLAT_XLAT_TABLES_DYNAMIC=1
 endif
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index b1b9514..26ed7ef 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -17,6 +17,7 @@
 #include "ccu/ncore_ccu.h"
 #include "socfpga_mailbox.h"
 #include "socfpga_private.h"
+#include "socfpga_sip_svc.h"
 
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
@@ -35,6 +36,25 @@
 		return NULL;
 }
 
+void setup_smmu_secure_context(void)
+{
+	/*
+	 * Program SCR0 register (0xFA000000)
+	 * to set SMCFCFG bit[21] to 0x1 which raise stream match conflict fault
+	 * to set CLIENTPD bit[0] to 0x0 which enables SMMU for secure context
+	 */
+	mmio_write_32(0xFA000000, 0x00200000);
+
+	/*
+	 * Program SCR1 register (0xFA000004)
+	 * to set NSNUMSMRGO bit[14:8] to 0x4 which stream mapping register
+	 * for non-secure context and the rest will be secure context
+	 * to set NSNUMCBO bit[5:0] to 0x4 which allocate context bank
+	 * for non-secure context and the rest will be secure context
+	 */
+	mmio_write_32(0xFA000004, 0x00000404);
+}
+
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
@@ -109,6 +129,7 @@
 	gicv2_distif_init();
 	gicv2_pcpu_distif_init();
 	gicv2_cpuif_enable();
+	setup_smmu_secure_context();
 
 	/* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */
 	mmio_write_64(PLAT_CPU_RELEASE_ADDR,
diff --git a/plat/intel/soc/agilex/include/agilex_pinmux.h b/plat/intel/soc/agilex/include/agilex_pinmux.h
index fe01062..0701208 100644
--- a/plat/intel/soc/agilex/include/agilex_pinmux.h
+++ b/plat/intel/soc/agilex/include/agilex_pinmux.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,10 +7,25 @@
 #ifndef AGX_PINMUX_H
 #define AGX_PINMUX_H
 
-#define AGX_PINMUX_PIN0SEL		0xffd13000
-#define AGX_PINMUX_IO0CTRL		0xffd13130
-#define AGX_PINMUX_PINMUX_EMAC0_USEFPGA	0xffd13300
-#define AGX_PINMUX_IO0_DELAY		0xffd13400
+#define AGX_PINMUX_BASE					0xffd13000
+#define AGX_PINMUX_PIN0SEL				(AGX_PINMUX_BASE + 0x000)
+#define AGX_PINMUX_IO0CTRL				(AGX_PINMUX_BASE + 0x130)
+#define AGX_PINMUX_EMAC0_USEFPGA			(AGX_PINMUX_BASE + 0x300)
+#define AGX_PINMUX_EMAC1_USEFPGA			(AGX_PINMUX_BASE + 0x304)
+#define AGX_PINMUX_EMAC2_USEFPGA			(AGX_PINMUX_BASE + 0x308)
+#define AGX_PINMUX_NAND_USEFPGA				(AGX_PINMUX_BASE + 0x320)
+#define AGX_PINMUX_SPIM0_USEFPGA			(AGX_PINMUX_BASE + 0x328)
+#define AGX_PINMUX_SPIM1_USEFPGA			(AGX_PINMUX_BASE + 0x32c)
+#define AGX_PINMUX_SDMMC_USEFPGA			(AGX_PINMUX_BASE + 0x354)
+#define AGX_PINMUX_IO0_DELAY				(AGX_PINMUX_BASE + 0x400)
+
+#define AGX_PINMUX_NAND_USEFPGA_VAL			BIT(4)
+#define AGX_PINMUX_SDMMC_USEFPGA_VAL			BIT(8)
+#define AGX_PINMUX_SPIM0_USEFPGA_VAL			BIT(16)
+#define AGX_PINMUX_SPIM1_USEFPGA_VAL			BIT(24)
+#define AGX_PINMUX_EMAC0_USEFPGA_VAL			BIT(0)
+#define AGX_PINMUX_EMAC1_USEFPGA_VAL			BIT(8)
+#define AGX_PINMUX_EMAC2_USEFPGA_VAL			BIT(16)
 
 #include "socfpga_handoff.h"
 
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index ccb4e07..a1e58fc 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -80,5 +80,4 @@
 BL2_AT_EL3			:= 1
 BL2_INV_DCACHE			:= 0
 MULTI_CONSOLE_API		:= 1
-SIMICS_BUILD			:= 0
 USE_COHERENT_MEM		:= 1
diff --git a/plat/intel/soc/agilex/soc/agilex_pinmux.c b/plat/intel/soc/agilex/soc/agilex_pinmux.c
index 0b908cf..96e1ade 100644
--- a/plat/intel/soc/agilex/soc/agilex_pinmux.c
+++ b/plat/intel/soc/agilex/soc/agilex_pinmux.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -188,7 +188,27 @@
 
 void config_fpgaintf_mod(void)
 {
-	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), 1<<8);
+	uint32_t val;
+
+	val = 0;
+	if (mmio_read_32(AGX_PINMUX_NAND_USEFPGA) & 1)
+		val |= AGX_PINMUX_NAND_USEFPGA_VAL;
+	if (mmio_read_32(AGX_PINMUX_SDMMC_USEFPGA) & 1)
+		val |= AGX_PINMUX_SDMMC_USEFPGA_VAL;
+	if (mmio_read_32(AGX_PINMUX_SPIM0_USEFPGA) & 1)
+		val |= AGX_PINMUX_SPIM0_USEFPGA_VAL;
+	if (mmio_read_32(AGX_PINMUX_SPIM1_USEFPGA) & 1)
+		val |= AGX_PINMUX_SPIM1_USEFPGA_VAL;
+	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), val);
+
+	val = 0;
+	if (mmio_read_32(AGX_PINMUX_EMAC0_USEFPGA) & 1)
+		val |= AGX_PINMUX_EMAC0_USEFPGA_VAL;
+	if (mmio_read_32(AGX_PINMUX_EMAC1_USEFPGA) & 1)
+		val |= AGX_PINMUX_EMAC1_USEFPGA_VAL;
+	if (mmio_read_32(AGX_PINMUX_EMAC2_USEFPGA) & 1)
+		val |= AGX_PINMUX_EMAC2_USEFPGA_VAL;
+	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_3), val);
 }
 
 
@@ -208,8 +228,8 @@
 			hoff_ptr->pinmux_io_array[i+1]);
 	}
 
-	for (i = 0; i < 42; i += 2) {
-		mmio_write_32(AGX_PINMUX_PINMUX_EMAC0_USEFPGA +
+	for (i = 0; i < 40; i += 2) {
+		mmio_write_32(AGX_PINMUX_EMAC0_USEFPGA +
 			hoff_ptr->pinmux_fpga_array[i],
 			hoff_ptr->pinmux_fpga_array[i+1]);
 	}
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index d9a238e..99d48d2 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -40,7 +40,7 @@
 			dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER);
 
 			/* Initialize All Entries */
-			mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(dir));
+			mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(sf));
 
 			/* Poll Active Bit */
 			ret = poll_active_bit(dir);
@@ -49,8 +49,9 @@
 				return -ETIMEDOUT;
 			}
 
-			/* Snoope Filter Enable */
-			mmio_setbits_32(dir_sf_en, BIT(sf));
+			/* Disable snoop filter, a bit per snoop filter */
+			mmio_clrbits_32(dir_sf_en, BIT(sf));
+
 		}
 	}
 
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index a31adf7..2b3f144 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -17,6 +17,7 @@
 #define PLAT_SOCFPGA_STRATIX10			1
 #define PLAT_SOCFPGA_AGILEX			2
 #define PLAT_SOCFPGA_N5X			3
+#define PLAT_SOCFPGA_EMULATOR			0
 
 /* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
 #define PLAT_CPU_RELEASE_ADDR			0xffd12210
@@ -170,14 +171,12 @@
 #define CRASH_CONSOLE_BASE	PLAT_UART0_BASE
 #define PLAT_INTEL_UART_BASE	PLAT_UART0_BASE
 
-#ifndef SIMICS_BUILD
-#define PLAT_BAUDRATE		(115200)
-#define PLAT_UART_CLOCK		(100000000)
-
-#else
+#if PLAT_SOCFPGA_EMULATOR
 #define PLAT_BAUDRATE		(4800)
 #define PLAT_UART_CLOCK		(76800)
-
+#else
+#define PLAT_BAUDRATE		(115200)
+#define PLAT_UART_CLOCK		(100000000)
 #endif
 
 /*******************************************************************************
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
index 893551d..8a8f348 100644
--- a/plat/intel/soc/common/include/socfpga_fcs.h
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -84,6 +84,14 @@
 #define FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE			17U
 #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
+
 /* FCS Payload Structure */
 typedef struct fcs_rng_payload_t {
 	uint32_t session_id;
@@ -235,6 +243,11 @@
 				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_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,
+				uint8_t is_finalised, uint32_t *mbox_error,
+				uint32_t *send_id);
 
 int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
 				uint32_t key_id, uint32_t param_size,
@@ -244,6 +257,11 @@
 				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_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,
+				uint32_t data_size, uint8_t is_finalised,
+				uint32_t *mbox_error, uint32_t *send_id);
 
 int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
 				uint32_t key_id, uint32_t param_size,
@@ -270,6 +288,11 @@
 				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_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, uint8_t is_finalised,
+				uint32_t *mbox_error, uint32_t *send_id);
 
 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
 				uint32_t context_id, uint32_t key_id,
@@ -280,6 +303,12 @@
 				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_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, uint32_t data_size,
+				uint8_t is_finalised, uint32_t *mbox_error,
+				uint32_t *send_id);
 
 int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
 				uint32_t key_id, uint32_t param_size,
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 1f4b2a4..3abf39d 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -129,6 +129,10 @@
 #define MBOX_BUSY					-5
 #define MBOX_TIMEOUT					-2047
 
+/* Key Status */
+#define MBOX_RET_SDOS_DECRYPTION_ERROR_102		-258
+#define MBOX_RET_SDOS_DECRYPTION_ERROR_103		-259
+
 /* Reconfig Status Response */
 #define RECONFIG_STATUS_STATE				0
 #define RECONFIG_STATUS_PIN_STATUS			2
@@ -139,6 +143,7 @@
 #define SOFTFUNC_STATUS_CONF_DONE			(1 << 0)
 #define MBOX_CFGSTAT_STATE_IDLE				0x00000000
 #define MBOX_CFGSTAT_STATE_CONFIG			0x10000000
+#define MBOX_CFGSTAT_VAB_BS_PREAUTH			0x20000000
 #define MBOX_CFGSTAT_STATE_FAILACK			0x08000000
 #define MBOX_CFGSTAT_STATE_ERROR_INVALID		0xf0000001
 #define MBOX_CFGSTAT_STATE_ERROR_CORRUPT		0xf0000002
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 0803eb5..21169f7 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -86,49 +86,57 @@
 #define INTEL_SIP_SMC_GET_USERCODE				0xC200003D
 
 /* FPGA Crypto Services */
-#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER				0xC200005A
-#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER_EXT			0x4200008F
-#define INTEL_SIP_SMC_FCS_CRYPTION				0x4200005B
-#define INTEL_SIP_SMC_FCS_CRYPTION_EXT				0xC2000090
-#define INTEL_SIP_SMC_FCS_SERVICE_REQUEST			0x4200005C
-#define INTEL_SIP_SMC_FCS_SEND_CERTIFICATE			0x4200005D
-#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA			0x4200005E
-#define INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH			0xC200005F
-#define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN			0xC2000064
-#define INTEL_SIP_SMC_FCS_CHIP_ID				0xC2000065
-#define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY			0xC2000066
-#define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS		0xC2000067
-#define INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT			0xC2000068
-#define INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD			0xC2000069
-#define INTEL_SIP_SMC_FCS_OPEN_CS_SESSION			0xC200006E
-#define INTEL_SIP_SMC_FCS_CLOSE_CS_SESSION			0xC200006F
-#define INTEL_SIP_SMC_FCS_IMPORT_CS_KEY				0x42000070
-#define INTEL_SIP_SMC_FCS_EXPORT_CS_KEY				0xC2000071
-#define INTEL_SIP_SMC_FCS_REMOVE_CS_KEY				0xC2000072
-#define INTEL_SIP_SMC_FCS_GET_CS_KEY_INFO			0xC2000073
-#define INTEL_SIP_SMC_FCS_AES_CRYPT_INIT			0xC2000074
-#define INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE			0x42000075
-#define INTEL_SIP_SMC_FCS_AES_CRYPT_FINALIZE			0x42000076
-#define INTEL_SIP_SMC_FCS_GET_DIGEST_INIT			0xC2000077
-#define INTEL_SIP_SMC_FCS_GET_DIGEST_UPDATE			0xC2000078
-#define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE			0xC2000079
-#define INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT			0xC200007A
-#define INTEL_SIP_SMC_FCS_MAC_VERIFY_UPDATE			0xC200007B
-#define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE			0xC200007C
-#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT			0xC200007D
-#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_FINALIZE		0xC200007F
-#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT		0xC2000080
-#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE		0xC2000081
-#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE		0xC2000082
-#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_INIT		0xC2000083
-#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE	0xC2000085
-#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT	0xC2000086
-#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE	0xC2000087
-#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE	0xC2000088
-#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT			0xC2000089
-#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE		0xC200008B
-#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT			0xC200008C
-#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE			0xC200008E
+#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER					0xC200005A
+#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER_EXT				0x4200008F
+#define INTEL_SIP_SMC_FCS_CRYPTION					0x4200005B
+#define INTEL_SIP_SMC_FCS_CRYPTION_EXT					0xC2000090
+#define INTEL_SIP_SMC_FCS_SERVICE_REQUEST				0x4200005C
+#define INTEL_SIP_SMC_FCS_SEND_CERTIFICATE				0x4200005D
+#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA				0x4200005E
+#define INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH				0xC200005F
+#define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN				0xC2000064
+#define INTEL_SIP_SMC_FCS_CHIP_ID					0xC2000065
+#define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY				0xC2000066
+#define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS			0xC2000067
+#define INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT				0xC2000068
+#define INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD				0xC2000069
+#define INTEL_SIP_SMC_FCS_OPEN_CS_SESSION				0xC200006E
+#define INTEL_SIP_SMC_FCS_CLOSE_CS_SESSION				0xC200006F
+#define INTEL_SIP_SMC_FCS_IMPORT_CS_KEY					0x42000070
+#define INTEL_SIP_SMC_FCS_EXPORT_CS_KEY					0xC2000071
+#define INTEL_SIP_SMC_FCS_REMOVE_CS_KEY					0xC2000072
+#define INTEL_SIP_SMC_FCS_GET_CS_KEY_INFO				0xC2000073
+#define INTEL_SIP_SMC_FCS_AES_CRYPT_INIT				0xC2000074
+#define INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE				0x42000075
+#define INTEL_SIP_SMC_FCS_AES_CRYPT_FINALIZE				0x42000076
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_INIT				0xC2000077
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_UPDATE				0xC2000078
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE				0xC2000079
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_SMMU_UPDATE			0x42000091
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_SMMU_FINALIZE			0x42000092
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT				0xC200007A
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_UPDATE				0xC200007B
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE				0xC200007C
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_SMMU_UPDATE			0x42000093
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_SMMU_FINALIZE			0x42000094
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT				0xC200007D
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_FINALIZE			0xC200007F
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT			0xC2000080
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE			0xC2000081
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE			0xC2000082
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_UPDATE		0x42000095
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_FINALIZE		0x42000096
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_INIT			0xC2000083
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE		0xC2000085
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT		0xC2000086
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE		0xC2000087
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE		0xC2000088
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_UPDATE	0x42000097
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_FINALIZE	0x42000098
+#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT				0xC2000089
+#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE			0xC200008B
+#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT				0xC200008C
+#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE				0xC200008E
 
 #define INTEL_SIP_SMC_FCS_SHA_MODE_MASK				0xF
 #define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK			0xF
@@ -166,8 +174,14 @@
 #define SIP_SVC_VERSION						0x8200ff03
 
 /* SiP Service Calls version numbers */
-#define SIP_SVC_VERSION_MAJOR					1
-#define SIP_SVC_VERSION_MINOR					0
+/*
+ * Increase if there is any backward compatibility impact
+ */
+#define SIP_SVC_VERSION_MAJOR					2
+/*
+ * Increase if there is new SMC function ID being added
+ */
+#define SIP_SVC_VERSION_MINOR					1
 
 
 /* Structure Definitions */
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 7f67313..69ee6d3 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -42,6 +42,8 @@
 #define IDLE_DATA_SOC2FPGA				BIT(0)
 #define IDLE_DATA_MASK		(IDLE_DATA_LWSOC2FPGA | IDLE_DATA_SOC2FPGA)
 
+#define SYSMGR_QSPI_REFCLK_MASK				GENMASK(27, 0)
+
 #define SYSMGR_ECC_OCRAM_MASK				BIT(1)
 #define SYSMGR_ECC_DDR0_MASK				BIT(16)
 #define SYSMGR_ECC_DDR1_MASK				BIT(17)
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index facee0f..3b0b370 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -411,7 +411,10 @@
 				(uint32_t *) &payload, payload_size,
 				CMD_CASUAL, resp_data, &resp_len);
 
-	if (status < 0) {
+	if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 ||
+		status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) {
+		*mbox_error = -status;
+	} else if (status < 0) {
 		*mbox_error = -status;
 		return INTEL_SIP_SMC_STATUS_ERROR;
 	}
@@ -946,6 +949,104 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+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, uint8_t is_finalised,
+				uint32_t *mbox_error, uint32_t *send_id)
+{
+	int status;
+	uint32_t i;
+	uint32_t flag;
+	uint32_t crypto_header;
+	uint32_t resp_len;
+	uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
+
+	/* Source data must be 8 bytes aligned */
+	if (dst_size == NULL || mbox_error == NULL ||
+		!is_8_bytes_aligned(src_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (fcs_sha_get_digest_param.session_id != session_id ||
+	    fcs_sha_get_digest_param.context_id != context_id) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (!is_address_in_ddr_range(src_addr, src_size) ||
+		 !is_address_in_ddr_range(dst_addr, *dst_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	resp_len = *dst_size / MBOX_WORD_BYTE;
+
+	/* Prepare crypto header */
+	flag = 0;
+
+	if (fcs_sha_get_digest_param.is_updated) {
+		fcs_sha_get_digest_param.crypto_param_size = 0;
+	} else {
+		flag |=  FCS_CS_FIELD_FLAG_INIT;
+	}
+
+	if (is_finalised != 0U) {
+		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
+	} else {
+		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
+		fcs_sha_get_digest_param.is_updated = 1;
+	}
+
+	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
+			(fcs_sha_get_digest_param.crypto_param_size &
+			FCS_CS_FIELD_SIZE_MASK));
+
+	/* Prepare command payload */
+	i = 0;
+	payload[i] = fcs_sha_get_digest_param.session_id;
+	i++;
+	payload[i] = fcs_sha_get_digest_param.context_id;
+	i++;
+	payload[i] = crypto_header;
+	i++;
+
+	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+		FCS_CS_FIELD_FLAG_INIT) {
+		payload[i] = fcs_sha_get_digest_param.key_id;
+		i++;
+		/* Crypto parameters */
+		payload[i] = fcs_sha_get_digest_param.crypto_param
+				& INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
+		payload[i] |= ((fcs_sha_get_digest_param.crypto_param
+				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
+				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
+				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
+		i++;
+	}
+	/* Data source address and size */
+	payload[i] = src_addr;
+	i++;
+	payload[i] = src_size;
+	i++;
+
+	status = mailbox_send_cmd_async(send_id, MBOX_FCS_GET_DIGEST_REQ,
+					payload, i, CMD_INDIRECT);
+
+	if (is_finalised != 0U) {
+		memset((void *)&fcs_sha_get_digest_param, 0,
+		sizeof(fcs_crypto_service_data));
+	}
+
+	if (status < 0) {
+		*mbox_error = -status;
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	*dst_size = resp_len * MBOX_WORD_BYTE;
+	flush_dcache_range(dst_addr, *dst_size);
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 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)
@@ -1071,6 +1172,127 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+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, uint32_t data_size,
+				uint8_t is_finalised, uint32_t *mbox_error,
+				uint32_t *send_id)
+{
+	int status;
+	uint32_t i;
+	uint32_t flag;
+	uint32_t crypto_header;
+	uint32_t resp_len;
+	uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
+	uintptr_t mac_offset;
+
+	/*
+	 * Source data must be 4 bytes aligned
+	 * User data must be 8 bytes aligned
+	 */
+	if (dst_size == NULL || mbox_error == NULL ||
+		!is_size_4_bytes_aligned(src_size) ||
+		!is_8_bytes_aligned(data_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (data_size > src_size) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (fcs_sha_mac_verify_param.session_id != session_id ||
+		fcs_sha_mac_verify_param.context_id != context_id) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (!is_address_in_ddr_range(src_addr, src_size) ||
+		!is_address_in_ddr_range(dst_addr, *dst_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	resp_len = *dst_size / MBOX_WORD_BYTE;
+
+	/* Prepare crypto header */
+	flag = 0;
+
+	if (fcs_sha_mac_verify_param.is_updated) {
+		fcs_sha_mac_verify_param.crypto_param_size = 0;
+	} else {
+		flag |=  FCS_CS_FIELD_FLAG_INIT;
+	}
+
+	if (is_finalised) {
+		flag |=  FCS_CS_FIELD_FLAG_FINALIZE;
+	} else {
+		flag |=  FCS_CS_FIELD_FLAG_UPDATE;
+		fcs_sha_mac_verify_param.is_updated = 1;
+	}
+
+	crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
+			(fcs_sha_mac_verify_param.crypto_param_size &
+			FCS_CS_FIELD_SIZE_MASK));
+
+	/* Prepare command payload */
+	i = 0;
+	payload[i] = fcs_sha_mac_verify_param.session_id;
+	i++;
+	payload[i] = fcs_sha_mac_verify_param.context_id;
+	i++;
+	payload[i] = crypto_header;
+	i++;
+
+	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+		FCS_CS_FIELD_FLAG_INIT) {
+		payload[i] = fcs_sha_mac_verify_param.key_id;
+		i++;
+		/* Crypto parameters */
+		payload[i] = ((fcs_sha_mac_verify_param.crypto_param
+				>> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
+				& INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
+				<< FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
+		i++;
+	}
+	/* Data source address and size */
+	payload[i] = src_addr;
+	i++;
+	payload[i] = data_size;
+	i++;
+
+	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+		FCS_CS_FIELD_FLAG_FINALIZE) {
+		/* Copy mac data to command
+		 * Using dst_addr (physical address) to store mac_offset
+		 * mac_offset = MAC data
+		 */
+		mac_offset = dst_addr;
+		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
+		src_size - data_size);
+
+		memset((void *)&dst_addr, 0, sizeof(dst_size));
+
+		i += (src_size - data_size) / MBOX_WORD_BYTE;
+	}
+
+	status = mailbox_send_cmd_async(send_id, MBOX_FCS_MAC_VERIFY_REQ,
+					payload, i, CMD_INDIRECT);
+
+	if (is_finalised) {
+		memset((void *)&fcs_sha_mac_verify_param, 0,
+		sizeof(fcs_crypto_service_data));
+	}
+
+	if (status < 0) {
+		*mbox_error = -status;
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	*dst_size = resp_len * MBOX_WORD_BYTE;
+	flush_dcache_range(dst_addr, *dst_size);
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 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)
@@ -1348,6 +1570,99 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+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,
+				uint32_t *dst_size, uint8_t is_finalised,
+				uint32_t *mbox_error, uint32_t *send_id)
+{
+	int status;
+	int i;
+	uint32_t flag;
+	uint32_t crypto_header;
+	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
+	uint32_t resp_len;
+
+	/* Source data must be 8 bytes aligned */
+	if ((dst_size == NULL) || (mbox_error == NULL ||
+		!is_8_bytes_aligned(src_size))) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (fcs_sha2_data_sign_param.session_id != session_id ||
+		fcs_sha2_data_sign_param.context_id != context_id) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (!is_address_in_ddr_range(src_addr, src_size) ||
+		!is_address_in_ddr_range(dst_addr, *dst_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	resp_len = *dst_size / MBOX_WORD_BYTE;
+
+	/* Prepare crypto header */
+	flag = 0;
+	if (fcs_sha2_data_sign_param.is_updated) {
+		fcs_sha2_data_sign_param.crypto_param_size = 0;
+	} else {
+		flag |= FCS_CS_FIELD_FLAG_INIT;
+	}
+
+	if (is_finalised != 0U) {
+		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+	} else {
+		flag |= FCS_CS_FIELD_FLAG_UPDATE;
+		fcs_sha2_data_sign_param.is_updated = 1;
+	}
+	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
+			fcs_sha2_data_sign_param.crypto_param_size;
+
+	/* Prepare command payload */
+	i = 0;
+	payload[i] = fcs_sha2_data_sign_param.session_id;
+	i++;
+	payload[i] = fcs_sha2_data_sign_param.context_id;
+	i++;
+	payload[i] = crypto_header;
+	i++;
+
+	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+		FCS_CS_FIELD_FLAG_INIT) {
+		payload[i] = fcs_sha2_data_sign_param.key_id;
+		/* Crypto parameters */
+		i++;
+		payload[i] = fcs_sha2_data_sign_param.crypto_param
+				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+		i++;
+	}
+
+	/* Data source address and size */
+	payload[i] = src_addr;
+	i++;
+	payload[i] = src_size;
+	i++;
+
+	status = mailbox_send_cmd_async(send_id,
+					MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ,
+					payload, i, CMD_INDIRECT);
+
+	if (is_finalised != 0U) {
+		memset((void *)&fcs_sha2_data_sign_param, 0,
+			sizeof(fcs_crypto_service_data));
+	}
+
+	if (status < 0) {
+		*mbox_error = -status;
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	*dst_size = resp_len * MBOX_WORD_BYTE;
+	flush_dcache_range(dst_addr, *dst_size);
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
 				uint32_t context_id, uint32_t key_id,
 				uint32_t param_size, uint64_t param_data,
@@ -1469,6 +1784,121 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+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,
+				uint32_t *dst_size, uint32_t data_size,
+				uint8_t is_finalised, uint32_t *mbox_error,
+				uint32_t *send_id)
+{
+	int status;
+	uint32_t i;
+	uint32_t flag;
+	uint32_t crypto_header;
+	uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
+	uint32_t resp_len;
+	uintptr_t sig_pubkey_offset;
+
+	/*
+	 * Source data must be 4 bytes aligned
+	 * Source addrress must be 8 bytes aligned
+	 * User data must be 8 bytes aligned
+	 */
+	if ((dst_size == NULL) || (mbox_error == NULL) ||
+		!is_size_4_bytes_aligned(src_size) ||
+		!is_8_bytes_aligned(src_addr) ||
+		!is_8_bytes_aligned(data_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
+		fcs_sha2_data_sig_verify_param.context_id != context_id) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (!is_address_in_ddr_range(src_addr, src_size) ||
+		!is_address_in_ddr_range(dst_addr, *dst_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	resp_len = *dst_size / MBOX_WORD_BYTE;
+
+	/* Prepare crypto header */
+	flag = 0;
+	if (fcs_sha2_data_sig_verify_param.is_updated)
+		fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
+	else
+		flag |= FCS_CS_FIELD_FLAG_INIT;
+
+	if (is_finalised != 0U)
+		flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+	else {
+		flag |= FCS_CS_FIELD_FLAG_UPDATE;
+		fcs_sha2_data_sig_verify_param.is_updated = 1;
+	}
+	crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
+			fcs_sha2_data_sig_verify_param.crypto_param_size;
+
+	/* Prepare command payload */
+	i = 0;
+	payload[i] = fcs_sha2_data_sig_verify_param.session_id;
+	i++;
+	payload[i] = fcs_sha2_data_sig_verify_param.context_id;
+	i++;
+	payload[i] = crypto_header;
+	i++;
+
+	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+		FCS_CS_FIELD_FLAG_INIT) {
+		payload[i] = fcs_sha2_data_sig_verify_param.key_id;
+		i++;
+		/* Crypto parameters */
+		payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
+				& INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+		i++;
+	}
+
+	/* Data source address and size */
+	payload[i] = src_addr;
+	i++;
+	payload[i] = data_size;
+	i++;
+
+	if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+		FCS_CS_FIELD_FLAG_FINALIZE) {
+		/* Copy mac data to command
+		 * Using dst_addr (physical address) to store sig_pubkey_offset
+		 * sig_pubkey_offset is Signature + Public Key Data
+		 */
+		sig_pubkey_offset = dst_addr;
+		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
+			src_size - data_size);
+
+		memset((void *)&dst_addr, 0, sizeof(dst_size));
+
+		i += (src_size - data_size) / MBOX_WORD_BYTE;
+	}
+
+	status = mailbox_send_cmd_async(send_id,
+					MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY,
+					payload, i, CMD_INDIRECT);
+
+	if (is_finalised != 0U) {
+		memset((void *) &fcs_sha2_data_sig_verify_param, 0,
+			sizeof(fcs_crypto_service_data));
+	}
+
+	if (status < 0) {
+		*mbox_error = -status;
+		return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	*dst_size = resp_len * MBOX_WORD_BYTE;
+	flush_dcache_range(dst_addr, *dst_size);
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 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)
@@ -1620,6 +2050,29 @@
 				uint32_t key_id, uint64_t param_addr,
 				uint32_t param_size, uint32_t *mbox_error)
 {
+	/* ptr to get param_addr value */
+	uint64_t *param_addr_ptr;
+
+	param_addr_ptr = (uint64_t *) param_addr;
+
+	/*
+	 * Since crypto param size vary between mode.
+	 * Check ECB here and limit to size 12 bytes
+	 */
+	if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
+		(param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+	/*
+	 * Since crypto param size vary between mode.
+	 * 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_size > FCS_CRYPTO_CBC_CTR_BUFFER_SIZE)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	if (mbox_error == NULL) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
diff --git a/plat/intel/soc/common/soc/socfpga_firewall.c b/plat/intel/soc/common/soc/socfpga_firewall.c
index 515784b..fc3889c 100644
--- a/plat/intel/soc/common/soc/socfpga_firewall.c
+++ b/plat/intel/soc/common/soc/socfpga_firewall.c
@@ -60,6 +60,7 @@
 	mmio_write_32(SOCFPGA_L4_PER_SCR(I2C3), DISABLE_L4_FIREWALL);
 	mmio_write_32(SOCFPGA_L4_PER_SCR(I2C4), DISABLE_L4_FIREWALL);
 
+	mmio_write_32(SOCFPGA_L4_PER_SCR(SP_TIMER0), DISABLE_L4_FIREWALL);
 	mmio_write_32(SOCFPGA_L4_PER_SCR(SP_TIMER1), DISABLE_L4_FIREWALL);
 
 	mmio_write_32(SOCFPGA_L4_PER_SCR(UART0), DISABLE_L4_FIREWALL);
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 79817e6..7010d81 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -10,6 +10,7 @@
 
 #include "socfpga_mailbox.h"
 #include "socfpga_sip_svc.h"
+#include "socfpga_system_manager.h"
 
 static mailbox_payload_t mailbox_resp_payload;
 static mailbox_container_t mailbox_resp_ctr = {0, 0, &mailbox_resp_payload};
@@ -464,8 +465,26 @@
 
 void mailbox_set_qspi_direct(void)
 {
+	uint32_t response[1], qspi_clk, reg;
+	unsigned int resp_len = ARRAY_SIZE(response);
+
 	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, NULL, 0U,
-				CMD_CASUAL, NULL, NULL);
+			 CMD_CASUAL, response, &resp_len);
+
+	qspi_clk = response[0];
+	INFO("QSPI ref clock: %u\n", qspi_clk);
+
+	/*
+	 * Store QSPI ref clock frequency in BOOT_SCRATCH_COLD_0 register for
+	 * later boot loader (i.e. u-boot) use.
+	 * The frequency is stored in kHz and occupies BOOT_SCRATCH_COLD_0
+	 * register bits[27:0].
+	 */
+	qspi_clk /= 1000;
+	reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_0));
+	reg &= ~SYSMGR_QSPI_REFCLK_MASK;
+	reg |= qspi_clk & SYSMGR_QSPI_REFCLK_MASK;
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_0), reg);
 }
 
 void mailbox_set_qspi_close(void)
@@ -590,6 +609,11 @@
 	}
 
 	res = response[RECONFIG_STATUS_STATE];
+
+	if (res == MBOX_CFGSTAT_VAB_BS_PREAUTH) {
+		return MBOX_CFGSTAT_STATE_CONFIG;
+	}
+
 	if ((res != 0U) && (res != MBOX_CFGSTAT_STATE_CONFIG)) {
 		return res;
 	}
@@ -601,7 +625,7 @@
 
 	res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
 	if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) {
-		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
+		ERROR("SoftFunction Status SEU ERROR\n");
 	}
 
 	if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index f079349..79f743f 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -344,6 +344,28 @@
 	case(0xF8011120):	/* INTSTAT */
 	case(0xF8011124):	/* DIAGINTTEST */
 	case(0xF801112C):	/* DERRADDRA */
+	case(0xFA000000):	/* SMMU SCR0 */
+	case(0xFA000004):	/* SMMU SCR1 */
+	case(0xFA000400):	/* SMMU NSCR0 */
+	case(0xFA004000):	/* SMMU SSD0_REG */
+	case(0xFA000820):	/* SMMU SMR8 */
+	case(0xFA000c20):	/* SMMU SCR8 */
+	case(0xFA028000):	/* SMMU CB8_SCTRL */
+	case(0xFA001020):	/* SMMU CBAR8 */
+	case(0xFA028030):	/* SMMU TCR_LPAE */
+	case(0xFA028020):	/* SMMU CB8_TTBR0_LOW */
+	case(0xFA028024):	/* SMMU CB8_PRRR_HIGH */
+	case(0xFA028038):	/* SMMU CB8_PRRR_MIR0 */
+	case(0xFA02803C):	/* SMMU CB8_PRRR_MIR1 */
+	case(0xFA028010):	/* SMMU_CB8)TCR2 */
+	case(0xFFD080A4):	/* SDM SMMU STREAM ID REG */
+	case(0xFA001820):	/* SMMU_CBA2R8 */
+	case(0xFA000074):	/* SMMU_STLBGSTATUS */
+	case(0xFA0287F4):	/* SMMU_CB8_TLBSTATUS */
+	case(0xFA000060):	/* SMMU_STLBIALL */
+	case(0xFA000070):	/* SMMU_STLBGSYNC */
+	case(0xFA028618):	/* CB8_TLBALL */
+	case(0xFA0287F0):	/* CB8_TLBSYNC */
 	case(0xFFD12028):	/* SDMMCGRP_CTRL */
 	case(0xFFD12044):	/* EMAC0 */
 	case(0xFFD12048):	/* EMAC1 */
@@ -469,10 +491,6 @@
 /* Intel HWMON services */
 static uint32_t intel_hwmon_readtemp(uint32_t chan, uint32_t *retval)
 {
-	if (chan > TEMP_CHANNEL_MAX) {
-		return INTEL_SIP_SMC_STATUS_ERROR;
-	}
-
 	if (mailbox_hwmon_readtemp(chan, retval) < 0) {
 		return INTEL_SIP_SMC_STATUS_ERROR;
 	}
@@ -482,10 +500,6 @@
 
 static uint32_t intel_hwmon_readvolt(uint32_t chan, uint32_t *retval)
 {
-	if (chan > VOLT_CHANNEL_MAX) {
-		return INTEL_SIP_SMC_STATUS_ERROR;
-	}
-
 	if (mailbox_hwmon_readvolt(chan, retval) < 0) {
 		return INTEL_SIP_SMC_STATUS_ERROR;
 	}
@@ -597,7 +611,10 @@
 	*ret_size = resp_len * MBOX_WORD_BYTE;
 	flush_dcache_range(addr, *ret_size);
 
-	if (status != MBOX_RET_OK) {
+	if (status == MBOX_RET_SDOS_DECRYPTION_ERROR_102 ||
+		status == MBOX_RET_SDOS_DECRYPTION_ERROR_103) {
+		*mbox_error = -status;
+	} else if (status != MBOX_RET_OK) {
 		*mbox_error = -status;
 		return INTEL_SIP_SMC_STATUS_ERROR;
 	}
@@ -935,6 +952,22 @@
 					&mbox_error);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
+	case INTEL_SIP_SMC_FCS_GET_DIGEST_SMMU_UPDATE:
+		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+		status = intel_fcs_get_digest_smmu_update_finalize(x1, x2, x3,
+					x4, x5, (uint32_t *) &x6, false,
+					&mbox_error, &send_id);
+		SMC_RET4(handle, status, mbox_error, x5, x6);
+
+	case INTEL_SIP_SMC_FCS_GET_DIGEST_SMMU_FINALIZE:
+		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+		status = intel_fcs_get_digest_smmu_update_finalize(x1, x2, x3,
+					x4, x5, (uint32_t *) &x6, true,
+					&mbox_error, &send_id);
+		SMC_RET4(handle, status, mbox_error, x5, x6);
+
 	case INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		status = intel_fcs_mac_verify_init(x1, x2, x3,
@@ -959,6 +992,24 @@
 					true, &mbox_error);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
+	case INTEL_SIP_SMC_FCS_MAC_VERIFY_SMMU_UPDATE:
+		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_smmu_update_finalize(x1, x2, x3,
+					x4, x5, (uint32_t *) &x6, x7,
+					false, &mbox_error, &send_id);
+		SMC_RET4(handle, status, mbox_error, x5, x6);
+
+	case INTEL_SIP_SMC_FCS_MAC_VERIFY_SMMU_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_smmu_update_finalize(x1, x2, x3,
+					x4, x5, (uint32_t *) &x6, x7,
+					true, &mbox_error, &send_id);
+		SMC_RET4(handle, status, mbox_error, x5, x6);
+
 	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		status = intel_fcs_ecdsa_sha2_data_sign_init(x1, x2, x3,
@@ -981,6 +1032,22 @@
 					&mbox_error);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
+	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_UPDATE:
+		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+		status = intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(x1,
+					x2, x3, x4, x5, (uint32_t *) &x6, false,
+					&mbox_error, &send_id);
+		SMC_RET4(handle, status, mbox_error, x5, x6);
+
+	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_FINALIZE:
+		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+		status = intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(x1,
+					x2, x3, x4, x5, (uint32_t *) &x6, true,
+					&mbox_error, &send_id);
+		SMC_RET4(handle, status, mbox_error, x5, x6);
+
 	case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		status = intel_fcs_ecdsa_hash_sign_init(x1, x2, x3,
@@ -1022,6 +1089,24 @@
 					x7, false, &mbox_error);
 		SMC_RET4(handle, status, mbox_error, x5, x6);
 
+	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_UPDATE:
+		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_ecdsa_sha2_data_sig_verify_smmu_update_finalize(
+					x1, x2, x3, x4, x5, (uint32_t *) &x6,
+					x7, false, &mbox_error, &send_id);
+		SMC_RET4(handle, status, mbox_error, x5, x6);
+
+	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_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_ecdsa_sha2_data_sig_verify_smmu_update_finalize(
+					x1, x2, x3, x4, x5, (uint32_t *) &x6,
+					x7, true, &mbox_error, &send_id);
+		SMC_RET4(handle, status, mbox_error, x5, x6);
+
 	case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 		x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index 953bf0c..be1ad8c 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -49,5 +49,4 @@
 BL2_AT_EL3			:= 1
 BL2_INV_DCACHE			:= 0
 MULTI_CONSOLE_API		:= 1
-SIMICS_BUILD			:= 0
 USE_COHERENT_MEM		:= 1
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index 5c0b421..b7eb4bd 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -77,5 +77,4 @@
 
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 BL2_AT_EL3			:= 1
-SIMICS_BUILD			:= 0
 USE_COHERENT_MEM		:= 1
diff --git a/plat/mediatek/build_helpers/options.mk b/plat/mediatek/build_helpers/options.mk
index 7b63a3e..0279648 100644
--- a/plat/mediatek/build_helpers/options.mk
+++ b/plat/mediatek/build_helpers/options.mk
@@ -12,6 +12,7 @@
 $(eval $(call add_defined_option,MTK_BL33_IS_64BIT))
 $(eval $(call add_defined_option,PLAT_XLAT_TABLES_DYNAMIC))
 $(eval $(call add_defined_option,MTK_ADAPTED))
+$(eval $(call add_defined_option,MTK_PUBEVENT_ENABLE))
 $(eval $(call add_defined_option,MTK_SOC))
 $(eval $(call add_defined_option,UART_CLOCK))
 $(eval $(call add_defined_option,UART_BAUDRATE))
diff --git a/plat/mediatek/drivers/audio/audio.c b/plat/mediatek/drivers/audio/audio.c
new file mode 100644
index 0000000..285c565
--- /dev/null
+++ b/plat/mediatek/drivers/audio/audio.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+
+#include <audio.h>
+
+#include <mtk_sip_svc.h>
+
+#define MODULE_TAG "[AUDIO]"
+
+static u_register_t audio_smc_handler(u_register_t x1, u_register_t x2,
+				      u_register_t x3, u_register_t x4,
+				      void *handle, struct smccc_res *smccc_ret)
+{
+	uint32_t request_ops;
+	int ret;
+
+	request_ops = (uint32_t)x1;
+
+	switch (request_ops) {
+	case MTK_AUDIO_SMC_OP_DOMAIN_SIDEBANDS:
+		ret = set_audio_domain_sidebands();
+		break;
+	default:
+		ERROR("%s: %s: Unsupported request_ops %x\n",
+		      MODULE_TAG, __func__, request_ops);
+		ret = -EIO;
+		break;
+	}
+
+	VERBOSE("%s: %s, request_ops = %x, ret = %d\n",
+		MODULE_TAG, __func__, request_ops, ret);
+	return ret;
+}
+/* Register SiP SMC service */
+DECLARE_SMC_HANDLER(MTK_SIP_AUDIO_CONTROL, audio_smc_handler);
diff --git a/plat/mediatek/drivers/audio/audio.h b/plat/mediatek/drivers/audio/audio.h
new file mode 100644
index 0000000..1598a92
--- /dev/null
+++ b/plat/mediatek/drivers/audio/audio.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AUDIO_H
+#define AUDIO_H
+
+#include <stdint.h>
+#include <lib/mmio.h>
+
+enum mtk_audio_smc_call_op {
+	MTK_AUDIO_SMC_OP_INIT = 0,
+	MTK_AUDIO_SMC_OP_DRAM_REQUEST,
+	MTK_AUDIO_SMC_OP_DRAM_RELEASE,
+	MTK_AUDIO_SMC_OP_SRAM_REQUEST,
+	MTK_AUDIO_SMC_OP_SRAM_RELEASE,
+	MTK_AUDIO_SMC_OP_ADSP_REQUEST,
+	MTK_AUDIO_SMC_OP_ADSP_RELEASE,
+	MTK_AUDIO_SMC_OP_DOMAIN_SIDEBANDS,
+	MTK_AUDIO_SMC_OP_BTCVSD_WRITE,
+	MTK_AUDIO_SMC_OP_BTCVSD_UPDATE_CTRL_CLEAR,
+	MTK_AUDIO_SMC_OP_BTCVSD_UPDATE_CTRL_UNDERFLOW,
+	MTK_AUDIO_SMC_OP_NUM,
+};
+
+int32_t set_audio_domain_sidebands(void);
+
+#endif /* AUDIO_H */
diff --git a/plat/mediatek/drivers/audio/mt8188/audio_domain.c b/plat/mediatek/drivers/audio/mt8188/audio_domain.c
new file mode 100644
index 0000000..cbafd19
--- /dev/null
+++ b/plat/mediatek/drivers/audio/mt8188/audio_domain.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <common/debug.h>
+
+#include <audio.h>
+#include <mt_audio_private.h>
+#include <mtk_mmap_pool.h>
+#include <platform_def.h>
+#include <spm_reg.h>
+
+#define MODULE_TAG "[AUDIO_DOMAIN]"
+
+int32_t set_audio_domain_sidebands(void)
+{
+	uint32_t val = mmio_read_32(PWR_STATUS);
+
+	if ((val & BIT(SPM_PWR_STATUS_AUDIO_BIT)) == 0) {
+		ERROR("%s: %s, pwr_status=0x%x, w/o [%d]AUDIO!\n",
+		      MODULE_TAG, __func__, val, SPM_PWR_STATUS_AUDIO_BIT);
+		return -EIO;
+	}
+
+	mmio_write_32(AFE_SE_SECURE_CON, 0x0);
+
+	mmio_write_32(AFE_SECURE_SIDEBAND0, 0x0);
+	mmio_write_32(AFE_SECURE_SIDEBAND1, 0x0);
+	mmio_write_32(AFE_SECURE_SIDEBAND2, 0x0);
+	mmio_write_32(AFE_SECURE_SIDEBAND3, 0x0);
+
+	VERBOSE("%s: %s, SE_SECURE_CON=0x%x, SIDEBAND0/1/2/3=0x%x/0x%x/0x%x/0x%x\n",
+		MODULE_TAG, __func__,
+		mmio_read_32(AFE_SE_SECURE_CON),
+		mmio_read_32(AFE_SECURE_SIDEBAND0),
+		mmio_read_32(AFE_SECURE_SIDEBAND1),
+		mmio_read_32(AFE_SECURE_SIDEBAND2),
+		mmio_read_32(AFE_SECURE_SIDEBAND3));
+
+	return 0;
+}
diff --git a/plat/mediatek/drivers/audio/mt8188/mt_audio_private.h b/plat/mediatek/drivers/audio/mt8188/mt_audio_private.h
new file mode 100644
index 0000000..bcb1abc
--- /dev/null
+++ b/plat/mediatek/drivers/audio/mt8188/mt_audio_private.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_AUDIO_PRIVATE_H
+#define MT_AUDIO_PRIVATE_H
+
+#include <platform_def.h>
+
+#define AFE_SE_SECURE_CON		 (AUDIO_BASE + 0x17a8)
+#define AFE_SECURE_SIDEBAND0		 (AUDIO_BASE + 0x1908)
+#define AFE_SECURE_SIDEBAND1		 (AUDIO_BASE + 0x190c)
+#define AFE_SECURE_SIDEBAND2		 (AUDIO_BASE + 0x1910)
+#define AFE_SECURE_SIDEBAND3		 (AUDIO_BASE + 0x1914)
+
+#define SPM_PWR_STATUS_AUDIO_BIT	 (6)
+
+#endif /* MT_AUDIO_PRIVATE_H */
diff --git a/plat/mediatek/drivers/audio/mt8188/rules.mk b/plat/mediatek/drivers/audio/mt8188/rules.mk
new file mode 100644
index 0000000..82acbfc
--- /dev/null
+++ b/plat/mediatek/drivers/audio/mt8188/rules.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := audio_${MTK_SOC}
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/audio_domain.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/audio/rules.mk b/plat/mediatek/drivers/audio/rules.mk
new file mode 100644
index 0000000..8538a64
--- /dev/null
+++ b/plat/mediatek/drivers/audio/rules.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := audio
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/audio.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC)
+
+SUB_RULES-y:= ${LOCAL_DIR}/${MTK_SOC}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/ptp3/mt8188/ptp3_plat.h b/plat/mediatek/drivers/ptp3/mt8188/ptp3_plat.h
new file mode 100644
index 0000000..aa7d7ca
--- /dev/null
+++ b/plat/mediatek/drivers/ptp3/mt8188/ptp3_plat.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PTP3_PLAT_H
+#define PTP3_PLAT_H
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <ptp3_common.h>
+
+/* CPU Info */
+#define NR_PTP3_CFG_CPU			U(8)
+#define PTP3_CFG_CPU_START_ID_L		U(0)
+#define PTP3_CFG_CPU_START_ID_B		U(6)
+#define PTP3_CFG_CPU_END_ID		U(7)
+
+#define NR_PTP3_CFG1_DATA		U(2)
+#define PTP3_CFG1_MASK			(0x3000)
+
+#define NR_PTP3_CFG2_DATA		U(5)
+
+#define PTP3_CFG3_MASK1			(0x1180)
+#define PTP3_CFG3_MASK2			(0x35C0)
+#define PTP3_CFG3_MASK3			(0x3DC0)
+
+
+/* Central control */
+static unsigned int ptp3_cfg1[NR_PTP3_CFG1_DATA][NR_PTP3_CFG] = {
+	{0x0C53A2A0, 0x1000},
+	{0x0C53A2A4, 0x1000}
+};
+
+static unsigned int ptp3_cfg2[NR_PTP3_CFG2_DATA][NR_PTP3_CFG] = {
+	{0x0C530404, 0x3A1000},
+	{0x0C530428, 0x13E0408},
+	{0x0C530434, 0xB22800},
+	{0x0C53043C, 0x750},
+	{0x0C530440, 0x0222c4cc}
+};
+
+static unsigned int ptp3_cfg3[NR_PTP3_CFG] = {0x0C530400, 0xC00};
+static unsigned int ptp3_cfg3_ext[NR_PTP3_CFG] = {0x0C530400, 0xC00};
+
+#endif /* PTP3_PLAT_H */
diff --git a/plat/mediatek/drivers/ptp3/ptp3_common.c b/plat/mediatek/drivers/ptp3/ptp3_common.c
new file mode 100644
index 0000000..6846852
--- /dev/null
+++ b/plat/mediatek/drivers/ptp3/ptp3_common.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#if MTK_PUBEVENT_ENABLE
+#include <lib/pm/mtk_pm.h>
+#endif
+#include <ptp3_plat.h>
+
+#define PTP3_CORE_OFT(core)	(0x800 * (core))
+
+static void ptp3_init(unsigned int core)
+{
+	unsigned int i, addr, value;
+
+	if (core < PTP3_CFG_CPU_START_ID_B) {
+		mmio_clrsetbits_32(ptp3_cfg1[0][PTP3_CFG_ADDR], PTP3_CFG1_MASK,
+				   ptp3_cfg1[0][PTP3_CFG_VALUE]);
+	} else {
+		mmio_clrsetbits_32(ptp3_cfg1[1][PTP3_CFG_ADDR], PTP3_CFG1_MASK,
+				   ptp3_cfg1[1][PTP3_CFG_VALUE]);
+	}
+
+	if (core < PTP3_CFG_CPU_START_ID_B) {
+		for (i = 0; i < NR_PTP3_CFG2_DATA; i++) {
+			addr = ptp3_cfg2[i][PTP3_CFG_ADDR] + PTP3_CORE_OFT(core);
+			value = ptp3_cfg2[i][PTP3_CFG_VALUE];
+
+			mmio_write_32(addr, value);
+		}
+	} else {
+		for (i = 0; i < NR_PTP3_CFG2_DATA; i++) {
+			addr = ptp3_cfg2[i][PTP3_CFG_ADDR] + PTP3_CORE_OFT(core);
+
+			if (i == 2) {
+				value = ptp3_cfg2[i][PTP3_CFG_VALUE] + 0x5E0;
+			} else {
+				value = ptp3_cfg2[i][PTP3_CFG_VALUE];
+			}
+			mmio_write_32(addr, value);
+		}
+	}
+
+	if (core < PTP3_CFG_CPU_START_ID_B) {
+		addr = ptp3_cfg3[PTP3_CFG_ADDR] + PTP3_CORE_OFT(core);
+		value = ptp3_cfg3[PTP3_CFG_VALUE];
+	} else {
+		addr = ptp3_cfg3_ext[PTP3_CFG_ADDR] + PTP3_CORE_OFT(core);
+		value = ptp3_cfg3_ext[PTP3_CFG_VALUE];
+	}
+	mmio_write_32(addr, value & PTP3_CFG3_MASK1);
+	mmio_write_32(addr, value & PTP3_CFG3_MASK2);
+	mmio_write_32(addr, value & PTP3_CFG3_MASK3);
+}
+
+static void pdp_proc_arm_write(unsigned int pdp_n)
+{
+	unsigned long v = 0;
+
+	dsb();
+	__asm__ volatile ("mrs %0, S3_6_C15_C2_0" : "=r" (v));
+	v |= (UL(0x0) << 52);
+	v |= (UL(0x1) << 53);
+	v |= (UL(0x0) << 54);
+	v |= (UL(0x0) << 48);
+	v |= (UL(0x1) << 49);
+	__asm__ volatile ("msr S3_6_C15_C2_0, %0" : : "r" (v));
+	dsb();
+}
+
+static void pdp_init(unsigned int pdp_cpu)
+{
+	if ((pdp_cpu >= PTP3_CFG_CPU_START_ID_B) && (pdp_cpu < NR_PTP3_CFG_CPU)) {
+		pdp_proc_arm_write(pdp_cpu);
+	}
+}
+
+void ptp3_core_init(unsigned int core)
+{
+	ptp3_init(core);
+	pdp_init(core);
+}
+
+void ptp3_core_deinit(unsigned int core)
+{
+	/* TBD */
+}
+
+#if MTK_PUBEVENT_ENABLE
+/* Handle for power on domain */
+void *ptp3_handle_pwr_on_event(const void *arg)
+{
+	if (arg != NULL) {
+		struct mt_cpupm_event_data *data = (struct mt_cpupm_event_data *)arg;
+
+		if ((data->pwr_domain & MT_CPUPM_PWR_DOMAIN_CORE) > 0) {
+			ptp3_core_init(data->cpuid);
+		}
+	}
+	return (void *)arg;
+}
+MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(ptp3_handle_pwr_on_event);
+
+/* Handle for power off domain */
+void *ptp3_handle_pwr_off_event(const void *arg)
+{
+	if (arg != NULL) {
+		struct mt_cpupm_event_data *data = (struct mt_cpupm_event_data *)arg;
+
+		if ((data->pwr_domain & MT_CPUPM_PWR_DOMAIN_CORE) > 0) {
+			ptp3_core_deinit(data->cpuid);
+		}
+	}
+	return (void *)arg;
+}
+MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(ptp3_handle_pwr_off_event);
+#else
+#pragma message "PSCI hint not enable"
+#endif
diff --git a/plat/mediatek/drivers/ptp3/ptp3_common.h b/plat/mediatek/drivers/ptp3/ptp3_common.h
new file mode 100644
index 0000000..83ce62b
--- /dev/null
+++ b/plat/mediatek/drivers/ptp3/ptp3_common.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PTP3_COMMON_H
+#define PTP3_COMMON_H
+
+/* config enum */
+enum PTP3_CFG {
+	PTP3_CFG_ADDR,
+	PTP3_CFG_VALUE,
+	NR_PTP3_CFG,
+};
+
+/* prototype */
+void ptp3_core_init(unsigned int core);
+void ptp3_core_deinit(unsigned int core);
+
+#endif /* PTP3_COMMON_H */
diff --git a/plat/mediatek/drivers/ptp3/rules.mk b/plat/mediatek/drivers/ptp3/rules.mk
new file mode 100644
index 0000000..81d79d2
--- /dev/null
+++ b/plat/mediatek/drivers/ptp3/rules.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mtk_ptp3
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/ptp3_common.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+PLAT_INCLUDES += -I${LOCAL_DIR}/$(MTK_SOC)
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/include/mtk_sip_def.h b/plat/mediatek/include/mtk_sip_def.h
index 907f0c1..2039017 100644
--- a/plat/mediatek/include/mtk_sip_def.h
+++ b/plat/mediatek/include/mtk_sip_def.h
@@ -14,6 +14,7 @@
 	_func(MTK_SIP_KERNEL_MSDC, 0x273) \
 	_func(MTK_SIP_VCORE_CONTROL, 0x506) \
 	_func(MTK_SIP_IOMMU_CONTROL, 0x514) \
+	_func(MTK_SIP_AUDIO_CONTROL, 0x517) \
 	_func(MTK_SIP_APUSYS_CONTROL, 0x51E) \
 	_func(MTK_SIP_DP_CONTROL, 0x523) \
 	_func(MTK_SIP_KERNEL_GIC_OP, 0x526)
diff --git a/plat/mediatek/lib/pm/armv8_2/pwr_ctrl.c b/plat/mediatek/lib/pm/armv8_2/pwr_ctrl.c
index ccd04e6..447234a 100644
--- a/plat/mediatek/lib/pm/armv8_2/pwr_ctrl.c
+++ b/plat/mediatek/lib/pm/armv8_2/pwr_ctrl.c
@@ -12,7 +12,7 @@
 #include <lib/psci/psci.h>
 #include <lib/utils.h>
 #ifdef MTK_PUBEVENT_ENABLE
-#include <mtk_event/mtk_pubsub_events.h>
+#include <vendor_pubsub_events.h>
 #endif
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
@@ -103,7 +103,7 @@
 /* MediaTek mcusys power on control interface */
 static void armv8_2_mcusys_pwr_on_common(const struct mtk_cpupm_pwrstate *state)
 {
-	mt_gic_init();
+	gicv3_distif_init();
 	mt_gic_distif_restore();
 	gic_sgi_restore_all();
 
@@ -154,9 +154,8 @@
 {
 	coordinate_cluster_pwron();
 
-	gicv3_rdistif_on(plat_my_core_pos());
+	gicv3_rdistif_init(plat_my_core_pos());
 	gicv3_cpuif_enable(plat_my_core_pos());
-	mt_gic_rdistif_init();
 
 	/* If MCUSYS has been powered down then restore GIC redistributor for all CPUs. */
 	if (IS_PLAT_SYSTEM_RETENTION(state->pwr.afflv)) {
diff --git a/plat/mediatek/lib/pm/mtk_pm.h b/plat/mediatek/lib/pm/mtk_pm.h
index 892a0b0..4a29439 100644
--- a/plat/mediatek/lib/pm/mtk_pm.h
+++ b/plat/mediatek/lib/pm/mtk_pm.h
@@ -9,7 +9,7 @@
 #include <lib/psci/psci.h>
 
 #if MTK_PUBEVENT_ENABLE
-#include <mtk_event/mtk_pubsub_events.h>
+#include <vendor_pubsub_events.h>
 #endif
 
 #define MTK_CPUPM_E_OK			(0)
diff --git a/plat/mediatek/mt8186/drivers/spm/mt_spm_pmic_wrap.c b/plat/mediatek/mt8186/drivers/spm/mt_spm_pmic_wrap.c
index 849ffb7..c0000ed 100644
--- a/plat/mediatek/mt8186/drivers/spm/mt_spm_pmic_wrap.c
+++ b/plat/mediatek/mt8186/drivers/spm/mt_spm_pmic_wrap.c
@@ -51,10 +51,10 @@
 	.addr = { {0UL, 0UL} },
 	.set[PMIC_WRAP_PHASE_ALLINONE] = {
 		._[CMD_0] = { BUCK_VCORE_ELR0_66, VOLT_TO_PMIC_VAL_66(80000), },
-		._[CMD_1] = { BUCK_VCORE_ELR0_66, VOLT_TO_PMIC_VAL_66(75000), },
-		._[CMD_2] = { BUCK_VCORE_ELR0_66, VOLT_TO_PMIC_VAL_66(70000), },
-		._[CMD_3] = { BUCK_VCORE_ELR0_66, VOLT_TO_PMIC_VAL_66(65000), },
-		._[CMD_4] = { BUCK_VCORE_ELR0_66, VOLT_TO_PMIC_VAL_66(60000), },
+		._[CMD_1] = { BUCK_VCORE_ELR0_66, VOLT_TO_PMIC_VAL_66(80000), },
+		._[CMD_2] = { BUCK_VCORE_ELR0_66, VOLT_TO_PMIC_VAL_66(80000), },
+		._[CMD_3] = { BUCK_VCORE_ELR0_66, VOLT_TO_PMIC_VAL_66(80000), },
+		._[CMD_4] = { BUCK_VCORE_ELR0_66, VOLT_TO_PMIC_VAL_66(80000), },
 		._[CMD_5] = { TOP_SPI_CON0_66, 0x1, },
 		._[CMD_6] = { TOP_SPI_CON0_66, 0x0, },
 		.nr_idx = NR_IDX_ALL,
diff --git a/plat/mediatek/mt8188/include/platform_def.h b/plat/mediatek/mt8188/include/platform_def.h
index ee507fd..156a7e2 100644
--- a/plat/mediatek/mt8188/include/platform_def.h
+++ b/plat/mediatek/mt8188/include/platform_def.h
@@ -23,6 +23,16 @@
 #define MTK_DEV_RNG1_SIZE	(0x10000000)
 
 /*******************************************************************************
+ * AUDIO related constants
+ ******************************************************************************/
+#define AUDIO_BASE		(IO_PHYS + 0x00b10000)
+
+/*******************************************************************************
+ * SPM related constants
+ ******************************************************************************/
+#define SPM_BASE		(IO_PHYS + 0x00006000)
+
+/*******************************************************************************
  * GPIO related constants
  ******************************************************************************/
 #define GPIO_BASE		(IO_PHYS + 0x00005000)
@@ -168,5 +178,6 @@
 #define PLAT_CPU_PM_B_BUCK_ISO_ID	(6)
 #define PLAT_CPU_PM_ILDO_ID		(6)
 #define CPU_IDLE_SRAM_BASE		(0x11B000)
+#define CPU_IDLE_SRAM_SIZE		(0x1000)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt8188/include/spm_reg.h b/plat/mediatek/mt8188/include/spm_reg.h
new file mode 100644
index 0000000..e20f1aa
--- /dev/null
+++ b/plat/mediatek/mt8188/include/spm_reg.h
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPM_REG_H
+#define SPM_REG_H
+
+#include <platform_def.h>
+
+/* Register_SPM_CFG */
+#define MD32PCM_CFG_BASE                (SPM_BASE + 0xA00)
+#define POWERON_CONFIG_EN               (SPM_BASE + 0x000)
+#define SPM_POWER_ON_VAL0               (SPM_BASE + 0x004)
+#define SPM_POWER_ON_VAL1               (SPM_BASE + 0x008)
+#define SPM_CLK_CON                     (SPM_BASE + 0x00C)
+#define SPM_CLK_SETTLE                  (SPM_BASE + 0x010)
+#define SPM_AP_STANDBY_CON              (SPM_BASE + 0x014)
+#define PCM_CON0                        (SPM_BASE + 0x018)
+#define PCM_CON1                        (SPM_BASE + 0x01C)
+#define SPM_POWER_ON_VAL2               (SPM_BASE + 0x020)
+#define SPM_POWER_ON_VAL3               (SPM_BASE + 0x024)
+#define PCM_REG_DATA_INI                (SPM_BASE + 0x028)
+#define PCM_PWR_IO_EN                   (SPM_BASE + 0x02C)
+#define PCM_TIMER_VAL                   (SPM_BASE + 0x030)
+#define PCM_WDT_VAL                     (SPM_BASE + 0x034)
+#define SPM_SW_RST_CON                  (SPM_BASE + 0x040)
+#define SPM_SW_RST_CON_SET              (SPM_BASE + 0x044)
+#define SPM_SW_RST_CON_CLR              (SPM_BASE + 0x048)
+#define SPM_ARBITER_EN                  (SPM_BASE + 0x050)
+#define SCPSYS_CLK_CON                  (SPM_BASE + 0x054)
+#define SPM_SRAM_RSV_CON                (SPM_BASE + 0x058)
+#define SPM_SWINT                       (SPM_BASE + 0x05C)
+#define SPM_SWINT_SET                   (SPM_BASE + 0x060)
+#define SPM_SWINT_CLR                   (SPM_BASE + 0x064)
+#define SPM_SCP_MAILBOX                 (SPM_BASE + 0x068)
+#define SCP_SPM_MAILBOX                 (SPM_BASE + 0x06C)
+#define SPM_SCP_IRQ                     (SPM_BASE + 0x070)
+#define SPM_CPU_WAKEUP_EVENT            (SPM_BASE + 0x074)
+#define SPM_IRQ_MASK                    (SPM_BASE + 0x078)
+#define SPM_SRC_REQ                     (SPM_BASE + 0x080)
+#define SPM_SRC_MASK                    (SPM_BASE + 0x084)
+#define SPM_SRC2_MASK                   (SPM_BASE + 0x088)
+#define SPM_SRC3_MASK                   (SPM_BASE + 0x090)
+#define SPM_SRC4_MASK                   (SPM_BASE + 0x094)
+#define SPM_WAKEUP_EVENT_MASK2          (SPM_BASE + 0x098)
+#define SPM_WAKEUP_EVENT_MASK           (SPM_BASE + 0x09C)
+#define SPM_WAKEUP_EVENT_SENS           (SPM_BASE + 0x0A0)
+#define SPM_WAKEUP_EVENT_CLEAR          (SPM_BASE + 0x0A4)
+#define SPM_WAKEUP_EVENT_EXT_MASK       (SPM_BASE + 0x0A8)
+#define SCP_CLK_CON                     (SPM_BASE + 0x0AC)
+#define PCM_DEBUG_CON                   (SPM_BASE + 0x0B0)
+#define DDREN_DBC_CON                   (SPM_BASE + 0x0B4)
+#define SPM_RESOURCE_ACK_CON0           (SPM_BASE + 0x0B8)
+#define SPM_RESOURCE_ACK_CON1           (SPM_BASE + 0x0BC)
+#define SPM_RESOURCE_ACK_CON2           (SPM_BASE + 0x0C0)
+#define SPM_RESOURCE_ACK_CON3           (SPM_BASE + 0x0C4)
+#define SPM_RESOURCE_ACK_CON4           (SPM_BASE + 0x0C8)
+#define SPM_SRAM_CON                    (SPM_BASE + 0x0CC)
+#define PCM_REG0_DATA                   (SPM_BASE + 0x100)
+#define PCM_REG2_DATA                   (SPM_BASE + 0x104)
+#define PCM_REG6_DATA                   (SPM_BASE + 0x108)
+#define PCM_REG7_DATA                   (SPM_BASE + 0x10C)
+#define PCM_REG13_DATA                  (SPM_BASE + 0x110)
+#define SRC_REQ_STA_0                   (SPM_BASE + 0x114)
+#define SRC_REQ_STA_1                   (SPM_BASE + 0x118)
+#define SRC_REQ_STA_2                   (SPM_BASE + 0x120)
+#define SRC_REQ_STA_3                   (SPM_BASE + 0x124)
+#define SRC_REQ_STA_4                   (SPM_BASE + 0x128)
+#define PCM_TIMER_OUT                   (SPM_BASE + 0x130)
+#define PCM_WDT_OUT                     (SPM_BASE + 0x134)
+#define SPM_IRQ_STA                     (SPM_BASE + 0x138)
+#define MD32PCM_WAKEUP_STA              (SPM_BASE + 0x13C)
+#define MD32PCM_EVENT_STA               (SPM_BASE + 0x140)
+#define SPM_WAKEUP_STA                  (SPM_BASE + 0x144)
+#define SPM_WAKEUP_EXT_STA              (SPM_BASE + 0x148)
+#define SPM_WAKEUP_MISC                 (SPM_BASE + 0x14C)
+#define MM_DVFS_HALT                    (SPM_BASE + 0x150)
+#define SUBSYS_IDLE_STA                 (SPM_BASE + 0x164)
+#define PCM_STA                         (SPM_BASE + 0x168)
+#define PWR_STATUS                      (SPM_BASE + 0x16C)
+#define PWR_STATUS_2ND                  (SPM_BASE + 0x170)
+#define CPU_PWR_STATUS                  (SPM_BASE + 0x174)
+#define CPU_PWR_STATUS_2ND              (SPM_BASE + 0x178)
+#define SPM_VTCXO_EVENT_COUNT_STA       (SPM_BASE + 0x17C)
+#define SPM_INFRA_EVENT_COUNT_STA       (SPM_BASE + 0x180)
+#define SPM_VRF18_EVENT_COUNT_STA       (SPM_BASE + 0x184)
+#define SPM_APSRC_EVENT_COUNT_STA       (SPM_BASE + 0x188)
+#define SPM_DDREN_EVENT_COUNT_STA       (SPM_BASE + 0x18C)
+#define MD32PCM_STA                     (SPM_BASE + 0x190)
+#define MD32PCM_PC                      (SPM_BASE + 0x194)
+#define OTHER_PWR_STATUS                (SPM_BASE + 0x198)
+#define DVFSRC_EVENT_STA                (SPM_BASE + 0x19C)
+#define BUS_PROTECT_RDY                 (SPM_BASE + 0x1A0)
+#define BUS_PROTECT1_RDY                (SPM_BASE + 0x1A4)
+#define BUS_PROTECT2_RDY                (SPM_BASE + 0x1A8)
+#define BUS_PROTECT3_RDY                (SPM_BASE + 0x1AC)
+#define BUS_PROTECT4_RDY                (SPM_BASE + 0x1B0)
+#define BUS_PROTECT5_RDY                (SPM_BASE + 0x1B4)
+#define BUS_PROTECT6_RDY                (SPM_BASE + 0x1B8)
+#define BUS_PROTECT7_RDY                (SPM_BASE + 0x1BC)
+#define BUS_PROTECT8_RDY                (SPM_BASE + 0x1C0)
+#define BUS_PROTECT9_RDY                (SPM_BASE + 0x1C4)
+#define SPM_TWAM_LAST_STA0              (SPM_BASE + 0x1D0)
+#define SPM_TWAM_LAST_STA1              (SPM_BASE + 0x1D4)
+#define SPM_TWAM_LAST_STA2              (SPM_BASE + 0x1D8)
+#define SPM_TWAM_LAST_STA3              (SPM_BASE + 0x1DC)
+#define SPM_TWAM_CURR_STA0              (SPM_BASE + 0x1E0)
+#define SPM_TWAM_CURR_STA1              (SPM_BASE + 0x1E4)
+#define SPM_TWAM_CURR_STA2              (SPM_BASE + 0x1E8)
+#define SPM_TWAM_CURR_STA3              (SPM_BASE + 0x1EC)
+#define SPM_TWAM_TIMER_OUT              (SPM_BASE + 0x1F0)
+#define SPM_CG_CHECK_STA                (SPM_BASE + 0x1F4)
+#define SPM_DVFS_STA                    (SPM_BASE + 0x1F8)
+#define SPM_DVFS_OPP_STA                (SPM_BASE + 0x1FC)
+#define CPUEB_PWR_CON                   (SPM_BASE + 0x200)
+#define SPM_MCUSYS_PWR_CON              (SPM_BASE + 0x204)
+#define SPM_CPUTOP_PWR_CON              (SPM_BASE + 0x208)
+#define SPM_CPU0_PWR_CON                (SPM_BASE + 0x20C)
+#define SPM_CPU1_PWR_CON                (SPM_BASE + 0x210)
+#define SPM_CPU2_PWR_CON                (SPM_BASE + 0x214)
+#define SPM_CPU3_PWR_CON                (SPM_BASE + 0x218)
+#define SPM_CPU4_PWR_CON                (SPM_BASE + 0x21C)
+#define SPM_CPU5_PWR_CON                (SPM_BASE + 0x220)
+#define SPM_CPU6_PWR_CON                (SPM_BASE + 0x224)
+#define SPM_CPU7_PWR_CON                (SPM_BASE + 0x228)
+#define ARMPLL_CLK_CON                  (SPM_BASE + 0x22C)
+#define MCUSYS_IDLE_STA                 (SPM_BASE + 0x230)
+#define GIC_WAKEUP_STA                  (SPM_BASE + 0x234)
+#define CPU_SPARE_CON                   (SPM_BASE + 0x238)
+#define CPU_SPARE_CON_SET               (SPM_BASE + 0x23C)
+#define CPU_SPARE_CON_CLR               (SPM_BASE + 0x240)
+#define ARMPLL_CLK_SEL                  (SPM_BASE + 0x244)
+#define EXT_INT_WAKEUP_REQ              (SPM_BASE + 0x248)
+#define EXT_INT_WAKEUP_REQ_SET          (SPM_BASE + 0x24C)
+#define EXT_INT_WAKEUP_REQ_CLR          (SPM_BASE + 0x250)
+#define CPU_IRQ_MASK                    (SPM_BASE + 0x260)
+#define CPU_IRQ_MASK_SET                (SPM_BASE + 0x264)
+#define CPU_IRQ_MASK_CLR                (SPM_BASE + 0x268)
+#define CPU_WFI_EN                      (SPM_BASE + 0x280)
+#define CPU_WFI_EN_SET                  (SPM_BASE + 0x284)
+#define CPU_WFI_EN_CLR                  (SPM_BASE + 0x288)
+#define SYSRAM_CON                      (SPM_BASE + 0x290)
+#define SYSROM_CON                      (SPM_BASE + 0x294)
+#define ROOT_CPUTOP_ADDR                (SPM_BASE + 0x2A0)
+#define ROOT_CORE_ADDR                  (SPM_BASE + 0x2A4)
+#define SPM2SW_MAILBOX_0                (SPM_BASE + 0x2D0)
+#define SPM2SW_MAILBOX_1                (SPM_BASE + 0x2D4)
+#define SPM2SW_MAILBOX_2                (SPM_BASE + 0x2D8)
+#define SPM2SW_MAILBOX_3                (SPM_BASE + 0x2DC)
+#define SW2SPM_INT                      (SPM_BASE + 0x2E0)
+#define SW2SPM_INT_SET                  (SPM_BASE + 0x2E4)
+#define SW2SPM_INT_CLR                  (SPM_BASE + 0x2E8)
+#define SW2SPM_MAILBOX_0                (SPM_BASE + 0x2EC)
+#define SW2SPM_MAILBOX_1                (SPM_BASE + 0x2F0)
+#define SW2SPM_MAILBOX_2                (SPM_BASE + 0x2F4)
+#define SW2SPM_MAILBOX_3                (SPM_BASE + 0x2F8)
+#define SW2SPM_CFG                      (SPM_BASE + 0x2FC)
+#define MFG0_PWR_CON                    (SPM_BASE + 0x300)
+#define MFG1_PWR_CON                    (SPM_BASE + 0x304)
+#define MFG2_PWR_CON                    (SPM_BASE + 0x308)
+#define MFG3_PWR_CON                    (SPM_BASE + 0x30C)
+#define MFG4_PWR_CON                    (SPM_BASE + 0x310)
+#define MFG5_PWR_CON                    (SPM_BASE + 0x314)
+#define IFR_PWR_CON                     (SPM_BASE + 0x318)
+#define IFR_SUB_PWR_CON                 (SPM_BASE + 0x31C)
+#define PERI_PWR_CON                    (SPM_BASE + 0x320)
+#define PEXTP_MAC_TOP_P0_PWR_CON        (SPM_BASE + 0x324)
+#define PEXTP_PHY_TOP_PWR_CON           (SPM_BASE + 0x328)
+#define APHY_N_PWR_CON                  (SPM_BASE + 0x32C)
+#define APHY_S_PWR_CON                  (SPM_BASE + 0x330)
+#define ETHER_PWR_CON                   (SPM_BASE + 0x338)
+#define DPY0_PWR_CON                    (SPM_BASE + 0x33C)
+#define DPY1_PWR_CON                    (SPM_BASE + 0x340)
+#define DPM0_PWR_CON                    (SPM_BASE + 0x344)
+#define DPM1_PWR_CON                    (SPM_BASE + 0x348)
+#define AUDIO_PWR_CON                   (SPM_BASE + 0x34C)
+#define AUDIO_ASRC_PWR_CON              (SPM_BASE + 0x350)
+#define ADSP_PWR_CON                    (SPM_BASE + 0x354)
+#define ADSP_INFRA_PWR_CON              (SPM_BASE + 0x358)
+#define ADSP_AO_PWR_CON                 (SPM_BASE + 0x35C)
+#define VPPSYS0_PWR_CON                 (SPM_BASE + 0x360)
+#define VPPSYS1_PWR_CON                 (SPM_BASE + 0x364)
+#define VDOSYS0_PWR_CON                 (SPM_BASE + 0x368)
+#define VDOSYS1_PWR_CON                 (SPM_BASE + 0x36C)
+#define WPESYS_PWR_CON                  (SPM_BASE + 0x370)
+#define DP_TX_PWR_CON                   (SPM_BASE + 0x374)
+#define EDP_TX_PWR_CON                  (SPM_BASE + 0x378)
+#define HDMI_TX_PWR_CON                 (SPM_BASE + 0x37C)
+#define VDE0_PWR_CON                    (SPM_BASE + 0x380)
+#define VDE1_PWR_CON                    (SPM_BASE + 0x384)
+#define VDE2_PWR_CON                    (SPM_BASE + 0x388)
+#define VEN_PWR_CON                     (SPM_BASE + 0x38C)
+#define VEN_CORE1_PWR_CON               (SPM_BASE + 0x390)
+#define CAM_MAIN_PWR_CON                (SPM_BASE + 0x394)
+#define CAM_SUBA_PWR_CON                (SPM_BASE + 0x398)
+#define CAM_SUBB_PWR_CON                (SPM_BASE + 0x39C)
+#define CAM_VCORE_PWR_CON               (SPM_BASE + 0x3A0)
+#define IMG_VCORE_PWR_CON               (SPM_BASE + 0x3A4)
+#define IMG_MAIN_PWR_CON                (SPM_BASE + 0x3A8)
+#define IMG_DIP_PWR_CON                 (SPM_BASE + 0x3AC)
+#define IMG_IPE_PWR_CON                 (SPM_BASE + 0x3B0)
+#define NNA0_PWR_CON                    (SPM_BASE + 0x3B4)
+#define NNA1_PWR_CON                    (SPM_BASE + 0x3B8)
+#define IPNNA_PWR_CON                   (SPM_BASE + 0x3C0)
+#define CSI_RX_TOP_PWR_CON              (SPM_BASE + 0x3C4)
+#define SSPM_SRAM_CON                   (SPM_BASE + 0x3CC)
+#define SCP_SRAM_CON                    (SPM_BASE + 0x3D0)
+#define DEVAPC_IFR_SRAM_CON             (SPM_BASE + 0x3D8)
+#define DEVAPC_SUBIFR_SRAM_CON          (SPM_BASE + 0x3DC)
+#define DEVAPC_ACP_SRAM_CON             (SPM_BASE + 0x3E0)
+#define USB_SRAM_CON                    (SPM_BASE + 0x3E4)
+#define DUMMY_SRAM_CON                  (SPM_BASE + 0x3E8)
+#define EXT_BUCK_ISO                    (SPM_BASE + 0x3EC)
+#define MSDC_SRAM_CON                   (SPM_BASE + 0x3F0)
+#define DEBUGTOP_SRAM_CON               (SPM_BASE + 0x3F4)
+#define DPMAIF_SRAM_CON                 (SPM_BASE + 0x3F8)
+#define GCPU_SRAM_CON                   (SPM_BASE + 0x3FC)
+#define SPM_MEM_CK_SEL                  (SPM_BASE + 0x400)
+#define SPM_BUS_PROTECT_MASK_B          (SPM_BASE + 0x404)
+#define SPM_BUS_PROTECT1_MASK_B         (SPM_BASE + 0x408)
+#define SPM_BUS_PROTECT2_MASK_B         (SPM_BASE + 0x40C)
+#define SPM_BUS_PROTECT3_MASK_B         (SPM_BASE + 0x410)
+#define SPM_BUS_PROTECT4_MASK_B         (SPM_BASE + 0x414)
+#define SPM_BUS_PROTECT5_MASK_B         (SPM_BASE + 0x418)
+#define SPM_BUS_PROTECT6_MASK_B         (SPM_BASE + 0x41C)
+#define SPM_BUS_PROTECT7_MASK_B         (SPM_BASE + 0x420)
+#define SPM_BUS_PROTECT8_MASK_B         (SPM_BASE + 0x424)
+#define SPM_BUS_PROTECT9_MASK_B         (SPM_BASE + 0x428)
+#define SPM_EMI_BW_MODE                 (SPM_BASE + 0x42C)
+#define SPM2MM_CON                      (SPM_BASE + 0x434)
+#define SPM2CPUEB_CON                   (SPM_BASE + 0x438)
+#define AP_MDSRC_REQ                    (SPM_BASE + 0x43C)
+#define SPM2EMI_ENTER_ULPM              (SPM_BASE + 0x440)
+#define SPM_PLL_CON                     (SPM_BASE + 0x444)
+#define RC_SPM_CTRL                     (SPM_BASE + 0x448)
+#define SPM_DRAM_MCU_SW_CON_0           (SPM_BASE + 0x44C)
+#define SPM_DRAM_MCU_SW_CON_1           (SPM_BASE + 0x450)
+#define SPM_DRAM_MCU_SW_CON_2           (SPM_BASE + 0x454)
+#define SPM_DRAM_MCU_SW_CON_3           (SPM_BASE + 0x458)
+#define SPM_DRAM_MCU_SW_CON_4           (SPM_BASE + 0x45C)
+#define SPM_DRAM_MCU_STA_0              (SPM_BASE + 0x460)
+#define SPM_DRAM_MCU_STA_1              (SPM_BASE + 0x464)
+#define SPM_DRAM_MCU_STA_2              (SPM_BASE + 0x468)
+#define SPM_DRAM_MCU_SW_SEL_0           (SPM_BASE + 0x46C)
+#define RELAY_DVFS_LEVEL                (SPM_BASE + 0x470)
+#define DRAMC_DPY_CLK_SW_CON_0          (SPM_BASE + 0x474)
+#define DRAMC_DPY_CLK_SW_CON_1          (SPM_BASE + 0x478)
+#define DRAMC_DPY_CLK_SW_CON_2          (SPM_BASE + 0x47C)
+#define DRAMC_DPY_CLK_SW_CON_3          (SPM_BASE + 0x480)
+#define DRAMC_DPY_CLK_SW_SEL_0          (SPM_BASE + 0x484)
+#define DRAMC_DPY_CLK_SW_SEL_1          (SPM_BASE + 0x488)
+#define DRAMC_DPY_CLK_SW_SEL_2          (SPM_BASE + 0x48C)
+#define DRAMC_DPY_CLK_SW_SEL_3          (SPM_BASE + 0x490)
+#define DRAMC_DPY_CLK_SPM_CON           (SPM_BASE + 0x494)
+#define SPM_DVFS_LEVEL                  (SPM_BASE + 0x498)
+#define SPM_CIRQ_CON                    (SPM_BASE + 0x49C)
+#define SPM_DVFS_MISC                   (SPM_BASE + 0x4A0)
+#define RG_MODULE_SW_CG_0_MASK_REQ_0    (SPM_BASE + 0x4A4)
+#define RG_MODULE_SW_CG_0_MASK_REQ_1    (SPM_BASE + 0x4A8)
+#define RG_MODULE_SW_CG_0_MASK_REQ_2    (SPM_BASE + 0x4AC)
+#define RG_MODULE_SW_CG_1_MASK_REQ_0    (SPM_BASE + 0x4B0)
+#define RG_MODULE_SW_CG_1_MASK_REQ_1    (SPM_BASE + 0x4B4)
+#define RG_MODULE_SW_CG_1_MASK_REQ_2    (SPM_BASE + 0x4B8)
+#define RG_MODULE_SW_CG_2_MASK_REQ_0    (SPM_BASE + 0x4BC)
+#define RG_MODULE_SW_CG_2_MASK_REQ_1    (SPM_BASE + 0x4C0)
+#define RG_MODULE_SW_CG_2_MASK_REQ_2    (SPM_BASE + 0x4C4)
+#define RG_MODULE_SW_CG_3_MASK_REQ_0    (SPM_BASE + 0x4C8)
+#define RG_MODULE_SW_CG_3_MASK_REQ_1    (SPM_BASE + 0x4CC)
+#define RG_MODULE_SW_CG_3_MASK_REQ_2    (SPM_BASE + 0x4D0)
+#define PWR_STATUS_MASK_REQ_0           (SPM_BASE + 0x4D4)
+#define PWR_STATUS_MASK_REQ_1           (SPM_BASE + 0x4D8)
+#define PWR_STATUS_MASK_REQ_2           (SPM_BASE + 0x4DC)
+#define SPM_CG_CHECK_CON                (SPM_BASE + 0x4E0)
+#define SPM_SRC_RDY_STA                 (SPM_BASE + 0x4E4)
+#define SPM_DVS_DFS_LEVEL               (SPM_BASE + 0x4E8)
+#define SPM_FORCE_DVFS                  (SPM_BASE + 0x4EC)
+#define DRAMC_MCU_SRAM_CON              (SPM_BASE + 0x4F0)
+#define DRAMC_MCU2_SRAM_CON             (SPM_BASE + 0x4F4)
+#define DPY_SHU_SRAM_CON                (SPM_BASE + 0x4F8)
+#define DPY_SHU2_SRAM_CON               (SPM_BASE + 0x4FC)
+#define SPM_DPM_P2P_STA                 (SPM_BASE + 0x514)
+#define SPM_DPM_P2P_CON                 (SPM_BASE + 0x518)
+#define SPM_SW_FLAG_0                   (SPM_BASE + 0x600)
+#define SPM_SW_DEBUG_0                  (SPM_BASE + 0x604)
+#define SPM_SW_FLAG_1                   (SPM_BASE + 0x608)
+#define SPM_SW_DEBUG_1                  (SPM_BASE + 0x60C)
+#define SPM_SW_RSV_0                    (SPM_BASE + 0x610)
+#define SPM_SW_RSV_1                    (SPM_BASE + 0x614)
+#define SPM_SW_RSV_2                    (SPM_BASE + 0x618)
+#define SPM_SW_RSV_3                    (SPM_BASE + 0x61C)
+#define SPM_SW_RSV_4                    (SPM_BASE + 0x620)
+#define SPM_SW_RSV_5                    (SPM_BASE + 0x624)
+#define SPM_SW_RSV_6                    (SPM_BASE + 0x628)
+#define SPM_SW_RSV_7                    (SPM_BASE + 0x62C)
+#define SPM_SW_RSV_8                    (SPM_BASE + 0x630)
+#define SPM_BK_WAKE_EVENT               (SPM_BASE + 0x634)
+#define SPM_BK_VTCXO_DUR                (SPM_BASE + 0x638)
+#define SPM_BK_WAKE_MISC                (SPM_BASE + 0x63C)
+#define SPM_BK_PCM_TIMER                (SPM_BASE + 0x640)
+#define ULPOSC_CON                      (SPM_BASE + 0x644)
+#define SPM_RSV_CON_0                   (SPM_BASE + 0x650)
+#define SPM_RSV_CON_1                   (SPM_BASE + 0x654)
+#define SPM_RSV_STA_0                   (SPM_BASE + 0x658)
+#define SPM_RSV_STA_1                   (SPM_BASE + 0x65C)
+#define SPM_SPARE_CON                   (SPM_BASE + 0x660)
+#define SPM_SPARE_CON_SET               (SPM_BASE + 0x664)
+#define SPM_SPARE_CON_CLR               (SPM_BASE + 0x668)
+#define SPM_CROSS_WAKE_M00_REQ          (SPM_BASE + 0x66C)
+#define SPM_CROSS_WAKE_M01_REQ          (SPM_BASE + 0x670)
+#define SPM_CROSS_WAKE_M02_REQ          (SPM_BASE + 0x674)
+#define SPM_CROSS_WAKE_M03_REQ          (SPM_BASE + 0x678)
+#define SCP_VCORE_LEVEL                 (SPM_BASE + 0x67C)
+#define SC_MM_CK_SEL_CON                (SPM_BASE + 0x680)
+#define SPARE_ACK_MASK                  (SPM_BASE + 0x684)
+#define SPM_DV_CON_0                    (SPM_BASE + 0x68C)
+#define SPM_DV_CON_1                    (SPM_BASE + 0x690)
+#define SPM_DV_STA                      (SPM_BASE + 0x694)
+#define CONN_XOWCN_DEBUG_EN             (SPM_BASE + 0x698)
+#define SPM_SEMA_M0                     (SPM_BASE + 0x69C)
+#define SPM_SEMA_M1                     (SPM_BASE + 0x6A0)
+#define SPM_SEMA_M2                     (SPM_BASE + 0x6A4)
+#define SPM_SEMA_M3                     (SPM_BASE + 0x6A8)
+#define SPM_SEMA_M4                     (SPM_BASE + 0x6AC)
+#define SPM_SEMA_M5                     (SPM_BASE + 0x6B0)
+#define SPM_SEMA_M6                     (SPM_BASE + 0x6B4)
+#define SPM_SEMA_M7                     (SPM_BASE + 0x6B8)
+#define SPM2ADSP_MAILBOX                (SPM_BASE + 0x6BC)
+#define ADSP2SPM_MAILBOX                (SPM_BASE + 0x6C0)
+#define SPM_ADSP_IRQ                    (SPM_BASE + 0x6C4)
+#define SPM_MD32_IRQ                    (SPM_BASE + 0x6C8)
+#define SPM2PMCU_MAILBOX_0              (SPM_BASE + 0x6CC)
+#define SPM2PMCU_MAILBOX_1              (SPM_BASE + 0x6D0)
+#define SPM2PMCU_MAILBOX_2              (SPM_BASE + 0x6D4)
+#define SPM2PMCU_MAILBOX_3              (SPM_BASE + 0x6D8)
+#define PMCU2SPM_MAILBOX_0              (SPM_BASE + 0x6DC)
+#define PMCU2SPM_MAILBOX_1              (SPM_BASE + 0x6E0)
+#define PMCU2SPM_MAILBOX_2              (SPM_BASE + 0x6E4)
+#define PMCU2SPM_MAILBOX_3              (SPM_BASE + 0x6E8)
+#define SPM_AP_SEMA                     (SPM_BASE + 0x6F8)
+#define SPM_SPM_SEMA                    (SPM_BASE + 0x6FC)
+#define SPM_DVFS_CON                    (SPM_BASE + 0x700)
+#define SPM_DVFS_CON_STA                (SPM_BASE + 0x704)
+#define SPM_PMIC_SPMI_CON               (SPM_BASE + 0x708)
+#define SPM_DVFS_CMD0                   (SPM_BASE + 0x710)
+#define SPM_DVFS_CMD1                   (SPM_BASE + 0x714)
+#define SPM_DVFS_CMD2                   (SPM_BASE + 0x718)
+#define SPM_DVFS_CMD3                   (SPM_BASE + 0x71C)
+#define SPM_DVFS_CMD4                   (SPM_BASE + 0x720)
+#define SPM_DVFS_CMD5                   (SPM_BASE + 0x724)
+#define SPM_DVFS_CMD6                   (SPM_BASE + 0x728)
+#define SPM_DVFS_CMD7                   (SPM_BASE + 0x72C)
+#define SPM_DVFS_CMD8                   (SPM_BASE + 0x730)
+#define SPM_DVFS_CMD9                   (SPM_BASE + 0x734)
+#define SPM_DVFS_CMD10                  (SPM_BASE + 0x738)
+#define SPM_DVFS_CMD11                  (SPM_BASE + 0x73C)
+#define SPM_DVFS_CMD12                  (SPM_BASE + 0x740)
+#define SPM_DVFS_CMD13                  (SPM_BASE + 0x744)
+#define SPM_DVFS_CMD14                  (SPM_BASE + 0x748)
+#define SPM_DVFS_CMD15                  (SPM_BASE + 0x74C)
+#define SPM_DVFS_CMD16                  (SPM_BASE + 0x750)
+#define SPM_DVFS_CMD17                  (SPM_BASE + 0x754)
+#define SPM_DVFS_CMD18                  (SPM_BASE + 0x758)
+#define SPM_DVFS_CMD19                  (SPM_BASE + 0x75C)
+#define SPM_DVFS_CMD20                  (SPM_BASE + 0x760)
+#define SPM_DVFS_CMD21                  (SPM_BASE + 0x764)
+#define SPM_DVFS_CMD22                  (SPM_BASE + 0x768)
+#define SPM_DVFS_CMD23                  (SPM_BASE + 0x76C)
+#define SYS_TIMER_VALUE_L               (SPM_BASE + 0x770)
+#define SYS_TIMER_VALUE_H               (SPM_BASE + 0x774)
+#define SYS_TIMER_START_L               (SPM_BASE + 0x778)
+#define SYS_TIMER_START_H               (SPM_BASE + 0x77C)
+#define SYS_TIMER_LATCH_L_00            (SPM_BASE + 0x780)
+#define SYS_TIMER_LATCH_H_00            (SPM_BASE + 0x784)
+#define SYS_TIMER_LATCH_L_01            (SPM_BASE + 0x788)
+#define SYS_TIMER_LATCH_H_01            (SPM_BASE + 0x78C)
+#define SYS_TIMER_LATCH_L_02            (SPM_BASE + 0x790)
+#define SYS_TIMER_LATCH_H_02            (SPM_BASE + 0x794)
+#define SYS_TIMER_LATCH_L_03            (SPM_BASE + 0x798)
+#define SYS_TIMER_LATCH_H_03            (SPM_BASE + 0x79C)
+#define SYS_TIMER_LATCH_L_04            (SPM_BASE + 0x7A0)
+#define SYS_TIMER_LATCH_H_04            (SPM_BASE + 0x7A4)
+#define SYS_TIMER_LATCH_L_05            (SPM_BASE + 0x7A8)
+#define SYS_TIMER_LATCH_H_05            (SPM_BASE + 0x7AC)
+#define SYS_TIMER_LATCH_L_06            (SPM_BASE + 0x7B0)
+#define SYS_TIMER_LATCH_H_06            (SPM_BASE + 0x7B4)
+#define SYS_TIMER_LATCH_L_07            (SPM_BASE + 0x7B8)
+#define SYS_TIMER_LATCH_H_07            (SPM_BASE + 0x7BC)
+#define SYS_TIMER_LATCH_L_08            (SPM_BASE + 0x7C0)
+#define SYS_TIMER_LATCH_H_08            (SPM_BASE + 0x7C4)
+#define SYS_TIMER_LATCH_L_09            (SPM_BASE + 0x7C8)
+#define SYS_TIMER_LATCH_H_09            (SPM_BASE + 0x7CC)
+#define SYS_TIMER_LATCH_L_10            (SPM_BASE + 0x7D0)
+#define SYS_TIMER_LATCH_H_10            (SPM_BASE + 0x7D4)
+#define SYS_TIMER_LATCH_L_11            (SPM_BASE + 0x7D8)
+#define SYS_TIMER_LATCH_H_11            (SPM_BASE + 0x7DC)
+#define SYS_TIMER_LATCH_L_12            (SPM_BASE + 0x7E0)
+#define SYS_TIMER_LATCH_H_12            (SPM_BASE + 0x7E4)
+#define SYS_TIMER_LATCH_L_13            (SPM_BASE + 0x7E8)
+#define SYS_TIMER_LATCH_H_13            (SPM_BASE + 0x7EC)
+#define SYS_TIMER_LATCH_L_14            (SPM_BASE + 0x7F0)
+#define SYS_TIMER_LATCH_H_14            (SPM_BASE + 0x7F4)
+#define SYS_TIMER_LATCH_L_15            (SPM_BASE + 0x7F8)
+#define SYS_TIMER_LATCH_H_15            (SPM_BASE + 0x7FC)
+#define PCM_WDT_LATCH_0                 (SPM_BASE + 0x800)
+#define PCM_WDT_LATCH_1                 (SPM_BASE + 0x804)
+#define PCM_WDT_LATCH_2                 (SPM_BASE + 0x808)
+#define PCM_WDT_LATCH_3                 (SPM_BASE + 0x80C)
+#define PCM_WDT_LATCH_4                 (SPM_BASE + 0x810)
+#define PCM_WDT_LATCH_5                 (SPM_BASE + 0x814)
+#define PCM_WDT_LATCH_6                 (SPM_BASE + 0x818)
+#define PCM_WDT_LATCH_7                 (SPM_BASE + 0x81C)
+#define PCM_WDT_LATCH_8                 (SPM_BASE + 0x820)
+#define PCM_WDT_LATCH_9                 (SPM_BASE + 0x824)
+#define PCM_WDT_LATCH_10                (SPM_BASE + 0x828)
+#define PCM_WDT_LATCH_11                (SPM_BASE + 0x82C)
+#define PCM_WDT_LATCH_12                (SPM_BASE + 0x830)
+#define PCM_WDT_LATCH_13                (SPM_BASE + 0x834)
+#define PCM_WDT_LATCH_14                (SPM_BASE + 0x838)
+#define PCM_WDT_LATCH_15                (SPM_BASE + 0x83C)
+#define PCM_WDT_LATCH_16                (SPM_BASE + 0x840)
+#define PCM_WDT_LATCH_17                (SPM_BASE + 0x844)
+#define PCM_WDT_LATCH_18                (SPM_BASE + 0x848)
+#define PCM_WDT_LATCH_SPARE_0           (SPM_BASE + 0x84C)
+#define PCM_WDT_LATCH_SPARE_1           (SPM_BASE + 0x850)
+#define PCM_WDT_LATCH_SPARE_2           (SPM_BASE + 0x854)
+#define DRAMC_GATING_ERR_LATCH_CH0_0    (SPM_BASE + 0x8A0)
+#define DRAMC_GATING_ERR_LATCH_CH0_1    (SPM_BASE + 0x8A4)
+#define DRAMC_GATING_ERR_LATCH_CH0_2    (SPM_BASE + 0x8A8)
+#define DRAMC_GATING_ERR_LATCH_CH0_3    (SPM_BASE + 0x8AC)
+#define DRAMC_GATING_ERR_LATCH_CH0_4    (SPM_BASE + 0x8B0)
+#define DRAMC_GATING_ERR_LATCH_CH0_5    (SPM_BASE + 0x8B4)
+#define DRAMC_GATING_ERR_LATCH_SPARE_0  (SPM_BASE + 0x8F4)
+#define SPM_ACK_CHK_CON_0               (SPM_BASE + 0x900)
+#define SPM_ACK_CHK_PC_0                (SPM_BASE + 0x904)
+#define SPM_ACK_CHK_SEL_0               (SPM_BASE + 0x908)
+#define SPM_ACK_CHK_TIMER_0             (SPM_BASE + 0x90C)
+#define SPM_ACK_CHK_STA_0               (SPM_BASE + 0x910)
+#define SPM_ACK_CHK_SWINT_0             (SPM_BASE + 0x914)
+#define SPM_ACK_CHK_CON_1               (SPM_BASE + 0x920)
+#define SPM_ACK_CHK_PC_1                (SPM_BASE + 0x924)
+#define SPM_ACK_CHK_SEL_1               (SPM_BASE + 0x928)
+#define SPM_ACK_CHK_TIMER_1             (SPM_BASE + 0x92C)
+#define SPM_ACK_CHK_STA_1               (SPM_BASE + 0x930)
+#define SPM_ACK_CHK_SWINT_1             (SPM_BASE + 0x934)
+#define SPM_ACK_CHK_CON_2               (SPM_BASE + 0x940)
+#define SPM_ACK_CHK_PC_2                (SPM_BASE + 0x944)
+#define SPM_ACK_CHK_SEL_2               (SPM_BASE + 0x948)
+#define SPM_ACK_CHK_TIMER_2             (SPM_BASE + 0x94C)
+#define SPM_ACK_CHK_STA_2               (SPM_BASE + 0x950)
+#define SPM_ACK_CHK_SWINT_2             (SPM_BASE + 0x954)
+#define SPM_ACK_CHK_CON_3               (SPM_BASE + 0x960)
+#define SPM_ACK_CHK_PC_3                (SPM_BASE + 0x964)
+#define SPM_ACK_CHK_SEL_3               (SPM_BASE + 0x968)
+#define SPM_ACK_CHK_TIMER_3             (SPM_BASE + 0x96C)
+#define SPM_ACK_CHK_STA_3               (SPM_BASE + 0x970)
+#define SPM_ACK_CHK_SWINT_3             (SPM_BASE + 0x974)
+#define SPM_COUNTER_0                   (SPM_BASE + 0x978)
+#define SPM_COUNTER_1                   (SPM_BASE + 0x97C)
+#define SPM_COUNTER_2                   (SPM_BASE + 0x980)
+#define SYS_TIMER_CON                   (SPM_BASE + 0x98C)
+#define SPM_TWAM_CON                    (SPM_BASE + 0x990)
+#define SPM_TWAM_WINDOW_LEN             (SPM_BASE + 0x994)
+#define SPM_TWAM_IDLE_SEL               (SPM_BASE + 0x998)
+#define SPM_TWAM_EVENT_CLEAR            (SPM_BASE + 0x99C)
+#define PMSR_LAST_DAT                   (SPM_BASE + 0xF00)
+#define PMSR_LAST_CNT                   (SPM_BASE + 0xF04)
+#define PMSR_LAST_ACK                   (SPM_BASE + 0xF08)
+#define SPM_PMSR_SEL_CON0               (SPM_BASE + 0xF10)
+#define SPM_PMSR_SEL_CON1               (SPM_BASE + 0xF14)
+#define SPM_PMSR_SEL_CON2               (SPM_BASE + 0xF18)
+#define SPM_PMSR_SEL_CON3               (SPM_BASE + 0xF1C)
+#define SPM_PMSR_SEL_CON4               (SPM_BASE + 0xF20)
+#define SPM_PMSR_SEL_CON5               (SPM_BASE + 0xF24)
+#define SPM_PMSR_SEL_CON6               (SPM_BASE + 0xF28)
+#define SPM_PMSR_SEL_CON7               (SPM_BASE + 0xF2C)
+#define SPM_PMSR_SEL_CON8               (SPM_BASE + 0xF30)
+#define SPM_PMSR_SEL_CON9               (SPM_BASE + 0xF34)
+#define SPM_PMSR_SEL_CON10              (SPM_BASE + 0xF3C)
+#define SPM_PMSR_SEL_CON11              (SPM_BASE + 0xF40)
+#define SPM_PMSR_TIEMR_STA0             (SPM_BASE + 0xFB8)
+#define SPM_PMSR_TIEMR_STA1             (SPM_BASE + 0xFBC)
+#define SPM_PMSR_TIEMR_STA2             (SPM_BASE + 0xFC0)
+#define SPM_PMSR_GENERAL_CON0           (SPM_BASE + 0xFC4)
+#define SPM_PMSR_GENERAL_CON1           (SPM_BASE + 0xFC8)
+#define SPM_PMSR_GENERAL_CON2           (SPM_BASE + 0xFCC)
+#define SPM_PMSR_GENERAL_CON3           (SPM_BASE + 0xFD0)
+#define SPM_PMSR_GENERAL_CON4           (SPM_BASE + 0xFD4)
+#define SPM_PMSR_GENERAL_CON5           (SPM_BASE + 0xFD8)
+#define SPM_PMSR_SW_RESET               (SPM_BASE + 0xFDC)
+#define SPM_PMSR_MON_CON0               (SPM_BASE + 0xFE0)
+#define SPM_PMSR_MON_CON1               (SPM_BASE + 0xFE4)
+#define SPM_PMSR_MON_CON2               (SPM_BASE + 0xFE8)
+#define SPM_PMSR_LEN_CON0               (SPM_BASE + 0xFEC)
+#define SPM_PMSR_LEN_CON1               (SPM_BASE + 0xFF0)
+#define SPM_PMSR_LEN_CON2               (SPM_BASE + 0xFF4)
+
+#endif /* SPM_REG_H */
diff --git a/plat/mediatek/mt8188/plat_config.mk b/plat/mediatek/mt8188/plat_config.mk
index cff97cb..137318e 100644
--- a/plat/mediatek/mt8188/plat_config.mk
+++ b/plat/mediatek/mt8188/plat_config.mk
@@ -42,6 +42,7 @@
 CONFIG_MTK_SMP_EN := y
 CONFIG_MTK_CPU_SUSPEND_EN := y
 CPU_PM_TINYSYS_SUPPORT := y
+MTK_PUBEVENT_ENABLE := y
 
 MACH_MT8188 := 1
 $(eval $(call add_define,MACH_MT8188))
diff --git a/plat/mediatek/mt8188/plat_mmap.c b/plat/mediatek/mt8188/plat_mmap.c
index 0d4cbe8..a611d22 100644
--- a/plat/mediatek/mt8188/plat_mmap.c
+++ b/plat/mediatek/mt8188/plat_mmap.c
@@ -13,6 +13,8 @@
 			MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(MTK_DEV_RNG1_BASE, MTK_DEV_RNG1_SIZE,
 			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CPU_IDLE_SRAM_BASE, CPU_IDLE_SRAM_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
 	{ 0 }
 };
 DECLARE_MTK_MMAP_REGIONS(plat_mmap);
diff --git a/plat/mediatek/mt8188/platform.mk b/plat/mediatek/mt8188/platform.mk
index b509edc..b6a17aa 100644
--- a/plat/mediatek/mt8188/platform.mk
+++ b/plat/mediatek/mt8188/platform.mk
@@ -24,6 +24,7 @@
 MODULES-y += $(MTK_PLAT)/lib/mtk_init
 MODULES-y += $(MTK_PLAT)/lib/pm
 MODULES-y += $(MTK_PLAT)/lib/system_reset
+MODULES-y += $(MTK_PLAT)/drivers/audio
 MODULES-y += $(MTK_PLAT)/drivers/cirq
 MODULES-y += $(MTK_PLAT)/drivers/cpu_pm
 MODULES-y += $(MTK_PLAT)/drivers/dcm
@@ -36,6 +37,7 @@
 MODULES-y += $(MTK_PLAT)/drivers/mcusys
 MODULES-y += $(MTK_PLAT)/drivers/pmic
 MODULES-y += $(MTK_PLAT)/drivers/pmic_wrap
+MODULES-y += $(MTK_PLAT)/drivers/ptp3
 MODULES-y += $(MTK_PLAT)/drivers/rtc
 MODULES-y += $(MTK_PLAT)/drivers/timer
 MODULES-y += $(MTK_PLAT)/helpers
diff --git a/plat/mediatek/mt8195/drivers/ptp3/mtk_ptp3_common.h b/plat/mediatek/mt8195/drivers/ptp3/mtk_ptp3_common.h
deleted file mode 100644
index 341cf86..0000000
--- a/plat/mediatek/mt8195/drivers/ptp3/mtk_ptp3_common.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2021, MediaTek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MTK_PTP3_COMMON_H
-#define MTK_PTP3_COMMON_H
-
-#include <lib/mmio.h>
-#include <lib/utils_def.h>
-
-/************************************************
- * CPU info
- ************************************************/
-#define NR_PTP3_CFG_CPU			U(8)
-#define PTP3_CFG_CPU_START_ID_L		U(0)
-#define PTP3_CFG_CPU_START_ID_B		U(4)
-#define PTP3_CFG_CPU_END_ID		U(7)
-
-#define NR_PTP3_CFG1_DATA		U(2)
-#define PTP3_CFG1_MASK			0x3000
-
-#define NR_PTP3_CFG2_DATA		U(5)
-
-#define PTP3_CFG3_MASK1			0x1180
-#define PTP3_CFG3_MASK2			0x35C0
-#define PTP3_CFG3_MASK3			0x3DC0
-
-/************************************************
- * register read/write
- ************************************************/
-#define ptp3_write(addr, val) mmio_write_32((uintptr_t)addr, val)
-#define ptp3_clrsetbits(addr, clear, set) \
-	mmio_clrsetbits_32((uintptr_t)addr, clear, set)
-
-/************************************************
- * config enum
- ************************************************/
-enum PTP3_CFG {
-	PTP3_CFG_ADDR,
-	PTP3_CFG_VALUE,
-	NR_PTP3_CFG,
-};
-
-/************************************
- * prototype
- ************************************/
-extern void ptp3_core_init(unsigned int core);
-extern void ptp3_core_unInit(unsigned int core);
-
-#endif /* MTK_PTP3_COMMON_H */
diff --git a/plat/mediatek/mt8195/drivers/ptp3/mtk_ptp3_main.c b/plat/mediatek/mt8195/drivers/ptp3/mtk_ptp3_main.c
deleted file mode 100644
index 540cb33..0000000
--- a/plat/mediatek/mt8195/drivers/ptp3/mtk_ptp3_main.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2021, MediaTek Inc. All rights reserved. \
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <mtk_ptp3_common.h>
-
-#define PTP3_CORE_OFT(core)	(0x800 * (core))
-
-/************************************************
- * Central control
- ************************************************/
-static unsigned int ptp3_cfg1[NR_PTP3_CFG1_DATA][NR_PTP3_CFG] = {
-	{0x0C53A2A0, 0x1000},
-	{0x0C53A2A4, 0x1000}
-};
-
-static unsigned int ptp3_cfg2[NR_PTP3_CFG2_DATA][NR_PTP3_CFG] = {
-	{0x0C530404, 0x3A1000},
-	{0x0C530428, 0x13E0408},
-	{0x0C530434, 0xB22800},
-	{0x0C53043C, 0x750},
-	{0x0C530440, 0x0222c4cc}
-};
-
-static unsigned int ptp3_cfg3[NR_PTP3_CFG] = {0x0C530400, 0x2D80};
-static unsigned int ptp3_cfg3_ext[NR_PTP3_CFG] = {0x0C530400, 0xC00};
-
-static void ptp3_init(unsigned int core)
-{
-	unsigned int i, addr, value;
-
-	if (core < PTP3_CFG_CPU_START_ID_B) {
-		ptp3_clrsetbits(ptp3_cfg1[0][PTP3_CFG_ADDR], PTP3_CFG1_MASK,
-				ptp3_cfg1[0][PTP3_CFG_VALUE]);
-	} else {
-		ptp3_clrsetbits(ptp3_cfg1[1][PTP3_CFG_ADDR], PTP3_CFG1_MASK,
-				ptp3_cfg1[1][PTP3_CFG_VALUE]);
-	}
-
-	if (core < PTP3_CFG_CPU_START_ID_B) {
-		for (i = 0; i < NR_PTP3_CFG2_DATA; i++) {
-			addr = ptp3_cfg2[i][PTP3_CFG_ADDR] +
-			       PTP3_CORE_OFT(core);
-			value = ptp3_cfg2[i][PTP3_CFG_VALUE];
-
-			ptp3_write(addr, value);
-		}
-	} else {
-		for (i = 0; i < NR_PTP3_CFG2_DATA; i++) {
-			addr = ptp3_cfg2[i][PTP3_CFG_ADDR] +
-			       PTP3_CORE_OFT(core);
-
-			if (i == 2) {
-				value = ptp3_cfg2[i][PTP3_CFG_VALUE] + 0x5E0;
-			} else {
-				value = ptp3_cfg2[i][PTP3_CFG_VALUE];
-			}
-			ptp3_write(addr, value);
-		}
-	}
-
-	if (core < PTP3_CFG_CPU_START_ID_B) {
-		addr = ptp3_cfg3[PTP3_CFG_ADDR] + PTP3_CORE_OFT(core);
-		value = ptp3_cfg3[PTP3_CFG_VALUE];
-
-		ptp3_write(addr, value & PTP3_CFG3_MASK1);
-		ptp3_write(addr, value & PTP3_CFG3_MASK2);
-		ptp3_write(addr, value & PTP3_CFG3_MASK3);
-	} else {
-		addr = ptp3_cfg3_ext[PTP3_CFG_ADDR] + PTP3_CORE_OFT(core);
-		value = ptp3_cfg3_ext[PTP3_CFG_VALUE];
-
-		ptp3_write(addr, value & PTP3_CFG3_MASK1);
-		ptp3_write(addr, value & PTP3_CFG3_MASK2);
-		ptp3_write(addr, value & PTP3_CFG3_MASK3);
-	}
-}
-
-void pdp_proc_ARM_write(unsigned int pdp_n)
-{
-	unsigned long v = 0;
-
-	dsb();
-	__asm__ volatile ("mrs %0, S3_6_C15_C2_0" : "=r" (v));
-	v |= (UL(0x0) << 52);
-	v |= (UL(0x1) << 53);
-	v |= (UL(0x0) << 54);
-	v |= (UL(0x0) << 48);
-	v |= (UL(0x1) << 49);
-	__asm__ volatile ("msr S3_6_C15_C2_0, %0" : : "r" (v));
-	dsb();
-}
-
-void pdp_init(unsigned int pdp_cpu, unsigned int en)
-{
-	if ((pdp_cpu >= PTP3_CFG_CPU_START_ID_B) &&
-	    (pdp_cpu < NR_PTP3_CFG_CPU)) {
-		pdp_proc_ARM_write(pdp_cpu);
-	}
-}
-
-static void dt_proc_ARM_write(unsigned int dt_n)
-{
-	unsigned long v = 0;
-
-	dsb();
-	__asm__ volatile ("mrs %0, S3_6_C15_C2_0" : "=r" (v));
-	v |= (UL(0x0) << 33);
-	v |= (UL(0x0) << 32);
-	__asm__ volatile ("msr S3_6_C15_C2_0, %0" : : "r" (v));
-	dsb();
-}
-
-void dt_init(unsigned int dt_cpu, unsigned int en)
-{
-	if ((dt_cpu >= PTP3_CFG_CPU_START_ID_B) &&
-	    (dt_cpu < NR_PTP3_CFG_CPU)) {
-		dt_proc_ARM_write(dt_cpu);
-	}
-}
-void ptp3_core_init(unsigned int core)
-{
-	/* init for ptp3 */
-	ptp3_init(core);
-	/* init for pdp */
-	pdp_init(core, 1);
-	/* init for dt */
-	dt_init(core, 1);
-}
-
-void ptp3_core_unInit(unsigned int core)
-{
-	/* TBD */
-}
diff --git a/plat/mediatek/mt8195/drivers/ptp3/ptp3_plat.h b/plat/mediatek/mt8195/drivers/ptp3/ptp3_plat.h
new file mode 100644
index 0000000..7d5391c
--- /dev/null
+++ b/plat/mediatek/mt8195/drivers/ptp3/ptp3_plat.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PTP3_PLAT_H
+#define PTP3_PLAT_H
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <ptp3_common.h>
+
+/* CPU info */
+#define NR_PTP3_CFG_CPU			U(8)
+#define PTP3_CFG_CPU_START_ID_L		U(0)
+#define PTP3_CFG_CPU_START_ID_B		U(4)
+#define PTP3_CFG_CPU_END_ID		U(7)
+
+#define NR_PTP3_CFG1_DATA		U(2)
+#define PTP3_CFG1_MASK			0x3000
+
+#define NR_PTP3_CFG2_DATA		U(5)
+
+#define PTP3_CFG3_MASK1			0x1180
+#define PTP3_CFG3_MASK2			0x35C0
+#define PTP3_CFG3_MASK3			0x3DC0
+
+/* Central control */
+static unsigned int ptp3_cfg1[NR_PTP3_CFG1_DATA][NR_PTP3_CFG] = {
+	{0x0C53A2A0, 0x1000},
+	{0x0C53A2A4, 0x1000}
+};
+
+static unsigned int ptp3_cfg2[NR_PTP3_CFG2_DATA][NR_PTP3_CFG] = {
+	{0x0C530404, 0x3A1000},
+	{0x0C530428, 0x13E0408},
+	{0x0C530434, 0xB22800},
+	{0x0C53043C, 0x750},
+	{0x0C530440, 0x0222c4cc}
+};
+
+static unsigned int ptp3_cfg3[NR_PTP3_CFG] = {0x0C530400, 0x2D80};
+static unsigned int ptp3_cfg3_ext[NR_PTP3_CFG] = {0x0C530400, 0xC00};
+
+#endif /* PTP3_PLAT_H */
diff --git a/plat/mediatek/mt8195/plat_pm.c b/plat/mediatek/mt8195/plat_pm.c
index b77ab27..bd8a3fa 100644
--- a/plat/mediatek/mt8195/plat_pm.c
+++ b/plat/mediatek/mt8195/plat_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,15 +13,15 @@
 #include <lib/psci/psci.h>
 
 /* platform specific headers */
+#include <plat/common/platform.h>
 #include <mt_gic_v3.h>
-#include <mtk_ptp3_common.h>
 #include <mtspmc.h>
-#include <plat/common/platform.h>
 #include <plat_dfd.h>
 #include <plat_mtk_lpm.h>
 #include <plat_params.h>
 #include <plat_pm.h>
 #include <pmic.h>
+#include <ptp3_common.h>
 #include <rtc.h>
 
 /*
diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk
index 80dfa53..07d39cb 100644
--- a/plat/mediatek/mt8195/platform.mk
+++ b/plat/mediatek/mt8195/platform.mk
@@ -15,6 +15,7 @@
                  -I${MTK_PLAT}/drivers/gpio/                      \
                  -I${MTK_PLAT}/drivers/pmic/                      \
                  -I${MTK_PLAT}/drivers/pmic_wrap/                 \
+                 -I${MTK_PLAT}/drivers/ptp3/                      \
                  -I${MTK_PLAT}/drivers/rtc/                       \
                  -I${MTK_PLAT}/drivers/timer/                     \
                  -I${MTK_PLAT}/drivers/uart/                      \
@@ -59,6 +60,7 @@
                 ${MTK_PLAT}/drivers/gpio/mtgpio_common.c              \
                 ${MTK_PLAT}/drivers/pmic/pmic.c                       \
                 ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init_v2.c     \
+                ${MTK_PLAT}/drivers/ptp3/ptp3_common.c            \
                 ${MTK_PLAT}/drivers/rtc/rtc_common.c                  \
                 ${MTK_PLAT}/drivers/rtc/rtc_mt6359p.c                 \
                 ${MTK_PLAT}/drivers/timer/mt_timer.c                  \
@@ -79,7 +81,6 @@
                 ${MTK_PLAT_SOC}/drivers/mcdi/mt_mcdi.c                \
                 ${MTK_PLAT_SOC}/drivers/mcdi/mt_lp_irqremain.c        \
                 ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c                 \
-                ${MTK_PLAT_SOC}/drivers/ptp3/mtk_ptp3_main.c          \
                 ${MTK_PLAT_SOC}/drivers/spmc/mtspmc.c                 \
                 ${MTK_PLAT_SOC}/plat_pm.c                             \
                 ${MTK_PLAT_SOC}/plat_sip_calls.c                      \
diff --git a/plat/nxp/common/nv_storage/plat_nv_storage.c b/plat/nxp/common/nv_storage/plat_nv_storage.c
index af3b966..97d777e 100644
--- a/plat/nxp/common/nv_storage/plat_nv_storage.c
+++ b/plat/nxp/common/nv_storage/plat_nv_storage.c
@@ -93,7 +93,7 @@
 	uint8_t ready_to_write_val[sizeof(nv_app_data_t)];
 	uintptr_t nv_base_addr = NV_STORAGE_BASE_ADDR;
 
-	assert((nv_base_addr + data_offset + data_size) > (nv_base_addr + F_SECTOR_ERASE_SZ));
+	assert((nv_base_addr + data_offset + data_size) <= (nv_base_addr + F_SECTOR_ERASE_SZ));
 
 	ret = fspi_init(NXP_FLEXSPI_ADDR, NXP_FLEXSPI_FLASH_ADDR);
 
diff --git a/plat/nxp/soc-ls1028a/soc.def b/plat/nxp/soc-ls1028a/soc.def
index c23c1bb..93275b3 100644
--- a/plat/nxp/soc-ls1028a/soc.def
+++ b/plat/nxp/soc-ls1028a/soc.def
@@ -70,8 +70,8 @@
 BL2_HDR_LOC	:=	0x1800A000
 
 # SoC ERRATAS to be enabled
-ERRATA_SOC_A008850	:=	1
 
+# DDR ERRATA
 ERRATA_DDR_A009803	:=	1
 ERRATA_DDR_A009942	:=	1
 ERRATA_DDR_A010165	:=	1
diff --git a/plat/nxp/soc-ls1043a/soc.c b/plat/nxp/soc-ls1043a/soc.c
index 7badf8c..3e821d0 100644
--- a/plat/nxp/soc-ls1043a/soc.c
+++ b/plat/nxp/soc-ls1043a/soc.c
@@ -21,9 +21,7 @@
 #ifdef POLICY_FUSE_PROVISION
 #include <nxp_gpio.h>
 #endif
-#if TRUSTED_BOARD_BOOT
 #include <nxp_smmu.h>
-#endif
 #include <nxp_timer.h>
 #include <plat_console.h>
 #include <plat_gic.h>
@@ -174,6 +172,12 @@
 	get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
 	plat_ls_interconnect_enter_coherency(num_clusters);
 
+	/*
+	 * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts.
+	 */
+	smmu_cache_unlock(NXP_SMMU_ADDR);
+	INFO("SMMU Cache Unlocking is Configured.\n");
+
 #if TRUSTED_BOARD_BOOT
 	uint32_t mode;
 
diff --git a/plat/nxp/soc-ls1043a/soc.mk b/plat/nxp/soc-ls1043a/soc.mk
index b6ce14e..0ebb377 100644
--- a/plat/nxp/soc-ls1043a/soc.mk
+++ b/plat/nxp/soc-ls1043a/soc.mk
@@ -19,8 +19,8 @@
 
 # For Security Features
 DISABLE_FUSE_WRITE	:= 1
-ifeq (${TRUSTED_BOARD_BOOT}, 1)
 $(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
 $(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
 $(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
 SECURE_BOOT	:= yes
diff --git a/plat/nxp/soc-ls1046a/soc.c b/plat/nxp/soc-ls1046a/soc.c
index d17e672..6dfea89 100644
--- a/plat/nxp/soc-ls1046a/soc.c
+++ b/plat/nxp/soc-ls1046a/soc.c
@@ -21,9 +21,7 @@
 #ifdef POLICY_FUSE_PROVISION
 #include <nxp_gpio.h>
 #endif
-#if TRUSTED_BOARD_BOOT
 #include <nxp_smmu.h>
-#endif
 #include <nxp_timer.h>
 #include <plat_console.h>
 #include <plat_gic.h>
@@ -168,6 +166,12 @@
 	get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
 	plat_ls_interconnect_enter_coherency(num_clusters);
 
+	/*
+	 * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts.
+	 */
+	smmu_cache_unlock(NXP_SMMU_ADDR);
+	INFO("SMMU Cache Unlocking is Configured.\n");
+
 #if TRUSTED_BOARD_BOOT
 	uint32_t mode;
 
diff --git a/plat/nxp/soc-ls1046a/soc.def b/plat/nxp/soc-ls1046a/soc.def
index e6b37c0..50fc9c9 100644
--- a/plat/nxp/soc-ls1046a/soc.def
+++ b/plat/nxp/soc-ls1046a/soc.def
@@ -41,11 +41,11 @@
 DDRPHY		:=	NXP
 
 # Area of OCRAM reserved by ROM code
-NXP_ROM_RSVD	:= 0x5900
+NXP_ROM_RSVD	:= 0x8000
 
 # Max Size of CSF header. Required to define BL2 TEXT LIMIT in soc.def
 # Input to CST create_hdr_esbc tool
-CSF_HDR_SZ	:= 0x3000
+CSF_HDR_SZ	:= 0x4000
 
 # In IMAGE_BL2, compile time flag for handling Cache coherency
 # with CAAM for BL2 running from OCRAM
diff --git a/plat/nxp/soc-ls1046a/soc.mk b/plat/nxp/soc-ls1046a/soc.mk
index 8207dcd..7644027 100644
--- a/plat/nxp/soc-ls1046a/soc.mk
+++ b/plat/nxp/soc-ls1046a/soc.mk
@@ -19,8 +19,8 @@
 
 # For Security Features
 DISABLE_FUSE_WRITE	:= 1
-ifeq (${TRUSTED_BOARD_BOOT}, 1)
 $(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
 $(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
 $(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
 SECURE_BOOT	:= yes
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c b/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c
index b7397ba..705463b 100644
--- a/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c
@@ -78,7 +78,5 @@
 		ERROR("DDR init failed.\n");
 	}
 
-	erratum_a008850_post();
-
 	return dram_size;
 }
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c b/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c
index c88583f..107871a 100644
--- a/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c
@@ -80,7 +80,5 @@
 		ERROR("DDR init failed.\n");
 	}
 
-	erratum_a008850_post();
-
 	return dram_size;
 }
diff --git a/plat/nxp/soc-ls1088a/soc.c b/plat/nxp/soc-ls1088a/soc.c
index 5f9f313..02d62ea 100644
--- a/plat/nxp/soc-ls1088a/soc.c
+++ b/plat/nxp/soc-ls1088a/soc.c
@@ -17,9 +17,7 @@
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <ls_interconnect.h>
-#if TRUSTED_BOARD_BOOT
 #include <nxp_smmu.h>
-#endif
 #include <nxp_timer.h>
 #include <plat_console.h>
 #include <plat_gic.h>
@@ -254,6 +252,12 @@
 				MT_DEVICE | MT_RW | MT_NS);
 	}
 
+	/*
+	 * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts.
+	 */
+	smmu_cache_unlock(NXP_SMMU_ADDR);
+	INFO("SMMU Cache Unlocking is Configured.\n");
+
 #if TRUSTED_BOARD_BOOT
 	uint32_t mode;
 
diff --git a/plat/nxp/soc-ls1088a/soc.def b/plat/nxp/soc-ls1088a/soc.def
index 25d0847..17c59ff 100644
--- a/plat/nxp/soc-ls1088a/soc.def
+++ b/plat/nxp/soc-ls1088a/soc.def
@@ -62,7 +62,6 @@
 BL2_BASE		:=	0x1800a000
 
 # SoC ERRATUM to be enabled
-ERRATA_SOC_A008850	:=	1
 
 # ARM Erratum
 ERRATA_A53_855873	:=	1
diff --git a/plat/nxp/soc-ls1088a/soc.mk b/plat/nxp/soc-ls1088a/soc.mk
index 83ac9d0..6e39461 100644
--- a/plat/nxp/soc-ls1088a/soc.mk
+++ b/plat/nxp/soc-ls1088a/soc.mk
@@ -23,12 +23,12 @@
 
 # For Security Features
 DISABLE_FUSE_WRITE	:= 1
+$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
 ifeq (${TRUSTED_BOARD_BOOT}, 1)
 ifeq (${GENERATE_COT},1)
 # Save Keys to be used by DDR FIP image
 SAVE_KEYS=1
 endif
-$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
 $(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
 $(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
 # Used by create_pbl tool to
diff --git a/plat/nxp/soc-lx2160a/include/soc.h b/plat/nxp/soc-lx2160a/include/soc.h
index 7cc4a03..b781ff8 100644
--- a/plat/nxp/soc-lx2160a/include/soc.h
+++ b/plat/nxp/soc-lx2160a/include/soc.h
@@ -54,8 +54,31 @@
 
 /* SVR Definition (not include major and minor rev) */
 #define SVR_LX2160A		0x873601
+#define SVR_LX2160E		0x873610
+#define SVR_LX2160C		0x873600
+#define SVR_LX2160N		0x873611
 #define SVR_LX2120A		0x873621
+#define SVR_LX2120E		0x873630
+#define SVR_LX2120C		0x873620
+#define SVR_LX2120N		0x873631
 #define SVR_LX2080A		0x873603
+#define SVR_LX2080E		0x873612
+#define SVR_LX2080C		0x873602
+#define SVR_LX2080N		0x873613
+
+/* SVR Definition of SoC LX2162A. */
+#define SVR_LX2162A		0x873609
+#define SVR_LX2162E		0x873618
+#define SVR_LX2162C		0x873608
+#define SVR_LX2162N		0x873619
+#define SVR_LX2122A		0x873629
+#define SVR_LX2122E		0x873638
+#define SVR_LX2122C		0x873628
+#define SVR_LX2122N		0x873639
+#define SVR_LX2082A		0x87360b
+#define SVR_LX2082E		0x87361a
+#define SVR_LX2082C		0x87360a
+#define SVR_LX2082N		0x87361b
 
 /* Number of cores in platform */
 /* Used by common code for array initialization */
diff --git a/plat/nxp/soc-lx2160a/soc.c b/plat/nxp/soc-lx2160a/soc.c
index 2209fda..427189d 100644
--- a/plat/nxp/soc-lx2160a/soc.c
+++ b/plat/nxp/soc-lx2160a/soc.c
@@ -23,9 +23,7 @@
 #ifdef POLICY_FUSE_PROVISION
 #include <nxp_gpio.h>
 #endif
-#if TRUSTED_BOARD_BOOT
 #include <nxp_smmu.h>
-#endif
 #include <nxp_timer.h>
 #include <plat_console.h>
 #include <plat_gic.h>
@@ -37,6 +35,9 @@
 
 #include <errata.h>
 #include <ls_interrupt_mgmt.h>
+#ifdef CONFIG_OCRAM_ECC_EN
+#include <ocram.h>
+#endif
 #include "plat_common.h"
 #ifdef NXP_NV_SW_MAINT_LAST_EXEC_DATA
 #include <plat_nv_storage.h>
@@ -48,9 +49,32 @@
 #include "soc.h"
 
 static struct soc_type soc_list[] =  {
+	/* SoC LX2160A */
 	SOC_ENTRY(LX2160A, LX2160A, 8, 2),
+	SOC_ENTRY(LX2160E, LX2160E, 8, 2),
+	SOC_ENTRY(LX2160C, LX2160C, 8, 2),
+	SOC_ENTRY(LX2160N, LX2160N, 8, 2),
 	SOC_ENTRY(LX2080A, LX2080A, 8, 1),
+	SOC_ENTRY(LX2080E, LX2080E, 8, 1),
+	SOC_ENTRY(LX2080C, LX2080C, 8, 1),
+	SOC_ENTRY(LX2080N, LX2080N, 8, 1),
 	SOC_ENTRY(LX2120A, LX2120A, 6, 2),
+	SOC_ENTRY(LX2120E, LX2120E, 6, 2),
+	SOC_ENTRY(LX2120C, LX2120C, 6, 2),
+	SOC_ENTRY(LX2120N, LX2120N, 6, 2),
+	/* SoC LX2162A */
+	SOC_ENTRY(LX2162A, LX2162A, 8, 2),
+	SOC_ENTRY(LX2162E, LX2162E, 8, 2),
+	SOC_ENTRY(LX2162C, LX2162C, 8, 2),
+	SOC_ENTRY(LX2162N, LX2162N, 8, 2),
+	SOC_ENTRY(LX2082A, LX2082A, 8, 1),
+	SOC_ENTRY(LX2082E, LX2082E, 8, 1),
+	SOC_ENTRY(LX2082C, LX2082C, 8, 1),
+	SOC_ENTRY(LX2082N, LX2082N, 8, 1),
+	SOC_ENTRY(LX2122A, LX2122A, 6, 2),
+	SOC_ENTRY(LX2122E, LX2122E, 6, 2),
+	SOC_ENTRY(LX2122C, LX2122C, 6, 2),
+	SOC_ENTRY(LX2122N, LX2122N, 6, 2),
 };
 
 static dcfg_init_info_t dcfg_init_data = {
@@ -215,6 +239,9 @@
  ******************************************************************************/
 void soc_early_init(void)
 {
+#ifdef CONFIG_OCRAM_ECC_EN
+	ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE);
+#endif
 	dcfg_init(&dcfg_init_data);
 #ifdef POLICY_FUSE_PROVISION
 	gpio_init(&gpio_init_data);
@@ -257,6 +284,12 @@
 	sfp_init(NXP_SFP_ADDR);
 #endif
 
+	/*
+	 * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts.
+	 */
+	smmu_cache_unlock(NXP_SMMU_ADDR);
+	INFO("SMMU Cache Unlocking is Configured.\n");
+
 #if TRUSTED_BOARD_BOOT
 	uint32_t mode;
 
@@ -451,8 +484,8 @@
 
 	/* low-level init of the soc */
 	soc_init_start();
-	soc_init_percpu();
 	_init_global_data();
+	soc_init_percpu();
 	_initialize_psci();
 
 	if (ccn_get_part0_id(NXP_CCN_ADDR) != CCN_508_PART0_ID) {
diff --git a/plat/nxp/soc-lx2160a/soc.def b/plat/nxp/soc-lx2160a/soc.def
index 81d6744..0442962 100644
--- a/plat/nxp/soc-lx2160a/soc.def
+++ b/plat/nxp/soc-lx2160a/soc.def
@@ -114,3 +114,6 @@
 
 # enable dynamic memory mapping
 PLAT_XLAT_TABLES_DYNAMIC :=	1
+
+# OCRAM ECC Enabled
+OCRAM_ECC_EN            :=      yes
diff --git a/plat/nxp/soc-lx2160a/soc.mk b/plat/nxp/soc-lx2160a/soc.mk
index 75a3af2..239442c 100644
--- a/plat/nxp/soc-lx2160a/soc.mk
+++ b/plat/nxp/soc-lx2160a/soc.mk
@@ -36,12 +36,12 @@
 
  # For Security Features
 DISABLE_FUSE_WRITE	:= 1
+$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
 ifeq (${TRUSTED_BOARD_BOOT}, 1)
 ifeq (${GENERATE_COT},1)
 # Save Keys to be used by DDR FIP image
 SAVE_KEYS=1
 endif
-$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
 $(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
 $(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
 # Used by create_pbl tool to
diff --git a/plat/qemu/common/qemu_bl2_mem_params_desc.c b/plat/qemu/common/qemu_bl2_mem_params_desc.c
index 5af3a22..bb1797d 100644
--- a/plat/qemu/common/qemu_bl2_mem_params_desc.c
+++ b/plat/qemu/common/qemu_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,18 @@
 #include <common/desc_image_load.h>
 #include <plat/common/platform.h>
 
+#define SP_PKG_ENTRY(id) \
+	{ \
+		.image_id = (id), \
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, VERSION_2, \
+				      entry_point_info_t, \
+				      SECURE | NON_EXECUTABLE), \
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, \
+				      VERSION_2, image_info_t, \
+				      IMAGE_ATTRIB_SKIP_LOADING), \
+		.next_handoff_image_id = INVALID_IMAGE_ID, \
+	}
+
 /*******************************************************************************
  * Following descriptor provides BL image/ep information that gets used
  * by BL2 to load the images and also subset of this information is
@@ -122,6 +134,48 @@
 #endif
 	   .next_handoff_image_id = INVALID_IMAGE_ID,
 	},
+
+#if defined(SPD_spmd)
+	/* Fill TOS_FW_CONFIG related information */
+	{
+	    .image_id = TOS_FW_CONFIG_ID,
+	    SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+		    VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+	    SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+		    VERSION_2, image_info_t, 0),
+	    .image_info.image_base = TOS_FW_CONFIG_BASE,
+	    .image_info.image_max_size = TOS_FW_CONFIG_LIMIT -
+					 TOS_FW_CONFIG_BASE,
+	    .next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+#if SPMD_SPM_AT_SEL2
+	/* Fill TB_FW_CONFIG related information */
+	{
+	    .image_id = TB_FW_CONFIG_ID,
+	    SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+		    VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+	    SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+		    VERSION_2, image_info_t, 0),
+	    .image_info.image_base = TB_FW_CONFIG_BASE,
+	    .image_info.image_max_size = TB_FW_CONFIG_LIMIT - TB_FW_CONFIG_BASE,
+	    .next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+	/*
+	 * Empty entries for SP packages to be filled in according to
+	 * TB_FW_CONFIG.
+	 */
+	SP_PKG_ENTRY(SP_PKG1_ID),
+	SP_PKG_ENTRY(SP_PKG2_ID),
+	SP_PKG_ENTRY(SP_PKG3_ID),
+	SP_PKG_ENTRY(SP_PKG4_ID),
+	SP_PKG_ENTRY(SP_PKG5_ID),
+	SP_PKG_ENTRY(SP_PKG6_ID),
+	SP_PKG_ENTRY(SP_PKG7_ID),
+	SP_PKG_ENTRY(SP_PKG8_ID),
+#endif
+#endif
 # endif /* QEMU_LOAD_BL32 */
 
 	/* Fill BL33 related information */
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index 2c0da15..be55877 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +16,7 @@
 #include <common/debug.h>
 #include <common/desc_image_load.h>
 #include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
 #include <lib/optee_utils.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
@@ -140,6 +141,48 @@
 	return spsr;
 }
 
+#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+static int load_sps_from_tb_fw_config(struct image_info *image_info)
+{
+	void *dtb = (void *)image_info->image_base;
+	const char *compat_str = "arm,sp";
+	const struct fdt_property *uuid;
+	uint32_t load_addr;
+	const char *name;
+	int sp_node;
+	int node;
+
+	node = fdt_node_offset_by_compatible(dtb, -1, compat_str);
+	if (node < 0) {
+		ERROR("Can't find %s in TB_FW_CONFIG", compat_str);
+		return -1;
+	}
+
+	fdt_for_each_subnode(sp_node, dtb, node) {
+		name = fdt_get_name(dtb, sp_node, NULL);
+		if (name == NULL) {
+			ERROR("Can't get name of node in dtb\n");
+			return -1;
+		}
+		uuid = fdt_get_property(dtb, sp_node, "uuid", NULL);
+		if (uuid == NULL) {
+			ERROR("Can't find property uuid in node %s", name);
+			return -1;
+		}
+		if (fdt_read_uint32(dtb, sp_node, "load-address",
+				    &load_addr) < 0) {
+			ERROR("Can't read load-address in node %s", name);
+			return -1;
+		}
+		if (qemu_io_register_sp_pkg(name, uuid->data, load_addr) < 0) {
+			return -1;
+		}
+	}
+
+	return 0;
+}
+#endif /*defined(SPD_spmd) && SPMD_SPM_AT_SEL2*/
+
 static int qemu_bl2_handle_post_image_load(unsigned int image_id)
 {
 	int err = 0;
@@ -149,8 +192,7 @@
 	bl_mem_params_node_t *paged_mem_params = NULL;
 #endif
 #if defined(SPD_spmd)
-	unsigned int mode_rw = MODE_RW_64;
-	uint64_t pagable_part = 0;
+	bl_mem_params_node_t *bl32_mem_params = NULL;
 #endif
 
 	assert(bl_mem_params);
@@ -170,17 +212,18 @@
 		if (err != 0) {
 			WARN("OPTEE header parse error.\n");
 		}
-#if defined(SPD_spmd)
-		mode_rw = bl_mem_params->ep_info.args.arg0;
-		pagable_part = bl_mem_params->ep_info.args.arg1;
-#endif
 #endif
 
-#if defined(SPD_spmd)
-		bl_mem_params->ep_info.args.arg0 = ARM_PRELOADED_DTB_BASE;
-		bl_mem_params->ep_info.args.arg1 = pagable_part;
-		bl_mem_params->ep_info.args.arg2 = mode_rw;
-		bl_mem_params->ep_info.args.arg3 = 0;
+#if defined(SPMC_OPTEE)
+		/*
+		 * Explicit zeroes to unused registers since they may have
+		 * been populated by parse_optee_header() above.
+		 *
+		 * OP-TEE expects system DTB in x2 and TOS_FW_CONFIG in x0,
+		 * the latter is filled in below for TOS_FW_CONFIG_ID and
+		 * applies to any other SPMC too.
+		 */
+		bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE;
 #elif defined(SPD_opteed)
 		/*
 		 * OP-TEE expect to receive DTB address in x2.
@@ -224,6 +267,19 @@
 
 		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
 		break;
+#ifdef SPD_spmd
+#if SPMD_SPM_AT_SEL2
+	case TB_FW_CONFIG_ID:
+		err = load_sps_from_tb_fw_config(&bl_mem_params->image_info);
+		break;
+#endif
+	case TOS_FW_CONFIG_ID:
+		/* An SPMC expects TOS_FW_CONFIG in x0/r0 */
+		bl32_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
+		bl32_mem_params->ep_info.args.arg0 =
+					bl_mem_params->image_info.image_base;
+		break;
+#endif
 	default:
 		/* Do nothing in default case */
 		break;
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 0c184f4..23ac581 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -10,6 +10,7 @@
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
+#include <services/el3_spmc_ffa_memory.h>
 
 #include <plat/common/platform.h>
 #include "qemu_private.h"
@@ -100,7 +101,7 @@
 #if SPM_MM
 	MAP_NS_DRAM0,
 	QEMU_SPM_BUF_EL3_MMAP,
-#else
+#elif !SPMC_AT_EL3
 	MAP_BL32_MEM,
 #endif
 	{0}
@@ -167,3 +168,30 @@
 	return get_mbedtls_heap_helper(heap_addr, heap_size);
 }
 #endif
+
+#if SPMC_AT_EL3
+/*
+ * When using the EL3 SPMC implementation allocate the datastore
+ * for tracking shared memory descriptors in normal memory.
+ */
+#define PLAT_SPMC_SHMEM_DATASTORE_SIZE 64 * 1024
+
+uint8_t plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE];
+
+int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
+{
+	*datastore = plat_spmc_shmem_datastore;
+	*size = PLAT_SPMC_SHMEM_DATASTORE_SIZE;
+	return 0;
+}
+
+int plat_spmc_shmem_begin(struct ffa_mtd *desc)
+{
+	return 0;
+}
+
+int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
+{
+	return 0;
+}
+#endif
diff --git a/plat/qemu/common/qemu_io_storage.c b/plat/qemu/common/qemu_io_storage.c
index 1107e44..4c61b14 100644
--- a/plat/qemu/common/qemu_io_storage.c
+++ b/plat/qemu/common/qemu_io_storage.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,8 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <common/uuid.h>
 #include <drivers/io/io_driver.h>
 #include <drivers/io/io_encrypted.h>
 #include <drivers/io/io_fip.h>
@@ -20,10 +22,14 @@
 #include <lib/semihosting.h>
 #include <tools_share/firmware_image_package.h>
 
+#include "qemu_private.h"
+
 /* Semihosting filenames */
 #define BL2_IMAGE_NAME			"bl2.bin"
 #define BL31_IMAGE_NAME			"bl31.bin"
 #define BL32_IMAGE_NAME			"bl32.bin"
+#define TB_FW_CONFIG_NAME		"tb_fw_config.dtb"
+#define TOS_FW_CONFIG_NAME		"tos_fw_config.dtb"
 #define BL32_EXTRA1_IMAGE_NAME		"bl32_extra1.bin"
 #define BL32_EXTRA2_IMAGE_NAME		"bl32_extra2.bin"
 #define BL33_IMAGE_NAME			"bl33.bin"
@@ -78,6 +84,14 @@
 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
 };
 
+static const io_uuid_spec_t tb_fw_config_uuid_spec = {
+	.uuid = UUID_TB_FW_CONFIG,
+};
+
+static const io_uuid_spec_t tos_fw_config_uuid_spec = {
+	.uuid = UUID_TOS_FW_CONFIG,
+};
+
 static const io_uuid_spec_t bl33_uuid_spec = {
 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
 };
@@ -137,6 +151,14 @@
 		.path = BL32_EXTRA2_IMAGE_NAME,
 		.mode = FOPEN_MODE_RB
 	},
+	[TB_FW_CONFIG_ID] = {
+		.path = TB_FW_CONFIG_NAME,
+		.mode = FOPEN_MODE_RB
+	},
+	[TOS_FW_CONFIG_ID] = {
+		.path = TOS_FW_CONFIG_NAME,
+		.mode = FOPEN_MODE_RB
+	},
 	[BL33_IMAGE_ID] = {
 		.path = BL33_IMAGE_NAME,
 		.mode = FOPEN_MODE_RB
@@ -252,6 +274,16 @@
 		open_fip
 	},
 #endif
+	[TB_FW_CONFIG_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&tb_fw_config_uuid_spec,
+		open_fip
+	},
+	[TOS_FW_CONFIG_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&tos_fw_config_uuid_spec,
+		open_fip
+	},
 	[BL33_IMAGE_ID] = {
 		&fip_dev_handle,
 		(uintptr_t)&bl33_uuid_spec,
@@ -301,6 +333,80 @@
 #endif /* TRUSTED_BOARD_BOOT */
 };
 
+#if defined(SPD_spmd)
+static struct sp_pkg {
+	struct plat_io_policy policy;
+	io_file_spec_t sh_file_spec;
+	uint8_t uuid[UUID_BYTES_LENGTH];
+	char path[80];
+} sp_pkgs[MAX_SP_IDS];
+static unsigned int sp_pkg_count;
+
+int qemu_io_register_sp_pkg(const char *name, const char *uuid,
+			    uintptr_t load_addr)
+{
+	struct sp_pkg *pkg;
+	bl_mem_params_node_t *mem_params;
+
+	if (sp_pkg_count == MAX_SP_IDS) {
+		INFO("Reached Max number of SPs\n");
+		return -1;
+	}
+	mem_params = get_bl_mem_params_node(SP_PKG1_ID + sp_pkg_count);
+	if (mem_params == NULL) {
+		ERROR("Can't find SP_PKG ID %u (SP_PKG%u_ID)\n",
+		      SP_PKG1_ID + sp_pkg_count, sp_pkg_count);
+		return -1;
+	}
+	pkg = sp_pkgs + sp_pkg_count;
+
+	if (read_uuid(pkg->uuid, (char *)uuid)) {
+		return -1;
+	}
+
+	strlcpy(pkg->path, name, sizeof(pkg->path));
+	strlcat(pkg->path, ".pkg", sizeof(pkg->path));
+
+	pkg->policy.dev_handle = &fip_dev_handle;
+	pkg->policy.image_spec = (uintptr_t)&pkg->uuid;
+	pkg->policy.check = open_fip;
+	pkg->sh_file_spec.path = pkg->path;
+	pkg->sh_file_spec.mode = FOPEN_MODE_RB;
+
+	mem_params->image_info.image_base = load_addr;
+	mem_params->image_info.image_max_size = SZ_4M;
+	mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+
+	sp_pkg_count++;
+
+	return 0;
+}
+#endif /*SPD_spmd*/
+
+static const io_file_spec_t *get_io_file_spec(unsigned int image_id)
+{
+#if defined(SPD_spmd)
+	if (image_id >= SP_PKG1_ID && image_id <= SP_PKG8_ID) {
+		return &sp_pkgs[image_id - SP_PKG1_ID].sh_file_spec;
+	}
+#endif
+
+	assert(image_id < ARRAY_SIZE(sh_file_spec));
+	return &sh_file_spec[image_id];
+}
+
+static const struct plat_io_policy *get_io_policy(unsigned int image_id)
+{
+#if defined(SPD_spmd)
+	if (image_id >= SP_PKG1_ID && image_id <= SP_PKG8_ID) {
+		return &sp_pkgs[image_id - SP_PKG1_ID].policy;
+	}
+#endif
+
+	assert(image_id < ARRAY_SIZE(policies));
+	return &policies[image_id];
+}
+
 static int open_fip(const uintptr_t spec)
 {
 	int result;
@@ -413,11 +519,13 @@
 static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle,
 				  uintptr_t *image_spec)
 {
-	int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]);
+	const io_file_spec_t *spec = get_io_file_spec(image_id);
+	int result;
 
+	result = open_semihosting((const uintptr_t)spec);
 	if (result == 0) {
 		*dev_handle = sh_dev_handle;
-		*image_spec = (uintptr_t)&sh_file_spec[image_id];
+		*image_spec = (uintptr_t)spec;
 	}
 
 	return result;
@@ -430,12 +538,9 @@
 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
 			  uintptr_t *image_spec)
 {
+	const struct plat_io_policy *policy = get_io_policy(image_id);
 	int result;
-	const struct plat_io_policy *policy;
-
-	assert(image_id < ARRAY_SIZE(policies));
 
-	policy = &policies[image_id];
 	result = policy->check(policy->image_spec);
 	if (result == 0) {
 		*image_spec = policy->image_spec;
diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h
index c313cb6..159c44f 100644
--- a/plat/qemu/common/qemu_private.h
+++ b/plat/qemu/common/qemu_private.h
@@ -26,6 +26,8 @@
 			unsigned long coh_start, unsigned long coh_limit);
 
 void plat_qemu_io_setup(void);
+int qemu_io_register_sp_pkg(const char *name, const char *uuid,
+			    uintptr_t load_addr);
 unsigned int plat_qemu_calc_core_pos(u_register_t mpidr);
 
 void qemu_console_init(void);
diff --git a/plat/qemu/common/qemu_spmd_manifest.c b/plat/qemu/common/qemu_spmd_manifest.c
deleted file mode 100644
index fd46e26..0000000
--- a/plat/qemu/common/qemu_spmd_manifest.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <services/spm_core_manifest.h>
-
-#include <plat/common/platform.h>
-#include <platform_def.h>
-
-int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
-				const void *pm_addr)
-{
-	entry_point_info_t *ep_info = bl31_plat_get_next_image_ep_info(SECURE);
-
-	assert(ep_info != NULL);
-	assert(manifest != NULL);
-
-	manifest->major_version = 1;
-	manifest->minor_version = 0;
-	manifest->exec_state = ep_info->args.arg2;
-	manifest->load_address = BL32_BASE;
-	manifest->entrypoint = BL32_BASE;
-	manifest->binary_size = BL32_LIMIT - BL32_BASE;
-	manifest->spmc_id = 0x8000;
-
-	return 0;
-}
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index c9ed640..803f8e2 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -118,6 +118,11 @@
 #define BL_RAM_BASE			(SHARED_RAM_BASE + SHARED_RAM_SIZE)
 #define BL_RAM_SIZE			(SEC_SRAM_SIZE - SHARED_RAM_SIZE)
 
+#define TB_FW_CONFIG_BASE		BL_RAM_BASE
+#define TB_FW_CONFIG_LIMIT		(TB_FW_CONFIG_BASE + PAGE_SIZE)
+#define TOS_FW_CONFIG_BASE		TB_FW_CONFIG_LIMIT
+#define TOS_FW_CONFIG_LIMIT		(TOS_FW_CONFIG_BASE + PAGE_SIZE)
+
 /*
  * BL1 specific defines.
  *
@@ -137,7 +142,7 @@
  * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
  * size plus a little space for growth.
  */
-#define BL2_BASE			(BL31_BASE - 0x25000)
+#define BL2_BASE			(BL31_BASE - 0x35000)
 #define BL2_LIMIT			BL31_BASE
 
 /*
@@ -183,8 +188,8 @@
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#define MAX_MMAP_REGIONS		11
-#define MAX_XLAT_TABLES			6
+#define MAX_MMAP_REGIONS		(11 + MAX_MMAP_REGIONS_SPMC)
+#define MAX_XLAT_TABLES			(6 + MAX_XLAT_TABLES_SPMC)
 #define MAX_IO_DEVICES			4
 #define MAX_IO_HANDLES			4
 
@@ -275,4 +280,32 @@
  */
 #define	PLAT_EVENT_LOG_MAX_SIZE		UL(0x400)
 
+#if SPMC_AT_EL3
+/*
+ * Number of Secure Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of
+ * supported secure partitions.
+ */
+#define SECURE_PARTITION_COUNT		1
+
+/*
+ * Number of Logical Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of
+ * supported logical partitions.
+ */
+#define MAX_EL3_LP_DESCS_COUNT		0
+
+/*
+ * Number of Normal World Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of
+ * supported normal world partitions.
+ */
+#define NS_PARTITION_COUNT		1
+
+#define MAX_MMAP_REGIONS_SPMC		2
+#define MAX_XLAT_TABLES_SPMC		4
+#else
+#define MAX_MMAP_REGIONS_SPMC		0
+#define MAX_XLAT_TABLES_SPMC		0
+#endif
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 6becc32..4cbce9d 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -109,7 +109,6 @@
     endif
 
     BL2_SOURCES		+=	plat/qemu/qemu/qemu_measured_boot.c	\
-				plat/qemu/qemu/qemu_common_measured_boot.c	\
 				plat/qemu/qemu/qemu_helpers.c		\
 				${EVENT_LOG_SOURCES}
 
@@ -162,7 +161,8 @@
 				${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c		\
 				common/fdt_fixup.c					\
 				common/fdt_wrappers.c					\
-				common/desc_image_load.c
+				common/desc_image_load.c				\
+				common/uuid.c
 
 ifeq ($(add-lib-optee),yes)
 BL2_SOURCES		+=	lib/optee/optee_utils.c
@@ -211,8 +211,17 @@
 				${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c		\
 				${QEMU_GIC_SOURCES}
 
+# Pointer Authentication sources
+ifeq (${ENABLE_PAUTH}, 1)
+PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c	\
+				lib/extensions/pauth/pauth_helpers.S
+endif
+
 ifeq (${SPD},spmd)
-BL31_SOURCES		+=	plat/qemu/common/qemu_spmd_manifest.c
+BL31_SOURCES		+=	plat/common/plat_spmd_manifest.c	\
+				common/uuid.c				\
+				${LIBFDT_SRCS} 				\
+				${FDT_WRAPPERS_SOURCES}
 endif
 endif
 
@@ -231,6 +240,20 @@
 else
 $(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2))
 endif
+endif
+
+ifneq ($(QEMU_TB_FW_CONFIG_DTS),)
+FDT_SOURCES		+=	${QEMU_TB_FW_CONFIG_DTS}
+QEMU_TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/$(notdir $(basename ${QEMU_TB_FW_CONFIG_DTS})).dtb
+# Add the TB_FW_CONFIG to FIP
+$(eval $(call TOOL_ADD_PAYLOAD,${QEMU_TB_FW_CONFIG},--tb-fw-config,${QEMU_TB_FW_CONFIG}))
+endif
+
+ifneq ($(QEMU_TOS_FW_CONFIG_DTS),)
+FDT_SOURCES		+=	${QEMU_TOS_FW_CONFIG_DTS}
+QEMU_TOS_FW_CONFIG	:=	${BUILD_PLAT}/fdts/$(notdir $(basename ${QEMU_TOS_FW_CONFIG_DTS})).dtb
+# Add the TOS_FW_CONFIG to FIP
+$(eval $(call TOOL_ADD_PAYLOAD,${QEMU_TOS_FW_CONFIG},--tos-fw-config,${QEMU_TOS_FW_CONFIG}))
 endif
 
 SEPARATE_CODE_AND_RODATA := 1
diff --git a/plat/qemu/qemu/qemu_common_measured_boot.c b/plat/qemu/qemu/qemu_common_measured_boot.c
deleted file mode 100644
index 41f7f87..0000000
--- a/plat/qemu/qemu/qemu_common_measured_boot.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2022, Linaro.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <stdint.h>
-
-#include <common/desc_image_load.h>
-#include <drivers/measured_boot/event_log/event_log.h>
-#include <plat/common/platform.h>
-
-extern event_log_metadata_t qemu_event_log_metadata[];
-
-const event_log_metadata_t *plat_event_log_get_metadata(void)
-{
-	return qemu_event_log_metadata;
-}
-
-int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
-{
-	/* Calculate image hash and record data in Event Log */
-	int err = event_log_measure_and_record(image_data->image_base,
-					       image_data->image_size,
-					       image_id);
-	if (err != 0) {
-		ERROR("%s%s image id %u (%i)\n",
-		      "Failed to ", "record", image_id, err);
-		return err;
-	}
-
-	return 0;
-}
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
index d9e475a..122bb23 100644
--- a/plat/qemu/qemu/qemu_measured_boot.c
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -9,6 +9,7 @@
 
 #include <drivers/measured_boot/event_log/event_log.h>
 #include <plat/common/common_def.h>
+#include <plat/common/platform.h>
 #include <tools_share/tbbr_oid.h>
 
 #include "../common/qemu_private.h"
@@ -17,8 +18,8 @@
 static uint8_t event_log[PLAT_EVENT_LOG_MAX_SIZE];
 static uint64_t event_log_base;
 
-/* FVP table with platform specific image IDs, names and PCRs */
-const event_log_metadata_t qemu_event_log_metadata[] = {
+/* QEMU table with platform specific image IDs, names and PCRs */
+static const event_log_metadata_t qemu_event_log_metadata[] = {
 	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
 	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
 	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
@@ -101,3 +102,19 @@
 
 	dump_event_log((uint8_t *)event_log_base, event_log_cur_size);
 }
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	/* Calculate image hash and record data in Event Log */
+	int err = event_log_measure_and_record(image_data->image_base,
+					       image_data->image_size,
+					       image_id,
+					       qemu_event_log_metadata);
+	if (err != 0) {
+		ERROR("%s%s image id %u (%i)\n",
+		      "Failed to ", "record", image_id, err);
+		return err;
+	}
+
+	return 0;
+}
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 5a6b1e1..2393b39 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -123,5 +123,6 @@
 ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
-# Do not enable SVE
-ENABLE_SVE_FOR_NS	:= 0
+# Later QEMU versions support SME and SVE.
+ENABLE_SVE_FOR_NS	:= 1
+ENABLE_SME_FOR_NS	:= 1
diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c
index aec53ee..68054ad 100644
--- a/plat/rockchip/common/params_setup.c
+++ b/plat/rockchip/common/params_setup.c
@@ -38,7 +38,7 @@
 static uint32_t rk_uart_baudrate = PLAT_RK_UART_BAUDRATE;
 static uint32_t rk_uart_clock = PLAT_RK_UART_CLOCK;
 #define FDT_BUFFER_SIZE 0x20000
-static uint8_t fdt_buffer[FDT_BUFFER_SIZE];
+static uint64_t fdt_buffer[FDT_BUFFER_SIZE / 8];
 
 void *plat_get_fdt(void)
 {
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 7222584..1bbaff6 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -14,6 +14,7 @@
 #include <drivers/fwu/fwu_metadata.h>
 #include <drivers/io/io_block.h>
 #include <drivers/io/io_driver.h>
+#include <drivers/io/io_encrypted.h>
 #include <drivers/io/io_fip.h>
 #include <drivers/io/io_memmap.h>
 #include <drivers/io/io_mtd.h>
@@ -48,6 +49,11 @@
 
 static const io_dev_connector_t *fip_dev_con;
 
+#ifndef DECRYPTION_SUPPORT_none
+static const io_dev_connector_t *enc_dev_con;
+uintptr_t enc_dev_handle;
+#endif
+
 #if STM32MP_SDMMC || STM32MP_EMMC
 static struct mmc_device_info mmc_info;
 
@@ -117,6 +123,29 @@
 {
 	return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
 }
+
+#ifndef DECRYPTION_SUPPORT_none
+int open_enc_fip(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_image_handle;
+
+	result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID);
+	if (result != 0) {
+		return result;
+	}
+
+	result = io_open(enc_dev_handle, spec, &local_image_handle);
+	if (result != 0) {
+		return result;
+	}
+
+	VERBOSE("Using encrypted FIP\n");
+	io_close(local_image_handle);
+
+	return 0;
+}
+#endif
 
 int open_storage(const uintptr_t spec)
 {
@@ -383,6 +412,15 @@
 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
 				&fip_dev_handle);
 
+#ifndef DECRYPTION_SUPPORT_none
+	io_result = register_io_dev_enc(&enc_dev_con);
+	assert(io_result == 0);
+
+	io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL,
+				&enc_dev_handle);
+	assert(io_result == 0);
+#endif
+
 	switch (boot_context->boot_interface_selected) {
 #if STM32MP_SDMMC
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
@@ -569,7 +607,7 @@
  *     - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode.
  * we select the previous_active_index.
  */
-#define INVALID_BOOT_IDX		0xFFFFFFFF
+#define INVALID_BOOT_IDX		0xFFFFFFFFU
 
 uint32_t plat_fwu_get_boot_idx(void)
 {
diff --git a/plat/st/common/bl2_stm32_io_storage.c b/plat/st/common/bl2_stm32_io_storage.c
deleted file mode 100644
index 4391195..0000000
--- a/plat/st/common/bl2_stm32_io_storage.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <drivers/io/io_block.h>
-#include <drivers/io/io_driver.h>
-#include <drivers/io/io_dummy.h>
-#include <drivers/io/io_mtd.h>
-#include <drivers/io/io_storage.h>
-#include <drivers/mmc.h>
-#include <drivers/partition/partition.h>
-#include <drivers/raw_nand.h>
-#include <drivers/spi_nand.h>
-#include <drivers/spi_nor.h>
-#include <drivers/st/io_mmc.h>
-#include <drivers/st/io_stm32image.h>
-#include <drivers/st/stm32_fmc2_nand.h>
-#include <drivers/st/stm32_qspi.h>
-#include <drivers/st/stm32_sdmmc2.h>
-#include <lib/mmio.h>
-#include <lib/utils.h>
-#include <plat/common/platform.h>
-
-#include <platform_def.h>
-
-/* IO devices */
-#ifndef AARCH32_SP_OPTEE
-static const io_dev_connector_t *dummy_dev_con;
-static uintptr_t dummy_dev_handle;
-static uintptr_t dummy_dev_spec;
-#endif
-
-static uintptr_t image_dev_handle;
-static uintptr_t storage_dev_handle;
-
-#if STM32MP_SDMMC || STM32MP_EMMC
-static struct mmc_device_info mmc_info;
-static io_block_spec_t gpt_block_spec = {
-	.offset = 0U,
-	.length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */
-};
-
-static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
-
-static const io_block_dev_spec_t mmc_block_dev_spec = {
-	/* It's used as temp buffer in block driver */
-	.buffer = {
-		.offset = (size_t)&block_buffer,
-		.length = MMC_BLOCK_SIZE,
-	},
-	.ops = {
-		.read = mmc_read_blocks,
-		.write = NULL,
-	},
-	.block_size = MMC_BLOCK_SIZE,
-};
-
-#if STM32MP_EMMC_BOOT
-static io_block_spec_t emmc_boot_ssbl_block_spec = {
-	.offset = PLAT_EMMC_BOOT_SSBL_OFFSET,
-	.length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */
-};
-
-static const io_block_dev_spec_t mmc_block_dev_boot_part_spec = {
-	/* It's used as temp buffer in block driver */
-	.buffer = {
-		.offset = (size_t)&block_buffer,
-		.length = MMC_BLOCK_SIZE,
-	},
-	.ops = {
-		.read = mmc_boot_part_read_blocks,
-		.write = NULL,
-	},
-	.block_size = MMC_BLOCK_SIZE,
-};
-#endif
-
-static struct io_mmc_dev_spec mmc_device_spec = {
-	.use_boot_part = false,
-};
-
-static const io_dev_connector_t *mmc_dev_con;
-#endif /* STM32MP_SDMMC || STM32MP_EMMC */
-
-#if STM32MP_SPI_NOR
-static io_mtd_dev_spec_t spi_nor_dev_spec = {
-	.ops = {
-		.init = spi_nor_init,
-		.read = spi_nor_read,
-	},
-};
-#endif
-
-#if STM32MP_RAW_NAND
-static io_mtd_dev_spec_t nand_dev_spec = {
-	.ops = {
-		.init = nand_raw_init,
-		.read = nand_read,
-	},
-};
-
-static const io_dev_connector_t *nand_dev_con;
-#endif
-
-#if STM32MP_SPI_NAND
-static io_mtd_dev_spec_t spi_nand_dev_spec = {
-	.ops = {
-		.init = spi_nand_init,
-		.read = nand_read,
-	},
-};
-#endif
-
-#if STM32MP_SPI_NAND || STM32MP_SPI_NOR
-static const io_dev_connector_t *spi_dev_con;
-#endif
-
-#ifdef AARCH32_SP_OPTEE
-static const struct stm32image_part_info optee_header_partition_spec = {
-	.name = OPTEE_HEADER_IMAGE_NAME,
-	.binary_type = OPTEE_HEADER_BINARY_TYPE,
-};
-
-static const struct stm32image_part_info optee_core_partition_spec = {
-	.name = OPTEE_CORE_IMAGE_NAME,
-	.binary_type = OPTEE_CORE_BINARY_TYPE,
-};
-
-static const struct stm32image_part_info optee_paged_partition_spec = {
-	.name = OPTEE_PAGED_IMAGE_NAME,
-	.binary_type = OPTEE_PAGED_BINARY_TYPE,
-};
-#else
-static const io_block_spec_t bl32_block_spec = {
-	.offset = BL32_BASE,
-	.length = STM32MP_BL32_SIZE
-};
-#endif
-
-static const struct stm32image_part_info bl33_partition_spec = {
-	.name = BL33_IMAGE_NAME,
-	.binary_type = BL33_BINARY_TYPE,
-};
-
-enum {
-	IMG_IDX_BL33,
-#ifdef AARCH32_SP_OPTEE
-	IMG_IDX_OPTEE_HEADER,
-	IMG_IDX_OPTEE_CORE,
-	IMG_IDX_OPTEE_PAGED,
-#endif
-	IMG_IDX_NUM
-};
-
-static struct stm32image_device_info stm32image_dev_info_spec __unused = {
-	.lba_size = MMC_BLOCK_SIZE,
-	.part_info[IMG_IDX_BL33] = {
-		.name = BL33_IMAGE_NAME,
-		.binary_type = BL33_BINARY_TYPE,
-	},
-#ifdef AARCH32_SP_OPTEE
-	.part_info[IMG_IDX_OPTEE_HEADER] = {
-		.name = OPTEE_HEADER_IMAGE_NAME,
-		.binary_type = OPTEE_HEADER_BINARY_TYPE,
-	},
-	.part_info[IMG_IDX_OPTEE_CORE] = {
-		.name = OPTEE_CORE_IMAGE_NAME,
-		.binary_type = OPTEE_CORE_BINARY_TYPE,
-	},
-	.part_info[IMG_IDX_OPTEE_PAGED] = {
-		.name = OPTEE_PAGED_IMAGE_NAME,
-		.binary_type = OPTEE_PAGED_BINARY_TYPE,
-	},
-#endif
-};
-
-static io_block_spec_t stm32image_block_spec = {
-	.offset = 0U,
-	.length = 0U,
-};
-
-static const io_dev_connector_t *stm32image_dev_con __unused;
-
-#ifndef AARCH32_SP_OPTEE
-static int open_dummy(const uintptr_t spec);
-#endif
-static int open_image(const uintptr_t spec);
-static int open_storage(const uintptr_t spec);
-
-struct plat_io_policy {
-	uintptr_t *dev_handle;
-	uintptr_t image_spec;
-	int (*check)(const uintptr_t spec);
-};
-
-static const struct plat_io_policy policies[] = {
-#ifdef AARCH32_SP_OPTEE
-	[BL32_IMAGE_ID] = {
-		.dev_handle = &image_dev_handle,
-		.image_spec = (uintptr_t)&optee_header_partition_spec,
-		.check = open_image
-	},
-	[BL32_EXTRA1_IMAGE_ID] = {
-		.dev_handle = &image_dev_handle,
-		.image_spec = (uintptr_t)&optee_core_partition_spec,
-		.check = open_image
-	},
-	[BL32_EXTRA2_IMAGE_ID] = {
-		.dev_handle = &image_dev_handle,
-		.image_spec = (uintptr_t)&optee_paged_partition_spec,
-		.check = open_image
-	},
-#else
-	[BL32_IMAGE_ID] = {
-		.dev_handle = &dummy_dev_handle,
-		.image_spec = (uintptr_t)&bl32_block_spec,
-		.check = open_dummy
-	},
-#endif
-	[BL33_IMAGE_ID] = {
-		.dev_handle = &image_dev_handle,
-		.image_spec = (uintptr_t)&bl33_partition_spec,
-		.check = open_image
-	},
-#if STM32MP_SDMMC || STM32MP_EMMC
-	[GPT_IMAGE_ID] = {
-		.dev_handle = &storage_dev_handle,
-		.image_spec = (uintptr_t)&gpt_block_spec,
-		.check = open_storage
-	},
-#endif
-	[STM32_IMAGE_ID] = {
-		.dev_handle = &storage_dev_handle,
-		.image_spec = (uintptr_t)&stm32image_block_spec,
-		.check = open_storage
-	}
-};
-
-#ifndef AARCH32_SP_OPTEE
-static int open_dummy(const uintptr_t spec)
-{
-	return io_dev_init(dummy_dev_handle, 0);
-}
-#endif
-
-static int open_image(const uintptr_t spec)
-{
-	return io_dev_init(image_dev_handle, 0);
-}
-
-static int open_storage(const uintptr_t spec)
-{
-	return io_dev_init(storage_dev_handle, 0);
-}
-
-#if STM32MP_EMMC_BOOT
-static uint32_t get_boot_part_ssbl_header(void)
-{
-	uint32_t magic = 0U;
-	int io_result;
-	size_t bytes_read;
-
-	io_result = register_io_dev_block(&mmc_dev_con);
-	if (io_result != 0) {
-		panic();
-	}
-
-	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_boot_part_spec,
-				&storage_dev_handle);
-	assert(io_result == 0);
-
-	io_result = io_open(storage_dev_handle, (uintptr_t)&emmc_boot_ssbl_block_spec,
-			    &image_dev_handle);
-	assert(io_result == 0);
-
-	io_result = io_read(image_dev_handle, (uintptr_t)&magic, sizeof(magic),
-			    &bytes_read);
-	assert(io_result == 0);
-	assert(bytes_read == sizeof(magic));
-
-	io_result = io_dev_close(storage_dev_handle);
-	assert(io_result == 0);
-
-	return magic;
-}
-#endif
-
-static void print_boot_device(boot_api_context_t *boot_context)
-{
-	switch (boot_context->boot_interface_selected) {
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
-		INFO("Using SDMMC\n");
-		break;
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
-		INFO("Using EMMC\n");
-		break;
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
-		INFO("Using QSPI NOR\n");
-		break;
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
-		INFO("Using FMC NAND\n");
-		break;
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
-		INFO("Using SPI NAND\n");
-		break;
-	default:
-		ERROR("Boot interface not found\n");
-		panic();
-		break;
-	}
-
-	if (boot_context->boot_interface_instance != 0U) {
-		INFO("  Instance %d\n", boot_context->boot_interface_instance);
-	}
-}
-
-static void stm32image_io_setup(void)
-{
-	int io_result __unused;
-
-	io_result = register_io_dev_stm32image(&stm32image_dev_con);
-	assert(io_result == 0);
-
-	io_result = io_dev_open(stm32image_dev_con,
-				(uintptr_t)&stm32image_dev_info_spec,
-				&image_dev_handle);
-	assert(io_result == 0);
-}
-
-#if STM32MP_SDMMC || STM32MP_EMMC
-static void boot_mmc(enum mmc_device_type mmc_dev_type,
-		     uint16_t boot_interface_instance)
-{
-	int io_result __unused;
-	uint8_t idx;
-	struct stm32image_part_info *part;
-	struct stm32_sdmmc2_params params;
-	const partition_entry_t *entry __unused;
-	uint32_t magic __unused;
-
-	zeromem(&params, sizeof(struct stm32_sdmmc2_params));
-
-	mmc_info.mmc_dev_type = mmc_dev_type;
-
-	switch (boot_interface_instance) {
-	case 1:
-		params.reg_base = STM32MP_SDMMC1_BASE;
-		break;
-	case 2:
-		params.reg_base = STM32MP_SDMMC2_BASE;
-		break;
-	case 3:
-		params.reg_base = STM32MP_SDMMC3_BASE;
-		break;
-	default:
-		WARN("SDMMC instance not found, using default\n");
-		if (mmc_dev_type == MMC_IS_SD) {
-			params.reg_base = STM32MP_SDMMC1_BASE;
-		} else {
-			params.reg_base = STM32MP_SDMMC2_BASE;
-		}
-		break;
-	}
-
-	params.device_info = &mmc_info;
-	if (stm32_sdmmc2_mmc_init(&params) != 0) {
-		ERROR("SDMMC%u init failed\n", boot_interface_instance);
-		panic();
-	}
-
-	stm32image_dev_info_spec.device_size =
-		stm32_sdmmc2_mmc_get_device_size();
-
-#if STM32MP_EMMC_BOOT
-	if (mmc_dev_type == MMC_IS_EMMC) {
-		magic = get_boot_part_ssbl_header();
-
-		if (magic == BOOT_API_IMAGE_HEADER_MAGIC_NB) {
-			VERBOSE("%s, header found, jump to emmc load\n", __func__);
-			idx = IMG_IDX_BL33;
-			part = &stm32image_dev_info_spec.part_info[idx];
-			part->part_offset = PLAT_EMMC_BOOT_SSBL_OFFSET;
-			part->bkp_offset = 0U;
-			mmc_device_spec.use_boot_part = true;
-
-			goto emmc_boot;
-		} else {
-			WARN("%s: Can't find STM32 header on a boot partition\n", __func__);
-		}
-	}
-#endif
-
-	/* Open MMC as a block device to read GPT table */
-	io_result = register_io_dev_block(&mmc_dev_con);
-	if (io_result != 0) {
-		panic();
-	}
-
-	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec,
-				&storage_dev_handle);
-	assert(io_result == 0);
-
-	partition_init(GPT_IMAGE_ID);
-
-	io_result = io_dev_close(storage_dev_handle);
-	assert(io_result == 0);
-
-	for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
-		part = &stm32image_dev_info_spec.part_info[idx];
-		entry = get_partition_entry(part->name);
-		if (entry == NULL) {
-			ERROR("Partition %s not found\n", part->name);
-			panic();
-		}
-
-		part->part_offset = entry->start;
-		part->bkp_offset = 0U;
-	}
-
-#if STM32MP_EMMC_BOOT
-emmc_boot:
-#endif
-	/*
-	 * Re-open MMC with io_mmc, for better perfs compared to
-	 * io_block.
-	 */
-	io_result = register_io_dev_mmc(&mmc_dev_con);
-	assert(io_result == 0);
-
-	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_device_spec,
-				&storage_dev_handle);
-	assert(io_result == 0);
-}
-#endif /* STM32MP_SDMMC || STM32MP_EMMC */
-
-#if STM32MP_SPI_NOR
-static void boot_spi_nor(boot_api_context_t *boot_context)
-{
-	int io_result __unused;
-	uint8_t idx;
-	struct stm32image_part_info *part;
-
-	io_result = stm32_qspi_init();
-	assert(io_result == 0);
-
-	io_result = register_io_dev_mtd(&spi_dev_con);
-	assert(io_result == 0);
-
-	/* Open connections to device */
-	io_result = io_dev_open(spi_dev_con,
-				(uintptr_t)&spi_nor_dev_spec,
-				&storage_dev_handle);
-	assert(io_result == 0);
-
-	stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size;
-
-	idx = IMG_IDX_BL33;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NOR_BL33_OFFSET;
-	part->bkp_offset = 0U;
-
-#ifdef AARCH32_SP_OPTEE
-	idx = IMG_IDX_OPTEE_HEADER;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NOR_TEEH_OFFSET;
-	part->bkp_offset = 0U;
-
-	idx = IMG_IDX_OPTEE_PAGED;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NOR_TEED_OFFSET;
-	part->bkp_offset = 0U;
-
-	idx = IMG_IDX_OPTEE_CORE;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NOR_TEEX_OFFSET;
-	part->bkp_offset = 0U;
-#endif
-}
-#endif /* STM32MP_SPI_NOR */
-
-#if STM32MP_RAW_NAND
-static void boot_fmc2_nand(boot_api_context_t *boot_context)
-{
-	int io_result __unused;
-	uint8_t idx;
-	struct stm32image_part_info *part;
-
-	io_result = stm32_fmc2_init();
-	assert(io_result == 0);
-
-	/* Register the IO device on this platform */
-	io_result = register_io_dev_mtd(&nand_dev_con);
-	assert(io_result == 0);
-
-	/* Open connections to device */
-	io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
-				&storage_dev_handle);
-	assert(io_result == 0);
-
-	stm32image_dev_info_spec.device_size = nand_dev_spec.device_size;
-
-	idx = IMG_IDX_BL33;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NAND_BL33_OFFSET;
-	part->bkp_offset = nand_dev_spec.erase_size;
-
-#ifdef AARCH32_SP_OPTEE
-	idx = IMG_IDX_OPTEE_HEADER;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NAND_TEEH_OFFSET;
-	part->bkp_offset = nand_dev_spec.erase_size;
-
-	idx = IMG_IDX_OPTEE_PAGED;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NAND_TEED_OFFSET;
-	part->bkp_offset = nand_dev_spec.erase_size;
-
-	idx = IMG_IDX_OPTEE_CORE;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NAND_TEEX_OFFSET;
-	part->bkp_offset = nand_dev_spec.erase_size;
-#endif
-}
-#endif /* STM32MP_RAW_NAND */
-
-#if STM32MP_SPI_NAND
-static void boot_spi_nand(boot_api_context_t *boot_context)
-{
-	int io_result __unused;
-	uint8_t idx;
-	struct stm32image_part_info *part;
-
-	io_result = stm32_qspi_init();
-	assert(io_result == 0);
-
-	io_result = register_io_dev_mtd(&spi_dev_con);
-	assert(io_result == 0);
-
-	/* Open connections to device */
-	io_result = io_dev_open(spi_dev_con,
-				(uintptr_t)&spi_nand_dev_spec,
-				&storage_dev_handle);
-	assert(io_result == 0);
-
-	stm32image_dev_info_spec.device_size =
-		spi_nand_dev_spec.device_size;
-
-	idx = IMG_IDX_BL33;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NAND_BL33_OFFSET;
-	part->bkp_offset = spi_nand_dev_spec.erase_size;
-
-#ifdef AARCH32_SP_OPTEE
-	idx = IMG_IDX_OPTEE_HEADER;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NAND_TEEH_OFFSET;
-	part->bkp_offset = spi_nand_dev_spec.erase_size;
-
-	idx = IMG_IDX_OPTEE_PAGED;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NAND_TEED_OFFSET;
-	part->bkp_offset = spi_nand_dev_spec.erase_size;
-
-	idx = IMG_IDX_OPTEE_CORE;
-	part = &stm32image_dev_info_spec.part_info[idx];
-	part->part_offset = STM32MP_NAND_TEEX_OFFSET;
-	part->bkp_offset = spi_nand_dev_spec.erase_size;
-#endif
-}
-#endif /* STM32MP_SPI_NAND */
-
-void stm32mp_io_setup(void)
-{
-	int io_result __unused;
-	boot_api_context_t *boot_context =
-		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
-
-	print_boot_device(boot_context);
-
-	if ((boot_context->boot_partition_used_toboot == 1U) ||
-	    (boot_context->boot_partition_used_toboot == 2U)) {
-		INFO("Boot used partition fsbl%u\n",
-		     boot_context->boot_partition_used_toboot);
-	}
-
-#ifndef AARCH32_SP_OPTEE
-	io_result = register_io_dev_dummy(&dummy_dev_con);
-	assert(io_result == 0);
-
-	io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
-				&dummy_dev_handle);
-	assert(io_result == 0);
-#endif
-
-	switch (boot_context->boot_interface_selected) {
-#if STM32MP_SDMMC
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
-		dmbsy();
-		boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
-		stm32image_io_setup();
-		break;
-#endif
-#if STM32MP_EMMC
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
-		dmbsy();
-		boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
-		stm32image_io_setup();
-		break;
-#endif
-#if STM32MP_SPI_NOR
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
-		dmbsy();
-		boot_spi_nor(boot_context);
-		stm32image_io_setup();
-		break;
-#endif
-#if STM32MP_RAW_NAND
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
-		dmbsy();
-		boot_fmc2_nand(boot_context);
-		stm32image_io_setup();
-		break;
-#endif
-#if STM32MP_SPI_NAND
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
-		dmbsy();
-		boot_spi_nand(boot_context);
-		stm32image_io_setup();
-		break;
-#endif
-
-	default:
-		ERROR("Boot interface %d not supported\n",
-		      boot_context->boot_interface_selected);
-		panic();
-		break;
-	}
-}
-
-/*
- * Return an IO device handle and specification which can be used to access
- * an image. Use this to enforce platform load policy.
- */
-int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
-			  uintptr_t *image_spec)
-{
-	int rc;
-	const struct plat_io_policy *policy;
-
-	assert(image_id < ARRAY_SIZE(policies));
-
-	policy = &policies[image_id];
-	rc = policy->check(policy->image_spec);
-	if (rc == 0) {
-		*image_spec = policy->image_spec;
-		*dev_handle = *(policy->dev_handle);
-	}
-
-	return rc;
-}
diff --git a/plat/st/common/include/stm32mp_auth.h b/plat/st/common/include/stm32mp_auth.h
deleted file mode 100644
index 3075d18..0000000
--- a/plat/st/common/include/stm32mp_auth.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STM32MP_AUTH_H
-#define STM32MP_AUTH_H
-
-struct stm32mp_auth_ops {
-	uint32_t (*check_key)(uint8_t *pubkey_in, uint8_t *pubkey_out);
-	uint32_t (*verify_signature)(uint8_t *hash_in, uint8_t *pubkey_in,
-				     uint8_t *signature, uint32_t ecc_algo);
-};
-
-void stm32mp_init_auth(struct stm32mp_auth_ops *init_ptr);
-int stm32mp_auth_image(boot_api_image_header_t *header, uintptr_t buffer);
-
-#endif /* STM32MP_AUTH_H */
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index 79f81db..a5316b6 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -109,16 +109,6 @@
 /* Initialise the IO layer and register platform IO devices */
 void stm32mp_io_setup(void);
 
-#if STM32MP_USE_STM32IMAGE
-/*
- * Check that the STM32 header of a .stm32 binary image is valid
- * @param header: pointer to the stm32 image header
- * @param buffer: address of the binary image (payload)
- * @return: 0 on success, negative value in case of error
- */
-int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer);
-#endif /* STM32MP_USE_STM32IMAGE */
-
 /* Functions to map DDR in MMU with non-cacheable attribute, and unmap it */
 int stm32mp_map_ddr_non_cacheable(void);
 int stm32mp_unmap_ddr(void);
@@ -130,10 +120,10 @@
 /* Functions to save and get boot authentication status and partition used */
 void stm32_save_boot_auth(uint32_t auth_status, uint32_t boot_partition);
 
-#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
 void stm32mp1_fwu_set_boot_idx(void);
 uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void);
 void stm32_set_max_fwu_trial_boot_cnt(void);
-#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
 
 #endif /* STM32MP_COMMON_H */
diff --git a/plat/st/common/include/stm32mp_efi.h b/plat/st/common/include/stm32mp_efi.h
index 490560f..af9165f 100644
--- a/plat/st/common/include/stm32mp_efi.h
+++ b/plat/st/common/include/stm32mp_efi.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause */
 /*
  * Copyright (c) 2021, Linaro Limited
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
  */
 
 #ifndef STM32MP_EFI_H
@@ -9,7 +10,7 @@
 #include <drivers/partition/efi.h>
 
 #define STM32MP_FIP_GUID \
-	EFI_GUID(0x19d5df83, 0x11b0, 0x457b, \
-		 0xbe, 0x2c, 0x75, 0x59, 0xc1, 0x31, 0x42, 0xa5)
+	EFI_GUID(0x19d5df83U, 0x11b0U, 0x457bU, \
+		 0xbeU, 0x2cU, 0x75U, 0x59U, 0xc1U, 0x31U, 0x42U, 0xa5U)
 
 #endif /* STM32MP_EFI_H */
diff --git a/plat/st/common/include/stm32mp_io_storage.h b/plat/st/common/include/stm32mp_io_storage.h
index 989c890..3c04c47 100644
--- a/plat/st/common/include/stm32mp_io_storage.h
+++ b/plat/st/common/include/stm32mp_io_storage.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,11 +13,15 @@
 /* IO devices handle */
 extern uintptr_t storage_dev_handle;
 extern uintptr_t fip_dev_handle;
+extern uintptr_t enc_dev_handle;
 
 extern io_block_spec_t image_block_spec;
 
 /* Function declarations */
 int open_fip(const uintptr_t spec);
+#ifndef DECRYPTION_SUPPORT_none
+int open_enc_fip(const uintptr_t spec);
+#endif
 int open_storage(const uintptr_t spec);
 
 #endif /* STM32MP_IO_STORAGE_H */
diff --git a/plat/st/common/stm32mp_auth.c b/plat/st/common/stm32mp_auth.c
deleted file mode 100644
index 97fbffa..0000000
--- a/plat/st/common/stm32mp_auth.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <errno.h>
-
-#include <common/debug.h>
-#include <drivers/io/io_storage.h>
-#include <drivers/st/bsec.h>
-#include <drivers/st/stm32_hash.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <plat/common/platform.h>
-
-#include <platform_def.h>
-
-static const struct stm32mp_auth_ops *auth_ops;
-
-void stm32mp_init_auth(struct stm32mp_auth_ops *init_ptr)
-{
-	if ((init_ptr == NULL) ||
-	    (init_ptr->check_key == NULL) ||
-	    (init_ptr->verify_signature == NULL) ||
-	    (stm32_hash_register() != 0)) {
-		panic();
-	}
-
-	auth_ops = init_ptr;
-}
-
-int stm32mp_auth_image(boot_api_image_header_t *header, uintptr_t buffer)
-{
-	int ret;
-	uint8_t image_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES];
-	uint32_t header_skip_cksum = sizeof(header->magic) +
-				     sizeof(header->image_signature) +
-				     sizeof(header->payload_checksum);
-
-	/* Check Security Status */
-	if (!stm32mp_is_closed_device()) {
-		if (header->option_flags != 0U) {
-			WARN("Skip signature check (header option)\n");
-			return 0;
-		}
-		INFO("Check signature on Open device\n");
-	}
-
-	if (auth_ops == NULL) {
-		ERROR("Device doesn't support image authentication\n");
-		return -EOPNOTSUPP;
-	}
-
-	ret = mmap_add_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_BASE,
-				      STM32MP_ROM_SIZE_2MB_ALIGNED, MT_CODE | MT_SECURE);
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* Check Public Key */
-	if (auth_ops->check_key(header->ecc_pubk, NULL) != BOOT_API_RETURN_OK) {
-		ret = -EINVAL;
-		goto err;
-	}
-
-	/* Compute end of header hash and payload hash */
-	stm32_hash_init(HASH_SHA256);
-
-	ret = stm32_hash_update((uint8_t *)&header->header_version,
-				sizeof(boot_api_image_header_t) -
-				header_skip_cksum);
-	if (ret != 0) {
-		ERROR("Hash of header failed, %i\n", ret);
-		goto err;
-	}
-
-	ret = stm32_hash_final_update((uint8_t *)buffer,
-			       header->image_length, image_hash);
-	if (ret != 0) {
-		ERROR("Hash of payload failed\n");
-		goto err;
-	}
-
-	/* Verify signature */
-	if (auth_ops->verify_signature(image_hash, header->ecc_pubk,
-				       header->image_signature,
-				       header->ecc_algo_type) !=
-	    BOOT_API_RETURN_OK) {
-		ret = -EINVAL;
-	}
-
-err:
-	mmap_remove_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_SIZE_2MB_ALIGNED);
-	return ret;
-}
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index eee983f..bb56bac 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -85,43 +85,6 @@
 	return (read_sctlr() & c_m_bits) == c_m_bits;
 }
 
-#if STM32MP_USE_STM32IMAGE
-int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer)
-{
-	uint32_t i;
-	uint32_t img_checksum = 0U;
-
-	/*
-	 * Check header/payload validity:
-	 *	- Header magic
-	 *	- Header version
-	 *	- Payload checksum
-	 */
-	if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) {
-		ERROR("Header magic\n");
-		return -EINVAL;
-	}
-
-	if ((header->header_version & HEADER_VERSION_MAJOR_MASK) !=
-	    (BOOT_API_HEADER_VERSION & HEADER_VERSION_MAJOR_MASK)) {
-		ERROR("Header version\n");
-		return -EINVAL;
-	}
-
-	for (i = 0U; i < header->image_length; i++) {
-		img_checksum += *(uint8_t *)(buffer + i);
-	}
-
-	if (header->payload_checksum != img_checksum) {
-		ERROR("Checksum: 0x%x (awaited: 0x%x)\n", img_checksum,
-		      header->payload_checksum);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-#endif /* STM32MP_USE_STM32IMAGE */
-
 int stm32mp_map_ddr_non_cacheable(void)
 {
 	return  mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE,
diff --git a/plat/st/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c
new file mode 100644
index 0000000..0da0019
--- /dev/null
+++ b/plat/st/common/stm32mp_crypto_lib.c
@@ -0,0 +1,662 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <endian.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/io/io_storage.h>
+#include <drivers/st/bsec.h>
+#include <drivers/st/stm32_hash.h>
+#include <drivers/st/stm32_pka.h>
+#include <drivers/st/stm32_rng.h>
+#include <drivers/st/stm32_saes.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <mbedtls/asn1.h>
+#include <mbedtls/md.h>
+#include <mbedtls/oid.h>
+#include <mbedtls/platform.h>
+#include <mbedtls/x509.h>
+#include <plat/common/platform.h>
+#include <tools_share/firmware_encrypted.h>
+
+#include <platform_def.h>
+
+#define CRYPTO_HASH_MAX_SIZE	32U
+#define CRYPTO_SIGN_MAX_SIZE	64U
+#define CRYPTO_PUBKEY_MAX_SIZE	64U
+#define CRYPTO_MAX_TAG_SIZE	16U
+
+/* brainpoolP256t1 OID is not defined in mbedTLS */
+#define OID_EC_GRP_BP256T1          MBEDTLS_OID_EC_BRAINPOOL_V1 "\x08"
+
+#if STM32MP_CRYPTO_ROM_LIB
+struct stm32mp_auth_ops {
+	uint32_t (*verify_signature)(uint8_t *hash_in, uint8_t *pubkey_in,
+				     uint8_t *signature, uint32_t ecc_algo);
+};
+
+static struct stm32mp_auth_ops auth_ops;
+#endif
+
+static void crypto_lib_init(void)
+{
+	boot_api_context_t *boot_context __maybe_unused;
+	int ret;
+
+	NOTICE("TRUSTED_BOARD_BOOT support enabled\n");
+
+	ret = stm32_hash_register();
+	if (ret != 0) {
+		ERROR("HASH init (%d)\n", ret);
+		panic();
+	}
+
+	if (stm32mp_is_closed_device() || stm32mp_is_auth_supported()) {
+#if STM32MP_CRYPTO_ROM_LIB
+		boot_context = (boot_api_context_t *)stm32mp_get_boot_ctx_address();
+		auth_ops.verify_signature = boot_context->bootrom_ecdsa_verify_signature;
+#else
+		/* Use hardware peripherals */
+		if (stm32_rng_init() != 0) {
+			panic();
+		}
+
+		if (stm32_saes_driver_init() != 0) {
+			panic();
+		}
+
+		if (stm32_pka_init() != 0) {
+			panic();
+		}
+#endif
+	}
+}
+
+static int get_plain_pk_from_asn1(void *pk_ptr, unsigned int pk_len, void **plain_pk,
+			   unsigned int *len, int *pk_alg)
+{
+	int ret;
+	mbedtls_pk_context mbedtls_pk = {0};
+	unsigned char *p, *end;
+	mbedtls_asn1_buf alg_params = {0};
+	mbedtls_asn1_buf alg_oid = {0};
+
+	*plain_pk = NULL;
+	*len = 0U;
+
+	/* Parse the public key */
+	mbedtls_pk_init(&mbedtls_pk);
+	p = (unsigned char *)pk_ptr;
+	end = (unsigned char *)(p + pk_len);
+
+	ret =  mbedtls_asn1_get_tag(&p, end, len,
+				    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+	if (ret != 0) {
+		return -EINVAL;
+	}
+
+	end = p + *len;
+	ret = mbedtls_asn1_get_alg(&p, end, &alg_oid, &alg_params);
+	if (ret != 0) {
+		VERBOSE("%s: mbedtls_asn1_get_alg (%d)\n", __func__, ret);
+		return -EINVAL;
+	}
+
+	if (pk_alg != NULL) {
+		if ((strlen(MBEDTLS_OID_EC_GRP_SECP256R1) == alg_params.len) &&
+		    (memcmp(MBEDTLS_OID_EC_GRP_SECP256R1, alg_params.p, alg_params.len) == 0)) {
+			*pk_alg = BOOT_API_ECDSA_ALGO_TYPE_P256NIST;
+		} else if ((strlen(OID_EC_GRP_BP256T1) == alg_params.len) &&
+		    (memcmp(OID_EC_GRP_BP256T1, alg_params.p, alg_params.len) == 0)) {
+			*pk_alg = BOOT_API_ECDSA_ALGO_TYPE_BRAINPOOL256;
+		} else {
+			ERROR("%s: Algorithm is not supported\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	ret = mbedtls_asn1_get_bitstring_null(&p, end, len);
+	if (ret != 0) {
+		VERBOSE("%s: mbedtls_asn1_get_bitstring_null (%d)\n", __func__, ret);
+		return -EINVAL;
+	}
+
+	/* We remove the ident (0x04) first byte. */
+	if ((*len < 1U) || (p[0] !=  MBEDTLS_ASN1_OCTET_STRING)) {
+		VERBOSE("%s: not expected len or tag\n", __func__);
+		return -EINVAL;
+	}
+
+	*len = *len - 1U;
+	*plain_pk = p + 1U;
+
+	return 0;
+}
+
+#if STM32MP_CRYPTO_ROM_LIB
+uint32_t verify_signature(uint8_t *hash_in, uint8_t *pubkey_in,
+			  uint8_t *signature, uint32_t ecc_algo)
+{
+	int ret;
+
+	ret = mmap_add_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_BASE,
+				      STM32MP_ROM_SIZE_2MB_ALIGNED, MT_CODE | MT_SECURE);
+	if (ret != 0) {
+		VERBOSE("%s: mmap_add_dynamic_region (%d)\n", __func__, ret);
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	ret = auth_ops.verify_signature(hash_in, pubkey_in, signature, ecc_algo);
+
+	if (ret != BOOT_API_RETURN_OK) {
+		VERBOSE("%s: auth_ops.verify_sign (%d)\n", __func__, ret);
+		ret = CRYPTO_ERR_SIGNATURE;
+	} else {
+		ret = 0;
+	}
+
+	mmap_remove_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_SIZE_2MB_ALIGNED);
+
+	return ret;
+}
+
+int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+		    void **hashed_pk_ptr, unsigned int *hashed_pk_len)
+{
+	return get_plain_pk_from_asn1(full_pk_ptr, full_pk_len, hashed_pk_ptr, hashed_pk_len, NULL);
+}
+#else /* STM32MP_CRYPTO_ROM_LIB*/
+static uint32_t verify_signature(uint8_t *hash_in, uint8_t *pubkey_in,
+				 uint8_t *signature, uint32_t ecc_algo)
+{
+	int ret = -1;
+	enum stm32_pka_ecdsa_curve_id cid;
+
+	switch (ecc_algo) {
+	case BOOT_API_ECDSA_ALGO_TYPE_P256NIST:
+#if PKA_USE_NIST_P256
+		cid = PKA_NIST_P256;
+		ret = 0;
+#else
+		WARN("%s nist_p256 requested but not included\n", __func__);
+#endif
+		break;
+	case BOOT_API_ECDSA_ALGO_TYPE_BRAINPOOL256:
+#if PKA_USE_BRAINPOOL_P256T1
+		cid = PKA_BRAINPOOL_P256T1;
+		ret = 0;
+#else
+		WARN("%s brainpool_p256t1 requested but not included\n", __func__);
+#endif
+		break;
+	default:
+		WARN("%s unexpected ecc_algo(%u)\n", __func__, ecc_algo);
+		break;
+	}
+
+	if (ret < 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	ret = stm32_pka_ecdsa_verif(hash_in,
+				    BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES,
+				    signature, BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES / 2U,
+				    signature + BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES / 2U,
+				    BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES / 2U,
+				    pubkey_in, BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES / 2U,
+				    pubkey_in + BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES / 2U,
+				    BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES / 2U, cid);
+	if (ret < 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	return 0;
+}
+
+int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
+		    void **hashed_pk_ptr, unsigned int *hashed_pk_len)
+{
+	static uint8_t st_pk[CRYPTO_PUBKEY_MAX_SIZE + sizeof(uint32_t)];
+	int ret;
+	void *plain_pk;
+	unsigned int len;
+	int curve_id;
+	uint32_t cid;
+
+	ret = get_plain_pk_from_asn1(full_pk_ptr, full_pk_len, &plain_pk, &len, &curve_id);
+	if ((ret != 0) || (len > CRYPTO_PUBKEY_MAX_SIZE))  {
+		return -EINVAL;
+	}
+
+	cid = curve_id; /* we want value of curve_id (1 or 2) in a uint32_t */
+
+	memcpy(st_pk, &cid, sizeof(cid));
+	memcpy(st_pk + sizeof(cid), plain_pk, len);
+
+	*hashed_pk_ptr = st_pk;
+	*hashed_pk_len = len + sizeof(cid);
+
+	return 0;
+}
+#endif /* STM32MP_CRYPTO_ROM_LIB */
+
+static int get_plain_digest_from_asn1(void *digest_ptr, unsigned int digest_len,
+				      uint8_t **out, size_t *out_len, mbedtls_md_type_t *md_alg)
+{
+	int ret;
+	mbedtls_asn1_buf hash_oid, params;
+	size_t len;
+	unsigned char *p, *end;
+
+	*out = NULL;
+	*out_len = 0U;
+
+	/* Digest info should be an MBEDTLS_ASN1_SEQUENCE */
+	p = (unsigned char *)digest_ptr;
+	end = p + digest_len;
+	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+				   MBEDTLS_ASN1_SEQUENCE);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Get the hash algorithm */
+	ret = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = mbedtls_oid_get_md_alg(&hash_oid, md_alg);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Length of hash must match the algorithm's size */
+	if (len != BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES) {
+		return -1;
+	}
+
+	*out = p;
+	*out_len = len;
+
+	return 0;
+}
+
+static int crypto_verify_signature(void *data_ptr, unsigned int data_len,
+				   void *sig_ptr, unsigned int sig_len,
+				   void *sig_alg, unsigned int sig_alg_len,
+				   void *pk_ptr, unsigned int pk_len)
+{
+	uint8_t image_hash[CRYPTO_HASH_MAX_SIZE] = {0};
+	uint8_t sig[CRYPTO_SIGN_MAX_SIZE];
+	uint8_t my_pk[CRYPTO_PUBKEY_MAX_SIZE];
+	int ret;
+	size_t len;
+	mbedtls_asn1_sequence seq;
+	mbedtls_asn1_sequence *cur;
+	unsigned char *p, *end;
+	int curve_id;
+	mbedtls_asn1_buf sig_oid, sig_params;
+	mbedtls_md_type_t md_alg;
+	mbedtls_pk_type_t pk_alg;
+	size_t bignum_len = sizeof(sig) / 2U;
+	unsigned int seq_num = 0U;
+
+	if (!stm32mp_is_closed_device() && !stm32mp_is_auth_supported()) {
+		return CRYPTO_SUCCESS;
+	}
+
+	/* Get pointers to signature OID and parameters */
+	p = (unsigned char *)sig_alg;
+	end = (unsigned char *)(p + sig_alg_len);
+	ret = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params);
+	if (ret != 0) {
+		VERBOSE("%s: mbedtls_asn1_get_alg (%d)\n", __func__, ret);
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	/* Get the actual signature algorithm (MD + PK) */
+	ret = mbedtls_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg);
+	if (ret != 0) {
+		VERBOSE("%s: mbedtls_oid_get_sig_alg (%d)\n", __func__, ret);
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	if ((md_alg != MBEDTLS_MD_SHA256) || (pk_alg != MBEDTLS_PK_ECDSA)) {
+		VERBOSE("%s: md_alg=%u pk_alg=%u\n", __func__, md_alg, pk_alg);
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	ret = get_plain_pk_from_asn1(pk_ptr, pk_len, &pk_ptr, &pk_len, &curve_id);
+	if (ret != 0) {
+		VERBOSE("%s: get_plain_pk_from_asn1 (%d)\n", __func__, ret);
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	/* We expect a known pk_len */
+	if (pk_len != sizeof(my_pk)) {
+		VERBOSE("%s: pk_len=%u sizeof(my_pk)=%zu)\n", __func__, pk_len, sizeof(my_pk));
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	/* Need to copy as auth_ops.verify_signature
+	 * expects aligned public key.
+	 */
+	memcpy(my_pk, pk_ptr, sizeof(my_pk));
+
+	/* Get the signature (bitstring) */
+	p = (unsigned char *)sig_ptr;
+	end = (unsigned char *)(p + sig_len);
+	ret = mbedtls_asn1_get_bitstring_null(&p, end, &len);
+	if (ret != 0) {
+		VERBOSE("%s: mbedtls_asn1_get_bitstring_null (%d)\n", __func__, ret);
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	/* Get r and s from sequence */
+	ret = mbedtls_asn1_get_sequence_of(&p, end, &seq, MBEDTLS_ASN1_INTEGER);
+	if (ret != 0) {
+		VERBOSE("%s: mbedtls_asn1_get_sequence_of (%d)\n", __func__, ret);
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	/* We expect only 2 integers (r and s) from the sequence */
+	if (seq.next->next != NULL) {
+		cur = seq.next;
+		mbedtls_asn1_sequence *next;
+
+		VERBOSE("%s: nb seq != 2\n", __func__);
+		/* Free all the sequences */
+		while (cur != NULL) {
+			next = cur->next;
+			mbedtls_free(cur);
+			cur = next;
+		}
+
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	/*
+	 * ECDSA signatures are composed of a tuple (R,S) where R and S are between 0 and n.
+	 * This means that the R and S can have a maximum of 32 each, but can also be smaller.
+	 * Also seen the integer sequence may (sometime) start with 0x00 as MSB, but we can only
+	 * manage exactly 2*32 bytes, we remove this higher byte if there are not 00,
+	 * we will fail either.
+	 */
+	cur = &seq;
+	memset(sig, 0U, sizeof(sig));
+
+	while (cur != NULL) {
+		size_t skip = 0U;
+		size_t seek = seq_num * bignum_len;
+
+		if (cur->buf.len > bignum_len) {
+			/* Remove extra 0x00 bytes */
+			skip = cur->buf.len - bignum_len;
+		} else if (cur->buf.len < bignum_len) {
+			/* Add padding to match HW required size */
+			seek += (bignum_len % cur->buf.len);
+		}
+
+		if (seek + cur->buf.len > sizeof(sig) + skip) {
+			panic();
+		}
+
+		memcpy(sig + seek, cur->buf.p + skip, cur->buf.len - skip);
+		cur = cur->next;
+		seq_num++;
+	}
+
+	/* Need to free allocated 'next' in mbedtls_asn1_get_sequence_of */
+	mbedtls_free(seq.next);
+
+	/* Compute hash for the data covered by the signature */
+	stm32_hash_init(HASH_SHA256);
+
+	ret = stm32_hash_final_update((uint8_t *)data_ptr, data_len, image_hash);
+	if (ret != 0) {
+		VERBOSE("%s: stm32_hash_final_update (%d)\n", __func__, ret);
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	return verify_signature(image_hash, my_pk, sig, curve_id);
+}
+
+static int crypto_verify_hash(void *data_ptr, unsigned int data_len,
+			      void *digest_info_ptr,
+			      unsigned int digest_info_len)
+{
+	int ret;
+	uint8_t calc_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES];
+	unsigned char *p;
+	mbedtls_md_type_t md_alg;
+	size_t len;
+
+	/* we receive an asn1 encapsulated digest, we flatten it */
+	ret = get_plain_digest_from_asn1(digest_info_ptr,
+					 digest_info_len, &p, &len,
+					 &md_alg);
+	if ((ret != 0) || (md_alg != MBEDTLS_MD_SHA256) || (len != sizeof(calc_hash))) {
+		return CRYPTO_ERR_HASH;
+	}
+
+	digest_info_ptr = p;
+	digest_info_len = len;
+
+	stm32_hash_init(HASH_SHA256);
+
+	ret = stm32_hash_final_update(data_ptr, data_len, calc_hash);
+	if (ret != 0) {
+		VERBOSE("%s: hash failed\n", __func__);
+		return CRYPTO_ERR_HASH;
+	}
+
+	ret = memcmp(calc_hash, digest_info_ptr, digest_info_len);
+	if (ret != 0) {
+		VERBOSE("%s: not expected digest\n", __func__);
+		ret = CRYPTO_ERR_HASH;
+	}
+
+	return ret;
+}
+
+#if !defined(DECRYPTION_SUPPORT_none)
+static int derive_key(uint8_t *key, size_t *key_len, size_t len,
+		      unsigned int *flags, const uint8_t *img_id, size_t img_id_len)
+{
+	size_t i, j;
+
+	assert(*key_len >= 32U);
+
+	/*
+	 * Not a real derivation yet
+	 *
+	 * But we expect a 32 bytes key, and OTP is only 16 bytes
+	 *   => duplicate.
+	 */
+	for (i = 0U, j = len; j < 32U;
+	     i += sizeof(uint32_t), j += sizeof(uint32_t)) {
+		memcpy(key + j, key + i, sizeof(uint32_t));
+	}
+
+	*key_len = 32U;
+	/* Variable 'key' store a real key */
+	*flags = 0U;
+
+	return 0;
+}
+
+int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key,
+			  size_t *key_len, unsigned int *flags,
+			  const uint8_t *img_id, size_t img_id_len)
+{
+	uint32_t otp_idx;
+	uint32_t otp_len;
+	size_t read_len;
+	size_t i;
+
+	if (fw_enc_status == FW_ENC_WITH_BSSK) {
+		return -EINVAL;
+	}
+
+	if (stm32_get_otp_index(ENCKEY_OTP, &otp_idx, &otp_len) != 0) {
+		VERBOSE("%s: get %s index error\n", __func__, ENCKEY_OTP);
+		return -EINVAL;
+	}
+
+	if (otp_len > (*key_len * CHAR_BIT)) {
+		VERBOSE("%s: length Error otp_len=%u key_len=%u\n", __func__,
+			otp_len, *key_len * CHAR_BIT);
+		return -EINVAL;
+	}
+
+	read_len = otp_len / CHAR_BIT;
+	assert(read_len % sizeof(uint32_t) == 0);
+
+	for (i = 0U; i < read_len / sizeof(uint32_t); i++) {
+		uint32_t tmp;
+		uint32_t otp_val;
+
+		if (stm32_get_otp_value_from_idx(otp_idx + i, &otp_val) != 0) {
+			zeromem(key, *key_len);
+			VERBOSE("%s: unable to read from otp\n", __func__);
+			return -EINVAL;
+		}
+
+		tmp = bswap32(otp_val);
+		memcpy(key + i * sizeof(uint32_t), &tmp, sizeof(tmp));
+	}
+
+	/* Now we have the OTP values in key till read_len */
+
+	if (derive_key(key, key_len, read_len, flags, img_id,
+		       img_id_len) != 0) {
+		zeromem(key, *key_len);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum stm32_saes_key_selection select_key(unsigned int key_flags)
+{
+	if ((key_flags & ENC_KEY_IS_IDENTIFIER) != 0U) {
+		panic();
+	}
+
+	/* Use the provided key buffer */
+	return STM32_SAES_KEY_SOFT;
+}
+
+static int stm32_decrypt_aes_gcm(void *data, size_t data_len,
+				 const void *key, unsigned int key_len,
+				 unsigned int key_flags,
+				 const void *iv, unsigned int iv_len,
+				 const void *tag, unsigned int tag_len)
+{
+	int ret;
+	struct stm32_saes_context ctx;
+	unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE];
+	enum stm32_saes_key_selection key_mode;
+	unsigned int diff = 0U;
+	unsigned int i;
+
+	key_mode = select_key(key_flags);
+
+	ret = stm32_saes_init(&ctx, true, STM32_SAES_MODE_GCM, key_mode, key,
+			      key_len, iv, iv_len);
+	if (ret != 0) {
+		return CRYPTO_ERR_INIT;
+	}
+
+	ret = stm32_saes_update_assodata(&ctx, true, NULL, 0U);
+	if (ret != 0) {
+		return CRYPTO_ERR_DECRYPTION;
+	}
+
+	ret = stm32_saes_update_load(&ctx, true, data, data, data_len);
+	if (ret != 0) {
+		return CRYPTO_ERR_DECRYPTION;
+	}
+
+	ret = stm32_saes_final(&ctx, tag_buf, sizeof(tag_buf));
+	if (ret != 0) {
+		return CRYPTO_ERR_DECRYPTION;
+	}
+
+	/* Check tag in "constant-time" */
+	for (i = 0U; i < tag_len; i++) {
+		diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i];
+	}
+
+	if (diff != 0U) {
+		return CRYPTO_ERR_DECRYPTION;
+	}
+
+	return CRYPTO_SUCCESS;
+}
+
+/*
+ * Authenticated decryption of an image
+ *
+ */
+static int crypto_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, size_t len,
+			       const void *key, unsigned int key_len, unsigned int key_flags,
+			       const void *iv, unsigned int iv_len, const void *tag,
+			       unsigned int tag_len)
+{
+	int rc = -1;
+	uint32_t real_iv[4];
+
+	switch (dec_algo) {
+	case CRYPTO_GCM_DECRYPT:
+		/*
+		 * GCM expect a Nonce
+		 * The AES IV is the nonce (a uint32_t[3])
+		 * then a counter (a uint32_t big endian)
+		 * The counter starts at 2.
+		 */
+		memcpy(real_iv, iv, iv_len);
+		real_iv[3] = htobe32(0x2U);
+
+		rc = stm32_decrypt_aes_gcm(data_ptr, len, key, key_len, key_flags,
+					   real_iv, sizeof(real_iv), tag, tag_len);
+		break;
+	default:
+		rc = CRYPTO_ERR_DECRYPTION;
+		break;
+	}
+
+	if (rc != 0) {
+		return rc;
+	}
+
+	return CRYPTO_SUCCESS;
+}
+
+REGISTER_CRYPTO_LIB("stm32_crypto_lib",
+		    crypto_lib_init,
+		    crypto_verify_signature,
+		    crypto_verify_hash,
+		    crypto_auth_decrypt);
+
+#else /* No decryption support */
+REGISTER_CRYPTO_LIB("stm32_crypto_lib",
+		    crypto_lib_init,
+		    crypto_verify_signature,
+		    crypto_verify_hash,
+		    NULL);
+
+#endif
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index c9efeb5..34d52e1 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.c
@@ -79,11 +79,8 @@
 	}
 
 	cchar = fdt_getprop(fdt, node, "secure-status", NULL);
-	if (cchar == NULL) {
-		if (status == DT_NON_SECURE) {
-			status |= DT_SECURE;
-		}
-	} else if (strncmp(cchar, "okay", strlen("okay")) == 0) {
+	if (((cchar == NULL) && (status == DT_NON_SECURE)) ||
+	    ((cchar != NULL) && (strncmp(cchar, "okay", strlen("okay")) == 0))) {
 		status |= DT_SECURE;
 	}
 
@@ -350,7 +347,7 @@
 		return -FDT_ERR_BADVALUE;
 	}
 
-	if (fdt32_to_cpu(*cuint) % sizeof(uint32_t)) {
+	if ((fdt32_to_cpu(*cuint) % sizeof(uint32_t)) != 0U) {
 		ERROR("Misaligned nvmem %s element: ignored\n", name);
 		return -FDT_ERR_BADVALUE;
 	}
@@ -386,7 +383,7 @@
 
 	fdt_for_each_subnode(node, fdt, pinctrl_node) {
 		const fdt32_t *cuint;
-		int pin_count;
+		int pin_count = 0;
 		int len;
 		int i;
 
@@ -415,11 +412,9 @@
 		}
 
 		/* Get the last defined gpio line (offset + nb of pins) */
-		pin_count = fdt32_to_cpu(*(cuint + 1)) + fdt32_to_cpu(*(cuint + 3));
-		for (i = 0; i < len / 4; i++) {
-			pin_count = MAX(pin_count, (int)(fdt32_to_cpu(*(cuint + 1)) +
-							 fdt32_to_cpu(*(cuint + 3))));
-			cuint += 4;
+		for (i = 0; i < len; i += 4) {
+			pin_count = MAX(pin_count, (int)(fdt32_to_cpu(cuint[i + 1]) +
+							 fdt32_to_cpu(cuint[i + 3])));
 		}
 
 		return pin_count;
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index ca71958..1a59f0b 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,7 +28,7 @@
 #endif
 
 #if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
-io_block_spec_t metadata_block_spec = {
+static io_block_spec_t metadata_block_spec = {
 	.offset = 0,    /* To be filled at runtime */
 	.length = 0,    /* To be filled at runtime */
 };
@@ -42,6 +42,14 @@
 		.img_type_guid = STM32MP_FIP_GUID,
 		.check = open_storage
 	},
+#ifndef DECRYPTION_SUPPORT_none
+	[ENC_IMAGE_ID] = {
+		.dev_handle = &fip_dev_handle,
+		.image_spec = (uintptr_t)NULL,
+		.img_type_guid = NULL_GUID,
+		.check = open_fip
+	},
+#endif
 #if STM32MP_SDMMC || STM32MP_EMMC
 	[GPT_IMAGE_ID] = {
 		.dev_handle = &storage_dev_handle,
@@ -66,7 +74,16 @@
 #endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
 };
 
+#define DEFAULT_UUID_NUMBER	U(7)
+
-#define FCONF_ST_IO_UUID_NUMBER	U(8)
+#if TRUSTED_BOARD_BOOT
+#define TBBR_UUID_NUMBER	U(6)
+#else
+#define TBBR_UUID_NUMBER	U(0)
+#endif
+
+#define FCONF_ST_IO_UUID_NUMBER	(DEFAULT_UUID_NUMBER + \
+				 TBBR_UUID_NUMBER)
 
 static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER];
 static OBJECT_POOL_ARRAY(fconf_stm32mp_uuids_pool, fconf_stm32mp_uuids);
@@ -85,7 +102,14 @@
 	{BL33_IMAGE_ID, "bl33_uuid"},
 	{HW_CONFIG_ID, "hw_cfg_uuid"},
 	{TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"},
-	{NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"},
+#if TRUSTED_BOARD_BOOT
+	{STM32MP_CONFIG_CERT_ID, "stm32mp_cfg_cert_uuid"},
+	{TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"},
+	{TRUSTED_OS_FW_KEY_CERT_ID, "tos_fw_key_cert_uuid"},
+	{NON_TRUSTED_FW_KEY_CERT_ID, "nt_fw_key_cert_uuid"},
+	{TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"},
+	{NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"},
+#endif /* TRUSTED_BOARD_BOOT */
 };
 
 int fconf_populate_stm32mp_io_policies(uintptr_t config)
@@ -135,8 +159,20 @@
 
 		uuid_ptr->uuid = uuid_helper.uuid_struct;
 		policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr;
-		policies[load_info[i].image_id].dev_handle = &fip_dev_handle;
-		policies[load_info[i].image_id].check = open_fip;
+		switch (load_info[i].image_id) {
+#if ENCRYPT_BL32 && !defined(DECRYPTION_SUPPORT_none)
+		case BL32_IMAGE_ID:
+		case BL32_EXTRA1_IMAGE_ID:
+		case BL32_EXTRA2_IMAGE_ID:
+			policies[load_info[i].image_id].dev_handle = &enc_dev_handle;
+			policies[load_info[i].image_id].check = open_enc_fip;
+			break;
+#endif
+		default:
+			policies[load_info[i].image_id].dev_handle = &fip_dev_handle;
+			policies[load_info[i].image_id].check = open_fip;
+			break;
+		}
 	}
 
 	return 0;
diff --git a/plat/st/common/stm32mp_trusted_boot.c b/plat/st/common/stm32mp_trusted_boot.c
new file mode 100644
index 0000000..051d6fc
--- /dev/null
+++ b/plat/st/common/stm32mp_trusted_boot.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <endian.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <common/debug.h>
+#include <common/tbbr/cot_def.h>
+#include <drivers/st/stm32_hash.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/fconf/fconf_tbbr_getter.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <boot_api.h>
+#include <platform_def.h>
+
+#define HEADER_AND_EXT_TOTAL_SIZE 512
+
+static uint8_t der_sha256_header[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
+	0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
+static uint8_t root_pk_hash[HASH_DER_LEN];
+
+static int copy_hash_from_otp(const char *otp_name, uint8_t *hash, size_t len)
+{
+	uint32_t otp_idx;
+	uint32_t otp_len;
+	size_t i;
+	bool valid = false;
+
+	assert(len % sizeof(uint32_t) == 0);
+
+	if (stm32_get_otp_index(otp_name, &otp_idx, &otp_len) != 0) {
+		VERBOSE("%s: get %s index error\n", __func__, otp_name);
+		return -EINVAL;
+	}
+	if (otp_len != (len * CHAR_BIT)) {
+		VERBOSE("%s: length Error\n", __func__);
+		return -EINVAL;
+	}
+
+	for (i = 0U; i < len / sizeof(uint32_t); i++) {
+		uint32_t tmp;
+		uint32_t otp_val;
+		uint32_t first;
+
+		if (stm32_get_otp_value_from_idx(otp_idx + i, &otp_val) != 0) {
+			VERBOSE("%s: unable to read from otp\n", __func__);
+			return -EINVAL;
+		}
+
+		tmp = bswap32(otp_val);
+		memcpy(hash + i * sizeof(uint32_t), &tmp, sizeof(tmp));
+
+		if (i == 0U) {
+			first = tmp;
+		}
+
+		/*
+		 * Check if key hash values in OTP are 0 or 0xFFFFFFFFF
+		 * programmed : Invalid Key
+		 */
+		if (!stm32mp_is_closed_device() && !valid) {
+			if ((tmp != 0U) && (tmp != 0xFFFFFFFFU) && (tmp != first)) {
+				valid = true;
+			}
+		}
+	}
+
+	if (!stm32mp_is_closed_device() && !valid) {
+		return 0;
+	}
+
+	return len;
+}
+
+#if STM32_HEADER_VERSION_MAJOR == 1
+static int get_rotpk_hash(void *cookie, uint8_t *hash, size_t len)
+{
+	if (cookie != NULL) {
+		return -EINVAL;
+	}
+
+	return copy_hash_from_otp(PKH_OTP, hash, len);
+}
+#else
+static int get_rotpk_hash(void *cookie, uint8_t *hash, size_t len)
+{
+	int ret;
+	uint32_t pk_idx = 0U;
+	uint8_t calc_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES];
+	uint8_t otp_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES];
+	boot_api_image_header_t *hdr = (boot_api_image_header_t *)(SRAM3_BASE + SRAM3_SIZE -
+								   HEADER_AND_EXT_TOTAL_SIZE);
+	boot_extension_header_t *ext_header = (boot_extension_header_t *)hdr->ext_header;
+	boot_ext_header_params_authentication_t *param;
+
+	if (cookie != NULL) {
+		return -EINVAL;
+	}
+
+	if (hdr->header_version != BOOT_API_HEADER_VERSION) {
+		VERBOSE("%s: unexpected header_version\n", __func__);
+		return -EINVAL;
+	}
+
+	param = (boot_ext_header_params_authentication_t *)ext_header->params;
+
+	pk_idx = param->pk_idx;
+
+	stm32_hash_init(HASH_SHA256);
+	ret = stm32_hash_final_update((uint8_t *)param->pk_hashes,
+				      param->nb_pk * sizeof(boot_api_sha256_t), calc_hash);
+	if (ret != 0) {
+		VERBOSE("%s: hash failed\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = copy_hash_from_otp(PKH_OTP, otp_hash, len);
+	if (ret < 0) {
+		return -EINVAL;
+	}
+
+	if (ret != 0) {
+		ret = memcmp(calc_hash, otp_hash, sizeof(calc_hash));
+		if (ret != 0) {
+			VERBOSE("%s: not expected digest\n", __func__);
+			return -EINVAL;
+		}
+
+		ret = sizeof(otp_hash);
+	}
+
+	memcpy(hash, param->pk_hashes[pk_idx], sizeof(otp_hash));
+
+	return ret;
+}
+#endif
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	size_t start_copy_idx = 0U;
+	int res;
+
+	memcpy(root_pk_hash, der_sha256_header, sizeof(der_sha256_header));
+	start_copy_idx = sizeof(der_sha256_header);
+
+	res = get_rotpk_hash(cookie, root_pk_hash + start_copy_idx,
+			     BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES);
+	if (res < 0) {
+		return -EINVAL;
+	}
+
+	*key_len = HASH_DER_LEN;
+	*key_ptr = &root_pk_hash;
+	*flags = ROTPK_IS_HASH;
+
+	if ((res == 0) && !stm32mp_is_closed_device()) {
+		*flags |= ROTPK_NOT_DEPLOYED;
+	}
+
+	return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+	*nv_ctr = mmio_read_32(TAMP_BASE + TAMP_COUNTR);
+
+	return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+	while (mmio_read_32(TAMP_BASE + TAMP_COUNTR) != nv_ctr) {
+		mmio_write_32(TAMP_BASE + TAMP_COUNTR, 1U);
+	}
+
+	return 0;
+}
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	assert(heap_addr != NULL);
+	assert(heap_size != NULL);
+
+#if STM32MP_USE_EXTERNAL_HEAP
+	/* Retrieve the already allocated heap's info from DTB */
+	*heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr);
+	*heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size);
+
+	/* We expect heap already statically mapped */
+
+	return 0;
+#else
+	return get_mbedtls_heap_helper(heap_addr, heap_size);
+#endif
+}
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 5015f7d..87d2d39 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -17,6 +17,7 @@
 #include <drivers/st/bsec.h>
 #include <drivers/st/regulator_fixed.h>
 #include <drivers/st/stm32_iwdg.h>
+#include <drivers/st/stm32_rng.h>
 #include <drivers/st/stm32_uart.h>
 #include <drivers/st/stm32mp1_clk.h>
 #include <drivers/st/stm32mp1_pwr.h>
@@ -47,10 +48,6 @@
 };
 #endif
 
-#if STM32MP15
-static struct stm32mp_auth_ops stm32mp1_auth_ops;
-#endif
-
 static void print_reset_reason(void)
 {
 	uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_MP_RSTSCLRR);
@@ -167,14 +164,6 @@
 		ERROR("DDR mapping: error %d\n", ret);
 		panic();
 	}
-
-#if STM32MP_USE_STM32IMAGE
-#ifdef AARCH32_SP_OPTEE
-	INFO("BL2 runs OP-TEE setup\n");
-#else
-	INFO("BL2 runs SP_MIN setup\n");
-#endif
-#endif /* STM32MP_USE_STM32IMAGE */
 }
 
 #if STM32MP15
@@ -229,19 +218,6 @@
 			BL_CODE_END - BL_CODE_BASE,
 			MT_CODE | MT_SECURE);
 
-#if STM32MP_USE_STM32IMAGE
-#ifdef AARCH32_SP_OPTEE
-	mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE,
-			STM32MP_OPTEE_SIZE,
-			MT_MEMORY | MT_RW | MT_SECURE);
-#else
-	/* Prevent corruption of preloaded BL32 */
-	mmap_add_region(BL32_BASE, BL32_BASE,
-			BL32_LIMIT - BL32_BASE,
-			MT_RO_DATA | MT_SECURE);
-#endif
-#endif /* STM32MP_USE_STM32IMAGE */
-
 	/* Prevent corruption of preloaded Device Tree */
 	mmap_add_region(DTB_BASE, DTB_BASE,
 			DTB_LIMIT - DTB_BASE,
@@ -344,6 +320,14 @@
 	}
 
 skip_console_init:
+#if !TRUSTED_BOARD_BOOT
+	if (stm32mp_is_closed_device()) {
+		/* Closed chip mandates authentication */
+		ERROR("Secure chip: TRUSTED_BOARD_BOOT must be enabled\n");
+		panic();
+	}
+#endif
+
 	if (fixed_regulator_register() != 0) {
 		panic();
 	}
@@ -375,14 +359,9 @@
 		}
 	}
 
-#if STM32MP15
-	if (stm32mp_is_auth_supported()) {
-		stm32mp1_auth_ops.check_key =
-			boot_context->bootrom_ecdsa_check_key;
-		stm32mp1_auth_ops.verify_signature =
-			boot_context->bootrom_ecdsa_verify_signature;
-
-		stm32mp_init_auth(&stm32mp1_auth_ops);
+#if STM32MP13
+	if (stm32_rng_init() != 0) {
+		panic();
 	}
 #endif
 
@@ -396,9 +375,7 @@
 
 	stm32mp1_syscfg_enable_io_compensation_finish();
 
-#if !STM32MP_USE_STM32IMAGE
 	fconf_populate("TB_FW", STM32MP_DTB_BASE);
-#endif /* !STM32MP_USE_STM32IMAGE */
 
 	stm32mp_io_setup();
 }
@@ -414,7 +391,6 @@
 	bl_mem_params_node_t *bl32_mem_params;
 	bl_mem_params_node_t *pager_mem_params __unused;
 	bl_mem_params_node_t *paged_mem_params __unused;
-#if !STM32MP_USE_STM32IMAGE
 	const struct dyn_cfg_dtb_info_t *config_info;
 	bl_mem_params_node_t *tos_fw_mem_params;
 	unsigned int i;
@@ -426,12 +402,10 @@
 		HW_CONFIG_ID,
 		TOS_FW_CONFIG_ID,
 	};
-#endif /* !STM32MP_USE_STM32IMAGE */
 
 	assert(bl_mem_params != NULL);
 
 	switch (image_id) {
-#if !STM32MP_USE_STM32IMAGE
 	case FW_CONFIG_ID:
 		/* Set global DTB info for fixed fw_config information */
 		set_config_info(STM32MP_FW_CONFIG_BASE, ~0UL, STM32MP_FW_CONFIG_MAX_SIZE,
@@ -494,7 +468,6 @@
 			}
 		}
 		break;
-#endif /* !STM32MP_USE_STM32IMAGE */
 
 	case BL32_IMAGE_ID:
 		if (optee_header_is_valid(bl_mem_params->image_info.image_base)) {
@@ -510,18 +483,6 @@
 				paged_image_info = &paged_mem_params->image_info;
 			}
 
-#if STM32MP_USE_STM32IMAGE && defined(AARCH32_SP_OPTEE)
-			/* Set OP-TEE extra image load areas at run-time */
-			pager_mem_params->image_info.image_base = STM32MP_OPTEE_BASE;
-			pager_mem_params->image_info.image_max_size = STM32MP_OPTEE_SIZE;
-
-			paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
-								  dt_get_ddr_size() -
-								  STM32MP_DDR_S_SIZE -
-								  STM32MP_DDR_SHMEM_SIZE;
-			paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE;
-#endif /* STM32MP_USE_STM32IMAGE && defined(AARCH32_SP_OPTEE) */
-
 			err = parse_optee_header(&bl_mem_params->ep_info,
 						 &pager_mem_params->image_info,
 						 paged_image_info);
@@ -541,13 +502,11 @@
 			bl_mem_params->ep_info.args.arg1 = 0U; /* Unused */
 			bl_mem_params->ep_info.args.arg2 = 0U; /* No DT supported */
 		} else {
-#if !STM32MP_USE_STM32IMAGE
 			bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
 			tos_fw_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
 			assert(tos_fw_mem_params != NULL);
 			bl_mem_params->image_info.image_max_size +=
 				tos_fw_mem_params->image_info.image_max_size;
-#endif /* !STM32MP_USE_STM32IMAGE */
 			bl_mem_params->ep_info.args.arg0 = 0;
 		}
 		break;
@@ -556,9 +515,9 @@
 		bl32_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
 		assert(bl32_mem_params != NULL);
 		bl32_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
-#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
 		stm32mp1_fwu_set_boot_idx();
-#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
 		break;
 
 	default:
@@ -584,20 +543,15 @@
 
 void bl2_el3_plat_prepare_exit(void)
 {
+#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
 	uint16_t boot_itf = stm32mp_get_boot_itf_selected();
 
-	switch (boot_itf) {
-#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART:
-	case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB:
+	if ((boot_itf == BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART) ||
+	    (boot_itf == BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB)) {
 		/* Invalidate the downloaded buffer used with io_memmap */
 		inv_dcache_range(DWL_BUFFER_BASE, DWL_BUFFER_SIZE);
-		break;
-#endif /* STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER */
-	default:
-		/* Do nothing in default case */
-		break;
 	}
+#endif /* STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER */
 
 	stm32mp1_security_setup();
 }
diff --git a/plat/st/stm32mp1/cert_create_tbbr.mk b/plat/st/stm32mp1/cert_create_tbbr.mk
new file mode 100644
index 0000000..5b1a3ed
--- /dev/null
+++ b/plat/st/stm32mp1/cert_create_tbbr.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Override TBBR Cert to update generic certificate
+
+$(eval $(call add_define,PDEF_CERTS))
+
+PLAT_INCLUDE	+= -I${PLAT_DIR}include
+
+src/stm32mp1_tbb_cert.o: ${PLAT_DIR}stm32mp1_tbb_cert.c
+	${Q}${HOSTCC} -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+
+PLAT_OBJECTS	= src/stm32mp1_tbb_cert.o
+
+OBJECTS		+= $(PLAT_OBJECTS)
+
diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h
index 7638418..1054609 100644
--- a/plat/st/stm32mp1/include/boot_api.h
+++ b/plat/st/stm32mp1/include/boot_api.h
@@ -232,21 +232,14 @@
 #if STM32MP15
 	/*
 	 * Pointers to bootROM External Secure Services
-	 * - ECDSA check key
 	 * - ECDSA verify signature
-	 * - ECDSA verify signature and go
 	 */
-	uint32_t (*bootrom_ecdsa_check_key)(uint8_t *pubkey_in,
-					    uint8_t *pubkey_out);
+	uint32_t reserved3;
 	uint32_t (*bootrom_ecdsa_verify_signature)(uint8_t *hash_in,
 						   uint8_t *pubkey_in,
 						   uint8_t *signature,
 						   uint32_t ecc_algo);
-	uint32_t (*bootrom_ecdsa_verify_and_go)(uint8_t *hash_in,
-						uint8_t *pub_key_in,
-						uint8_t *signature,
-						uint32_t ecc_algo,
-						uint32_t *entry_in);
+	uint32_t reserved4;
 #endif
 	/*
 	 * Information specific to an SD boot
@@ -340,6 +333,8 @@
 	uint32_t binary_type;
 	/* Pad up to 128 byte total size */
 	uint8_t pad[16];
+	/* Followed by extension header */
+	uint8_t ext_header[];
 #endif
 #if STM32MP15
 	/*
@@ -370,4 +365,45 @@
 #endif
 } __packed boot_api_image_header_t;
 
+typedef uint8_t boot_api_sha256_t[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES];
+
+typedef struct {
+	/* Extension header type:
+	 * BOOT_API_FSBL_DECRYPTION_HEADER_MAGIC_NB or
+	 * BOOT_API_AUTHENTICATION_HEADER_MAGIC_NB
+	 * BOOT_API_PADDING_HEADER_MAGIC_NB
+	 */
+	uint32_t type;
+	/* Extension header len in byte */
+	uint32_t len;
+	/* parameters of this extension */
+	uint8_t  params[];
+} __packed boot_extension_header_t;
+
+typedef struct {
+	/* Idx of ECDSA public key to be used in table */
+	uint32_t pk_idx;
+	/* Number of ECDSA public key in table */
+	uint32_t nb_pk;
+	/*
+	 * Type of ECC algorithm to use  :
+	 * value 1 : for P-256 NIST algorithm
+	 * value 2 : for Brainpool 256 algorithm
+	 * See definitions 'BOOT_API_ECDSA_ALGO_TYPE_XXX' above.
+	 */
+	uint32_t ecc_algo_type;
+	/* ECDSA public key to be used to check signature. */
+	uint8_t ecc_pubk[BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES];
+	/* table of Hash of Algo+ECDSA public key */
+	boot_api_sha256_t pk_hashes[];
+} __packed boot_ext_header_params_authentication_t;
+
+typedef struct {
+	/* Size of encryption key (128 or 256) */
+	uint32_t key_size;
+	uint32_t derivation_cont;
+	/* 128 msb bits of plain payload SHA256 */
+	uint32_t hash[4];
+} __packed boot_ext_header_params_encrypted_fsbl_t;
+
 #endif /* BOOT_API_H */
diff --git a/plat/st/stm32mp1/include/plat_def_fip_uuid.h b/plat/st/stm32mp1/include/plat_def_fip_uuid.h
new file mode 100644
index 0000000..e5fbc2d
--- /dev/null
+++ b/plat/st/stm32mp1/include/plat_def_fip_uuid.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_FIP_UUID_H
+#define PLAT_DEF_FIP_UUID_H
+
+#define UUID_STM32MP_CONFIG_CERT \
+	{{0x50, 0x1d, 0x8d, 0xd2}, {0x8b, 0xce}, {0x49, 0xa5}, 0x84, 0xeb, \
+	 {0x55, 0x9a, 0x9f, 0x2e, 0xae, 0xaf} }
+#endif /* PLAT_DEF_FIP_UUID_H */
+
diff --git a/plat/st/stm32mp1/include/plat_tbbr_img_def.h b/plat/st/stm32mp1/include/plat_tbbr_img_def.h
new file mode 100644
index 0000000..984aae8
--- /dev/null
+++ b/plat/st/stm32mp1/include/plat_tbbr_img_def.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef STM32MP1_IMG_DEF_H
+#define STM32MP1_IMG_DEF_H
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/* Undef the existing values */
+#undef BL32_EXTRA1_IMAGE_ID
+#undef BL32_EXTRA2_IMAGE_ID
+#undef TOS_FW_CONFIG_ID
+#undef TRUSTED_BOOT_FW_CERT_ID
+#undef FWU_METADATA_IMAGE_ID
+#undef BKUP_FWU_METADATA_IMAGE_ID
+#undef FW_CONFIG_ID
+#undef HW_CONFIG_ID
+#undef GPT_IMAGE_ID
+#undef ENC_IMAGE_ID
+
+/* Define the STM32MP1 used ID */
+#define FW_CONFIG_ID			U(1)
+#define HW_CONFIG_ID			U(2)
+#define GPT_IMAGE_ID			U(3)
+#define ENC_IMAGE_ID			U(6)
+#define BL32_EXTRA1_IMAGE_ID		U(8)
+#define BL32_EXTRA2_IMAGE_ID		U(9)
+#define FWU_METADATA_IMAGE_ID		U(12)
+#define BKUP_FWU_METADATA_IMAGE_ID	U(13)
+#define TOS_FW_CONFIG_ID		U(16)
+#define STM32MP_CONFIG_CERT_ID		U(17)
+
+/* Increase the MAX_NUMBER_IDS to match the authentication pool required */
+#define MAX_NUMBER_IDS			U(19)
+
+#endif	/* STM32MP1_IMG_DEF_H */
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index fe4ef3d..61b847f 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -25,26 +25,10 @@
 #define PLATFORM_STACK_SIZE		0xC00
 #endif
 
-#if STM32MP_USE_STM32IMAGE
-#ifdef AARCH32_SP_OPTEE
-#define OPTEE_HEADER_IMAGE_NAME		"teeh"
-#define OPTEE_CORE_IMAGE_NAME		"teex"
-#define OPTEE_PAGED_IMAGE_NAME		"teed"
-#define OPTEE_HEADER_BINARY_TYPE	U(0x20)
-#define OPTEE_CORE_BINARY_TYPE		U(0x21)
-#define OPTEE_PAGED_BINARY_TYPE		U(0x22)
-#endif
-
-/* SSBL = second stage boot loader */
-#define BL33_IMAGE_NAME			"ssbl"
-#define BL33_BINARY_TYPE		U(0x0)
-#else /* STM32MP_USE_STM32IMAGE */
 #define FIP_IMAGE_NAME			"fip"
 #define METADATA_PART_1			"metadata1"
 #define METADATA_PART_2			"metadata2"
 
-#endif /* STM32MP_USE_STM32IMAGE */
-
 #define STM32MP_PRIMARY_CPU		U(0x0)
 #define STM32MP_SECONDARY_CPU		U(0x1)
 
@@ -81,7 +65,7 @@
 /*******************************************************************************
  * BL32 specific defines.
  ******************************************************************************/
-#if STM32MP_USE_STM32IMAGE || defined(IMAGE_BL32)
+#if defined(IMAGE_BL32)
 #if ENABLE_PIE
 #define BL32_BASE			0
 #define BL32_LIMIT			STM32MP_BL32_SIZE
@@ -90,7 +74,7 @@
 #define BL32_LIMIT			(STM32MP_BL32_BASE + \
 					 STM32MP_BL32_SIZE)
 #endif
-#endif /* STM32MP_USE_STM32IMAGE || defined(IMAGE_BL32) */
+#endif /* defined(IMAGE_BL32) */
 
 /*******************************************************************************
  * BL33 specific defines.
diff --git a/plat/st/stm32mp1/include/stm32mp1_mbedtls_config.h b/plat/st/stm32mp1/include/stm32mp1_mbedtls_config.h
new file mode 100644
index 0000000..2f07621
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_mbedtls_config.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef MBEDTLS_CONFIG_H
+#define MBEDTLS_CONFIG_H
+
+/*
+ * Key algorithms currently supported on mbed TLS libraries
+ */
+#define TF_MBEDTLS_USE_RSA	0
+#define TF_MBEDTLS_USE_ECDSA	1
+
+/*
+ * Hash algorithms currently supported on mbed TLS libraries
+ */
+#define TF_MBEDTLS_SHA256		1
+#define TF_MBEDTLS_SHA384		2
+#define TF_MBEDTLS_SHA512		3
+
+/*
+ * Configuration file to build mbed TLS with the required features for
+ * Trusted Boot
+ */
+
+#define MBEDTLS_PLATFORM_MEMORY
+#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */
+#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+
+#define MBEDTLS_PKCS1_V21
+
+#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+#define MBEDTLS_X509_CHECK_KEY_USAGE
+#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+
+#define MBEDTLS_ASN1_PARSE_C
+#define MBEDTLS_ASN1_WRITE_C
+
+#define MBEDTLS_BASE64_C
+#define MBEDTLS_BIGNUM_C
+
+#define MBEDTLS_ERROR_C
+#define MBEDTLS_MD_C
+
+#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
+#define MBEDTLS_OID_C
+
+#define MBEDTLS_PK_C
+#define MBEDTLS_PK_PARSE_C
+#define MBEDTLS_PK_WRITE_C
+
+#define MBEDTLS_PLATFORM_C
+
+#if TF_MBEDTLS_USE_ECDSA
+#define MBEDTLS_ECDSA_C
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_NO_INTERNAL_RNG
+#endif
+#if TF_MBEDTLS_USE_RSA
+#define MBEDTLS_RSA_C
+#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
+#endif
+
+#define MBEDTLS_SHA256_C
+#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256)
+#define MBEDTLS_SHA512_C
+#endif
+
+#define MBEDTLS_VERSION_C
+
+#define MBEDTLS_X509_USE_C
+#define MBEDTLS_X509_CRT_PARSE_C
+
+#if TF_MBEDTLS_USE_AES_GCM
+#define MBEDTLS_AES_C
+#define MBEDTLS_CIPHER_C
+#define MBEDTLS_GCM_C
+#endif
+
+/* MPI / BIGNUM options */
+#define MBEDTLS_MPI_WINDOW_SIZE			2
+
+#if TF_MBEDTLS_USE_RSA
+#if TF_MBEDTLS_KEY_SIZE <= 2048
+#define MBEDTLS_MPI_MAX_SIZE			256
+#else
+#define MBEDTLS_MPI_MAX_SIZE			512
+#endif
+#else
+#define MBEDTLS_MPI_MAX_SIZE			256
+#endif
+
+/* Memory buffer allocator options */
+#define MBEDTLS_MEMORY_ALIGN_MULTIPLE		8
+
+/*
+ * Prevent the use of 128-bit division which
+ * creates dependency on external libraries.
+ */
+#define MBEDTLS_NO_UDBL_DIVISION
+
+#ifndef __ASSEMBLER__
+/* System headers required to build mbed TLS with the current configuration */
+#include <stdlib.h>
+#include <mbedtls/check_config.h>
+#endif
+
+/*
+ * Mbed TLS heap size is smal as we only use the asn1
+ * parsing functions
+ * digest, signature and crypto algorithm are done by
+ * other library.
+ */
+
+#define TF_MBEDTLS_HEAP_SIZE           U(5120)
+#endif /* MBEDTLS_CONFIG_H */
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index 23934e9..21ef60d 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -34,9 +34,5 @@
 
 void stm32mp1_deconfigure_uart_pins(void);
 
-#if STM32MP_USE_STM32IMAGE
-uint32_t stm32mp_get_ddr_ns_size(void);
-#endif /* STM32MP_USE_STM32IMAGE */
-
 void stm32mp1_init_scmi_server(void);
 #endif /* STM32MP1_PRIVATE_H */
diff --git a/plat/st/stm32mp1/include/tbbr/stm32mp1_tbb_cert.h b/plat/st/stm32mp1/include/tbbr/stm32mp1_tbb_cert.h
new file mode 100644
index 0000000..2cc1e19
--- /dev/null
+++ b/plat/st/stm32mp1/include/tbbr/stm32mp1_tbb_cert.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_TBB_CERT_H
+#define STM32MP1_TBB_CERT_H
+
+#include <tbbr/tbb_cert.h>
+
+/*
+ * Enumerate the certificates that are used to establish the chain of trust
+ */
+enum {
+	STM32MP_CONFIG_CERT = FWU_CERT + 1
+};
+
+#endif /* STM32MP1_TBB_CERT_H */
diff --git a/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c
deleted file mode 100644
index 4fce55a..0000000
--- a/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/bl_common.h>
-#include <common/desc_image_load.h>
-#include <plat/common/platform.h>
-
-#include <platform_def.h>
-
-/*******************************************************************************
- * Following descriptor provides BL image/ep information that gets used
- * by BL2 to load the images and also subset of this information is
- * passed to next BL image. The image loading sequence is managed by
- * populating the images in required loading order. The image execution
- * sequence is managed by populating the `next_handoff_image_id` with
- * the next executable image id.
- ******************************************************************************/
-static bl_mem_params_node_t bl2_mem_params_descs[] = {
-	/* Fill BL32 related information */
-	{
-		.image_id = BL32_IMAGE_ID,
-
-		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
-				      VERSION_2, entry_point_info_t,
-				      SECURE | EXECUTABLE | EP_FIRST_EXE),
-
-		/* Updated at runtime if OP-TEE is loaded */
-		.ep_info.pc = STM32MP_BL32_BASE,
-
-		.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
-					    SPSR_E_LITTLE,
-					    DISABLE_ALL_EXCEPTIONS),
-
-		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
-				      VERSION_2, image_info_t,
-				      IMAGE_ATTRIB_PLAT_SETUP),
-
-		/* Updated at runtime if OP-TEE is loaded */
-		.image_info.image_base = STM32MP_BL32_BASE,
-		.image_info.image_max_size = STM32MP_BL32_SIZE,
-
-		.next_handoff_image_id = BL33_IMAGE_ID,
-	},
-
-#if defined(AARCH32_SP_OPTEE)
-	/* Fill BL32 external 1 image related information */
-	{
-		.image_id = BL32_EXTRA1_IMAGE_ID,
-
-		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
-				      VERSION_2, entry_point_info_t,
-				      SECURE | NON_EXECUTABLE),
-
-		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
-				      VERSION_2, image_info_t,
-				      IMAGE_ATTRIB_SKIP_LOADING),
-
-		.next_handoff_image_id = INVALID_IMAGE_ID,
-	},
-	/* Fill BL32 external 2 image related information */
-	{
-		.image_id = BL32_EXTRA2_IMAGE_ID,
-
-		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
-				      VERSION_2, entry_point_info_t,
-				      SECURE | NON_EXECUTABLE),
-
-		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
-				      VERSION_2, image_info_t,
-				      IMAGE_ATTRIB_SKIP_LOADING),
-
-		.next_handoff_image_id = INVALID_IMAGE_ID,
-	},
-#endif /* AARCH32_SP_OPTEE */
-
-	/* Fill BL33 related information */
-	{
-		.image_id = BL33_IMAGE_ID,
-
-		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
-				      VERSION_2, entry_point_info_t,
-				      NON_SECURE | EXECUTABLE),
-
-		.ep_info.pc = PLAT_STM32MP_NS_IMAGE_OFFSET,
-		.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
-					    SPSR_E_LITTLE,
-					    DISABLE_ALL_EXCEPTIONS),
-
-		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
-				      VERSION_2, image_info_t, 0U),
-
-		.image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET,
-		.image_info.image_max_size = STM32MP_DDR_MAX_SIZE -
-			(PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_DDR_BASE),
-
-		.next_handoff_image_id = INVALID_IMAGE_ID,
-	}
-};
-
-REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/st/stm32mp1/plat_def_uuid_config.c b/plat/st/stm32mp1/plat_def_uuid_config.c
new file mode 100644
index 0000000..efaf567
--- /dev/null
+++ b/plat/st/stm32mp1/plat_def_uuid_config.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <firmware_image_package.h>
+
+#include "tbbr_config.h"
+
+toc_entry_t plat_def_toc_entries[] = {
+	{
+		.name = "STM32MP CONFIG CERT",
+		.uuid = UUID_STM32MP_CONFIG_CERT,
+		.cmdline_name = "stm32mp-cfg-cert"
+	}
+};
+
diff --git a/plat/st/stm32mp1/plat_fiptool.mk b/plat/st/stm32mp1/plat_fiptool.mk
new file mode 100644
index 0000000..00570c2
--- /dev/null
+++ b/plat/st/stm32mp1/plat_fiptool.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Name of the platform defined source file name,
+# which contains platform defined UUID entries populated
+# in the plat_def_toc_entries[].
+PLAT_DEF_UUID_FILE_NAME	:= plat_def_uuid_config
+
+INCLUDE_PATHS		+= -I${PLAT_DIR}/include -I./
+
+PLAT_DEF_UUID		:= yes
+
+ifeq (${PLAT_DEF_UUID},yes)
+HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
+
+${PLAT_DEF_UUID_FILE_NAME}.o: ${PLAT_DIR}${PLAT_DEF_UUID_FILE_NAME}.c
+	${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
+
+PLAT_OBJECTS += ${PLAT_DEF_UUID_FILE_NAME}.o
+endif
+
+OBJECTS += ${PLAT_OBJECTS}
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
index f68eb38..c455544 100644
--- a/plat/st/stm32mp1/plat_image_load.c
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -4,13 +4,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <assert.h>
-
 #include <common/desc_image_load.h>
 #include <plat/common/platform.h>
 
-#include <platform_def.h>
-
 /*******************************************************************************
  * This function flushes the data structures so that they are visible
  * in memory for the next BL image.
@@ -25,17 +21,6 @@
  ******************************************************************************/
 bl_load_info_t *plat_get_bl_image_load_info(void)
 {
-#if STM32MP_USE_STM32IMAGE
-	bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID);
-	uint32_t ddr_ns_size = stm32mp_get_ddr_ns_size();
-
-	assert(bl33 != NULL);
-
-	/* Max size is non-secure DDR end address minus image_base */
-	bl33->image_info.image_max_size = STM32MP_DDR_BASE + ddr_ns_size -
-					  bl33->image_info.image_base;
-#endif /* STM32MP_USE_STM32IMAGE */
-
 	return get_bl_load_info_from_mem_params_desc();
 }
 
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index def2898..7eecf30 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -13,10 +13,11 @@
 STM32MP_RECONFIGURE_CONSOLE ?=	0
 STM32MP_UART_BAUDRATE	?=	115200
 
-# Allow TF-A to concatenate BL2 & BL32 binaries in a single file,
-# share DTB file between BL2 and BL32
-# If it is set to 0, then FIP is used
-STM32MP_USE_STM32IMAGE	?=	0
+TRUSTED_BOARD_BOOT	?=	0
+STM32MP_USE_EXTERNAL_HEAP ?=	0
+
+# Use secure library from the ROM code for authentication
+STM32MP_CRYPTO_ROM_LIB	?=	0
 
 # Please don't increment this value without good understanding of
 # the monotonic counter
@@ -49,10 +50,19 @@
 endif
 
 ifeq ($(STM32MP13),1)
+# Will use SRAM2 as mbedtls heap
+STM32MP_USE_EXTERNAL_HEAP :=	1
+
 # DDR controller with single AXI port and 16-bit interface
 STM32MP_DDR_DUAL_AXI_PORT:=	0
 STM32MP_DDR_32BIT_INTERFACE:=	0
 
+ifeq (${TRUSTED_BOARD_BOOT},1)
+# PKA algo to include
+PKA_USE_NIST_P256	:=	1
+PKA_USE_BRAINPOOL_P256T1:=	1
+endif
+
 # STM32 image header version v2.0
 STM32_HEADER_VERSION_MAJOR:=	2
 STM32_HEADER_VERSION_MINOR:=	0
@@ -70,6 +80,13 @@
 # Add OP-TEE reserved shared memory area in mapping
 STM32MP15_OPTEE_RSV_SHM	:=	1
 $(eval $(call add_defines,STM32MP15_OPTEE_RSV_SHM))
+
+STM32MP_CRYPTO_ROM_LIB :=	1
+
+# Decryption support
+ifneq ($(DECRYPTION_SUPPORT),none)
+$(error "DECRYPTION_SUPPORT not supported on STM32MP15")
+endif
 endif
 
 # STM32 image header binary type for BL2
@@ -95,7 +112,6 @@
 PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + 4)))
 
 ifeq (${PSA_FWU_SUPPORT},1)
-ifneq (${STM32MP_USE_STM32IMAGE},1)
 # Number of banks of updatable firmware
 NR_OF_FW_BANKS			:=	2
 NR_OF_IMAGES_IN_FW_BANK		:=	1
@@ -105,9 +121,14 @@
 $(error "Required partition number is $(FWU_MAX_PART) where PLAT_PARTITION_MAX_ENTRIES is only \
 $(PLAT_PARTITION_MAX_ENTRIES)")
 endif
-else
-$(error FWU Feature enabled only with FIP images)
 endif
+
+ifeq ($(STM32MP13),1)
+STM32_HASH_VER		:=	4
+STM32_RNG_VER		:=	4
+else # Assuming STM32MP15
+STM32_HASH_VER		:=	2
+STM32_RNG_VER		:=	2
 endif
 
 # Boot devices
@@ -130,22 +151,13 @@
 BL2_DTSI		:=	stm32mp13-bl2.dtsi
 FDT_SOURCES		:=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
 else
-ifeq ($(STM32MP_USE_STM32IMAGE),1)
-ifeq ($(AARCH32_SP),optee)
 BL2_DTSI		:=	stm32mp15-bl2.dtsi
 FDT_SOURCES		:=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
-else
-FDT_SOURCES		:=	$(addprefix fdts/, $(patsubst %.dtb,%.dts,$(DTB_FILE_NAME)))
-endif
-else
-BL2_DTSI		:=	stm32mp15-bl2.dtsi
-FDT_SOURCES		:=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
 ifeq ($(AARCH32_SP),sp_min)
 BL32_DTSI		:=	stm32mp15-bl32.dtsi
 FDT_SOURCES		+=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dts,$(DTB_FILE_NAME)))
 endif
 endif
-endif
 
 $(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
 $(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o "[0-9]*")))
@@ -172,7 +184,6 @@
 STM32IMAGE		?= ${STM32IMAGEPATH}/stm32image${BIN_EXT}
 STM32IMAGE_SRC		:= ${STM32IMAGEPATH}/stm32image.c
 
-ifneq (${STM32MP_USE_STM32IMAGE},1)
 FIP_DEPS		+=	dtbs
 STM32MP_HW_CONFIG	:=	${BL33_CFG}
 STM32MP_FW_CONFIG_NAME	:=	$(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
@@ -184,6 +195,11 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
 # Add the HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_HW_CONFIG},--hw-config))
+ifeq ($(GENERATE_COT),1)
+STM32MP_CFG_CERT	:=	$(BUILD_PLAT)/stm32mp_cfg_cert.crt
+# Add the STM32MP_CFG_CERT to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_CFG_CERT},--stm32mp-cfg-cert))
+endif
 ifeq ($(AARCH32_SP),sp_min)
 STM32MP_TOS_FW_CONFIG	:= $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dtb,$(DTB_FILE_NAME)))
 $(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_TOS_FW_CONFIG},--tos-fw-config))
@@ -191,18 +207,21 @@
 # Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
 # in the FIP if the platform requires.
 ifneq ($(BL32_EXTRA1),)
-$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1))
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1,,$(ENCRYPT_BL32)))
 endif
 ifneq ($(BL32_EXTRA2),)
-$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2))
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2,,$(ENCRYPT_BL32)))
 endif
 endif
-endif
 
 # Enable flags for C files
 $(eval $(call assert_booleans,\
 	$(sort \
+		PKA_USE_BRAINPOOL_P256T1 \
+		PKA_USE_NIST_P256 \
+		PLAT_TBBR_IMG_DEF \
 		PLAT_XLAT_TABLES_DYNAMIC \
+		STM32MP_CRYPTO_ROM_LIB \
 		STM32MP_DDR_32BIT_INTERFACE \
 		STM32MP_DDR_DUAL_AXI_PORT \
 		STM32MP_EARLY_CONSOLE \
@@ -215,7 +234,7 @@
 		STM32MP_SPI_NOR \
 		STM32MP_UART_PROGRAMMER \
 		STM32MP_USB_PROGRAMMER \
-		STM32MP_USE_STM32IMAGE \
+		STM32MP_USE_EXTERNAL_HEAP \
 		STM32MP13 \
 		STM32MP15 \
 )))
@@ -223,6 +242,9 @@
 $(eval $(call assert_numerics,\
 	$(sort \
 		PLAT_PARTITION_MAX_ENTRIES \
+		STM32_HASH_VER \
+		STM32_HEADER_VERSION_MAJOR \
+		STM32_RNG_VER \
 		STM32_TF_A_COPIES \
 		STM32_TF_VERSION \
 		STM32MP_UART_BAUDRATE \
@@ -231,10 +253,17 @@
 $(eval $(call add_defines,\
 	$(sort \
 		DWL_BUFFER_BASE \
+		PKA_USE_BRAINPOOL_P256T1 \
+		PKA_USE_NIST_P256 \
 		PLAT_PARTITION_MAX_ENTRIES \
+		PLAT_TBBR_IMG_DEF \
 		PLAT_XLAT_TABLES_DYNAMIC \
+		STM32_HASH_VER \
+		STM32_HEADER_VERSION_MAJOR \
+		STM32_RNG_VER \
 		STM32_TF_A_COPIES \
 		STM32_TF_VERSION \
+		STM32MP_CRYPTO_ROM_LIB \
 		STM32MP_DDR_32BIT_INTERFACE \
 		STM32MP_DDR_DUAL_AXI_PORT \
 		STM32MP_EARLY_CONSOLE \
@@ -248,7 +277,7 @@
 		STM32MP_UART_BAUDRATE \
 		STM32MP_UART_PROGRAMMER \
 		STM32MP_USB_PROGRAMMER \
-		STM32MP_USE_STM32IMAGE \
+		STM32MP_USE_EXTERNAL_HEAP \
 		STM32MP13 \
 		STM32MP15 \
 )))
@@ -257,11 +286,7 @@
 PLAT_INCLUDES		:=	-Iplat/st/common/include/
 PLAT_INCLUDES		+=	-Iplat/st/stm32mp1/include/
 
-ifeq (${STM32MP_USE_STM32IMAGE},1)
-include common/fdt_wrappers.mk
-else
 include lib/fconf/fconf.mk
-endif
 include lib/libfdt/libfdt.mk
 
 PLAT_BL_COMMON_SOURCES	:=	common/uuid.c						\
@@ -302,12 +327,12 @@
 
 ifeq ($(STM32MP13),1)
 PLAT_BL_COMMON_SOURCES	+=	drivers/st/clk/clk-stm32-core.c				\
-				drivers/st/clk/clk-stm32mp13.c
+				drivers/st/clk/clk-stm32mp13.c				\
+				drivers/st/crypto/stm32_rng.c
 else
 PLAT_BL_COMMON_SOURCES	+=	drivers/st/clk/stm32mp1_clk.c
 endif
 
-ifneq (${STM32MP_USE_STM32IMAGE},1)
 BL2_SOURCES		+=	${FCONF_SOURCES} ${FCONF_DYN_SOURCES}
 
 BL2_SOURCES		+=	drivers/io/io_fip.c					\
@@ -315,15 +340,6 @@
 				plat/st/common/stm32mp_fconf_io.c			\
 				plat/st/stm32mp1/plat_bl2_mem_params_desc.c		\
 				plat/st/stm32mp1/stm32mp1_fconf_firewall.c
-else
-BL2_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
-
-BL2_SOURCES		+=	drivers/io/io_dummy.c					\
-				drivers/st/io/io_stm32image.c				\
-				plat/st/common/bl2_stm32_io_storage.c			\
-				plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c	\
-				plat/st/stm32mp1/stm32mp1_security.c
-endif
 
 include lib/zlib/zlib.mk
 
@@ -340,9 +356,47 @@
 				drivers/st/crypto/stm32_hash.c				\
 				plat/st/stm32mp1/bl2_plat_setup.c
 
+ifneq (${DECRYPTION_SUPPORT},none)
+BL2_SOURCES		+=	drivers/io/io_encrypted.c
+endif
 
-ifeq ($(STM32MP15),1)
-BL2_SOURCES		+=	plat/st/common/stm32mp_auth.c
+ifeq (${TRUSTED_BOARD_BOOT},1)
+AUTH_SOURCES		:=	drivers/auth/auth_mod.c					\
+				drivers/auth/crypto_mod.c				\
+				drivers/auth/img_parser_mod.c
+
+ifeq (${GENERATE_COT},1)
+TFW_NVCTR_VAL		:=	0
+NTFW_NVCTR_VAL		:=	0
+KEY_SIZE		:=
+KEY_ALG			:=	ecdsa
+HASH_ALG		:=	sha256
+
+ifeq (${SAVE_KEYS},1)
+TRUSTED_WORLD_KEY	?=	${BUILD_PLAT}/trusted.pem
+NON_TRUSTED_WORLD_KEY	?=	${BUILD_PLAT}/non-trusted.pem
+BL32_KEY		?=	${BUILD_PLAT}/trusted_os.pem
+BL33_KEY		?=	${BUILD_PLAT}/non-trusted_os.pem
+endif
+
+endif
+TF_MBEDTLS_KEY_ALG 	:=	ecdsa
+MBEDTLS_CONFIG_FILE	?=	"<stm32mp1_mbedtls_config.h>"
+
+include drivers/auth/mbedtls/mbedtls_x509.mk
+
+COT_DESC_IN_DTB		:=	1
+AUTH_SOURCES		+=	lib/fconf/fconf_cot_getter.c				\
+				lib/fconf/fconf_tbbr_getter.c				\
+				plat/st/common/stm32mp_crypto_lib.c
+
+ifeq ($(STM32MP13),1)
+AUTH_SOURCES		+=	drivers/st/crypto/stm32_pka.c
+AUTH_SOURCES		+=	drivers/st/crypto/stm32_saes.c
+endif
+
+BL2_SOURCES		+=	$(AUTH_SOURCES)						\
+				plat/st/common/stm32mp_trusted_boot.c
 endif
 
 ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),)
@@ -451,13 +505,6 @@
 		false; \
 	fi
 
-ifeq ($(STM32MP_USE_STM32IMAGE)-$(AARCH32_SP),1-sp_min)
-${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%.dtb plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP}
-	@echo "  AS      stm32mp1.S"
-	${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
-		-DDTB_BIN_PATH=\"$<\" \
-		-c $(word 2,$^) -o $@
-else
 # Create DTB file for BL2
 ${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs
 	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
@@ -479,7 +526,6 @@
 	${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
 		-DDTB_BIN_PATH=\"$<\" \
 		-c plat/st/stm32mp1/stm32mp1.S -o $@
-endif
 
 $(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,bl2))
 
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index c3fc2cb..1d754d9 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -10,11 +10,9 @@
 
 SP_MIN_WITH_SECURE_FIQ	:=	1
 
-ifneq ($(STM32MP_USE_STM32IMAGE),1)
 override ENABLE_PIE	:=	1
 BL32_CFLAGS		+=	-fpie -DENABLE_PIE
 BL32_LDFLAGS		+=	$(PIE_LDFLAGS)
-endif
 
 BL32_CFLAGS		+=	-DSTM32MP_SHARED_RESOURCES
 
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index 325666f..50b0794 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -115,11 +115,7 @@
 				  u_register_t arg2, u_register_t arg3)
 {
 	bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
-#if STM32MP_USE_STM32IMAGE
-	uintptr_t dt_addr = STM32MP_DTB_BASE;
-#else
 	uintptr_t dt_addr = arg1;
-#endif
 
 	stm32mp_setup_early_console();
 
diff --git a/plat/st/stm32mp1/stm32mp1.S b/plat/st/stm32mp1/stm32mp1.S
index 85caa0a..aee4f0e 100644
--- a/plat/st/stm32mp1/stm32mp1.S
+++ b/plat/st/stm32mp1/stm32mp1.S
@@ -1,16 +1,9 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#if STM32MP_USE_STM32IMAGE
-#ifdef BL32_BIN_PATH
-.section .bl32_image
-.incbin BL32_BIN_PATH
-#endif
-#endif /* STM32MP_USE_STM32IMAGE */
-
 .section .bl2_image
 .incbin BL2_BIN_PATH
 
diff --git a/plat/st/stm32mp1/stm32mp1.ld.S b/plat/st/stm32mp1/stm32mp1.ld.S
index 2254fee..1be8219 100644
--- a/plat/st/stm32mp1/stm32mp1.ld.S
+++ b/plat/st/stm32mp1/stm32mp1.ld.S
@@ -43,11 +43,7 @@
          * The strongest and only alignment contraint is MMU 4K page.
          * Indeed as images below will be removed, 4K pages will be re-used.
          */
-#if STM32MP_USE_STM32IMAGE
-        . = ( STM32MP_DTB_BASE - STM32MP_BINARY_BASE );
-#else
         . = ( STM32MP_BL2_DTB_BASE - STM32MP_BINARY_BASE );
-#endif /* STM32MP_USE_STM32IMAGE */
         __DTB_IMAGE_START__ = .;
         *(.dtb_image*)
         __DTB_IMAGE_END__ = .;
@@ -66,18 +62,6 @@
         *(.bl2_image*)
         __BL2_IMAGE_END__ = .;
 
-#if STM32MP_USE_STM32IMAGE && !defined(AARCH32_SP_OPTEE)
-        /*
-         * bl32 will be settled by bl2.
-         * The strongest and only alignment constraint is 8 words to simplify
-         * memraise8 assembly code.
-         */
-        . = ( STM32MP_BL32_BASE - STM32MP_BINARY_BASE );
-        __BL32_IMAGE_START__ = .;
-        *(.bl32_image*)
-        __BL32_IMAGE_END__ = .;
-#endif /* STM32MP_USE_STM32IMAGE && !defined(AARCH32_SP_OPTEE) */
-
         __DATA_END__ = .;
     } >RAM
 
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index a74d58c..f0d8526 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -19,7 +19,6 @@
 #include <drivers/st/stm32mp1_clk.h>
 
 #include <boot_api.h>
-#include <stm32mp_auth.h>
 #include <stm32mp_common.h>
 #include <stm32mp_dt.h>
 #include <stm32mp1_dbgmcu.h>
@@ -27,11 +26,7 @@
 #include <stm32mp1_shared_resources.h>
 #endif
 
-#if !STM32MP_USE_STM32IMAGE
 #include "stm32mp1_fip_def.h"
-#else /* STM32MP_USE_STM32IMAGE */
-#include "stm32mp1_stm32image_def.h"
-#endif /* STM32MP_USE_STM32IMAGE */
 
 /*******************************************************************************
  * CHIP ID
@@ -451,6 +446,8 @@
 #endif
 #define MONOTONIC_OTP			"monotonic_otp"
 #define UID_OTP				"uid_otp"
+#define PKH_OTP				"pkh_otp"
+#define ENCKEY_OTP			"enckey_otp"
 #define BOARD_ID_OTP			"board_id"
 
 /* OTP mask */
@@ -551,6 +548,7 @@
  ******************************************************************************/
 #define TAMP_BASE			U(0x5C00A000)
 #define TAMP_BKP_REGISTER_BASE		(TAMP_BASE + U(0x100))
+#define TAMP_COUNTR			U(0x40)
 
 #if !(defined(__LINKER__) || defined(__ASSEMBLER__))
 static inline uintptr_t tamp_bkpr(uint32_t idx)
diff --git a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
index f2568ab..7d99564 100644
--- a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
+++ b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
@@ -99,15 +99,16 @@
 
 	/* Locate the memory cells and read all values */
 	for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
+		uint32_t idx = i * STM32MP_REGION_PARAMS;
 		uint32_t base;
 		uint32_t size;
 		uint32_t sec_attr;
 		uint32_t nsaid;
 
-		base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
-		size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
-		sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
-		nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);
+		base = fdt32_to_cpu(conf_list->id_attr[idx]);
+		size = fdt32_to_cpu(conf_list->id_attr[idx + 1]);
+		sec_attr = fdt32_to_cpu(conf_list->id_attr[idx + 2]);
+		nsaid = fdt32_to_cpu(conf_list->id_attr[idx + 3]);
 
 		VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
 			base, size, sec_attr, nsaid);
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
index 5652597..4098386 100644
--- a/plat/st/stm32mp1/stm32mp1_fip_def.h
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -15,14 +15,36 @@
 #define STM32MP_DDR_SHMEM_SIZE		U(0)		/* empty */
 #endif
 
+#if TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP
+#if STM32MP15
+#define STM32MP_BL2_RO_SIZE		U(0x00014000)	/* 80 KB */
+#define STM32MP_BL2_SIZE		U(0x0001B000)	/* 108 KB for BL2 */
+#endif /* STM32MP15 */
+#else /* TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP */
 #if STM32MP13
+#if BL2_IN_XIP_MEM
 #define STM32MP_BL2_RO_SIZE		U(0x00015000)	/* 84 KB */
 #define STM32MP_BL2_SIZE		U(0x00017000)	/* 92 KB for BL2 */
-#define STM32MP_BL2_DTB_SIZE		U(0x00004000)	/* 16 KB for DTB */
+#else
+/* STM32MP_BL2_RO_SIZE not used if !BL2_IN_XIP_MEM */
+#define STM32MP_BL2_SIZE		U(0x0001B000)	/* 108KB for BL2 */
+					/* with 20KB for DTB, SYSRAM is full */
+#endif
 #endif /* STM32MP13 */
 #if STM32MP15
 #define STM32MP_BL2_RO_SIZE		U(0x00011000)	/* 68 KB */
 #define STM32MP_BL2_SIZE		U(0x00016000)	/* 88 KB for BL2 */
+#endif /* STM32MP15 */
+#endif /* TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP */
+
+#if STM32MP13
+#if TRUSTED_BOARD_BOOT
+#define STM32MP_BL2_DTB_SIZE		U(0x00005000)	/* 20 KB for DTB */
+#else /* TRUSTED_BOARD_BOOT */
+#define STM32MP_BL2_DTB_SIZE		U(0x00004000)	/* 16 KB for DTB */
+#endif /* TRUSTED_BOARD_BOOT */
+#endif /* STM32MP13 */
+#if STM32MP15
 #define STM32MP_BL2_DTB_SIZE		U(0x00007000)	/* 28 KB for DTB */
 #endif /* STM32MP15 */
 #define STM32MP_BL32_SIZE		U(0x0001B000)	/* 108 KB for BL32 */
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index c40e045..e6cb071 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -140,14 +140,14 @@
 uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
 {
 #if STM32MP13
-	assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
+	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return GPIOZ_BASE;
 	}
 
-	assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
+	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
 #endif
 
 	return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
@@ -156,14 +156,14 @@
 uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
 {
 #if STM32MP13
-	assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
+	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return 0;
 	}
 
-	assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
+	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
 #endif
 
 	return bank * GPIO_BANK_OFFSET;
@@ -186,14 +186,14 @@
 unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
 {
 #if STM32MP13
-	assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
+	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return GPIOZ;
 	}
 
-	assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
+	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
 #endif
 
 	return GPIOA + (bank - GPIO_BANK_A);
@@ -378,7 +378,7 @@
 
 void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
 {
-	char *cpu_s, *cpu_r, *pkg;
+	const char *cpu_s, *cpu_r, *pkg;
 
 	/* MPUs Part Numbers */
 	switch (get_part_number()) {
@@ -697,29 +697,6 @@
 }
 #endif
 
-#if STM32MP_USE_STM32IMAGE
-/* Get the non-secure DDR size */
-uint32_t stm32mp_get_ddr_ns_size(void)
-{
-	static uint32_t ddr_ns_size;
-	uint32_t ddr_size;
-
-	if (ddr_ns_size != 0U) {
-		return ddr_ns_size;
-	}
-
-	ddr_size = dt_get_ddr_size();
-	if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
-	    (ddr_size > STM32MP_DDR_MAX_SIZE)) {
-		panic();
-	}
-
-	ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
-
-	return ddr_ns_size;
-}
-#endif /* STM32MP_USE_STM32IMAGE */
-
 void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
 {
 	uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
@@ -767,7 +744,7 @@
 	clk_disable(RTCAPB);
 }
 
-#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
 void stm32mp1_fwu_set_boot_idx(void)
 {
 	clk_enable(RTCAPB);
@@ -808,4 +785,4 @@
 			   TAMP_BOOT_FWU_INFO_CNT_MSK);
 	clk_disable(RTCAPB);
 }
-#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c
deleted file mode 100644
index c84bffc..0000000
--- a/plat/st/stm32mp1/stm32mp1_security.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdint.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <drivers/arm/tzc400.h>
-#include <drivers/clk.h>
-#include <drivers/st/stm32mp1_clk.h>
-#include <dt-bindings/clock/stm32mp1-clks.h>
-#include <dt-bindings/soc/stm32mp15-tzc400.h>
-#include <lib/mmio.h>
-
-static unsigned int region_nb;
-
-static void init_tzc400_begin(unsigned int region0_attr)
-{
-	tzc400_init(STM32MP1_TZC_BASE);
-	tzc400_disable_filters();
-
-	/* Region 0 set to cover all DRAM at 0xC000_0000 */
-	tzc400_configure_region0(region0_attr, 0);
-
-	region_nb = 1U;
-}
-
-static void init_tzc400_end(unsigned int action)
-{
-	tzc400_set_action(action);
-	tzc400_enable_filters();
-}
-
-static void tzc400_add_region(unsigned long long region_base,
-			      unsigned long long region_top, bool sec)
-{
-	unsigned int sec_attr;
-	unsigned int nsaid_permissions;
-
-	if (sec) {
-		sec_attr = TZC_REGION_S_RDWR;
-		nsaid_permissions = 0;
-	} else {
-		sec_attr = TZC_REGION_S_NONE;
-		nsaid_permissions = TZC_REGION_NSEC_ALL_ACCESS_RDWR;
-	}
-
-	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, region_nb, region_base,
-				region_top, sec_attr, nsaid_permissions);
-
-	region_nb++;
-}
-
-/*******************************************************************************
- * Initialize the TrustZone Controller. Configure Region 0 with Secure RW access
- * and allow Non-Secure masters full access.
- ******************************************************************************/
-static void init_tzc400(void)
-{
-	unsigned long long region_base, region_top;
-	unsigned long long ddr_base = STM32MP_DDR_BASE;
-	unsigned long long ddr_ns_size =
-		(unsigned long long)stm32mp_get_ddr_ns_size();
-	unsigned long long ddr_ns_top = ddr_base + (ddr_ns_size - 1U);
-	unsigned long long ddr_top __unused;
-
-	init_tzc400_begin(TZC_REGION_S_NONE);
-
-	/*
-	 * Region 1 set to cover all non-secure DRAM at 0xC000_0000. Apply the
-	 * same configuration to all filters in the TZC.
-	 */
-	region_base = ddr_base;
-	region_top = ddr_ns_top;
-	tzc400_add_region(region_base, region_top, false);
-
-#ifdef AARCH32_SP_OPTEE
-	/* Region 2 set to cover all secure DRAM. */
-	region_base = region_top + 1U;
-	region_top += STM32MP_DDR_S_SIZE;
-	tzc400_add_region(region_base, region_top, true);
-
-	ddr_top = STM32MP_DDR_BASE + dt_get_ddr_size() - 1U;
-	if (region_top < ddr_top) {
-		/* Region 3 set to cover non-secure memory DRAM after BL32. */
-		region_base = region_top + 1U;
-		region_top = ddr_top;
-		tzc400_add_region(region_base, region_top, false);
-	}
-#endif
-
-	/*
-	 * Raise an interrupt (secure FIQ) if a NS device tries to access
-	 * secure memory
-	 */
-	init_tzc400_end(TZC_ACTION_INT);
-}
-
-/*******************************************************************************
- * Initialize the TrustZone Controller.
- * Early initialization create only one region with full access to secure.
- * This setting is used before and during DDR initialization.
- ******************************************************************************/
-static void early_init_tzc400(void)
-{
-	clk_enable(TZC1);
-	clk_enable(TZC2);
-
-	/* Region 0 set to cover all DRAM secure at 0xC000_0000 */
-	init_tzc400_begin(TZC_REGION_S_RDWR);
-
-	/* Raise an exception if a NS device tries to access secure memory */
-	init_tzc400_end(TZC_ACTION_ERR);
-}
-
-/*******************************************************************************
- * Initialize the secure environment. At this moment only the TrustZone
- * Controller is initialized.
- ******************************************************************************/
-void stm32mp1_arch_security_setup(void)
-{
-	early_init_tzc400();
-}
-
-/*******************************************************************************
- * Initialize the secure environment. At this moment only the TrustZone
- * Controller is initialized.
- ******************************************************************************/
-void stm32mp1_security_setup(void)
-{
-	init_tzc400();
-}
diff --git a/plat/st/stm32mp1/stm32mp1_stm32image_def.h b/plat/st/stm32mp1/stm32mp1_stm32image_def.h
deleted file mode 100644
index 6260cb9..0000000
--- a/plat/st/stm32mp1/stm32mp1_stm32image_def.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2021-2022, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STM32MP1_STM32IMAGE_DEF_H
-#define STM32MP1_STM32IMAGE_DEF_H
-
-#ifdef AARCH32_SP_OPTEE
-#if STM32MP15_OPTEE_RSV_SHM
-#define STM32MP_DDR_S_SIZE		U(0x01E00000)	/* 30 MB */
-#define STM32MP_DDR_SHMEM_SIZE		U(0x00200000)	/* 2 MB */
-#else
-#define STM32MP_DDR_S_SIZE		U(0x02000000)	/* 32 MB */
-#define STM32MP_DDR_SHMEM_SIZE		U(0)		/* empty */
-#endif
-#else
-#define STM32MP_DDR_S_SIZE		U(0)
-#define STM32MP_DDR_SHMEM_SIZE		U(0)
-#endif
-
-#define STM32MP_BL2_SIZE		U(0x0001C000)	/* 112 KB for BL2 */
-#define STM32MP_DTB_SIZE		U(0x00006000)	/* 24 KB for DTB */
-
-#ifdef AARCH32_SP_OPTEE
-#define STM32MP_BL32_BASE		STM32MP_SEC_SYSRAM_BASE
-
-#define STM32MP_BL2_BASE		(STM32MP_SEC_SYSRAM_BASE + \
-					 STM32MP_SEC_SYSRAM_SIZE - \
-					 STM32MP_BL2_SIZE)
-
-/* OP-TEE loads from SYSRAM base to BL2 DTB start address */
-#define STM32MP_OPTEE_BASE		STM32MP_BL32_BASE
-#define STM32MP_OPTEE_SIZE		(STM32MP_SEC_SYSRAM_SIZE -  \
-					 STM32MP_BL2_SIZE - STM32MP_DTB_SIZE)
-#define STM32MP_BL32_SIZE		STM32MP_OPTEE_SIZE
-#else /* AARCH32_SP_OPTEE */
-#define STM32MP_BL32_SIZE		U(0x00019000)	/* 96 KB for BL32 */
-
-#define STM32MP_BL32_BASE		(STM32MP_SEC_SYSRAM_BASE + \
-					 STM32MP_SEC_SYSRAM_SIZE - \
-					 STM32MP_BL32_SIZE)
-
-#define STM32MP_BL2_BASE		(STM32MP_BL32_BASE - \
-					 STM32MP_BL2_SIZE)
-#endif /* AARCH32_SP_OPTEE */
-
-/* DTB initialization value */
-#define STM32MP_DTB_BASE		(STM32MP_BL2_BASE -	\
-					 STM32MP_DTB_SIZE)
-
-/*
- * MAX_MMAP_REGIONS is usually:
- * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup
- */
-#if defined(IMAGE_BL32)
-#define MAX_MMAP_REGIONS		6
-#endif
-
-/*******************************************************************************
- * STM32MP1 RAW partition offset for MTD devices
- ******************************************************************************/
-#define STM32MP_NOR_BL33_OFFSET		U(0x00080000)
-#ifdef AARCH32_SP_OPTEE
-#define STM32MP_NOR_TEEH_OFFSET		U(0x00280000)
-#define STM32MP_NOR_TEED_OFFSET		U(0x002C0000)
-#define STM32MP_NOR_TEEX_OFFSET		U(0x00300000)
-#endif
-
-#define STM32MP_NAND_BL33_OFFSET	U(0x00200000)
-#ifdef AARCH32_SP_OPTEE
-#define STM32MP_NAND_TEEH_OFFSET	U(0x00600000)
-#define STM32MP_NAND_TEED_OFFSET	U(0x00680000)
-#define STM32MP_NAND_TEEX_OFFSET	U(0x00700000)
-#endif
-
-#endif /* STM32MP1_STM32IMAGE_DEF_H */
diff --git a/plat/st/stm32mp1/stm32mp1_syscfg.c b/plat/st/stm32mp1/stm32mp1_syscfg.c
index ff79428..75dd709 100644
--- a/plat/st/stm32mp1/stm32mp1_syscfg.c
+++ b/plat/st/stm32mp1/stm32mp1_syscfg.c
@@ -235,7 +235,9 @@
 	}
 
 	if (apply_hslv) {
-		mmio_write_32(SYSCFG_BASE + SYSCFG_HSLVEN0R + index * sizeof(uint32_t), HSLV_KEY);
+		uint32_t reg_offset = index * sizeof(uint32_t);
+
+		mmio_write_32(SYSCFG_BASE + SYSCFG_HSLVEN0R + reg_offset, HSLV_KEY);
 	}
 }
 #endif
diff --git a/plat/st/stm32mp1/stm32mp1_tbb_cert.c b/plat/st/stm32mp1/stm32mp1_tbb_cert.c
new file mode 100644
index 0000000..0e77397
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_tbb_cert.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "tbbr/tbb_ext.h"
+#include "tbbr/tbb_key.h"
+
+#include "tbbr/stm32mp1_tbb_cert.h"
+
+/*
+ * Certificates used in the chain of trust
+ *
+ * The order of the certificates must follow the enumeration specified in
+ * stm32mp1_tbb_cert.h. All certificates are self-signed, so the issuer certificate
+ * field points to itself.
+ */
+static cert_t stm32mp1_tbb_certs[] = {
+	[0] = {
+		.id = STM32MP_CONFIG_CERT,
+		.opt = "stm32mp-cfg-cert",
+		.help_msg = "STM32MP Config Certificate (output file)",
+		.fn = NULL,
+		.cn = "STM32MP config FW Certificate",
+		.key = ROT_KEY,
+		.issuer = STM32MP_CONFIG_CERT,
+		.ext = {
+			TRUSTED_FW_NVCOUNTER_EXT,
+			HW_CONFIG_HASH_EXT,
+			FW_CONFIG_HASH_EXT
+		},
+		.num_ext = 3
+	},
+};
+
+PLAT_REGISTER_COT(stm32mp1_tbb_certs);
diff --git a/plat/xilinx/common/include/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h
index 8a15668..52dfc47 100644
--- a/plat/xilinx/common/include/pm_ipi.h
+++ b/plat/xilinx/common/include/pm_ipi.h
@@ -16,7 +16,7 @@
 #define IPI_BLOCKING		1
 #define IPI_NON_BLOCKING	0
 
-int32_t pm_ipi_init(const struct pm_proc *proc);
+void pm_ipi_init(const struct pm_proc *proc);
 
 enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
 			       uint32_t payload[PAYLOAD_ARG_CNT]);
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index cb6aaa5..8438aba 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -21,7 +21,6 @@
 #include <plat_private.h>
 
 #include "ipi_mailbox_svc.h"
-#include "../../../services/spd/trusty/smcall.h"
 
 /*********************************************************************
  * Macros definitions
@@ -75,17 +74,23 @@
 	ipi_local_id = x1 & UNSIGNED32_MASK;
 	ipi_remote_id = x2 & UNSIGNED32_MASK;
 
-	if (SMC_ENTITY(smc_fid) >= SMC_ENTITY_TRUSTED_APP)
+	/* OEN Number 48 to 63 is for Trusted App and OS
+	 * GET_SMC_OEN limits the return value of OEN number to 63 by bitwise
+	 * AND operation with 0x3F.
+	 * Upper limit check for OEN value is not required.
+	 */
+	if (GET_SMC_OEN(smc_fid) >= OEN_TAP_START) {
 		is_secure = 1;
-	else
+	} else {
 		is_secure = 0;
+	}
 
 	/* Validate IPI mailbox access */
 	ret = ipi_mb_validate(ipi_local_id, ipi_remote_id, is_secure);
 	if (ret)
 		SMC_RET1(handle, ret);
 
-	switch (SMC_FUNCTION(smc_fid)) {
+	switch (GET_SMC_NUM(smc_fid)) {
 	case IPI_MAILBOX_OPEN:
 		ipi_mb_open(ipi_local_id, ipi_remote_id);
 		SMC_RET1(handle, 0);
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index a0403cf..513d6be 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -19,6 +19,7 @@
 #include "pm_ipi.h"
 
 #define ERROR_CODE_MASK		(0xFFFFU)
+#define PM_OFFSET		(0U)
 
 DEFINE_BAKERY_LOCK(pm_secure_lock);
 
@@ -33,12 +34,10 @@
  *
  * Called from pm_setup initialization function
  */
-int32_t pm_ipi_init(const struct pm_proc *proc)
+void pm_ipi_init(const struct pm_proc *proc)
 {
 	bakery_lock_init(&pm_secure_lock);
 	ipi_mb_open(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
-
-	return 0;
 }
 
 /**
@@ -55,7 +54,7 @@
 					     uint32_t payload[PAYLOAD_ARG_CNT],
 					     uint32_t is_blocking)
 {
-	unsigned int offset = 0;
+	uint32_t offset = PM_OFFSET;
 	uintptr_t buffer_base = proc->ipi->buffer_base +
 					IPI_BUFFER_TARGET_REMOTE_OFFSET +
 					IPI_BUFFER_REQ_OFFSET;
@@ -185,7 +184,7 @@
 	size_t i;
 #if IPI_CRC_CHECK
 	size_t j;
-	unsigned int response_payload[PAYLOAD_ARG_CNT];
+	unsigned int response_payload[PAYLOAD_ARG_CNT] = {0};
 #endif
 	uintptr_t buffer_base = IPI_BUFFER_REMOTE_BASE +
 				IPI_BUFFER_TARGET_LOCAL_OFFSET +
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index ce5e533..54f4eb2 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -120,11 +120,9 @@
 {
 	uint32_t reg_num;
 	uint32_t device_id;
-	uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX];
+	uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = { 0U };
 	uintptr_t isenabler1 = PLAT_VERSAL_GICD_BASE + GICD_ISENABLER + 4;
 
-	zeromem(&pm_wakeup_nodes_set, (u_register_t)sizeof(pm_wakeup_nodes_set));
-
 	for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
 		uint32_t base_irq = reg_num << ISENABLER_SHIFT;
 		uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index 48888e4..c90f9e1 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -119,16 +119,10 @@
  */
 int32_t pm_setup(void)
 {
-	int32_t status, ret = 0;
+	int32_t ret = 0;
 
-	status = pm_ipi_init(primary_proc);
-
-	if (status < 0) {
-		INFO("BL31: PM Service Init Failed, Error Code %d!\n", status);
-		ret = status;
-	} else {
-		pm_up = true;
-	}
+	pm_ipi_init(primary_proc);
+	pm_up = true;
 
 	/*
 	 * Enable IPI IRQ
@@ -166,7 +160,7 @@
 
 	case PM_IOCTL:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 		ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
 				   pm_arg[3], pm_arg[4],
diff --git a/plat/xilinx/zynqmp/include/plat_ipi.h b/plat/xilinx/zynqmp/include/plat_ipi.h
index bccd2f1..a78f93a 100644
--- a/plat/xilinx/zynqmp/include/plat_ipi.h
+++ b/plat/xilinx/zynqmp/include/plat_ipi.h
@@ -41,7 +41,7 @@
 #define IPI_BUFFER_TARGET_LOCAL_OFFSET	0x80U
 #define IPI_BUFFER_TARGET_REMOTE_OFFSET	0x1C0U
 
-#define IPI_BUFFER_MAX_WORDS	8
+#define IPI_BUFFER_MAX_WORDS	8U
 
 #define IPI_BUFFER_REQ_OFFSET	0x0U
 #define IPI_BUFFER_RESP_OFFSET	0x20U
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index a853e38..7217fa1 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -176,7 +176,7 @@
 static void pm_client_set_wakeup_sources(void)
 {
 	uint32_t reg_num;
-	uint8_t pm_wakeup_nodes_set[NODE_MAX];
+	uint8_t pm_wakeup_nodes_set[NODE_MAX] = { 0 };
 	uintptr_t isenabler1 = BASE_GICD_BASE + GICD_ISENABLER + 4U;
 
 	/* In case of power-off suspend, only NODE_EXTERN must be set */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index b91878e..4adbef3 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -207,11 +207,16 @@
  */
 int32_t pm_setup(void)
 {
-	int32_t status, ret;
+	enum pm_ret_status err;
 
-	status = pm_ipi_init(primary_proc);
+	pm_ipi_init(primary_proc);
 
-	ret = pm_get_api_version(&pm_ctx.api_version);
+	err = pm_get_api_version(&pm_ctx.api_version);
+	if (err != PM_RET_SUCCESS) {
+		ERROR("BL31: Failed to read Platform Management API version. "
+		      "Return: %d\n", err);
+		return -EINVAL;
+	}
 	if (pm_ctx.api_version < PM_VERSION) {
 		ERROR("BL31: Platform Management API version error. Expected: "
 		      "v%d.%d - Found: v%d.%d\n", PM_VERSION_MAJOR,
@@ -220,6 +225,7 @@
 		return -EINVAL;
 	}
 
+	int32_t status = 0, ret = 0;
 #if ZYNQMP_WDT_RESTART
 	status = pm_wdt_restart_setup();
 	if (status)
@@ -263,7 +269,7 @@
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	uint32_t pm_arg[5];
-	uint32_t result[PAYLOAD_ARG_CNT];
+	uint32_t result[PAYLOAD_ARG_CNT] = {0};
 	uint32_t api_id;
 
 	/* Handle case where PM wasn't initialized properly */
@@ -350,7 +356,7 @@
 
 	case PM_FPGA_GET_STATUS:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 		ret = pm_fpga_get_status(&value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
@@ -368,7 +374,7 @@
 			 (uint64_t)result[2] | ((uint64_t)result[3] << 32));
 	case PM_IOCTL:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 		ret = pm_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
 			       pm_arg[3], &value);
@@ -395,7 +401,7 @@
 
 	case PM_CLOCK_GETSTATE:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 		ret = pm_clock_getstate(pm_arg[0], &value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
@@ -407,7 +413,7 @@
 
 	case PM_CLOCK_GETDIVIDER:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 		ret = pm_clock_getdivider(pm_arg[0], &value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
@@ -436,7 +442,7 @@
 
 	case PM_CLOCK_GETPARENT:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 		ret = pm_clock_getparent(pm_arg[0], &value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
@@ -470,7 +476,7 @@
 
 	case PM_FPGA_READ:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 		ret = pm_fpga_read(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
 				   &value);
@@ -479,7 +485,7 @@
 
 	case PM_SECURE_AES:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 		ret = pm_aes_engine(pm_arg[0], pm_arg[1], &value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
@@ -491,7 +497,7 @@
 
 	case PM_PLL_GET_PARAMETER:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 		ret = pm_pll_get_parameter(pm_arg[0], pm_arg[1], &value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32U));
@@ -503,7 +509,7 @@
 
 	case PM_PLL_GET_MODE:
 	{
-		uint32_t mode;
+		uint32_t mode = 0U;
 
 		ret = pm_pll_get_mode(pm_arg[0], &mode);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32U));
@@ -511,7 +517,7 @@
 
 	case PM_REGISTER_ACCESS:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 		ret = pm_register_access(pm_arg[0], pm_arg[1], pm_arg[2],
 					 pm_arg[3], &value);
@@ -520,7 +526,7 @@
 
 	case PM_EFUSE_ACCESS:
 	{
-		uint32_t value;
+		uint32_t value = 0U;
 
 #if defined(ZYNQMP_SECURE_EFUSES)
 		if (is_caller_non_secure(flags)) {
diff --git a/services/std_svc/rmmd/trp/trp_entry.S b/services/std_svc/rmmd/trp/trp_entry.S
index 47c1df1..3e1d8c9 100644
--- a/services/std_svc/rmmd/trp/trp_entry.S
+++ b/services/std_svc/rmmd/trp/trp_entry.S
@@ -83,7 +83,17 @@
 	mov	x3, x23
 	bl	trp_setup
 	bl	trp_main
+	b	1f
+
 warm_boot:
+	mov	x0, x20
+	mov	x1, x21
+	mov	x2, x22
+	mov	x3, x23
+	bl	trp_validate_warmboot_args
+	cbnz	x0, trp_panic /* Failed to validate warmboot args */
+
+1:
 	mov_imm	x0, RMM_BOOT_COMPLETE
 	mov	x1, xzr /* RMM_BOOT_SUCCESS */
 	smc	#0
@@ -115,7 +125,29 @@
 	 * ---------------------------------------------
 	 */
 func trp_handler
+	/*
+	 * Save Link Register and X4, as per SMCCC v1.2 its value
+	 * must be preserved unless it contains result, as specified
+	 * in the function definition.
+	 */
+	stp	x4, lr, [sp, #-16]!
+
+	/*
+	 * Zero the space for X0-X3 in trp_smc_result structure
+	 * and pass its address as the last argument.
+	 */
+	stp	xzr, xzr, [sp, #-16]!
+	stp	xzr, xzr, [sp, #-16]!
+	mov	x7, sp
+
 	bl	trp_rmi_handler
-	restore_args_call_smc
+
+	ldp	x1, x2, [sp], #16
+	ldp	x3, x4, [sp], #16
+	ldp	x5, lr, [sp], #16
+
+	ldr	x0, =RMM_RMI_REQ_COMPLETE
+	smc	#0
+
 	b	trp_handler
 endfunc trp_handler
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 5a56af0..196bc11 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -4,7 +4,6 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-
 #include <common/debug.h>
 #include <plat/common/platform.h>
 #include <services/rmm_core_manifest.h>
@@ -31,11 +30,11 @@
 	       uint64_t x3)
 {
 	/*
-	 * Validate boot parameters.
+	 * Validate boot parameters
 	 *
-	 * According to the Boot Interface ABI v.0.1, the
-	 * parameters recived from EL3 are:
-	 * x0: CPUID (verified earlier so not used)
+	 * According to the Boot Interface ABI v.0.1,
+	 * the parameters received from EL3 are:
+	 * x0: CPUID (verified earlier, so not used)
 	 * x1: Boot Interface version
 	 * x2: PLATFORM_CORE_COUNT
 	 * x3: Pointer to the shared memory area.
@@ -66,6 +65,24 @@
 	trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start);
 }
 
+int trp_validate_warmboot_args(uint64_t x0, uint64_t x1,
+			       uint64_t x2, uint64_t x3)
+{
+	/*
+	 * Validate boot parameters for warm boot
+	 *
+	 * According to the Boot Interface ABI v.0.1, the parameters
+	 * received from EL3 during warm boot are:
+	 *
+	 * x0: CPUID (verified earlier so not used here)
+	 * [x1:x3]: RES0
+	 */
+
+	(void)x0;
+
+	return ((x1 | x2 | x3) == 0UL) ? 0 : E_RMM_BOOT_UNKNOWN;
+}
+
 /* Main function for TRP */
 void trp_main(void)
 {
@@ -73,14 +90,14 @@
 	NOTICE("TRP: %s\n", build_message);
 	NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
 		TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
-	NOTICE("TRP: Boot Manifest Version : v.%u.%u\n",
+	NOTICE("TRP: Boot Manifest Version: v.%u.%u\n",
 		RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version),
 		RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version));
-	INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE);
-	INFO("TRP: Base address for the shared region : 0x%lx\n",
+	INFO("TRP: Memory base: 0x%lx\n", (unsigned long)RMM_BASE);
+	INFO("TRP: Shared region base address: 0x%lx\n",
 			(unsigned long)trp_shared_region_start);
-	INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END
-								- RMM_BASE));
+	INFO("TRP: Total size: 0x%lx bytes\n",
+			(unsigned long)(RMM_END - RMM_BASE));
 	INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n",
 		TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version),
 		TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version));
@@ -89,62 +106,73 @@
 /*******************************************************************************
  * Returning RMI version back to Normal World
  ******************************************************************************/
-static trp_args_t *trp_ret_rmi_version(void)
+static void trp_ret_rmi_version(struct trp_smc_result *smc_ret)
 {
 	VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
 					  RMI_ABI_VERSION_MINOR);
-	return set_smc_args(RMM_RMI_REQ_COMPLETE, RMI_ABI_VERSION,
-			    0, 0, 0, 0, 0, 0);
+	smc_ret->x[0] = RMI_ABI_VERSION;
 }
 
 /*******************************************************************************
  * Transitioning granule of NON-SECURE type to REALM type
  ******************************************************************************/
-static trp_args_t *trp_asc_mark_realm(unsigned long long x1)
+static void trp_asc_mark_realm(unsigned long long x1,
+				struct trp_smc_result *smc_ret)
 {
-	unsigned long long ret;
-
 	VERBOSE("Delegating granule 0x%llx\n", x1);
-	ret = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1, 0, 0, 0, 0, 0, 0));
+	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1,
+						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
 
-	if (ret != 0ULL) {
+	if (smc_ret->x[0] != 0ULL) {
 		ERROR("Granule transition from NON-SECURE type to REALM type "
-			"failed 0x%llx\n", ret);
+			"failed 0x%llx\n", smc_ret->x[0]);
 	}
-	return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
 }
 
 /*******************************************************************************
  * Transitioning granule of REALM type to NON-SECURE type
  ******************************************************************************/
-static trp_args_t *trp_asc_mark_nonsecure(unsigned long long x1)
+static void trp_asc_mark_nonsecure(unsigned long long x1,
+				   struct trp_smc_result *smc_ret)
 {
-	unsigned long long ret;
-
 	VERBOSE("Undelegating granule 0x%llx\n", x1);
-	ret = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1, 0, 0, 0, 0, 0, 0));
+	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1,
+						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
 
-	if (ret != 0ULL) {
+	if (smc_ret->x[0] != 0ULL) {
 		ERROR("Granule transition from REALM type to NON-SECURE type "
-			"failed 0x%llx\n", ret);
+			"failed 0x%llx\n", smc_ret->x[0]);
 	}
-	return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
 }
 
 /*******************************************************************************
  * Main RMI SMC handler function
  ******************************************************************************/
-trp_args_t *trp_rmi_handler(unsigned long fid, unsigned long long x1)
+void trp_rmi_handler(unsigned long fid,
+		     unsigned long long x1, unsigned long long x2,
+		     unsigned long long x3, unsigned long long x4,
+		     unsigned long long x5, unsigned long long x6,
+		     struct trp_smc_result *smc_ret)
 {
+	/* Not used in the current implementation */
+	(void)x2;
+	(void)x3;
+	(void)x4;
+	(void)x5;
+	(void)x6;
+
 	switch (fid) {
 	case RMI_RMM_REQ_VERSION:
-		return trp_ret_rmi_version();
+		trp_ret_rmi_version(smc_ret);
+		break;
 	case RMI_RMM_GRANULE_DELEGATE:
-		return trp_asc_mark_realm(x1);
+		trp_asc_mark_realm(x1, smc_ret);
+		break;
 	case RMI_RMM_GRANULE_UNDELEGATE:
-		return trp_asc_mark_nonsecure(x1);
+		trp_asc_mark_nonsecure(x1, smc_ret);
+		break;
 	default:
-		ERROR("Invalid SMC code to %s, FID %lu\n", __func__, fid);
+		ERROR("Invalid SMC code to %s, FID %lx\n", __func__, fid);
+		smc_ret->x[0] = SMC_UNK;
 	}
-	return set_smc_args(SMC_UNK, 0, 0, 0, 0, 0, 0, 0);
 }
diff --git a/services/std_svc/rmmd/trp/trp_private.h b/services/std_svc/rmmd/trp/trp_private.h
index 945ae1c..d8c6960 100644
--- a/services/std_svc/rmmd/trp/trp_private.h
+++ b/services/std_svc/rmmd/trp/trp_private.h
@@ -53,5 +53,9 @@
 	       uint64_t x2,
 	       uint64_t x3);
 
+/* Validate arguments for warm boot only */
+int trp_validate_warmboot_args(uint64_t x0, uint64_t x1,
+			       uint64_t x2, uint64_t x3);
+
 #endif /* __ASSEMBLER__ */
 #endif /* TRP_PRIVATE_H */
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
index 5233650..61afee3 100644
--- a/services/std_svc/spm/el3_spmc/spmc.h
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -228,6 +228,12 @@
 	uint32_t uuid[4];
 };
 
+/* FF-A Partition Info Get related macros. */
+#define FFA_PARTITION_INFO_GET_PROPERTIES_V1_0_MASK	U(0x7)
+#define FFA_PARTITION_INFO_GET_EXEC_STATE_SHIFT 	U(8)
+#define FFA_PARTITION_INFO_GET_AARCH32_STATE 		U(0)
+#define FFA_PARTITION_INFO_GET_AARCH64_STATE 		U(1)
+
 /* Reference to power management hooks */
 extern const spd_pm_ops_t spmc_pm;
 
diff --git a/services/std_svc/spm/el3_spmc/spmc.mk b/services/std_svc/spm/el3_spmc/spmc.mk
index c674e71..6442af0 100644
--- a/services/std_svc/spm/el3_spmc/spmc.mk
+++ b/services/std_svc/spm/el3_spmc/spmc.mk
@@ -20,7 +20,9 @@
                     ${PLAT}_el3_spmc_logical_sp.c)
 
 
+ifneq ($(wildcard $(SPMC_LP_SOURCES)),)
 SPMC_SOURCES += $(SPMC_LP_SOURCES)
+endif
 
 # Let the top-level Makefile know that we intend to include a BL32 image
 NEED_BL32		:=	yes
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index 9b8621a..08e7218 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -746,6 +746,27 @@
 }
 
 /*
+ * Helper function to populate the properties field of a Partition Info Get
+ * descriptor.
+ */
+static uint32_t
+partition_info_get_populate_properties(uint32_t sp_properties,
+				       enum sp_execution_state sp_ec_state)
+{
+	uint32_t properties = sp_properties;
+	uint32_t ec_state;
+
+	/* Determine the execution state of the SP. */
+	ec_state = sp_ec_state == SP_STATE_AARCH64 ?
+		   FFA_PARTITION_INFO_GET_AARCH64_STATE :
+		   FFA_PARTITION_INFO_GET_AARCH32_STATE;
+
+	properties |= ec_state << FFA_PARTITION_INFO_GET_EXEC_STATE_SHIFT;
+
+	return properties;
+}
+
+/*
  * Collate the partition information in a v1.1 partition information
  * descriptor format, this will be converter later if required.
  */
@@ -771,7 +792,12 @@
 			desc = &partitions[*partition_count];
 			desc->ep_id = el3_lp_descs[index].sp_id;
 			desc->execution_ctx_count = PLATFORM_CORE_COUNT;
-			desc->properties = el3_lp_descs[index].properties;
+			/* LSPs must be AArch64. */
+			desc->properties =
+				partition_info_get_populate_properties(
+					el3_lp_descs[index].properties,
+					SP_STATE_AARCH64);
+
 			if (null_uuid) {
 				copy_uuid(desc->uuid, el3_lp_descs[index].uuid);
 			}
@@ -794,7 +820,11 @@
 			 * S-EL1 SPs.
 			 */
 			desc->execution_ctx_count = PLATFORM_CORE_COUNT;
-			desc->properties = sp_desc[index].properties;
+			desc->properties =
+				partition_info_get_populate_properties(
+					sp_desc[index].properties,
+					sp_desc[index].execution_state);
+
 			if (null_uuid) {
 				copy_uuid(desc->uuid, sp_desc[index].uuid);
 			}
@@ -835,7 +865,7 @@
 
 /*
  * If the caller of the PARTITION_INFO_GET ABI was a v1.0 caller, populate
- * the coresponding descriptor format from the v1.1 descriptor array.
+ * the corresponding descriptor format from the v1.1 descriptor array.
  */
 static uint64_t partition_info_populate_v1_0(struct ffa_partition_info_v1_1
 					     *partitions,
@@ -860,8 +890,10 @@
 		v1_0_partitions[index].ep_id = partitions[index].ep_id;
 		v1_0_partitions[index].execution_ctx_count =
 			partitions[index].execution_ctx_count;
+		/* Only report v1.0 properties. */
 		v1_0_partitions[index].properties =
-			partitions[index].properties;
+			(partitions[index].properties &
+			FFA_PARTITION_INFO_GET_PROPERTIES_V1_0_MASK);
 	}
 	return 0;
 }
diff --git a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
index 89d7b31..c039350 100644
--- a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
+++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
@@ -274,13 +274,15 @@
  * spmc_shmem_obj_validate_id - Validate a partition ID is participating in
  *				a given memory transaction.
  * @sp_id:      Partition ID to validate.
- * @desc:       Descriptor of the memory transaction.
- *
+ * @obj:        The shared memory object containing the descriptor
+ *              of the memory transaction.
  * Return: true if ID is valid, else false.
  */
-bool spmc_shmem_obj_validate_id(const struct ffa_mtd *desc, uint16_t sp_id)
+bool spmc_shmem_obj_validate_id(struct spmc_shmem_obj *obj, uint16_t sp_id)
 {
 	bool found = false;
+	struct ffa_mtd *desc = &obj->desc;
+	size_t desc_size = obj->desc_size;
 
 	/* Validate the partition is a valid participant. */
 	for (unsigned int i = 0U; i < desc->emad_count; i++) {
@@ -290,6 +292,15 @@
 		emad = spmc_shmem_obj_get_emad(desc, i,
 					       MAKE_FFA_VERSION(1, 1),
 					       &emad_size);
+		/*
+		 * Validate the calculated emad address resides within the
+		 * descriptor.
+		 */
+		if ((emad == NULL) || (uintptr_t) emad >=
+		    (uintptr_t)((uint8_t *) desc + desc_size)) {
+			VERBOSE("Invalid emad.\n");
+			break;
+		}
 		if (sp_id == emad->mapd.endpoint_id) {
 			found = true;
 			break;
@@ -385,7 +396,8 @@
 	      emad_array[0].comp_mrd_offset);
 
 	/* Check the calculated address is within the memory descriptor. */
-	if ((uintptr_t) mrd >= (uintptr_t)((uint8_t *) orig + desc_size)) {
+	if (((uintptr_t) mrd + sizeof(struct ffa_comp_mrd)) >
+	    (uintptr_t)((uint8_t *) orig + desc_size)) {
 		return 0;
 	}
 	size += mrd->address_range_count * sizeof(struct ffa_cons_mrd);
@@ -424,7 +436,8 @@
 	      emad_array[0].comp_mrd_offset);
 
 	/* Check the calculated address is within the memory descriptor. */
-	if ((uintptr_t) mrd >= (uintptr_t)((uint8_t *) orig + desc_size)) {
+	if (((uintptr_t) mrd + sizeof(struct ffa_comp_mrd)) >
+	    (uintptr_t)((uint8_t *) orig + desc_size)) {
 		return 0;
 	}
 	size += mrd->address_range_count * sizeof(struct ffa_cons_mrd);
@@ -475,6 +488,12 @@
 
 	/* Copy across the emad structs. */
 	for (unsigned int i = 0U; i < out->emad_count; i++) {
+		/* Bound check for emad array. */
+		if (((uint8_t *)emad_array_in + sizeof(struct ffa_emad_v1_0)) >
+		    ((uint8_t *) mtd_orig + orig->desc_size)) {
+			VERBOSE("%s: Invalid mtd structure.\n", __func__);
+			return false;
+		}
 		memcpy(&emad_array_out[i], &emad_array_in[i],
 		       sizeof(struct ffa_emad_v1_0));
 	}
@@ -542,6 +561,7 @@
 	size_t mrd_out_offset;
 	size_t emad_out_array_size;
 	size_t mrd_size = 0;
+	size_t orig_desc_size = orig->desc_size;
 
 	/* Populate the v1.0 descriptor format from the v1.1 struct. */
 	out->sender_id = mtd_orig->sender_id;
@@ -559,6 +579,12 @@
 	/* Copy across the emad structs. */
 	emad_in = emad_array_in;
 	for (unsigned int i = 0U; i < out->emad_count; i++) {
+		/* Bound check for emad array. */
+		if (((uint8_t *)emad_in + sizeof(struct ffa_emad_v1_0)) >
+				((uint8_t *) mtd_orig + orig_desc_size)) {
+			VERBOSE("%s: Invalid mtd structure.\n", __func__);
+			return false;
+		}
 		memcpy(&emad_array_out[i], emad_in,
 		       sizeof(struct ffa_emad_v1_0));
 
@@ -1442,7 +1468,7 @@
 	}
 
 	/* Validate the caller is a valid participant. */
-	if (!spmc_shmem_obj_validate_id(&obj->desc, sp_ctx->sp_id)) {
+	if (!spmc_shmem_obj_validate_id(obj, sp_ctx->sp_id)) {
 		WARN("%s: Invalid endpoint ID (0x%x).\n",
 			__func__, sp_ctx->sp_id);
 		ret = FFA_ERROR_INVALID_PARAMETER;
@@ -1761,7 +1787,7 @@
 	}
 
 	/* Validate the caller is a valid participant. */
-	if (!spmc_shmem_obj_validate_id(&obj->desc, sp_ctx->sp_id)) {
+	if (!spmc_shmem_obj_validate_id(obj, sp_ctx->sp_id)) {
 		WARN("%s: Invalid endpoint ID (0x%x).\n",
 			__func__, req->endpoint_array[0]);
 		ret = FFA_ERROR_INVALID_PARAMETER;
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index d951286..042e844 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,12 +9,12 @@
 DEBUG		:= 0
 CRTTOOL		?= cert_create${BIN_EXT}
 BINARY		:= $(notdir ${CRTTOOL})
-OPENSSL_DIR	:= /usr
 COT		:= tbbr
 
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}defaults.mk
 
 ifneq (${PLAT},none)
 TF_PLATFORM_ROOT	:=	../../plat/
@@ -45,6 +45,10 @@
 include ${PLAT_CERT_CREATE_HELPER_MK}
 endif
 
+# Select OpenSSL version flag according to the OpenSSL build selected
+# from setting the OPENSSL_DIR path.
+$(eval $(call SELECT_OPENSSL_API_VERSION))
+
 HOSTCCFLAGS := -Wall -std=c99
 
 ifeq (${DEBUG},1)
@@ -60,6 +64,9 @@
 endif
 
 HOSTCCFLAGS += ${DEFINES}
+# USING_OPENSSL3 flag will be added to the HOSTCCFLAGS variable with the proper
+# computed value.
+HOSTCCFLAGS += -DUSING_OPENSSL3=$(USING_OPENSSL3)
 
 # Make soft links and include from local directory otherwise wrong headers
 # could get pulled in from firmware tree.
@@ -76,11 +83,11 @@
 
 HOSTCC ?= gcc
 
-.PHONY: all clean realclean
+.PHONY: all clean realclean --openssl
 
 all: ${BINARY}
 
-${BINARY}: ${OBJECTS} Makefile
+${BINARY}: --openssl ${OBJECTS} Makefile
 	@echo "  HOSTLD  $@"
 	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \
                 const char platform_msg[] = "${PLAT_MSG}";' | \
@@ -91,6 +98,11 @@
 	@echo "  HOSTCC  $<"
 	${Q}${HOSTCC} -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
+--openssl:
+ifeq ($(DEBUG),1)
+	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+endif
+
 clean:
 	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
 
diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h
index e63b474..5d39a88 100644
--- a/tools/cert_create/include/cert.h
+++ b/tools/cert_create/include/cert.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -54,6 +54,7 @@
 	int days,
 	int ca,
 	STACK_OF(X509_EXTENSION) * sk);
+void cert_cleanup(void);
 
 /* Macro to register the certificates used in the CoT */
 #define REGISTER_COT(_certs) \
diff --git a/tools/cert_create/include/ext.h b/tools/cert_create/include/ext.h
index e900a6d..0e7f3be 100644
--- a/tools/cert_create/include/ext.h
+++ b/tools/cert_create/include/ext.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -72,6 +72,7 @@
 		unsigned char *buf, size_t len);
 X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value);
 X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k);
+void ext_cleanup(void);
 
 /* Macro to register the extensions used in the CoT */
 #define REGISTER_EXTENSIONS(_ext) \
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
index 128e7f7..312575b 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,7 +22,9 @@
 enum {
 	KEY_ALG_RSA,		/* RSA PSS as defined by PKCS#1 v2.1 (default) */
 #ifndef OPENSSL_NO_EC
-	KEY_ALG_ECDSA,
+	KEY_ALG_ECDSA_NIST,
+	KEY_ALG_ECDSA_BRAINPOOL_R,
+	KEY_ALG_ECDSA_BRAINPOOL_T,
 #endif /* OPENSSL_NO_EC */
 	KEY_ALG_MAX_NUM
 };
@@ -42,7 +44,9 @@
 static const unsigned int KEY_SIZES[KEY_ALG_MAX_NUM][KEY_SIZE_MAX_NUM] = {
 	{ 2048, 1024, 3072, 4096 },	/* KEY_ALG_RSA */
 #ifndef OPENSSL_NO_EC
-	{}				/* KEY_ALG_ECDSA */
+	{},				/* KEY_ALG_ECDSA_NIST */
+	{},				/* KEY_ALG_ECDSA_BRAINPOOL_R */
+	{}				/* KEY_ALG_ECDSA_BRAINPOOL_T */
 #endif /* OPENSSL_NO_EC */
 };
 
@@ -66,10 +70,13 @@
 /* Exported API */
 int key_init(void);
 key_t *key_get_by_opt(const char *opt);
+#if !USING_OPENSSL3
 int key_new(key_t *key);
+#endif
 int key_create(key_t *key, int type, int key_bits);
 int key_load(key_t *key, unsigned int *err_code);
 int key_store(key_t *key);
+void key_cleanup(void);
 
 /* Macro to register the keys used in the CoT */
 #define REGISTER_KEYS(_keys) \
diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c
index 67ae1d6..2513213 100644
--- a/tools/cert_create/src/cert.c
+++ b/tools/cert_create/src/cert.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -39,7 +39,11 @@
 	if (!btmp)
 		return 0;
 
+#if USING_OPENSSL3
 	if (!BN_rand(btmp, SERIAL_RAND_BITS, 0, 0))
+#else
+	if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
+#endif
 		goto error;
 	if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
 		goto error;
@@ -272,3 +276,19 @@
 
 	return NULL;
 }
+
+void cert_cleanup(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_certs; i++) {
+		if (certs[i].fn != NULL) {
+			void *ptr = (void *)certs[i].fn;
+
+			certs[i].fn = NULL;
+			free(ptr);
+		}
+	}
+	free(certs);
+}
+
diff --git a/tools/cert_create/src/ext.c b/tools/cert_create/src/ext.c
index 2882123..acf57a4 100644
--- a/tools/cert_create/src/ext.c
+++ b/tools/cert_create/src/ext.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -315,3 +315,20 @@
 
 	return NULL;
 }
+
+void ext_cleanup(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_extensions; i++) {
+		if (extensions[i].arg != NULL) {
+			void *ptr = (void *)extensions[i].arg;
+
+			extensions[i].arg = NULL;
+			free(ptr);
+		}
+	}
+	free(extensions);
+	X509V3_EXT_cleanup();
+}
+
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 2857a3b..487777b 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,7 @@
 key_t *keys;
 unsigned int num_keys;
 
+#if !USING_OPENSSL3
 /*
  * Create a new key container
  */
@@ -37,9 +38,11 @@
 
 	return 1;
 }
+#endif
 
 static int key_create_rsa(key_t *key, int key_bits)
 {
+#if USING_OPENSSL3
 	EVP_PKEY *rsa = EVP_RSA_gen(key_bits);
 	if (rsa == NULL) {
 		printf("Cannot generate RSA key\n");
@@ -47,26 +50,128 @@
 	}
 	key->key = rsa;
 	return 1;
+#else
+	BIGNUM *e;
+	RSA *rsa = NULL;
+
+	e = BN_new();
+	if (e == NULL) {
+		printf("Cannot create RSA exponent\n");
+		return 0;
+	}
+
+	if (!BN_set_word(e, RSA_F4)) {
+		printf("Cannot assign RSA exponent\n");
+		goto err2;
+	}
+
+	rsa = RSA_new();
+	if (rsa == NULL) {
+		printf("Cannot create RSA key\n");
+		goto err2;
+	}
+
+	if (!RSA_generate_key_ex(rsa, key_bits, e, NULL)) {
+		printf("Cannot generate RSA key\n");
+		goto err;
+	}
+
+	if (!EVP_PKEY_assign_RSA(key->key, rsa)) {
+		printf("Cannot assign RSA key\n");
+		goto err;
+	}
+
+	BN_free(e);
+	return 1;
+
+err:
+	RSA_free(rsa);
+err2:
+	BN_free(e);
+	return 0;
+#endif
 }
 
 #ifndef OPENSSL_NO_EC
-static int key_create_ecdsa(key_t *key, int key_bits)
+#if USING_OPENSSL3
+static int key_create_ecdsa(key_t *key, int key_bits, const char *curve)
 {
-	EVP_PKEY *ec = EVP_EC_gen("prime256v1");
+	EVP_PKEY *ec = EVP_EC_gen(curve);
 	if (ec == NULL) {
 		printf("Cannot generate EC key\n");
 		return 0;
 	}
+
 	key->key = ec;
 	return 1;
 }
+
+static int key_create_ecdsa_nist(key_t *key, int key_bits)
+{
+	return key_create_ecdsa(key, key_bits, "prime256v1");
+}
+
+static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
+{
+	return key_create_ecdsa(key, key_bits, "brainpoolP256r1");
+}
+
+static int key_create_ecdsa_brainpool_t(key_t *key, int key_bits)
+{
+	return key_create_ecdsa(key, key_bits, "brainpoolP256t1");
+}
+#else
+static int key_create_ecdsa(key_t *key, int key_bits, const int curve_id)
+{
+	EC_KEY *ec;
+
+	ec = EC_KEY_new_by_curve_name(curve_id);
+	if (ec == NULL) {
+		printf("Cannot create EC key\n");
+		return 0;
+	}
+	if (!EC_KEY_generate_key(ec)) {
+		printf("Cannot generate EC key\n");
+		goto err;
+	}
+	EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS);
+	EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
+	if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) {
+		printf("Cannot assign EC key\n");
+		goto err;
+	}
+
+	return 1;
+
+err:
+	EC_KEY_free(ec);
+	return 0;
+}
+
+static int key_create_ecdsa_nist(key_t *key, int key_bits)
+{
+	return key_create_ecdsa(key, key_bits, NID_X9_62_prime256v1);
+}
+
+static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
+{
+	return key_create_ecdsa(key, key_bits, NID_brainpoolP256r1);
+}
+
+static int key_create_ecdsa_brainpool_t(key_t *key, int key_bits)
+{
+	return key_create_ecdsa(key, key_bits, NID_brainpoolP256t1);
+}
+#endif /* USING_OPENSSL3 */
 #endif /* OPENSSL_NO_EC */
 
 typedef int (*key_create_fn_t)(key_t *key, int key_bits);
 static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = {
-	key_create_rsa, 	/* KEY_ALG_RSA */
+	[KEY_ALG_RSA] = key_create_rsa,
 #ifndef OPENSSL_NO_EC
-	key_create_ecdsa, 	/* KEY_ALG_ECDSA */
+	[KEY_ALG_ECDSA_NIST] = key_create_ecdsa_nist,
+	[KEY_ALG_ECDSA_BRAINPOOL_R] = key_create_ecdsa_brainpool_r,
+	[KEY_ALG_ECDSA_BRAINPOOL_T] = key_create_ecdsa_brainpool_t,
 #endif /* OPENSSL_NO_EC */
 };
 
@@ -194,3 +299,20 @@
 
 	return NULL;
 }
+
+void key_cleanup(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_keys; i++) {
+		EVP_PKEY_free(keys[i].key);
+		if (keys[i].fn != NULL) {
+			void *ptr = keys[i].fn;
+
+			free(ptr);
+			keys[i].fn = NULL;
+		}
+	}
+	free(keys);
+}
+
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index b39378c..2ab6bcf 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -84,7 +84,9 @@
 static const char *key_algs_str[] = {
 	[KEY_ALG_RSA] = "rsa",
 #ifndef OPENSSL_NO_EC
-	[KEY_ALG_ECDSA] = "ecdsa"
+	[KEY_ALG_ECDSA_NIST] = "ecdsa",
+	[KEY_ALG_ECDSA_BRAINPOOL_R] = "ecdsa-brainpool-regular",
+	[KEY_ALG_ECDSA_BRAINPOOL_T] = "ecdsa-brainpool-twisted",
 #endif /* OPENSSL_NO_EC */
 };
 
@@ -106,7 +108,7 @@
 
 	printf("\n\n");
 	printf("The certificate generation tool loads the binary images and\n"
-	       "optionally the RSA keys, and outputs the key and content\n"
+	       "optionally the RSA or ECC keys, and outputs the key and content\n"
 	       "certificates properly signed to implement the chain of trust.\n"
 	       "If keys are provided, they must be in PEM format.\n"
 	       "Certificates are generated in DER format.\n");
@@ -267,7 +269,8 @@
 	},
 	{
 		{ "key-alg", required_argument, NULL, 'a' },
-		"Key algorithm: 'rsa' (default)- RSAPSS scheme as per PKCS#1 v2.1, 'ecdsa'"
+		"Key algorithm: 'rsa' (default)- RSAPSS scheme as per PKCS#1 v2.1, " \
+		"'ecdsa', 'ecdsa-brainpool-regular', 'ecdsa-brainpool-twisted'"
 	},
 	{
 		{ "key-size", required_argument, NULL, 'b' },
@@ -430,10 +433,12 @@
 
 	/* Load private keys from files (or generate new ones) */
 	for (i = 0 ; i < num_keys ; i++) {
+#if !USING_OPENSSL3
 		if (!key_new(&keys[i])) {
 			ERROR("Failed to allocate key container\n");
 			exit(1);
 		}
+#endif
 
 		/* First try to load the key from disk */
 		if (key_load(&keys[i], &err_code)) {
@@ -594,9 +599,7 @@
 	/* If we got here, then we must have filled the key array completely.
 	 * We can then safely call free on all of the keys in the array
 	 */
-	for (i = 0; i < num_keys; i++) {
-		EVP_PKEY_free(keys[i].key);
-	}
+	key_cleanup();
 
 #ifndef OPENSSL_NO_ENGINE
 	ENGINE_cleanup();
@@ -605,30 +608,10 @@
 
 
 	/* We allocated strings through strdup, so now we have to free them */
-	for (i = 0; i < num_keys; i++) {
-		if (keys[i].fn != NULL) {
-			void *ptr = keys[i].fn;
-
-			keys[i].fn = NULL;
-			free(ptr);
-		}
-	}
-	for (i = 0; i < num_extensions; i++) {
-		if (extensions[i].arg != NULL) {
-			void *ptr = (void *)extensions[i].arg;
 
-			extensions[i].arg = NULL;
-			free(ptr);
-		}
-	}
-	for (i = 0; i < num_certs; i++) {
-		if (certs[i].fn != NULL) {
-			void *ptr = (void *)certs[i].fn;
+	ext_cleanup();
 
-			certs[i].fn = NULL;
-			free(ptr);
-		}
-	}
+	cert_cleanup();
 
 	return 0;
 }
diff --git a/tools/cert_create/src/sha.c b/tools/cert_create/src/sha.c
index 06ef360..bb750d4 100644
--- a/tools/cert_create/src/sha.c
+++ b/tools/cert_create/src/sha.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,11 +7,16 @@
 #include <stdio.h>
 #include "debug.h"
 #include "key.h"
+#if USING_OPENSSL3
 #include <openssl/evp.h>
 #include <openssl/obj_mac.h>
+#else
+#include <openssl/sha.h>
+#endif
 
 #define BUFFER_SIZE	256
 
+#if USING_OPENSSL3
 static int get_algorithm_nid(int hash_alg)
 {
 	int nids[] = {NID_sha256, NID_sha384, NID_sha512};
@@ -20,16 +25,22 @@
 	}
 	return nids[hash_alg];
 }
+#endif
 
 int sha_file(int md_alg, const char *filename, unsigned char *md)
 {
 	FILE *inFile;
+	int bytes;
+	unsigned char data[BUFFER_SIZE];
+#if USING_OPENSSL3
 	EVP_MD_CTX *mdctx;
 	const EVP_MD *md_type;
-	int bytes;
 	int alg_nid;
 	unsigned int total_bytes;
-	unsigned char data[BUFFER_SIZE];
+#else
+	SHA256_CTX shaContext;
+	SHA512_CTX sha512Context;
+#endif
 
 	if ((filename == NULL) || (md == NULL)) {
 		ERROR("%s(): NULL argument\n", __func__);
@@ -42,6 +53,8 @@
 		return 0;
 	}
 
+#if USING_OPENSSL3
+
 	mdctx = EVP_MD_CTX_new();
 	if (mdctx == NULL) {
 		fclose(inFile);
@@ -74,5 +87,32 @@
 	fclose(inFile);
 	EVP_MD_CTX_free(mdctx);
 	return 0;
+
+#else
+
+	if (md_alg == HASH_ALG_SHA384) {
+		SHA384_Init(&sha512Context);
+		while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+			SHA384_Update(&sha512Context, data, bytes);
+		}
+		SHA384_Final(md, &sha512Context);
+	} else if (md_alg == HASH_ALG_SHA512) {
+		SHA512_Init(&sha512Context);
+		while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+			SHA512_Update(&sha512Context, data, bytes);
+		}
+		SHA512_Final(md, &sha512Context);
+	} else {
+		SHA256_Init(&shaContext);
+		while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+			SHA256_Update(&shaContext, data, bytes);
+		}
+		SHA256_Final(md, &shaContext);
+	}
+
+	fclose(inFile);
+	return 1;
+
+#endif
 }
 
diff --git a/tools/conventional-changelog-tf-a/package.json b/tools/conventional-changelog-tf-a/package.json
index 0008b53..3dd9877 100644
--- a/tools/conventional-changelog-tf-a/package.json
+++ b/tools/conventional-changelog-tf-a/package.json
@@ -1,6 +1,6 @@
 {
   "name": "conventional-changelog-tf-a",
-  "version": "2.7.0",
+  "version": "2.8.0",
   "license": "BSD-3-Clause",
   "private": true,
   "main": "index.js",
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index 60bd8ea..2939b14 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -11,15 +11,21 @@
 BINARY		:= $(notdir ${ENCTOOL})
 OPENSSL_DIR	:= /usr
 
+
+MAKE_HELPERS_DIRECTORY := ../../make_helpers/
+include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
+include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}defaults.mk
+
 OBJECTS := src/encrypt.o \
            src/cmd_opt.o \
            src/main.o
 
 HOSTCCFLAGS := -Wall -std=c99
 
-MAKE_HELPERS_DIRECTORY := ../../make_helpers/
-include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
-include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+# Select OpenSSL version flag according to the OpenSSL build selected
+# from setting the OPENSSL_DIR path.
+$(eval $(call SELECT_OPENSSL_API_VERSION))
 
 ifeq (${DEBUG},1)
   HOSTCCFLAGS += -g -O0 -DDEBUG -DLOG_LEVEL=40
@@ -36,6 +42,12 @@
   Q :=
 endif
 
+HOSTCCFLAGS += ${DEFINES}
+# USING_OPENSSL3 flag will be added to the HOSTCCFLAGS variable with the proper
+# computed value.
+HOSTCCFLAGS += -DUSING_OPENSSL3=$(USING_OPENSSL3)
+
+
 # Make soft links and include from local directory otherwise wrong headers
 # could get pulled in from firmware tree.
 INC_DIR := -I ./include -I ../../include/tools_share -I ${OPENSSL_DIR}/include
@@ -51,11 +63,11 @@
 
 HOSTCC ?= gcc
 
-.PHONY: all clean realclean
+.PHONY: all clean realclean --openssl
 
 all: ${BINARY}
 
-${BINARY}: ${OBJECTS} Makefile
+${BINARY}: --openssl ${OBJECTS} Makefile
 	@echo "  HOSTLD  $@"
 	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__;' | \
                 ${HOSTCC} -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o
@@ -65,6 +77,11 @@
 	@echo "  HOSTCC  $<"
 	${Q}${HOSTCC} -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
+--openssl:
+ifeq ($(DEBUG),1)
+	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+endif
+
 clean:
 	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
 
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index e6aeba9..d7e0fe5 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,6 +7,7 @@
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}defaults.mk
 
 FIPTOOL ?= fiptool${BIN_EXT}
 PROJECT := $(notdir ${FIPTOOL})
@@ -23,6 +24,15 @@
   HOSTCCFLAGS += -O2
 endif
 
+# Select OpenSSL version flag according to the OpenSSL build selected
+# from setting the OPENSSL_DIR path.
+$(eval $(call SELECT_OPENSSL_API_VERSION))
+
+HOSTCCFLAGS += ${DEFINES}
+# USING_OPENSSL3 flag will be added to the HOSTCCFLAGS variable with the proper
+# computed value.
+HOSTCCFLAGS += -DUSING_OPENSSL3=$(USING_OPENSSL3)
+
 # Include library directories where OpenSSL library files are located.
 # For a normal installation (i.e.: when ${OPENSSL_DIR} = /usr or
 # /usr/local), binaries are located under the ${OPENSSL_DIR}/lib/
@@ -51,11 +61,11 @@
 include ${PLAT_FIPTOOL_HELPER_MK}
 endif
 
-.PHONY: all clean distclean
+.PHONY: all clean distclean --openssl
 
 all: ${PROJECT}
 
-${PROJECT}: ${OBJECTS} Makefile
+${PROJECT}: --openssl ${OBJECTS} Makefile
 	@echo "  HOSTLD  $@"
 	${Q}${HOSTCC} ${OBJECTS} -o $@ ${LDLIBS}
 	@${ECHO_BLANK_LINE}
@@ -66,5 +76,11 @@
 	@echo "  HOSTCC  $<"
 	${Q}${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
+--openssl:
+ifeq ($(DEBUG),1)
+	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+endif
+
+
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
diff --git a/tools/nxp/create_pbl/create_pbl.c b/tools/nxp/create_pbl/create_pbl.c
index 9457a00..792747f 100644
--- a/tools/nxp/create_pbl/create_pbl.c
+++ b/tools/nxp/create_pbl/create_pbl.c
@@ -823,7 +823,9 @@
 		}
 	}
 
-	if ((args & MAND_ARG_MASK) != MAND_ARG_MASK) {
+	if ((args & MAND_ARG_MASK) != MAND_ARG_MASK
+			|| pblimg.rcw_nm == NULL
+			|| pblimg.imagefile == NULL) {
 		print_usage();
 	}
 
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index f3af584..4067331 100644
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -132,20 +132,21 @@
     sp_pkg = get_sp_pkg(sp, args)
     sp_dtb_name = os.path.basename(get_file_from_layout(sp_layout[sp]["pm"]))[:-1] + "b"
     sp_dtb = os.path.join(args["out_dir"], f"fdts/{sp_dtb_name}")
+    sp_img = get_sp_img_full_path(sp_layout[sp], args)
 
     # Do not generate rule if already there.
     if is_line_in_sp_gen(f'{sp_pkg}:', args):
         return args
     write_to_sp_mk_gen(f"SP_PKGS += {sp_pkg}\n", args)
 
-    sptool_args = f" -i {get_sp_img_full_path(sp_layout[sp], args)}:{sp_dtb}"
+    sptool_args = f" -i {sp_img}:{sp_dtb}"
     pm_offset = get_pm_offset(sp_layout[sp])
     sptool_args += f" --pm-offset {pm_offset}" if pm_offset is not None else ""
     image_offset = get_image_offset(sp_layout[sp])
     sptool_args += f" --img-offset {image_offset}" if image_offset is not None else ""
     sptool_args += f" -o {sp_pkg}"
     sppkg_rule = f'''
-{sp_pkg}: {sp_dtb}
+{sp_pkg}: {sp_dtb} {sp_img}
 \t$(Q)echo Generating {sp_pkg}
 \t$(Q)$(PYTHON) $(SPTOOL) {sptool_args}
 '''