Merge "docs(spm): update FF-A manifest binding" into integration
diff --git a/Makefile b/Makefile
index a14d4d8..4f5ec5d 100644
--- a/Makefile
+++ b/Makefile
@@ -278,7 +278,7 @@
 		TF_CFLAGS_aarch64	:=	-target aarch64-arm-none-eabi $(march64-directive)
 		LD			:=	$(LINKER)
 	else
-		TF_CFLAGS_aarch32	:=	$(target32-directive) $(march32-directive)
+		TF_CFLAGS_aarch32	=	$(target32-directive) $(march32-directive)
 		TF_CFLAGS_aarch64	:=	-target aarch64-elf $(march64-directive)
 		LD			:=	$(shell $(CC) --print-prog-name ld.lld)
 
@@ -715,8 +715,8 @@
 
 # For RAS_EXTENSION, require that EAs are handled in EL3 first
 ifeq ($(RAS_EXTENSION),1)
-    ifneq ($(HANDLE_EA_EL3_FIRST),1)
-        $(error For RAS_EXTENSION, HANDLE_EA_EL3_FIRST must also be 1)
+    ifneq ($(HANDLE_EA_EL3_FIRST_NS),1)
+        $(error For RAS_EXTENSION, HANDLE_EA_EL3_FIRST_NS must also be 1)
     endif
 endif
 
@@ -1033,7 +1033,7 @@
         FAULT_INJECTION_SUPPORT \
         GENERATE_COT \
         GICV2_G0_FOR_EL3 \
-        HANDLE_EA_EL3_FIRST \
+        HANDLE_EA_EL3_FIRST_NS \
         HW_ASSISTED_COHERENCY \
         INVERTED_MEMMAP \
         MEASURED_BOOT \
@@ -1079,6 +1079,8 @@
         ENABLE_MPMM_FCONF \
         SIMICS_BUILD \
         FEATURE_DETECTION \
+	TRNG_SUPPORT \
+	CONDITIONAL_CMO \
 )))
 
 $(eval $(call assert_numerics,\
@@ -1172,7 +1174,7 @@
         ERROR_DEPRECATED \
         FAULT_INJECTION_SUPPORT \
         GICV2_G0_FOR_EL3 \
-        HANDLE_EA_EL3_FIRST \
+        HANDLE_EA_EL3_FIRST_NS \
         HW_ASSISTED_COHERENCY \
         LOG_LEVEL \
         MEASURED_BOOT \
@@ -1240,6 +1242,7 @@
         FEATURE_DETECTION \
         TWED_DELAY \
         ENABLE_FEAT_TWED \
+	CONDITIONAL_CMO \
 )))
 
 ifeq (${SANITIZE_UB},trap)
@@ -1467,7 +1470,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}
@@ -1512,7 +1515,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.
@@ -1533,7 +1536,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/bl1/bl1.ld.S b/bl1/bl1.ld.S
index bc23828..c4ec5fe 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -38,16 +38,16 @@
         *(.vectors)
         . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
-     } >ROM
+    } >ROM
 
-     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
-     .ARM.extab . : {
+    /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+    .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
-     } >ROM
+    } >ROM
 
-     .ARM.exidx . : {
+    .ARM.exidx . : {
         *(.ARM.exidx* .gnu.linkonce.armexidx.*)
-     } >ROM
+    } >ROM
 
     .rodata . : {
         __RODATA_START__ = .;
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index d332ec0..80cf7db 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -34,16 +34,16 @@
         *(.vectors)
         . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
-     } >RAM
+    } >RAM
 
-     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
-     .ARM.extab . : {
+    /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+    .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
-     } >RAM
+    } >RAM
 
-     .ARM.exidx . : {
+    .ARM.exidx . : {
         *(.ARM.exidx* .gnu.linkonce.armexidx.*)
-     } >RAM
+    } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index 5e53ab4..dbb3234 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -195,23 +195,30 @@
  */
 func delegate_async_ea
 #if RAS_EXTENSION
+	/* Check Exception Class to ensure SError, as this function should
+	 * only be invoked for SError. If that is not the case, which implies
+	 * either an HW error or programming error, panic.
+	 */
+	ubfx	x2, x1, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+	cmp	x2, EC_SERROR
+	b.ne	do_panic
 	/*
 	 * Check for Implementation Defined Syndrome. If so, skip checking
 	 * Uncontainable error type from the syndrome as the format is unknown.
 	 */
 	tbnz	x1, #SERROR_IDS_BIT, 1f
 
+	/* AET only valid when DFSC is 0x11 */
+	ubfx	x2, x1, #EABORT_DFSC_SHIFT, #EABORT_DFSC_WIDTH
+	cmp	x2, #DFSC_SERROR
+	b.ne	1f
+
 	/*
 	 * Check for Uncontainable error type. If so, route to the platform
 	 * fatal error handler rather than the generic EA one.
 	 */
-	ubfx	x2, x1, #EABORT_AET_SHIFT, #EABORT_AET_WIDTH
-	cmp	x2, #ERROR_STATUS_UET_UC
-	b.ne	1f
-
-	/* Check DFSC for SError type */
-	ubfx	x3, x1, #EABORT_DFSC_SHIFT, #EABORT_DFSC_WIDTH
-	cmp	x3, #DFSC_SERROR
+	ubfx	x3, x1, #EABORT_AET_SHIFT, #EABORT_AET_WIDTH
+	cmp	x3, #ERROR_STATUS_UET_UC
 	b.ne	1f
 
 	no_ret	plat_handle_uncontainable_ea
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index bf5bd8d..0283553 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -512,7 +512,7 @@
 
 	/*
 	 * Shift copied SCR_EL3.NSE bit by 5 to create space for
-	 * SCR_EL3.NS bit. Bit 5 of the flag correspondes to
+	 * SCR_EL3.NS bit. Bit 5 of the flag corresponds to
 	 * the SCR_EL3.NSE bit.
 	 */
 	lsl	x7, x7, #5
@@ -521,6 +521,16 @@
 	/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
 	bfi	x7, x18, #0, #1
 
+	/*
+	 * Per SMCCCv1.3 a caller can set the SVE hint bit in the SMC FID
+	 * passed through x0. Copy the SVE hint bit to flags and mask the
+	 * bit in smc_fid passed to the standard service dispatcher.
+	 * A service/dispatcher can retrieve the SVE hint bit state from
+	 * flags using the appropriate helper.
+	 */
+	bfi	x7, x0, #FUNCID_SVE_HINT_SHIFT, #FUNCID_SVE_HINT_MASK
+	bic	x0, x0, #(FUNCID_SVE_HINT_MASK << FUNCID_SVE_HINT_SHIFT)
+
 	mov	sp, x12
 
 	/* Get the unique owning entity number */
diff --git a/changelog.yaml b/changelog.yaml
index 8fcb217..cfb2bb5 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -89,18 +89,42 @@
       - title: Activity Monitors Extension (FEAT_AMU)
         scope: amu
 
+      - title: Branch Record Buffer Extension (FEAT_BRBE)
+        scope: brbe
+
+      - title: Branch Target Identification Extension
+        scope: bti
+
       - title: Confidential Compute Architecture (CCA)
         scope: cca
 
+      - title: Extended Cache Index (FEAT_CCIDX)
+        scope: ccidx
+
       - title: Support for the `HCRX_EL2` register (FEAT_HCX)
         scope: hcx
 
       - title: Memory Partitioning and Monitoring (MPAM) Extension (FEAT_MPAM)
         scope: mpam
 
+      - title: Memory Tagging Extension
+        scope: mte
+
+      - title: Pointer Authentication Extension
+        scope: pauth
+
+      - title: Performance Monitors Extension (FEAT_PMUv3)
+        scope: pmu
+
+      - title: Trapping support for RNDR/RNDRRS (FEAT_RNG_TRAP)
+        scope: rng-trap
+
       - title: Scalable Matrix Extension (FEAT_SME)
         scope: sme
 
+      - title: Statistical profiling Extension (FEAT_SPE)
+        scope: spe
+
       - title: Scalable Vector Extension (FEAT_SVE)
         scope: sve
 
@@ -116,21 +140,6 @@
       - title: Self-hosted Trace Extensions (FEAT_TRF)
         scope: trf
 
-      - title: Statistical profiling Extension (FEAT_SPE)
-        scope: spe
-
-      - title: Branch Record Buffer Extension (FEAT_BRBE)
-        scope: brbe
-
-      - title: Extended Cache Index (FEAT_CCIDX)
-        scope: ccidx
-
-      - title: Trapping support for RNDR/RNDRRS (FEAT_RNG_TRAP)
-        scope: rng-trap
-
-      - title: Performance Monitors Extension (FEAT_PMUv3)
-        scope: pmu
-
   - title: Platforms
 
     subsections:
@@ -147,6 +156,12 @@
           - plat/arm
 
         subsections:
+          - title: CSS
+            scope: css
+
+            deprecated:
+              - plat/arm/css
+
           - title: FPGA
             scope: fpga
 
@@ -160,6 +175,7 @@
 
             deprecated:
               - plat/fvp
+              - fvp/tsp_manifest
 
           - title: FVP-R
             scope: fvp-r
@@ -167,6 +183,9 @@
             deprecated:
               - fvp_r
 
+          - title: FVP Versatile Express
+            scope: fvp_ve
+
           - title: Juno
             scope: juno
 
@@ -209,6 +228,16 @@
       - title: Broadcom
         scope: brcm
 
+      - title: HiSilicon
+        scope: hisilicon
+
+        subsections:
+          - title: HiKey
+            scope: hikey
+
+          - title: HiKey960
+            scope: hikey960
+
       - title: Intel
         scope: intel
 
@@ -256,6 +285,16 @@
             deprecated:
               - plat/mediatek/mt8183
 
+          - title: MT8186
+            scope: mt8186
+
+            deprecated:
+              - plat/mediatek/mt8186
+              - mt8186-emi-mpu
+
+          - title: MT8188
+            scope: mt8188
+
           - title: MT8192
             scope: mt8192
 
@@ -270,12 +309,6 @@
               - plat/mediatek/mt8195
               - plat/mdeiatek/mt8195
 
-          - title: MT8186
-            scope: mt8186
-
-            deprecated:
-              - plat/mediatek/mt8186
-
       - title: NVIDIA
         scope: nvidia
 
@@ -426,6 +459,9 @@
       - title: QTI
         scope: qti
 
+        deprecated:
+          - plat/qti
+
         subsections:
           - title: SC1780
             scope: sc7180
@@ -446,6 +482,9 @@
         scope: rpi
 
         subsections:
+          - title: Raspberry Pi 3
+            scope: rpi3
+
           - title: Raspberry Pi 4
             scope: rpi4
 
@@ -514,6 +553,9 @@
           - title: K3
             scope: k3
 
+            deprecated:
+              - ti-k3
+
       - title: Xilinx
         scope: xilinx
 
@@ -529,6 +571,13 @@
               - plat/xilinx/versal
               - plat/versal
 
+            subsections:
+             - title: Versal NET
+               scope: versal-net
+
+               deprecated:
+                 - versal_net
+
           - title: ZynqMP
             scope: zynqmp
 
@@ -572,6 +621,9 @@
       - title: RME
         scope: rme
 
+        deprecated:
+          - rme/fid
+
         subsections:
           - title: TRP
             scope: trp
@@ -586,6 +638,9 @@
           - title: EL3 SPMC
             scope: el3-spmc
 
+            deprecated:
+              - spmc
+
           - title: SPMD
             scope: spmd
 
@@ -595,6 +650,9 @@
       - title: DRTM
         scope: drtm
 
+      - title: TRNG
+        scope: trng
+
   - title: Libraries
 
     subsections:
@@ -616,6 +674,9 @@
           - title: Context Management
             scope: cm
 
+          - title: RAS
+            scope: ras
+
       - title: FCONF
         scope: fconf
 
@@ -652,8 +713,14 @@
       - title: PSA
         scope: psa
 
+        deprecated:
+          - lib/psa
+
       - title: Context Management
-        scope: context mgmt
+        scope: context-mgmt
+
+        deprecated:
+          - context mgmt
 
       - title: Semihosting
         scope: semihosting
@@ -735,6 +802,7 @@
         deprecated:
           - scmi_common
           - drivers/scmi-msg
+          - scmi-msg
 
       - title: UFS
         scope: ufs
@@ -756,7 +824,13 @@
               - title: GICv3
                 scope: gicv3
 
+                deprecated:
+                  - gicv3/multichip
+
                 subsections:
+                  - title: GIC-600
+                    scope: gic600
+
                   - title: GIC-600AE
                     scope: gic600ae
 
@@ -1171,6 +1245,9 @@
       - title: Certificate Creation Tool
         scope: cert-create
 
+        deprecated:
+          - cert_create
+
   - title: Dependencies
     scope: deps
 
diff --git a/common/aarch64/debug.S b/common/aarch64/debug.S
index d105d08..742e022 100644
--- a/common/aarch64/debug.S
+++ b/common/aarch64/debug.S
@@ -168,7 +168,7 @@
 	mrs	x0, currentel
 	ubfx	x0, x0, #MODE_EL_SHIFT, #MODE_EL_WIDTH
 	cmp	x0, #MODE_EL3
-#if !HANDLE_EA_EL3_FIRST
+#if !HANDLE_EA_EL3_FIRST_NS
 	ldr	x0, [sp], #0x10
 	b.eq	el3_panic
 #else
@@ -184,7 +184,7 @@
 
 to_panic_common:
 	ldr	x0, [sp], #0x10
-#endif /* HANDLE_EA_EL3_FIRST */
+#endif /* HANDLE_EA_EL3_FIRST_NS */
 #endif /* CRASH_REPORTING */
 
 panic_common:
diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c
index 89380b3..f994ae5 100644
--- a/common/backtrace/backtrace.c
+++ b/common/backtrace/backtrace.c
@@ -54,17 +54,6 @@
 	return ret;
 }
 
-const char *get_el_str(unsigned int el)
-{
-	if (el == 3U) {
-		return "EL3";
-	} else if (el == 2U) {
-		return "EL2";
-	} else {
-		return "S-EL1";
-	}
-}
-
 /*
  * Returns true if the address points to a virtual address that can be read at
  * the current EL, false otherwise.
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index a980ed9..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:
 
@@ -67,26 +78,26 @@
 
 Build Definitions for CMake Build System
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
-:|G|: `javieralso-arm`_
 :|M|: Chris Kay <chris.kay@arm.com>
 :|G|: `CJKay`_
 :|F|: /
 
 Software Delegated Exception Interface (SDEI)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Mark Dykes <mark.dykes@arm.com>
-:|G|: `mardyk01`_
+:|M|: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
+:|G|: `jayanthchidanand-arm`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
 :|F|: services/std_svc/sdei/
 
 Trusted Boot
 ^^^^^^^^^^^^
 :|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
 :|G|: `sandrine-bailleux-arm`_
-:|M|: Manish Pandey <manish.pandey2@arm.com>
-:|G|: `manish-pandey-arm`_
 :|M|: Manish Badarkhe <manish.badarkhe@arm.com>
 :|G|: `ManishVB-Arm`_
+:|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:|G|: `laurenw-arm`_
 :|F|: drivers/auth/
 
 Secure Partition Manager Core (EL3 FF-A SPMC)
@@ -99,36 +110,34 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Olivier Deprez <olivier.deprez@arm.com>
 :|G|: `odeprez`_
-:|M|: Manish Pandey <manish.pandey2@arm.com>
-:|G|: `manish-pandey-arm`_
-:|M|: Maksims Svecovs <maksims.svecovs@arm.com>
-:|G|: `max-shvetsov`_
 :|M|: Joao Alves <Joao.Alves@arm.com>
 :|G|: `J-Alves`_
 :|F|: services/std_svc/spmd/\*
 
 Exception Handling Framework (EHF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
-:|G|: `ManishVB-Arm`_
+:|M|: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
+:|G|: `jayanthchidanand-arm`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
 :|F|: bl31/ehf.c
 
 Realm Management Monitor Dispatcher (RMMD)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
 :|G|: `javieralso-arm`_
+:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
+:|G|: `AlexeiFedorov`_
 :|F|: services/std_svc/rmmd/\*
 :|F|: include/services/rmmd_svc.h
 :|F|: include/services/rmm_core_manifest.h
 
 Realm Management Extension (RME)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Bipin Ravi <bipin.ravi@arm.com>
-:|G|: `bipinravi-arm`_
-:|M|: Mark Dykes <mark.dykes@arm.com>
-:|G|: `mardyk01`_
 :|M|: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
 :|G|: `javieralso-arm`_
+:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
+:|G|: `AlexeiFedorov`_
 
 Drivers, Libraries and Framework Code
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -185,14 +194,12 @@
 
 Power State Coordination Interface (PSCI)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
-:|G|: `javieralso-arm`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
 :|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
 :|G|: `madhukar-Arm`_
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
-:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:|G|: `zelalem-aweke`_
 :|F|: lib/psci/
 
 DebugFS
@@ -217,18 +224,27 @@
 :|G|: `J-Alves`_
 :|F|: lib/pmf/
 
+Errata Management
+^^^^^^^^^^^^^^^^^
+:|M|: Bipin Ravi <bipin.ravi@arm.com>
+:|G|: `bipinravi-arm`_
+:|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:|G|: `laurenw-arm`_
+
 Arm CPU libraries
 ^^^^^^^^^^^^^^^^^
+:|M|: Bipin Ravi <bipin.ravi@arm.com>
+:|G|: `bipinravi-arm`_
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
 :|F|: lib/cpus/
 
 Reliability Availability Serviceabilty (RAS) framework
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Olivier Deprez <olivier.deprez@arm.com>
-:|G|: `odeprez`_
 :|M|: Manish Pandey <manish.pandey2@arm.com>
 :|G|: `manish-pandey-arm`_
+:|M|: Olivier Deprez <olivier.deprez@arm.com>
+:|G|: `odeprez`_
 :|F|: lib/extensions/ras/
 
 Activity Monitors Unit (AMU) extensions
@@ -241,28 +257,28 @@
 
 Memory Partitioning And Monitoring (MPAM) extensions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:|G|: `zelalem-aweke`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
 :|F|: lib/extensions/mpam/
 
 Pointer Authentication (PAuth) and Branch Target Identification (BTI) extensions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
 :|G|: `AlexeiFedorov`_
-:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:|G|: `zelalem-aweke`_
 :|F|: lib/extensions/pauth/
 
 Statistical Profiling Extension (SPE)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:|G|: `zelalem-aweke`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
 :|F|: lib/extensions/spe/
 
 Standard C library
 ^^^^^^^^^^^^^^^^^^
-:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
-:|G|: `AlexeiFedorov`_
+:|M|: Chris Kay <chris.kay@arm.com>
+:|G|: `CJKay`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
 :|F|: lib/libc/
 
 Library At ROM (ROMlib)
@@ -273,8 +289,8 @@
 
 Translation tables (``xlat_tables``) library
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
-:|G|: `javieralso-arm`_
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
 :|M|: Joao Alves <Joao.Alves@arm.com>
 :|G|: `J-Alves`_
 :|F|: lib/xlat\_tables_\*/
@@ -331,17 +347,23 @@
 
 Measured Boot
 ^^^^^^^^^^^^^
-:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
-:|G|: `AlexeiFedorov`_
-:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
-:|G|: `javieralso-arm`_
 :|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
 :|G|: `sandrine-bailleux-arm`_
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
 :|F|: drivers/measured_boot
 :|F|: include/drivers/measured_boot
 :|F|: docs/components/measured_boot
 :|F|: plat/arm/board/fvp/fvp\*_measured_boot.c
 
+DRTM
+^^^^
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|F|: services/std_svc/drtm
+
 PSA Firmware Update
 ^^^^^^^^^^^^^^^^^^^
 :|M|: Manish Badarkhe <manish.badarkhe@arm.com>
@@ -376,8 +398,10 @@
 
 Granule Protection Tables Library (GPT-RME)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Mark Dykes <mark.dykes@arm.com>
-:|G|: `mardyk01`_
+:|M|: Soby Mathew <soby.mathew@arm.com>
+:|G|: `soby-mathew`_
+:|M|: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
+:|G|: `javieralso-arm`_
 :|F|: lib/gpt_rme
 :|F|: include/lib/gpt_rme
 
@@ -631,6 +655,8 @@
 :|G|: `lachitp`_
 :|M|: Sreevyshanavi Kare <skare@codeaurora.org>
 :|G|: `sreekare`_
+:|M|: Muhammad Arsath K F <quic_mkf@quicinc.com>
+:|G|: `quic_mkf`_
 :|M|: QTI TF Maintainers <qti.trustedfirmware.maintainers@codeaurora.org>
 :|F|: docs/plat/qti.rst
 :|F|: plat/qti/
@@ -794,6 +820,8 @@
 
 Fiptool
 ^^^^^^^
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
 :|M|: Joao Alves <Joao.Alves@arm.com>
 :|G|: `J-Alves`_
 :|F|: tools/fiptool/
@@ -802,6 +830,10 @@
 ^^^^^^^^^^^^^^^^
 :|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
 :|G|: `sandrine-bailleux-arm`_
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
+:|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:|G|: `laurenw-arm`_
 :|F|: tools/cert_create/
 
 Encrypt_fw tool
@@ -820,6 +852,8 @@
 
 Build system
 ^^^^^^^^^^^^
+:|M|: Chris Kay <chris.kay@arm.com>
+:|G|: `CJKay`_
 :|M|: Manish Pandey <manish.pandey2@arm.com>
 :|G|: `manish-pandey-arm`_
 :|F|: Makefile
@@ -827,8 +861,6 @@
 
 Threat Model
 ~~~~~~~~~~~~~
-:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:|G|: `zelalem-aweke`_
 :|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
 :|G|: `sandrine-bailleux-arm`_
 :|M|: Joanna Farley <joanna.farley@arm.com>
@@ -878,6 +910,7 @@
 .. _niej: https://github.com/niej
 .. _npoushin: https://github.com/npoushin
 .. _prabhakarlad: https://github.com/prabhakarlad
+.. _quic_mkf: https://github.com/quicmkf
 .. _remi-triplefault: https://github.com/repk
 .. _rockchip-linux: https://github.com/rockchip-linux
 .. _sandrine-bailleux-arm: https://github.com/sandrine-bailleux-arm
@@ -904,7 +937,6 @@
 .. _max-shvetsov: https://github.com/max-shvetsov
 .. _javieralso-arm: https://github.com/javieralso-arm
 .. _laurenw-arm: https://github.com/laurenw-arm
-.. _zelalem-aweke: https://github.com/zelalem-aweke
 .. _J-Alves: https://github.com/J-Alves
 .. _madhukar-Arm: https://github.com/madhukar-Arm
 .. _raghuncstate: https://github.com/raghuncstate
@@ -922,5 +954,7 @@
 .. _arve-android: https://github.com/arve-android
 .. _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 e9eaa80..cb2b883 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -56,18 +56,21 @@
 Removal of Deprecated Interfaces
 --------------------------------
 
-As mentioned in the :ref:`Platform Compatibility Policy`, this is a live
-document cataloging all the deprecated interfaces in TF-A project and the
-Release version after which it will be removed.
+As mentioned in the :ref:`Platform Ports Policy`, this is a live document
+cataloging all the deprecated interfaces in TF-A project and the Release version
+after which it will be removed.
 
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 | Interface                      | Deprecation | Removed | Comments                                                |
 |                                | 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    | Next    | Platform conversion to manage specific PK hash          |
+|                                |             | release |                                                         |
+|                                |             | after   |                                                         |
+|                                |             | 2.8     |                                                         |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
 --------------
 
-*Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/ras.rst b/docs/components/ras.rst
index b435349..871be2d 100644
--- a/docs/components/ras.rst
+++ b/docs/components/ras.rst
@@ -6,10 +6,11 @@
 later CPUs, and also an optional extension to the base Armv8.0 architecture.
 
 In conjunction with the |EHF|, support for RAS extension enables firmware-first
-paradigm for handling platform errors: exceptions resulting from errors are
-routed to and handled in EL3. Said errors are Synchronous External Abort (SEA),
-Asynchronous External Abort (signalled as SErrors), Fault Handling and Error
-Recovery interrupts.  The |EHF| document mentions various :ref:`error handling
+paradigm for handling platform errors: exceptions resulting from errors in
+Non-secure world are routed to and handled in EL3.
+Said errors are Synchronous External Abort (SEA), Asynchronous External Abort
+(signalled as SErrors), Fault Handling and Error Recovery interrupts.
+The |EHF| document mentions various :ref:`error handling
 use-cases <delegation-use-cases>` .
 
 For the description of Arm RAS extensions, Standard Error Records, and the
@@ -29,7 +30,7 @@
 .. __: `Standard Error Record helpers`_
 
 The build option ``RAS_EXTENSION`` when set to ``1`` includes the RAS in run
-time firmware; ``EL3_EXCEPTION_HANDLING`` and ``HANDLE_EA_EL3_FIRST`` must also
+time firmware; ``EL3_EXCEPTION_HANDLING`` and ``HANDLE_EA_EL3_FIRST_NS`` must also
 be set ``1``. ``RAS_TRAP_NS_ERR_REC_ACCESS`` controls the access to the RAS
 error record registers from Non-secure.
 
@@ -198,8 +199,8 @@
 -  ``EL3_EXCEPTION_HANDLING=1`` enables handling of exceptions at EL3. See
    `Interaction with Exception Handling Framework`_;
 
--  ``HANDLE_EA_EL3_FIRST=1`` enables routing of External Aborts and SErrors to
-   EL3.
+-  ``HANDLE_EA_EL3_FIRST_NS=1`` enables routing of External Aborts and SErrors,
+   resulting from errors in NS world, to EL3.
 
 The RAS support in |TF-A| introduces a default implementation of
 ``plat_ea_handler``, the External Abort handler in EL3. When ``RAS_EXTENSION``
diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst
index ea921fc..6fc0c2e 100644
--- a/docs/components/realm-management-extension.rst
+++ b/docs/components/realm-management-extension.rst
@@ -95,66 +95,218 @@
 This section describes how you can build and run TF-A with RME enabled.
 We assume you have all the :ref:`Prerequisites` to build TF-A.
 
-To enable RME, you need to set the ENABLE_RME build flag when building
-TF-A. Currently, this feature is only supported for the FVP platform.
-
 The following instructions show you how to build and run TF-A with RME
-for two scenarios: TF-A with TF-A Tests, and four-world execution with
-Hafnium and TF-A Tests. The instructions assume you have already obtained
-TF-A. You can use the following command to clone TF-A.
+for two scenarios:
 
-.. code:: shell
+- Three-world execution: TF-A with TF-A Tests or Linux.
 
- git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
+  - NS (TF-A Test or Linux),
+  - Root (TF-A)
+  - Realm (RMM or TRP)
+
+- Four-world execution: TF-A, Hafnium and TF-A Tests or Linux.
+
+  - NS (TF-A Test or Linux),
+  - Root (TF-A)
+  - Realm (RMM or TRP)
+  - SPM (Hafnium)
 
 To run the tests, you need an FVP model. Please use the :ref:`latest version
 <Arm Fixed Virtual Platforms (FVP)>` of *FVP_Base_RevC-2xAEMvA* model.
 
-.. note::
+Three World Testing with TF-A Tests
+*************************************
 
- ENABLE_RME build option is currently experimental.
+**1. Obtain and build TF-A Tests with Realm Payload**
 
-Building TF-A with TF-A Tests
-********************************************
+The full set of instructions to setup build host and build options for
+TF-A-Tests can be found in the `TFTF Getting Started`_.
+
 Use the following instructions to build TF-A with `TF-A Tests`_ as the
 non-secure payload (BL33).
 
-**1. Obtain and build TF-A Tests**
-
 .. code:: shell
 
  git clone https://git.trustedfirmware.org/TF-A/tf-a-tests.git
  cd tf-a-tests
- make CROSS_COMPILE=aarch64-none-elf- PLAT=fvp DEBUG=1
+ make CROSS_COMPILE=aarch64-none-elf- PLAT=fvp DEBUG=1 all pack_realm
 
-This produces a TF-A Tests binary (*tftf.bin*) in the *build/fvp/debug* directory.
+This produces a TF-A Tests binary (**tftf.bin**) with Realm payload packaged
+and **sp_layout.json** in the **build/fvp/debug** directory.
 
-**2. Build TF-A**
+**2. Obtain and build RMM Image**
+
+Please refer to the `RMM Getting Started`_ on how to setup
+Host Environment and build RMM.
+
+The below command shows how to build RMM using the default build options for FVP.
 
 .. code:: shell
 
+ git clone --recursive https://git.trustedfirmware.org/TF-RMM/tf-rmm.git
+ cd tf-rmm
+ cmake -DRMM_CONFIG=fvp_defcfg -S . -B build
+ cmake --build build
+
+This will generate **rmm.img** in **build** folder.
+
+**3. Build TF-A**
+
+The `TF-A Getting Started`_ has the necessary instructions to setup Host
+machine and build TF-A.
+
+To build for RME, set ``ENABLE_RME`` build option to 1 and provide the path to
+the RMM binary using the ``RMM`` build option.
+Currently, this feature is only supported for the FVP platform.
+
+.. note::
+
+ ENABLE_RME build option is currently experimental.
+
+If the ``RMM`` option is not used, then the Test Realm Payload (TRP) in TF-A
+will be built and used as the RMM.
+
+.. code:: shell
+
+ git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
  cd trusted-firmware-a
  make CROSS_COMPILE=aarch64-none-elf- \
  PLAT=fvp \
  ENABLE_RME=1 \
+ RMM=<path/to/rmm.img> \
  FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
  DEBUG=1 \
  BL33=<path/to/tftf.bin> \
  all fip
 
+This produces **bl1.bin** and **fip.bin** binaries in the **build/fvp/debug** directory.
+
+Running the tests for a 3 world FVP setup
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Use the following command to run the tests on FVP. TF-A Tests should boot
+and run the default tests including Realm world tests.
+
+.. code:: shell
+
+ FVP_Base_RevC-2xAEMvA                                          \
+ -C bp.refcounter.non_arch_start_at_default=1                   \
+ -C bp.secureflashloader.fname=<path/to/bl1.bin>                \
+ -C bp.flashloader0.fname=<path/to/fip.bin>                     \
+ -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.secure_memory=1                                          \
+ -C pci.pci_smmuv3.mmu.SMMU_ROOT_IDR0=3                         \
+ -C pci.pci_smmuv3.mmu.SMMU_ROOT_IIDR=0x43B                     \
+ -C pci.pci_smmuv3.mmu.root_register_page_offset=0x20000        \
+ -C cluster0.NUM_CORES=4                                        \
+ -C cluster0.PA_SIZE=48                                         \
+ -C cluster0.ecv_support_level=2                                \
+ -C cluster0.gicv3.cpuintf-mmap-access-level=2                  \
+ -C cluster0.gicv3.without-DS-support=1                         \
+ -C cluster0.gicv4.mask-virtual-interrupt=1                     \
+ -C cluster0.has_arm_v8-6=1                                     \
+ -C cluster0.has_amu=1                                          \
+ -C cluster0.has_branch_target_exception=1                      \
+ -C cluster0.rme_support_level=2                                \
+ -C cluster0.has_rndr=1                                         \
+ -C cluster0.has_v8_7_pmu_extension=2                           \
+ -C cluster0.max_32bit_el=-1                                    \
+ -C cluster0.stage12_tlb_size=1024                              \
+ -C cluster0.check_memory_attributes=0                          \
+ -C cluster0.ish_is_osh=1                                       \
+ -C cluster0.restriction_on_speculative_execution=2             \
+ -C cluster0.restriction_on_speculative_execution_aarch32=2     \
+ -C cluster1.NUM_CORES=4                                        \
+ -C cluster1.PA_SIZE=48                                         \
+ -C cluster1.ecv_support_level=2                                \
+ -C cluster1.gicv3.cpuintf-mmap-access-level=2                  \
+ -C cluster1.gicv3.without-DS-support=1                         \
+ -C cluster1.gicv4.mask-virtual-interrupt=1                     \
+ -C cluster1.has_arm_v8-6=1                                     \
+ -C cluster1.has_amu=1                                          \
+ -C cluster1.has_branch_target_exception=1                      \
+ -C cluster1.rme_support_level=2                                \
+ -C cluster1.has_rndr=1                                         \
+ -C cluster1.has_v8_7_pmu_extension=2                           \
+ -C cluster1.max_32bit_el=-1                                    \
+ -C cluster1.stage12_tlb_size=1024                              \
+ -C cluster1.check_memory_attributes=0                          \
+ -C cluster1.ish_is_osh=1                                       \
+ -C cluster1.restriction_on_speculative_execution=2             \
+ -C cluster1.restriction_on_speculative_execution_aarch32=2     \
+ -C pctl.startup=0.0.0.0                                        \
+ -C bp.smsc_91c111.enabled=1                                    \
+ -C bp.hostbridge.userNetworking=1
+
+The bottom of the output from *uart0* should look something like the following.
+
+.. code-block:: shell
+
+ ...
+
+ > Test suite 'FF-A Interrupt'
+                                                                Passed
+ > Test suite 'SMMUv3 tests'
+                                                                Passed
+ > Test suite 'PMU Leakage'
+                                                                Passed
+ > Test suite 'DebugFS'
+                                                                Passed
+ > Test suite 'RMI and SPM tests'
+                                                                Passed
+ > Test suite 'Realm payload at EL1'
+                                                                Passed
+ > Test suite 'Invalid memory access'
+                                                                Passed
+ ...
+
+Building TF-A with RME enabled Linux Kernel
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If an RME enabled Linux kernel and filesystem is available for testing,
+and a suitable NS boot loader is not available, then this option can be used to
+launch kernel directly after BL31:
+
+.. code-block:: shell
+
+ cd trusted-firmware-a
+ make CROSS_COMPILE=aarch64-none-elf- \
+ PLAT=fvp \
+ ENABLE_RME=1 \
+ RMM=<path/to/rmm.img> \
+ FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
+ DEBUG=1 \
+ ARM_LINUX_KERNEL_AS_BL33=1 \
+ PRELOADED_BL33_BASE=0x84000000 \
+ all fip
+
+Boot and run the RME enabled Linux Kernel
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Use the following additional arguments to boot the kernel on FVP.
+
+.. code-block:: shell
+
+ --data cluster0.cpu0=<path_to_kernel_Image>@0x84000000         \
+ -C bp.virtioblockdevice.image_path=<path_to_rootfs.ext4>
+
-This produces *bl1.bin* and *fip.bin* binaries in the *build/fvp/debug* directory.
-The above command also builds TRP. The TRP binary is packaged in *fip.bin*.
+.. tip::
+
+ Set the FVP option `cache_state_modelled=0` to run Linux based tests much faster.
 
 Four-world execution with Hafnium and TF-A Tests
-****************************************************
-Four-world execution involves software components at each security state: root,
+*************************************************
+
+Four-world execution involves software components in each security state: root,
 secure, realm and non-secure. This section describes how to build TF-A
-with four-world support. We use TF-A as the root firmware, `Hafnium`_ as the
-secure component, TRP as the realm-world firmware and TF-A Tests as the
-non-secure payload.
+with four-world support.
 
-Before building TF-A, you first need to build the other software components.
-You can find instructions on how to get and build TF-A Tests above.
+We use TF-A as the root firmware, `Hafnium SPM`_ is the reference Secure world component
+and the software components for the other 2 worlds (Realm and Non-Secure)
+are as described in the previous section.
 
 **1. Obtain and build Hafnium**
 
@@ -164,6 +316,27 @@
  cd hafnium
  #  Use the default prebuilt LLVM/clang toolchain
  PATH=$PWD/prebuilts/linux-x64/clang/bin:$PWD/prebuilts/linux-x64/dtc:$PATH
+
+Feature MTE needs to be disabled in Hafnium build, apply following patch to
+project/reference submodule
+
+.. code:: diff
+
+ diff --git a/BUILD.gn b/BUILD.gn
+ index cc6a78f..234b20a 100644
+ --- a/BUILD.gn
+ +++ b/BUILD.gn
+ @@ -83,7 +83,6 @@ aarch64_toolchains("secure_aem_v8a_fvp") {
+     pl011_base_address = "0x1c090000"
+     smmu_base_address = "0x2b400000"
+     smmu_memory_size = "0x100000"
+ -    enable_mte = "1"
+     plat_log_level = "LOG_LEVEL_INFO"
+   }
+ }
+
+.. code:: shell
+
  make PROJECT=reference
 
 The Hafnium binary should be located at
@@ -173,6 +346,8 @@
 
 Build TF-A with RME as well as SPM enabled.
 
+Use sp_layout.json previously generated in tf-a-test build.
+
 .. code:: shell
 
  make CROSS_COMPILE=aarch64-none-elf- \
@@ -184,92 +359,33 @@
  BRANCH_PROTECTION=1 \
  CTX_INCLUDE_PAUTH_REGS=1 \
  DEBUG=1 \
- SP_LAYOUT_FILE=<path/to/tf-a-tests>/build/fvp/debug/sp_layout.json> \
+ SP_LAYOUT_FILE=<path/to/sp_layout.json> \
  BL32=<path/to/hafnium.bin> \
  BL33=<path/to/tftf.bin> \
+ RMM=<path/to/rmm.img> \
  all fip
 
-Running the tests
-*********************
-Use the following command to run the tests on FVP. TF-A Tests should boot
-and run the default tests including RME tests.
+Running the tests for a 4 world FVP setup
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. code:: shell
-
- FVP_Base_RevC-2xAEMvA \
- -C bp.flashloader0.fname=<path/to/fip.bin> \
- -C bp.secureflashloader.fname=<path/to/bl1.bin> \
- -C bp.refcounter.non_arch_start_at_default=1 \
- -C bp.refcounter.use_real_time=0 \
- -C bp.ve_sysregs.exit_on_shutdown=1 \
- -C cache_state_modelled=1 \
- -C cluster0.NUM_CORES=4 \
- -C cluster0.PA_SIZE=48 \
- -C cluster0.ecv_support_level=2 \
- -C cluster0.gicv3.cpuintf-mmap-access-level=2 \
- -C cluster0.gicv3.without-DS-support=1 \
- -C cluster0.gicv4.mask-virtual-interrupt=1 \
- -C cluster0.has_arm_v8-6=1 \
- -C cluster0.has_branch_target_exception=1 \
- -C cluster0.has_rme=1 \
- -C cluster0.has_rndr=1 \
- -C cluster0.has_amu=1 \
- -C cluster0.has_v8_7_pmu_extension=2 \
- -C cluster0.max_32bit_el=-1 \
- -C cluster0.restriction_on_speculative_execution=2 \
- -C cluster0.restriction_on_speculative_execution_aarch32=2 \
- -C cluster1.NUM_CORES=4 \
- -C cluster1.PA_SIZE=48 \
- -C cluster1.ecv_support_level=2 \
- -C cluster1.gicv3.cpuintf-mmap-access-level=2 \
- -C cluster1.gicv3.without-DS-support=1 \
- -C cluster1.gicv4.mask-virtual-interrupt=1 \
- -C cluster1.has_arm_v8-6=1 \
- -C cluster1.has_branch_target_exception=1 \
- -C cluster1.has_rme=1 \
- -C cluster1.has_rndr=1 \
- -C cluster1.has_amu=1 \
- -C cluster1.has_v8_7_pmu_extension=2 \
- -C cluster1.max_32bit_el=-1 \
- -C cluster1.restriction_on_speculative_execution=2 \
- -C cluster1.restriction_on_speculative_execution_aarch32=2 \
- -C pci.pci_smmuv3.mmu.SMMU_AIDR=2 \
- -C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B \
- -C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002 \
- -C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714 \
- -C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0475 \
- -C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002 \
- -C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0 \
- -C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0 \
- -C bp.pl011_uart0.out_file=uart0.log \
- -C bp.pl011_uart1.out_file=uart1.log \
- -C bp.pl011_uart2.out_file=uart2.log \
- -C pctl.startup=0.0.0.0 \
- -Q 1000 \
- "$@"
+Use the following arguments in addition to
+`Running the tests for a 3 world FVP setup`_ to run tests for 4 world setup.
 
-The bottom of the output from *uart0* should look something like the following.
-
-.. code-block:: shell
-
- ...
-
- > Test suite 'FF-A Interrupt'
-                                                                Passed
- > Test suite 'SMMUv3 tests'
-                                                                Passed
- > Test suite 'PMU Leakage'
-                                                                Passed
- > Test suite 'DebugFS'
-                                                                Passed
- > Test suite 'Realm payload tests'
-                                                                Passed
- > Test suite 'Invalid memory access'
-                                                                Passed
- ...
+.. code:: shell
 
+ -C pci.pci_smmuv3.mmu.SMMU_AIDR=2              \
+ -C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B     \
+ -C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002     \
+ -C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714         \
+ -C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0475     \
+ -C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002   \
+ -C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0            \
+ -C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0
 
 .. _Arm Confidential Compute Architecture (Arm CCA): https://www.arm.com/why-arm/architecture/security-features/arm-confidential-compute-architecture
 .. _Arm Architecture Models website: https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models
+.. _TF-A Getting Started: https://trustedfirmware-a.readthedocs.io/en/latest/getting_started/index.html
 .. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io/en/latest
-.. _Hafnium: https://www.trustedfirmware.org/projects/hafnium
+.. _TFTF Getting Started: https://trustedfirmware-a-tests.readthedocs.io/en/latest/getting_started/index.html
+.. _Hafnium SPM: https://www.trustedfirmware.org/projects/hafnium
+.. _RMM Getting Started: https://git.trustedfirmware.org/TF-RMM/tf-rmm.git/tree/docs/getting_started/index.rst
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 7ba79b9..55e265c 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -256,6 +256,10 @@
 -  ``ERRATA_A76_1946160``: This applies errata 1946160 workaround to Cortex-A76
    CPU. This needs to be enabled only for revisions r3p0 - r4p1 of the CPU.
 
+-  ``ERRATA_A76_2743102``: This applies errata 2743102 workaround to Cortex-A76
+   CPU. This needs to be enabled for all revisions <= r4p1 of the CPU and is
+   still open.
+
 For Cortex-A77, the following errata build flags are defined :
 
 -  ``ERRATA_A77_1508412``: This applies errata 1508412 workaround to Cortex-A77
@@ -276,6 +280,9 @@
  -  ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77
     CPU. This needs to be enabled for revisions <= r1p1 of the CPU.
 
+ -  ``ERRATA_A77_2743100``: This applies errata 2743100 workaround to Cortex-A77
+    CPU. This needs to be enabled for r0p0, r1p0, and r1p1, it is still open.
+
 For Cortex-A78, the following errata build flags are defined :
 
 -  ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78
@@ -399,6 +406,10 @@
    CPU. This needs to be enabled for revisions r3p0, r3p1, r4p0, and r4p1, for
    revisions r0p0, r1p0, and r2p0 there is no workaround.
 
+-  ``ERRATA_N1_2743102``: This applies errata 2743102 workaround to Neoverse-N1
+   CPU. This needs to be enabled for all revisions <= r4p1 of the CPU and is
+   still open.
+
 For Neoverse V1, the following errata build flags are defined :
 
 -  ``ERRATA_V1_1618635``: This applies errata 1618635 workaround to Neoverse-V1
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 71fdfcb..84bba18 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -990,9 +990,10 @@
 directly, the others are saved into memory for retrieval (if needed) by the
 handler. The handler is also provided with an opaque ``handle`` for use with the
 supporting library for parameter retrieval, setting return values and context
-manipulation; and with ``flags`` indicating the security state of the caller. The
-framework finally sets up the execution stack for the handler, and invokes the
-services ``handle()`` function.
+manipulation. The ``flags`` parameter indicates the security state of the caller
+and the state of the SVE hint bit per the SMCCCv1.3. The framework finally sets
+up the execution stack for the handler, and invokes the services ``handle()``
+function.
 
 On return from the handler the result registers are populated in X0-X7 as needed
 before restoring the stack and CPU state and returning from the original SMC.
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 5980050..402de13 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -569,10 +569,11 @@
    EL1 for handling. The default value of this option is ``0``, which means the
    Group 0 interrupts are assumed to be handled by Secure EL1.
 
--  ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError
-   Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to
-   ``0`` (default), these exceptions will be trapped in the current exception
-   level (or in EL1 if the current exception level is EL0).
+-  ``HANDLE_EA_EL3_FIRST_NS``: When set to ``1``, External Aborts and SError
+   Interrupts, resulting from errors in NS world, will be always trapped in
+   EL3 i.e. in BL31 at runtime. When set to ``0`` (default), these exceptions
+   will be trapped in the current exception level (or in EL1 if the current
+   exception level is EL0).
 
 -  ``HW_ASSISTED_COHERENCY``: On most Arm systems to-date, platform-specific
    software operations are required for CPUs to enter and exit coherency.
@@ -609,22 +610,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             |
-   +-----------+------------------------------------+
+   +---------------------------+------------------------------------+
+   |         KEY_ALG           |        Possible key sizes          |
+   +===========================+====================================+
+   |           rsa             | 1024 , 2048 (default), 3072, 4096* |
+   +---------------------------+------------------------------------+
+   |          ecdsa            |            unavailable             |
+   +---------------------------+------------------------------------+
+   |  ecdsa-brainpool-regular  |            unavailable             |
+   +---------------------------+------------------------------------+
+   |  ecdsa-brainpool-twisted  |            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.
@@ -725,7 +732,7 @@
    or later CPUs. This flag can take the values 0 to 2, to align with the
    ``FEATURE_DETECTION`` mechanism.
 
-   When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST`` must also be
+   When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST_NS`` must also be
    set to ``1``.
 
    This option is disabled by default.
@@ -851,6 +858,9 @@
    hardware will limit the effective VL to the maximum physically supported
    VL.
 
+-  ``TRNG_SUPPORT``: Setting this to ``1`` enables support for True
+   Random Number Generator Interface to BL31 image. This defaults to ``0``.
+
 -  ``TRUSTED_BOARD_BOOT``: Boolean flag to include support for the Trusted Board
    Boot feature. When set to '1', BL1 and BL2 images include support to load
    and verify the certificates and images in a FIP, and BL1 includes support
@@ -1028,6 +1038,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..1762558 100644
--- a/docs/getting_started/docs-build.rst
+++ b/docs/getting_started/docs-build.rst
@@ -31,8 +31,8 @@
 requirements file as an argument to ``pip3`` automatically installs the specific
 module versions required by |TF-A|.
 
-An example set of installation commands for Ubuntu 18.04 LTS follows, assuming
-that the working directory is ``docs``:
+An example set of installation commands for Ubuntu follows, assuming that the
+working directory is ``docs``:
 
 .. code:: shell
 
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 6996c17..aa57e1d 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -23,8 +23,8 @@
 discusses these in detail. The subsequent sections discuss the remaining
 modifications for each BL stage in detail.
 
-Please refer to the :ref:`Platform Compatibility Policy` for the policy
-regarding compatibility and deprecation of these porting interfaces.
+Please refer to the :ref:`Platform Ports Policy` for the policy regarding
+compatibility and deprecation of these porting interfaces.
 
 Only Arm development platforms (such as FVP and Juno) may use the
 functions/definitions in ``include/plat/arm/common/`` and the corresponding
@@ -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
 ---------------------------------------------
 
@@ -2468,7 +2512,7 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 This value must be defined to the UUID of the TRNG backend that is specific to
-the hardware after ``plat_trng_setup`` function is called. This value must
+the hardware after ``plat_entropy_setup`` function is called. This value must
 conform to the SMCCC calling convention; The most significant 32 bits of the
 UUID must not equal ``0xffffffff`` or the signed integer ``-1`` as this value in
 w0 indicates failure to get a TRNG source.
@@ -3156,6 +3200,34 @@
 (``GICD_IGRPMODRn``) is read to figure out whether the interrupt is configured
 as Group 0 secure interrupt, Group 1 secure interrupt or Group 1 NS interrupt.
 
+Common helper functions
+-----------------------
+
+Function : do_panic()
+~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : void
+
+This API is called from assembly files when encountering a critical failure that
+cannot be recovered from. It also invokes elx_panic() which allows to report a
+crash from lower exception level. This function assumes that it is invoked from
+a C runtime environment i.e. valid stack exists. This call **must not** return.
+
+Function : panic()
+~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : void
+
+This API called from C files when encountering a critical failure that cannot
+be recovered from. This function in turn prints backtrace (if enabled) and calls
+do_panic(). This call **must not** return.
+
 Crash Reporting mechanism (in BL31)
 -----------------------------------
 
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 65a66b6..d8d3b7a 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.
 
@@ -54,15 +54,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:
@@ -104,14 +104,15 @@
 
     sudo apt install device-tree-compiler
 
-Additionally, to install an up-to-date version of Node.js, you can use the `Node
-Version Manager`_ to install a version of your choosing (we recommend 16, but
-later LTS versions might offer a more stable experience):
+Additionally, to install a version of Node.js compatible with TF-A's repository
+scripts, you can use the `Node Version Manager`_. To install both NVM and an
+appropriate version of Node.js, run the following **from the root directory of
+the repository**:
 
 .. code:: shell
 
-    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | "$SHELL"
-    exec "$SHELL" -ic "nvm install 16; exec $SHELL"
+    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
+    exec "$SHELL" -ic "nvm install; exec $SHELL"
 
 .. _Node Version Manager: https://github.com/nvm-sh/nvm#install--update-script
 
diff --git a/docs/getting_started/psci-lib-integration-guide.rst b/docs/getting_started/psci-lib-integration-guide.rst
index 3735265..4d690a9 100644
--- a/docs/getting_started/psci-lib-integration-guide.rst
+++ b/docs/getting_started/psci-lib-integration-guide.rst
@@ -337,16 +337,6 @@
 This function invalidates (flushes) the data cache for memory at address
 ``addr`` (first argument) address and of size ``size`` (second argument).
 
-**Function : do_panic()**
-
-::
-
-    Argument : void
-    Return   : void
-
-This function will be called by the PSCI library on encountering a critical
-failure that cannot be recovered from. This function **must not** return.
-
 CPU Context management API
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index b28c247..42c0eda 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -12,61 +12,59 @@
 (64-bit host machine only).
 
 .. note::
-   The FVP models used are Version 11.17 Build 21, unless otherwise stated.
+   The FVP models used are Version 11.19 Build 14, unless otherwise stated.
 
 -  ``Foundation_Platform``
--  ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502``
--  ``FVP_Base_AEMv8A-AEMv8A`` (For certain configurations also uses 11.14/21)
--  ``FVP_Base_AEMv8A-GIC600AE``
--  ``FVP_Base_AEMvA``         (For certain configurations also uses 0.0/6684)
--  ``FVP_Base_Cortex-A32x4``  (Version 11.12/38)
+-  ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502`` (Version 11.17/21)
+-  ``FVP_Base_AEMv8A-GIC600AE`` (Version 11.17/21)
+-  ``FVP_Base_AEMvA``
+-  ``FVP_Base_AEMvA-AEMvA``
+-  ``FVP_Base_Cortex-A32x4`` (Version 11.12/38)
 -  ``FVP_Base_Cortex-A35x4``
 -  ``FVP_Base_Cortex-A53x4``
--  ``FVP_Base_Cortex-A55x4``
+-  ``FVP_Base_Cortex-A55``
 -  ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
+-  ``FVP_Base_Cortex-A55x4+Cortex-A76x2``
 -  ``FVP_Base_Cortex-A57x1-A53x1``
 -  ``FVP_Base_Cortex-A57x2-A53x4``
--  ``FVP_Base_Cortex-A57x4-A53x4``
 -  ``FVP_Base_Cortex-A57x4``
--  ``FVP_Base_Cortex-A65AEx8``
--  ``FVP_Base_Cortex-A65x4``
--  ``FVP_Base_Cortex-A710x4``
--  ``FVP_Base_Cortex-A72x4-A53x4``
+-  ``FVP_Base_Cortex-A57x4-A53x4``
+-  ``FVP_Base_Cortex-A65``
+-  ``FVP_Base_Cortex-A65AE``
+-  ``FVP_Base_Cortex-A710x4`` (Version 11.17/21)
 -  ``FVP_Base_Cortex-A72x4``
--  ``FVP_Base_Cortex-A73x4-A53x4``
+-  ``FVP_Base_Cortex-A72x4-A53x4``
 -  ``FVP_Base_Cortex-A73x4``
--  ``FVP_Base_Cortex-A75x4``
--  ``FVP_Base_Cortex-A76AEx4``
--  ``FVP_Base_Cortex-A76AEx8``
--  ``FVP_Base_Cortex-A76x4``
--  ``FVP_Base_Cortex-A77x4``
--  ``FVP_Base_Cortex-A78x4``
--  ``FVP_Base_Neoverse-E1x1``
--  ``FVP_Base_Neoverse-E1x2``
--  ``FVP_Base_Neoverse-E1x4``
--  ``FVP_Base_Neoverse-N1x4``
--  ``FVP_Base_Neoverse-N2x4`` (Version 11.12 build 38)
--  ``FVP_Base_Neoverse-V1x4``
--  ``FVP_Base_RevC-2xAEMvA``  (For certain configurations also uses 0.0/6557)
--  ``FVP_CSS_SGI-575``        (Version 11.17/33)
+-  ``FVP_Base_Cortex-A73x4-A53x4``
+-  ``FVP_Base_Cortex-A75``
+-  ``FVP_Base_Cortex-A76``
+-  ``FVP_Base_Cortex-A76AE``
+-  ``FVP_Base_Cortex-A77``
+-  ``FVP_Base_Cortex-A78``
+-  ``FVP_Base_Cortex-A78C``
+-  ``FVP_Base_Cortex-X2x4`` (Version 11.17/21)
+-  ``FVP_Base_Neoverse-E1``
+-  ``FVP_Base_Neoverse-N1``
+-  ``FVP_Base_Neoverse-N2x4`` (Version 11.16/16)
+-  ``FVP_Base_Neoverse-V1``
+-  ``FVP_Base_RevC-2xAEMvA``
 -  ``FVP_Morello``            (Version 0.11/33)
--  ``FVP_RD_E1_edge``         (Version 11.17/33)
--  ``FVP_RD_N1_edge_dual``    (Version 11.17/33)
--  ``FVP_RD_N1_edge``         (Version 11.17/33)
--  ``FVP_RD_V1``              (Version 11.17/33)
--  ``FVP_TC0``
--  ``FVP_TC1``
+-  ``FVP_RD_E1_edge``         (Version 11.17/29)
+-  ``FVP_RD_V1``              (Version 11.17/29)
+-  ``FVP_TC0`` (Version 11.17/18)
+-  ``FVP_TC1`` (Version 11.17/33)
+-  ``FVP_TC2`` (Version 11.18/28)
 
 The latest version of the AArch32 build of TF-A has been tested on the
 following Arm FVPs without shifted affinities, and that do not support threaded
 CPU cores (64-bit host machine only).
 
 -  ``FVP_Base_AEMvA``
--  ``FVP_Base_AEMv8A-AEMv8A``
+-  ``FVP_Base_AEMvA-AEMvA``
 -  ``FVP_Base_Cortex-A32x4``
 
 .. note::
-   The ``FVP_Base_RevC-2xAEMv8A`` FVP only supports shifted affinities, which
+   The ``FVP_Base_RevC-2xAEMvA`` FVP only supports shifted affinities, which
    is not compatible with legacy GIC configurations. Therefore this FVP does not
    support these legacy GIC configurations.
 
diff --git a/docs/plat/deprecated.rst b/docs/plat/deprecated.rst
deleted file mode 100644
index 557454c..0000000
--- a/docs/plat/deprecated.rst
+++ /dev/null
@@ -1,24 +0,0 @@
-Deprecated platforms
-====================
-
-Process of deprecating a platform
----------------------------------
-
-Platform can be deprecated and its source can be kept in repository for a cooling
-off period before deleting it or it can be deleted straight away. For later types
-Deprecated/Deleted version would be same.
-
-List of deprecated platforms
-----------------------------
-
-+----------------+----------------+--------------------+--------------------+
-|    Platform    |     Vendor     | Deprecated version |  Deleted version   |
-+================+================+====================+====================+
-|    sgm775      |      Arm       |        2.5         |       2.7          |
-+----------------+----------------+--------------------+--------------------+
-|    mt6795      |      MTK       |        2.5         |       2.7          |
-+----------------+----------------+--------------------+--------------------+
-|    sgi575      |      Arm       |        2.8         |       3.0          |
-+----------------+----------------+--------------------+--------------------+
-|    rdn1edge    |      Arm       |        2.8         |       3.0          |
-+----------------+----------------+--------------------+--------------------+
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 28b1787..3eac6f7 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -9,7 +9,6 @@
 
    allwinner
    arm/index
-   deprecated
    meson-axg
    meson-gxbb
    meson-gxl
@@ -59,10 +58,26 @@
    - Arm Neoverse N1 System Development Platform (N1SDP)
    - Arm Neoverse Reference Design N1 Edge (RD-N1-Edge) FVP
    - Arm Neoverse Reference Design E1 Edge (RD-E1-Edge) FVP
-   - Arm SGI-575 and SGM-775
-   - MediaTek MT6795 and MT8173 SoCs
-   - Arm Morello Platform
+   - Arm SGI-575
+   - MediaTek MT8173 SoCs
+
+Deprecated platforms
+--------------------
+
++----------------+----------------+--------------------+--------------------+
+|    Platform    |     Vendor     | Deprecated version |  Deleted version   |
++================+================+====================+====================+
+|    sgm775      |      Arm       |        2.5         |       2.7          |
++----------------+----------------+--------------------+--------------------+
+|    mt6795      |      MTK       |        2.5         |       2.7          |
++----------------+----------------+--------------------+--------------------+
+|    sgi575      |      Arm       |        2.8         |       3.0          |
++----------------+----------------+--------------------+--------------------+
+|    rdn1edge    |      Arm       |        2.8         |       3.0          |
++----------------+----------------+--------------------+--------------------+
+|    tc0         |      Arm       |        2.8         |       3.0          |
++----------------+----------------+--------------------+--------------------+
 
 --------------
 
-*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst
index adb9603..ff7b573 100644
--- a/docs/plat/marvell/armada/build.rst
+++ b/docs/plat/marvell/armada/build.rst
@@ -165,14 +165,14 @@
 
 Armada37x0 specific build options:
 
-- HANDLE_EA_EL3_FIRST
+- HANDLE_EA_EL3_FIRST_NS
 
-        When ``HANDLE_EA_EL3_FIRST=1``, External Aborts and SError Interrupts will be always trapped
-        in TF-A. TF-A in this case enables dirty hack / workaround for a bug found in U-Boot and
-        Linux kernel PCIe controller driver pci-aardvark.c, traps and then masks SError interrupt
-        caused by AXI SLVERR on external access (syndrome 0xbf000002).
+        When ``HANDLE_EA_EL3_FIRST_NS=1``, External Aborts and SError Interrupts, resulting from errors
+        in NS world, will be always trapped in TF-A. TF-A in this case enables dirty hack / workaround for
+        a bug found in U-Boot and Linux kernel PCIe controller driver pci-aardvark.c, traps and then masks
+        SError interrupt caused by AXI SLVERR on external access (syndrome 0xbf000002).
 
-        Otherwise when ``HANDLE_EA_EL3_FIRST=0``, these exceptions will be trapped in the current
+        Otherwise when ``HANDLE_EA_EL3_FIRST_NS=0``, these exceptions will be trapped in the current
         exception level (or in EL1 if the current exception level is EL0). So exceptions caused by
         U-Boot will be trapped in U-Boot, exceptions caused by Linux kernel (or user applications)
         will be trapped in Linux kernel.
@@ -185,8 +185,8 @@
         recommended to not enable this workaround as it disallows propagating of all External Aborts
         to running Linux kernel and makes correctable errors as fatal aborts.
 
-        This option is now disabled by default. In past this option was enabled by default in
-        TF-A versions v2.2, v2.3, v2.4 and v2.5.
+        This option is now disabled by default. In past this option has different name "HANDLE_EA_EL3_FIRST" and
+        was enabled by default in TF-A versions v2.2, v2.3, v2.4 and v2.5.
 
 - CM3_SYSTEM_RESET
 
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/coding-guidelines.rst b/docs/process/coding-guidelines.rst
index ef319e4..26c272d 100644
--- a/docs/process/coding-guidelines.rst
+++ b/docs/process/coding-guidelines.rst
@@ -463,11 +463,11 @@
 
 --------------
 
-*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020, 2022, Arm Limited and Contributors. All rights reserved.*
 
 .. _`Linux master tree`: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/
-.. _`Procedure Call Standard for the Arm Architecture`: https://developer.arm.com/docs/ihi0042/latest/
-.. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://developer.arm.com/docs/ihi0055/latest/
+.. _`Procedure Call Standard for the Arm Architecture`: https://github.com/ARM-software/abi-aa/blob/main/aapcs32/aapcs32.rst
+.. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
 .. _`EditorConfig`: http://editorconfig.org/
 .. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
 .. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
diff --git a/docs/process/commit-style.rst b/docs/process/commit-style.rst
index de899ab..d7e937b 100644
--- a/docs/process/commit-style.rst
+++ b/docs/process/commit-style.rst
@@ -96,36 +96,25 @@
 Adding Scopes
 -------------
 
-Scopes that are either a) unblessed in the configuration file, or b) do not
-exist in the configuration file at all are considered to be deprecated. If you
-are adding a new component that does not yet have a designated scope, please
-feel free to add one.
+Scopes that are not present in the changelog configuration file are considered
+to be deprecated, and should be avoided. If you are adding a new component that
+does not yet have a designated scope, please add one.
 
 For example, if you are adding or making modifications to `Foo`'s latest and
-greatest new platform `Bar`, you would add it to the `Platforms` changelog
-section, and the hierarchy should look something like this:
+greatest new platform `Bar` then you would add it to the `Platforms` changelog
+sub-section, and the hierarchy should look something like this:
 
-.. code:: json
+.. code:: yaml
 
-    {
-        "sections": [
-            {
-                "title": "Platforms",
-                "sections": [
-                    {
-                        "title": "Foo",
-                        "scopes": ["foo"],
-                        "sections": [
-                            {
-                                "title": "Bar",
-                                "scopes": ["bar"]
-                            }
-                        ]
-                    }
-                ]
-            }
-        ]
-    }
+    - title: Platforms
+
+      subsections:
+        - title: Foo
+          scope: foo
+
+          subsections:
+            - title: Bar
+              scope: bar
 
 When creating new scopes, try to keep them short and succinct, and use kebab
 case (``this-is-kebab-case``). Components with a product name (i.e. most
@@ -138,7 +127,9 @@
 
 Commits are expected to be signed off with the ``Signed-off-by:`` trailer using
 your real name and email address. You can do this automatically by committing
-with Git's ``-s`` flag.
+with Git's ``-s`` flag. By adding this line the contributor certifies the
+contribution is made under the terms of the :download:`Developer Certificate of
+Origin <../../dco.txt>`.
 
 There may be multiple ``Signed-off-by:`` lines depending on the history of the
 patch, but one **must** be the committer. More details may be found in the
diff --git a/docs/process/index.rst b/docs/process/index.rst
index bba2b40..422ab28 100644
--- a/docs/process/index.rst
+++ b/docs/process/index.rst
@@ -7,7 +7,7 @@
    :numbered:
 
    security
-   platform-compatibility-policy
+   platform-ports-policy
    commit-style
    coding-style
    coding-guidelines
diff --git a/docs/process/platform-compatibility-policy.rst b/docs/process/platform-ports-policy.rst
similarity index 63%
rename from docs/process/platform-compatibility-policy.rst
rename to docs/process/platform-ports-policy.rst
index a10236c..7983749 100644
--- a/docs/process/platform-compatibility-policy.rst
+++ b/docs/process/platform-ports-policy.rst
@@ -1,11 +1,8 @@
-Platform Compatibility Policy
-=============================
+Platform Ports Policy
+=====================
 
-Introduction
-------------
-
-This document clarifies the project's policy around compatibility for upstream
-platforms.
+This document clarifies a couple of policy points around platform ports
+management.
 
 Platform compatibility policy
 -----------------------------
@@ -29,6 +26,24 @@
 deprecated interfaces. Platforms are expected to migrate before the removal of
 the deprecated interface.
 
+Platform deprecation policy
+---------------------------
+
+If a platform is no longer maintained, it is best to deprecate it to keep the
+projects' source tree clean and healthy. Deprecation can be a 1-stage or 2-stage
+process (up to the platform maintainers).
+
+ - *2-stage*: The platform's source code can be kept in the repository for a
+   cooling off period before deleting it (typically 2 release cycles). In this
+   case, we keep track ot the *Deprecated* version separately from the *Deleted*
+   version.
+
+ - *1-stage*: The platform's source code can be deleted straight away. In this
+   case, both versions are the same.
+
+The :ref:`Platform Ports` page provides a list of all deprecated/deleted
+platform ports (or soon to be) to this day.
+
 --------------
 
 *Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/security_advisories/security-advisory-tfv-9.rst b/docs/security_advisories/security-advisory-tfv-9.rst
index 08bfdc4..d73e74b 100644
--- a/docs/security_advisories/security-advisory-tfv-9.rst
+++ b/docs/security_advisories/security-advisory-tfv-9.rst
@@ -75,7 +75,7 @@
 +----------------------+
 | Cortex-A710          |
 +----------------------+
-| Cortex-Makalu        |
+| Cortex-A715          |
 +----------------------+
 | Cortex-Hunter        |
 +----------------------+
@@ -99,7 +99,9 @@
 Convention specification`_ for more details.
 
 `Gerrit topic #spectre_bhb`_ This patchset implements the Spectre-BHB loop
-workaround for CPUs mentioned in the above table. It also mitigates against
+workaround for CPUs mentioned in the above table. For CPUs supporting
+speculative barrier instruction, the loop workaround is optimised by using SB
+in place of the common DSB and ISB sequence. It also mitigates against
 this vulnerability for Cortex-A72 CPU versions that support the CSV2 feature
 (from r1p0). The patch stack also includes an implementation for a specified
 `CVE-2022-23960`_ workaround SMC(``SMCCC_ARCH_WORKAROUND_3``) for use by normal
diff --git a/drivers/arm/rss/rss_comms.mk b/drivers/arm/rss/rss_comms.mk
index 8f19a0b..c1c994b 100644
--- a/drivers/arm/rss/rss_comms.mk
+++ b/drivers/arm/rss/rss_comms.mk
@@ -4,6 +4,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+$(warning "RSS driver is an experimental feature")
+
 RSS_COMMS_SOURCES	:=	$(addprefix drivers/arm/rss/,			\
 					rss_comms.c				\
 					rss_comms_protocol.c			\
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_x509_parser.c b/drivers/auth/mbedtls/mbedtls_x509_parser.c
index 129566b..993ef12 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
  */
@@ -114,10 +114,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;
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..e03cf0f
--- /dev/null
+++ b/drivers/st/crypto/stm32_pka.c
@@ -0,0 +1,707 @@
+/*
+ * 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;
+
+#pragma weak stm32_pka_get_platdata
+
+int stm32_pka_get_platdata(struct stm32_pka_platdata *pdata)
+{
+	return -ENODEV;
+}
+
+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) {
+		err = stm32_pka_get_platdata(&pka_pdata);
+		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..02baf21
--- /dev/null
+++ b/drivers/st/crypto/stm32_saes.c
@@ -0,0 +1,913 @@
+/*
+ * 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)
+
+#define pragma weak stm32_saes_get_platdata
+
+static struct stm32_saes_platdata saes_pdata;
+
+int stm32_saes_get_platdata(struct stm32_saes_platdata *pdata)
+{
+	return -ENODEV;
+}
+
+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) {
+		err = stm32_saes_get_platdata(&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/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/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/include/common/debug.h b/include/common/debug.h
index a7ca0d7..af47999 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -91,9 +91,10 @@
 # define VERBOSE(...)	no_tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
 #endif
 
+const char *get_el_str(unsigned int el);
+
 #if ENABLE_BACKTRACE
 void backtrace(const char *cookie);
-const char *get_el_str(unsigned int el);
 #else
 #define backtrace(x)
 #endif
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/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/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/smccc.h b/include/lib/smccc.h
index 9940ea9..cce91af 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -37,6 +37,10 @@
 #define FUNCID_OEN_MASK			U(0x3f)
 #define FUNCID_OEN_WIDTH		U(6)
 
+#define FUNCID_SVE_HINT_SHIFT          U(16)
+#define FUNCID_SVE_HINT_MASK           U(1)
+#define FUNCID_SVE_HINT_WIDTH          U(1)
+
 #define FUNCID_NUM_SHIFT		U(0)
 #define FUNCID_NUM_MASK			U(0xffff)
 #define FUNCID_NUM_WIDTH		U(16)
@@ -122,6 +126,12 @@
  *   0        0      SMC_FROM_SECURE
  *   0        1      SMC_FROM_NON_SECURE
  *   1        1      SMC_FROM_REALM
+ *
+ * Bit 16 of flags records the caller's SMC
+ * SVE hint bit according to SMCCCv1.3.
+ * It can be consumed by dispatchers using
+ * is_sve_hint_set macro.
+ *
  */
 
 #define SMC_FROM_SECURE		(U(0) << 0)
@@ -148,6 +158,9 @@
 #define is_caller_secure(_f)		(!is_caller_non_secure(_f))
 #endif /* ENABLE_RME */
 
+#define is_sve_hint_set(_f)		(((_f) & (FUNCID_SVE_HINT_MASK \
+						<< FUNCID_SVE_HINT_SHIFT)) != U(0))
+
 /* The macro below is used to identify a Standard Service SMC call */
 #define is_std_svc_call(_fid)		(GET_SMC_OEN(_fid) == OEN_STD_START)
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index c90441c..8407bbd 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -16,10 +16,10 @@
 #if ENABLE_RME
 #include <services/rmm_core_manifest.h>
 #endif
+#include <drivers/fwu/fwu_metadata.h>
 #if TRNG_SUPPORT
 #include "plat_trng.h"
-#endif
-#include <drivers/fwu/fwu_metadata.h>
+#endif /* TRNG_SUPPORT */
 #if DRTM_SUPPORT
 #include "plat_drtm.h"
 #endif /* DRTM_SUPPORT */
@@ -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,
diff --git a/include/services/trng_svc.h b/include/services/trng_svc.h
index ed4d557..92417c2 100644
--- a/include/services/trng_svc.h
+++ b/include/services/trng_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,7 +17,7 @@
 #define ARM_TRNG_FEATURES	U(0x84000051)
 #define ARM_TRNG_GET_UUID	U(0x84000052)
 #define ARM_TRNG_RND32		U(0x84000053)
-#define ARM_TRNG_RND64		U(0xc4000053)
+#define ARM_TRNG_RND64		U(0xC4000053)
 
 /* TRNG version numbers */
 #define TRNG_VERSION_MAJOR	(0x1)
@@ -30,19 +30,17 @@
 #define TRNG_E_NO_ENTROPY	(-3)
 #define TRNG_E_NOT_IMPLEMENTED	(-4)
 
-#if TRNG_SUPPORT
+/* TRNG Entropy Bit Numbers */
+#define TRNG_RND32_ENTROPY_MAXBITS	(96U)
+#define TRNG_RND64_ENTROPY_MAXBITS	(192U)
+
+/* Public API to perform the initial TRNG entropy setup */
 void trng_setup(void);
+
+/* Public API to verify function id is part of TRNG */
 bool is_trng_fid(uint32_t smc_fid);
-#else
-static inline void trng_setup(void)
-{
-}
 
-static inline bool is_trng_fid(uint32_t smc_fid)
-{
-	return false;
-}
-#endif
+/* Handler to be called to handle TRNG smc calls */
 uintptr_t trng_smc_handler(
 	uint32_t smc_fid,
 	u_register_t x1,
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_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 6d4017a..36507de 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -586,6 +586,30 @@
 	b	cpu_rev_var_range
 endfunc check_errata_1946160
 
+	/* ----------------------------------------------------
+	 * Errata Workaround for Cortex-A76 Errata #2743102
+	 * This applies to revisions <= r4p1 and is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * ----------------------------------------------------
+	 */
+func errata_a76_2743102_wa
+	mov	x17, x30
+	bl	check_errata_2743102
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_a76_2743102_wa
+
+func check_errata_2743102
+	/* Applies to all revisions <= r4p1 */
+	mov	x1, #0x41
+	b	cpu_rev_var_ls
+endfunc check_errata_2743102
+
 func check_errata_cve_2018_3639
 #if WORKAROUND_CVE_2018_3639
 	mov	x0, #ERRATA_APPLIES
@@ -748,6 +772,12 @@
 	mrs	x0, CORTEX_A76_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A76_CORE_PWRDN_EN_MASK
 	msr	CORTEX_A76_CPUPWRCTLR_EL1, x0
+#if ERRATA_A76_2743102
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_a76_2743102_wa
+	mov	x30, x15
+#endif /* ERRATA_A76_2743102 */
 	isb
 	ret
 endfunc cortex_a76_core_pwr_dwn
@@ -768,6 +798,7 @@
 	 */
 	report_errata ERRATA_A76_1073348, cortex_a76, 1073348
 	report_errata ERRATA_A76_1130799, cortex_a76, 1130799
+	report_errata ERRATA_A76_1165522, cortex_a76, 1165522
 	report_errata ERRATA_A76_1220197, cortex_a76, 1220197
 	report_errata ERRATA_A76_1257314, cortex_a76, 1257314
 	report_errata ERRATA_A76_1262606, cortex_a76, 1262606
@@ -775,9 +806,9 @@
 	report_errata ERRATA_A76_1275112, cortex_a76, 1275112
 	report_errata ERRATA_A76_1286807, cortex_a76, 1286807
 	report_errata ERRATA_A76_1791580, cortex_a76, 1791580
-	report_errata ERRATA_A76_1165522, cortex_a76, 1165522
 	report_errata ERRATA_A76_1868343, cortex_a76, 1868343
 	report_errata ERRATA_A76_1946160, cortex_a76, 1946160
+	report_errata ERRATA_A76_2743102, cortex_a76, 2743102
 	report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639
 	report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953
 	report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index 8cafe4a..2882df7 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -227,6 +227,30 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2356587
 
+	/* -----------------------------------------------------------------
+	 * Errata Workaround for Cortex A77 Errata #2743100
+	 * This applies to revisions r0p0, r1p0, and r1p1 and is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * -----------------------------------------------------------------
+	 */
+func errata_a77_2743100_wa
+	mov	x17, x30
+	bl	check_errata_2743100
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_a77_2743100_wa
+
+func check_errata_2743100
+	/* Applies to r0p0, r1p0, and r1p1 right now */
+	mov	x1, #0x11
+	b	cpu_rev_var_ls
+endfunc check_errata_2743100
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -330,6 +354,12 @@
 	mrs	x0, CORTEX_A77_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A77_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	msr	CORTEX_A77_CPUPWRCTLR_EL1, x0
+#if ERRATA_A77_2743100
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_a77_2743100_wa
+	mov	x30, x15
+#endif /* ERRATA_A77_2743100 */
 	isb
 	ret
 endfunc cortex_a77_core_pwr_dwn
@@ -354,6 +384,7 @@
 	report_errata ERRATA_A77_1925769, cortex_a77, 1925769
 	report_errata ERRATA_A77_1946167, cortex_a77, 1946167
 	report_errata ERRATA_A77_2356587, cortex_a77, 2356587
+	report_errata ERRATA_A77_2743100, cortex_a77, 2743100
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a77, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index b75b0c1..ec62519 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -468,6 +468,30 @@
 	b	cpu_rev_var_range
 endfunc check_errata_1946160
 
+	/* ----------------------------------------------------
+	 * Errata Workaround for Neoverse N1 Errata #2743102
+	 * This applies to revisions <= r4p1 and is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * ----------------------------------------------------
+	 */
+func errata_n1_2743102_wa
+	mov	x17, x30
+	bl	check_errata_2743102
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_n1_2743102_wa
+
+func check_errata_2743102
+	/* Applies to all revisions <= r4p1 */
+	mov	x1, #0x41
+	b	cpu_rev_var_ls
+endfunc check_errata_2743102
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -613,6 +637,12 @@
 	mrs	x0, NEOVERSE_N1_CPUPWRCTLR_EL1
 	orr	x0, x0, #NEOVERSE_N1_CORE_PWRDN_EN_MASK
 	msr	NEOVERSE_N1_CPUPWRCTLR_EL1, x0
+#if ERRATA_N1_2743102
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_n1_2743102_wa
+	mov	x30, x15
+#endif /* ERRATA_N1_2743102 */
 	isb
 	ret
 endfunc neoverse_n1_core_pwr_dwn
@@ -645,6 +675,7 @@
 	report_errata ERRATA_N1_1542419, neoverse_n1, 1542419
 	report_errata ERRATA_N1_1868343, neoverse_n1, 1868343
 	report_errata ERRATA_N1_1946160, neoverse_n1, 1946160
+	report_errata ERRATA_N1_2743102, neoverse_n1, 2743102
 	report_errata ERRATA_DSU_936184, neoverse_n1, dsu_936184
 	report_errata WORKAROUND_CVE_2022_23960, neoverse_n1, cve_2022_23960
 
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index b4421dd..f19c16e 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -287,6 +287,10 @@
 # only to revisions r3p0 - r4p1 of the Cortex A76 cpu.
 ERRATA_A76_1946160	?=0
 
+# Flag to apply erratum 2743102 workaround during powerdown. This erratum
+# applies to all revisions <= r4p1 of the Cortex A76 cpu and is still open.
+ERRATA_A76_2743102	?=0
+
 # Flag to apply erratum 1508412 workaround during reset. This erratum applies
 # only to revision <= r1p0 of the Cortex A77 cpu.
 ERRATA_A77_1508412	?=0
@@ -311,6 +315,10 @@
 # to revisions <= r1p1 of the Cortex A77 cpu.
 ERRATA_A77_1800714	?=0
 
+# Flag to apply erratum 2743100 workaround during power down. This erratum
+# applies to revisions r0p0, r1p0, and r1p1, it is still open.
+ERRATA_A77_2743100	?=0
+
 # Flag to apply erratum 1688305 workaround during reset. This erratum applies
 # to revisions r0p0 - r1p0 of the A78 cpu.
 ERRATA_A78_1688305	?=0
@@ -450,6 +458,10 @@
 # exists in revisions r0p0, r1p0, and r2p0 as well but there is no workaround.
 ERRATA_N1_1946160	?=0
 
+# Flag to apply erratum 2743102 workaround during powerdown. This erratum
+# 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
@@ -912,6 +924,10 @@
 $(eval $(call assert_boolean,ERRATA_A76_1946160))
 $(eval $(call add_define,ERRATA_A76_1946160))
 
+# Process ERRATA_A76_2743102 flag
+$(eval $(call assert_boolean,ERRATA_A76_2743102))
+$(eval $(call add_define,ERRATA_A76_2743102))
+
 # Process ERRATA_A77_1508412 flag
 $(eval $(call assert_boolean,ERRATA_A77_1508412))
 $(eval $(call add_define,ERRATA_A77_1508412))
@@ -936,6 +952,10 @@
 $(eval $(call assert_boolean,ERRATA_A77_1800714))
 $(eval $(call add_define,ERRATA_A77_1800714))
 
+# Process ERRATA_A77_2743100 flag
+$(eval $(call assert_boolean,ERRATA_A77_2743100))
+$(eval $(call add_define,ERRATA_A77_2743100))
+
 # Process ERRATA_A78_1688305 flag
 $(eval $(call assert_boolean,ERRATA_A78_1688305))
 $(eval $(call add_define,ERRATA_A78_1688305))
@@ -1072,6 +1092,10 @@
 $(eval $(call assert_boolean,ERRATA_N1_1946160))
 $(eval $(call add_define,ERRATA_N1_1946160))
 
+# 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))
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 8213cbe..866ac41 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -206,6 +206,11 @@
 	/* Allow access to Allocation Tags when MTE is implemented. */
 	scr_el3 |= SCR_ATA_BIT;
 
+#if HANDLE_EA_EL3_FIRST_NS
+	/* SCR_EL3.EA: Route External Abort and SError Interrupt to EL3. */
+	scr_el3 |= SCR_EA_BIT;
+#endif
+
 #if RAS_TRAP_NS_ERR_REC_ACCESS
 	/*
 	 * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR
@@ -249,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 */
 }
 
@@ -279,7 +294,7 @@
 	 * Security state and entrypoint attributes of the next EL.
 	 */
 	scr_el3 = read_scr();
-	scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT |
+	scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_EA_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT |
 			SCR_ST_BIT | SCR_HCE_BIT | SCR_NSE_BIT);
 
 	/*
@@ -317,15 +332,6 @@
 	scr_el3 |= SCR_TRNDR_BIT;
 #endif
 
-#if !HANDLE_EA_EL3_FIRST
-	/*
-	 * SCR_EL3.EA: Do not route External Abort and SError Interrupt External
-	 * to EL3 when executing at a lower EL. When executing at EL3, External
-	 * Aborts are taken to EL3.
-	 */
-	scr_el3 &= ~SCR_EA_BIT;
-#endif
-
 #if FAULT_INJECTION_SUPPORT
 	/* Enable fault injection from lower ELs */
 	scr_el3 |= SCR_FIEN_BIT;
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/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 65ceb7f..683d7ac 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -216,9 +216,9 @@
 # default, they are for Secure EL1.
 GICV2_G0_FOR_EL3		:= 0
 
-# Route External Aborts to EL3. Disabled by default; External Aborts are handled
+# Route NS External Aborts to EL3. Disabled by default; External Aborts are handled
 # by lower ELs.
-HANDLE_EA_EL3_FIRST		:= 0
+HANDLE_EA_EL3_FIRST_NS		:= 0
 
 # Secure hash algorithm flag, accepts 3 values: sha256, sha384 and sha512.
 # The default value is sha256.
@@ -270,7 +270,7 @@
 # Software Delegated Exception support
 SDEI_SUPPORT			:= 0
 
-# True Random Number firmware Interface
+# True Random Number firmware Interface support
 TRNG_SUPPORT			:= 0
 
 # SMCCC PCI support
@@ -419,7 +419,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 +480,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/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index 9728a08..7492fe5 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -18,6 +18,7 @@
 
 # RD-N2 platform uses GIC-700 which is based on GICv4.1
 GIC_ENABLE_V4_EXTN	:=	1
+GIC_EXT_INTID		:=	1
 
 #Enable GIC Multichip Extension only for Multichip Platforms
 ifeq (${CSS_SGI_PLATFORM_VARIANT}, 2)
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c
index 8cf1929..2506f9d 100644
--- a/plat/arm/board/rdn2/rdn2_plat.c
+++ b/plat/arm/board/rdn2/rdn2_plat.c
@@ -47,15 +47,15 @@
 #endif
 	},
 	.spi_ids = {
-		{32, 479},
+		{32, 511},
 	#if CSS_SGI_CHIP_COUNT > 1
-		{0, 0},
+		{512, 991},
 	#endif
 	#if CSS_SGI_CHIP_COUNT > 2
-		{0, 0},
+		{4096, 4575},
 	#endif
 	#if CSS_SGI_CHIP_COUNT > 3
-		{0, 0},
+		{4576, 5055},
 	#endif
 	}
 };
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index a9b031d..37ba229 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
@@ -21,7 +26,7 @@
 
 EL3_EXCEPTION_HANDLING	:=	0
 
-HANDLE_EA_EL3_FIRST	:=	0
+HANDLE_EA_EL3_FIRST_NS	:=	0
 
 # System coherency is managed in hardware
 HW_ASSISTED_COHERENCY	:=	1
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 682a278..7162ce9 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -195,8 +195,10 @@
 # Enable CRC instructions via extension for ARMv8-A CPUs.
 # For ARMv8.1-A, and onwards CRC instructions are default enabled.
 # Enable HW computed CRC support unconditionally in BL2 component.
-ifeq (${ARM_ARCH_MINOR},0)
-  BL2_CPPFLAGS += -march=armv8-a+crc
+ifeq (${ARM_ARCH_MAJOR},8)
+    ifeq (${ARM_ARCH_MINOR},0)
+        BL2_CPPFLAGS += -march=armv8-a+crc
+    endif
 endif
 
 ifeq ($(PSA_FWU_SUPPORT),1)
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 6c1a2dd..282a5f0 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -14,7 +14,7 @@
 
 EL3_EXCEPTION_HANDLING		:=	0
 
-HANDLE_EA_EL3_FIRST		:=	0
+HANDLE_EA_EL3_FIRST_NS		:=	0
 
 CSS_SGI_CHIP_COUNT		:=	1
 
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 8f998af..8ce1d6c 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -67,17 +67,15 @@
 }
 #endif
 
-#if !ENABLE_BACKTRACE
-static const char *get_el_str(unsigned int el)
+const char *get_el_str(unsigned int el)
 {
 	if (el == MODE_EL3) {
 		return "EL3";
 	} else if (el == MODE_EL2) {
 		return "EL2";
 	}
-	return "S-EL1";
+	return "EL1";
 }
-#endif /* !ENABLE_BACKTRACE */
 
 /* RAS functions common to AArch64 ARM platforms */
 void plat_default_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
@@ -95,7 +93,7 @@
 	ERROR("Unhandled External Abort received on 0x%lx from %s\n",
 		read_mpidr_el1(), get_el_str(level));
 	ERROR("exception reason=%u syndrome=0x%" PRIx64 "\n", ea_reason, syndrome);
-#if HANDLE_EA_EL3_FIRST
+#if HANDLE_EA_EL3_FIRST_NS
 	/* Skip backtrace for lower EL */
 	if (level != MODE_EL3) {
 		console_flush();
diff --git a/plat/hisilicon/hikey960/aarch64/hikey960_common.c b/plat/hisilicon/hikey960/aarch64/hikey960_common.c
index 612a7f2..c70286f 100644
--- a/plat/hisilicon/hikey960/aarch64/hikey960_common.c
+++ b/plat/hisilicon/hikey960/aarch64/hikey960_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,7 +12,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
 #include "../hikey960_def.h"
@@ -69,7 +69,6 @@
 #ifdef IMAGE_BL31
 static const mmap_region_t hikey960_mmap[] = {
 	MAP_DEVICE,
-	MAP_TSP_MEM,
 	{0}
 };
 #endif
diff --git a/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c b/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c
index 39a54cb..e42785a 100644
--- a/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c
+++ b/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -138,6 +138,22 @@
 #endif
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
+
+#ifdef 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 = DDR_SEC_CONFIG_BASE,
+		.image_info.image_max_size = DDR_SEC_CONFIG_SIZE,
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+#endif
+
 # endif /* BL32_BASE */
 
 	/* Fill BL33 related information */
diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c
index c1c2a8c..7334853 100644
--- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,6 +31,9 @@
 
 #define BL2_RW_BASE		(BL_CODE_END)
 
+/* BL2 platform parameters passed to BL31 */
+static plat_params_from_bl2_t plat_params_from_bl2;
+
 static meminfo_t bl2_el3_tzram_layout;
 static console_t console;
 extern int load_lpm3(void);
@@ -217,6 +220,11 @@
 	assert(bl_mem_params);
 
 	switch (image_id) {
+	case BL31_IMAGE_ID:
+		/* Pass BL2 platform parameter to BL31 */
+		bl_mem_params->ep_info.args.arg1 = (uint64_t) &plat_params_from_bl2;
+		break;
+
 #ifdef __aarch64__
 	case BL32_IMAGE_ID:
 #ifdef SPD_opteed
@@ -307,6 +315,8 @@
 
 void bl2_platform_setup(void)
 {
+	int ret;
+
 	/* disable WDT0 */
 	if (mmio_read_32(WDT0_REG_BASE + WDT_LOCK_OFFSET) == WDT_LOCKED) {
 		mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, WDT_UNLOCK);
@@ -322,4 +332,13 @@
 	hikey960_gpio_init();
 	hikey960_init_ufs();
 	hikey960_io_setup();
+
+	/* Read serial number from storage */
+	plat_params_from_bl2.fastboot_serno = 0;
+	ret = hikey960_load_serialno(&plat_params_from_bl2.fastboot_serno);
+	if (ret != 0) {
+		ERROR("BL2: could not read serial number\n");
+	}
+	INFO("BL2: fastboot_serno %lx\n", plat_params_from_bl2.fastboot_serno);
+	flush_dcache_range((uintptr_t)&plat_params_from_bl2, sizeof(plat_params_from_bl2_t));
 }
diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
index f5f8ffe..0debe1e 100644
--- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,9 @@
 #include <drivers/console.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
+#include <services/el3_spmc_ffa_memory.h>
 
 #include <hi3660.h>
 #include <hisi_ipc.h>
@@ -31,6 +33,9 @@
 static entry_point_info_t bl33_ep_info;
 static console_t console;
 
+/* fastboot serial number consumed by Kinibi SPD/LP for gpd.tee.deviceID. */
+uint64_t fastboot_serno;
+
 /******************************************************************************
  * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
  * interrupts.
@@ -71,6 +76,7 @@
 {
 	unsigned int id, uart_base;
 	void *from_bl2;
+	plat_params_from_bl2_t *plat_params_from_bl2 = (plat_params_from_bl2_t *) arg1;
 
 	from_bl2 = (void *) arg0;
 
@@ -89,6 +95,10 @@
 	cci_init(CCI400_REG_BASE, cci_map, ARRAY_SIZE(cci_map));
 	cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
 
+	/* Fastboot serial number passed from BL2 as a platform parameter */
+	fastboot_serno = plat_params_from_bl2->fastboot_serno;
+	INFO("BL31: fastboot_serno %lx\n", fastboot_serno);
+
 	/*
 	 * Check params passed from BL2 should not be NULL,
 	 */
@@ -119,6 +129,11 @@
 
 void bl31_plat_arch_setup(void)
 {
+#if SPMC_AT_EL3
+	mmap_add_region(DDR2_SEC_BASE, DDR2_SEC_BASE, DDR2_SEC_SIZE,
+	       MT_MEMORY | MT_RW | MT_SECURE);
+#endif
+
 	hikey960_init_mmu_el3(BL31_BASE,
 			BL31_LIMIT - BL31_BASE,
 			BL_CODE_BASE,
@@ -156,6 +171,48 @@
 	}
 }
 
+#if SPMC_AT_EL3
+/*
+ * On the hikey960 platform when using the EL3 SPMC implementation allocate the
+ * datastore for tracking shared memory descriptors in the RAM2 DRAM section
+ * to ensure sufficient storage can be allocated.
+ * Provide an implementation of the accessor method to allow the datastore
+ * details to be retrieved by the SPMC.
+ * The SPMC will take care of initializing the memory region.
+ */
+
+#define SPMC_SHARED_MEMORY_OBJ_SIZE (512 * 1024)
+
+__section("ram2_region") uint8_t plat_spmc_shmem_datastore[SPMC_SHARED_MEMORY_OBJ_SIZE];
+
+int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
+{
+	*datastore = plat_spmc_shmem_datastore;
+	*size = SPMC_SHARED_MEMORY_OBJ_SIZE;
+	return 0;
+}
+
+/*
+ * Add dummy implementations of memory management related platform hooks.
+ * These can be used to implement platform specific functionality to support
+ * a memory sharing/lending operation.
+ *
+ * Note: The hooks must be located as part of the initial share request and
+ * final reclaim to prevent order dependencies with operations that may take
+ * place in the normal world without visibility of the SPMC.
+ */
+int plat_spmc_shmem_begin(struct ffa_mtd *desc)
+{
+	return 0;
+}
+
+int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
+{
+	return 0;
+}
+
+#endif
+
 void bl31_platform_setup(void)
 {
 	/* Initialize the GIC driver, cpu and distributor interfaces */
diff --git a/plat/hisilicon/hikey960/hikey960_def.h b/plat/hisilicon/hikey960/hikey960_def.h
index 9651d78..e103cf4 100644
--- a/plat/hisilicon/hikey960/hikey960_def.h
+++ b/plat/hisilicon/hikey960/hikey960_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,15 +21,21 @@
 #define HIKEY960_DRAM_ID	1
 
 /*
- * DDR for OP-TEE (32MB from 0x3E00000-0x3FFFFFFF) is divided in several
+ * DDR for TEE (80MB from 0x3E00000-0x43000FFF) is divided into several
  * regions:
- *   - Secure DDR (default is the top 16MB) used by OP-TEE
+ *   - SPMC manifest (4KB at the top) used by SPMC_AT_EL3 and the TEE
+ *   - Datastore for SPMC_AT_EL3 (4MB at the top) used by BL31
+ *   - Secure DDR (default is the top 60MB) used by OP-TEE
  *   - Non-secure DDR used by OP-TEE (shared memory and padding) (4MB)
  *   - Secure DDR (4MB aligned on 4MB) for OP-TEE's "Secure Data Path" feature
  *   - Non-secure DDR (8MB) reserved for OP-TEE's future use
  */
-#define DDR_SEC_SIZE			0x01000000
+#define DDR_SEC_SIZE			0x03C00000 /* reserve 60MB secure memory */
 #define DDR_SEC_BASE			0x3F000000
+#define DDR2_SEC_SIZE			0x00400000 /* SPMC_AT_EL3: 4MB for BL31 RAM2 */
+#define DDR2_SEC_BASE			0x42C00000
+#define DDR_SEC_CONFIG_SIZE		0x00001000 /* SPMC_AT_EL3: SPMC manifest */
+#define DDR_SEC_CONFIG_BASE		0x43000000
 
 #define DDR_SDP_SIZE			0x00400000
 #define DDR_SDP_BASE			(DDR_SEC_BASE - 0x400000 /* align */ - \
@@ -50,4 +56,27 @@
 #define HIKEY960_UFS_DATA_BASE		0x10000000
 #define HIKEY960_UFS_DATA_SIZE		0x0A000000	/* 160MB */
 
+#if defined(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 Nwld Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * nwld partitions.
+ */
+#define NS_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		1
+
+#endif /* SPMC_AT_EL3 */
+
 #endif /* HIKEY960_DEF_H */
diff --git a/plat/hisilicon/hikey960/hikey960_el3_spmc_logical_sp.c b/plat/hisilicon/hikey960/hikey960_el3_spmc_logical_sp.c
new file mode 100644
index 0000000..b9e4f86
--- /dev/null
+++ b/plat/hisilicon/hikey960/hikey960_el3_spmc_logical_sp.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <services/el3_spmc_logical_sp.h>
+#include <services/ffa_svc.h>
+#include <smccc_helpers.h>
+
+#define LP_PARTITION_ID 0xC001
+#define LP_UUID {0x47a3bf57, 0xe98e43ad, 0xb7db524f, 0x1588f4e3}
+
+/* Our Logical SP currently only supports receipt of direct messaging. */
+#define PARTITION_PROPERTIES FFA_PARTITION_DIRECT_REQ_RECV
+
+static int32_t sp_init(void)
+{
+	INFO("LSP: Init function called.\n");
+	return 0;
+}
+
+static uint64_t handle_ffa_direct_request(uint32_t smc_fid,  bool secure_origin,
+					  uint64_t x1, uint64_t x2, uint64_t x3,
+					  uint64_t x4, void *cookie,
+					  void *handle, uint64_t flags)
+{
+	uint64_t ret;
+
+	/* Determine if we have a 64 or 32 direct request. */
+	if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC32) {
+		ret = FFA_MSG_SEND_DIRECT_RESP_SMC32;
+	} else if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC64) {
+		ret = FFA_MSG_SEND_DIRECT_RESP_SMC64;
+	} else {
+		panic(); /* Unknown SMC. */
+	}
+	/*
+	 * Handle the incoming request. For testing purposes we echo the
+	 * incoming message.
+	 */
+	INFO("Logical Partition: Received Direct Request from %s world!\n",
+	     secure_origin ? "Secure" : "Normal");
+
+	/*
+	 * Logical SP's must always send a direct response so we can populate
+	 * our response directly.
+	 */
+	SMC_RET8(handle, ret, 0, 0, x4, 0, 0, 0, 0);
+}
+
+/* Register logical partition  */
+DECLARE_LOGICAL_PARTITION(
+	my_logical_partition,
+	sp_init,			/* Init Function */
+	LP_PARTITION_ID,		/* FF-A Partition ID */
+	LP_UUID,			/* UUID */
+	PARTITION_PROPERTIES,		/* Partition Properties. */
+	handle_ffa_direct_request	/* Callback for direct requests. */
+);
diff --git a/plat/hisilicon/hikey960/hikey960_image_load.c b/plat/hisilicon/hikey960/hikey960_image_load.c
index 57cb1b2..9a5b74e 100644
--- a/plat/hisilicon/hikey960/hikey960_image_load.c
+++ b/plat/hisilicon/hikey960/hikey960_image_load.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <common/bl_common.h>
 #include <common/desc_image_load.h>
 #include <plat/common/platform.h>
@@ -25,10 +26,30 @@
 	return get_bl_load_info_from_mem_params_desc();
 }
 
+
+/*******************************************************************************
+ * ARM helper function to return the list of executable images. Since the default
+ * descriptors are allocated within BL2 RW memory, this prevents BL31/BL32
+ * overlay of BL2 memory. Hence this function also copies the descriptors to a
+ * pre-allocated memory indicated by ARM_BL2_MEM_DESC_BASE.
+ ******************************************************************************/
+struct bl_params *hikey960_get_next_bl_params(void)
+{
+	bl_params_t *next_bl_params;
+
+	next_bl_params = get_next_bl_params_from_mem_params_desc();
+	assert(next_bl_params != NULL);
+
+	populate_next_bl_params_config(next_bl_params);
+
+	return next_bl_params;
+}
+
+
 /*******************************************************************************
  * This function returns the list of executable images.
  ******************************************************************************/
 bl_params_t *plat_get_next_bl_params(void)
 {
-	return get_next_bl_params_from_mem_params_desc();
+	return hikey960_get_next_bl_params();
 }
diff --git a/plat/hisilicon/hikey960/hikey960_io_storage.c b/plat/hisilicon/hikey960/hikey960_io_storage.c
index e1c5845..475e416 100644
--- a/plat/hisilicon/hikey960/hikey960_io_storage.c
+++ b/plat/hisilicon/hikey960/hikey960_io_storage.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,6 +23,9 @@
 #include <lib/semihosting.h>
 #include <tools_share/firmware_image_package.h>
 
+#include "hikey960_def.h"
+#include "hikey960_private.h"
+
 struct plat_io_policy {
 	uintptr_t *dev_handle;
 	uintptr_t image_spec;
@@ -45,6 +48,12 @@
 			  (PLAT_PARTITION_MAX_ENTRIES / 4 + 2),
 };
 
+/* Fastboot serial number stored within first UFS device blocks */
+static const io_block_spec_t ufs_fastboot_spec = {
+	.offset         = UFS_BASE,
+	.length         = 1 << 20,
+};
+
 static const io_block_dev_spec_t ufs_dev_spec = {
 	/* It's used as temp buffer in block driver. */
 	.buffer		= {
@@ -77,6 +86,12 @@
 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
 };
+
+#ifdef SPD_spmd
+static const io_uuid_spec_t bl32_tos_fw_spec = {
+	.uuid = UUID_TOS_FW_CONFIG,
+};
+#endif
 
 static const io_uuid_spec_t bl33_uuid_spec = {
 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
@@ -151,6 +166,15 @@
 		(uintptr_t)&bl32_extra2_uuid_spec,
 		check_fip
 	},
+
+#ifdef SPD_spmd
+	[TOS_FW_CONFIG_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_tos_fw_spec,
+		check_fip
+	},
+#endif
+
 	[BL33_IMAGE_ID] = {
 		&fip_dev_handle,
 		(uintptr_t)&bl33_uuid_spec,
@@ -241,6 +265,54 @@
 	return result;
 }
 
+int hikey960_load_serialno(uint64_t *serno)
+{
+	int result;
+	size_t len = 0;
+	uintptr_t local_handle;
+	uint64_t buf[HIKEY960_SERIAL_NUMBER_SIZE / sizeof(uint64_t)];
+
+	if (serno == NULL) {
+		return -1;
+	}
+
+	result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
+	if (result != 0) {
+		return result;
+	}
+
+	result = io_open(ufs_dev_handle,
+		(uintptr_t)&ufs_fastboot_spec, &local_handle);
+	if (result != 0) {
+		return result;
+	}
+
+	result = io_seek(local_handle, IO_SEEK_SET,
+		HIKEY960_SERIAL_NUMBER_LBA * UFS_BLOCK_SIZE);
+	if (result != 0) {
+		goto closing;
+	}
+
+	result = io_read(local_handle, (uintptr_t)buf,
+		HIKEY960_SERIAL_NUMBER_SIZE, &len);
+	if (result != 0) {
+		goto closing;
+	}
+
+	if (len != HIKEY960_SERIAL_NUMBER_SIZE) {
+		result = -1;
+		goto closing;
+	}
+
+	/* UEFI fastboot app stores a 16 bytes blob       */
+	/* We extract only relevant 8 bytes serial number */
+	*serno = buf[1];
+
+closing:
+	io_close(local_handle);
+	return result;
+}
+
 void hikey960_io_setup(void)
 {
 	int result;
diff --git a/plat/hisilicon/hikey960/hikey960_private.h b/plat/hisilicon/hikey960/hikey960_private.h
index 54bf501..742725c 100644
--- a/plat/hisilicon/hikey960/hikey960_private.h
+++ b/plat/hisilicon/hikey960/hikey960_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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,10 @@
 
 #include <common/bl_common.h>
 
+/* Fastboot serial number */
+#define HIKEY960_SERIAL_NUMBER_LBA	(UFS_BASE + 20)
+#define HIKEY960_SERIAL_NUMBER_SIZE	16
+
 /*
  * Function and variable prototypes
  */
@@ -27,6 +31,7 @@
 void hikey960_io_setup(void);
 int hikey960_read_boardid(unsigned int *id);
 int hikey960_set_fip_addr(unsigned int image_id, const char *name);
+int hikey960_load_serialno(uint64_t *serno);
 void hikey960_clk_init(void);
 void hikey960_pmu_init(void);
 void hikey960_regulator_enable(void);
@@ -39,4 +44,12 @@
 void clr_ex(void);
 void nop(void);
 
+/*******************************************************************************
+ * Struct for parameters received from BL2
+ ******************************************************************************/
+typedef struct plat_params_from_bl2 {
+	/* Fastboot serial number gathered from UFS */
+	uint64_t fastboot_serno;
+} plat_params_from_bl2_t;
+
 #endif /* HIKEY960_PRIVATE_H */
diff --git a/plat/hisilicon/hikey960/include/plat.ld.S b/plat/hisilicon/hikey960/include/plat.ld.S
new file mode 100644
index 0000000..0cc25cd
--- /dev/null
+++ b/plat/hisilicon/hikey960/include/plat.ld.S
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_LD_S
+#define PLAT_LD_S
+
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+MEMORY {
+    RAM2 (rw): ORIGIN = DDR2_SEC_BASE, LENGTH = DDR2_SEC_SIZE
+}
+
+SECTIONS
+{
+	ram2_region (NOLOAD) : {
+	*(ram2_region)
+	}>RAM2
+}
+
+#endif /* PLAT_LD_S */
diff --git a/plat/hisilicon/hikey960/include/platform_def.h b/plat/hisilicon/hikey960/include/platform_def.h
index 215eebe..10eff01 100644
--- a/plat/hisilicon/hikey960/include/platform_def.h
+++ b/plat/hisilicon/hikey960/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -114,15 +114,23 @@
 /*
  * Platform specific page table and MMU setup constants
  */
-#define PLAT_VIRT_ADDR_SPACE_SIZE   (1ULL << 32)
-#define PLAT_PHY_ADDR_SPACE_SIZE    (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE   (1ULL << 36)
+#define PLAT_PHY_ADDR_SPACE_SIZE    (1ULL << 36)
 
-#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || defined(IMAGE_BL32)
+#if defined(IMAGE_BL1) || defined(IMAGE_BL32)
 #define MAX_XLAT_TABLES			3
 #endif
 
-#ifdef IMAGE_BL2
-#define MAX_XLAT_TABLES			4
+#if defined(IMAGE_BL2)
+#define MAX_XLAT_TABLES			5
+#endif
+
+#if defined(IMAGE_BL31)
+#if defined(SPMC_AT_EL3)
+#define MAX_XLAT_TABLES			17
+#else
+#define MAX_XLAT_TABLES			5
+#endif
 #endif
 
 #define MAX_MMAP_REGIONS		16
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index c8ad66c..4c3c817 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -46,11 +46,12 @@
 PLAT_BL_COMMON_SOURCES	:=	drivers/arm/pl011/aarch64/pl011_console.S \
 				drivers/delay_timer/delay_timer.c	\
 				drivers/delay_timer/generic_delay_timer.c \
-				lib/xlat_tables/aarch64/xlat_tables.c	\
-				lib/xlat_tables/xlat_tables_common.c	\
 				plat/hisilicon/hikey960/aarch64/hikey960_common.c \
 				plat/hisilicon/hikey960/hikey960_boardid.c
 
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
+
 HIKEY960_GIC_SOURCES	:=	drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v2/gicv2_main.c		\
 				drivers/arm/gic/v2/gicv2_helpers.c	\
@@ -160,3 +161,22 @@
 ERRATA_A53_855873		:=	1
 
 FIP_ALIGN			:=	512
+
+# SPM dispatcher
+ifeq (${SPD},spmd)
+ifeq (${SPMC_AT_EL3},1)
+# include device tree helper library
+include lib/libfdt/libfdt.mk
+BL31_SOURCES		+=	common/fdt_wrappers.c		\
+				${LIBFDT_SRCS}			\
+				common/uuid.c
+
+# Add support for platform supplied linker script for BL31 build
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+endif
+
+ifeq ($(PLAT_SP_MANIFEST_DTS),)
+        $(error "Error: A SP manifest is required for the SPMC.")
+endif
+FDT_SOURCES		+=	${PLAT_SP_MANIFEST_DTS}
+endif
diff --git a/plat/imx/imx8m/ddr/dram.c b/plat/imx/imx8m/ddr/dram.c
index 6ccd6fd..8ea9ba1 100644
--- a/plat/imx/imx8m/ddr/dram.c
+++ b/plat/imx/imx8m/ddr/dram.c
@@ -120,6 +120,7 @@
 void dram_info_init(unsigned long dram_timing_base)
 {
 	uint32_t ddrc_mstr, current_fsp;
+	unsigned int idx = 0;
 	uint32_t flags = 0;
 	uint32_t rc;
 	unsigned int i;
@@ -144,11 +145,12 @@
 		if (!dram_info.timing_info->fsp_table[i]) {
 			break;
 		}
+		idx = i;
 	}
 	dram_info.num_fsp = i;
 
 	/* check if has bypass mode support */
-	if (dram_info.timing_info->fsp_table[i-1] < 666) {
+	if (dram_info.timing_info->fsp_table[idx] < 666) {
 		dram_info.bypass_mode = true;
 	} else {
 		dram_info.bypass_mode = false;
diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c
index d396902..8f545d6 100644
--- a/plat/imx/imx8m/imx8m_psci_common.c
+++ b/plat/imx/imx8m/imx8m_psci_common.c
@@ -40,7 +40,7 @@
 int imx_pwr_domain_on(u_register_t mpidr)
 {
 	unsigned int core_id;
-	uint64_t base_addr = BL31_BASE;
+	uint64_t base_addr = BL31_START;
 
 	core_id = MPIDR_AFFLVL0_VAL(mpidr);
 
@@ -102,7 +102,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/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index 38fac92..67bfd36 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -184,24 +184,30 @@
 	bl31_tzc380_setup();
 }
 
+#define MAP_BL31_TOTAL										   \
+	MAP_REGION_FLAT(BL31_START, BL31_SIZE, MT_MEMORY | MT_RW | MT_SECURE)
+#define MAP_BL31_RO										   \
+	MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_MEMORY | MT_RO | MT_SECURE)
+#define MAP_COHERENT_MEM									   \
+	MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,	   \
+			MT_DEVICE | MT_RW | MT_SECURE)
+#define MAP_BL32_TOTAL										   \
+	MAP_REGION_FLAT(BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW)
+
 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);
+	const mmap_region_t bl_regions[] = {
+		MAP_BL31_TOTAL,
+		MAP_BL31_RO,
 #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_COHERENT_MEM,
 #endif
-	/* Map TEE memory */
-	mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW);
-
-	mmap_add(imx_mmap);
-
-	init_xlat_tables();
+		/* Map TEE memory */
+		MAP_BL32_TOTAL,
+		{0}
+	};
 
+	setup_page_tables(bl_regions, imx_mmap);
 	enable_mmu_el3(0);
 }
 
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 930372f..65749f3 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -7,6 +7,7 @@
 #include <arch.h>
 #include <common/tbbr/tbbr_img_def.h>
 #include <lib/utils_def.h>
+#include <plat/common/common_def.h>
 
 #define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
 #define PLATFORM_LINKER_ARCH		aarch64
@@ -40,9 +41,9 @@
 
 #if defined(NEED_BL2)
 #define BL2_BASE			U(0x920000)
-#define BL2_LIMIT			U(0x940000)
+#define BL2_SIZE			SZ_128K
+#define BL2_LIMIT			(BL2_BASE + BL2_SIZE)
 #define BL31_BASE			U(0x900000)
-#define BL31_LIMIT			U(0x920000)
 #define IMX_FIP_BASE			U(0x40310000)
 #define IMX_FIP_SIZE			U(0x000300000)
 #define IMX_FIP_LIMIT			U(FIP_BASE + FIP_SIZE)
@@ -53,9 +54,11 @@
 #define PLAT_IMX8MM_BOOT_MMC_BASE	U(0x30B50000) /* SD */
 #else
 #define BL31_BASE			U(0x920000)
-#define BL31_LIMIT			U(0x940000)
 #endif
 
+#define BL31_SIZE			SZ_128K
+#define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
+
 /* non-secure uboot base */
 #define PLAT_NS_IMAGE_OFFSET		U(0x40200000)
 #define PLAT_NS_IMAGE_SIZE		U(0x00200000)
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index ebf5c7b..7a42554 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -142,6 +142,7 @@
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
+ENABLE_PIE		:=	1
 USE_COHERENT_MEM	:=	1
 RESET_TO_BL31		:=	1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index de30967..eff198d 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -181,25 +181,30 @@
 	bl31_tzc380_setup();
 }
 
+#define MAP_BL31_TOTAL										   \
+	MAP_REGION_FLAT(BL31_START, BL31_SIZE, MT_MEMORY | MT_RW | MT_SECURE)
+#define MAP_BL31_RO										   \
+	MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_MEMORY | MT_RO | MT_SECURE)
+#define MAP_COHERENT_MEM									   \
+	MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,	   \
+			MT_DEVICE | MT_RW | MT_SECURE)
+#define MAP_BL32_TOTAL										   \
+	MAP_REGION_FLAT(BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW)
+
 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);
+	const mmap_region_t bl_regions[] = {
+		MAP_BL31_TOTAL,
+		MAP_BL31_RO,
 #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_COHERENT_MEM,
 #endif
-
-	/* Map TEE memory */
-	mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW);
-
-	mmap_add(imx_mmap);
-
-	init_xlat_tables();
+		/* Map TEE memory */
+		MAP_BL32_TOTAL,
+		{0}
+	};
 
+	setup_page_tables(bl_regions, imx_mmap);
 	enable_mmu_el3(0);
 }
 
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index d4b1717..c75e250 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -8,8 +8,7 @@
 
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
-
-#include <lib/utils_def.h>
+#include <plat/common/common_def.h>
 
 #define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
 #define PLATFORM_LINKER_ARCH		aarch64
@@ -42,7 +41,8 @@
 #define PLAT_SDEI_SGI_PRIVATE		U(9)
 
 #define BL31_BASE			U(0x960000)
-#define BL31_LIMIT			U(0x980000)
+#define BL31_SIZE			SZ_128K
+#define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
 
 /* non-secure uboot base */
 #define PLAT_NS_IMAGE_OFFSET		U(0x40200000)
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
index c70f3a1..1c0ad4f 100644
--- a/plat/imx/imx8m/imx8mn/platform.mk
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -48,6 +48,7 @@
 				${IMX_GIC_SOURCES}				\
 				${XLAT_TABLES_LIB_SRCS}
 
+ENABLE_PIE		:=	1
 USE_COHERENT_MEM	:=	1
 RESET_TO_BL31		:=	1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index 70dd8c8..4c31fa2 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -177,25 +177,30 @@
 	bl31_tzc380_setup();
 }
 
+#define MAP_BL31_TOTAL										   \
+	MAP_REGION_FLAT(BL31_START, BL31_SIZE, MT_MEMORY | MT_RW | MT_SECURE)
+#define MAP_BL31_RO										   \
+	MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_MEMORY | MT_RO | MT_SECURE)
+#define MAP_COHERENT_MEM									   \
+	MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,	   \
+			MT_DEVICE | MT_RW | MT_SECURE)
+#define MAP_BL32_TOTAL										   \
+	MAP_REGION_FLAT(BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW)
+
 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);
+	const mmap_region_t bl_regions[] = {
+		MAP_BL31_TOTAL,
+		MAP_BL31_RO,
 #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_COHERENT_MEM,
 #endif
-
-	/* Map TEE memory */
-	mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW);
-
-	mmap_add(imx_mmap);
-
-	init_xlat_tables();
+		/* Map TEE memory */
+		MAP_BL32_TOTAL,
+		{0}
+	};
 
+	setup_page_tables(bl_regions, imx_mmap);
 	enable_mmu_el3(0);
 }
 
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index 1c58f48..14cb709 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -9,6 +9,7 @@
 #include <common/tbbr/tbbr_img_def.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/common_def.h>
 
 #define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
 #define PLATFORM_LINKER_ARCH		aarch64
@@ -37,9 +38,9 @@
 
 #if defined(NEED_BL2)
 #define BL2_BASE			U(0x970000)
-#define BL2_LIMIT			U(0x990000)
+#define BL2_SIZE			SZ_128K
+#define BL2_LIMIT			(BL2_BASE + BL2_SIZE)
 #define BL31_BASE			U(0x950000)
-#define BL31_LIMIT			U(0x970000)
 #define IMX_FIP_BASE			U(0x40310000)
 #define IMX_FIP_SIZE			U(0x000300000)
 #define IMX_FIP_LIMIT			U(FIP_BASE + FIP_SIZE)
@@ -50,9 +51,11 @@
 #define PLAT_IMX8MP_BOOT_MMC_BASE	U(0x30B50000) /* SD */
 #else
 #define BL31_BASE			U(0x970000)
-#define BL31_LIMIT			U(0x990000)
 #endif
 
+#define BL31_SIZE			SZ_128K
+#define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
+
 #define PLAT_PRI_BITS			U(3)
 #define PLAT_SDEI_CRITICAL_PRI		0x10
 #define PLAT_SDEI_NORMAL_PRI		0x20
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 09f9ee9..5414c0a 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -139,6 +139,7 @@
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
+ENABLE_PIE		:=	1
 USE_COHERENT_MEM	:=	1
 RESET_TO_BL31		:=	1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
index 5547201..b9c28de 100644
--- a/plat/marvell/armada/a3k/common/a3700_common.mk
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -62,7 +62,7 @@
 				$(PLAT_COMMON_BASE)/a3700_sip_svc.c	\
 				$(MARVELL_DRV)
 
-ifeq ($(HANDLE_EA_EL3_FIRST),1)
+ifeq ($(HANDLE_EA_EL3_FIRST_NS),1)
 BL31_SOURCES		+=	$(PLAT_COMMON_BASE)/a3700_ea.c
 endif
 
diff --git a/plat/marvell/armada/a3k/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c
index bc12845..5696b5c 100644
--- a/plat/marvell/armada/a3k/common/a3700_ea.c
+++ b/plat/marvell/armada/a3k/common/a3700_ea.c
@@ -16,21 +16,9 @@
 
 #define A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS 0xbf000002
 
-#if !ENABLE_BACKTRACE
-static const char *get_el_str(unsigned int el)
-{
-	if (el == MODE_EL3) {
-		return "EL3";
-	} else if (el == MODE_EL2) {
-		return "EL2";
-	}
-	return "S-EL1";
-}
-#endif /* !ENABLE_BACKTRACE */
-
 /*
  * This source file with custom plat_ea_handler function is compiled only when
- * building TF-A with compile option HANDLE_EA_EL3_FIRST=1
+ * building TF-A with compile option HANDLE_EA_EL3_FIRST_NS=1
  */
 void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
 		void *handle, uint64_t flags)
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/common/mtk_bl31_setup.c b/plat/mediatek/common/mtk_bl31_setup.c
index 79ab29d..7c9db8b 100644
--- a/plat/mediatek/common/mtk_bl31_setup.c
+++ b/plat/mediatek/common/mtk_bl31_setup.c
@@ -166,6 +166,7 @@
 void bl31_plat_runtime_setup(void)
 {
 	mtk_init_one_level(MTK_INIT_LVL_PLAT_RUNTIME);
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 unsigned int plat_get_syscnt_freq2(void)
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/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk
index 7583833..631c926 100644
--- a/plat/nvidia/tegra/soc/t194/platform_t194.mk
+++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk
@@ -33,7 +33,7 @@
 $(eval $(call add_define,MAX_MMAP_REGIONS))
 
 # enable RAS handling
-HANDLE_EA_EL3_FIRST			:= 1
+HANDLE_EA_EL3_FIRST_NS			:= 1
 RAS_EXTENSION				:= 1
 
 # platform files
diff --git a/plat/qti/common/inc/qti_plat.h b/plat/qti/common/inc/qti_plat.h
index d616efe..7483c49 100644
--- a/plat/qti/common/inc/qti_plat.h
+++ b/plat/qti/common/inc/qti_plat.h
@@ -54,4 +54,9 @@
 void qti_pmic_prepare_reset(void);
 void qti_pmic_prepare_shutdown(void);
 
+typedef struct chip_id_info {
+	uint16_t jtag_id;
+	uint16_t chipinfo_id;
+} chip_id_info_t;
+
 #endif /* QTI_PLAT_H */
diff --git a/plat/qti/common/src/qti_common.c b/plat/qti/common/src/qti_common.c
index 8821731..74ccb5b 100644
--- a/plat/qti/common/src/qti_common.c
+++ b/plat/qti/common/src/qti_common.c
@@ -17,6 +17,7 @@
 #include <services/arm_arch_svc.h>
 
 #include <platform_def.h>
+#include <qti_map_chipinfo.h>
 #include <qti_plat.h>
 #include <qtiseclib_interface.h>
 
@@ -154,9 +155,22 @@
  */
 int32_t plat_get_soc_version(void)
 {
-	uint32_t soc_version = (QTI_SOC_VERSION & QTI_SOC_VERSION_MASK);
+	int i = 0;
+	/* Variant other than in mapped g_map_jtag_chipinfo_id variable will have
+	 * default chipinfo id as 0xFFFF
+	 */
+	uint32_t soc_version = (QTI_DEFAULT_CHIPINFO_ID & QTI_SOC_VERSION_MASK);
 	uint32_t jep106az_code = (JEDEC_QTI_BKID << QTI_SOC_CONTINUATION_SHIFT)
 			 | (JEDEC_QTI_MFID << QTI_SOC_IDENTIFICATION_SHIFT);
+	uint32_t jtag_id = mmio_read_32(QTI_JTAG_ID_REG);
+	uint32_t jtag_id_val = (jtag_id >> QTI_JTAG_ID_SHIFT)
+			 & QTI_SOC_VERSION_MASK;
+
+	for (i = 0; i < ARRAY_SIZE(g_map_jtag_chipinfo_id); i++) {
+		if (g_map_jtag_chipinfo_id[i].jtag_id == jtag_id_val)
+			soc_version = g_map_jtag_chipinfo_id[i].chipinfo_id
+			 & QTI_SOC_VERSION_MASK;
+	}
 	return (int32_t)(jep106az_code | (soc_version));
 }
 
diff --git a/plat/qti/sc7180/inc/platform_def.h b/plat/qti/sc7180/inc/platform_def.h
index e3dc811..b69dfd9 100644
--- a/plat/qti/sc7180/inc/platform_def.h
+++ b/plat/qti/sc7180/inc/platform_def.h
@@ -185,7 +185,6 @@
 /*----------------------------------------------------------------------------*/
 /* SOC hw version register */
 /*----------------------------------------------------------------------------*/
-#define QTI_SOC_VERSION				U(0x7180)
 #define QTI_SOC_VERSION_MASK			U(0xFFFF)
 #define QTI_SOC_REVISION_REG			0x1FC8000
 #define QTI_SOC_REVISION_MASK			U(0xFFFF)
diff --git a/plat/qti/sc7180/inc/qti_map_chipinfo.h b/plat/qti/sc7180/inc/qti_map_chipinfo.h
new file mode 100644
index 0000000..4ab6191
--- /dev/null
+++ b/plat/qti/sc7180/inc/qti_map_chipinfo.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_MAP_CHIPINFO_H
+#define QTI_MAP_CHIPINFO_H
+
+#include <stdint.h>
+
+#include <qti_plat.h>
+
+#define QTI_JTAG_ID_REG                         0x786130
+#define QTI_SOC_VERSION_MASK                    U(0xFFFF)
+#define QTI_SOC_REVISION_REG                    0x1FC8000
+#define QTI_SOC_REVISION_MASK                   U(0xFFFF)
+#define QTI_JTAG_ID_SHIFT                       12
+#define QTI_JTAG_ID_SC7180                      U(0x012C)
+#define QTI_JTAG_ID_SC7180P                     U(0x0195)
+#define QTI_CHIPINFO_ID_SC7180                  U(0x01A9)
+#define QTI_CHIPINFO_ID_SC7180P                 U(0x01EF)
+#define QTI_DEFAULT_CHIPINFO_ID                 U(0xFFFF)
+
+static const chip_id_info_t g_map_jtag_chipinfo_id[] = {
+	{QTI_JTAG_ID_SC7180, QTI_CHIPINFO_ID_SC7180},
+	{QTI_JTAG_ID_SC7180P, QTI_CHIPINFO_ID_SC7180P},
+};
+#endif /* QTI_MAP_CHIPINFO_H */
diff --git a/plat/qti/sc7280/inc/platform_def.h b/plat/qti/sc7280/inc/platform_def.h
index da7eddc..48b48ac 100644
--- a/plat/qti/sc7280/inc/platform_def.h
+++ b/plat/qti/sc7280/inc/platform_def.h
@@ -185,7 +185,6 @@
 /*----------------------------------------------------------------------------*/
 /* SOC hw version register */
 /*----------------------------------------------------------------------------*/
-#define QTI_SOC_VERSION				U(0x7280)
 #define QTI_SOC_VERSION_MASK			U(0xFFFF)
 #define QTI_SOC_REVISION_REG			0x1FC8000
 #define QTI_SOC_REVISION_MASK			U(0xFFFF)
diff --git a/plat/qti/sc7280/inc/qti_map_chipinfo.h b/plat/qti/sc7280/inc/qti_map_chipinfo.h
new file mode 100644
index 0000000..7303e20
--- /dev/null
+++ b/plat/qti/sc7280/inc/qti_map_chipinfo.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_MAP_CHIPINFO_H
+#define QTI_MAP_CHIPINFO_H
+
+#include <stdint.h>
+
+#include <qti_plat.h>
+
+#define QTI_JTAG_ID_REG                         0x786130
+#define QTI_JTAG_ID_SHIFT                       12
+#define QTI_JTAG_ID_SC7280                      U(0x0193)
+#define QTI_JTAG_ID_SC7280P                     U(0x01EB)
+#define QTI_JTAG_ID_SC8270                      U(0x01E3)
+#define QTI_JTAG_ID_SC8270P                     U(0x020A)
+#define QTI_JTAG_ID_SC7270P                     U(0x0215)
+#define QTI_CHIPINFO_ID_SC7280                  U(0x01E7)
+#define QTI_CHIPINFO_ID_SC7280P                 U(0x0222)
+#define QTI_CHIPINFO_ID_SC8270                  U(0x0229)
+#define QTI_CHIPINFO_ID_SC8270P                 U(0x0233)
+#define QTI_CHIPINFO_ID_SC7270P                 U(0x0237)
+#define QTI_DEFAULT_CHIPINFO_ID                 U(0xFFFF)
+
+static const chip_id_info_t g_map_jtag_chipinfo_id[] = {
+	{QTI_JTAG_ID_SC7280, QTI_CHIPINFO_ID_SC7280},
+	{QTI_JTAG_ID_SC7280P, QTI_CHIPINFO_ID_SC7280P},
+	{QTI_JTAG_ID_SC8270, QTI_CHIPINFO_ID_SC8270},
+	{QTI_JTAG_ID_SC8270P, QTI_CHIPINFO_ID_SC8270P},
+	{QTI_JTAG_ID_SC7270P, QTI_CHIPINFO_ID_SC7270P},
+};
+#endif /* QTI_MAP_CHIPINFO_H */
diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk
index 26a5798..ca61f0e 100644
--- a/plat/renesas/common/common.mk
+++ b/plat/renesas/common/common.mk
@@ -15,7 +15,7 @@
 MULTI_CONSOLE_API		:= 1
 
 CRASH_REPORTING			:= 1
-HANDLE_EA_EL3_FIRST		:= 1
+HANDLE_EA_EL3_FIRST_NS		:= 1
 
 # This option gets enabled automatically if the TRUSTED_BOARD_BOOT
 # is set via root Makefile, but Renesas support Trusted-Boot without
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..b271ed6 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;
 
@@ -118,6 +124,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)
 {
 	return io_dev_init(storage_dev_handle, 0);
@@ -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:
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_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..d644242
--- /dev/null
+++ b/plat/st/common/stm32mp_crypto_lib.c
@@ -0,0 +1,661 @@
+/*
+ * 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/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
+	}
+}
+
+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_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index ca71958..0b6cc78 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
  */
@@ -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..4f04a6f 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:
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..c4048fc 100644
--- a/plat/st/stm32mp1/plat_image_load.c
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -4,12 +4,7 @@
  * 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
@@ -25,17 +20,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_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..9bdb075 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -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_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/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index e299c30..026d6a3 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -27,7 +27,7 @@
 ERRATA_A72_1319367	:=	1
 
 CRASH_REPORTING		:= 1
-HANDLE_EA_EL3_FIRST	:= 1
+HANDLE_EA_EL3_FIRST_NS	:= 1
 
 # Split out RO data into a non-executable section
 SEPARATE_CODE_AND_RODATA :=    1
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/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_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index 48888e4..9eb426a 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;
-
-	status = pm_ipi_init(primary_proc);
+	int32_t ret = 0;
 
-	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
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 97080e9..c9942d6 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -88,6 +88,9 @@
 		uart_clock = 25000000;
 		break;
 	case VERSAL_NET_SILICON:
+		cpu_clock = 100000000;
+		uart_clock = 100000000;
+		break;
 	default:
 		panic();
 	}
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..03fa316 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -207,11 +207,10 @@
  */
 int32_t pm_setup(void)
 {
-	int32_t status, ret;
 
-	status = pm_ipi_init(primary_proc);
+	pm_ipi_init(primary_proc);
 
-	ret = pm_get_api_version(&pm_ctx.api_version);
+	pm_get_api_version(&pm_ctx.api_version);
 	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 +219,7 @@
 		return -EINVAL;
 	}
 
+	int32_t status = 0, ret = 0;
 #if ZYNQMP_WDT_RESTART
 	status = pm_wdt_restart_setup();
 	if (status)
@@ -263,7 +263,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 +350,7 @@
 
 	case PM_FPGA_GET_STATUS:
 	{
-		uint32_t value;
+		uint32_t value = 0;
 
 		ret = pm_fpga_get_status(&value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
@@ -368,7 +368,7 @@
 			 (uint64_t)result[2] | ((uint64_t)result[3] << 32));
 	case PM_IOCTL:
 	{
-		uint32_t value;
+		uint32_t value = 0;
 
 		ret = pm_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
 			       pm_arg[3], &value);
@@ -395,7 +395,7 @@
 
 	case PM_CLOCK_GETSTATE:
 	{
-		uint32_t value;
+		uint32_t value = 0;
 
 		ret = pm_clock_getstate(pm_arg[0], &value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
@@ -407,7 +407,7 @@
 
 	case PM_CLOCK_GETDIVIDER:
 	{
-		uint32_t value;
+		uint32_t value = 0;
 
 		ret = pm_clock_getdivider(pm_arg[0], &value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
@@ -436,7 +436,7 @@
 
 	case PM_CLOCK_GETPARENT:
 	{
-		uint32_t value;
+		uint32_t value = 0;
 
 		ret = pm_clock_getparent(pm_arg[0], &value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
@@ -470,7 +470,7 @@
 
 	case PM_FPGA_READ:
 	{
-		uint32_t value;
+		uint32_t value = 0;
 
 		ret = pm_fpga_read(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
 				   &value);
@@ -479,7 +479,7 @@
 
 	case PM_SECURE_AES:
 	{
-		uint32_t value;
+		uint32_t value = 0;
 
 		ret = pm_aes_engine(pm_arg[0], pm_arg[1], &value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
@@ -491,7 +491,7 @@
 
 	case PM_PLL_GET_PARAMETER:
 	{
-		uint32_t value;
+		uint32_t value = 0;
 
 		ret = pm_pll_get_parameter(pm_arg[0], pm_arg[1], &value);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32U));
@@ -503,7 +503,7 @@
 
 	case PM_PLL_GET_MODE:
 	{
-		uint32_t mode;
+		uint32_t mode = 0;
 
 		ret = pm_pll_get_mode(pm_arg[0], &mode);
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32U));
@@ -511,7 +511,7 @@
 
 	case PM_REGISTER_ACCESS:
 	{
-		uint32_t value;
+		uint32_t value = 0;
 
 		ret = pm_register_access(pm_arg[0], pm_arg[1], pm_arg[2],
 					 pm_arg[3], &value);
@@ -520,7 +520,7 @@
 
 	case PM_EFUSE_ACCESS:
 	{
-		uint32_t value;
+		uint32_t value = 0;
 
 #if defined(ZYNQMP_SECURE_EFUSES)
 		if (is_caller_non_secure(flags)) {
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c
index e0f5c17..3acf683 100644
--- a/services/std_svc/drtm/drtm_main.c
+++ b/services/std_svc/drtm/drtm_main.c
@@ -366,9 +366,10 @@
 	}
 	a = &args_buf;
 
-	if (a->version != 1) {
-		ERROR("DRTM: parameters structure incompatible with major version %d\n",
-		      ARM_DRTM_VERSION_MAJOR);
+	if (!((a->version >= ARM_DRTM_PARAMS_MIN_VERSION) &&
+	    (a->version <= ARM_DRTM_PARAMS_MAX_VERSION))) {
+		ERROR("DRTM: parameters structure version %u is unsupported\n",
+		      a->version);
 		return NOT_SUPPORTED;
 	}
 
diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h
index baa37ae..6005163 100644
--- a/services/std_svc/drtm/drtm_main.h
+++ b/services/std_svc/drtm/drtm_main.h
@@ -36,6 +36,12 @@
 #define DL_ARGS_GET_DLME_ENTRY_POINT(a)	\
 		(((a)->dlme_paddr + (a)->dlme_img_off + (a)->dlme_img_ep_off))
 
+/*
+ * Range(Min/Max) of DRTM parameter structure versions supported
+ */
+#define ARM_DRTM_PARAMS_MIN_VERSION	U(1)
+#define ARM_DRTM_PARAMS_MAX_VERSION	U(1)
+
 enum drtm_dlme_el {
 	DLME_AT_EL1 = MODE_EL1,
 	DLME_AT_EL2 = MODE_EL2
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 eab2096..89d7b31 100644
--- a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
+++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
@@ -72,13 +72,23 @@
 {
 	struct spmc_shmem_obj *obj;
 	size_t free = state->data_size - state->allocated;
+	size_t obj_size;
 
 	if (state->data == NULL) {
 		ERROR("Missing shmem datastore!\n");
 		return NULL;
 	}
 
-	if (spmc_shmem_obj_size(desc_size) > free) {
+	obj_size = spmc_shmem_obj_size(desc_size);
+
+	/* Ensure the obj size has not overflowed. */
+	if (obj_size < desc_size) {
+		WARN("%s(0x%zx) desc_size overflow\n",
+		     __func__, desc_size);
+		return NULL;
+	}
+
+	if (obj_size > free) {
 		WARN("%s(0x%zx) failed, free 0x%zx\n",
 		     __func__, desc_size, free);
 		return NULL;
@@ -88,7 +98,7 @@
 	obj->desc_size = desc_size;
 	obj->desc_filled = 0;
 	obj->in_use = 0;
-	state->allocated += spmc_shmem_obj_size(desc_size);
+	state->allocated += obj_size;
 	return obj;
 }
 
@@ -330,10 +340,9 @@
 				PAGE_SIZE_4KB;
 			region2_end = region2_start + region2_size;
 
-			if ((region1_start >= region2_start &&
-			     region1_start < region2_end) ||
-			    (region1_end > region2_start
-			     && region1_end < region2_end)) {
+			/* Check if regions are not overlapping. */
+			if (!((region2_end <= region1_start) ||
+			      (region1_end <= region2_start))) {
 				WARN("Overlapping mem regions 0x%lx-0x%lx & 0x%lx-0x%lx\n",
 				     region1_start, region1_end,
 				     region2_start, region2_end);
@@ -886,9 +895,6 @@
 		goto err_arg;
 	}
 
-	memcpy((uint8_t *)&obj->desc + obj->desc_filled,
-	       (uint8_t *) mbox->tx_buffer, fragment_length);
-
 	if (fragment_length > obj->desc_size - obj->desc_filled) {
 		WARN("%s: bad fragment size %u > %zu remaining\n", __func__,
 		     fragment_length, obj->desc_size - obj->desc_filled);
@@ -896,6 +902,9 @@
 		goto err_arg;
 	}
 
+	memcpy((uint8_t *)&obj->desc + obj->desc_filled,
+	       (uint8_t *) mbox->tx_buffer, fragment_length);
+
 	/* Ensure that the sender ID resides in the normal world. */
 	if (ffa_is_secure_world_id(obj->desc.sender_id)) {
 		WARN("%s: Invalid sender ID 0x%x.\n",
@@ -1018,7 +1027,7 @@
 		/* Calculate the size that the v1.1 descriptor will required. */
 		size_t v1_1_desc_size =
 		    spmc_shm_get_v1_1_descriptor_size((void *) &obj->desc,
-						      fragment_length);
+						      obj->desc_size);
 
 		if (v1_1_desc_size == 0U) {
 			ERROR("%s: cannot determine size of descriptor.\n",
@@ -1030,7 +1039,7 @@
 		v1_1_obj =
 		    spmc_shmem_obj_alloc(&spmc_shmem_obj_state, v1_1_desc_size);
 
-		if (!obj) {
+		if (!v1_1_obj) {
 			ret = FFA_ERROR_NO_MEMORY;
 			goto err_arg;
 		}
@@ -1347,7 +1356,8 @@
 	if (req->emad_count == 0U) {
 		WARN("%s: unsupported attribute desc count %u.\n",
 		     __func__, obj->desc.emad_count);
-		return -EINVAL;
+		ret = FFA_ERROR_INVALID_PARAMETER;
+		goto err_unlock_mailbox;
 	}
 
 	/* Determine the appropriate minimum descriptor size. */
@@ -1827,6 +1837,13 @@
 		goto err_unlock;
 	}
 
+	if (obj->desc_filled != obj->desc_size) {
+		WARN("%s: incomplete object desc filled %zu < size %zu\n",
+		     __func__, obj->desc_filled, obj->desc_size);
+		ret = FFA_ERROR_INVALID_PARAMETER;
+		goto err_unlock;
+	}
+
 	/* Allow for platform specific operations to be performed. */
 	ret = plat_spmc_shmem_reclaim(&obj->desc);
 	if (ret != 0) {
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 08d16e2..2884a3b 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -74,7 +74,10 @@
 	sdei_init();
 #endif
 
+#if TRNG_SUPPORT
+	/* TRNG initialisation */
 	trng_setup();
+#endif /* TRNG_SUPPORT */
 
 #if DRTM_SUPPORT
 	if (drtm_setup() != 0) {
@@ -172,7 +175,8 @@
 		return trng_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
 				flags);
 	}
-#endif
+#endif /* TRNG_SUPPORT */
+
 #if ENABLE_RME
 
 	if (is_rmmd_el3_fid(smc_fid)) {
diff --git a/services/std_svc/trng/trng_entropy_pool.c b/services/std_svc/trng/trng_entropy_pool.c
index ac13b1d..30105b3 100644
--- a/services/std_svc/trng/trng_entropy_pool.c
+++ b/services/std_svc/trng/trng_entropy_pool.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,7 +18,7 @@
  * 192 bits of entropy, we don't have to throw out the leftover 1-63 bits of
  * entropy.
  */
-#define WORDS_IN_POOL (4)
+#define WORDS_IN_POOL	(4)
 static uint64_t entropy[WORDS_IN_POOL];
 /* index in bits of the first bit of usable entropy */
 static uint32_t entropy_bit_index;
@@ -27,14 +27,14 @@
 
 static spinlock_t trng_pool_lock;
 
-#define BITS_PER_WORD (sizeof(entropy[0]) * 8)
-#define BITS_IN_POOL (WORDS_IN_POOL * BITS_PER_WORD)
-#define ENTROPY_MIN_WORD (entropy_bit_index / BITS_PER_WORD)
-#define ENTROPY_FREE_BIT (entropy_bit_size + entropy_bit_index)
-#define _ENTROPY_FREE_WORD (ENTROPY_FREE_BIT / BITS_PER_WORD)
-#define ENTROPY_FREE_INDEX (_ENTROPY_FREE_WORD % WORDS_IN_POOL)
+#define BITS_PER_WORD		(sizeof(entropy[0]) * 8)
+#define BITS_IN_POOL		(WORDS_IN_POOL * BITS_PER_WORD)
+#define ENTROPY_MIN_WORD	(entropy_bit_index / BITS_PER_WORD)
+#define ENTROPY_FREE_BIT	(entropy_bit_size + entropy_bit_index)
+#define _ENTROPY_FREE_WORD	(ENTROPY_FREE_BIT / BITS_PER_WORD)
+#define ENTROPY_FREE_INDEX	(_ENTROPY_FREE_WORD % WORDS_IN_POOL)
 /* ENTROPY_WORD_INDEX(0) includes leftover bits in the lower bits */
-#define ENTROPY_WORD_INDEX(i) ((ENTROPY_MIN_WORD + i) % WORDS_IN_POOL)
+#define ENTROPY_WORD_INDEX(i)	((ENTROPY_MIN_WORD + i) % WORDS_IN_POOL)
 
 /*
  * Fill the entropy pool until we have at least as many bits as requested.
@@ -65,12 +65,12 @@
  */
 bool trng_pack_entropy(uint32_t nbits, uint64_t *out)
 {
-	bool success = true;
+	bool ret = true;
 
 	spin_lock(&trng_pool_lock);
 
 	if (!trng_fill_entropy(nbits)) {
-		success = false;
+		ret = false;
 		goto out;
 	}
 
@@ -82,9 +82,8 @@
 	for (word_i = 0; word_i < to_fill; word_i++) {
 		/*
 		 * Repack the entropy from the pool into the passed in out
-		 * buffer. This takes the lower bits from the valid upper bits
-		 * of word_i and the upper bits from the lower bits of
-		 * (word_i + 1).
+		 * buffer. This takes lesser bits from the valid upper bits
+		 * of word_i and more bits from the lower bits of (word_i + 1).
 		 *
 		 * I found the following diagram useful. note: `e` represents
 		 * valid entropy, ` ` represents invalid bits (not entropy) and
@@ -136,7 +135,7 @@
 out:
 	spin_unlock(&trng_pool_lock);
 
-	return success;
+	return ret;
 }
 
 void trng_entropy_pool_setup(void)
diff --git a/services/std_svc/trng/trng_main.c b/services/std_svc/trng/trng_main.c
index 38aa649..90098a8 100644
--- a/services/std_svc/trng/trng_main.c
+++ b/services/std_svc/trng/trng_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,9 +23,9 @@
 static uintptr_t trng_rnd32(uint32_t nbits, void *handle)
 {
 	uint32_t mask = ~0U;
-	uint64_t ent[2];
+	uint64_t ent[2] = {0};
 
-	if (nbits == 0U || nbits > 96U) {
+	if (nbits == 0U || nbits > TRNG_RND32_ENTROPY_MAXBITS) {
 		SMC_RET1(handle, TRNG_E_INVALID_PARAMS);
 	}
 
@@ -59,9 +59,9 @@
 static uintptr_t trng_rnd64(uint32_t nbits, void *handle)
 {
 	uint64_t mask = ~0ULL;
-	uint64_t ent[3];
+	uint64_t ent[3] = {0};
 
-	if (nbits == 0U || nbits > 192U) {
+	if (nbits == 0U || nbits > TRNG_RND64_ENTROPY_MAXBITS) {
 		SMC_RET1(handle, TRNG_E_INVALID_PARAMS);
 	}
 
@@ -117,9 +117,9 @@
 	switch (smc_fid) {
 	case ARM_TRNG_VERSION:
 		SMC_RET1(handle, MAKE_SMCCC_VERSION(
-			TRNG_VERSION_MAJOR, TRNG_VERSION_MINOR
-		));
+			TRNG_VERSION_MAJOR, TRNG_VERSION_MINOR));
 		break; /* unreachable */
+
 	case ARM_TRNG_FEATURES:
 		if (is_trng_fid((uint32_t)x1)) {
 			SMC_RET1(handle, TRNG_E_SUCCESS);
@@ -127,16 +127,19 @@
 			SMC_RET1(handle, TRNG_E_NOT_SUPPORTED);
 		}
 		break; /* unreachable */
+
 	case ARM_TRNG_GET_UUID:
 		SMC_UUID_RET(handle, plat_trng_uuid);
 		break; /* unreachable */
+
 	case ARM_TRNG_RND32:
 		return trng_rnd32((uint32_t)x1, handle);
+
 	case ARM_TRNG_RND64:
 		return trng_rnd64((uint32_t)x1, handle);
+
 	default:
-		WARN("Unimplemented TRNG Service Call: 0x%x\n",
-			smc_fid);
+		WARN("Unimplemented TRNG Service Call: 0x%x\n", smc_fid);
 		SMC_RET1(handle, TRNG_E_NOT_IMPLEMENTED);
 		break; /* unreachable */
 	}
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/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})