Merge changes from topic "ffa_el3_spmc" into integration

* changes:
  docs(spm): add threat model for el3 spmc
  docs(spm): add design documentation
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..e0325e5
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+v16.17.1
diff --git a/Makefile b/Makefile
index afa417b..b42e4ec 100644
--- a/Makefile
+++ b/Makefile
@@ -148,7 +148,10 @@
 CTX_INCLUDE_EL2_REGS := 1
 CTX_INCLUDE_AARCH32_REGS := 0
 ARM_ARCH_MAJOR := 8
-ARM_ARCH_MINOR := 6
+ARM_ARCH_MINOR := 5
+ENABLE_FEAT_ECV = 1
+ENABLE_FEAT_FGT = 1
+
 endif
 
 # USE_SPINLOCK_CAS requires AArch64 build
@@ -730,7 +733,17 @@
     endif
 endif
 
-ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT}),)
+ifeq ($(MEASURED_BOOT)-$(TRUSTED_BOARD_BOOT),1-1)
+# Support authentication verification and hash calculation
+    CRYPTO_SUPPORT := 3
+else ifeq ($(DRTM_SUPPORT)-$(TRUSTED_BOARD_BOOT),1-1)
+# Support authentication verification and hash calculation
+    CRYPTO_SUPPORT := 3
+else ifneq ($(filter 1,${MEASURED_BOOT} ${DRTM_SUPPORT}),)
+# Support hash calculation only
+    CRYPTO_SUPPORT := 2
+else ifeq (${TRUSTED_BOARD_BOOT},1)
+# Support authentication verification only
     CRYPTO_SUPPORT := 1
 else
     CRYPTO_SUPPORT := 0
@@ -842,6 +855,12 @@
     $(info DRTM_SUPPORT is an experimental feature)
 endif
 
+ifeq (${ENABLE_RME},1)
+    ifneq (${SEPARATE_CODE_AND_RODATA},1)
+        $(error `ENABLE_RME=1` requires `SEPARATE_CODE_AND_RODATA=1`)
+    endif
+endif
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
@@ -1035,7 +1054,6 @@
         SPMC_AT_EL3 \
         SPMD_SPM_AT_SEL2 \
         TRUSTED_BOARD_BOOT \
-        CRYPTO_SUPPORT \
         USE_COHERENT_MEM \
         USE_DEBUGFS \
         ARM_IO_IN_DTB \
@@ -1051,7 +1069,7 @@
         ENCRYPT_BL31 \
         ENCRYPT_BL32 \
         ERRATA_SPECULATIVE_AT \
-        RAS_TRAP_LOWER_EL_ERR_ACCESS \
+        RAS_TRAP_NS_ERR_REC_ACCESS \
         COT_DESC_IN_DTB \
         USE_SP804_TIMER \
         PSA_FWU_SUPPORT \
@@ -1070,6 +1088,7 @@
         CTX_INCLUDE_PAUTH_REGS \
         CTX_INCLUDE_MTE_REGS \
         CTX_INCLUDE_NEVE_REGS \
+        CRYPTO_SUPPORT \
         ENABLE_BRBE_FOR_NS \
         ENABLE_TRBE_FOR_NS \
         ENABLE_BTI \
@@ -1191,7 +1210,7 @@
         BL2_INV_DCACHE \
         USE_SPINLOCK_CAS \
         ERRATA_SPECULATIVE_AT \
-        RAS_TRAP_LOWER_EL_ERR_ACCESS \
+        RAS_TRAP_NS_ERR_REC_ACCESS \
         COT_DESC_IN_DTB \
         USE_SP804_TIMER \
         ENABLE_FEAT_RNG \
diff --git a/bl1/aarch32/bl1_entrypoint.S b/bl1/aarch32/bl1_entrypoint.S
index 94dfd37..b22015e 100644
--- a/bl1/aarch32/bl1_entrypoint.S
+++ b/bl1/aarch32/bl1_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -23,8 +23,8 @@
 	b	bl1_entrypoint
 	b	report_exception	/* Undef */
 	b	bl1_aarch32_smc_handler	/* SMC call */
-	b	report_exception	/* Prefetch abort */
-	b	report_exception	/* Data abort */
+	b	report_prefetch_abort	/* Prefetch abort */
+	b	report_data_abort	/* Data abort */
 	b	report_exception	/* Reserved */
 	b	report_exception	/* IRQ */
 	b	report_exception	/* FIQ */
diff --git a/bl2/aarch32/bl2_el3_exceptions.S b/bl2/aarch32/bl2_el3_exceptions.S
index 087b665..eaa2582 100644
--- a/bl2/aarch32/bl2_el3_exceptions.S
+++ b/bl2/aarch32/bl2_el3_exceptions.S
@@ -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
  */
@@ -14,8 +14,8 @@
 	b	bl2_entrypoint
 	b	report_exception	/* Undef */
 	b	report_exception	/* SVC call */
-	b	report_exception	/* Prefetch abort */
-	b	report_exception	/* Data abort */
+	b	report_prefetch_abort	/* Prefetch abort */
+	b	report_data_abort	/* Data abort */
 	b	report_exception	/* Reserved */
 	b	report_exception	/* IRQ */
 	b	report_exception	/* FIQ */
diff --git a/bl2/aarch32/bl2_entrypoint.S b/bl2/aarch32/bl2_entrypoint.S
index 6e8e2c1..678d9c2 100644
--- a/bl2/aarch32/bl2_entrypoint.S
+++ b/bl2/aarch32/bl2_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -16,8 +16,8 @@
 	b	bl2_entrypoint
 	b	report_exception	/* Undef */
 	b	report_exception	/* SVC call */
-	b	report_exception	/* Prefetch abort */
-	b	report_exception	/* Data abort */
+	b	report_prefetch_abort	/* Prefetch abort */
+	b	report_data_abort	/* Data abort */
 	b	report_exception	/* Reserved */
 	b	report_exception	/* IRQ */
 	b	report_exception	/* FIQ */
diff --git a/bl2u/aarch32/bl2u_entrypoint.S b/bl2u/aarch32/bl2u_entrypoint.S
index e4dd03d..1063789 100644
--- a/bl2u/aarch32/bl2u_entrypoint.S
+++ b/bl2u/aarch32/bl2u_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -16,8 +16,8 @@
 	b	bl2u_entrypoint
 	b	report_exception	/* Undef */
 	b	report_exception	/* SVC call */
-	b	report_exception	/* Prefetch abort */
-	b	report_exception	/* Data abort */
+	b	report_prefetch_abort	/* Prefetch abort */
+	b	report_data_abort	/* Data abort */
 	b	report_exception	/* Reserved */
 	b	report_exception	/* IRQ */
 	b	report_exception	/* FIQ */
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 3964469..4c93a55 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -147,6 +147,15 @@
 BL31_SOURCES		+=	common/feat_detect.c
 endif
 
+ifeq (${DRTM_SUPPORT},1)
+BL31_SOURCES		+=	services/std_svc/drtm/drtm_main.c		\
+				services/std_svc/drtm/drtm_dma_prot.c		\
+				services/std_svc/drtm/drtm_res_address_map.c	\
+				services/std_svc/drtm/drtm_measurements.c	\
+				services/std_svc/drtm/drtm_remediation.c	\
+				${MBEDTLS_SOURCES}
+endif
+
 BL31_LINKERFILE		:=	bl31/bl31.ld.S
 
 # Flag used to indicate if Crash reporting via console should be included
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index 39f1065..f102967 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -51,8 +51,8 @@
 	b	sp_min_entrypoint
 	b	plat_panic_handler	/* Undef */
 	b	sp_min_handle_smc	/* Syscall */
-	b	plat_panic_handler	/* Prefetch abort */
-	b	plat_panic_handler	/* Data abort */
+	b	report_prefetch_abort	/* Prefetch abort */
+	b	report_data_abort	/* Data abort */
 	b	plat_panic_handler	/* Reserved */
 	b	plat_panic_handler	/* IRQ */
 	b	sp_min_handle_fiq	/* FIQ */
diff --git a/changelog.yaml b/changelog.yaml
index d3e235d..fac15a7 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -31,7 +31,7 @@
     type: ci
     hidden: true
 
-  - title: Build System
+  - title: Documentation
     description: Documentation-only changes
     type: docs
     hidden: true
@@ -128,6 +128,9 @@
       - title: Trapping support for RNDR/RNDRRS (FEAT_RNG_TRAP)
         scope: rng-trap
 
+      - title: Performance Monitors Extension (FEAT_PMUv3)
+        scope: pmu
+
   - title: Platforms
 
     subsections:
@@ -589,6 +592,9 @@
           - title: SPM MM
             scope: spm-mm
 
+      - title: DRTM
+        scope: drtm
+
   - title: Libraries
 
     subsections:
@@ -649,6 +655,9 @@
       - title: Context Management
         scope: context mgmt
 
+      - title: Semihosting
+        scope: semihosting
+
   - title: Drivers
 
     subsections:
@@ -662,6 +671,12 @@
           - title: CryptoCell-713
             scope: cc-713
 
+          - title: Crypto
+            scope: crypto
+
+          - title: mbedTLS
+            scope: mbedtls
+
       - title: Generic Clock
         scope: clk
 
diff --git a/common/aarch32/debug.S b/common/aarch32/debug.S
index 9d410df..ae0bb7a 100644
--- a/common/aarch32/debug.S
+++ b/common/aarch32/debug.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,8 @@
 	.globl	asm_assert
 	.globl	do_panic
 	.globl	report_exception
+	.globl	report_prefetch_abort
+	.globl	report_data_abort
 
 /* Since the max decimal input number is 65536 */
 #define MAX_DEC_DIVISOR		10000
@@ -205,3 +207,33 @@
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
 endfunc report_exception
+
+	/***********************************************************
+	 * This function is called from the vector table for
+	 * unhandled exceptions. The lr_abt is given as an
+	 * argument to platform handler.
+	 ***********************************************************/
+func report_prefetch_abort
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+	b	report_exception
+#else
+	mrs	r0, lr_abt
+	bl	plat_report_prefetch_abort
+	no_ret	plat_panic_handler
+#endif
+endfunc report_prefetch_abort
+
+	/***********************************************************
+	 * This function is called from the vector table for
+	 * unhandled exceptions. The lr_abt is given as an
+	 * argument to platform handler.
+	 ***********************************************************/
+func report_data_abort
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+	b	report_exception
+#else
+	mrs	r0, lr_abt
+	bl	plat_report_data_abort
+	no_ret	plat_panic_handler
+#endif
+endfunc report_data_abort
diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c
index 25e2c70..89380b3 100644
--- a/common/backtrace/backtrace.c
+++ b/common/backtrace/backtrace.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -37,6 +37,23 @@
 	uintptr_t return_addr;
 };
 
+static inline uintptr_t extract_address(uintptr_t address)
+{
+	uintptr_t ret = address;
+
+#if ENABLE_PAUTH
+	/*
+	 * When pointer authentication is enabled, the LR value saved on the
+	 * stack contains a PAC. It must be stripped to retrieve the return
+	 * address.
+	 */
+
+	xpaci(ret);
+#endif
+
+	return ret;
+}
+
 const char *get_el_str(unsigned int el)
 {
 	if (el == 3U) {
@@ -53,18 +70,11 @@
  * the current EL, false otherwise.
  */
 #ifdef __aarch64__
-static bool is_address_readable(uintptr_t addr)
+static bool is_address_readable(uintptr_t address)
 {
 	unsigned int el = get_current_el();
+	uintptr_t addr = extract_address(address);
 
-#if ENABLE_PAUTH
-	/*
-	 * When pointer authentication is enabled, the LR value saved on the
-	 * stack contains a PAC. It must be stripped to retrieve the return
-	 * address.
-	 */
-	xpaci(addr);
-#endif
 	if (el == 3U) {
 		ats1e3r(addr);
 	} else if (el == 2U) {
@@ -185,7 +195,8 @@
 		return;
 	}
 
-	if (fr->return_addr != link_register) {
+	call_site = extract_address(fr->return_addr);
+	if (call_site != link_register) {
 		printf("ERROR: Corrupted stack (frame record address = %p)\n",
 		       fr);
 		return;
@@ -207,16 +218,9 @@
 		 * call was made is the instruction before the return address,
 		 * which is always 4 bytes before it.
 		 */
-		call_site = fr->return_addr - 4U;
 
-#if ENABLE_PAUTH
-		/*
-		 * When pointer authentication is enabled, the LR value saved on
-		 * the stack contains a PAC. It must be stripped to retrieve the
-		 * return address.
-		 */
-		xpaci(call_site);
-#endif
+		call_site = extract_address(fr->return_addr) - 4U;
+
 		/*
 		 * If the address is invalid it means that the frame record is
 		 * probably corrupted.
diff --git a/docs/about/features.rst b/docs/about/features.rst
index 4b7fbe5..cb8b552 100644
--- a/docs/about/features.rst
+++ b/docs/about/features.rst
@@ -46,8 +46,8 @@
 -  A Test SP and SPD to demonstrate AArch64 Secure Monitor functionality and SP
    interaction with PSCI.
 
--  SPDs for the `OP-TEE Secure OS`_, `NVIDIA Trusted Little Kernel`_
-   and `Trusty Secure OS`_.
+-  SPDs for the `OP-TEE Secure OS`_, `NVIDIA Trusted Little Kernel`_,
+   `Trusty Secure OS`_ and `ProvenCore Secure OS`_.
 
 -  A Trusted Board Boot implementation, conforming to all mandatory TBBR
    requirements. This includes image authentication, Firmware Update (or
@@ -121,6 +121,7 @@
 .. _OP-TEE Secure OS: https://github.com/OP-TEE/optee_os
 .. _NVIDIA Trusted Little Kernel: http://nv-tegra.nvidia.com/gitweb/?p=3rdparty/ote_partner/tlk.git;a=summary
 .. _Trusty Secure OS: https://source.android.com/security/trusty
+.. _ProvenCore Secure OS: https://provenrun.com/products/provencore/
 
 --------------
 
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 96a0523..a980ed9 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -162,6 +162,18 @@
 :|F|: include/drivers/ufs.h
 :|F|: include/drivers/synopsys/dw_mmc.h
 
+Arm® Ethos™-N NPU driver
+^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Joshua Slater <joshua.slater@arm.com>
+:|G|: `jslater8`_
+:|M|: Mikael Olsson <mikael.olsson@arm.com>
+:|G|: `mikaelolsson-arm`_
+:|F|: drivers/arm/ethosn/
+:|F|: include/drivers/arm/ethosn.h
+:|F|: plat/arm/common/fconf/fconf_ethosn_getter.c
+:|F|: include/plat/arm/common/fconf_ethosn_getter.h
+:|F|: fdts/juno-ethosn.dtsi
+
 JTAG DCC console driver
 ^^^^^^^^^^^^^^^^^^^^^^^
 :M: Michal Simek <michal.simek@amd.com>
@@ -470,10 +482,8 @@
 
 Arm Total Compute platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
-:|G|: `arugan02`_
-:|M|: Usama Arif <usama.arif@arm.com>
-:|G|: `uarif1`_
+:|M|: Anders Dellien <anders.dellien@arm.com>
+:|G|: `andersdellien-arm`_
 :|F|: plat/arm/board/tc
 
 HiSilicon HiKey and HiKey960 platform ports
@@ -731,7 +741,7 @@
 :|G|: `michalsimek`_
 :|M|: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>
 :|G|: `venkatesh`_
-:|F|: docs/plat/xilinx-zynqmp.rst
+:|F|: docs/plat/xilinx\*
 :|F|: plat/xilinx/
 
 
@@ -772,6 +782,13 @@
 :|F|: bl32/tsp/
 :|F|: services/spd/tspd/
 
+ProvenCore Secure Payload Dispatcher
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Jérémie Corbier <jeremie.corbier@provenrun.com>
+:|G|: `jcorbier`_
+:|F|: docs/components/spd/pnc-dispatcher.rst
+:|F|: services/spd/pncd/
+
 Tools
 ~~~~~
 
@@ -829,6 +846,7 @@
 :|F|: tools/conventional-changelog-tf-a
 
 .. _AlexeiFedorov: https://github.com/AlexeiFedorov
+.. _andersdellien-arm: https://github.com/andersdellien-arm
 .. _Andre-ARM: https://github.com/Andre-ARM
 .. _Anson-Huang: https://github.com/Anson-Huang
 .. _bijucdas: https://github.com/bijucdas
@@ -842,7 +860,9 @@
 .. _grandpaul: https://github.com/grandpaul
 .. _hzhuang1: https://github.com/hzhuang1
 .. _JackyBai: https://github.com/JackyBai
+.. _jcorbier: https://github.com/jcorbier
 .. _jenswi-linaro: https://github.com/jenswi-linaro
+.. _jslater8: https://github.com/jslater8
 .. _jwerner-chromium: https://github.com/jwerner-chromium
 .. _kostapr: https://github.com/kostapr
 .. _lachitp: https://github.com/lachitp
@@ -850,6 +870,7 @@
 .. _marex: https://github.com/marex
 .. _masahir0y: https://github.com/masahir0y
 .. _michalsimek: https://github.com/michalsimek
+.. _mikaelolsson-arm: https://github.com/mikaelolsson-arm
 .. _mmind: https://github.com/mmind
 .. _MrVan: https://github.com/MrVan
 .. _mtk-rex-bc-chen: https://github.com/mtk-rex-bc-chen
diff --git a/docs/components/firmware-update.rst b/docs/components/firmware-update.rst
index a591565..1ba1e1c 100644
--- a/docs/components/firmware-update.rst
+++ b/docs/components/firmware-update.rst
@@ -1,22 +1,118 @@
 Firmware Update (FWU)
 =====================
 
+This document describes the design of the various Firmware Update (FWU)
+mechanisms available in TF-A.
+
+1. PSA Firmware Update (PSA FWU)
+2. TBBR Firmware Update (TBBR FWU)
+
+PSA Firmware Update implements the specification of the same name (Arm document
+IHI 0093), which defines a standard firmware interface for installing firmware
+updates.
+On the other hand, TBBR Firmware Update only covers firmware recovery. Arguably,
+its name is somewhat misleading but the TBBR specification and terminology
+predates PSA FWU. Both mechanisms are complementary in the sense that PSA FWU
+assumes that the device has a backup or recovery capability in the event of a
+failed update, which can be fulfilled with TBBR FWU implementation.
+
+.. _PSA Firmware Update:
+
+PSA Firmware Update (PSA FWU)
+-----------------------------
+
 Introduction
-------------
+~~~~~~~~~~~~
+The `PSA FW update specification`_ defines the concepts of ``Firmware Update
+Client`` and ``Firmware Update Agent``.
+The new firmware images are provided by the ``Client`` to the ``Update Agent``
+to flash them in non-volatile storage.
+
+A common system design will place the ``Update Agent`` in the Secure-world
+while the ``Client`` executes in the Normal-world.
+The `PSA FW update specification`_ provides ABIs meant for a Normal-world
+entity aka ``Client`` to transmit the firmware images to the ``Update Agent``.
+
+Scope
+~~~~~
+The design of the ``Client`` and ``Update Agent`` is out of scope of this
+document.
+This document mainly covers ``Platform Boot`` details i.e. the role of
+the second stage Bootloader after FWU has been done by ``Client`` and
+``Update Agent``.
+
+Overview
+~~~~~~~~
+
+There are active and update banks in the non-volatile storage identified
+by the ``active_index`` and the ``update_index`` respectively.
+An active bank stores running firmware, whereas an update bank contains
+firmware updates.
+
+Once Firmwares are updated in the update bank of the non-volatile
+storage, then ``Update Agent`` marks the update bank as the active bank,
+and write updated FWU metadata in non-volatile storage.
+On subsequent reboot, the second stage Bootloader (BL2) performs the
+following actions:
+
+-  Read FWU metadata in memory
+-  Retrieve the image specification (offset and length) of updated images
+   present in non-volatile storage with the help of FWU metadata
+-  Set these image specification in the corresponding I/O policies of the
+   updated images using the FWU platform functions
+   ``plat_fwu_set_images_source()`` and ``plat_fwu_set_metadata_image_source()``,
+   please refer :ref:`Porting Guide`
+-  Use these I/O policies to read the images from this address into the memory
+
+By default, the platform uses the active bank of non-volatile storage to boot
+the images in ``trial state``. If images pass through the authentication check
+and also if the system successfully booted the Normal-world image then
+``Update Agent`` marks this update as accepted after further sanitisation
+checking at Normal-world.
+
+The second stage Bootloader (BL2) avoids upgrading the platform NV-counter until
+it's been confirmed that given update is accepted.
 
-This document describes the design of the Firmware Update (FWU) feature, which
-enables authenticated firmware to update firmware images from external
-interfaces such as USB, UART, SD-eMMC, NAND, NOR or Ethernet to SoC Non-Volatile
-memories such as NAND Flash, LPDDR2-NVM or any memory determined by the
-platform. This feature functions even when the current firmware in the system
-is corrupt or missing; it therefore may be used as a recovery mode. It may also
-be complemented by other, higher level firmware update software.
+The following sequence diagram shows platform-boot flow:
+
+.. image:: ../resources/diagrams/PSA-FWU.png
+
+If the platform fails to boot from active bank due to any reasons such
+as authentication failure or non-fuctionality of Normal-world software then the
+watchdog will reset to give a chance to the platform to fix the issue. This
+boot failure & reset sequence might be repeated up to ``trial state`` times.
+After that, the platform can decide to boot from the ``previous_active_index``
+bank.
+
+If the images still does not boot successfully from the ``previous_active_index``
+bank (e.g. due to ageing effect of non-volatile storage) then the platform can
+choose firmware recovery mechanism :ref:`TBBR Firmware Update` to bring system
+back to life.
+
+.. _TBBR Firmware Update:
+
+TBBR Firmware Update (TBBR FWU)
+-------------------------------
+
+Introduction
+~~~~~~~~~~~~
+
+This technique enables authenticated firmware to update firmware images from
+external interfaces such as USB, UART, SD-eMMC, NAND, NOR or Ethernet to SoC
+Non-Volatile memories such as NAND Flash, LPDDR2-NVM or any memory determined
+by the platform.
+This feature functions even when the current firmware in the system is corrupt
+or missing; it therefore may be used as a recovery mode. It may also be
+complemented by other, higher level firmware update software.
 
 FWU implements a specific part of the Trusted Board Boot Requirements (TBBR)
 specification, Arm DEN0006C-1. It should be used in conjunction with the
 :ref:`Trusted Board Boot` design document, which describes the image
 authentication parts of the Trusted Firmware-A (TF-A) TBBR implementation.
 
+It can be used as a last resort when all firmware updates that are carried out
+as part of the :ref:`PSA Firmware Update` procedure have failed to function.
+
 Scope
 ~~~~~
 
@@ -25,8 +121,8 @@
 FWU images, please refer to the "Non-Trusted Firmware Updater" requirements in
 the TBBR.
 
-FWU Overview
-------------
+Overview
+~~~~~~~~
 
 The FWU boot flow is primarily mediated by BL1. Since BL1 executes in ROM, and
 it is usually desirable to minimize the amount of ROM code, the design allows
@@ -66,7 +162,7 @@
 |Flow Diagram|
 
 Image Identification
---------------------
+~~~~~~~~~~~~~~~~~~~~
 
 Each FWU image and certificate is identified by a unique ID, defined by the
 platform, which BL1 uses to fetch an image descriptor (``image_desc_t``) via a
@@ -93,7 +189,7 @@
 -  Initialize the execution state of the next FWU image.
 
 FWU State Machine
------------------
+~~~~~~~~~~~~~~~~~
 
 BL1 maintains state for each FWU image during FWU execution. FWU images at lower
 Exception Levels raise SMCs to invoke FWU functionality in BL1, which causes
@@ -126,10 +222,10 @@
    requested BL1 to resume normal world execution.
 
 BL1 SMC Interface
------------------
+~~~~~~~~~~~~~~~~~
 
 BL1_SMC_CALL_COUNT
-~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -142,7 +238,7 @@
 This SMC returns the number of SMCs supported by BL1.
 
 BL1_SMC_UID
-~~~~~~~~~~~
+^^^^^^^^^^^
 
 ::
 
@@ -156,7 +252,7 @@
 BL1 SMC service.
 
 BL1_SMC_VERSION
-~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^
 
 ::
 
@@ -170,7 +266,7 @@
 This SMC returns the current version of the BL1 SMC service.
 
 BL1_SMC_RUN_IMAGE
-~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -190,7 +286,7 @@
 this SMC for BL1 to pass execution control to BL31.
 
 FWU_SMC_IMAGE_COPY
-~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -239,7 +335,7 @@
 Once the SMC is handled, BL1 returns from exception to the normal world caller.
 
 FWU_SMC_IMAGE_AUTH
-~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -279,7 +375,7 @@
 the -EAUTH error and sets the image state back to RESET.
 
 FWU_SMC_IMAGE_EXECUTE
-~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -307,7 +403,7 @@
 EXECUTED, and returns from exception to the secure image.
 
 FWU_SMC_IMAGE_RESUME
-~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -334,7 +430,7 @@
 returned to the caller.
 
 FWU_SMC_SEC_IMAGE_DONE
-~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -355,7 +451,7 @@
 world.
 
 FWU_SMC_UPDATE_DONE
-~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -371,7 +467,7 @@
 a ``void *``. The SMC does not return.
 
 FWU_SMC_IMAGE_RESET
-~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -393,8 +489,9 @@
 
 --------------
 
-*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.*
 
 .. _Universally Unique Identifier: https://tools.ietf.org/rfc/rfc4122.txt
 .. |Flow Diagram| image:: ../resources/diagrams/fwu_flow.png
 .. |FWU state machine| image:: ../resources/diagrams/fwu_states.png
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
diff --git a/docs/components/ras.rst b/docs/components/ras.rst
index 02207d8..b435349 100644
--- a/docs/components/ras.rst
+++ b/docs/components/ras.rst
@@ -30,8 +30,8 @@
 
 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
-be set ``1``. ``RAS_TRAP_LOWER_EL_ERR_ACCESS`` controls the access to the RAS
-error record registers from lower ELs.
+be set ``1``. ``RAS_TRAP_NS_ERR_REC_ACCESS`` controls the access to the RAS
+error record registers from Non-secure.
 
 .. _ras-figure:
 
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index b767958..8070ff4 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -494,8 +494,11 @@
    #. General purpose registers (x0-x30) and ``sp_el0``, ``sp_el2`` stack pointers
    #. EL2 system register context for all enabled features by EL3. These include system registers with the ``_EL2`` prefix. The EL2 physical and virtual timer registers must not be included in this.
 
-It is the responsibility of EL3 that the above registers will not be leaked to
-the NS Host and to maintain the confidentiality of the Realm World.
+As part of SMC forwarding between the NS world and Realm world, EL3 allows x0-x7 to be passed
+as arguments to Realm and x0-x4 to be used for return arguments back to Non Secure.
+As per SMCCCv1.2, x4 must be preserved if not being used as return argument by the SMC function
+and it is the responsibility of RMM to preserve this or use this as a return argument.
+EL3 will always copy x0-x4 from Realm context to NS Context.
 
 EL3 will not save some registers as mentioned in the below list. It is the
 responsibility of RMM to ensure that these are appropriately saved if the
@@ -506,6 +509,9 @@
    #. SME registers
    #. EL1/0 registers
 
+It is the responsibility of EL3 that any other registers other than the ones mentioned above
+will not be leaked to the NS Host and to maintain the confidentiality of the Realm World.
+
 SMCCC v1.3 allows NS world to specify whether SVE context is in use. In this
 case, RMM could choose to not save the incoming SVE context but must ensure
 to clear SVE registers if they have been used in Realm World. The same applies
diff --git a/docs/components/spd/index.rst b/docs/components/spd/index.rst
index 25d0124..6857806 100644
--- a/docs/components/spd/index.rst
+++ b/docs/components/spd/index.rst
@@ -8,3 +8,4 @@
    optee-dispatcher
    tlk-dispatcher
    trusty-dispatcher
+   pnc-dispatcher
diff --git a/docs/components/spd/pnc-dispatcher.rst b/docs/components/spd/pnc-dispatcher.rst
new file mode 100644
index 0000000..5be2fc7
--- /dev/null
+++ b/docs/components/spd/pnc-dispatcher.rst
@@ -0,0 +1,10 @@
+ProvenCore Dispatcher
+=====================
+
+ProvenCore dispatcher (PnC-D) adds support for ProvenRun's ProvenCore micro-kernel
+to work with Trusted Firmware-A (TF-A).
+
+ProvenCore is a secure OS developed by ProvenRun S.A.S. using deductive formal methods.
+
+Once a BL32 is ready, PnC-D can be included in the image by adding "SPD=pncd"
+to the build command.
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 3477a04..7ba79b9 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -273,6 +273,9 @@
 -  ``ERRATA_A77_2356587``: This applies errata 2356587 workaround to Cortex-A77
    CPU. This needs to be enabled for r0p0, r1p0, and r1p1, it is still open.
 
+ -  ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77
+    CPU. This needs to be enabled for revisions <= r1p1 of the CPU.
+
 For Cortex-A78, the following errata build flags are defined :
 
 -  ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78
@@ -492,6 +495,10 @@
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
 
+- ``ERRATA_A710_2291219``: This applies errata 2291219 workaround to
+   Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
+   of the CPU and is fixed in r2p1.
+
 -  ``ERRATA_A710_2008768``: This applies errata 2008768 workaround to
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
@@ -532,6 +539,10 @@
 -  ``ERRATA_N2_2280757``: This applies errata 2280757 workaround to Neoverse-N2
    CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
 
+-  ``ERRATA_N2_2326639``: This applies errata 2326639 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
+   r0p1.
+
 -  ``ERRATA_N2_2376738``: This applies errata 2376738 workaround to Neoverse-N2
    CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
    r0p1.
@@ -573,6 +584,12 @@
    Cortex-X2 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
 
+For Cortex-X3, the following errata build flags are defined :
+
+- ``ERRATA_X3_2313909``: This applies errata 2313909 workaround to
+  Cortex-X3 CPU. This needs to be enabled only for revisions r0p0 and r1p0
+  of the CPU, it is fixed in r1p1.
+
 For Cortex-A510, the following errata build flags are defined :
 
 -  ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
@@ -613,6 +630,10 @@
    Cortex-A510 CPU. This needs to applied for revisions r0p0, r0p1, r0p2,
    r0p3, r1p0, r1p1, and is fixed in r1p2.
 
+-  ``ERRATA_A510_2666669``: This applies errata 2666669 workaround to
+   Cortex-A510 CPU. This needs to applied for revisions r0p0, r0p1, r0p2,
+   r0p3, r1p0, r1p1. It is fixed in r1p2.
+
 DSU Errata Workarounds
 ----------------------
 
diff --git a/docs/design_documents/drtm_poc.rst b/docs/design_documents/drtm_poc.rst
new file mode 100644
index 0000000..79e1142
--- /dev/null
+++ b/docs/design_documents/drtm_poc.rst
@@ -0,0 +1,132 @@
+DRTM Proof of Concept
+=====================
+
+Dynamic Root of Trust for Measurement (DRTM) begins a new trust environment
+by measuring and executing a protected payload.
+
+Static Root of Trust for Measurement (SRTM)/Measured Boot implementation,
+currently used by TF-A covers all firmwares, from the boot ROM to the normal
+world bootloader. As a whole, they make up the system's TCB. These boot
+measurements allow attesting to what software is running on the system and
+enable enforcing security policies.
+
+As the boot chain grows or firmware becomes dynamically extensible,
+establishing an attestable TCB becomes more challenging. DRTM  provides a
+solution to this problem by allowing measurement chains to be started at
+any time. As these measurements are stored separately from the boot-time
+measurements, they reduce the size of the TCB, which helps reduce the attack
+surface and the risk of untrusted code executing, which could compromise
+the security of the system.
+
+Components
+~~~~~~~~~~
+
+   - **DCE-Preamble**: The DCE Preamble prepares the platform for DRTM by
+     doing any needed configuration, loading the target payload image(DLME),
+     and preparing input parameters needed by DRTM. Finally, it invokes the
+     DL Event to start the dynamic launch.
+
+   - **D-CRTM**: The D-CRTM is the trust anchor (or root of trust) for the
+     DRTM boot sequence and is where the dynamic launch starts. The D-CRTM
+     must be implemented as a trusted agent in the system. The D-CRTM
+     initializes the TPM for DRTM and prepares the environment for the next
+     stage of DRTM, the DCE. The D-CRTM measures the DCE, verifies its
+     signature, and transfers control to it.
+
+   - **DCE**: The DCE executes on an application core. The DCE verifies the
+     system’s state, measures security-critical attributes of the system,
+     prepares the memory region for the target payload, measures the payload,
+     and finally transfers control to the payload.
+
+   - **DLME**: The protected payload is referred to as the Dynamically Launched
+     Measured Environment, or DLME. The DLME begins execution in a safe state,
+     with a single thread of execution, DMA protections, and interrupts
+     disabled. The DCE provides data to the DLME that it can use to verify the
+     configuration of the system.
+
+In this proof of concept, DCE and D-CRTM are implemented in BL31 and
+DCE-Preamble and DLME are implemented in UEFI application. A DL Event is
+triggered as a SMC by DCE-Preamble and handled by D-CRTM, which launches the
+DLME via DCE.
+
+This manual provides instructions to build TF-A code with pre-buit EDK2
+and DRTM UEFI application.
+
+Building the PoC for the Arm FVP platform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(1) Use the below command to clone TF-A source code -
+
+.. code:: shell
+
+   $ git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
+
+(2) There are prebuilt binaries required to execute the DRTM implementation
+    in the `prebuilts-drtm-bins`_.
+    Download EDK2  *FVP_AARCH64_EFI.fd* and UEFI DRTM application *test-disk.img*
+    binary from `prebuilts-drtm-bins`_.
+
+(3) Build the TF-A code using below command
+
+.. code:: shell
+
+   $ make CROSS_COMPILE=aarch64-none-elf- ARM_ROTPK_LOCATION=devel_rsa
+     DEBUG=1 V=1 BL33=</path/to/FVP_AARCH64_EFI.fd> DRTM_SUPPORT=1
+     MBEDTLS_DIR=</path/to/mbedTLS-source> USE_ROMLIB=1 all fip
+
+Running DRTM UEFI application on the Armv8-A AEM FVP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+To run the DRTM test application along with DRTM implementation in BL31,
+you need an FVP model. Please use the version of FVP_Base_RevC-2xAEMvA model
+advertised in the TF-A documentation.
+
+.. code:: shell
+
+    FVP_Base_RevC-2xAEMvA \
+    --data cluster0.cpu0=</path/to/romlib.bin>@0x03ff2000 \
+    --stat \
+    -C bp.flashloader0.fname=<path/to/fip.bin> \
+    -C bp.secureflashloader.fname=<path/to/bl1.bin> \
+    -C bp.ve_sysregs.exit_on_shutdown=1 \
+    -C bp.virtioblockdevice.image_path=<path/to/test-disk.img> \
+    -C cache_state_modelled=1 \
+    -C cluster0.check_memory_attributes=0 \
+    -C cluster0.cpu0.etm-present=0 \
+    -C cluster0.cpu1.etm-present=0 \
+    -C cluster0.cpu2.etm-present=0 \
+    -C cluster0.cpu3.etm-present=0 \
+    -C cluster0.stage12_tlb_size=1024 \
+    -C cluster1.check_memory_attributes=0 \
+    -C cluster1.cpu0.etm-present=0 \
+    -C cluster1.cpu1.etm-present=0 \
+    -C cluster1.cpu2.etm-present=0 \
+    -C cluster1.cpu3.etm-present=0 \
+    -C cluster1.stage12_tlb_size=1024 \
+    -C pctl.startup=0.0.0.0 \
+    -Q 1000 \
+    "$@"
+
+The bottom of the output from *uart1* should look something like the
+following to indicate that the last SMC to unprotect memory has been fired
+successfully.
+
+.. code-block:: shell
+
+ ...
+
+ INFO:    DRTM service handler: version
+ INFO:    ++ DRTM service handler: TPM features
+ INFO:    ++ DRTM service handler: Min. mem. requirement features
+ INFO:    ++ DRTM service handler: DMA protection features
+ INFO:    ++ DRTM service handler: Boot PE ID features
+ INFO:    ++ DRTM service handler: TCB-hashes features
+ INFO:    DRTM service handler: dynamic launch
+ WARNING: DRTM service handler: close locality is not supported
+ INFO:    DRTM service handler: unprotect mem
+
+--------------
+
+*Copyright (c) 2022, Arm Limited. All rights reserved.*
+
+.. _prebuilts-drtm-bins: https://downloads.trustedfirmware.org/tf-a/drtm
+.. _DRTM-specification: https://developer.arm.com/documentation/den0113/a
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index 257a510..765efe6 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -9,7 +9,8 @@
    cmake_framework
    context_mgmt_rework
    measured_boot_poc
+   drtm_poc
 
 --------------
 
-*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index cca76c6..5980050 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -987,7 +987,7 @@
       implement this workaround due to the behaviour of the errata mentioned
       in new SDEN document which will get published soon.
 
-- ``RAS_TRAP_LOWER_EL_ERR_ACCESS``: This flag enables/disables the SCR_EL3.TERR
+- ``RAS_TRAP_NS_ERR_REC_ACCESS``: This flag enables/disables the SCR_EL3.TERR
   bit, to trap access to the RAS ERR and RAS ERX registers from lower ELs.
   This flag is disabled by default.
 
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 992aca1..6996c17 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -242,6 +242,11 @@
 
    Defines the maximum address in secure RAM that the BL31 image can occupy.
 
+-  **#define : PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE**
+
+   Defines the maximum message size between AP and RSS. Need to define if
+   platform supports RSS.
+
 For every image, the platform must define individual identifiers that will be
 used by BL1 or BL2 to load the corresponding image into memory from non-volatile
 storage. For the sake of performance, integer numbers will be used as
@@ -564,6 +569,21 @@
    doesn't print anything to the console. If ``PLAT_LOG_LEVEL_ASSERT`` isn't
    defined, it defaults to ``LOG_LEVEL``.
 
+If the platform port uses the DRTM feature, the following constants must be
+defined:
+
+-  **#define : PLAT_DRTM_EVENT_LOG_MAX_SIZE**
+
+   Maximum Event Log size used by the platform. Platform can decide the maximum
+   size of the Event Log buffer, depending upon the highest hash algorithm
+   chosen and the number of components selected to measure during the DRTM
+   execution flow.
+
+-  **#define : PLAT_DRTM_MMAP_ENTRIES**
+
+   Number of the MMAP entries used by the DRTM implementation to calculate the
+   size of address map region of the platform.
+
 File : plat_macros.S [mandatory]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -789,6 +809,186 @@
 either could not be updated or the authentication image descriptor indicates
 that it is not allowed to be updated.
 
+Dynamic Root of Trust for Measurement support (in BL31)
+-------------------------------------------------------
+
+The functions mentioned in this section are mandatory, when platform enables
+DRTM_SUPPORT build flag.
+
+Function : plat_get_addr_mmap()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : const mmap_region_t *
+
+This function is used to return the address of the platform *address-map* table,
+which describes the regions of normal memory, memory mapped I/O
+and non-volatile memory.
+
+Function : plat_has_non_host_platforms()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : bool
+
+This function returns *true* if the platform has any trusted devices capable of
+DMA, otherwise returns *false*.
+
+Function : plat_has_unmanaged_dma_peripherals()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : bool
+
+This function returns *true* if platform uses peripherals whose DMA is not
+managed by an SMMU, otherwise returns *false*.
+
+Note -
+If the platform has peripherals that are not managed by the SMMU, then the
+platform should investigate such peripherals to determine whether they can
+be trusted, and such peripherals should be moved under "Non-host platforms"
+if they can be trusted.
+
+Function : plat_get_total_num_smmus()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : unsigned int
+
+This function returns the total number of SMMUs in the platform.
+
+Function : plat_enumerate_smmus()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+::
+
+
+    Argument : void
+    Return   : const uintptr_t *, size_t
+
+This function returns an array of SMMU addresses and the actual number of SMMUs
+reported by the platform.
+
+Function : plat_drtm_get_dma_prot_features()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : const plat_drtm_dma_prot_features_t*
+
+This function returns the address of plat_drtm_dma_prot_features_t structure
+containing the maximum number of protected regions and bitmap with the types
+of DMA protection supported by the platform.
+For more details see section 3.3 Table 6 of `DRTM`_ specification.
+
+Function : plat_drtm_dma_prot_get_max_table_bytes()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint64_t
+
+This function returns the maximum size of DMA protected regions table in
+bytes.
+
+Function : plat_drtm_get_tpm_features()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : const plat_drtm_tpm_features_t*
+
+This function returns the address of *plat_drtm_tpm_features_t* structure
+containing PCR usage schema, TPM-based hash, and firmware hash algorithm
+supported by the platform.
+
+Function : plat_drtm_get_min_size_normal_world_dce()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint64_t
+
+This function returns the size normal-world DCE of the platform.
+
+Function : plat_drtm_get_imp_def_dlme_region_size()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint64_t
+
+This function returns the size of implementation defined DLME region
+of the platform.
+
+Function : plat_drtm_get_tcb_hash_table_size()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint64_t
+
+This function returns the size of TCB hash table of the platform.
+
+Function : plat_drtm_get_tcb_hash_features()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : uint64_t
+
+This function returns the Maximum number of TCB hashes recorded by the
+platform.
+For more details see section 3.3 Table 6 of `DRTM`_ specification.
+
+Function : plat_drtm_validate_ns_region()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uintptr_t, uintptr_t
+    Return   : int
+
+This function validates that given region is within the Non-Secure region
+of DRAM. This function takes a region start address and size an input
+arguments, and returns 0 on success and -1 on failure.
+
+Function : plat_set_drtm_error()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uint64_t
+    Return   : int
+
+This function writes a 64 bit error code received as input into
+non-volatile storage and returns 0 on success and -1 on failure.
+
+Function : plat_get_drtm_error()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uint64_t*
+    Return   : int
+
+This function reads a 64 bit error code from the non-volatile storage
+into the received address, and returns 0 on success and -1 on failure.
+
 Common mandatory function modifications
 ---------------------------------------
 
@@ -1097,6 +1297,20 @@
    The address from where it was called is stored in x30 (Link Register).
    The default implementation simply spins.
 
+Function : plat_system_reset()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : void
+
+This function is used by the platform to resets the system. It can be used
+in any specific use-case where system needs to be resetted. For example,
+in case of DRTM implementation this function reset the system after
+writing the DRTM error code in the non-volatile storage. This function
+never returns. Failure in reset results in panic.
+
 Function : plat_get_bl_image_load_info()
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2555,7 +2769,8 @@
 The ``target_state`` has a similar meaning as described in the ``pwr_domain_off()``
 operation and it encodes the platform coordinated target local power states for
 the CPU power domain and its parent power domain levels. This function must
-not return back to the caller.
+not return back to the caller (by calling wfi in an infinite loop to ensure
+some CPUs power down mitigations work properly).
 
 If this function is not implemented by the platform, PSCI generic
 implementation invokes ``psci_power_down_wfi()`` for power down.
@@ -3225,3 +3440,4 @@
 .. _3.0 (GICv3): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0069b/index.html
 .. _FreeBSD: https://www.freebsd.org
 .. _SCC: http://www.simple-cc.org/
+.. _DRTM: https://developer.arm.com/documentation/den0113/a
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 81c55a5..0ed8517 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -26,7 +26,7 @@
 |TF-A| can be built with any of the following *cross-compiler* toolchains that
 target the Armv7-A or Armv8-A architectures:
 
-- GCC >= 11.2-2022.02 (from the `Arm Developer website`_)
+- GCC >= 11.3.Rel1 (from the `Arm Developer website`_)
 - Clang >= 14.0.0
 - Arm Compiler >= 6.18
 
diff --git a/docs/glossary.rst b/docs/glossary.rst
index e2cc794..e6b0239 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -40,6 +40,18 @@
       Common Vulnerabilities and Exposures. A CVE document is commonly used to
       describe a publicly-known security vulnerability.
 
+   DCE
+      DRTM Configuration Environment
+
+   D-CRTM
+      Dynamic Code Root of Trust for Measurement
+
+   DLME
+      Dynamically Launched Measured Environment
+
+   DRTM
+      Dynamic Root of Trust for Measurement
+
    DS-5
       Arm Development Studio 5
 
@@ -189,6 +201,9 @@
    TBBR
       Trusted Board Boot Requirements
 
+   TCB
+      Trusted Compute Base
+
    TEE
       Trusted Execution Environment
 
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index 339ebbe..407c04b 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -92,7 +92,7 @@
    SBROM library must be specified via ``CCSBROM_LIB_PATH`` flag.
 
 -  ``ARM_ETHOSN_NPU_DRIVER``: boolean option to enable a SiP service that can
-   configure an Arm Ethos-N NPU. To use this service the target platform's
+   configure an Arm® Ethos™-N NPU. To use this service the target platform's
    ``HW_CONFIG`` must include the device tree nodes for the NPU. Currently, only
    the Arm Juno platform has this included in its ``HW_CONFIG`` and the platform
    only loads the ``HW_CONFIG`` in AArch64 builds. Default is 0.
@@ -152,6 +152,11 @@
     to select the appropriate platform variant for the build. The range of
     valid values is platform specific.
 
+- ``CSS_SYSTEM_GRACEFUL_RESET``: Build option to enable graceful powerdown of
+   CPU core on reset. This build option can be used on CSS platforms that
+   require all the CPUs to execute the CPU specific power down sequence to
+   complete a warm reboot sequence in which only the CPUs are power cycled.
+
 --------------
 
 .. |FIP in a GPT image| image:: ../../resources/diagrams/FIP_in_a_GPT_image.png
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 3d10e45..b28c247 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -327,19 +327,14 @@
 
 -  ``fvp-base-gicv2-psci.dts``
 
-   For use with models such as the Cortex-A57-A53 Base FVPs without shifted
-   affinities and with Base memory map configuration.
-
--  ``fvp-base-gicv2-psci-aarch32.dts``
-
-   For use with models such as the Cortex-A32 Base FVPs without shifted
-   affinities and running Linux in AArch32 state with Base memory map
-   configuration.
+   For use with models such as the Cortex-A57-A53 or Cortex-A32 Base FVPs
+   without shifted affinities and with Base memory map configuration.
 
 -  ``fvp-base-gicv3-psci.dts``
 
-   For use with models such as the Cortex-A57-A53 Base FVPs without shifted
-   affinities and with Base memory map configuration and Linux GICv3 support.
+   For use with models such as the Cortex-A57-A53 or Cortex-A32 Base FVPs
+   without shifted affinities and with Base memory map configuration and
+   Linux GICv3 support.
 
 -  ``fvp-base-gicv3-psci-1t.dts``
 
@@ -352,12 +347,6 @@
    single cluster, single threaded CPUs, Base memory map configuration and Linux
    GICv3 support.
 
--  ``fvp-base-gicv3-psci-aarch32.dts``
-
-   For use with models such as the Cortex-A32 Base FVPs without shifted
-   affinities and running Linux in AArch32 state with Base memory map
-   configuration and Linux GICv3 support.
-
 -  ``fvp-foundation-gicv2-psci.dts``
 
    For use with Foundation FVP with Base memory map configuration.
diff --git a/docs/plat/arm/tc/index.rst b/docs/plat/arm/tc/index.rst
index ae2b836..df1847d 100644
--- a/docs/plat/arm/tc/index.rst
+++ b/docs/plat/arm/tc/index.rst
@@ -18,7 +18,7 @@
 is the CPUs supported as below:
 
 -  TC0 has support for Cortex A510, Cortex A710 and Cortex X2.
--  TC1 has support for Cortex A510, Cortex Makalu and Cortex Makalu ELP.
+-  TC1 has support for Cortex A510, Cortex Makalu and Cortex X3.
 -  TC2 has support for Hayes and Hunter Arm CPUs.
 
 
diff --git a/docs/plat/imx8m.rst b/docs/plat/imx8m.rst
index 101d52b..f8071f7 100644
--- a/docs/plat/imx8m.rst
+++ b/docs/plat/imx8m.rst
@@ -68,3 +68,46 @@
 with a DTB overlay. The overlay will be put at PLAT_IMX8M_DTO_BASE with
 maximum size PLAT_IMX8M_DTO_MAX_SIZE. Then in U-boot we can apply the DTB
 overlay and let U-boot to parse the event log and update the PCRs.
+
+High Assurance Boot (HABv4)
+---------------------------
+
+All actively maintained platforms have a support for High Assurance
+Boot (HABv4), which is implemented via ROM Vector Table (RVT) API to
+extend the Root-of-Trust beyond the SPL. Those calls are done via SMC
+and are executed in EL3, with results returned back to original caller.
+
+Note on DRAM Memory Mapping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There is a special case of mapping the DRAM: entire DRAM available on the
+platform is mapped into the EL3 with MT_RW attributes.
+
+Mapping the entire DRAM allows the usage of 2MB block mapping in Level-2
+Translation Table entries, which use less Page Table Entries (PTEs). If
+Level-3 PTE mapping is used instead then additional PTEs would be required,
+which leads to the increase of translation table size.
+
+Due to the fact that the size of SRAM is limited on some platforms in the
+family it should rather be avoided creating additional Level-3 mapping and
+introduce more PTEs, hence the implementation uses Level-2 mapping which
+maps entire DRAM space.
+
+The reason for the MT_RW attribute mapping scheme is the fact that the SMC
+API to get the status and events is called from NS world passing destination
+pointers which are located in DRAM. Mapping DRAM without MT_RW permissions
+causes those locations not to be filled, which in turn causing EL1&0 software
+not to receive replies.
+
+Therefore, DRAM mapping is done with MT_RW attributes, as it is required for
+data exchange between EL3 and EL1&0 software.
+
+Reference Documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Details on HABv4 usage and implementation could be found in following documents:
+
+- AN4581: "i.MX Secure Boot on HABv4 Supported Devices",  Rev. 4 - June 2020
+- AN12263: "HABv4 RVT Guidelines and Recommendations", Rev. 1 - 06/2020
+- "HABv4 API Reference Manual". This document in the part of NXP Code Signing Tool (CST) distribution.
+
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 1f497e0..28b1787 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -43,6 +43,7 @@
    synquacer
    stm32mp1
    ti-k3
+   xilinx-versal-net
    xilinx-versal
    xilinx-zynqmp
    brcm-stingray
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index 7ae98b1..fff86a8 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -144,8 +144,12 @@
 
 - | ``DTB_FILE_NAME``: to precise board device-tree blob to be used.
   | Default: stm32mp157c-ev1.dtb
+- | ``DWL_BUFFER_BASE``: the 'serial boot' load address of FIP,
+  | default location (end of the first 128MB) is used when absent
 - | ``STM32MP_EARLY_CONSOLE``: to enable early traces before clock driver is setup.
   | Default: 0 (disabled)
+- | ``STM32MP_RECONFIGURE_CONSOLE``: to re-configure crash console (especially after BL2).
+  | Default: 0 (disabled)
 - | ``STM32MP_UART_BAUDRATE``: to select UART baud rate.
   | Default: 115200
 - | ``STM32_TF_VERSION``: to manage BL2 monotonic counter.
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
new file mode 100644
index 0000000..5d2e663
--- /dev/null
+++ b/docs/plat/xilinx-versal-net.rst
@@ -0,0 +1,31 @@
+Xilinx Versal NET
+=================
+
+Trusted Firmware-A implements the EL3 firmware layer for Xilinx Versal NET.
+The platform only uses the runtime part of TF-A as Xilinx Versal NET already
+has a BootROM (BL1) and PMC FW (BL2).
+
+BL31 is TF-A.
+BL32 is an optional Secure Payload.
+BL33 is the non-secure world software (U-Boot, Linux etc).
+
+To build:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net bl31
+```
+
+Xilinx Versal NET platform specific build options
+-------------------------------------------------
+
+*   `VERSAL_NET_ATF_MEM_BASE`: Specifies the base address of the bl31 binary.
+*   `VERSAL_NET_ATF_MEM_SIZE`: Specifies the size of the memory region of the bl31 binary.
+*   `VERSAL_NET_BL32_MEM_BASE`: Specifies the base address of the bl32 binary.
+*   `VERSAL_NET_BL32_MEM_SIZE`: Specifies the size of the memory region of the bl32 binary.
+
+*   `VERSAL_NET_CONSOLE`: Select the console driver. Options:
+    -   `pl011`, `pl011_0`: ARM pl011 UART 0
+    -   `pl011_1`         : ARM pl011 UART 1
+
+*   `TFA_NO_PM` : Platform Management support.
+    -    0 : Enable Platform Management (Default)
+    -    1 : Disable Platform Management
diff --git a/docs/resources/diagrams/Makefile b/docs/resources/diagrams/Makefile
index 4e65569..c951754 100644
--- a/docs/resources/diagrams/Makefile
+++ b/docs/resources/diagrams/Makefile
@@ -73,7 +73,13 @@
 rmm_el3_manifest_struct_layers		= "Background"
 rmm_el3_manifest_struct_opts		=
 
-all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG) $(RMM_PNG) $(RMM_EL3_MANIFEST_PNG)
+PSA_FWU_DIA				= PSA-FWU.dia
+PSA_FWU_PNG				= PSA-FWU.png
+
+FWU-update_struct_layers		= "background"
+FWU-update_struct_opts			=
+
+all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG) $(RMM_PNG) $(RMM_EL3_MANIFEST_PNG) $(PSA_FWU_PNG)
 
 $(RESET_PNGS):$(RESET_DIA)
 	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
@@ -90,3 +96,6 @@
 
 $(RMM_EL3_MANIFEST_PNG):$(RMM_EL3_MANIFEST_DIA)
 	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
+
+$(PSA_FWU_PNG):$(PSA_FWU_DIA)
+	$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
diff --git a/docs/resources/diagrams/PSA-FWU.dia b/docs/resources/diagrams/PSA-FWU.dia
new file mode 100644
index 0000000..aac5276
--- /dev/null
+++ b/docs/resources/diagrams/PSA-FWU.dia
Binary files differ
diff --git a/docs/resources/diagrams/PSA-FWU.png b/docs/resources/diagrams/PSA-FWU.png
new file mode 100644
index 0000000..d58ba86
--- /dev/null
+++ b/docs/resources/diagrams/PSA-FWU.png
Binary files differ
diff --git a/docs/security_advisories/security-advisory-tfv-9.rst b/docs/security_advisories/security-advisory-tfv-9.rst
index a7b5984..08bfdc4 100644
--- a/docs/security_advisories/security-advisory-tfv-9.rst
+++ b/docs/security_advisories/security-advisory-tfv-9.rst
@@ -71,12 +71,12 @@
 +----------------------+
 | Cortex-X2            |
 +----------------------+
+| Cortex-X3            |
++----------------------+
 | Cortex-A710          |
 +----------------------+
 | Cortex-Makalu        |
 +----------------------+
-| Cortex-Makalu-ELP    |
-+----------------------+
 | Cortex-Hunter        |
 +----------------------+
 | Neoverse-N1          |
@@ -85,7 +85,7 @@
 +----------------------+
 | Neoverse-V1          |
 +----------------------+
-| Neoverse-Demeter     |
+| Neoverse-V2          |
 +----------------------+
 | Neoverse-Poseidon    |
 +----------------------+
diff --git a/drivers/amlogic/crypto/sha_dma.c b/drivers/amlogic/crypto/sha_dma.c
index fceb1c0..5c16d49 100644
--- a/drivers/amlogic/crypto/sha_dma.c
+++ b/drivers/amlogic/crypto/sha_dma.c
@@ -8,6 +8,7 @@
 #include <assert.h>
 #include <crypto/sha_dma.h>
 #include <lib/mmio.h>
+#include <platform_def.h>
 
 #include "aml_private.h"
 
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index 5de2604..9fe8b37 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -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
  */
@@ -11,6 +11,7 @@
 #include <common/debug.h>
 #include <drivers/arm/css/css_scp.h>
 #include <drivers/arm/css/scmi.h>
+#include <lib/mmio.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/arm/css/common/css_pm.h>
 #include <plat/common/platform.h>
@@ -286,15 +287,42 @@
 	return HW_OFF;
 }
 
+/*
+ * Callback function to raise a SGI designated to trigger the CPU power down
+ * sequence on all the online secondary cores.
+ */
+static void css_raise_pwr_down_interrupt(u_register_t mpidr)
+{
+#if CSS_SYSTEM_GRACEFUL_RESET
+	plat_ic_raise_el3_sgi(CSS_CPU_PWR_DOWN_REQ_INTR, mpidr);
+#endif
+}
+
 void __dead2 css_scp_system_off(int state)
 {
 	int ret;
 
 	/*
+	 * Before issuing the system power down command, set the trusted mailbox
+	 * to 0. This will ensure that in the case of a warm/cold reset, the
+	 * primary CPU executes from the cold boot sequence.
+	 */
+	mmio_write_64(PLAT_ARM_TRUSTED_MAILBOX_BASE, 0U);
+
+	/*
+	 * Send powerdown request to online secondary core(s)
+	 */
+	ret = psci_stop_other_cores(0, css_raise_pwr_down_interrupt);
+	if (ret != PSCI_E_SUCCESS) {
+		ERROR("Failed to powerdown secondary core(s)\n");
+	}
+
+	/*
 	 * Disable GIC CPU interface to prevent pending interrupt from waking
 	 * up the AP from WFI.
 	 */
 	plat_arm_gic_cpuif_disable();
+	plat_arm_gic_redistif_off();
 
 	/*
 	 * Issue SCMI command. First issue a graceful
@@ -309,6 +337,9 @@
 			state, ret);
 		panic();
 	}
+
+	/* Powerdown of primary core */
+	psci_pwrdown_cpu(PLAT_MAX_PWR_LVL);
 	wfi();
 	ERROR("CSS set power state: operation not handled.\n");
 	panic();
diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c
index 60364cd..915a0d8 100644
--- a/drivers/arm/ethosn/ethosn_smc.c
+++ b/drivers/arm/ethosn/ethosn_smc.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
  */
@@ -12,18 +12,17 @@
 #include <drivers/arm/ethosn.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
+#include <lib/utils_def.h>
 #include <plat/arm/common/fconf_ethosn_getter.h>
 
 /*
- * Number of Arm Ethos-N NPU (NPU) cores available for a
- * particular parent device
+ * Number of Arm(R) Ethos(TM)-N NPU (NPU) devices available
  */
-#define ETHOSN_NUM_CORES \
-	FCONF_GET_PROPERTY(hw_config, ethosn_config, num_cores)
+#define ETHOSN_NUM_DEVICES \
+	FCONF_GET_PROPERTY(hw_config, ethosn_config, num_devices)
 
-/* Address to an NPU core  */
-#define ETHOSN_CORE_ADDR(core_idx) \
-	FCONF_GET_PROPERTY(hw_config, ethosn_core_addr, core_idx)
+#define ETHOSN_GET_DEVICE(dev_idx) \
+	FCONF_GET_PROPERTY(hw_config, ethosn_device, dev_idx)
 
 /* NPU core sec registry address */
 #define ETHOSN_CORE_SEC_REG(core_addr, reg_offset) \
@@ -40,9 +39,6 @@
 #define SEC_SECCTLR_REG			U(0x0010)
 #define SEC_SECCTLR_VAL			U(0x3)
 
-#define SEC_DEL_MMUSID_REG		U(0x2008)
-#define SEC_DEL_MMUSID_VAL		U(0x3FFFF)
-
 #define SEC_DEL_ADDR_EXT_REG		U(0x201C)
 #define SEC_DEL_ADDR_EXT_VAL		U(0x15)
 
@@ -50,17 +46,63 @@
 #define SEC_SYSCTRL0_SOFT_RESET		U(3U << 29)
 #define SEC_SYSCTRL0_HARD_RESET		U(1U << 31)
 
-static bool ethosn_is_core_addr_valid(uintptr_t core_addr)
+#define SEC_MMUSID_REG_BASE		U(0x3008)
+#define SEC_MMUSID_OFFSET		U(0x1000)
+
+static bool ethosn_get_device_and_core(uintptr_t core_addr,
+				       const struct ethosn_device_t **dev_match,
+				       const struct ethosn_core_t **core_match)
 {
-	for (uint32_t core_idx = 0U; core_idx < ETHOSN_NUM_CORES; core_idx++) {
-		if (ETHOSN_CORE_ADDR(core_idx) == core_addr) {
-			return true;
+	uint32_t dev_idx;
+	uint32_t core_idx;
+
+	for (dev_idx = 0U; dev_idx < ETHOSN_NUM_DEVICES; ++dev_idx) {
+		const struct ethosn_device_t *dev = ETHOSN_GET_DEVICE(dev_idx);
+
+		for (core_idx = 0U; core_idx < dev->num_cores; ++core_idx) {
+			const struct ethosn_core_t *core = &(dev->cores[core_idx]);
+
+			if (core->addr == core_addr) {
+				*dev_match = dev;
+				*core_match = core;
+				return true;
+			}
 		}
 	}
 
+	WARN("ETHOSN: Unknown core address given to SMC call.\n");
 	return false;
 }
 
+static void ethosn_configure_smmu_streams(const struct ethosn_device_t *device,
+					  const struct ethosn_core_t *core,
+					  uint32_t asset_alloc_idx)
+{
+	const struct ethosn_main_allocator_t *main_alloc =
+		&(core->main_allocator);
+	const struct ethosn_asset_allocator_t *asset_alloc =
+		&(device->asset_allocators[asset_alloc_idx]);
+	const uint32_t streams[9] = {
+		main_alloc->firmware.stream_id,
+		main_alloc->working_data.stream_id,
+		asset_alloc->command_stream.stream_id,
+		0U, /* Not used*/
+		main_alloc->firmware.stream_id,
+		asset_alloc->weight_data.stream_id,
+		asset_alloc->buffer_data.stream_id,
+		asset_alloc->intermediate_data.stream_id,
+		asset_alloc->buffer_data.stream_id
+	};
+	size_t i;
+
+	for (i = 0U; i < ARRAY_SIZE(streams); ++i) {
+		const uintptr_t reg_addr = SEC_MMUSID_REG_BASE +
+			(SEC_MMUSID_OFFSET * i);
+		mmio_write_32(ETHOSN_CORE_SEC_REG(core->addr, reg_addr),
+			      streams[i]);
+	}
+}
+
 static void ethosn_delegate_to_ns(uintptr_t core_addr)
 {
 	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SECCTLR_REG),
@@ -69,9 +111,6 @@
 	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_DEL_REG),
 			SEC_DEL_VAL);
 
-	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_DEL_MMUSID_REG),
-			SEC_DEL_MMUSID_VAL);
-
 	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_DEL_ADDR_EXT_REG),
 			SEC_DEL_ADDR_EXT_VAL);
 }
@@ -112,7 +151,7 @@
 
 uintptr_t ethosn_smc_handler(uint32_t smc_fid,
 			     u_register_t core_addr,
-			     u_register_t x2,
+			     u_register_t asset_alloc_idx,
 			     u_register_t x3,
 			     u_register_t x4,
 			     void *cookie,
@@ -120,6 +159,8 @@
 			     u_register_t flags)
 {
 	int hard_reset = 0;
+	const struct ethosn_device_t *device = NULL;
+	const struct ethosn_core_t *core = NULL;
 	const uint32_t fid = smc_fid & FUNCID_NUM_MASK;
 
 	/* Only SiP fast calls are expected */
@@ -131,12 +172,14 @@
 	/* Truncate parameters to 32-bits for SMC32 */
 	if (GET_SMC_CC(smc_fid) == SMC_32) {
 		core_addr &= 0xFFFFFFFF;
-		x2 &= 0xFFFFFFFF;
+		asset_alloc_idx &= 0xFFFFFFFF;
 		x3 &= 0xFFFFFFFF;
 		x4 &= 0xFFFFFFFF;
 	}
 
-	if (!is_ethosn_fid(smc_fid)) {
+	if (!is_ethosn_fid(smc_fid) ||
+	    (fid < ETHOSN_FNUM_VERSION || fid > ETHOSN_FNUM_SOFT_RESET)) {
+		WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
 
@@ -146,25 +189,41 @@
 		SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR);
 	}
 
-	if (!ethosn_is_core_addr_valid(core_addr)) {
-		WARN("ETHOSN: Unknown core address given to SMC call.\n");
+	if (!ethosn_get_device_and_core(core_addr, &device, &core))  {
 		SMC_RET1(handle, ETHOSN_UNKNOWN_CORE_ADDRESS);
 	}
 
-	/* Commands that require a valid addr */
+	/* Commands that require a valid core address */
 	switch (fid) {
 	case ETHOSN_FNUM_IS_SEC:
-		SMC_RET1(handle, ethosn_is_sec(core_addr));
+		SMC_RET1(handle, ethosn_is_sec(core->addr));
+	}
+
+	if (!device->has_reserved_memory &&
+	    asset_alloc_idx >= device->num_allocators) {
+		WARN("ETHOSN: Unknown asset allocator index given to SMC call.\n");
+		SMC_RET1(handle, ETHOSN_UNKNOWN_ALLOCATOR_IDX);
+	}
+
+	/* Commands that require a valid device, core and asset allocator */
+	switch (fid) {
 	case ETHOSN_FNUM_HARD_RESET:
 		hard_reset = 1;
 		/* Fallthrough */
 	case ETHOSN_FNUM_SOFT_RESET:
-		if (!ethosn_reset(core_addr, hard_reset)) {
+		if (!ethosn_reset(core->addr, hard_reset)) {
 			SMC_RET1(handle, ETHOSN_FAILURE);
 		}
+
+		if (!device->has_reserved_memory) {
+			ethosn_configure_smmu_streams(device, core,
+						      asset_alloc_idx);
+		}
-		ethosn_delegate_to_ns(core_addr);
+
+		ethosn_delegate_to_ns(core->addr);
 		SMC_RET1(handle, ETHOSN_SUCCESS);
 	default:
+		WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
 }
diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c
index 939d097..1925a13 100644
--- a/drivers/arm/gic/v2/gicv2_main.c
+++ b/drivers/arm/gic/v2/gicv2_main.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -417,7 +418,7 @@
  * The proc_num parameter must be the linear index of the target PE in the
  * system.
  ******************************************************************************/
-void gicv2_raise_sgi(int sgi_num, int proc_num)
+void gicv2_raise_sgi(int sgi_num, bool ns, int proc_num)
 {
 	unsigned int sgir_val, target;
 
@@ -437,7 +438,7 @@
 	target = driver_data->target_masks[proc_num];
 	assert(target != 0U);
 
-	sgir_val = GICV2_SGIR_VALUE(SGIR_TGT_SPECIFIC, target, sgi_num);
+	sgir_val = GICV2_SGIR_VALUE(SGIR_TGT_SPECIFIC, target, ns, sgi_num);
 
 	/*
 	 * Ensure that any shared variable updates depending on out of band
diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c
index 75eb69a..83ef32f 100644
--- a/drivers/arm/gic/v3/gic-x00.c
+++ b/drivers/arm/gic/v3/gic-x00.c
@@ -16,6 +16,7 @@
 #include <assert.h>
 
 #include <arch_helpers.h>
+#include <common/debug.h>
 #include <drivers/arm/arm_gicv3_common.h>
 #include <drivers/arm/gicv3.h>
 
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
index 5f42ad9..e85dbc1 100644
--- a/drivers/arm/gic/v3/gic600_multichip.c
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -97,16 +98,28 @@
 		spi_id_max = GIC600_SPI_ID_MIN;
 	}
 
-	spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
-	spi_blocks    = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
-
 	switch ((gicd_iidr_val & IIDR_MODEL_MASK)) {
 	case IIDR_MODEL_ARM_GIC_600:
+		spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
+		spi_blocks    = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
+
 		chipr_n_val = GICD_CHIPR_VALUE_GIC_600(chip_addr,
 						       spi_block_min,
 						       spi_blocks);
 		break;
 	case IIDR_MODEL_ARM_GIC_700:
+		/* Calculate the SPI_ID_MIN value for ESPI */
+		if (spi_id_min >= GIC700_ESPI_ID_MIN) {
+			spi_block_min = ESPI_BLOCK_MIN_VALUE(spi_id_min);
+			spi_block_min += SPI_BLOCKS_VALUE(GIC700_SPI_ID_MIN,
+				GIC700_SPI_ID_MAX);
+		} else {
+			spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
+		}
+
+		/* Calculate the total number of blocks */
+		spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
+
 		chipr_n_val = GICD_CHIPR_VALUE_GIC_700(chip_addr,
 						       spi_block_min,
 						       spi_blocks);
@@ -202,13 +215,104 @@
 }
 
 /*******************************************************************************
- * Intialize GIC-600 Multichip operation.
+ * Validates the GIC-700 Multichip data structure passed by the platform.
+ ******************************************************************************/
+static void gic700_multichip_validate_data(
+		struct gic600_multichip_data *multichip_data)
+{
+	unsigned int i, spi_id_min, spi_id_max, blocks_of_32;
+	unsigned int multichip_spi_blocks = 0U, multichip_espi_blocks = 0U;
+
+	assert(multichip_data != NULL);
+
+	if (multichip_data->chip_count > GIC600_MAX_MULTICHIP) {
+		ERROR("GIC-700 Multichip count (%u) should not exceed %u\n",
+				multichip_data->chip_count, GIC600_MAX_MULTICHIP);
+		panic();
+	}
+
+	for (i = 0U; i < multichip_data->chip_count; i++) {
+		spi_id_min = multichip_data->spi_ids[i][SPI_MIN_INDEX];
+		spi_id_max = multichip_data->spi_ids[i][SPI_MAX_INDEX];
+
+		if ((spi_id_min == 0U) || (spi_id_max == 0U)) {
+			continue;
+		}
+
+		/* MIN SPI ID check */
+		if ((spi_id_min < GIC700_SPI_ID_MIN) ||
+		    ((spi_id_min >= GIC700_SPI_ID_MAX) &&
+		     (spi_id_min < GIC700_ESPI_ID_MIN))) {
+			ERROR("Invalid MIN SPI ID {%u} passed for "
+					"Chip %u\n", spi_id_min, i);
+			panic();
+		}
+
+		if ((spi_id_min > spi_id_max) ||
+		    ((spi_id_max - spi_id_min + 1) % 32 != 0)) {
+			ERROR("Unaligned SPI IDs {%u, %u} passed for "
+					"Chip %u\n", spi_id_min,
+					spi_id_max, i);
+			panic();
+		}
+
+		/* ESPI IDs range check */
+		if ((spi_id_min >= GIC700_ESPI_ID_MIN) &&
+		    (spi_id_max > GIC700_ESPI_ID_MAX)) {
+			ERROR("Invalid ESPI IDs {%u, %u} passed for "
+					"Chip %u\n", spi_id_min,
+					spi_id_max, i);
+			panic();
+
+		}
+
+		/* SPI IDs range check */
+		if (((spi_id_min < GIC700_SPI_ID_MAX) &&
+		     (spi_id_max > GIC700_SPI_ID_MAX))) {
+			ERROR("Invalid SPI IDs {%u, %u} passed for "
+					"Chip %u\n", spi_id_min,
+					spi_id_max, i);
+			panic();
+		}
+
+		/* SPI IDs overlap check */
+		if (spi_id_max < GIC700_SPI_ID_MAX) {
+			blocks_of_32 = BLOCKS_OF_32(spi_id_min, spi_id_max);
+			if ((multichip_spi_blocks & blocks_of_32) != 0) {
+				ERROR("SPI IDs of Chip %u overlapping\n", i);
+				panic();
+			}
+			multichip_spi_blocks |= blocks_of_32;
+		}
+
+		/* ESPI IDs overlap check */
+		if (spi_id_max > GIC700_ESPI_ID_MIN) {
+			blocks_of_32 = BLOCKS_OF_32(spi_id_min - GIC700_ESPI_ID_MIN,
+					spi_id_max - GIC700_ESPI_ID_MIN);
+			if ((multichip_espi_blocks & blocks_of_32) != 0) {
+				ERROR("SPI IDs of Chip %u overlapping\n", i);
+				panic();
+			}
+			multichip_espi_blocks |= blocks_of_32;
+		}
+	}
+}
+
+/*******************************************************************************
+ * Intialize GIC-600 and GIC-700 Multichip operation.
  ******************************************************************************/
 void gic600_multichip_init(struct gic600_multichip_data *multichip_data)
 {
 	unsigned int i;
+	uint32_t gicd_iidr_val = gicd_read_iidr(multichip_data->rt_owner_base);
 
-	gic600_multichip_validate_data(multichip_data);
+	if ((gicd_iidr_val & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) {
+		gic600_multichip_validate_data(multichip_data);
+	}
+
+	if ((gicd_iidr_val & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700) {
+		gic700_multichip_validate_data(multichip_data);
+	}
 
 	/*
 	 * Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures
diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h
index 5d1ff6a..414bd5b 100644
--- a/drivers/arm/gic/v3/gic600_multichip_private.h
+++ b/drivers/arm/gic/v3/gic600_multichip_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,6 +41,11 @@
 #define GIC600_SPI_ID_MIN		32
 #define GIC600_SPI_ID_MAX		960
 
+#define GIC700_SPI_ID_MIN		32
+#define GIC700_SPI_ID_MAX		991
+#define GIC700_ESPI_ID_MIN		4096
+#define GIC700_ESPI_ID_MAX		5119
+
 /* Number of retries for PUP update */
 #define GICD_PUP_UPDATE_RETRIES		10000
 
@@ -53,6 +58,9 @@
 #define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
 			(((spi_id_max) - (spi_id_min) + 1) / \
 			GIC600_SPI_ID_MIN)
+#define ESPI_BLOCK_MIN_VALUE(spi_id_min) \
+			(((spi_id_min) - GIC700_ESPI_ID_MIN + 1) / \
+			GIC700_SPI_ID_MIN)
 #define GICD_CHIPR_VALUE_GIC_700(chip_addr, spi_block_min, spi_blocks) \
 			(((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
 			((spi_block_min) << GIC_700_SPI_BLOCK_MIN_SHIFT) | \
@@ -66,7 +74,8 @@
  * Multichip data assertion macros
  */
 /* Set bits from 0 to ((spi_id_max + 1) / 32) */
-#define SPI_BLOCKS_TILL_MAX(spi_id_max)	((1 << (((spi_id_max) + 1) >> 5)) - 1)
+#define SPI_BLOCKS_TILL_MAX(spi_id_max) \
+			((1ULL << (((spi_id_max) + 1) >> 5)) - 1)
 /* Set bits from 0 to (spi_id_min / 32) */
 #define SPI_BLOCKS_TILL_MIN(spi_id_min)	((1 << ((spi_id_min) >> 5)) - 1)
 /* Set bits from (spi_id_min / 32) to ((spi_id_max + 1) / 32) */
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index f3852d2..446d0ad 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -12,6 +12,8 @@
 #include <common/interrupt_props.h>
 #include <drivers/arm/gic_common.h>
 
+#include <platform_def.h>
+
 #include "../common/gic_common_private.h"
 #include "gicv3_private.h"
 
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 8ead43b..bc93f93 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -1095,11 +1095,12 @@
 }
 
 /*******************************************************************************
- * This function raises the specified Secure Group 0 SGI.
+ * This function raises the specified SGI of the specified group.
  *
  * The target parameter must be a valid MPIDR in the system.
  ******************************************************************************/
-void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target)
+void gicv3_raise_sgi(unsigned int sgi_num, gicv3_irq_group_t group,
+		u_register_t target)
 {
 	unsigned int tgt, aff3, aff2, aff1, aff0;
 	uint64_t sgi_val;
@@ -1129,7 +1130,22 @@
 	 * interrupt trigger are observed before raising SGI.
 	 */
 	dsbishst();
-	write_icc_sgi0r_el1(sgi_val);
+
+	switch (group) {
+	case GICV3_G0:
+		write_icc_sgi0r_el1(sgi_val);
+		break;
+	case GICV3_G1NS:
+		write_icc_asgi1r(sgi_val);
+		break;
+	case GICV3_G1S:
+		write_icc_sgi1r(sgi_val);
+		break;
+	default:
+		assert(false);
+		break;
+	}
+
 	isb();
 }
 
diff --git a/drivers/arm/mhu/mhu_wrapper_v2_x.c b/drivers/arm/mhu/mhu_wrapper_v2_x.c
index d8b7cfd..60de1d3 100644
--- a/drivers/arm/mhu/mhu_wrapper_v2_x.c
+++ b/drivers/arm/mhu/mhu_wrapper_v2_x.c
@@ -300,3 +300,13 @@
 
 	return MHU_ERR_NONE;
 }
+
+size_t mhu_get_max_message_size(void)
+{
+	struct mhu_v2_x_dev_t *dev = &MHU1_SEH_DEV;
+	uint32_t num_channels = mhu_v2_x_get_num_channel_implemented(dev);
+
+	assert(num_channels != 0);
+
+	return num_channels * sizeof(uint32_t);
+}
diff --git a/drivers/arm/rss/rss_comms.c b/drivers/arm/rss/rss_comms.c
index 28a4925..5e224e1 100644
--- a/drivers/arm/rss/rss_comms.c
+++ b/drivers/arm/rss/rss_comms.c
@@ -10,199 +10,144 @@
 #include <common/debug.h>
 #include <drivers/arm/mhu.h>
 #include <drivers/arm/rss_comms.h>
-#include <initial_attestation.h>
 #include <psa/client.h>
+#include <rss_comms_protocol.h>
 
-#include <platform_def.h>
-
-#define TYPE_OFFSET	U(16)
-#define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
-#define IN_LEN_OFFSET	U(8)
-#define IN_LEN_MASK	(0xFFUL << IN_LEN_OFFSET)
-#define OUT_LEN_OFFSET	U(0)
-#define OUT_LEN_MASK	(0xFFUL << OUT_LEN_OFFSET)
-
-#define PARAM_PACK(type, in_len, out_len)			  \
-	(((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK)	| \
-	 ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK)	| \
-	 ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
-
-#define PARAM_UNPACK_IN_LEN(ctrl_param) \
-	((size_t)(((ctrl_param) & IN_LEN_MASK) >> IN_LEN_OFFSET))
-
-/* Message types */
-struct __packed packed_psa_call_t {
-	uint8_t protocol_ver;
-	uint8_t seq_num;
-	uint16_t client_id;
-	psa_handle_t handle;
-	uint32_t ctrl_param; /* type, in_len, out_len */
-	uint16_t io_size[4];
-};
-
-struct __packed packed_psa_reply_t {
-	uint8_t protocol_ver;
-	uint8_t seq_num;
-	uint16_t client_id;
-	int32_t return_val;
-	uint16_t out_size[4];
-};
-
-/*
- * In the current implementation the RoT Service request that requires the
- * biggest message buffer is the RSS_ATTEST_GET_TOKEN. The maximum required
- * buffer size is calculated based on the platform-specific needs of
- * this request.
+/* Union as message space and reply space are never used at the same time, and this saves space as
+ * we can overlap them.
  */
-#define MAX_REQUEST_PAYLOAD_SIZE	(PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 \
-					 + PLAT_ATTEST_TOKEN_MAX_SIZE)
-
-/* Buffer to store the messages to be sent/received. */
-static uint8_t message_buf[MAX_REQUEST_PAYLOAD_SIZE] __aligned(4);
+union __packed __attribute__((aligned(4))) rss_comms_io_buffer_t {
+	struct serialized_rss_comms_msg_t msg;
+	struct serialized_rss_comms_reply_t reply;
+};
 
-static int32_t pack_params(const psa_invec *invecs,
-			   size_t in_len,
-			   uint8_t *buf,
-			   size_t *buf_len)
+static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
+				       const psa_outvec *out_vec, size_t out_len)
 {
-	uint32_t i;
-	size_t payload_size = 0U;
+	size_t comms_mhu_msg_size;
+	size_t comms_embed_msg_min_size;
+	size_t comms_embed_reply_min_size;
+	size_t in_size_total = 0;
+	size_t out_size_total = 0;
+	size_t i;
 
 	for (i = 0U; i < in_len; ++i) {
-		if (invecs[i].len > *buf_len - payload_size) {
-			return -1;
-		}
-		memcpy(buf + payload_size, invecs[i].base, invecs[i].len);
-		payload_size += invecs[i].len;
+		in_size_total += in_vec[i].len;
 	}
-
-	*buf_len = payload_size;
-	return 0;
-}
-
-static int serialise_message(const struct packed_psa_call_t *msg,
-			     const psa_invec *invecs,
-			     uint8_t *payload_buf,
-			     size_t *payload_len)
-{
-	size_t message_len = 0U;
-	size_t len;
-
-	/* Copy the message header into the payload buffer. */
-	len = sizeof(*msg);
-	if (len > *payload_len) {
-		ERROR("[RSS-COMMS] Message buffer too small.\n");
-		return -1;
-	}
-	memcpy(payload_buf, (const void *)msg, len);
-	message_len += len;
-
-	/* The input data will follow the message header in the payload buffer. */
-	len = *payload_len - message_len;
-	if (pack_params(invecs, PARAM_UNPACK_IN_LEN(msg->ctrl_param),
-			payload_buf + message_len, &len) != 0) {
-		ERROR("[RSS-COMMS] Message buffer too small.\n");
-		return -1;
-	}
-	message_len += len;
-
-	*payload_len = message_len;
-	return 0;
-}
-
-static void unpack_params(const uint8_t *buf,
-			  psa_outvec *outvecs,
-			  size_t out_len)
-{
-	size_t i;
-
 	for (i = 0U; i < out_len; ++i) {
-		memcpy(outvecs[i].base, buf, outvecs[i].len);
-		buf += outvecs[i].len;
+		out_size_total += out_vec[i].len;
 	}
-}
 
-static void deserialise_reply(struct packed_psa_reply_t *reply,
-			      psa_outvec *outvecs,
-			      size_t outlen,
-			      const uint8_t *message,
-			      size_t message_len)
-{
-	uint32_t i;
+	comms_mhu_msg_size = mhu_get_max_message_size();
 
-	memcpy(reply, message, sizeof(*reply));
+	comms_embed_msg_min_size = sizeof(struct serialized_rss_comms_header_t) +
+				   sizeof(struct rss_embed_msg_t) -
+				   PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE;
 
-	/* Outvecs */
-	for (i = 0U; i < outlen; ++i) {
-		outvecs[i].len = reply->out_size[i];
-	}
+	comms_embed_reply_min_size = sizeof(struct serialized_rss_comms_header_t) +
+				     sizeof(struct rss_embed_reply_t) -
+				     PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE;
 
-	unpack_params(message + sizeof(*reply), outvecs, outlen);
+	/* Use embed if we can pack into one message and reply, else use
+	 * pointer_access. The underlying MHU transport protocol uses a
+	 * single uint32_t to track the length, so the amount of data that
+	 * can be in a message is 4 bytes less than mhu_get_max_message_size
+	 * reports.
+	 *
+	 * TODO tune this with real performance numbers, it's possible a
+	 * pointer_access message is less performant than multiple embed
+	 * messages due to ATU configuration costs to allow access to the
+	 * pointers.
+	 */
+	if ((comms_embed_msg_min_size + in_size_total > comms_mhu_msg_size - sizeof(uint32_t))
+	 || (comms_embed_reply_min_size + out_size_total > comms_mhu_msg_size) - sizeof(uint32_t)) {
+		return RSS_COMMS_PROTOCOL_POINTER_ACCESS;
+	} else {
+		return RSS_COMMS_PROTOCOL_EMBED;
+	}
 }
 
-psa_status_t psa_call(psa_handle_t handle, int32_t type,
-		      const psa_invec *in_vec, size_t in_len,
+psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec, size_t in_len,
 		      psa_outvec *out_vec, size_t out_len)
 {
+	/* Declared statically to avoid using huge amounts of stack space. Maybe revisit if
+	 * functions not being reentrant becomes a problem.
+	 */
+	static union rss_comms_io_buffer_t io_buf;
 	enum mhu_error_t err;
-	static uint32_t seq_num = 1U;
-	struct packed_psa_call_t msg = {
-		.protocol_ver = 0U,
-		.seq_num = seq_num,
-		/* No need to distinguish callers (currently concurrent calls are not supported). */
-		.client_id = 1U,
-		.handle = handle,
-		.ctrl_param = PARAM_PACK(type, in_len, out_len),
-	};
+	psa_status_t status;
+	static uint8_t seq_num = 1U;
+	size_t msg_size;
+	size_t reply_size = sizeof(io_buf.reply);
+	psa_status_t return_val;
+	size_t idx;
 
-	struct packed_psa_reply_t reply = {0};
-	size_t message_size;
-	uint32_t i;
-
-	/* Fill msg iovec lengths */
-	for (i = 0U; i < in_len; ++i) {
-		msg.io_size[i] = in_vec[i].len;
+	if (type > INT16_MAX || type < INT16_MIN || in_len > PSA_MAX_IOVEC
+	    || out_len > PSA_MAX_IOVEC) {
+		return PSA_ERROR_INVALID_ARGUMENT;
 	}
-	for (i = 0U; i < out_len; ++i) {
-		msg.io_size[in_len + i] = out_vec[i].len;
+
+	io_buf.msg.header.seq_num = seq_num,
+	/* No need to distinguish callers (currently concurrent calls are not supported). */
+	io_buf.msg.header.client_id = 1U,
+	io_buf.msg.header.protocol_ver = select_protocol_version(in_vec, in_len, out_vec, out_len);
+
+	status = rss_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec,
+					    out_len, &io_buf.msg, &msg_size);
+	if (status != PSA_SUCCESS) {
+		return status;
 	}
 
-	message_size = sizeof(message_buf);
-	if (serialise_message(&msg, in_vec, message_buf, &message_size)) {
-		/* Local buffer is probably too small. */
-		return PSA_ERROR_INSUFFICIENT_MEMORY;
+	VERBOSE("[RSS-COMMS] Sending message\n");
+	VERBOSE("protocol_ver=%u\n", io_buf.msg.header.protocol_ver);
+	VERBOSE("seq_num=%u\n", io_buf.msg.header.seq_num);
+	VERBOSE("client_id=%u\n", io_buf.msg.header.client_id);
+	for (idx = 0; idx < in_len; idx++) {
+		VERBOSE("in_vec[%lu].len=%lu\n", idx, in_vec[idx].len);
+		VERBOSE("in_vec[%lu].buf=%p\n", idx, (void *)in_vec[idx].base);
 	}
 
-	err = mhu_send_data(message_buf, message_size);
+	err = mhu_send_data((uint8_t *)&io_buf.msg, msg_size);
 	if (err != MHU_ERR_NONE) {
 		return PSA_ERROR_COMMUNICATION_FAILURE;
 	}
 
-	message_size = sizeof(message_buf);
 #if DEBUG
 	/*
 	 * Poisoning the message buffer (with a known pattern).
 	 * Helps in detecting hypothetical RSS communication bugs.
 	 */
-	memset(message_buf, 0xA5, message_size);
+	memset(&io_buf.msg, 0xA5, msg_size);
 #endif
-	err = mhu_receive_data(message_buf, &message_size);
+
+	err = mhu_receive_data((uint8_t *)&io_buf.reply, &reply_size);
 	if (err != MHU_ERR_NONE) {
 		return PSA_ERROR_COMMUNICATION_FAILURE;
 	}
 
-	deserialise_reply(&reply, out_vec, out_len, message_buf, message_size);
+	VERBOSE("[RSS-COMMS] Received reply\n");
+	VERBOSE("protocol_ver=%u\n", io_buf.reply.header.protocol_ver);
+	VERBOSE("seq_num=%u\n", io_buf.reply.header.seq_num);
+	VERBOSE("client_id=%u\n", io_buf.reply.header.client_id);
 
-	seq_num++;
+	status = rss_protocol_deserialize_reply(out_vec, out_len, &return_val,
+						&io_buf.reply, reply_size);
+	if (status != PSA_SUCCESS) {
+		return status;
+	}
 
-	VERBOSE("[RSS-COMMS] Received reply\n");
-	VERBOSE("protocol_ver=%d\n", reply.protocol_ver);
-	VERBOSE("seq_num=%d\n", reply.seq_num);
-	VERBOSE("client_id=%d\n", reply.client_id);
-	VERBOSE("return_val=%d\n", reply.return_val);
-	VERBOSE("out_size[0]=%d\n", reply.out_size[0]);
+	VERBOSE("return_val=%d\n", return_val);
+	for (idx = 0U; idx < out_len; idx++) {
+		VERBOSE("out_vec[%lu].len=%lu\n", idx, out_vec[idx].len);
+		VERBOSE("out_vec[%lu].buf=%p\n", idx, (void *)out_vec[idx].base);
+	}
+
+	/* Clear the MHU message buffer to remove assets from memory */
+	memset(&io_buf, 0x0, sizeof(io_buf));
+
+	seq_num++;
 
-	return reply.return_val;
+	return return_val;
 }
 
 int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base)
diff --git a/drivers/arm/rss/rss_comms.mk b/drivers/arm/rss/rss_comms.mk
new file mode 100644
index 0000000..8f19a0b
--- /dev/null
+++ b/drivers/arm/rss/rss_comms.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RSS_COMMS_SOURCES	:=	$(addprefix drivers/arm/rss/,			\
+					rss_comms.c				\
+					rss_comms_protocol.c			\
+					rss_comms_protocol_embed.c		\
+					rss_comms_protocol_pointer_access.c	\
+				)
+
+RSS_COMMS_SOURCES	+=	$(addprefix drivers/arm/mhu/,			\
+					mhu_v2_x.c				\
+					mhu_wrapper_v2_x.c			\
+				)
+
+PLAT_INCLUDES		+=	-Idrivers/arm/rss		\
+				-Idrivers/arm/mhu
diff --git a/drivers/arm/rss/rss_comms_protocol.c b/drivers/arm/rss/rss_comms_protocol.c
new file mode 100644
index 0000000..a1b1b58
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <assert.h>
+
+#include <common/debug.h>
+#include "rss_comms_protocol.h"
+
+psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
+					int16_t type,
+					const psa_invec *in_vec,
+					uint8_t in_len,
+					const psa_outvec *out_vec,
+					uint8_t out_len,
+					struct serialized_rss_comms_msg_t *msg,
+					size_t *msg_len)
+{
+	psa_status_t status;
+
+	assert(msg != NULL);
+	assert(msg_len != NULL);
+	assert(in_vec != NULL);
+
+	switch (msg->header.protocol_ver) {
+	case RSS_COMMS_PROTOCOL_EMBED:
+		status = rss_protocol_embed_serialize_msg(handle, type, in_vec, in_len, out_vec,
+							  out_len, &msg->msg.embed, msg_len);
+		if (status != PSA_SUCCESS) {
+			return status;
+		}
+		break;
+	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
+		status = rss_protocol_pointer_access_serialize_msg(handle, type, in_vec, in_len,
+								   out_vec, out_len,
+								   &msg->msg.pointer_access,
+								   msg_len);
+		if (status != PSA_SUCCESS) {
+			return status;
+		}
+		break;
+	default:
+		return PSA_ERROR_NOT_SUPPORTED;
+	}
+
+	*msg_len += sizeof(struct serialized_rss_comms_header_t);
+
+	return PSA_SUCCESS;
+}
+
+psa_status_t rss_protocol_deserialize_reply(psa_outvec *out_vec,
+					    uint8_t out_len,
+					    psa_status_t *return_val,
+					    const struct serialized_rss_comms_reply_t *reply,
+					    size_t reply_size)
+{
+	assert(reply != NULL);
+	assert(return_val != NULL);
+
+	switch (reply->header.protocol_ver) {
+	case RSS_COMMS_PROTOCOL_EMBED:
+		return rss_protocol_embed_deserialize_reply(out_vec, out_len, return_val,
+							    &reply->reply.embed, reply_size);
+	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
+		return rss_protocol_pointer_access_deserialize_reply(out_vec, out_len, return_val,
+								     &reply->reply.pointer_access,
+								     reply_size);
+	default:
+		return PSA_ERROR_NOT_SUPPORTED;
+	}
+
+	return PSA_SUCCESS;
+}
diff --git a/drivers/arm/rss/rss_comms_protocol.h b/drivers/arm/rss/rss_comms_protocol.h
new file mode 100644
index 0000000..9a38057
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSS_COMMS_PROTOCOL_H__
+#define __RSS_COMMS_PROTOCOL_H__
+
+#include <cdefs.h>
+#include <stdint.h>
+
+#include <psa/client.h>
+#include "rss_comms_protocol_embed.h"
+#include "rss_comms_protocol_pointer_access.h"
+
+enum rss_comms_protocol_version_t {
+	RSS_COMMS_PROTOCOL_EMBED = 0,
+	RSS_COMMS_PROTOCOL_POINTER_ACCESS = 1,
+};
+
+struct __packed serialized_rss_comms_header_t {
+	uint8_t protocol_ver;
+	uint8_t seq_num;
+	uint16_t client_id;
+};
+
+/* MHU message passed from Host to RSS to deliver a PSA client call */
+struct __packed serialized_rss_comms_msg_t {
+	struct serialized_rss_comms_header_t header;
+	union __packed {
+		struct rss_embed_msg_t embed;
+		struct rss_pointer_access_msg_t pointer_access;
+	} msg;
+};
+
+/* MHU reply message to hold the PSA client reply result returned by RSS */
+struct __packed serialized_rss_comms_reply_t {
+	struct serialized_rss_comms_header_t header;
+	union __packed {
+		struct rss_embed_reply_t embed;
+		struct rss_pointer_access_reply_t pointer_access;
+	} reply;
+};
+
+/* in_len and out_len are uint8_ts, therefore if there are more than 255 iovecs
+ * an error may occur.
+ */
+CASSERT(PSA_MAX_IOVEC <= UINT8_MAX, assert_rss_comms_max_iovec_too_large);
+
+psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
+					int16_t type,
+					const psa_invec *in_vec,
+					uint8_t in_len,
+					const psa_outvec *out_vec,
+					uint8_t out_len,
+					struct serialized_rss_comms_msg_t *msg,
+					size_t *msg_len);
+
+psa_status_t rss_protocol_deserialize_reply(psa_outvec *out_vec,
+					    uint8_t out_len,
+					    psa_status_t *return_val,
+					    const struct serialized_rss_comms_reply_t *reply,
+					    size_t reply_size);
+
+#endif /* __RSS_COMMS_PROTOCOL_H__ */
diff --git a/drivers/arm/rss/rss_comms_protocol_embed.c b/drivers/arm/rss/rss_comms_protocol_embed.c
new file mode 100644
index 0000000..801b7cc
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol_embed.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include "rss_comms_protocol_embed.h"
+
+#define TYPE_OFFSET	(16U)
+#define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
+#define IN_LEN_OFFSET	(8U)
+#define IN_LEN_MASK	(0xFFUL << IN_LEN_OFFSET)
+#define OUT_LEN_OFFSET	(0U)
+#define OUT_LEN_MASK	(0xFFUL << OUT_LEN_OFFSET)
+
+#define PARAM_PACK(type, in_len, out_len)			  \
+	(((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK)	| \
+	 ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK)	| \
+	 ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
+
+psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
+					      int16_t type,
+					      const psa_invec *in_vec,
+					      uint8_t in_len,
+					      const psa_outvec *out_vec,
+					      uint8_t out_len,
+					      struct rss_embed_msg_t *msg,
+					      size_t *msg_len)
+{
+	uint32_t payload_size = 0;
+	uint32_t i;
+
+	assert(msg != NULL);
+	assert(msg_len != NULL);
+	assert(in_vec != NULL);
+
+	msg->ctrl_param = PARAM_PACK(type, in_len, out_len);
+	msg->handle = handle;
+
+	/* Fill msg iovec lengths */
+	for (i = 0U; i < in_len; ++i) {
+		msg->io_size[i] = in_vec[i].len;
+	}
+	for (i = 0U; i < out_len; ++i) {
+		msg->io_size[in_len + i] = out_vec[i].len;
+	}
+
+	for (i = 0U; i < in_len; ++i) {
+		if (in_vec[i].len > sizeof(msg->trailer) - payload_size) {
+			return PSA_ERROR_INVALID_ARGUMENT;
+		}
+		memcpy(msg->trailer + payload_size, in_vec[i].base, in_vec[i].len);
+		payload_size += in_vec[i].len;
+	}
+
+	/* Output the actual size of the message, to optimize sending */
+	*msg_len = sizeof(*msg) - sizeof(msg->trailer) + payload_size;
+
+	return PSA_SUCCESS;
+}
+
+psa_status_t rss_protocol_embed_deserialize_reply(psa_outvec *out_vec,
+						  uint8_t out_len,
+						  psa_status_t *return_val,
+						  const struct rss_embed_reply_t *reply,
+						  size_t reply_size)
+{
+	uint32_t payload_offset = 0;
+	uint32_t i;
+
+	assert(reply != NULL);
+	assert(return_val != NULL);
+
+	for (i = 0U; i < out_len; ++i) {
+		if (sizeof(reply) - sizeof(reply->trailer) + payload_offset > reply_size) {
+			return PSA_ERROR_INVALID_ARGUMENT;
+		}
+
+		memcpy(out_vec[i].base, reply->trailer + payload_offset, out_vec[i].len);
+		payload_offset += out_vec[i].len;
+	}
+
+	*return_val = reply->return_val;
+
+	return PSA_SUCCESS;
+}
diff --git a/drivers/arm/rss/rss_comms_protocol_embed.h b/drivers/arm/rss/rss_comms_protocol_embed.h
new file mode 100644
index 0000000..c81c795
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol_embed.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSS_COMMS_PROTOCOL_EMBED_H__
+#define __RSS_COMMS_PROTOCOL_EMBED_H__
+
+#include <cdefs.h>
+
+#include <psa/client.h>
+
+#include <platform_def.h>
+
+
+
+struct __packed rss_embed_msg_t {
+	psa_handle_t handle;
+	uint32_t ctrl_param; /* type, in_len, out_len */
+	uint16_t io_size[PSA_MAX_IOVEC];
+	uint8_t trailer[PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE];
+};
+
+struct __packed rss_embed_reply_t {
+	int32_t return_val;
+	uint16_t out_size[PSA_MAX_IOVEC];
+	uint8_t trailer[PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE];
+};
+
+psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
+					      int16_t type,
+					      const psa_invec *in_vec,
+					      uint8_t in_len,
+					      const psa_outvec *out_vec,
+					      uint8_t out_len,
+					      struct rss_embed_msg_t *msg,
+					      size_t *msg_len);
+
+psa_status_t rss_protocol_embed_deserialize_reply(psa_outvec *out_vec,
+						  uint8_t out_len,
+						  psa_status_t *return_val,
+						  const struct rss_embed_reply_t *reply,
+						  size_t reply_size);
+
+#endif /* __RSS_COMMS_PROTOCOL_EMBED_H__ */
diff --git a/drivers/arm/rss/rss_comms_protocol_pointer_access.c b/drivers/arm/rss/rss_comms_protocol_pointer_access.c
new file mode 100644
index 0000000..5007b9d
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol_pointer_access.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <assert.h>
+
+#include "rss_comms_protocol_pointer_access.h"
+
+#define TYPE_OFFSET	(16U)
+#define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
+#define IN_LEN_OFFSET	(8U)
+#define IN_LEN_MASK	(0xFFUL << IN_LEN_OFFSET)
+#define OUT_LEN_OFFSET	(0U)
+#define OUT_LEN_MASK	(0xFFUL << OUT_LEN_OFFSET)
+
+#define PARAM_PACK(type, in_len, out_len)			  \
+	(((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK)	| \
+	 ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK)	| \
+	 ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
+
+psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
+						       int16_t type,
+						       const psa_invec *in_vec,
+						       uint8_t in_len,
+						       const psa_outvec *out_vec,
+						       uint8_t out_len,
+						       struct rss_pointer_access_msg_t *msg,
+						       size_t *msg_len)
+{
+	unsigned int i;
+
+	assert(msg != NULL);
+	assert(msg_len != NULL);
+	assert(in_vec != NULL);
+
+	msg->ctrl_param = PARAM_PACK(type, in_len, out_len);
+	msg->handle = handle;
+
+	/* Fill msg iovec lengths */
+	for (i = 0U; i < in_len; ++i) {
+		msg->io_sizes[i] = in_vec[i].len;
+		msg->host_ptrs[i] = (uint64_t)in_vec[i].base;
+	}
+	for (i = 0U; i < out_len; ++i) {
+		msg->io_sizes[in_len + i] = out_vec[i].len;
+		msg->host_ptrs[in_len + i] = (uint64_t)out_vec[i].base;
+	}
+
+	*msg_len = sizeof(*msg);
+
+	return PSA_SUCCESS;
+}
+
+psa_status_t rss_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
+							   uint8_t out_len,
+							   psa_status_t *return_val,
+							   const struct rss_pointer_access_reply_t *reply,
+							   size_t reply_size)
+{
+	unsigned int i;
+
+	assert(reply != NULL);
+	assert(return_val != NULL);
+
+	for (i = 0U; i < out_len; ++i) {
+		out_vec[i].len = reply->out_sizes[i];
+	}
+
+	*return_val = reply->return_val;
+
+	return PSA_SUCCESS;
+}
diff --git a/drivers/arm/rss/rss_comms_protocol_pointer_access.h b/drivers/arm/rss/rss_comms_protocol_pointer_access.h
new file mode 100644
index 0000000..a4d054b
--- /dev/null
+++ b/drivers/arm/rss/rss_comms_protocol_pointer_access.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__
+#define __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__
+
+#include <cdefs.h>
+
+#include <psa/client.h>
+
+struct __packed rss_pointer_access_msg_t {
+	psa_handle_t handle;
+	uint32_t ctrl_param;
+	uint32_t io_sizes[PSA_MAX_IOVEC];
+	uint64_t host_ptrs[PSA_MAX_IOVEC];
+};
+
+struct __packed rss_pointer_access_reply_t {
+	int32_t return_val;
+	uint32_t out_sizes[PSA_MAX_IOVEC];
+};
+
+psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
+						       int16_t type,
+						       const psa_invec *in_vec,
+						       uint8_t in_len,
+						       const psa_outvec *out_vec,
+						       uint8_t out_len,
+						       struct rss_pointer_access_msg_t *msg,
+						       size_t *msg_len);
+
+psa_status_t rss_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
+							   uint8_t out_len,
+							   psa_status_t *return_val,
+							   const struct rss_pointer_access_reply_t *reply,
+							   size_t reply_size);
+
+#endif /* __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__ */
diff --git a/drivers/auth/crypto_mod.c b/drivers/auth/crypto_mod.c
index eada357..fa1adb4 100644
--- a/drivers/auth/crypto_mod.c
+++ b/drivers/auth/crypto_mod.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
  */
@@ -46,19 +46,26 @@
 {
 	assert(crypto_lib_desc.name != NULL);
 	assert(crypto_lib_desc.init != NULL);
-#if TRUSTED_BOARD_BOOT
+#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 	assert(crypto_lib_desc.verify_signature != NULL);
 	assert(crypto_lib_desc.verify_hash != NULL);
-#endif /* TRUSTED_BOARD_BOOT */
-#if MEASURED_BOOT
+#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
+
+#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 	assert(crypto_lib_desc.calc_hash != NULL);
-#endif /* MEASURED_BOOT */
+#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
 	/* Initialize the cryptographic library */
 	crypto_lib_desc.init();
 	INFO("Using crypto library '%s'\n", crypto_lib_desc.name);
 }
 
+#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 /*
  * Function to verify a digital signature
  *
@@ -108,8 +115,11 @@
 	return crypto_lib_desc.verify_hash(data_ptr, data_len,
 					   digest_info_ptr, digest_info_len);
 }
+#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
-#if MEASURED_BOOT
+#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 /*
  * Calculate a hash
  *
@@ -129,7 +139,8 @@
 
 	return crypto_lib_desc.calc_hash(alg, data_ptr, data_len, output);
 }
-#endif	/* MEASURED_BOOT */
+#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
 /*
  * Authenticated decryption of data
diff --git a/drivers/auth/cryptocell/713/cryptocell_crypto.c b/drivers/auth/cryptocell/713/cryptocell_crypto.c
index 077317e..3ac16af 100644
--- a/drivers/auth/cryptocell/713/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/713/cryptocell_crypto.c
@@ -8,6 +8,8 @@
 #include <stddef.h>
 #include <string.h>
 
+#include <platform_def.h>
+
 #include <drivers/arm/cryptocell/713/bsv_api.h>
 #include <drivers/arm/cryptocell/713/bsv_crypto_asym_api.h>
 #include <drivers/auth/crypto_mod.h>
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index 0901d04..d231179 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -24,7 +24,8 @@
 
 #define LIB_NAME		"mbed TLS"
 
-#if MEASURED_BOOT
+#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 /*
  * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available
  * so make sure that mbed TLS MD maximum size must be lesser than this.
@@ -32,7 +33,8 @@
 CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE,
 	assert_mbedtls_md_size_overflow);
 
-#endif /* MEASURED_BOOT */
+#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
 /*
  * AlgorithmIdentifier  ::=  SEQUENCE  {
@@ -60,7 +62,8 @@
 	mbedtls_init();
 }
 
-#if TRUSTED_BOARD_BOOT
+#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 /*
  * Verify a signature.
  *
@@ -219,9 +222,11 @@
 
 	return CRYPTO_SUCCESS;
 }
-#endif /* TRUSTED_BOARD_BOOT */
+#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
-#if MEASURED_BOOT
+#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 /*
  * Map a generic crypto message digest algorithm to the corresponding macro used
  * by Mbed TLS.
@@ -264,7 +269,8 @@
 	 */
 	return mbedtls_md(md_info, data_ptr, data_len, output);
 }
-#endif /* MEASURED_BOOT */
+#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
 #if TF_MBEDTLS_USE_AES_GCM
 /*
@@ -368,7 +374,7 @@
 /*
  * Register crypto library descriptor
  */
-#if MEASURED_BOOT && TRUSTED_BOARD_BOOT
+#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 #if TF_MBEDTLS_USE_AES_GCM
 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
 		    auth_decrypt);
@@ -376,13 +382,13 @@
 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
 		    NULL);
 #endif
-#elif TRUSTED_BOARD_BOOT
+#elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
 #if TF_MBEDTLS_USE_AES_GCM
 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash,
 		    auth_decrypt);
 #else
 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
 #endif
-#elif MEASURED_BOOT
+#elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
 REGISTER_CRYPTO_LIB(LIB_NAME, init, calc_hash);
-#endif /* MEASURED_BOOT && TRUSTED_BOARD_BOOT */
+#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index 08b8e9f..e3fb749 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.c
@@ -5,6 +5,8 @@
  */
 
 #include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
 
 #include <drivers/console.h>
 
@@ -95,10 +97,17 @@
 			if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
 				err = ret;
 		}
-
 	return err;
 }
 
+int putchar(int c)
+{
+	if (console_putc(c) == 0)
+		return c;
+	else
+		return EOF;
+}
+
 int console_getc(void)
 {
 	int err = ERROR_NO_VALID_CONSOLE;
diff --git a/drivers/measured_boot/event_log/event_log.c b/drivers/measured_boot/event_log/event_log.c
index abe469b..d661c35 100644
--- a/drivers/measured_boot/event_log/event_log.c
+++ b/drivers/measured_boot/event_log/event_log.c
@@ -84,23 +84,26 @@
  * Record a measurement as a TCG_PCR_EVENT2 event
  *
  * @param[in] hash		Pointer to hash data of TCG_DIGEST_SIZE bytes
+ * @param[in] event_type	Type of Event, Various Event Types are
+ * 				mentioned in tcg.h header
  * @param[in] metadata_ptr	Pointer to event_log_metadata_t structure
  *
  * There must be room for storing this new event into the event log buffer.
  */
-static void event_log_record(const uint8_t *hash,
-			     const event_log_metadata_t *metadata_ptr)
+void event_log_record(const uint8_t *hash, uint32_t event_type,
+		      const event_log_metadata_t *metadata_ptr)
 {
 	void *ptr = log_ptr;
-	uint32_t name_len;
+	uint32_t name_len = 0U;
 
 	assert(hash != NULL);
 	assert(metadata_ptr != NULL);
-	assert(metadata_ptr->name != NULL);
-	/* event_log_init() must have been called prior to this. */
+	/* event_log_buf_init() must have been called prior to this. */
 	assert(log_ptr != NULL);
 
-	name_len = (uint32_t)strlen(metadata_ptr->name) + 1U;
+	if (metadata_ptr->name != NULL) {
+		name_len = (uint32_t)strlen(metadata_ptr->name) + 1U;
+	}
 
 	/* Check for space in Event Log buffer */
 	assert(((uintptr_t)ptr + (uint32_t)EVENT2_HDR_SIZE + name_len) <
@@ -115,7 +118,7 @@
 	((event2_header_t *)ptr)->pcr_index = metadata_ptr->pcr;
 
 	/* TCG_PCR_EVENT2.EventType */
-	((event2_header_t *)ptr)->event_type = EV_POST_CODE;
+	((event2_header_t *)ptr)->event_type = event_type;
 
 	/* TCG_PCR_EVENT2.Digests.Count */
 	ptr = (uint8_t *)ptr + offsetof(event2_header_t, digests);
@@ -139,14 +142,25 @@
 	((event2_data_t *)ptr)->event_size = name_len;
 
 	/* Copy event data to TCG_PCR_EVENT2.Event */
-	(void)memcpy((void *)(((event2_data_t *)ptr)->event),
-			(const void *)metadata_ptr->name, name_len);
+	if (metadata_ptr->name != NULL) {
+		(void)memcpy((void *)(((event2_data_t *)ptr)->event),
+				(const void *)metadata_ptr->name, name_len);
+	}
 
 	/* End of event data */
 	log_ptr = (uint8_t *)((uintptr_t)ptr +
 			offsetof(event2_data_t, event) + name_len);
 }
 
+void event_log_buf_init(uint8_t *event_log_start, uint8_t *event_log_finish)
+{
+	assert(event_log_start != NULL);
+	assert(event_log_finish > event_log_start);
+
+	log_ptr = event_log_start;
+	log_end = (uintptr_t)event_log_finish;
+}
+
 /*
  * Initialise Event Log global variables, used during the recording
  * of various payload measurements into the Event Log buffer
@@ -158,30 +172,20 @@
  */
 void event_log_init(uint8_t *event_log_start, uint8_t *event_log_finish)
 {
-	assert(event_log_start != NULL);
-	assert(event_log_finish > event_log_start);
-
-	log_ptr = event_log_start;
-	log_end = (uintptr_t)event_log_finish;
+	event_log_buf_init(event_log_start, event_log_finish);
 
 	/* Get pointer to platform's event_log_metadata_t structure */
 	plat_metadata_ptr = plat_event_log_get_metadata();
 	assert(plat_metadata_ptr != NULL);
 }
 
-/*
- * Initialises Event Log by writing Specification ID and
- * Startup Locality events
- */
-void event_log_write_header(void)
+void event_log_write_specid_event(void)
 {
-	const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE;
 	void *ptr = log_ptr;
 
-	/* event_log_init() must have been called prior to this. */
+	/* event_log_buf_init() must have been called prior to this. */
 	assert(log_ptr != NULL);
-	assert(((uintptr_t)log_ptr + ID_EVENT_SIZE + LOC_EVENT_SIZE) <
-		log_end);
+	assert(((uintptr_t)log_ptr + ID_EVENT_SIZE) < log_end);
 
 	/*
 	 * Add Specification ID Event first
@@ -202,8 +206,23 @@
 	 * No vendor data
 	 */
 	((id_event_struct_data_t *)ptr)->vendor_info_size = 0;
-	ptr = (uint8_t *)((uintptr_t)ptr +
+	log_ptr = (uint8_t *)((uintptr_t)ptr +
 			offsetof(id_event_struct_data_t, vendor_info));
+}
+
+/*
+ * Initialises Event Log by writing Specification ID and
+ * Startup Locality events
+ */
+void event_log_write_header(void)
+{
+	const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE;
+	void *ptr;
+
+	event_log_write_specid_event();
+
+	ptr = log_ptr;
+	assert(((uintptr_t)log_ptr + LOC_EVENT_SIZE) < log_end);
 
 	/*
 	 * The Startup Locality event should be placed in the log before
@@ -242,6 +261,14 @@
 	log_ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t));
 }
 
+int event_log_measure(uintptr_t data_base, uint32_t data_size,
+		      unsigned char hash_data[CRYPTO_MD_MAX_SIZE])
+{
+	/* Calculate hash */
+	return crypto_mod_calc_hash(CRYPTO_MD_ID,
+				    (void *)data_base, data_size, hash_data);
+}
+
 /*
  * Calculate and write hash of image, configuration data, etc.
  * to Event Log.
@@ -267,14 +294,13 @@
 	}
 	assert(metadata_ptr->id != EVLOG_INVALID_ID);
 
-	/* Calculate hash */
-	rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
-				  (void *)data_base, data_size, hash_data);
+	/* Measure the payload with algorithm selected by EventLog driver */
+	rc = event_log_measure(data_base, data_size, hash_data);
 	if (rc != 0) {
 		return rc;
 	}
 
-	event_log_record(hash_data, metadata_ptr);
+	event_log_record(hash_data, EV_POST_CODE, metadata_ptr);
 
 	return 0;
 }
diff --git a/drivers/measured_boot/rss/rss_measured_boot.c b/drivers/measured_boot/rss/rss_measured_boot.c
index fe2baf0..cf545a7 100644
--- a/drivers/measured_boot/rss/rss_measured_boot.c
+++ b/drivers/measured_boot/rss/rss_measured_boot.c
@@ -5,6 +5,7 @@
  */
 #include <assert.h>
 #include <stdint.h>
+#include <string.h>
 
 #include <common/debug.h>
 #include <drivers/auth/crypto_mod.h>
@@ -40,10 +41,21 @@
 	/* At this point it is expected that communication channel over MHU
 	 * is already initialised by platform init.
 	 */
+	struct rss_mboot_metadata *metadata_ptr;
 
 	/* Get pointer to platform's struct rss_mboot_metadata structure */
 	plat_metadata_ptr = plat_rss_mboot_get_metadata();
 	assert(plat_metadata_ptr != NULL);
+
+	/* Use a local variable to preserve the value of the global pointer */
+	metadata_ptr = plat_metadata_ptr;
+
+	/* Init the non-const members of the metadata structure */
+	while (metadata_ptr->id != RSS_MBOOT_INVALID_ID) {
+		metadata_ptr->sw_type_size =
+			strlen((const char *)&metadata_ptr->sw_type) + 1;
+		metadata_ptr++;
+	}
 }
 
 int rss_mboot_measure_and_record(uintptr_t data_base, uint32_t data_size,
diff --git a/drivers/rpi3/gpio/rpi3_gpio.c b/drivers/rpi3/gpio/rpi3_gpio.c
index f938f56..55a8832 100644
--- a/drivers/rpi3/gpio/rpi3_gpio.c
+++ b/drivers/rpi3/gpio/rpi3_gpio.c
@@ -10,6 +10,7 @@
 #include <lib/mmio.h>
 #include <drivers/delay_timer.h>
 #include <drivers/rpi3/gpio/rpi3_gpio.h>
+#include <platform_def.h>
 
 static uintptr_t reg_base;
 
diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c
index 80c2f41..01d1420 100644
--- a/drivers/st/clk/stm32mp_clkfunc.c
+++ b/drivers/st/clk/stm32mp_clkfunc.c
@@ -17,7 +17,6 @@
 
 #include <platform_def.h>
 
-#define DT_UART_COMPAT		"st,stm32h7-uart"
 /*
  * Get the frequency of an oscillator from its name in device tree.
  * @param name: oscillator name
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index e467f09..e3e0e67 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -46,10 +46,16 @@
 	cmp	r0, #0
 	beq	core_init_fail
 #if !defined(IMAGE_BL2)
+#if STM32MP_RECONFIGURE_CONSOLE
+	/* UART clock rate is set to 0 in BL32, skip init in that case */
+	cmp	r1, #0
+	beq	1f
+#else /* STM32MP_RECONFIGURE_CONSOLE */
 	/* Skip UART initialization if it is already enabled */
 	ldr	r3, [r0, #USART_CR1]
 	ands	r3, r3, #USART_CR1_UE
 	bne	1f
+#endif /* STM32MP_RECONFIGURE_CONSOLE */
 #endif /* IMAGE_BL2 */
 	/* Check baud rate and uart clock for sanity */
 	cmp	r1, #0
diff --git a/drivers/st/uart/stm32_uart.c b/drivers/st/uart/stm32_uart.c
index e2e5405..63970c7 100644
--- a/drivers/st/uart/stm32_uart.c
+++ b/drivers/st/uart/stm32_uart.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
  */
@@ -9,7 +9,9 @@
 #include <string.h>
 
 #include <common/bl_common.h>
+#include <drivers/clk.h>
 #include <drivers/delay_timer.h>
+#include <drivers/st/stm32_gpio.h>
 #include <drivers/st/stm32_uart.h>
 #include <drivers/st/stm32_uart_regs.h>
 #include <drivers/st/stm32mp_clkfunc.h>
@@ -106,7 +108,33 @@
 {
 	uint32_t tmpreg;
 	unsigned long clockfreq;
+	unsigned long int_div;
 	uint32_t brrtemp;
+	uint32_t over_sampling;
+
+	/*---------------------- USART BRR configuration --------------------*/
+	clockfreq = uart_get_clock_freq(huart);
+	if (clockfreq == 0UL) {
+		return -ENODEV;
+	}
+
+	int_div = clockfreq / init->baud_rate;
+	if (int_div < 16U) {
+		uint32_t usartdiv = uart_div_sampling8(clockfreq,
+						       init->baud_rate,
+						       init->prescaler);
+
+		brrtemp = (usartdiv & USART_BRR_DIV_MANTISSA) |
+			  ((usartdiv & USART_BRR_DIV_FRACTION) >> 1);
+		over_sampling = USART_CR1_OVER8;
+	} else {
+		brrtemp = uart_div_sampling16(clockfreq,
+					      init->baud_rate,
+					      init->prescaler) &
+			  (USART_BRR_DIV_FRACTION | USART_BRR_DIV_MANTISSA);
+		over_sampling = 0x0U;
+	}
+	mmio_write_32(huart->base + USART_BRR, brrtemp);
 
 	/*
 	 * ---------------------- USART CR1 Configuration --------------------
@@ -115,12 +143,12 @@
 	 * - set the M bits according to init->word_length value,
 	 * - set PCE and PS bits according to init->parity value,
 	 * - set TE and RE bits according to init->mode value,
-	 * - set OVER8 bit according to init->over_sampling value.
+	 * - set OVER8 bit according baudrate and clock.
 	 */
 	tmpreg = init->word_length |
 		 init->parity |
 		 init->mode |
-		 init->over_sampling |
+		 over_sampling |
 		 init->fifo_mode;
 	mmio_clrsetbits_32(huart->base + USART_CR1, STM32_UART_CR1_FIELDS, tmpreg);
 
@@ -161,27 +189,6 @@
 	mmio_clrsetbits_32(huart->base + USART_PRESC, USART_PRESC_PRESCALER,
 			   init->prescaler);
 
-	/*---------------------- USART BRR configuration --------------------*/
-	clockfreq = uart_get_clock_freq(huart);
-	if (clockfreq == 0UL) {
-		return -ENODEV;
-	}
-
-	if (init->over_sampling == STM32_UART_OVERSAMPLING_8) {
-		uint32_t usartdiv = uart_div_sampling8(clockfreq,
-						       init->baud_rate,
-						       init->prescaler);
-
-		brrtemp = (usartdiv & USART_BRR_DIV_MANTISSA) |
-			  ((usartdiv & USART_BRR_DIV_FRACTION) >> 1);
-	} else {
-		brrtemp = uart_div_sampling16(clockfreq,
-					      init->baud_rate,
-					      init->prescaler) &
-			  (USART_BRR_DIV_FRACTION | USART_BRR_DIV_MANTISSA);
-	}
-	mmio_write_32(huart->base + USART_BRR, brrtemp);
-
 	return 0;
 }
 
@@ -295,12 +302,14 @@
  * @param  init: UART initialization parameter.
  * @retval UART status.
  */
-
 int stm32_uart_init(struct stm32_uart_handle_s *huart,
 		    uintptr_t base_addr,
 		    const struct stm32_uart_init_s *init)
 {
 	int ret;
+	int uart_node;
+	int clk;
+	void *fdt = NULL;
 
 	if (huart == NULL || init == NULL || base_addr == 0U) {
 		return -EINVAL;
@@ -308,6 +317,32 @@
 
 	huart->base = base_addr;
 
+	/* Search UART instance in DT */
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if (fdt == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	uart_node = dt_match_instance_by_compatible(DT_UART_COMPAT, base_addr);
+	if (uart_node == -FDT_ERR_NOTFOUND) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	/* Pinctrl initialization */
+	if (dt_set_pinctrl_config(uart_node) != 0) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	/* Clock initialization */
+	clk = fdt_get_clock_id(uart_node);
+	if (clk < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+	clk_enable(clk);
+
 	/* Disable the peripheral */
 	stm32_uart_stop(huart->base);
 
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 754d173..d8c0a14 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -477,6 +477,7 @@
 {
 	utrd_header_t *hd;
 	resp_upiu_t *resp;
+	sense_data_t *sense;
 	unsigned int data;
 	int slot;
 
@@ -499,6 +500,15 @@
 	inv_dcache_range((uintptr_t)hd, UFS_DESC_SIZE);
 	assert(hd->ocs == OCS_SUCCESS);
 	assert((resp->trans_type & TRANS_TYPE_CODE_MASK) == trans_type);
+
+	sense = &resp->sd.sense;
+	if (sense->resp_code == SENSE_DATA_VALID &&
+	    sense->sense_key == SENSE_KEY_UNIT_ATTENTION && sense->asc == 0x29 &&
+	    sense->ascq == 0) {
+		WARN("Unit Attention Condition\n");
+		return -EAGAIN;
+	}
+
 	(void)resp;
 	(void)slot;
 	return 0;
@@ -507,14 +517,18 @@
 static void ufs_send_cmd(utp_utrd_t *utrd, uint8_t cmd_op, uint8_t lun, int lba, uintptr_t buf,
 			 size_t length)
 {
-	int result;
-
-	get_utrd(utrd);
+	int result, i;
 
-	result = ufs_prepare_cmd(utrd, cmd_op, lun, lba, buf, length);
-	assert(result == 0);
-	ufs_send_request(utrd->task_tag);
-	result = ufs_check_resp(utrd, RESPONSE_UPIU);
+	for (i = 0; i < UFS_CMD_RETRIES; ++i) {
+		get_utrd(utrd);
+		result = ufs_prepare_cmd(utrd, cmd_op, lun, lba, buf, length);
+		assert(result == 0);
+		ufs_send_request(utrd->task_tag);
+		result = ufs_check_resp(utrd, RESPONSE_UPIU);
+		if (result == 0 || result == -EIO) {
+			break;
+		}
+	}
 	assert(result == 0);
 	(void)result;
 }
diff --git a/fdts/fvp-base-gicv2-psci-aarch32.dts b/fdts/fvp-base-gicv2-psci-aarch32.dts
deleted file mode 100644
index 3a921f4..0000000
--- a/fdts/fvp-base-gicv2-psci-aarch32.dts
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/* Configuration: max 4 clusters with up to 4 CPUs */
-
-/dts-v1/;
-
-#define	AFF
-#define	REG_32
-
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include "fvp-defs.dtsi"
-
-/memreserve/ 0x80000000 0x00010000;
-
-/ {
-};
-
-/ {
-	model = "FVP Base";
-	compatible = "arm,vfp-base", "arm,vexpress";
-	interrupt-parent = <&gic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-	chosen { };
-
-	aliases {
-		serial0 = &v2m_serial0;
-		serial1 = &v2m_serial1;
-		serial2 = &v2m_serial2;
-		serial3 = &v2m_serial3;
-	};
-
-	psci {
-		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
-		method = "smc";
-		cpu_suspend = <0x84000001>;
-		cpu_off = <0x84000002>;
-		cpu_on = <0x84000003>;
-		sys_poweroff = <0x84000008>;
-		sys_reset = <0x84000009>;
-		max-pwr-lvl = <2>;
-	};
-
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		CPU_MAP
-
-		idle-states {
-			entry-method = "arm,psci";
-
-			CPU_SLEEP_0: cpu-sleep-0 {
-				compatible = "arm,idle-state";
-				local-timer-stop;
-				arm,psci-suspend-param = <0x0010000>;
-				entry-latency-us = <40>;
-				exit-latency-us = <100>;
-				min-residency-us = <150>;
-			};
-
-			CLUSTER_SLEEP_0: cluster-sleep-0 {
-				compatible = "arm,idle-state";
-				local-timer-stop;
-				arm,psci-suspend-param = <0x1010000>;
-				entry-latency-us = <500>;
-				exit-latency-us = <1000>;
-				min-residency-us = <2500>;
-			};
-		};
-
-		CPUS
-
-		L2_0: l2-cache0 {
-			compatible = "cache";
-		};
-	};
-
-	memory@80000000 {
-		device_type = "memory";
-		reg = <0x00000000 0x80000000 0 0x7F000000>,
-		      <0x00000008 0x80000000 0 0x80000000>;
-	};
-
-	gic: interrupt-controller@2f000000 {
-		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
-		#interrupt-cells = <3>;
-		#address-cells = <0>;
-		interrupt-controller;
-		reg = <0x0 0x2f000000 0 0x10000>,
-		      <0x0 0x2c000000 0 0x2000>,
-		      <0x0 0x2c010000 0 0x2000>,
-		      <0x0 0x2c02F000 0 0x2000>;
-		interrupts = <1 9 0xf04>;
-	};
-
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupts = <GIC_PPI 13
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
-		clock-frequency = <100000000>;
-	};
-
-	timer@2a810000 {
-			compatible = "arm,armv7-timer-mem";
-			reg = <0x0 0x2a810000 0x0 0x10000>;
-			clock-frequency = <100000000>;
-			#address-cells = <2>;
-			#size-cells = <2>;
-			ranges;
-			frame@2a830000 {
-				frame-number = <1>;
-				interrupts = <0 26 4>;
-				reg = <0x0 0x2a830000 0x0 0x10000>;
-			};
-	};
-
-	pmu {
-		compatible = "arm,armv8-pmuv3";
-		interrupts = <0 60 4>,
-			     <0 61 4>,
-			     <0 62 4>,
-			     <0 63 4>;
-	};
-
-	smb {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
-
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 63>;
-		interrupt-map = <0 0  0 &gic 0  0 4>,
-				<0 0  1 &gic 0  1 4>,
-				<0 0  2 &gic 0  2 4>,
-				<0 0  3 &gic 0  3 4>,
-				<0 0  4 &gic 0  4 4>,
-				<0 0  5 &gic 0  5 4>,
-				<0 0  6 &gic 0  6 4>,
-				<0 0  7 &gic 0  7 4>,
-				<0 0  8 &gic 0  8 4>,
-				<0 0  9 &gic 0  9 4>,
-				<0 0 10 &gic 0 10 4>,
-				<0 0 11 &gic 0 11 4>,
-				<0 0 12 &gic 0 12 4>,
-				<0 0 13 &gic 0 13 4>,
-				<0 0 14 &gic 0 14 4>,
-				<0 0 15 &gic 0 15 4>,
-				<0 0 16 &gic 0 16 4>,
-				<0 0 17 &gic 0 17 4>,
-				<0 0 18 &gic 0 18 4>,
-				<0 0 19 &gic 0 19 4>,
-				<0 0 20 &gic 0 20 4>,
-				<0 0 21 &gic 0 21 4>,
-				<0 0 22 &gic 0 22 4>,
-				<0 0 23 &gic 0 23 4>,
-				<0 0 24 &gic 0 24 4>,
-				<0 0 25 &gic 0 25 4>,
-				<0 0 26 &gic 0 26 4>,
-				<0 0 27 &gic 0 27 4>,
-				<0 0 28 &gic 0 28 4>,
-				<0 0 29 &gic 0 29 4>,
-				<0 0 30 &gic 0 30 4>,
-				<0 0 31 &gic 0 31 4>,
-				<0 0 32 &gic 0 32 4>,
-				<0 0 33 &gic 0 33 4>,
-				<0 0 34 &gic 0 34 4>,
-				<0 0 35 &gic 0 35 4>,
-				<0 0 36 &gic 0 36 4>,
-				<0 0 37 &gic 0 37 4>,
-				<0 0 38 &gic 0 38 4>,
-				<0 0 39 &gic 0 39 4>,
-				<0 0 40 &gic 0 40 4>,
-				<0 0 41 &gic 0 41 4>,
-				<0 0 42 &gic 0 42 4>;
-
-		#include "rtsm_ve-motherboard-aarch32.dtsi"
-	};
-
-	panels {
-		panel@0 {
-			compatible	= "panel";
-			mode		= "XVGA";
-			refresh		= <60>;
-			xres		= <1024>;
-			yres		= <768>;
-			pixclock	= <15748>;
-			left_margin	= <152>;
-			right_margin	= <48>;
-			upper_margin	= <23>;
-			lower_margin	= <3>;
-			hsync_len	= <104>;
-			vsync_len	= <4>;
-			sync		= <0>;
-			vmode		= "FB_VMODE_NONINTERLACED";
-			tim2		= "TIM2_BCD", "TIM2_IPC";
-			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
-			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
-			bpp		= <16>;
-		};
-	};
-};
diff --git a/fdts/fvp-base-gicv2-psci.dts b/fdts/fvp-base-gicv2-psci.dts
index e99719e..0361bdc 100644
--- a/fdts/fvp-base-gicv2-psci.dts
+++ b/fdts/fvp-base-gicv2-psci.dts
@@ -6,168 +6,13 @@
 
 /* Configuration: max 4 clusters with up to 4 CPUs */
 
-/dts-v1/;
-
 #define	AFF
 
-#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include "fvp-defs.dtsi"
 
-/memreserve/ 0x80000000 0x00010000;
-
-/ {
-};
-
-/ {
-	model = "FVP Base";
-	compatible = "arm,vfp-base", "arm,vexpress";
-	interrupt-parent = <&gic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-	chosen { };
-
-	aliases {
-		serial0 = &v2m_serial0;
-		serial1 = &v2m_serial1;
-		serial2 = &v2m_serial2;
-		serial3 = &v2m_serial3;
-	};
-
-	psci {
-		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
-		method = "smc";
-		cpu_suspend = <0xc4000001>;
-		cpu_off = <0x84000002>;
-		cpu_on = <0xc4000003>;
-		sys_poweroff = <0x84000008>;
-		sys_reset = <0x84000009>;
-		max-pwr-lvl = <2>;
-	};
-
-	cpus {
-		#address-cells = <2>;
-		#size-cells = <0>;
-
-		CPU_MAP
-
-		idle-states {
-			entry-method = "arm,psci";
-
-			CPU_SLEEP_0: cpu-sleep-0 {
-				compatible = "arm,idle-state";
-				local-timer-stop;
-				arm,psci-suspend-param = <0x0010000>;
-				entry-latency-us = <40>;
-				exit-latency-us = <100>;
-				min-residency-us = <150>;
-			};
-
-			CLUSTER_SLEEP_0: cluster-sleep-0 {
-				compatible = "arm,idle-state";
-				local-timer-stop;
-				arm,psci-suspend-param = <0x1010000>;
-				entry-latency-us = <500>;
-				exit-latency-us = <1000>;
-				min-residency-us = <2500>;
-			};
-		};
-
-		CPUS
-
-		L2_0: l2-cache0 {
-			compatible = "cache";
-		};
-	};
-
-	memory@80000000 {
-		device_type = "memory";
-		reg = <0x00000000 0x80000000 0 0x7F000000>,
-		      <0x00000008 0x80000000 0 0x80000000>;
-	};
-
-	gic: interrupt-controller@2f000000 {
-		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
-		#interrupt-cells = <3>;
-		#address-cells = <0>;
-		interrupt-controller;
-		reg = <0x0 0x2f000000 0 0x10000>,
-		      <0x0 0x2c000000 0 0x2000>,
-		      <0x0 0x2c010000 0 0x2000>,
-		      <0x0 0x2c02F000 0 0x2000>;
-		interrupts = <1 9 0xf04>;
-	};
-
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupts = <GIC_PPI 13
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
-		clock-frequency = <100000000>;
-	};
-
-	timer@2a810000 {
-			compatible = "arm,armv7-timer-mem";
-			reg = <0x0 0x2a810000 0x0 0x10000>;
-			clock-frequency = <100000000>;
-			#address-cells = <2>;
-			#size-cells = <2>;
-			ranges;
-			frame@2a830000 {
-				frame-number = <1>;
-				interrupts = <0 26 4>;
-				reg = <0x0 0x2a830000 0x0 0x10000>;
-			};
-	};
-
-	pmu {
-		compatible = "arm,armv8-pmuv3";
-		interrupts = <0 60 4>,
-			     <0 61 4>,
-			     <0 62 4>,
-			     <0 63 4>;
-	};
-
-	smb {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
+/dts-v1/;
 
-		#include "rtsm_ve-motherboard.dtsi"
-	};
+/memreserve/ 0x80000000 0x00010000;
 
-	panels {
-		panel@0 {
-			compatible	= "panel";
-			mode		= "XVGA";
-			refresh		= <60>;
-			xres		= <1024>;
-			yres		= <768>;
-			pixclock	= <15748>;
-			left_margin	= <152>;
-			right_margin	= <48>;
-			upper_margin	= <23>;
-			lower_margin	= <3>;
-			hsync_len	= <104>;
-			vsync_len	= <4>;
-			sync		= <0>;
-			vmode		= "FB_VMODE_NONINTERLACED";
-			tim2		= "TIM2_BCD", "TIM2_IPC";
-			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
-			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
-			bpp		= <16>;
-		};
-	};
-};
+#include "fvp-base-gicv2.dtsi"
+#include "fvp-base-psci-common.dtsi"
diff --git a/fdts/fvp-base-gicv2.dtsi b/fdts/fvp-base-gicv2.dtsi
new file mode 100644
index 0000000..8d84208
--- /dev/null
+++ b/fdts/fvp-base-gicv2.dtsi
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* GICv2 configuration, without V2M */
+
+/ {
+	gic: interrupt-controller@2f000000 {
+		compatible = "arm,cortex-a15-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <1>;
+		interrupt-controller;
+		reg = <0x0 0x2f000000 0 0x10000>,
+		      <0x0 0x2c000000 0 0x2000>,
+		      <0x0 0x2c010000 0 0x2000>,
+		      <0x0 0x2c02F000 0 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+};
diff --git a/fdts/fvp-base-gicv3-psci-1t.dts b/fdts/fvp-base-gicv3-psci-1t.dts
index c5e0424..829555b 100644
--- a/fdts/fvp-base-gicv3-psci-1t.dts
+++ b/fdts/fvp-base-gicv3-psci-1t.dts
@@ -6,9 +6,13 @@
 
 /* Configuration: max 4 clusters with up to 4 CPUs with 1 thread per each */
 
-/dts-v1/;
-
 #define	AFF	00
 
 #include "fvp-defs.dtsi"
-#include "fvp-base-gicv3-psci-common.dtsi"
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+#include "fvp-base-gicv3.dtsi"
+#include "fvp-base-psci-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci-aarch32-1t.dts b/fdts/fvp-base-gicv3-psci-aarch32-1t.dts
deleted file mode 100644
index a31c703..0000000
--- a/fdts/fvp-base-gicv3-psci-aarch32-1t.dts
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/* Configuration: max 4 clusters with up to 4 CPUs with 1 thread per each */
-
-/dts-v1/;
-
-#define	AFF	00
-#define	REG_32
-
-#include "fvp-defs.dtsi"
-#include "fvp-base-gicv3-psci-aarch32-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi
deleted file mode 100644
index 85988e9..0000000
--- a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-
-/memreserve/ 0x80000000 0x00010000;
-
-/ {
-};
-
-/ {
-	model = "FVP Base";
-	compatible = "arm,vfp-base", "arm,vexpress";
-	interrupt-parent = <&gic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-	chosen { };
-
-	aliases {
-		serial0 = &v2m_serial0;
-		serial1 = &v2m_serial1;
-		serial2 = &v2m_serial2;
-		serial3 = &v2m_serial3;
-	};
-
-	psci {
-		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
-		method = "smc";
-		cpu_suspend = <0x84000001>;
-		cpu_off = <0x84000002>;
-		cpu_on = <0x84000003>;
-		sys_poweroff = <0x84000008>;
-		sys_reset = <0x84000009>;
-		max-pwr-lvl = <2>;
-	};
-
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		CPU_MAP
-
-		idle-states {
-			entry-method = "arm,psci";
-
-			CPU_SLEEP_0: cpu-sleep-0 {
-				compatible = "arm,idle-state";
-				local-timer-stop;
-				arm,psci-suspend-param = <0x0010000>;
-				entry-latency-us = <40>;
-				exit-latency-us = <100>;
-				min-residency-us = <150>;
-			};
-
-			CLUSTER_SLEEP_0: cluster-sleep-0 {
-				compatible = "arm,idle-state";
-				local-timer-stop;
-				arm,psci-suspend-param = <0x1010000>;
-				entry-latency-us = <500>;
-				exit-latency-us = <1000>;
-				min-residency-us = <2500>;
-			};
-		};
-
-		CPUS
-
-		L2_0: l2-cache0 {
-			compatible = "cache";
-		};
-	};
-
-	memory@80000000 {
-		device_type = "memory";
-		reg = <0x00000000 0x80000000 0 0x7F000000>,
-		      <0x00000008 0x80000000 0 0x80000000>;
-	};
-
-	gic: interrupt-controller@2f000000 {
-		compatible = "arm,gic-v3";
-		#interrupt-cells = <3>;
-		#address-cells = <2>;
-		#size-cells = <2>;
-		ranges;
-		interrupt-controller;
-		reg = <0x0 0x2f000000 0 0x10000>,	// GICD
-		      <0x0 0x2f100000 0 0x200000>,	// GICR
-		      <0x0 0x2c000000 0 0x2000>,	// GICC
-		      <0x0 0x2c010000 0 0x2000>,	// GICH
-		      <0x0 0x2c02f000 0 0x2000>;	// GICV
-		interrupts = <1 9 4>;
-
-		its: its@2f020000 {
-			compatible = "arm,gic-v3-its";
-			msi-controller;
-			reg = <0x0 0x2f020000 0x0 0x20000>; // GITS
-		};
-	};
-
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupts = <GIC_PPI 13
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
-		clock-frequency = <100000000>;
-	};
-
-	timer@2a810000 {
-			compatible = "arm,armv7-timer-mem";
-			reg = <0x0 0x2a810000 0x0 0x10000>;
-			clock-frequency = <100000000>;
-			#address-cells = <2>;
-			#size-cells = <2>;
-			ranges;
-			frame@2a830000 {
-				frame-number = <1>;
-				interrupts = <0 26 4>;
-				reg = <0x0 0x2a830000 0x0 0x10000>;
-			};
-	};
-
-	pmu {
-		compatible = "arm,armv8-pmuv3";
-		interrupts = <0 60 4>,
-			     <0 61 4>,
-			     <0 62 4>,
-			     <0 63 4>;
-	};
-
-	smb {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
-
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 63>;
-		interrupt-map = <0 0  0 &gic 0 0 0  0 4>,
-				<0 0  1 &gic 0 0 0  1 4>,
-				<0 0  2 &gic 0 0 0  2 4>,
-				<0 0  3 &gic 0 0 0  3 4>,
-				<0 0  4 &gic 0 0 0  4 4>,
-				<0 0  5 &gic 0 0 0  5 4>,
-				<0 0  6 &gic 0 0 0  6 4>,
-				<0 0  7 &gic 0 0 0  7 4>,
-				<0 0  8 &gic 0 0 0  8 4>,
-				<0 0  9 &gic 0 0 0  9 4>,
-				<0 0 10 &gic 0 0 0 10 4>,
-				<0 0 11 &gic 0 0 0 11 4>,
-				<0 0 12 &gic 0 0 0 12 4>,
-				<0 0 13 &gic 0 0 0 13 4>,
-				<0 0 14 &gic 0 0 0 14 4>,
-				<0 0 15 &gic 0 0 0 15 4>,
-				<0 0 16 &gic 0 0 0 16 4>,
-				<0 0 17 &gic 0 0 0 17 4>,
-				<0 0 18 &gic 0 0 0 18 4>,
-				<0 0 19 &gic 0 0 0 19 4>,
-				<0 0 20 &gic 0 0 0 20 4>,
-				<0 0 21 &gic 0 0 0 21 4>,
-				<0 0 22 &gic 0 0 0 22 4>,
-				<0 0 23 &gic 0 0 0 23 4>,
-				<0 0 24 &gic 0 0 0 24 4>,
-				<0 0 25 &gic 0 0 0 25 4>,
-				<0 0 26 &gic 0 0 0 26 4>,
-				<0 0 27 &gic 0 0 0 27 4>,
-				<0 0 28 &gic 0 0 0 28 4>,
-				<0 0 29 &gic 0 0 0 29 4>,
-				<0 0 30 &gic 0 0 0 30 4>,
-				<0 0 31 &gic 0 0 0 31 4>,
-				<0 0 32 &gic 0 0 0 32 4>,
-				<0 0 33 &gic 0 0 0 33 4>,
-				<0 0 34 &gic 0 0 0 34 4>,
-				<0 0 35 &gic 0 0 0 35 4>,
-				<0 0 36 &gic 0 0 0 36 4>,
-				<0 0 37 &gic 0 0 0 37 4>,
-				<0 0 38 &gic 0 0 0 38 4>,
-				<0 0 39 &gic 0 0 0 39 4>,
-				<0 0 40 &gic 0 0 0 40 4>,
-				<0 0 41 &gic 0 0 0 41 4>,
-				<0 0 42 &gic 0 0 0 42 4>;
-
-		#include "rtsm_ve-motherboard-aarch32.dtsi"
-	};
-
-	panels {
-		panel@0 {
-			compatible	= "panel";
-			mode		= "XVGA";
-			refresh		= <60>;
-			xres		= <1024>;
-			yres		= <768>;
-			pixclock	= <15748>;
-			left_margin	= <152>;
-			right_margin	= <48>;
-			upper_margin	= <23>;
-			lower_margin	= <3>;
-			hsync_len	= <104>;
-			vsync_len	= <4>;
-			sync		= <0>;
-			vmode		= "FB_VMODE_NONINTERLACED";
-			tim2		= "TIM2_BCD", "TIM2_IPC";
-			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
-			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
-			bpp		= <16>;
-		};
-	};
-};
diff --git a/fdts/fvp-base-gicv3-psci-aarch32.dts b/fdts/fvp-base-gicv3-psci-aarch32.dts
deleted file mode 100644
index 971b2e4..0000000
--- a/fdts/fvp-base-gicv3-psci-aarch32.dts
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/* Configuration: max 4 clusters with up to 4 CPUs */
-
-/dts-v1/;
-
-#define	REG_32
-#define	AFF
-
-#include "fvp-defs.dtsi"
-#include "fvp-base-gicv3-psci-aarch32-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi
deleted file mode 100644
index 3cb613f..0000000
--- a/fdts/fvp-base-gicv3-psci-common.dtsi
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <services/sdei_flags.h>
-
-#define LEVEL	0
-#define EDGE	2
-#define SDEI_NORMAL	0x70
-#define HIGHEST_SEC	0
-
-/memreserve/ 0x80000000 0x00010000;
-
-/ {
-};
-
-/ {
-	model = "FVP Base";
-	compatible = "arm,vfp-base", "arm,vexpress";
-	interrupt-parent = <&gic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-#if (ENABLE_RME == 1)
-	chosen { bootargs = "mem=1G console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda ip=on";};
-#else
-	chosen {};
-#endif
-
-	aliases {
-		serial0 = &v2m_serial0;
-		serial1 = &v2m_serial1;
-		serial2 = &v2m_serial2;
-		serial3 = &v2m_serial3;
-	};
-
-	psci {
-		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
-		method = "smc";
-		cpu_suspend = <0xc4000001>;
-		cpu_off = <0x84000002>;
-		cpu_on = <0xc4000003>;
-		sys_poweroff = <0x84000008>;
-		sys_reset = <0x84000009>;
-		max-pwr-lvl = <2>;
-	};
-
-#if SDEI_IN_FCONF || SEC_INT_DESC_IN_FCONF
-	firmware {
-#if SDEI_IN_FCONF
-		sdei {
-			compatible = "arm,sdei-1.0";
-			method = "smc";
-			private_event_count = <3>;
-			shared_event_count = <3>;
-			/*
-			 * Each event descriptor has typically 3 fields:
-			 * 1. Event number
-			 * 2. Interrupt number the event is bound to or
-			 *    if event is dynamic, specified as SDEI_DYN_IRQ
-			 * 3. Bit map of event flags
-			 */
-			private_events =	<1000 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
-						<1001 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
-						<1002 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>;
-			shared_events =		<2000 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
-						<2001 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
-						<2002 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>;
-		};
-#endif /* SDEI_IN_FCONF */
-
-#if SEC_INT_DESC_IN_FCONF
-		sec_interrupts {
-			compatible = "arm,secure_interrupt_desc";
-			/* Number of G0 and G1 secure interrupts defined by the platform */
-			g0_intr_cnt = <2>;
-			g1s_intr_cnt = <9>;
-			/*
-			 * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
-			 * terminology. Each interrupt property descriptor has 3 fields:
-			 * 1. Interrupt number
-			 * 2. Interrupt priority
-			 * 3. Type of interrupt (Edge or Level configured)
-			 */
-			g0_intr_desc =	< 8 SDEI_NORMAL EDGE>,
-					<14 HIGHEST_SEC EDGE>;
-
-			g1s_intr_desc =	< 9 HIGHEST_SEC EDGE>,
-					<10 HIGHEST_SEC EDGE>,
-					<11 HIGHEST_SEC EDGE>,
-					<12 HIGHEST_SEC EDGE>,
-					<13 HIGHEST_SEC EDGE>,
-					<15 HIGHEST_SEC EDGE>,
-					<29 HIGHEST_SEC LEVEL>,
-					<56 HIGHEST_SEC LEVEL>,
-					<57 HIGHEST_SEC LEVEL>;
-		};
-#endif /* SEC_INT_DESC_IN_FCONF */
-	};
-#endif /* SDEI_IN_FCONF || SEC_INT_DESC_IN_FCONF */
-
-	cpus {
-		#address-cells = <2>;
-		#size-cells = <0>;
-
-		CPU_MAP
-
-		idle-states {
-			entry-method = "arm,psci";
-
-			CPU_SLEEP_0: cpu-sleep-0 {
-				compatible = "arm,idle-state";
-				local-timer-stop;
-				arm,psci-suspend-param = <0x0010000>;
-				entry-latency-us = <40>;
-				exit-latency-us = <100>;
-				min-residency-us = <150>;
-			};
-
-			CLUSTER_SLEEP_0: cluster-sleep-0 {
-				compatible = "arm,idle-state";
-				local-timer-stop;
-				arm,psci-suspend-param = <0x1010000>;
-				entry-latency-us = <500>;
-				exit-latency-us = <1000>;
-				min-residency-us = <2500>;
-			};
-		};
-
-		CPUS
-
-		L2_0: l2-cache0 {
-			compatible = "cache";
-		};
-	};
-
-	memory@80000000 {
-		device_type = "memory";
-#if (ENABLE_RME == 1)
-		reg = <0x00000000 0x80000000 0 0x7C000000>,
-		      <0x00000008 0x80000000 0 0x80000000>;
-#else
-		reg = <0x00000000 0x80000000 0 0x7F000000>,
-		      <0x00000008 0x80000000 0 0x80000000>;
-#endif
-	};
-
-	gic: interrupt-controller@2f000000 {
-		compatible = "arm,gic-v3";
-		#interrupt-cells = <3>;
-		#address-cells = <2>;
-		#size-cells = <2>;
-		ranges;
-		interrupt-controller;
-		reg = <0x0 0x2f000000 0 0x10000>,	// GICD
-		      <0x0 0x2f100000 0 0x200000>,	// GICR
-		      <0x0 0x2c000000 0 0x2000>,	// GICC
-		      <0x0 0x2c010000 0 0x2000>,	// GICH
-		      <0x0 0x2c02f000 0 0x2000>;	// GICV
-		interrupts = <1 9 4>;
-
-		its: its@2f020000 {
-			compatible = "arm,gic-v3-its";
-			msi-controller;
-			reg = <0x0 0x2f020000 0x0 0x20000>; // GITS
-		};
-	};
-
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupts = <GIC_PPI 13
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10
-				(GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
-		clock-frequency = <100000000>;
-	};
-
-	timer@2a810000 {
-			compatible = "arm,armv7-timer-mem";
-			reg = <0x0 0x2a810000 0x0 0x10000>;
-			clock-frequency = <100000000>;
-			#address-cells = <2>;
-			#size-cells = <2>;
-			ranges;
-			frame@2a830000 {
-				frame-number = <1>;
-				interrupts = <0 26 4>;
-				reg = <0x0 0x2a830000 0x0 0x10000>;
-			};
-	};
-
-	pmu {
-		compatible = "arm,armv8-pmuv3";
-		interrupts = <0 60 4>,
-			     <0 61 4>,
-			     <0 62 4>,
-			     <0 63 4>;
-	};
-
-	smb@0,0 {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
-
-		#include "rtsm_ve-motherboard.dtsi"
-	};
-
-	panels {
-		panel {
-			compatible	= "panel";
-			mode		= "XVGA";
-			refresh		= <60>;
-			xres		= <1024>;
-			yres		= <768>;
-			pixclock	= <15748>;
-			left_margin	= <152>;
-			right_margin	= <48>;
-			upper_margin	= <23>;
-			lower_margin	= <3>;
-			hsync_len	= <104>;
-			vsync_len	= <4>;
-			sync		= <0>;
-			vmode		= "FB_VMODE_NONINTERLACED";
-			tim2		= "TIM2_BCD", "TIM2_IPC";
-			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
-			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
-			bpp		= <16>;
-		};
-	};
-};
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
index bda4b8d..9d5b979 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
+++ b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
@@ -13,6 +13,11 @@
 #define	PE_PER_CPU		2
 #endif
 
+#include "fvp-defs-dynamiq.dtsi"
+
 /dts-v1/;
 
-#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
+/memreserve/ 0x80000000 0x00010000;
+
+#include "fvp-base-gicv3.dtsi"
+#include "fvp-base-psci-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq.dts b/fdts/fvp-base-gicv3-psci-dynamiq.dts
index b693f75..1bf803e 100644
--- a/fdts/fvp-base-gicv3-psci-dynamiq.dts
+++ b/fdts/fvp-base-gicv3-psci-dynamiq.dts
@@ -13,6 +13,11 @@
 #define	PE_PER_CPU		1
 #endif
 
+#include "fvp-defs-dynamiq.dtsi"
+
 /dts-v1/;
 
-#include "fvp-base-gicv3-psci-dynamiq-common.dtsi"
+/memreserve/ 0x80000000 0x00010000;
+
+#include "fvp-base-gicv3.dtsi"
+#include "fvp-base-psci-common.dtsi"
diff --git a/fdts/fvp-base-gicv3-psci.dts b/fdts/fvp-base-gicv3-psci.dts
index eb99472..69db267 100644
--- a/fdts/fvp-base-gicv3-psci.dts
+++ b/fdts/fvp-base-gicv3-psci.dts
@@ -6,9 +6,13 @@
 
 /* Configuration: max 4 clusters with up to 4 CPUs */
 
-/dts-v1/;
-
 #define	AFF
 
 #include "fvp-defs.dtsi"
-#include "fvp-base-gicv3-psci-common.dtsi"
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+#include "fvp-base-gicv3.dtsi"
+#include "fvp-base-psci-common.dtsi"
diff --git a/fdts/fvp-base-gicv3.dtsi b/fdts/fvp-base-gicv3.dtsi
new file mode 100644
index 0000000..fdcfa92
--- /dev/null
+++ b/fdts/fvp-base-gicv3.dtsi
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* GICv3 with ITS configuration  */
+
+/ {
+	gic: interrupt-controller@2f000000 {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x2f000000 0x100000>;
+		interrupt-controller;
+		reg = <0x0 0x2f000000 0 0x10000>,	// GICD
+		      <0x0 0x2f100000 0 0x200000>,	// GICR
+		      <0x0 0x2c000000 0 0x2000>,	// GICC
+		      <0x0 0x2c010000 0 0x2000>,	// GICH
+		      <0x0 0x2c02f000 0 0x2000>;	// GICV
+		interrupts = <1 9 4>;
+
+		its: msi-controller@2f020000 {
+			compatible = "arm,gic-v3-its";
+			msi-controller;
+			#msi-cells = <1>;
+			reg = <0x20000 0x20000>;	// GITS
+		};
+	};
+};
diff --git a/fdts/fvp-base-psci-common.dtsi b/fdts/fvp-base-psci-common.dtsi
new file mode 100644
index 0000000..6018f0c
--- /dev/null
+++ b/fdts/fvp-base-psci-common.dtsi
@@ -0,0 +1,251 @@
+// SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause
+/*
+ * ARM Ltd. Fast Models
+ *
+ * Architecture Envelope Model (AEM) ARMv8-A
+ * ARMAEMv8AMPCT
+ *
+ * RTSM_VE_AEMv8A.lisa
+ *
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <services/sdei_flags.h>
+
+#define LEVEL	0
+#define EDGE	2
+#define SDEI_NORMAL	0x70
+#define HIGHEST_SEC	0
+
+#include "rtsm_ve-motherboard.dtsi"
+
+/ {
+	model = "FVP Base";
+	compatible = "arm,fvp-base", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+#if (ENABLE_RME == 1)
+	chosen { bootargs = "mem=1G console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda ip=on";};
+#else
+	chosen {};
+#endif
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+		max-pwr-lvl = <2>;
+	};
+
+#if SDEI_IN_FCONF || SEC_INT_DESC_IN_FCONF
+	firmware {
+#if SDEI_IN_FCONF
+		sdei {
+			compatible = "arm,sdei-1.0";
+			method = "smc";
+			private_event_count = <3>;
+			shared_event_count = <3>;
+			/*
+			 * Each event descriptor has typically 3 fields:
+			 * 1. Event number
+			 * 2. Interrupt number the event is bound to or
+			 *    if event is dynamic, specified as SDEI_DYN_IRQ
+			 * 3. Bit map of event flags
+			 */
+			private_events =	<1000 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
+						<1001 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
+						<1002 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>;
+			shared_events =		<2000 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
+						<2001 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
+						<2002 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>;
+		};
+#endif /* SDEI_IN_FCONF */
+
+#if SEC_INT_DESC_IN_FCONF
+		sec_interrupts {
+			compatible = "arm,secure_interrupt_desc";
+			/* Number of G0 and G1 secure interrupts defined by the platform */
+			g0_intr_cnt = <2>;
+			g1s_intr_cnt = <9>;
+			/*
+			 * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+			 * terminology. Each interrupt property descriptor has 3 fields:
+			 * 1. Interrupt number
+			 * 2. Interrupt priority
+			 * 3. Type of interrupt (Edge or Level configured)
+			 */
+			g0_intr_desc =	< 8 SDEI_NORMAL EDGE>,
+					<14 HIGHEST_SEC EDGE>;
+
+			g1s_intr_desc =	< 9 HIGHEST_SEC EDGE>,
+					<10 HIGHEST_SEC EDGE>,
+					<11 HIGHEST_SEC EDGE>,
+					<12 HIGHEST_SEC EDGE>,
+					<13 HIGHEST_SEC EDGE>,
+					<15 HIGHEST_SEC EDGE>,
+					<29 HIGHEST_SEC LEVEL>,
+					<56 HIGHEST_SEC LEVEL>,
+					<57 HIGHEST_SEC LEVEL>;
+		};
+#endif /* SEC_INT_DESC_IN_FCONF */
+	};
+#endif /* SDEI_IN_FCONF || SEC_INT_DESC_IN_FCONF */
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		CPU_MAP
+
+		idle-states {
+			entry-method = "psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <40>;
+				exit-latency-us = <100>;
+				min-residency-us = <150>;
+			};
+
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x1010000>;
+				entry-latency-us = <500>;
+				exit-latency-us = <1000>;
+				min-residency-us = <2500>;
+			};
+		};
+
+		CPUS
+
+		L2_0: l2-cache0 {
+			compatible = "cache";
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+#if (ENABLE_RME == 1)
+		reg = <0x00000000 0x80000000 0 0x7C000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+#else
+		reg = <0x00000000 0x80000000 0 0x7F000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+#endif
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* Chipselect 2,00000000 is physically at 0x18000000 */
+		vram: vram@18000000 {
+			/* 8 MB of designated video RAM */
+			compatible = "shared-dma-pool";
+			reg = <0x00000000 0x18000000 0 0x00800000>;
+			no-map;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <100000000>;
+	};
+
+	timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0x0 0x10000>;
+			clock-frequency = <100000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x0 0x2a810000 0x100000>;
+
+			frame@2a830000 {
+				frame-number = <1>;
+				interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x20000 0x10000>;
+			};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	panel {
+		compatible = "arm,rtsm-display";
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&clcd_pads>;
+			};
+		};
+	};
+
+	bus@8000000 {
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0 GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  1 &gic 0 GIC_SPI  1 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  2 &gic 0 GIC_SPI  2 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  3 &gic 0 GIC_SPI  3 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  4 &gic 0 GIC_SPI  4 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  5 &gic 0 GIC_SPI  5 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  6 &gic 0 GIC_SPI  6 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  7 &gic 0 GIC_SPI  7 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  8 &gic 0 GIC_SPI  8 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  9 &gic 0 GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 10 &gic 0 GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 11 &gic 0 GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 12 &gic 0 GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 13 &gic 0 GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 14 &gic 0 GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 15 &gic 0 GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 16 &gic 0 GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 17 &gic 0 GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 18 &gic 0 GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 19 &gic 0 GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 20 &gic 0 GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 21 &gic 0 GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 22 &gic 0 GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 23 &gic 0 GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 24 &gic 0 GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 25 &gic 0 GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 26 &gic 0 GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 27 &gic 0 GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 28 &gic 0 GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 29 &gic 0 GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 30 &gic 0 GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 31 &gic 0 GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 32 &gic 0 GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 33 &gic 0 GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 34 &gic 0 GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 35 &gic 0 GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 36 &gic 0 GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 37 &gic 0 GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 38 &gic 0 GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 39 &gic 0 GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 40 &gic 0 GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 41 &gic 0 GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 42 &gic 0 GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+	};
+};
diff --git a/fdts/fvp-defs.dtsi b/fdts/fvp-defs.dtsi
index 1ffe65a..9fd33ca 100644
--- a/fdts/fvp-defs.dtsi
+++ b/fdts/fvp-defs.dtsi
@@ -43,35 +43,17 @@
 	device_type = "cpu";	\
 	compatible = "arm,armv8";
 
-#ifdef	REG_32
-/* 32-bit address */
-#define	REG(c, p)	\
-	reg = <CONC(0x, CONC(c, CONC(p, AFF)))>;
-#else
-/* 64-bit address */
-#define	REG(c, p)	\
-	reg = <0x0 CONC(0x, CONC(c, CONC(p, AFF)))>;
-#endif	/* REG_32 */
-
 #define	POST				\
 	enable-method = "psci";		\
 	cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;	\
 	next-level-cache = <&L2_0>;	\
 	};
 
-#ifdef	REG_32
-#define	CPU_0		\
-	CPU0:cpu@0 {	\
-	PRE		\
-	reg = <0x0>;	\
-	POST
-#else
 #define	CPU_0		\
 	CPU0:cpu@0 {	\
 	PRE		\
 	reg = <0x0 0x0>;\
 	POST
-#endif	/* REG_32 */
 
 /*
  * n - CPU number
@@ -79,7 +61,7 @@
 #define	CPU(n, c, p)	\
 	ADR(n, c, p)	\
 	PRE		\
-	REG(c, p)	\
+	reg = <0x0 CONC(0x, CONC(c, CONC(p, AFF)))>;	\
 	POST
 
 /* 2 CPUs */
diff --git a/fdts/fvp-ve-Cortex-A5x1.dts b/fdts/fvp-ve-Cortex-A5x1.dts
index 9d2d1d5..612b3b2 100644
--- a/fdts/fvp-ve-Cortex-A5x1.dts
+++ b/fdts/fvp-ve-Cortex-A5x1.dts
@@ -1,16 +1,20 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
 /dts-v1/;
 
+#include "rtsm_ve-motherboard.dtsi"
+
 / {
 	model = "V2P-CA5s";
 	compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress";
 	interrupt-parent = <&gic>;
-	#address-cells = <1>;
+	#address-cells = <2>;
 	#size-cells = <1>;
 
 	cpus {
@@ -27,12 +31,26 @@
 
 	memory@80000000 {
 		device_type = "memory";
-		reg = <0x80000000 0x1000000>;
+		reg = <0 0x80000000 0x1000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		/* Chipselect 2,00000000 is physically at 0x18000000 */
+		vram: vram@18000000 {
+			/* 8 MB of designated video RAM */
+			compatible = "shared-dma-pool";
+			reg = <0 0x18000000 0x00800000>;
+			no-map;
+		};
 	};
 
 	hdlcd@2a110000 {
 		compatible = "arm,hdlcd";
-		reg = <0x2a110000 0x1000>;
+		reg = <0 0x2a110000 0x1000>;
 		interrupts = <0 85 4>;
 		clocks = <&oscclk3>;
 		clock-names = "pxlclk";
@@ -40,12 +58,12 @@
 
 	scu@2c000000 {
 		compatible = "arm,cortex-a5-scu";
-		reg = <0x2c000000 0x58>;
+		reg = <0 0x2c000000 0x58>;
 	};
 
 	watchdog@2c000620 {
 		compatible = "arm,cortex-a5-twd-wdt";
-		reg = <0x2c000620 0x20>;
+		reg = <0 0x2c000620 0x20>;
 		interrupts = <1 14 0x304>;
 	};
 
@@ -54,15 +72,12 @@
 		#interrupt-cells = <3>;
 		#address-cells = <0>;
 		interrupt-controller;
-		reg = <0x2c001000 0x1000>,
-		      <0x2c000100 0x100>;
+		reg = <0 0x2c001000 0x1000>,
+		      <0 0x2c000100 0x100>;
 	};
 
-	dcc {
-		compatible = "arm,vexpress,config-bus";
-		arm,vexpress,config-bridge = <&v2m_sysreg>;
-
-		oscclk0: osc@0 {
+	mcc {
+		oscclk0: oscclk0 {
 			/* CPU and internal AXI reference clock */
 			compatible = "arm,vexpress-osc";
 			arm,vexpress-sysreg,func = <1 0>;
@@ -71,7 +86,7 @@
 			clock-output-names = "oscclk0";
 		};
 
-		oscclk1: osc@1 {
+		oscclk1: oscclk1 {
 			/* Multiplexed AXI master clock */
 			compatible = "arm,vexpress-osc";
 			arm,vexpress-sysreg,func = <1 1>;
@@ -80,7 +95,7 @@
 			clock-output-names = "oscclk1";
 		};
 
-		osc@2 {
+		oscclk2 {
 			/* DDR2 */
 			compatible = "arm,vexpress-osc";
 			arm,vexpress-sysreg,func = <1 2>;
@@ -89,7 +104,7 @@
 			clock-output-names = "oscclk2";
 		};
 
-		oscclk3: osc@3 {
+		oscclk3: oscclk3 {
 			/* HDLCD */
 			compatible = "arm,vexpress-osc";
 			arm,vexpress-sysreg,func = <1 3>;
@@ -98,7 +113,7 @@
 			clock-output-names = "oscclk3";
 		};
 
-		osc@4 {
+		oscclk4 {
 			/* Test chip gate configuration */
 			compatible = "arm,vexpress-osc";
 			arm,vexpress-sysreg,func = <1 4>;
@@ -107,7 +122,7 @@
 			clock-output-names = "oscclk4";
 		};
 
-		smbclk: osc@5 {
+		smbclk: oscclk5 {
 			/* SMB clock */
 			compatible = "arm,vexpress-osc";
 			arm,vexpress-sysreg,func = <1 5>;
@@ -117,28 +132,36 @@
 		};
 	};
 
-	smb {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x04000000>,
-			 <1 0 0x14000000 0x04000000>,
-			 <2 0 0x18000000 0x04000000>,
-			 <3 0 0x1c000000 0x04000000>,
-			 <4 0 0x0c000000 0x04000000>,
-			 <5 0 0x10000000 0x04000000>;
+	panel {
+		compatible = "arm,rtsm-display";
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&clcd_pads>;
+			};
+		};
+	};
 
+	bus@8000000 {
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
-		interrupt-map = <0 0  0 &gic 0  0 4>,
-				<0 0  1 &gic 0  1 4>,
-				<0 0  2 &gic 0  2 4>,
-				<0 0  3 &gic 0  3 4>,
-				<0 0  4 &gic 0  4 4>,
-				<0 0  5 &gic 0  5 4>,
-				<0 0 42 &gic 0 42 4>;
-
-		#include "rtsm_ve-motherboard-aarch32.dtsi"
+		interrupt-map = <0 0  0 &gic GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  1 &gic GIC_SPI  1 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  2 &gic GIC_SPI  2 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  3 &gic GIC_SPI  3 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  4 &gic GIC_SPI  4 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  5 &gic GIC_SPI  5 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  6 &gic GIC_SPI  6 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  7 &gic GIC_SPI  7 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  8 &gic GIC_SPI  8 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  9 &gic GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 10 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 11 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 12 &gic GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 13 &gic GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 15 &gic GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 42 &gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 43 &gic GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 44 &gic GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 46 &gic GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
diff --git a/fdts/fvp-ve-Cortex-A7x1.dts b/fdts/fvp-ve-Cortex-A7x1.dts
index 28de91d..6ec6adb 100644
--- a/fdts/fvp-ve-Cortex-A7x1.dts
+++ b/fdts/fvp-ve-Cortex-A7x1.dts
@@ -1,43 +1,61 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
 /dts-v1/;
 
+#include "rtsm_ve-motherboard.dtsi"
+
 / {
 	model = "V2F-1XV7 Cortex-A7x1 SMM";
 	compatible = "arm,vexpress,v2f-1xv7", "arm,vexpress";
 	interrupt-parent = <&gic>;
 	#address-cells = <2>;
-	#size-cells = <2>;
+	#size-cells = <1>;
 
 	cpus {
-		#address-cells = <2>;
+		#address-cells = <1>;
 		#size-cells = <0>;
 
 		cpu@0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
-			reg = <0 0>;
+			reg = <0>;
 		};
 	};
 
 	memory@0,80000000 {
 		device_type = "memory";
-		reg = <0 0x80000000 0 0x80000000>; /* 2GB @ 2GB */
+		reg = <0 0x80000000 0x80000000>; /* 2GB @ 2GB */
 	};
 
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		/* Chipselect 2,00000000 is physically at 0x18000000 */
+		vram: vram@18000000 {
+			/* 8 MB of designated video RAM */
+			compatible = "shared-dma-pool";
+			reg = <0 0x18000000 0x00800000>;
+			no-map;
+		};
+	};
+
 	gic: interrupt-controller@2c001000 {
 		compatible = "arm,cortex-a15-gic";
 		#interrupt-cells = <3>;
 		#address-cells = <0>;
 		interrupt-controller;
-		reg = <0 0x2c001000 0 0x1000>,
-		      <0 0x2c002000 0 0x1000>,
-		      <0 0x2c004000 0 0x2000>,
-		      <0 0x2c006000 0 0x2000>;
+		reg = <0 0x2c001000 0x1000>,
+		      <0 0x2c002000 0x1000>,
+		      <0 0x2c004000 0x2000>,
+		      <0 0x2c006000 0x2000>;
 		interrupts = <1 9 0xf04>;
 	};
 
@@ -49,28 +67,36 @@
 		clock-output-names = "smclk";
 	};
 
-	smb {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
+	panel {
+		compatible = "arm,rtsm-display";
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&clcd_pads>;
+			};
+		};
+	};
 
+	bus@8000000 {
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
-		interrupt-map = <0 0  0 &gic 0  0 4>,
-				<0 0  1 &gic 0  1 4>,
-				<0 0  2 &gic 0  2 4>,
-				<0 0  3 &gic 0  3 4>,
-				<0 0  4 &gic 0  4 4>,
-				<0 0  5 &gic 0  5 4>,
-				<0 0 42 &gic 0 42 4>;
-
-		#include "rtsm_ve-motherboard-aarch32.dtsi"
+		interrupt-map = <0 0  0 &gic GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  1 &gic GIC_SPI  1 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  2 &gic GIC_SPI  2 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  3 &gic GIC_SPI  3 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  4 &gic GIC_SPI  4 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  5 &gic GIC_SPI  5 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  6 &gic GIC_SPI  6 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  7 &gic GIC_SPI  7 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  8 &gic GIC_SPI  8 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0  9 &gic GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 10 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 11 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 12 &gic GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 13 &gic GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 15 &gic GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 42 &gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 43 &gic GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 44 &gic GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 46 &gic GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
diff --git a/fdts/juno-ethosn.dtsi b/fdts/juno-ethosn.dtsi
index e2f3355..4609524 100644
--- a/fdts/juno-ethosn.dtsi
+++ b/fdts/juno-ethosn.dtsi
@@ -1,12 +1,13 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 /*
- * For examples of multi-core and multi-device NPU, refer to the examples given in the
- * Arm Ethos-N NPU driver stack.
+ * This device tree is only an example and some properties have been omitted.
+ *
+ * Refer to the Arm(R) Ethos(TM)-N driver stack for complete device tree examples.
  * https://github.com/ARM-software/ethos-n-driver-stack
  */
 
@@ -14,14 +15,62 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	ethosn0: ethosn@6f300000 {
-		compatible = "ethosn";
-		reg = <0 0x6f300000 0 0x00100000>;
+	smmu_ethosn0: iommu@6f400000 {
+		compatible = "arm,smmu-v3";
+		reg = <0 0x6f400000 0 0x80000>;
 		status = "okay";
-
-		core0 {
-			compatible = "ethosn-core";
-			status = "okay";
-		};
+		/* msi-parent omitted */
+		#iommu-cells = <0x1>;
 	};
+
+	ethosn0: ethosn@6f300000 {
+		 compatible = "ethosn";
+		 reg = <0 0x6f300000 0 0x00100000>;
+		 status = "okay";
+
+		 core0 {
+			 compatible = "ethosn-core";
+			 status = "okay";
+
+			 main_allocator {
+				 compatible = "ethosn-main_allocator";
+				 status = "okay";
+
+				 firmware {
+					 compatible = "ethosn-memory";
+					 iommus = <&smmu_ethosn0 0>;
+				 };
+
+				 working_data {
+					 compatible = "ethosn-memory";
+					 iommus = <&smmu_ethosn0 1>;
+				 };
+			 };
+		 };
+
+		 asset_allocator {
+			 compatible = "ethosn-asset_allocator";
+			 status = "okay";
+
+			 command_stream {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 2>;
+			 };
+
+			 weight_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 3>;
+			 };
+
+			 buffer_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 4>;
+			 };
+
+			 intermediate_data {
+				 compatible = "ethosn-memory";
+				 iommus = <&smmu_ethosn0 5>;
+			 };
+		 };
+	 };
 };
diff --git a/fdts/rtsm_ve-motherboard-aarch32.dtsi b/fdts/rtsm_ve-motherboard-aarch32.dtsi
deleted file mode 100644
index 7a8af8e..0000000
--- a/fdts/rtsm_ve-motherboard-aarch32.dtsi
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-	motherboard {
-		arm,v2m-memory-map = "rs1";
-		compatible = "arm,vexpress,v2m-p1", "simple-bus";
-		#address-cells = <2>; /* SMB chipselect number and offset */
-		#size-cells = <1>;
-		#interrupt-cells = <1>;
-		ranges;
-
-		flash@0,00000000 {
-			compatible = "arm,vexpress-flash", "cfi-flash";
-			reg = <0 0x00000000 0x04000000>,
-			      <4 0x00000000 0x04000000>;
-			bank-width = <4>;
-		};
-
-		vram@2,00000000 {
-			compatible = "arm,vexpress-vram";
-			reg = <2 0x00000000 0x00800000>;
-		};
-
-		ethernet@2,02000000 {
-			compatible = "smsc,lan91c111";
-			reg = <2 0x02000000 0x10000>;
-			interrupts = <15>;
-		};
-
-		v2m_clk24mhz: clk24mhz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <24000000>;
-			clock-output-names = "v2m:clk24mhz";
-		};
-
-		v2m_refclk1mhz: refclk1mhz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <1000000>;
-			clock-output-names = "v2m:refclk1mhz";
-		};
-
-		v2m_refclk32khz: refclk32khz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <32768>;
-			clock-output-names = "v2m:refclk32khz";
-		};
-
-		iofpga@3,00000000 {
-			compatible = "arm,amba-bus", "simple-bus";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges = <0 3 0 0x200000>;
-
-			v2m_sysreg: sysreg@10000 {
-				compatible = "arm,vexpress-sysreg";
-				reg = <0x010000 0x1000>;
-				gpio-controller;
-				#gpio-cells = <2>;
-			};
-
-			v2m_sysctl: sysctl@20000 {
-				compatible = "arm,sp810", "arm,primecell";
-				reg = <0x020000 0x1000>;
-				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>;
-				clock-names = "refclk", "timclk", "apb_pclk";
-				#clock-cells = <1>;
-				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
-			};
-
-			aaci@40000 {
-				compatible = "arm,pl041", "arm,primecell";
-				reg = <0x040000 0x1000>;
-				interrupts = <11>;
-				clocks = <&v2m_clk24mhz>;
-				clock-names = "apb_pclk";
-			};
-
-			mmci@50000 {
-				compatible = "arm,pl180", "arm,primecell";
-				reg = <0x050000 0x1000>;
-				interrupts = <9 10>;
-				cd-gpios = <&v2m_sysreg 0 0>;
-				wp-gpios = <&v2m_sysreg 1 0>;
-				max-frequency = <12000000>;
-				vmmc-supply = <&v2m_fixed_3v3>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "mclk", "apb_pclk";
-			};
-
-			kmi@60000 {
-				compatible = "arm,pl050", "arm,primecell";
-				reg = <0x060000 0x1000>;
-				interrupts = <12>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "KMIREFCLK", "apb_pclk";
-			};
-
-			kmi@70000 {
-				compatible = "arm,pl050", "arm,primecell";
-				reg = <0x070000 0x1000>;
-				interrupts = <13>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "KMIREFCLK", "apb_pclk";
-			};
-
-			v2m_serial0: uart@90000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x090000 0x1000>;
-				interrupts = <5>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			v2m_serial1: uart@a0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0a0000 0x1000>;
-				interrupts = <6>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			v2m_serial2: uart@b0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0b0000 0x1000>;
-				interrupts = <7>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			v2m_serial3: uart@c0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0c0000 0x1000>;
-				interrupts = <8>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			wdt@f0000 {
-				compatible = "arm,sp805", "arm,primecell";
-				reg = <0x0f0000 0x1000>;
-				interrupts = <0>;
-				clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>;
-				clock-names = "wdogclk", "apb_pclk";
-			};
-
-			v2m_timer01: timer@110000 {
-				compatible = "arm,sp804", "arm,primecell";
-				reg = <0x110000 0x1000>;
-				interrupts = <2>;
-				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>;
-				clock-names = "timclken1", "timclken2", "apb_pclk";
-			};
-
-			v2m_timer23: timer@120000 {
-				compatible = "arm,sp804", "arm,primecell";
-				reg = <0x120000 0x1000>;
-				interrupts = <3>;
-				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>;
-				clock-names = "timclken1", "timclken2", "apb_pclk";
-			};
-
-			rtc@170000 {
-				compatible = "arm,pl031", "arm,primecell";
-				reg = <0x170000 0x1000>;
-				interrupts = <4>;
-				clocks = <&v2m_clk24mhz>;
-				clock-names = "apb_pclk";
-			};
-
-			clcd@1f0000 {
-				compatible = "arm,pl111", "arm,primecell";
-				reg = <0x1f0000 0x1000>;
-				interrupts = <14>;
-				clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
-				clock-names = "clcdclk", "apb_pclk";
-				mode = "XVGA";
-				use_dma = <0>;
-				framebuffer = <0x18000000 0x00180000>;
-			};
-
-			virtio_block@130000 {
-				compatible = "virtio,mmio";
-				reg = <0x130000 0x1000>;
-				interrupts = <0x2a>;
-			};
-		};
-
-		v2m_fixed_3v3: fixedregulator@0 {
-			compatible = "regulator-fixed";
-			regulator-name = "3V3";
-			regulator-min-microvolt = <3300000>;
-			regulator-max-microvolt = <3300000>;
-			regulator-always-on;
-		};
-
-		mcc {
-			compatible = "arm,vexpress,config-bus", "simple-bus";
-			arm,vexpress,config-bridge = <&v2m_sysreg>;
-
-			v2m_oscclk1: osc@1 {
-				/* CLCD clock */
-				compatible = "arm,vexpress-osc";
-				arm,vexpress-sysreg,func = <1 1>;
-				freq-range = <23750000 63500000>;
-				#clock-cells = <0>;
-				clock-output-names = "v2m:oscclk1";
-			};
-
-			/*
-			 * Not supported in FVP models
-			 *
-			 * reset@0 {
-			 * 	compatible = "arm,vexpress-reset";
-			 * 	arm,vexpress-sysreg,func = <5 0>;
-			 * };
-			 */
-
-			muxfpga@0 {
-				compatible = "arm,vexpress-muxfpga";
-				arm,vexpress-sysreg,func = <7 0>;
-			};
-
-			/*
-			 * Not used - Superseded by PSCI sys_poweroff
-			 *
-			 * shutdown@0 {
-			 * 	compatible = "arm,vexpress-shutdown";
-			 * 	arm,vexpress-sysreg,func = <8 0>;
-			 * };
-			 */
-
-			/*
-			 * Not used - Superseded by PSCI sys_reset
-			 *
-			 * reboot@0 {
-			 * 	compatible = "arm,vexpress-reboot";
-			 * 	arm,vexpress-sysreg,func = <9 0>;
-			 * };
-			 */
-
-			dvimode@0 {
-				compatible = "arm,vexpress-dvimode";
-				arm,vexpress-sysreg,func = <11 0>;
-			};
-		};
-	};
diff --git a/fdts/rtsm_ve-motherboard.dtsi b/fdts/rtsm_ve-motherboard.dtsi
index 486f8a9..0a824b3 100644
--- a/fdts/rtsm_ve-motherboard.dtsi
+++ b/fdts/rtsm_ve-motherboard.dtsi
@@ -1,251 +1,260 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * ARM Ltd. Fast Models
  *
- * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2012-2022 ARM Ltd.
+ *
+ * Versatile Express (VE) system model
+ * Motherboard component
+ *
+ * VEMotherBoard.lisa
  */
+/ {
+	v2m_clk24mhz: clk24mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "v2m:clk24mhz";
+	};
 
-	motherboard {
-		arm,v2m-memory-map = "rs1";
-		compatible = "arm,vexpress,v2m-p1", "simple-bus";
-		#address-cells = <2>; /* SMB chipselect number and offset */
-		#size-cells = <1>;
-		ranges;
+	v2m_refclk1mhz: refclk1mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000>;
+		clock-output-names = "v2m:refclk1mhz";
+	};
 
-		flash@0,00000000 {
-			compatible = "arm,vexpress-flash", "cfi-flash";
-			reg = <0 0x00000000 0x04000000>,
-			      <4 0x00000000 0x04000000>;
-			bank-width = <4>;
-		};
+	v2m_refclk32khz: refclk32khz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "v2m:refclk32khz";
+	};
 
-		vram@2,00000000 {
-			compatible = "arm,vexpress-vram";
-			reg = <2 0x00000000 0x00800000>;
-		};
+	v2m_fixed_3v3: v2m-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
 
-		ethernet@2,02000000 {
-			compatible = "smsc,lan91c111";
-			reg = <2 0x02000000 0x10000>;
-			interrupts = <0 15 4>;
-		};
+	mcc {
+		compatible = "arm,vexpress,config-bus";
+		arm,vexpress,config-bridge = <&v2m_sysreg>;
 
-		v2m_clk24mhz: clk24mhz {
-			compatible = "fixed-clock";
+		v2m_oscclk1: oscclk1 {
+			/* CLCD clock */
+			compatible = "arm,vexpress-osc";
+			arm,vexpress-sysreg,func = <1 1>;
+			freq-range = <23750000 63500000>;
 			#clock-cells = <0>;
-			clock-frequency = <24000000>;
-			clock-output-names = "v2m:clk24mhz";
+			clock-output-names = "v2m:oscclk1";
 		};
 
-		v2m_refclk1mhz: refclk1mhz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <1000000>;
-			clock-output-names = "v2m:refclk1mhz";
+		reset {
+			compatible = "arm,vexpress-reset";
+			arm,vexpress-sysreg,func = <5 0>;
 		};
 
-		v2m_refclk32khz: refclk32khz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <32768>;
-			clock-output-names = "v2m:refclk32khz";
+		muxfpga {
+			compatible = "arm,vexpress-muxfpga";
+			arm,vexpress-sysreg,func = <7 0>;
 		};
 
-		iofpga@3,00000000 {
-			compatible = "arm,amba-bus", "simple-bus";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges = <0 3 0 0x200000>;
+		shutdown {
+			compatible = "arm,vexpress-shutdown";
+			arm,vexpress-sysreg,func = <8 0>;
+		};
 
-			v2m_sysreg: sysreg@10000 {
-				compatible = "arm,vexpress-sysreg";
-				reg = <0x010000 0x1000>;
-				gpio-controller;
-				#gpio-cells = <2>;
-			};
+		reboot {
+			compatible = "arm,vexpress-reboot";
+			arm,vexpress-sysreg,func = <9 0>;
+		};
 
-			v2m_sysctl: sysctl@20000 {
-				compatible = "arm,sp810", "arm,primecell";
-				reg = <0x020000 0x1000>;
-				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>;
-				clock-names = "refclk", "timclk", "apb_pclk";
-				#clock-cells = <1>;
-				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
-			};
+		dvimode {
+			compatible = "arm,vexpress-dvimode";
+			arm,vexpress-sysreg,func = <11 0>;
+		};
+	};
 
-			aaci@40000 {
-				compatible = "arm,pl041", "arm,primecell";
-				reg = <0x040000 0x1000>;
-				interrupts = <0 11 4>;
-				clocks = <&v2m_clk24mhz>;
-				clock-names = "apb_pclk";
-			};
+	bus@8000000 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0x8000000 0 0x8000000 0x18000000>;
 
-			mmci@50000 {
-				compatible = "arm,pl180", "arm,primecell";
-				reg = <0x050000 0x1000>;
-				interrupts = <0 9 4 0 10 4>;
-				cd-gpios = <&v2m_sysreg 0 0>;
-				wp-gpios = <&v2m_sysreg 1 0>;
-				max-frequency = <12000000>;
-				vmmc-supply = <&v2m_fixed_3v3>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "mclk", "apb_pclk";
-			};
+		motherboard-bus@8000000 {
+			compatible = "arm,vexpress,v2m-p1", "simple-bus";
+			#address-cells = <2>; /* SMB chipselect number and offset */
+			#size-cells = <1>;
+			ranges = <0 0 0 0x08000000 0x04000000>,
+				 <1 0 0 0x14000000 0x04000000>,
+				 <2 0 0 0x18000000 0x04000000>,
+				 <3 0 0 0x1c000000 0x04000000>,
+				 <4 0 0 0x0c000000 0x04000000>,
+				 <5 0 0 0x10000000 0x04000000>;
 
-			kmi@60000 {
-				compatible = "arm,pl050", "arm,primecell";
-				reg = <0x060000 0x1000>;
-				interrupts = <0 12 4>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "KMIREFCLK", "apb_pclk";
+			flash@0 {
+				compatible = "arm,vexpress-flash", "cfi-flash";
+				reg = <0 0x00000000 0x04000000>,
+				      <4 0x00000000 0x04000000>;
+				bank-width = <4>;
 			};
 
-			kmi@70000 {
-				compatible = "arm,pl050", "arm,primecell";
-				reg = <0x070000 0x1000>;
-				interrupts = <0 13 4>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "KMIREFCLK", "apb_pclk";
+			ethernet@202000000 {
+				compatible = "smsc,lan91c111";
+				reg = <2 0x02000000 0x10000>;
+				interrupts = <15>;
 			};
 
-			v2m_serial0: uart@90000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x090000 0x1000>;
-				interrupts = <0 5 4>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
+			iofpga-bus@300000000 {
+				compatible = "simple-bus";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 3 0 0x210000>;
 
-			v2m_serial1: uart@a0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0a0000 0x1000>;
-				interrupts = <0 6 4>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
+				v2m_sysreg: sysreg@10000 {
+					compatible = "arm,vexpress-sysreg";
+					reg = <0x010000 0x1000>;
+					gpio-controller;
+					#gpio-cells = <2>;
+				};
 
-			v2m_serial2: uart@b0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0b0000 0x1000>;
-				interrupts = <0 7 4>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
+				v2m_sysctl: sysctl@20000 {
+					compatible = "arm,sp810", "arm,primecell";
+					reg = <0x020000 0x1000>;
+					clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>;
+					clock-names = "refclk", "timclk", "apb_pclk";
+					#clock-cells = <1>;
+					clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+					assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>;
+					assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>;
+				};
 
-			v2m_serial3: uart@c0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0c0000 0x1000>;
-				interrupts = <0 8 4>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
+				aaci@40000 {
+					compatible = "arm,pl041", "arm,primecell";
+					reg = <0x040000 0x1000>;
+					interrupts = <11>;
+					clocks = <&v2m_clk24mhz>;
+					clock-names = "apb_pclk";
+				};
 
-			wdt@f0000 {
-				compatible = "arm,sp805", "arm,primecell";
-				reg = <0x0f0000 0x1000>;
-				interrupts = <0 0 4>;
-				clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>;
-				clock-names = "wdogclk", "apb_pclk";
-			};
+				mmc@50000 {
+					compatible = "arm,pl180", "arm,primecell";
+					reg = <0x050000 0x1000>;
+					interrupts = <9>, <10>;
+					cd-gpios = <&v2m_sysreg 0 0>;
+					wp-gpios = <&v2m_sysreg 1 0>;
+					max-frequency = <12000000>;
+					vmmc-supply = <&v2m_fixed_3v3>;
+					clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+					clock-names = "mclk", "apb_pclk";
+				};
 
-			v2m_timer01: timer@110000 {
-				compatible = "arm,sp804", "arm,primecell";
-				reg = <0x110000 0x1000>;
-				interrupts = <0 2 4>;
-				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>;
-				clock-names = "timclken1", "timclken2", "apb_pclk";
-			};
+				kmi@60000 {
+					compatible = "arm,pl050", "arm,primecell";
+					reg = <0x060000 0x1000>;
+					interrupts = <12>;
+					clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+					clock-names = "KMIREFCLK", "apb_pclk";
+				};
 
-			v2m_timer23: timer@120000 {
-				compatible = "arm,sp804", "arm,primecell";
-				reg = <0x120000 0x1000>;
-				interrupts = <0 3 4>;
-				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>;
-				clock-names = "timclken1", "timclken2", "apb_pclk";
-			};
+				kmi@70000 {
+					compatible = "arm,pl050", "arm,primecell";
+					reg = <0x070000 0x1000>;
+					interrupts = <13>;
+					clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+					clock-names = "KMIREFCLK", "apb_pclk";
+				};
 
-			rtc@170000 {
-				compatible = "arm,pl031", "arm,primecell";
-				reg = <0x170000 0x1000>;
-				interrupts = <0 4 4>;
-				clocks = <&v2m_clk24mhz>;
-				clock-names = "apb_pclk";
-			};
+				v2m_serial0: serial@90000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x090000 0x1000>;
+					interrupts = <5>;
+					clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+					clock-names = "uartclk", "apb_pclk";
+				};
 
-			clcd@1f0000 {
-				compatible = "arm,pl111", "arm,primecell";
-				reg = <0x1f0000 0x1000>;
-				interrupts = <0 14 4>;
-				clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
-				clock-names = "clcdclk", "apb_pclk";
-				mode = "XVGA";
-				use_dma = <0>;
-				framebuffer = <0x18000000 0x00180000>;
-			};
+				v2m_serial1: serial@a0000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x0a0000 0x1000>;
+					interrupts = <6>;
+					clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+					clock-names = "uartclk", "apb_pclk";
+				};
 
-			virtio_block@130000 {
-				compatible = "virtio,mmio";
-				reg = <0x130000 0x1000>;
-				interrupts = <0 0x2a 4>;
-			};
-		};
+				v2m_serial2: serial@b0000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x0b0000 0x1000>;
+					interrupts = <7>;
+					clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+					clock-names = "uartclk", "apb_pclk";
+				};
 
-		v2m_fixed_3v3: fixedregulator {
-			compatible = "regulator-fixed";
-			regulator-name = "3V3";
-			regulator-min-microvolt = <3300000>;
-			regulator-max-microvolt = <3300000>;
-			regulator-always-on;
-		};
+				v2m_serial3: serial@c0000 {
+					compatible = "arm,pl011", "arm,primecell";
+					reg = <0x0c0000 0x1000>;
+					interrupts = <8>;
+					clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
+					clock-names = "uartclk", "apb_pclk";
+				};
 
-		mcc {
-			compatible = "arm,vexpress,config-bus", "simple-bus";
-			arm,vexpress,config-bridge = <&v2m_sysreg>;
+				watchdog@f0000 {
+					compatible = "arm,sp805", "arm,primecell";
+					reg = <0x0f0000 0x1000>;
+					interrupts = <0>;
+					clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>;
+					clock-names = "wdog_clk", "apb_pclk";
+				};
 
-			v2m_oscclk1: osc {
-				/* CLCD clock */
-				compatible = "arm,vexpress-osc";
-				arm,vexpress-sysreg,func = <1 1>;
-				freq-range = <23750000 63500000>;
-				#clock-cells = <0>;
-				clock-output-names = "v2m:oscclk1";
-			};
+				v2m_timer01: timer@110000 {
+					compatible = "arm,sp804", "arm,primecell";
+					reg = <0x110000 0x1000>;
+					interrupts = <2>;
+					clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>;
+					clock-names = "timclken1", "timclken2", "apb_pclk";
+				};
 
-			/*
-			 * Not supported in FVP models
-			 *
-			 * reset@0 {
-			 * 	compatible = "arm,vexpress-reset";
-			 * 	arm,vexpress-sysreg,func = <5 0>;
-			 * };
-			 */
+				v2m_timer23: timer@120000 {
+					compatible = "arm,sp804", "arm,primecell";
+					reg = <0x120000 0x1000>;
+					interrupts = <3>;
+					clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>;
+					clock-names = "timclken1", "timclken2", "apb_pclk";
+				};
 
-			muxfpga {
-				compatible = "arm,vexpress-muxfpga";
-				arm,vexpress-sysreg,func = <7 0>;
-			};
+				virtio@130000 {
+					compatible = "virtio,mmio";
+					reg = <0x130000 0x200>;
+					interrupts = <42>;
+				};
 
-			/*
-			 * Not used - Superseded by PSCI sys_poweroff
-			 *
-			 * shutdown@0 {
-			 * 	compatible = "arm,vexpress-shutdown";
-			 * 	arm,vexpress-sysreg,func = <8 0>;
-			 * };
-			 */
+				rtc@170000 {
+					compatible = "arm,pl031", "arm,primecell";
+					reg = <0x170000 0x1000>;
+					interrupts = <4>;
+					clocks = <&v2m_clk24mhz>;
+					clock-names = "apb_pclk";
+				};
 
-			/*
-			 * Not used - Superseded by PSCI sys_reset
-			 *
-			 * reboot@0 {
-			 * 	compatible = "arm,vexpress-reboot";
-			 * 	arm,vexpress-sysreg,func = <9 0>;
-			 * };
-			 */
+				clcd@1f0000 {
+					compatible = "arm,pl111", "arm,primecell";
+					reg = <0x1f0000 0x1000>;
+					interrupt-names = "combined";
+					interrupts = <14>;
+					clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
+					clock-names = "clcdclk", "apb_pclk";
+					memory-region = <&vram>;
 
-			dvimode {
-				compatible = "arm,vexpress-dvimode";
-				arm,vexpress-sysreg,func = <11 0>;
+					port {
+						clcd_pads: endpoint {
+							remote-endpoint = <&panel_in>;
+							arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+						};
+					};
+				};
 			};
 		};
 	};
+};
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
index e58be40..aa1dd01 100644
--- a/fdts/stm32mp135f-dk.dts
+++ b/fdts/stm32mp135f-dk.dts
@@ -228,13 +228,13 @@
 			frac = < 0x1400 >;
 		};
 
-		pll3_vco_417_8Mhz: pll2-vco-417_8Mhz {
+		pll3_vco_417_8Mhz: pll3-vco-417_8Mhz {
 			src = < CLK_PLL3_HSE >;
 			divmn = < 1 33 >;
 			frac = < 0x1a04 >;
 		};
 
-		pll4_vco_600Mhz: pll2-vco-600Mhz {
+		pll4_vco_600Mhz: pll4-vco-600Mhz {
 			src = < CLK_PLL4_HSE >;
 			divmn = < 1 49 >;
 		};
diff --git a/fdts/tc.dts b/fdts/tc.dts
index 2099229..5a8792e 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -336,6 +336,15 @@
 		status = "okay";
 	};
 
+	rtc0: rtc@1C170000 {
+		compatible = "arm,pl031", "arm,primecell";
+		reg = <0x0 0x1C170000 0x0 0x1000>;
+		interrupts = <0x0 100 0x4>;
+		clocks = <&soc_refclk100mhz>;
+		clock-names = "apb_pclk";
+		wakeup-source;
+	};
+
 	vencoder {
 		compatible = "drm,virtual-encoder";
 
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index bdff25b..8678bf3 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -617,6 +617,12 @@
 #define ICC_ASGI1R_EL1_64	p15, 1, c12
 #define ICC_SGI0R_EL1_64	p15, 2, c12
 
+/* Fault registers. The format is: coproc, opt1, CRn, CRm, opt2 */
+#define DFSR		p15, 0, c5, c0, 0
+#define IFSR		p15, 0, c5, c0, 1
+#define DFAR		p15, 0, c6, c0, 0
+#define IFAR		p15, 0, c6, c0, 2
+
 /*******************************************************************************
  * Definitions of MAIR encodings for device and normal memory
  ******************************************************************************/
diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h
index 0330989..95d056f 100644
--- a/include/arch/aarch32/arch_helpers.h
+++ b/include/arch/aarch32/arch_helpers.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -282,6 +283,7 @@
 DEFINE_COPROCR_RW_FUNCS(icc_eoir1_el1, ICC_EOIR1)
 DEFINE_COPROCR_RW_FUNCS_64(icc_sgi0r_el1, ICC_SGI0R_EL1_64)
 DEFINE_COPROCR_WRITE_FUNC_64(icc_sgi1r, ICC_SGI1R_EL1_64)
+DEFINE_COPROCR_WRITE_FUNC_64(icc_asgi1r, ICC_ASGI1R_EL1_64)
 
 DEFINE_COPROCR_RW_FUNCS(sdcr, SDCR)
 DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR)
@@ -402,6 +404,8 @@
 #define read_ctr_el0()		read_ctr()
 
 #define write_icc_sgi0r_el1(_v)	write64_icc_sgi0r_el1(_v)
+#define write_icc_sgi1r(_v)	write64_icc_sgi1r(_v)
+#define write_icc_asgi1r(_v)	write64_icc_asgi1r(_v)
 
 #define read_daif()		read_cpsr()
 #define write_daif(flags)	write_cpsr(flags)
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 3a2a032..f63e923 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -79,6 +79,7 @@
  ******************************************************************************/
 #define ICC_IGRPEN1_EL1		S3_0_C12_C12_7
 #define ICC_SGI1R		S3_0_C12_C11_5
+#define ICC_ASGI1R		S3_0_C12_C11_6
 #define ICC_SRE_EL1		S3_0_C12_C12_5
 #define ICC_SRE_EL2		S3_4_C12_C9_5
 #define ICC_SRE_EL3		S3_6_C12_C12_5
@@ -261,6 +262,15 @@
 #define ID_AA64ISAR1_SB_SUPPORTED	ULL(0x1)
 #define ID_AA64ISAR1_SB_NOT_SUPPORTED	ULL(0x0)
 
+/* ID_AA64ISAR2_EL1 definitions */
+#define ID_AA64ISAR2_EL1		S3_0_C0_C6_2
+
+#define ID_AA64ISAR2_GPA3_SHIFT		U(8)
+#define ID_AA64ISAR2_GPA3_MASK		ULL(0xf)
+
+#define ID_AA64ISAR2_APA3_SHIFT		U(12)
+#define ID_AA64ISAR2_APA3_MASK		ULL(0xf)
+
 /* ID_AA64MMFR0_EL1 definitions */
 #define ID_AA64MMFR0_EL1_PARANGE_SHIFT	U(0)
 #define ID_AA64MMFR0_EL1_PARANGE_MASK	ULL(0xf)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 0af5b74..932e885 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -35,15 +35,30 @@
 		ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
 }
 
+static inline bool is_feat_pacqarma3_present(void)
+{
+	uint64_t mask_id_aa64isar2 =
+			(ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
+			(ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
+
+	/* If any of the fields is not zero, QARMA3 algorithm is present */
+	return (read_id_aa64isar2_el1() & mask_id_aa64isar2) != 0U;
+}
+
 static inline bool is_armv8_3_pauth_present(void)
 {
-	uint64_t mask = (ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
-			(ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT) |
-			(ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
-			(ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
+	uint64_t mask_id_aa64isar1 =
+		(ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
+		(ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT) |
+		(ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
+		(ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
 
-	/* If any of the fields is not zero, PAuth is present */
-	return (read_id_aa64isar1_el1() & mask) != 0U;
+	/*
+	 * If any of the fields is not zero or QARMA3 is present,
+	 * PAuth is present
+	 */
+	return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) != 0U ||
+		is_feat_pacqarma3_present());
 }
 
 static inline bool is_armv8_4_dit_present(void)
@@ -85,7 +100,7 @@
 static inline bool is_armv8_6_fgt_present(void)
 {
 	return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) &
-		ID_AA64MMFR0_EL1_FGT_MASK) == ID_AA64MMFR0_EL1_FGT_SUPPORTED;
+		ID_AA64MMFR0_EL1_FGT_MASK) != 0U;
 }
 
 static inline unsigned long int get_armv8_6_ecv_support(void)
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 10b0a0b..50a5ad4 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -250,6 +250,7 @@
 DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64isar0_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
+DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64isar2_el1, ID_AA64ISAR2_EL1)
 DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64pfr1_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)
@@ -266,6 +267,8 @@
 DEFINE_SYSREG_RW_FUNCS(mdccsr_el0)
 DEFINE_SYSREG_RW_FUNCS(dbgdtrrx_el0)
 DEFINE_SYSREG_RW_FUNCS(dbgdtrtx_el0)
+DEFINE_SYSREG_RW_FUNCS(sp_el1)
+DEFINE_SYSREG_RW_FUNCS(sp_el2)
 
 DEFINE_SYSOP_FUNC(wfi)
 DEFINE_SYSOP_FUNC(wfe)
@@ -492,6 +495,7 @@
 DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1)
 DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sgi1r, ICC_SGI1R)
+DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r, ICC_ASGI1R)
 
 DEFINE_RENAME_SYSREG_READ_FUNC(amcfgr_el0, AMCFGR_EL0)
 DEFINE_RENAME_SYSREG_READ_FUNC(amcgcr_el0, AMCGCR_EL0)
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index 7706cd8..66c39e5 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -215,6 +215,19 @@
 	.endm
 
 	/*
+	 * Macro for using speculation barrier instruction introduced by
+	 * FEAT_SB, if it's enabled.
+	 */
+	.macro speculation_barrier
+#if ENABLE_FEAT_SB
+	sb
+#else
+	dsb	sy
+	isb
+#endif
+	.endm
+
+	/*
 	 * Macro for mitigating against speculative execution beyond ERET. Uses the
 	 * speculation barrier instruction introduced by FEAT_SB, if it's enabled.
 	 */
diff --git a/include/bl31/interrupt_mgmt.h b/include/bl31/interrupt_mgmt.h
index 694f1f0..21af112 100644
--- a/include/bl31/interrupt_mgmt.h
+++ b/include/bl31/interrupt_mgmt.h
@@ -107,7 +107,7 @@
 
 static inline int32_t validate_el3_interrupt_rm(uint32_t x)
 {
-#if defined (EL3_EXCEPTION_HANDLING) && !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1))
+#if EL3_EXCEPTION_HANDLING && !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1))
 	/*
 	 * With EL3 exception handling, EL3 interrupts are always routed to EL3
 	 * from both Secure and Non-secure, when the SPMC does not live in S-EL2.
diff --git a/include/bl32/pnc/pnc.h b/include/bl32/pnc/pnc.h
new file mode 100644
index 0000000..03a3214
--- /dev/null
+++ b/include/bl32/pnc/pnc.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PNC_H__
+#define __PNC_H__
+
+#define SMC_YIELD		0xbf000000
+#define SMC_ACTION_FROM_S	0xbf000001
+#define SMC_GET_SHAREDMEM	0xbf000002
+#define SMC_CONFIG_SHAREDMEM	0xbf000003
+#define SMC_ACTION_FROM_NS	0xbf000004
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+void *pncd_context_switch_to(unsigned long security_state);
+int plat_pncd_setup(void);
+uintptr_t plat_pncd_smc_handler(uint32_t smc_fid, u_register_t x1,
+				u_register_t x2, u_register_t x3,
+				u_register_t x4, void *cookie, void *handle,
+				u_register_t flags);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PNC_H__ */
diff --git a/include/bl32/sp_min/platform_sp_min.h b/include/bl32/sp_min/platform_sp_min.h
index 971f661..a7dffff 100644
--- a/include/bl32/sp_min/platform_sp_min.h
+++ b/include/bl32/sp_min/platform_sp_min.h
@@ -9,6 +9,8 @@
 
 #include <stdint.h>
 
+#include <common/bl_common.h>
+
 /*******************************************************************************
  * Mandatory SP_MIN functions
  ******************************************************************************/
diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h
index 9310733..dbaf16c 100644
--- a/include/drivers/arm/ethosn.h
+++ b/include/drivers/arm/ethosn.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
  */
@@ -38,7 +38,7 @@
 #define is_ethosn_fid(_fid) (((_fid) & ETHOSN_FID_MASK) == ETHOSN_FID_VALUE)
 
 /* Service version  */
-#define ETHOSN_VERSION_MAJOR U(1)
+#define ETHOSN_VERSION_MAJOR U(2)
 #define ETHOSN_VERSION_MINOR U(0)
 
 /* Return codes for function calls */
@@ -48,10 +48,11 @@
 /* -3 Reserved for INVALID_PARAMETER */
 #define ETHOSN_FAILURE			-4
 #define ETHOSN_UNKNOWN_CORE_ADDRESS	-5
+#define ETHOSN_UNKNOWN_ALLOCATOR_IDX	-6
 
 uintptr_t ethosn_smc_handler(uint32_t smc_fid,
 			     u_register_t core_addr,
-			     u_register_t x2,
+			     u_register_t asset_alloc_idx,
 			     u_register_t x3,
 			     u_register_t x4,
 			     void *cookie,
diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h
index b960194..cfc168d 100644
--- a/include/drivers/arm/gicv2.h
+++ b/include/drivers/arm/gicv2.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -50,13 +51,15 @@
 #define SGIR_TGTLSTFLT_MASK	U(0x3)
 #define SGIR_TGTLST_SHIFT	16
 #define SGIR_TGTLST_MASK	U(0xff)
+#define SGIR_NSATT		(U(0x1) << 16)
 #define SGIR_INTID_MASK		ULL(0xf)
 
 #define SGIR_TGT_SPECIFIC	U(0)
 
-#define GICV2_SGIR_VALUE(tgt_lst_flt, tgt, intid) \
+#define GICV2_SGIR_VALUE(tgt_lst_flt, tgt, nsatt, intid) \
 	((((tgt_lst_flt) & SGIR_TGTLSTFLT_MASK) << SGIR_TGTLSTFLT_SHIFT) | \
 	 (((tgt) & SGIR_TGTLST_MASK) << SGIR_TGTLST_SHIFT) | \
+	 ((nsatt) ? SGIR_NSATT : U(0)) | \
 	 ((intid) & SGIR_INTID_MASK))
 
 /*******************************************************************************
@@ -127,6 +130,7 @@
 #ifndef __ASSEMBLER__
 
 #include <cdefs.h>
+#include <stdbool.h>
 #include <stdint.h>
 
 #include <common/interrupt_props.h>
@@ -185,7 +189,7 @@
 void gicv2_disable_interrupt(unsigned int id);
 void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority);
 void gicv2_set_interrupt_type(unsigned int id, unsigned int type);
-void gicv2_raise_sgi(int sgi_num, int proc_num);
+void gicv2_raise_sgi(int sgi_num, bool ns, int proc_num);
 void gicv2_set_spi_routing(unsigned int id, int proc_num);
 void gicv2_set_interrupt_pending(unsigned int id);
 void gicv2_clear_interrupt_pending(unsigned int id);
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 8371dd5..5bb22fd 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -315,7 +315,7 @@
 #define SGIR_IRM_SHIFT			40
 #define SGIR_IRM_MASK			ULL(0x1)
 #define SGIR_AFF3_SHIFT			48
-#define SGIR_AFF_MASK			ULL(0xf)
+#define SGIR_AFF_MASK			ULL(0xff)
 
 #define SGIR_IRM_TO_AFF			U(0)
 
@@ -354,6 +354,12 @@
 #include <drivers/arm/gic_common.h>
 #include <lib/utils_def.h>
 
+typedef enum {
+	GICV3_G1S,
+	GICV3_G1NS,
+	GICV3_G0
+} gicv3_irq_group_t;
+
 static inline uintptr_t gicv3_redist_size(uint64_t typer_val)
 {
 #if GIC_ENABLE_V4_EXTN
@@ -575,7 +581,8 @@
 		unsigned int priority);
 void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
 		unsigned int type);
-void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target);
+void gicv3_raise_sgi(unsigned int sgi_num, gicv3_irq_group_t group,
+					 u_register_t target);
 void gicv3_set_spi_routing(unsigned int id, unsigned int irm,
 		u_register_t mpidr);
 void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num);
diff --git a/include/drivers/arm/mhu.h b/include/drivers/arm/mhu.h
index 7745bd9..31c6a81 100644
--- a/include/drivers/arm/mhu.h
+++ b/include/drivers/arm/mhu.h
@@ -76,4 +76,11 @@
  */
 enum mhu_error_t mhu_receive_data(uint8_t *receive_buffer, size_t *size);
 
+/**
+ * Gets the maximum amount of bytes that can be transmitted in a single send by MHU.
+ *
+ * Returns The amount of bytes that can be sent or received in a single message.
+ */
+size_t mhu_get_max_message_size(void);
+
 #endif /* MHU_H */
diff --git a/include/drivers/auth/crypto_mod.h b/include/drivers/auth/crypto_mod.h
index 73b2b99..3a23df4 100644
--- a/include/drivers/auth/crypto_mod.h
+++ b/include/drivers/auth/crypto_mod.h
@@ -7,6 +7,10 @@
 #ifndef CRYPTO_MOD_H
 #define CRYPTO_MOD_H
 
+#define	CRYPTO_AUTH_VERIFY_ONLY			1
+#define	CRYPTO_HASH_CALC_ONLY			2
+#define	CRYPTO_AUTH_VERIFY_AND_HASH_CALC	3
+
 /* Return values */
 enum crypto_ret_value {
 	CRYPTO_SUCCESS = 0,
@@ -48,6 +52,8 @@
 
 	/* Verify a digital signature. Return one of the
 	 * 'enum crypto_ret_value' options */
+#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 	int (*verify_signature)(void *data_ptr, unsigned int data_len,
 				void *sig_ptr, unsigned int sig_len,
 				void *sig_alg, unsigned int sig_alg_len,
@@ -56,13 +62,17 @@
 	/* Verify a hash. Return one of the 'enum crypto_ret_value' options */
 	int (*verify_hash)(void *data_ptr, unsigned int data_len,
 			   void *digest_info_ptr, unsigned int digest_info_len);
+#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
-#if MEASURED_BOOT
+#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 	/* Calculate a hash. Return hash value */
 	int (*calc_hash)(enum crypto_md_algo md_alg, void *data_ptr,
 			 unsigned int data_len,
 			 unsigned char output[CRYPTO_MD_MAX_SIZE]);
-#endif /* MEASURED_BOOT */
+#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
 	/*
 	 * Authenticated decryption. Return one of the
@@ -84,25 +94,32 @@
 }
 #endif /* CRYPTO_SUPPORT */
 
+#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len,
 				void *sig_ptr, unsigned int sig_len,
 				void *sig_alg_ptr, unsigned int sig_alg_len,
 				void *pk_ptr, unsigned int pk_len);
 int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
 			   void *digest_info_ptr, unsigned int digest_info_len);
+#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
+
 int crypto_mod_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);
 
-#if MEASURED_BOOT
+#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 int crypto_mod_calc_hash(enum crypto_md_algo alg, void *data_ptr,
 			 unsigned int data_len,
 			 unsigned char output[CRYPTO_MD_MAX_SIZE]);
-#endif /* MEASURED_BOOT */
+#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
+	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
-#if MEASURED_BOOT && TRUSTED_BOARD_BOOT
+#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 /* Macro to register a cryptographic library */
 #define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
 			    _calc_hash, _auth_decrypt) \
@@ -114,7 +131,7 @@
 		.calc_hash = _calc_hash, \
 		.auth_decrypt = _auth_decrypt \
 	}
-#elif TRUSTED_BOARD_BOOT
+#elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
 #define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
 			    _auth_decrypt) \
 	const crypto_lib_desc_t crypto_lib_desc = { \
@@ -124,14 +141,14 @@
 		.verify_hash = _verify_hash, \
 		.auth_decrypt = _auth_decrypt \
 	}
-#elif MEASURED_BOOT
+#elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
 #define REGISTER_CRYPTO_LIB(_name, _init, _calc_hash) \
 	const crypto_lib_desc_t crypto_lib_desc = { \
 		.name = _name, \
 		.init = _init, \
 		.calc_hash = _calc_hash, \
 	}
-#endif	/* MEASURED_BOOT && TRUSTED_BOARD_BOOT */
+#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
 
 extern const crypto_lib_desc_t crypto_lib_desc;
 
diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h
index f4c4fb8..eb0e2b1 100644
--- a/include/drivers/measured_boot/event_log/event_log.h
+++ b/include/drivers/measured_boot/event_log/event_log.h
@@ -11,6 +11,7 @@
 
 #include <common/debug.h>
 #include <common/tbbr/tbbr_img_def.h>
+#include <drivers/auth/crypto_mod.h>
 #include <drivers/measured_boot/event_log/tcg.h>
 
 /*
@@ -109,10 +110,16 @@
 			sizeof(event2_data_t))
 
 /* Functions' declarations */
+void event_log_buf_init(uint8_t *event_log_start, uint8_t *event_log_finish);
 void event_log_init(uint8_t *event_log_start, uint8_t *event_log_finish);
+void event_log_write_specid_event(void);
 void event_log_write_header(void);
 void dump_event_log(uint8_t *log_addr, size_t log_size);
 const event_log_metadata_t *plat_event_log_get_metadata(void);
+int event_log_measure(uintptr_t data_base, uint32_t data_size,
+		      unsigned char hash_data[CRYPTO_MD_MAX_SIZE]);
+void event_log_record(const uint8_t *hash, uint32_t event_type,
+		      const event_log_metadata_t *metadata_ptr);
 int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size,
 				 uint32_t data_id);
 size_t event_log_get_cur_size(uint8_t *event_log_start);
diff --git a/include/drivers/measured_boot/event_log/tcg.h b/include/drivers/measured_boot/event_log/tcg.h
index ab27a08..4ac2c2f 100644
--- a/include/drivers/measured_boot/event_log/tcg.h
+++ b/include/drivers/measured_boot/event_log/tcg.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -98,7 +98,12 @@
 	/* 8-15: Defined for use by the Static OS */
 	PCR_8,
 	/* Debug */
-	PCR_16 = 16
+	PCR_16 = 16,
+
+	/* D-CRTM-measurements by DRTM implementation */
+	PCR_17 = 17,
+	/* DCE measurements by DRTM implementation */
+	PCR_18 = 18
 };
 
 #pragma pack(push, 1)
diff --git a/include/drivers/st/stm32_uart.h b/include/drivers/st/stm32_uart.h
index 212968f..866e158 100644
--- a/include/drivers/st/stm32_uart.h
+++ b/include/drivers/st/stm32_uart.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
  */
@@ -34,10 +34,6 @@
 #define STM32_UART_HWCONTROL_CTS		USART_CR3_CTSE
 #define STM32_UART_HWCONTROL_RTS_CTS		(USART_CR3_RTSE | USART_CR3_CTSE)
 
-/* UART over sampling */
-#define STM32_UART_OVERSAMPLING_16		0x00000000U
-#define STM32_UART_OVERSAMPLING_8		USART_CR1_OVER8
-
 /* UART prescaler */
 #define STM32_UART_PRESCALER_DIV1		0x00000000U
 #define STM32_UART_PRESCALER_DIV2		0x00000001U
@@ -112,13 +108,6 @@
 					 * value of @ref STM32_UARTHWCONTROL_*.
 					 */
 
-	uint32_t over_sampling;		/*
-					 * Specifies whether the over sampling
-					 * 8 is enabled or disabled.
-					 * This parameter can be a value of
-					 * @ref STM32_UART_OVERSAMPLING_*.
-					 */
-
 	uint32_t one_bit_sampling;	/*
 					 * Specifies whether a single sample
 					 * or three samples' majority vote is
diff --git a/include/drivers/ufs.h b/include/drivers/ufs.h
index 09b8b72..1cd1bee 100644
--- a/include/drivers/ufs.h
+++ b/include/drivers/ufs.h
@@ -259,6 +259,9 @@
 /* maximum number of retries for a general UIC command  */
 #define UFS_UIC_COMMAND_RETRIES		3
 
+/* maximum number of retries for a transfer command  */
+#define UFS_CMD_RETRIES			3
+
 /* maximum number of retries for reading UFS capacity */
 #define UFS_READ_CAPACITY_RETRIES	10
 
diff --git a/include/lib/cpus/aarch64/cortex_a510.h b/include/lib/cpus/aarch64/cortex_a510.h
index af38734..6af85a8 100644
--- a/include/lib/cpus/aarch64/cortex_a510.h
+++ b/include/lib/cpus/aarch64/cortex_a510.h
@@ -36,5 +36,6 @@
  ******************************************************************************/
 #define CORTEX_A510_CPUACTLR_EL1				S3_0_C15_C1_0
 #define CORTEX_A510_CPUACTLR_EL1_BIT_17				(ULL(1) << 17)
+#define CORTEX_A510_CPUACTLR_EL1_BIT_38				(ULL(1) << 38)
 
 #endif /* CORTEX_A510_H */
\ No newline at end of file
diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h
index e33b9d5..432e17a 100644
--- a/include/lib/cpus/aarch64/cortex_a710.h
+++ b/include/lib/cpus/aarch64/cortex_a710.h
@@ -36,6 +36,7 @@
  ******************************************************************************/
 #define CORTEX_A710_CPUACTLR2_EL1				S3_0_C15_C1_1
 #define CORTEX_A710_CPUACTLR2_EL1_BIT_40			(ULL(1) << 40)
+#define CORTEX_A710_CPUACTLR2_EL1_BIT_36			(ULL(1) << 36)
 
 /*******************************************************************************
  * CPU Auxiliary Control register 5 specific definitions.
diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h
index 63f155f..a9b4546 100644
--- a/include/lib/cpus/aarch64/cortex_a77.h
+++ b/include/lib/cpus/aarch64/cortex_a77.h
@@ -20,6 +20,7 @@
  ******************************************************************************/
 #define CORTEX_A77_CPUECTLR_EL1				S3_0_C15_C1_4
 #define CORTEX_A77_CPUECTLR_EL1_BIT_8			(ULL(1) << 8)
+#define CORTEX_A77_CPUECTLR_EL1_BIT_53			(ULL(1) << 53)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions.
diff --git a/include/lib/cpus/aarch64/cortex_hunter_elp_arm.h b/include/lib/cpus/aarch64/cortex_hunter_elp_arm.h
new file mode 100644
index 0000000..f9bb0f3
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_hunter_elp_arm.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_HUNTER_ELP_ARM_H
+#define CORTEX_HUNTER_ELP_ARM_H
+
+#define CORTEX_HUNTER_ELP_ARM_MIDR					U(0x410FD821)
+
+/* Cortex Hunter ELP loop count for CVE-2022-23960 mitigation */
+#define CORTEX_HUNTER_ELP_ARM_BHB_LOOP_COUNT				U(132)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_HUNTER_ELP_ARM_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_HUNTER_ELP_ARM_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_HUNTER_ELP_ARM_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* CORTEX_HUNTER_ELP_ARM_H */
diff --git a/include/lib/cpus/aarch64/cortex_makalu_elp_arm.h b/include/lib/cpus/aarch64/cortex_makalu_elp_arm.h
deleted file mode 100644
index 9ed5ee3..0000000
--- a/include/lib/cpus/aarch64/cortex_makalu_elp_arm.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_MAKALU_ELP_ARM_H
-#define CORTEX_MAKALU_ELP_ARM_H
-
-#define CORTEX_MAKALU_ELP_ARM_MIDR				U(0x410FD4E0)
-
-/* Cortex Makalu ELP loop count for CVE-2022-23960 mitigation */
-#define CORTEX_MAKALU_ELP_ARM_BHB_LOOP_COUNT			U(132)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_MAKALU_ELP_ARM_CPUECTLR_EL1			S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_MAKALU_ELP_ARM_CPUPWRCTLR_EL1			S3_0_C15_C2_7
-#define CORTEX_MAKALU_ELP_ARM_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
-
-#endif /* CORTEX_MAKALU_ELP_ARM_H */
diff --git a/include/lib/cpus/aarch64/cortex_x3.h b/include/lib/cpus/aarch64/cortex_x3.h
new file mode 100644
index 0000000..076a87b
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_x3.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_X3_H
+#define CORTEX_X3_H
+
+#define CORTEX_X3_MIDR				U(0x410FD4E0)
+
+/* Cortex-X3 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_X3_BHB_LOOP_COUNT			U(132)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X3_CPUECTLR_EL1			S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X3_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define CORTEX_X3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 2 specific definitions.
+ ******************************************************************************/
+#define CORTEX_X3_CPUACTLR2_EL1			S3_0_C15_C1_1
+#define CORTEX_X3_CPUACTLR2_EL1_BIT_36		(ULL(1) << 36)
+
+#endif /* CORTEX_X3_H */
diff --git a/include/lib/cpus/aarch64/neoverse_demeter.h b/include/lib/cpus/aarch64/neoverse_demeter.h
deleted file mode 100644
index f1afae7..0000000
--- a/include/lib/cpus/aarch64/neoverse_demeter.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef NEOVERSE_DEMETER_H
-#define NEOVERSE_DEMETER_H
-
-#define NEOVERSE_DEMETER_MIDR				U(0x410FD4F0)
-
-/* Neoverse Demeter loop count for CVE-2022-23960 mitigation */
-#define NEOVERSE_DEMETER_BHB_LOOP_COUNT			U(132)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define NEOVERSE_DEMETER_CPUECTLR_EL1			S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define NEOVERSE_DEMETER_CPUPWRCTLR_EL1			S3_0_C15_C2_7
-#define NEOVERSE_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
-
-#endif /* NEOVERSE_DEMETER_H */
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index 3ff817c..cb1be5b 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -39,6 +39,7 @@
 #define NEOVERSE_N2_CPUACTLR2_EL1			S3_0_C15_C1_1
 #define NEOVERSE_N2_CPUACTLR2_EL1_BIT_0			(ULL(1) << 0)
 #define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2			(ULL(1) << 2)
+#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_36		(ULL(1) << 36)
 #define NEOVERSE_N2_CPUACTLR2_EL1_BIT_40		(ULL(1) << 40)
 
 /*******************************************************************************
diff --git a/include/lib/cpus/aarch64/neoverse_v2.h b/include/lib/cpus/aarch64/neoverse_v2.h
new file mode 100644
index 0000000..efb960e
--- /dev/null
+++ b/include/lib/cpus/aarch64/neoverse_v2.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEOVERSE_V2_H
+#define NEOVERSE_V2_H
+
+#define NEOVERSE_V2_MIDR				U(0x410FD4F0)
+
+/* Neoverse V2 loop count for CVE-2022-23960 mitigation */
+#define NEOVERSE_V2_BHB_LOOP_COUNT			U(132)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_V2_CPUECTLR_EL1			S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_V2_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+
+#endif /* NEOVERSE_V2_H */
diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h
index 917e053..131c542 100644
--- a/include/lib/fconf/fconf.h
+++ b/include/lib/fconf/fconf.h
@@ -7,6 +7,7 @@
 #ifndef FCONF_H
 #define FCONF_H
 
+#include <stddef.h>
 #include <stdint.h>
 
 /* Public API */
diff --git a/include/lib/libc/aarch32/inttypes_.h b/include/lib/libc/aarch32/inttypes_.h
index 11d2d35..ef3fb8f 100644
--- a/include/lib/libc/aarch32/inttypes_.h
+++ b/include/lib/libc/aarch32/inttypes_.h
@@ -18,4 +18,11 @@
 #define PRIx64		"llx"	/* uint64_t */
 #define PRIX64		"llX"	/* uint64_t */
 
+#define PRIdPTR         "d"     /* intptr_t */
+#define PRIiPTR         "i"     /* intptr_t */
+#define PRIoPTR         "o"     /* intptr_t */
+#define PRIuPTR         "u"     /* uintptr_t */
+#define PRIxPTR         "x"     /* uintptr_t */
+#define PRIXPTR         "X"     /* uintptr_t */
+
 #endif /* INTTYPES__H */
diff --git a/include/lib/libc/aarch64/inttypes_.h b/include/lib/libc/aarch64/inttypes_.h
index 197d627..f25882f 100644
--- a/include/lib/libc/aarch64/inttypes_.h
+++ b/include/lib/libc/aarch64/inttypes_.h
@@ -18,4 +18,11 @@
 #define PRIx64		"lx"	/* uint64_t */
 #define PRIX64		"lX"	/* uint64_t */
 
+#define PRIdPTR         "ld"    /* intptr_t */
+#define PRIiPTR         "li"    /* intptr_t */
+#define PRIoPTR         "lo"    /* intptr_t */
+#define PRIuPTR         "lu"    /* uintptr_t */
+#define PRIxPTR         "lx"    /* uintptr_t */
+#define PRIXPTR         "lX"    /* uintptr_t */
+
 #endif /* INTTYPES__H */
diff --git a/include/lib/libc/assert.h b/include/lib/libc/assert.h
index 486bbc2..462bb43 100644
--- a/include/lib/libc/assert.h
+++ b/include/lib/libc/assert.h
@@ -9,8 +9,6 @@
 
 #include <cdefs.h>
 
-#include <platform_def.h>
-
 #include <common/debug.h>
 
 #ifndef PLAT_LOG_LEVEL_ASSERT
@@ -18,9 +16,7 @@
 #endif
 
 #if ENABLE_ASSERTIONS
-# if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
-#  define assert(e)	((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))
-# elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
+# if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
 #  define assert(e)	((e) ? (void)0 : __assert(__FILE__, __LINE__))
 # else
 #  define assert(e)	((e) ? (void)0 : __assert())
@@ -29,10 +25,7 @@
 #define assert(e)	((void)0)
 #endif /* ENABLE_ASSERTIONS */
 
-#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
-void __dead2 __assert(const char *file, unsigned int line,
-		      const char *assertion);
-#elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
+#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
 void __dead2 __assert(const char *file, unsigned int line);
 #else
 void __dead2 __assert(void);
diff --git a/include/lib/libc/inttypes.h b/include/lib/libc/inttypes.h
index 0f9e8c6..6ad1c9e 100644
--- a/include/lib/libc/inttypes.h
+++ b/include/lib/libc/inttypes.h
@@ -17,31 +17,25 @@
 #define PRId8		"d"	/* int8_t */
 #define PRId16		"d"	/* int16_t */
 #define PRId32		"d"	/* int32_t */
-#define PRIdPTR		"d"	/* intptr_t */
 
 #define PRIi8		"i"	/* int8_t */
 #define PRIi16		"i"	/* int16_t */
 #define PRIi32		"i"	/* int32_t */
-#define PRIiPTR		"i"	/* intptr_t */
 
 #define PRIo8		"o"	/* int8_t */
 #define PRIo16		"o"	/* int16_t */
 #define PRIo32		"o"	/* int32_t */
-#define PRIoPTR		"o"	/* intptr_t */
 
 #define PRIu8		"u"	/* uint8_t */
 #define PRIu16		"u"	/* uint16_t */
 #define PRIu32		"u"	/* uint32_t */
-#define PRIuPTR		"u"	/* uintptr_t */
 
 #define PRIx8		"x"	/* uint8_t */
 #define PRIx16		"x"	/* uint16_t */
 #define PRIx32		"x"	/* uint32_t */
-#define PRIxPTR		"x"	/* uintptr_t */
 
 #define PRIX8		"X"	/* uint8_t */
 #define PRIX16		"X"	/* uint16_t */
 #define PRIX32		"X"	/* uint32_t */
-#define PRIXPTR		"X"	/* uintptr_t */
 
 #endif
diff --git a/include/lib/psa/delegated_attestation.h b/include/lib/psa/delegated_attestation.h
new file mode 100644
index 0000000..7aaceb3
--- /dev/null
+++ b/include/lib/psa/delegated_attestation.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* This file describes the Delegated Attestation API */
+
+#ifndef DELEGATED_ATTESTATION_H
+#define DELEGATED_ATTESTATION_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "psa/error.h"
+
+/* RSS Delegated Attestation message types that distinguish its services. */
+#define RSS_DELEGATED_ATTEST_GET_DELEGATED_KEY      1001U
+#define RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN     1002U
+
+/**
+ * The aim of these APIs to get a derived signing key (private only) for the
+ * delegated attestation model and obtain the corresponding platform attestation
+ * token. In the delegated attestation model the final token consist of more
+ * than one subtokens which are signed by different entities. There is a
+ * cryptographical binding between the tokens. The derived delegated attestation
+ * key is bind to the platform token (details below).
+ *
+ * Expected usage model:
+ *  - First rss_delegated_attest_get_delegated_key() API need to be called to
+ *    obtain the private part of the delegated attestation key. The public part
+ *    of key is computed by the cryptographic library when the key is
+ *    registered.
+ *  - Secondly the rss_delegated_attest_get_token() must be called to obtain
+ *    platform attestation token. The hash of the public key (computed by
+ *    the hash_algo indicated in the rss_delegated_attest_get_delegated_key()
+ *    call) must be the input of this call. This ensures that nothing but the
+ *    previously derived delegated key is bindable to the platform token.
+ */
+
+/**
+ * Get a delegated attestation key (DAK).
+ *
+ * The aim of the delegated attestation key is to enable other SW components
+ * within the system to sign an attestation token which is different than the
+ * initial/platform token. The initial attestation token MUST contain the hash
+ * of the public delegated key to make a cryptographical binding (hash lock)
+ * between the key and the token.
+ * The initial attestation token has two roles in this scenario:
+ *   - Attest the device boot status and security lifecycle.
+ *   - Attest the delegated attestation key.
+ * The delegated attestation key is derived from a preprovisioned seed. The
+ * input for the key derivation is the platform boot status. The system can be
+ * attestated with the two tokens together.
+ *
+ * ecc_curve     The type of the elliptic curve to which the requested
+ *               attestation key belongs. Please check the note section for
+ *               limitations.
+ * key_bits      The size of the requested attestation key, in bits.
+ * key_buf       Pointer to the buffer where the delegated attestation key will
+ *               be stored.
+ * key_buf_size  Size of allocated buffer for the key, in bytes.
+ * key_size      Size of the key that has been returned, in bytes.
+ * hash_algo     The hash algorithm that will be used later by the owner of the
+ *               requested delegated key for binding it to the platform
+ *               attestation token.
+ *
+ * Returns error code as specified in psa_status_t.
+ *
+ * Notes:
+ *   - Currently, only the PSA_ECC_FAMILY_SECP_R1 curve type is supported.
+ *   - The delegated attestation key must be derived before requesting for the
+ *     platform attestation token as they are cryptographically linked together.
+ */
+psa_status_t
+rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+				       uint32_t  key_bits,
+				       uint8_t  *key_buf,
+				       size_t    key_buf_size,
+				       size_t   *key_size,
+				       uint32_t  hash_algo);
+
+/**
+ * Get platform attestation token
+ *
+ * dak_pub_hash       Pointer to buffer where the hash of the public DAK is
+ *                    stored.
+ * dak_pub_hash_size  Size of the hash value, in bytes.
+ * token_buf          Pointer to the buffer where the platform attestation token
+ *                    will be stored.
+ * token_buf_size     Size of allocated buffer for token, in bytes.
+ * token_size         Size of the token that has been returned, in bytes.
+ *
+ * Returns error code as specified in psa_status_t.
+ *
+ * A delegated attestation key must be derived before requesting for the
+ * platform attestation token as they are cryptographically linked together.
+ * Otherwise, the token request will fail and the PSA_ERROR_INVALID_ARGUMENT
+ * code will be returned.
+ */
+psa_status_t
+rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+			       size_t         dak_pub_hash_size,
+			       uint8_t       *token_buf,
+			       size_t         token_buf_size,
+			       size_t        *token_size);
+
+#endif /* DELEGATED_ATTESTATION_H */
diff --git a/include/lib/psa/initial_attestation.h b/include/lib/psa/initial_attestation.h
deleted file mode 100644
index 93169f0..0000000
--- a/include/lib/psa/initial_attestation.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef PSA_INITIAL_ATTESTATION_H
-#define PSA_INITIAL_ATTESTATION_H
-
-#include <limits.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "psa/error.h"
-
-/*
- * Initial attestation API version is: 1.0.0
- */
-#define PSA_INITIAL_ATTEST_API_VERSION_MAJOR	(1)
-#define PSA_INITIAL_ATTEST_API_VERSION_MINOR	(0)
-
-/* The allowed size of input challenge in bytes. */
-#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32	32U
-#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48	48U
-#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64	64U
-
-/* Initial Attestation message types that distinguish Attest services. */
-#define RSS_ATTEST_GET_TOKEN		1001U
-#define RSS_ATTEST_GET_TOKEN_SIZE	1002U
-#define RSS_ATTEST_GET_DELEGATED_KEY	1003U
-
-/**
- * Get the platform attestation token.
- *
- * auth_challenge	Pointer to buffer where challenge input is stored. This
- *			must be the hash of the public part of the delegated
- *			attestation key.
- * challenge_size	Size of challenge object in bytes.
- * token_buf		Pointer to the buffer where attestation token will be
- *			stored.
- * token_buf_size	Size of allocated buffer for token, in bytes.
- * token_size		Size of the token that has been returned, in bytes.
- *
- * Returns error code as specified in psa_status_t.
- */
-psa_status_t
-psa_initial_attest_get_token(const uint8_t *auth_challenge,
-			     size_t         challenge_size,
-			     uint8_t       *token_buf,
-			     size_t         token_buf_size,
-			     size_t        *token_size);
-
-#endif /* PSA_INITIAL_ATTESTATION_H */
diff --git a/include/lib/psa/psa_manifest/sid.h b/include/lib/psa/psa_manifest/sid.h
index 580a4cf..0bdeed4 100644
--- a/include/lib/psa/psa_manifest/sid.h
+++ b/include/lib/psa/psa_manifest/sid.h
@@ -8,10 +8,10 @@
 #ifndef PSA_MANIFEST_SID_H
 #define PSA_MANIFEST_SID_H
 
-/******** PSA_SP_INITIAL_ATTESTATION ********/
-#define RSS_ATTESTATION_SERVICE_HANDLE			(0x40000103U)
-
 /******** PSA_SP_MEASURED_BOOT ********/
 #define RSS_MEASURED_BOOT_HANDLE			(0x40000110U)
 
+/******** PSA_SP_DELAGATED_ATTESTATION ********/
+#define RSS_DELEGATED_SERVICE_HANDLE			(0x40000111U)
+
 #endif /* PSA_MANIFEST_SID_H */
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index 43e2f96..3edc50b 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -92,6 +92,7 @@
 int psci_stop_other_cores(unsigned int wait_ms,
 			  void (*stop_func)(u_register_t mpidr));
 bool psci_is_last_on_cpu_safe(void);
+void psci_pwrdown_cpu(unsigned int power_level);
 
 #endif /* __ASSEMBLER__ */
 
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index 1a39f24..9940ea9 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -41,6 +41,8 @@
 #define FUNCID_NUM_MASK			U(0xffff)
 #define FUNCID_NUM_WIDTH		U(16)
 
+#define FUNCID_MASK			U(0xffffffff)
+
 #define GET_SMC_NUM(id)			(((id) >> FUNCID_NUM_SHIFT) & \
 					 FUNCID_NUM_MASK)
 #define GET_SMC_TYPE(id)		(((id) >> FUNCID_TYPE_SHIFT) & \
diff --git a/include/lib/xlat_tables/xlat_tables_compat.h b/include/lib/xlat_tables/xlat_tables_compat.h
index 90768db..5f28195 100644
--- a/include/lib/xlat_tables/xlat_tables_compat.h
+++ b/include/lib/xlat_tables/xlat_tables_compat.h
@@ -1,11 +1,16 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#ifndef XLAT_TABLES_COMPAT_H
+#define XLAT_TABLES_COMPAT_H
+
 #if XLAT_TABLES_LIB_V2
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #else
 #include <lib/xlat_tables/xlat_tables.h>
 #endif
+
+#endif /* XLAT_TABLES_COMPAT_H */
diff --git a/include/plat/arm/common/arm_sip_svc.h b/include/plat/arm/common/arm_sip_svc.h
index 2eeed95..025d10e 100644
--- a/include/plat/arm/common/arm_sip_svc.h
+++ b/include/plat/arm/common/arm_sip_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019,2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019,2021-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,7 +26,7 @@
 /* DEBUGFS_SMC_64			0xC2000030U */
 
 /*
- * Arm Ethos-N NPU SiP SMC function IDs
+ * Arm(R) Ethos(TM)-N NPU SiP SMC function IDs
  * 0xC2000050-0xC200005F
  * 0x82000050-0x8200005F
  */
diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h
index aa628df..96ed963 100644
--- a/include/plat/arm/common/fconf_arm_sp_getter.h
+++ b/include/plat/arm/common/fconf_arm_sp_getter.h
@@ -7,6 +7,7 @@
 #ifndef FCONF_ARM_SP_GETTER_H
 #define FCONF_ARM_SP_GETTER_H
 
+#include <common/tbbr/tbbr_img_def.h>
 #include <lib/fconf/fconf.h>
 #include <tools_share/uuid.h>
 
diff --git a/include/plat/arm/common/fconf_ethosn_getter.h b/include/plat/arm/common/fconf_ethosn_getter.h
index fcdc31f..5b9a7ed 100644
--- a/include/plat/arm/common/fconf_ethosn_getter.h
+++ b/include/plat/arm/common/fconf_ethosn_getter.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
  */
@@ -8,27 +8,52 @@
 #define FCONF_ETHOSN_GETTER_H
 
 #include <assert.h>
+#include <stdbool.h>
 
 #include <lib/fconf/fconf.h>
 
 #define hw_config__ethosn_config_getter(prop) ethosn_config.prop
-#define hw_config__ethosn_core_addr_getter(idx) __extension__ ({	\
-	assert(idx < ethosn_config.num_cores);				\
-	ethosn_config.core[idx].addr;					\
+#define hw_config__ethosn_device_getter(dev_idx) __extension__ ({	\
+	assert(dev_idx < ethosn_config.num_devices);			\
+	&ethosn_config.devices[dev_idx];				\
 })
 
-#define ETHOSN_STATUS_DISABLED U(0)
-#define ETHOSN_STATUS_ENABLED  U(1)
+#define ETHOSN_DEV_NUM_MAX U(2)
+#define ETHOSN_DEV_CORE_NUM_MAX U(8)
+#define ETHOSN_DEV_ASSET_ALLOCATOR_NUM_MAX U(16)
 
-#define ETHOSN_CORE_NUM_MAX U(64)
+struct ethosn_allocator_t {
+	uint32_t stream_id;
+};
+
+struct ethosn_main_allocator_t {
+	struct ethosn_allocator_t firmware;
+	struct ethosn_allocator_t working_data;
+};
+
+struct ethosn_asset_allocator_t {
+	struct ethosn_allocator_t command_stream;
+	struct ethosn_allocator_t weight_data;
+	struct ethosn_allocator_t buffer_data;
+	struct ethosn_allocator_t intermediate_data;
+};
 
 struct ethosn_core_t {
 	uint64_t addr;
+	struct ethosn_main_allocator_t main_allocator;
 };
 
-struct ethosn_config_t {
+struct ethosn_device_t {
+	bool has_reserved_memory;
 	uint32_t num_cores;
-	struct ethosn_core_t core[ETHOSN_CORE_NUM_MAX];
+	struct ethosn_core_t cores[ETHOSN_DEV_CORE_NUM_MAX];
+	uint32_t num_allocators;
+	struct ethosn_asset_allocator_t asset_allocators[ETHOSN_DEV_ASSET_ALLOCATOR_NUM_MAX];
+};
+
+struct ethosn_config_t {
+	uint32_t num_devices;
+	struct ethosn_device_t devices[ETHOSN_DEV_NUM_MAX];
 };
 
 int fconf_populate_arm_ethosn(uintptr_t config);
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index d060332..6c0d91d 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -297,6 +297,7 @@
 void plat_arm_program_trusted_mailbox(uintptr_t address);
 bool plat_arm_bl1_fwu_needed(void);
 __dead2 void plat_arm_error_handler(int err);
+__dead2 void plat_arm_system_reset(void);
 
 /*
  * Optional functions in ARM standard platforms
diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h
index e5357f5..84e6b38 100644
--- a/include/plat/arm/css/common/css_pm.h
+++ b/include/plat/arm/css/common/css_pm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,9 @@
 
 #include <lib/psci/psci.h>
 
+/* SGI used to trigger per-core power down request */
+#define CSS_CPU_PWR_DOWN_REQ_INTR	ARM_IRQ_SEC_SGI_7
+
 /* Macros to read the CSS power domain state */
 #define CSS_CORE_PWR_STATE(state)	(state)->pwr_domain_state[ARM_PWR_LVL0]
 #define CSS_CLUSTER_PWR_STATE(state)	(state)->pwr_domain_state[ARM_PWR_LVL1]
@@ -37,6 +40,9 @@
 void css_cpu_standby(plat_local_state_t cpu_state);
 void css_get_sys_suspend_power_state(psci_power_state_t *req_state);
 int css_node_hw_state(u_register_t mpidr, unsigned int power_level);
+void css_setup_cpu_pwr_down_intr(void);
+int css_reboot_interrupt_handler(uint32_t intr_raw, uint32_t flags,
+		void *handle, void *cookie);
 
 /*
  * This mapping array has to be exported by the platform. Each element at
diff --git a/include/plat/common/plat_drtm.h b/include/plat/common/plat_drtm.h
new file mode 100644
index 0000000..e96e719
--- /dev/null
+++ b/include/plat/common/plat_drtm.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DRTM_H
+#define PLAT_DRTM_H
+
+#include <stdint.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
+
+typedef struct {
+	uint8_t max_num_mem_prot_regions;
+	uint8_t dma_protection_support;
+} plat_drtm_dma_prot_features_t;
+
+typedef struct {
+	bool tpm_based_hash_support;
+	uint32_t firmware_hash_algorithm;
+} plat_drtm_tpm_features_t;
+
+typedef struct {
+	uint64_t region_address;
+	uint64_t region_size_type;
+} __attribute__((packed)) drtm_mem_region_t;
+
+/*
+ * Memory region descriptor table structure as per DRTM beta0 section 3.13
+ * Table 11 MEMORY_REGION_DESCRIPTOR_TABLE
+ */
+typedef struct {
+	uint16_t revision;
+	uint16_t reserved;
+	uint32_t num_regions;
+	drtm_mem_region_t region[];
+} __attribute__((packed)) drtm_memory_region_descriptor_table_t;
+
+/* platform specific address map functions */
+const mmap_region_t *plat_get_addr_mmap(void);
+
+/* platform-specific DMA protection functions */
+bool plat_has_non_host_platforms(void);
+bool plat_has_unmanaged_dma_peripherals(void);
+unsigned int plat_get_total_smmus(void);
+void plat_enumerate_smmus(const uintptr_t **smmus_out,
+			  size_t *smmu_count_out);
+const plat_drtm_dma_prot_features_t *plat_drtm_get_dma_prot_features(void);
+uint64_t plat_drtm_dma_prot_get_max_table_bytes(void);
+
+/* platform-specific TPM functions */
+const plat_drtm_tpm_features_t *plat_drtm_get_tpm_features(void);
+
+/*
+ * TODO: Implement these functions as per the platform use case,
+ * as of now none of the platform uses these functions
+ */
+uint64_t plat_drtm_get_min_size_normal_world_dce(void);
+uint64_t plat_drtm_get_tcb_hash_table_size(void);
+uint64_t plat_drtm_get_imp_def_dlme_region_size(void);
+uint64_t plat_drtm_get_tcb_hash_features(void);
+
+/* DRTM error handling functions */
+int plat_set_drtm_error(uint64_t error_code);
+int plat_get_drtm_error(uint64_t *error_code);
+
+/*
+ * Platform-specific function to ensure passed region lies within
+ * Non-Secure region of DRAM
+ */
+int plat_drtm_validate_ns_region(uintptr_t region_start,
+				 size_t region_size);
+
+#endif /* PLAT_DRTM_H */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 184606a..c90441c 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,6 +20,9 @@
 #include "plat_trng.h"
 #endif
 #include <drivers/fwu/fwu_metadata.h>
+#if DRTM_SUPPORT
+#include "plat_drtm.h"
+#endif /* DRTM_SUPPORT */
 
 /*******************************************************************************
  * Forward declarations
@@ -104,6 +107,8 @@
 void plat_ic_set_interrupt_type(unsigned int id, unsigned int type);
 void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority);
 void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target);
+void plat_ic_raise_ns_sgi(int sgi_num, u_register_t target);
+void plat_ic_raise_s_el1_sgi(int sgi_num, u_register_t target);
 void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
 		u_register_t mpidr);
 void plat_ic_set_interrupt_pending(unsigned int id);
@@ -116,11 +121,14 @@
  ******************************************************************************/
 uintptr_t plat_get_my_stack(void);
 void plat_report_exception(unsigned int exception_type);
+void plat_report_prefetch_abort(unsigned int fault_address);
+void plat_report_data_abort(unsigned int fault_address);
 int plat_crash_console_init(void);
 int plat_crash_console_putc(int c);
 void plat_crash_console_flush(void);
 void plat_error_handler(int err) __dead2;
 void plat_panic_handler(void) __dead2;
+void plat_system_reset(void) __dead2;
 const char *plat_log_get_prefix(unsigned int log_level);
 void bl2_plat_preload_setup(void);
 int plat_try_next_boot_source(void);
diff --git a/include/plat/marvell/armada/a8k/common/plat_marvell.h b/include/plat/marvell/armada/a8k/common/plat_marvell.h
index 5d805a7..bec21a0 100644
--- a/include/plat/marvell/armada/a8k/common/plat_marvell.h
+++ b/include/plat/marvell/armada/a8k/common/plat_marvell.h
@@ -10,6 +10,7 @@
 
 #include <stdint.h>
 
+#include <common/bl_common.h>
 #include <lib/cassert.h>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/utils.h>
diff --git a/include/services/drtm_svc.h b/include/services/drtm_svc.h
new file mode 100644
index 0000000..69b314f
--- /dev/null
+++ b/include/services/drtm_svc.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ * DRTM service
+ *
+ * Authors:
+ *	Lucian Paul-Trifu <lucian.paultrifu@gmail.com>
+ *	Brian Nezvadovitz <brinez@microsoft.com> 2021-02-01
+ *
+ */
+
+#ifndef ARM_DRTM_SVC_H
+#define ARM_DRTM_SVC_H
+
+/*
+ * SMC function IDs for DRTM Service
+ * Upper word bits set: Fast call, SMC64, Standard Secure Svc. Call (OEN = 4)
+ */
+#define DRTM_FID(func_num)				\
+	((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) |		\
+	(SMC_64 << FUNCID_CC_SHIFT) |			\
+	(OEN_STD_START << FUNCID_OEN_SHIFT) |		\
+	((func_num) << FUNCID_NUM_SHIFT))
+
+#define DRTM_FNUM_SVC_VERSION		U(0x110)
+#define DRTM_FNUM_SVC_FEATURES		U(0x111)
+#define DRTM_FNUM_SVC_UNPROTECT_MEM	U(0x113)
+#define DRTM_FNUM_SVC_DYNAMIC_LAUNCH	U(0x114)
+#define DRTM_FNUM_SVC_CLOSE_LOCALITY	U(0x115)
+#define DRTM_FNUM_SVC_GET_ERROR		U(0x116)
+#define DRTM_FNUM_SVC_SET_ERROR		U(0x117)
+#define DRTM_FNUM_SVC_SET_TCB_HASH	U(0x118)
+#define DRTM_FNUM_SVC_LOCK_TCB_HASH	U(0x119)
+
+#define ARM_DRTM_SVC_VERSION		DRTM_FID(DRTM_FNUM_SVC_VERSION)
+#define ARM_DRTM_SVC_FEATURES		DRTM_FID(DRTM_FNUM_SVC_FEATURES)
+#define ARM_DRTM_SVC_UNPROTECT_MEM	DRTM_FID(DRTM_FNUM_SVC_UNPROTECT_MEM)
+#define ARM_DRTM_SVC_DYNAMIC_LAUNCH	DRTM_FID(DRTM_FNUM_SVC_DYNAMIC_LAUNCH)
+#define ARM_DRTM_SVC_CLOSE_LOCALITY	DRTM_FID(DRTM_FNUM_SVC_CLOSE_LOCALITY)
+#define ARM_DRTM_SVC_GET_ERROR		DRTM_FID(DRTM_FNUM_SVC_GET_ERROR)
+#define ARM_DRTM_SVC_SET_ERROR		DRTM_FID(DRTM_FNUM_SVC_SET_ERROR)
+#define ARM_DRTM_SVC_SET_TCB_HASH	DRTM_FID(DRTM_FNUM_SVC_SET_TCB_HASH)
+#define ARM_DRTM_SVC_LOCK_TCB_HASH	DRTM_FID(DRTM_FNUM_SVC_LOCK_TCB_HASH)
+
+#define ARM_DRTM_FEATURES_TPM		U(0x1)
+#define ARM_DRTM_FEATURES_MEM_REQ	U(0x2)
+#define ARM_DRTM_FEATURES_DMA_PROT	U(0x3)
+#define ARM_DRTM_FEATURES_BOOT_PE_ID	U(0x4)
+#define ARM_DRTM_FEATURES_TCB_HASHES	U(0x5)
+
+#define is_drtm_fid(_fid) \
+	(((_fid) >= ARM_DRTM_SVC_VERSION) && ((_fid) <= ARM_DRTM_SVC_LOCK_TCB_HASH))
+
+/* ARM DRTM Service Calls version numbers */
+#define ARM_DRTM_VERSION_MAJOR		U(0)
+#define ARM_DRTM_VERSION_MAJOR_SHIFT	16
+#define ARM_DRTM_VERSION_MAJOR_MASK	U(0x7FFF)
+#define ARM_DRTM_VERSION_MINOR		U(1)
+#define ARM_DRTM_VERSION_MINOR_SHIFT	0
+#define ARM_DRTM_VERSION_MINOR_MASK	U(0xFFFF)
+
+#define ARM_DRTM_VERSION						\
+	((((ARM_DRTM_VERSION_MAJOR) & ARM_DRTM_VERSION_MAJOR_MASK) <<	\
+	ARM_DRTM_VERSION_MAJOR_SHIFT)					\
+	| (((ARM_DRTM_VERSION_MINOR) & ARM_DRTM_VERSION_MINOR_MASK) <<	\
+	ARM_DRTM_VERSION_MINOR_SHIFT))
+
+#define ARM_DRTM_FUNC_SHIFT	U(63)
+#define ARM_DRTM_FUNC_MASK	ULL(0x1)
+#define ARM_DRTM_FUNC_ID	U(0x0)
+#define ARM_DRTM_FEAT_ID	U(0x1)
+#define ARM_DRTM_FEAT_ID_MASK	ULL(0xff)
+
+/*
+ * Definitions for DRTM features as per DRTM beta0 section 3.3,
+ * Table 6 DRTM_FEATURES
+ */
+#define ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_SHIFT		U(33)
+#define ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_MASK		ULL(0xF)
+#define ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_DEFAULT	ULL(0x1)
+
+#define ARM_DRTM_TPM_FEATURES_TPM_HASH_SHIFT		U(32)
+#define ARM_DRTM_TPM_FEATURES_TPM_HASH_MASK		ULL(0x1)
+#define ARM_DRTM_TPM_FEATURES_TPM_HASH_NOT_SUPPORTED	ULL(0x0)
+#define ARM_DRTM_TPM_FEATURES_TPM_HASH_SUPPORTED	ULL(0x1)
+
+#define ARM_DRTM_TPM_FEATURES_FW_HASH_SHIFT		U(0)
+#define ARM_DRTM_TPM_FEATURES_FW_HASH_MASK		ULL(0xFFFFFFFF)
+#define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA256		ULL(0xB)
+#define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA384		ULL(0xC)
+#define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA512		ULL(0xD)
+
+#define ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_SHIFT		U(32)
+#define ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_MASK		ULL(0xFFFFFFFF)
+
+#define ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_SHIFT	U(0)
+#define ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_MASK	ULL(0xFFFFFFFF)
+
+#define ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_SHIFT	U(8)
+#define ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_MASK	ULL(0xF)
+
+#define ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_SHIFT	U(0)
+#define ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_MASK	ULL(0xFF)
+#define ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_COMPLETE	ULL(0x1)
+#define ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_REGION	ULL(0x2)
+
+#define ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_SHIFT	U(0)
+#define ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_MASK	ULL(0xFF)
+
+#define ARM_DRTM_TPM_FEATURES_SET_PCR_SCHEMA(reg, val)			\
+	do {								\
+		reg = (((reg) & ~(ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_MASK \
+		<< ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_SHIFT)) | (((val) & \
+		ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_MASK) <<		\
+		ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_SHIFT));		\
+	} while (false)
+
+#define ARM_DRTM_TPM_FEATURES_SET_TPM_HASH(reg, val)			\
+	do {								\
+		reg = (((reg) & ~(ARM_DRTM_TPM_FEATURES_TPM_HASH_MASK	\
+		<< ARM_DRTM_TPM_FEATURES_TPM_HASH_SHIFT)) | (((val) &	\
+		ARM_DRTM_TPM_FEATURES_TPM_HASH_MASK) <<			\
+		ARM_DRTM_TPM_FEATURES_TPM_HASH_SHIFT));			\
+	} while (false)
+
+#define ARM_DRTM_TPM_FEATURES_SET_FW_HASH(reg, val)			\
+	do {								\
+		reg = (((reg) & ~(ARM_DRTM_TPM_FEATURES_FW_HASH_MASK	\
+		<< ARM_DRTM_TPM_FEATURES_FW_HASH_SHIFT)) | (((val) &	\
+		ARM_DRTM_TPM_FEATURES_FW_HASH_MASK) <<			\
+		ARM_DRTM_TPM_FEATURES_FW_HASH_SHIFT));			\
+	} while (false)
+
+#define ARM_DRTM_MIN_MEM_REQ_SET_DCE_SIZE(reg, val)			\
+	do {								\
+		reg = (((reg) & ~(ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_MASK	\
+		<< ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_SHIFT)) | (((val) &	\
+		ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_MASK) <<			\
+		ARM_DRTM_MIN_MEM_REQ_DCE_SIZE_SHIFT));			\
+	} while (false)
+
+#define ARM_DRTM_MIN_MEM_REQ_SET_MIN_DLME_DATA_SIZE(reg, val)		\
+	do {								\
+		reg = (((reg) &						\
+		~(ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_MASK <<	\
+		ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_SHIFT)) |	\
+		(((val) & ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_MASK) \
+		<< ARM_DRTM_MIN_MEM_REQ_MIN_DLME_DATA_SIZE_SHIFT));	\
+	} while (false)
+
+#define ARM_DRTM_DMA_PROT_FEATURES_SET_MAX_REGIONS(reg, val)		\
+	do {								\
+		reg = (((reg) &						\
+		~(ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_MASK <<	\
+		ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_SHIFT)) |	\
+		(((val) & ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_MASK)	\
+		<< ARM_DRTM_DMA_PROT_FEATURES_MAX_REGIONS_SHIFT));	\
+	} while (false)
+
+#define ARM_DRTM_DMA_PROT_FEATURES_SET_DMA_SUPPORT(reg, val) \
+	do {								\
+		reg = (((reg) &						\
+		~(ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_MASK <<	\
+		ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_SHIFT)) |	\
+		(((val) & ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_MASK)	\
+		<< ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_SHIFT));	\
+	} while (false)
+
+#define ARM_DRTM_TCB_HASH_FEATURES_SET_MAX_NUM_HASHES(reg, val)		\
+	do {								\
+		reg = (((reg) &						\
+		~(ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_MASK <<	\
+		ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_SHIFT)) |	\
+		(((val) &						\
+		ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_MASK) <<	\
+		ARM_DRTM_TCB_HASH_FEATURES_MAX_NUM_HASHES_SHIFT));	\
+	} while (false)
+
+/* Definitions for DRTM address map */
+#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_SHIFT	U(55)
+#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_MASK	ULL(0x3)
+#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_NC	ULL(0)
+#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_WC	ULL(1)
+#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_WT	ULL(2)
+#define ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_WB	ULL(3)
+
+#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_SHIFT	U(52)
+#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_MASK	ULL(0x7)
+#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NORMAL	ULL(0)
+#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NCAR	ULL(1)
+#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_DEVICE	ULL(2)
+#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NV	ULL(3)
+#define ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_RSVD	ULL(4)
+
+#define ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_SHIFT	U(0)
+#define ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_MASK	ULL(0xFFFFFFFFFFFFF)
+
+#define ARM_DRTM_REGION_SIZE_TYPE_SET_CACHEABILITY(reg, val)		\
+	do {								\
+		reg = (((reg) &						\
+		~(ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_MASK << 	\
+		ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_SHIFT)) |	\
+		(((val) &						\
+		ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_MASK) <<		\
+		ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_SHIFT));		\
+	} while (false)
+
+#define ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(reg, val)		\
+	do {								\
+		reg = (((reg) &						\
+		~(ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_MASK <<		\
+		ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_SHIFT)) |		\
+		(((val) & ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_MASK)	\
+		<< ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_SHIFT));	\
+	} while (false)
+
+#define ARM_DRTM_REGION_SIZE_TYPE_SET_4K_PAGE_NUM(reg, val)		\
+	do {								\
+		reg = (((reg) &						\
+		~(ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_MASK <<		\
+		ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_SHIFT)) |		\
+		(((val) & ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_MASK)	\
+		<< ARM_DRTM_REGION_SIZE_TYPE_4K_PAGE_NUM_SHIFT));	\
+	} while (false)
+
+/* Initialization routine for the DRTM service */
+int drtm_setup(void);
+
+/* Handler to be called to handle DRTM SMC calls */
+uint64_t drtm_smc_handler(uint32_t smc_fid,
+			  uint64_t x1,
+			  uint64_t x2,
+			  uint64_t x3,
+			  uint64_t x4,
+			  void *cookie,
+			  void *handle,
+			  uint64_t flags);
+
+#endif /* ARM_DRTM_SVC_H */
diff --git a/include/services/sdei.h b/include/services/sdei.h
index 063ed6f..c12a182 100644
--- a/include/services/sdei.h
+++ b/include/services/sdei.h
@@ -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
  */
@@ -137,4 +137,7 @@
 /* Public API to dispatch an event to Normal world */
 int sdei_dispatch_event(int ev_num);
 
+/* Public API to check how many SDEI events are registered. */
+int sdei_get_registered_event_count(void);
+
 #endif /* SDEI_H */
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index 81a4a78..f7f8027 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -330,6 +330,37 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2371937
 
+	/* ------------------------------------------------------
+	 * Errata Workaround for Cortex-A510 Errata #2666669
+	 * This applies to revisions r1p1 and lower, and is fixed
+	 * in r1p2.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0, x1, x17
+	 * ------------------------------------------------------
+	 */
+func errata_cortex_a510_2666669_wa
+	mov	x17, x30
+	bl	check_errata_2666669
+	cbz	x0, 1f
+
+	/*
+	 * Workaround will set IMP_CPUACTLR_EL1[38]
+	 * to 0b1.
+	 */
+	mrs	x1, CORTEX_A510_CPUACTLR_EL1
+	orr	x1, x1, CORTEX_A510_CPUACTLR_EL1_BIT_38
+	msr	CORTEX_A510_CPUACTLR_EL1, x1
+1:
+	ret	x17
+endfunc errata_cortex_a510_2666669_wa
+
+func check_errata_2666669
+	/* Applies to r1p1 and lower */
+	mov	x1, #0x11
+	b	cpu_rev_var_ls
+endfunc check_errata_2666669
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -361,14 +392,15 @@
 	 * checking functions of each errata.
 	 */
 	report_errata ERRATA_A510_1922240, cortex_a510, 1922240
-	report_errata ERRATA_A510_2288014, cortex_a510, 2288014
-	report_errata ERRATA_A510_2042739, cortex_a510, 2042739
 	report_errata ERRATA_A510_2041909, cortex_a510, 2041909
-	report_errata ERRATA_A510_2250311, cortex_a510, 2250311
-	report_errata ERRATA_A510_2218950, cortex_a510, 2218950
+	report_errata ERRATA_A510_2042739, cortex_a510, 2042739
 	report_errata ERRATA_A510_2172148, cortex_a510, 2172148
+	report_errata ERRATA_A510_2218950, cortex_a510, 2218950
+	report_errata ERRATA_A510_2250311, cortex_a510, 2250311
+	report_errata ERRATA_A510_2288014, cortex_a510, 2288014
 	report_errata ERRATA_A510_2347730, cortex_a510, 2347730
 	report_errata ERRATA_A510_2371937, cortex_a510, 2371937
+	report_errata ERRATA_A510_2666669, cortex_a510, 2666669
 	report_errata ERRATA_DSU_2313941, cortex_a510, dsu_2313941
 
 	ldp	x8, x30, [sp], #16
@@ -435,6 +467,11 @@
 	bl	errata_cortex_a510_2347730_wa
 #endif
 
+#if ERRATA_A510_2666669
+	mov	x0, x18
+	bl	errata_cortex_a510_2666669_wa
+#endif
+
 	isb
 	ret	x19
 endfunc cortex_a510_reset_func
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 77f7a8d..fed3f33 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -383,6 +383,34 @@
 	b       cpu_rev_var_ls
 endfunc check_errata_2282622
 
+/* ------------------------------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2291219 on power down request.
+ * This applies to revision <= r2p0 and is fixed in r2p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * ------------------------------------------------------------------------
+ */
+func errata_a710_2291219_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2291219
+	cbz	x0, 1f
+
+	/* Set bit 36 in ACTLR2_EL1 */
+	mrs	x1, CORTEX_A710_CPUACTLR2_EL1
+	orr	x1, x1, #CORTEX_A710_CPUACTLR2_EL1_BIT_36
+	msr	CORTEX_A710_CPUACTLR2_EL1, x1
+1:
+	ret	x17
+endfunc errata_a710_2291219_wa
+
+func check_errata_2291219
+	/* Applies to <= r2p0. */
+	mov	x1, #0x20
+	b	cpu_rev_var_ls
+endfunc check_errata_2291219
+
 /* ---------------------------------------------------------------
  * Errata Workaround for Cortex-A710 Erratum 2008768.
  * This applies to revision r0p0, r1p0 and r2p0.
@@ -476,6 +504,13 @@
 	mov	x30, x4
 #endif
 
+#if ERRATA_A710_2291219
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_a710_2291219_wa
+	mov	x30, x15
+#endif /* ERRATA_A710_2291219 */
+
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
@@ -513,6 +548,7 @@
 	report_errata ERRATA_A710_2008768, cortex_a710, 2008768
 	report_errata ERRATA_A710_2147715, cortex_a710, 2147715
 	report_errata ERRATA_A710_2216384, cortex_a710, 2216384
+	report_errata ERRATA_A710_2291219, cortex_a710, 2291219
 	report_errata ERRATA_A710_2371105, cortex_a710, 2371105
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a710, cve_2022_23960
 	report_errata ERRATA_DSU_2313941, cortex_a710, dsu_2313941
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index aa66e94..8cafe4a 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -236,6 +236,35 @@
 	ret
 endfunc check_errata_cve_2022_23960
 
+	/* --------------------------------------------------
+	 * Errata Workaround for Cortex A77 Errata #1800714.
+	 * This applies to revision <= r1p1 of Cortex A77.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * --------------------------------------------------
+	 */
+func errata_a77_1800714_wa
+	/* Compare x0 against revision <= r1p1 */
+	mov	x17, x30
+	bl	check_errata_1800714
+	cbz	x0, 1f
+
+	/* Disable allocation of splintered pages in the L2 TLB */
+	mrs	x1, CORTEX_A77_CPUECTLR_EL1
+	orr	x1, x1, CORTEX_A77_CPUECTLR_EL1_BIT_53
+	msr	CORTEX_A77_CPUECTLR_EL1, x1
+	isb
+1:
+	ret	x17
+endfunc errata_a77_1800714_wa
+
+func check_errata_1800714
+	/* Applies to everything <= r1p1 */
+	mov	x1, #0x11
+	b	cpu_rev_var_ls
+endfunc check_errata_1800714
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A77.
 	 * Shall clobber: x0-x19
@@ -280,6 +309,11 @@
 	msr	vbar_el3, x0
 #endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
 
+#if ERRATA_A77_1800714
+	mov	x0, x18
+	bl	errata_a77_1800714_wa
+#endif
+
 	isb
 	ret	x19
 endfunc cortex_a77_reset_func
@@ -315,9 +349,10 @@
 	 * checking functions of each errata.
 	 */
 	report_errata ERRATA_A77_1508412, cortex_a77, 1508412
+	report_errata ERRATA_A77_1791578, cortex_a77, 1791578
+	report_errata ERRATA_A77_1800714, cortex_a77, 1800714
 	report_errata ERRATA_A77_1925769, cortex_a77, 1925769
 	report_errata ERRATA_A77_1946167, cortex_a77, 1946167
-	report_errata ERRATA_A77_1791578, cortex_a77, 1791578
 	report_errata ERRATA_A77_2356587, cortex_a77, 2356587
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a77, cve_2022_23960
 
diff --git a/lib/cpus/aarch64/cortex_hunter_elp_arm.S b/lib/cpus/aarch64/cortex_hunter_elp_arm.S
new file mode 100644
index 0000000..5f86d4e
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_hunter_elp_arm.S
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_hunter_elp_arm.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex Hunter ELP must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex Hunter ELP supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+#if WORKAROUND_CVE_2022_23960
+        wa_cve_2022_23960_bhb_vector_table CORTEX_HUNTER_ELP_ARM_BHB_LOOP_COUNT, cortex_hunter_elp_arm
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_cve_2022_23960
+
+func cortex_hunter_elp_arm_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Cortex Hunter ELP generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_cortex_hunter_elp_arm
+	msr	vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
+	isb
+	ret
+endfunc cortex_hunter_elp_arm_reset_func
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_hunter_elp_arm_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_HUNTER_ELP_ARM_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_HUNTER_ELP_ARM_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_HUNTER_ELP_ARM_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_hunter_elp_arm_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex Hunter ELP. Must follow AAPCS.
+ */
+func cortex_hunter_elp_arm_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata WORKAROUND_CVE_2022_23960, cortex_hunter_elp_arm, cve_2022_23960
+
+	ldp	x8, x30, [sp], #16
+	ret
+endfunc cortex_hunter_elp_arm_errata_report
+#endif
+
+	/* ---------------------------------------------
+	 * This function provides Cortex Hunter ELP-specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_hunter_elp_arm_regs, "aS"
+cortex_hunter_elp_arm_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_hunter_elp_arm_cpu_reg_dump
+	adr	x6, cortex_hunter_elp_arm_regs
+	mrs	x8, CORTEX_HUNTER_ELP_ARM_CPUECTLR_EL1
+	ret
+endfunc cortex_hunter_elp_arm_cpu_reg_dump
+
+declare_cpu_ops cortex_hunter_elp_arm, CORTEX_HUNTER_ELP_ARM_MIDR, \
+	cortex_hunter_elp_arm_reset_func, \
+	cortex_hunter_elp_arm_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index f4d2df0..bf1b6ec 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -7,40 +7,47 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <common/bl_common.h>
-#include <cortex_makalu_elp_arm.h>
+#include <cortex_x3.h>
 #include <cpu_macros.S>
 #include <plat_macros.S>
 #include "wa_cve_2022_23960_bhb_vector.S"
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Makalu ELP must be compiled with HW_ASSISTED_COHERENCY enabled"
+#error "Cortex-X3 must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
 /* 64-bit only core */
 #if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Makalu ELP supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#error "Cortex-X3 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
 #if WORKAROUND_CVE_2022_23960
-	wa_cve_2022_23960_bhb_vector_table CORTEX_MAKALU_ELP_ARM_BHB_LOOP_COUNT, cortex_makalu_elp_arm
+	wa_cve_2022_23960_bhb_vector_table CORTEX_X3_BHB_LOOP_COUNT, cortex_x3
 #endif /* WORKAROUND_CVE_2022_23960 */
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
 	 */
-func cortex_makalu_elp_arm_core_pwr_dwn
+func cortex_x3_core_pwr_dwn
+#if ERRATA_X3_2313909
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_cortex_x3_2313909_wa
+	mov	x30, x15
+#endif /* ERRATA_X3_2313909 */
+
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	mrs	x0, CORTEX_MAKALU_ELP_ARM_CPUPWRCTLR_EL1
-	orr	x0, x0, #CORTEX_MAKALU_ELP_ARM_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	CORTEX_MAKALU_ELP_ARM_CPUPWRCTLR_EL1, x0
+	mrs	x0, CORTEX_X3_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_X3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_X3_CPUPWRCTLR_EL1, x0
 	isb
 	ret
-endfunc cortex_makalu_elp_arm_core_pwr_dwn
+endfunc cortex_x3_core_pwr_dwn
 
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
@@ -51,28 +58,56 @@
 	ret
 endfunc check_errata_cve_2022_23960
 
-func cortex_makalu_elp_arm_reset_func
+func cortex_x3_reset_func
 	/* Disable speculative loads */
 	msr	SSBS, xzr
 
 #if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
 	/*
-	 * The Cortex Makalu ELP generic vectors are overridden to apply
+	 * The Cortex-X3 generic vectors are overridden to apply
 	 * errata mitigation on exception entry from lower ELs.
          */
-	adr	x0, wa_cve_vbar_cortex_makalu_elp_arm
+	adr	x0, wa_cve_vbar_cortex_x3
 	msr	vbar_el3, x0
 #endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
 
 	isb
 	ret
-endfunc cortex_makalu_elp_arm_reset_func
+endfunc cortex_x3_reset_func
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex Makalu ELP. Must follow AAPCS.
+/* ----------------------------------------------------------------------
+ * Errata Workaround for Cortex-X3 Erratum 2313909 on power down request.
+ * This applies to revision r0p0 and r1p0 of Cortex-X3. Fixed in r1p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * ----------------------------------------------------------------------
  */
-func cortex_makalu_elp_arm_errata_report
+func errata_cortex_x3_2313909_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2313909
+	cbz	x0, 1f
+
+	/* Set bit 36 in ACTLR2_EL1 */
+	mrs	x1, CORTEX_X3_CPUACTLR2_EL1
+	orr	x1, x1, #CORTEX_X3_CPUACTLR2_EL1_BIT_36
+	msr	CORTEX_X3_CPUACTLR2_EL1, x1
+1:
+	ret	x17
+endfunc errata_cortex_x3_2313909_wa
+
+func check_errata_2313909
+	/* Applies to r0p0 and r1p0 */
+	mov	x1, #0x10
+	b	cpu_rev_var_ls
+endfunc check_errata_2313909
+
+#if REPORT_ERRATA
+	/*
+	 * Errata printing function for Cortex-X3. Must follow AAPCS.
+	 */
+func cortex_x3_errata_report
 	stp	x8, x30, [sp, #-16]!
 
 	bl	cpu_get_rev_var
@@ -82,15 +117,16 @@
 	 * Report all errata. The revision-variant information is passed to
 	 * checking functions of each errata.
 	 */
-	report_errata WORKAROUND_CVE_2022_23960, cortex_makalu_elp_arm, cve_2022_23960
+	report_errata ERRATA_X3_2313909, cortex_x3, 2313909
+	report_errata WORKAROUND_CVE_2022_23960, cortex_x3, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
 	ret
-endfunc cortex_makalu_elp_arm_errata_report
+endfunc cortex_x3_errata_report
 #endif
 
 	/* ---------------------------------------------
-	 * This function provides Cortex Makalu ELP-
+	 * This function provides Cortex-X3-
 	 * specific register information for crash
 	 * reporting. It needs to return with x6
 	 * pointing to a list of register names in ascii
@@ -98,16 +134,16 @@
 	 * reported.
 	 * ---------------------------------------------
 	 */
-.section .rodata.cortex_makalu_elp_arm_regs, "aS"
-cortex_makalu_elp_arm_regs:  /* The ascii list of register names to be reported */
+.section .rodata.cortex_x3_regs, "aS"
+cortex_x3_regs:  /* The ascii list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
 
-func cortex_makalu_elp_arm_cpu_reg_dump
-	adr	x6, cortex_makalu_elp_arm_regs
-	mrs	x8, CORTEX_MAKALU_ELP_ARM_CPUECTLR_EL1
+func cortex_x3_cpu_reg_dump
+	adr	x6, cortex_x3_regs
+	mrs	x8, CORTEX_X3_CPUECTLR_EL1
 	ret
-endfunc cortex_makalu_elp_arm_cpu_reg_dump
+endfunc cortex_x3_cpu_reg_dump
 
-declare_cpu_ops cortex_makalu_elp_arm, CORTEX_MAKALU_ELP_ARM_MIDR, \
-	cortex_makalu_elp_arm_reset_func, \
-	cortex_makalu_elp_arm_core_pwr_dwn
+declare_cpu_ops cortex_x3, CORTEX_X3_MIDR, \
+	cortex_x3_reset_func, \
+	cortex_x3_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_demeter.S b/lib/cpus/aarch64/neoverse_demeter.S
deleted file mode 100644
index 41cb4ee..0000000
--- a/lib/cpus/aarch64/neoverse_demeter.S
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <neoverse_demeter.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-#include "wa_cve_2022_23960_bhb_vector.S"
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Neoverse Demeter must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Neoverse Demeter supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-#if WORKAROUND_CVE_2022_23960
-	wa_cve_2022_23960_bhb_vector_table NEOVERSE_DEMETER_BHB_LOOP_COUNT, neoverse_demeter
-#endif /* WORKAROUND_CVE_2022_23960 */
-
-	/* ----------------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ----------------------------------------------------
-	 */
-func neoverse_demeter_core_pwr_dwn
-	/* ---------------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------------
-	 */
-	mrs	x0, NEOVERSE_DEMETER_CPUPWRCTLR_EL1
-	orr	x0, x0, #NEOVERSE_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	msr	NEOVERSE_DEMETER_CPUPWRCTLR_EL1, x0
-	isb
-	ret
-endfunc neoverse_demeter_core_pwr_dwn
-
-func check_errata_cve_2022_23960
-#if WORKAROUND_CVE_2022_23960
-	mov	x0, #ERRATA_APPLIES
-#else
-	mov	x0, #ERRATA_MISSING
-#endif
-	ret
-endfunc check_errata_cve_2022_23960
-
-func neoverse_demeter_reset_func
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-
-#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
-	/*
-	 * The Neoverse Demeter vectors are overridden to apply
-	 * errata mitigation on exception entry from lower ELs.
-	 */
-	adr	x0, wa_cve_vbar_neoverse_demeter
-	msr	vbar_el3, x0
-#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
-	isb
-	ret
-endfunc neoverse_demeter_reset_func
-
-#if REPORT_ERRATA
-/*
- * Errata printing function for Neoverse Demeter. Must follow AAPCS.
- */
-func neoverse_demeter_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata WORKAROUND_CVE_2022_23960, neoverse_demeter, cve_2022_23960
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc neoverse_demeter_errata_report
-#endif
-
-	/* ---------------------------------------------
-	 * This function provides Neoverse Demeter-
-	 * specific register information for crash
-	 * reporting. It needs to return with x6
-	 * pointing to a list of register names in ascii
-	 * and x8 - x15 having values of registers to be
-	 * reported.
-	 * ---------------------------------------------
-	 */
-.section .rodata.neoverse_demeter_regs, "aS"
-neoverse_demeter_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func neoverse_demeter_cpu_reg_dump
-	adr	x6, neoverse_demeter_regs
-	mrs	x8, NEOVERSE_DEMETER_CPUECTLR_EL1
-	ret
-endfunc neoverse_demeter_cpu_reg_dump
-
-declare_cpu_ops neoverse_demeter, NEOVERSE_DEMETER_MIDR, \
-	neoverse_demeter_reset_func, \
-	neoverse_demeter_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index a807b63..5861dec 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -338,6 +338,34 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2280757
 
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2326639.
+ * This applies to revision r0p0 of Neoverse N2,
+ * fixed in r0p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2326639_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2326639
+	cbz	x0, 1f
+
+	/* Set bit 36 in ACTLR2_EL1 */
+	mrs	x1, NEOVERSE_N2_CPUACTLR2_EL1
+	orr	x1, x1, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_36
+	msr	NEOVERSE_N2_CPUACTLR2_EL1, x1
+1:
+	ret	x17
+endfunc errata_n2_2326639_wa
+
+func check_errata_2326639
+	/* Applies to r0p0, fixed in r0p1 */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_2326639
 
 /* --------------------------------------------------
  * Errata Workaround for Neoverse N2 Erratum 2376738.
@@ -429,6 +457,10 @@
 	orr	x0, x0, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_2
 	msr	NEOVERSE_N2_CPUACTLR2_EL1, x0
 
+	/* Get the CPU revision and stash it in x18. */
+	bl	cpu_get_rev_var
+	mov	x18, x0
+
 #if ERRATA_DSU_2313941
 	bl	errata_dsu_2313941_wa
 #endif
@@ -510,9 +542,6 @@
 	msr	NEOVERSE_N2_CPUECTLR_EL1, x0
 #endif
 
-	bl	cpu_get_rev_var
-	mov	x18, x0
-
 #if ERRATA_N2_2002655
 	mov	x0, x18
 	bl	errata_n2_2002655_wa
@@ -532,6 +561,13 @@
 endfunc neoverse_n2_reset_func
 
 func neoverse_n2_core_pwr_dwn
+#if ERRATA_N2_2326639
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_n2_2326639_wa
+	mov	x30, x15
+#endif /* ERRATA_N2_2326639 */
+
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * No need to do cache maintenance here.
@@ -568,6 +604,7 @@
 	report_errata ERRATA_N2_2138958, neoverse_n2, 2138958
 	report_errata ERRATA_N2_2242400, neoverse_n2, 2242400
 	report_errata ERRATA_N2_2280757, neoverse_n2, 2280757
+	report_errata ERRATA_N2_2326639, neoverse_n2, 2326639
 	report_errata ERRATA_N2_2376738, neoverse_n2, 2376738
 	report_errata ERRATA_N2_2388450, neoverse_n2, 2388450
 	report_errata WORKAROUND_CVE_2022_23960, neoverse_n2, cve_2022_23960
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 109b725..3282fbc 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -508,8 +508,8 @@
 	report_errata ERRATA_V1_1925756, neoverse_v1, 1925756
 	report_errata ERRATA_V1_1940577, neoverse_v1, 1940577
 	report_errata ERRATA_V1_1966096, neoverse_v1, 1966096
-	report_errata ERRATA_V1_2139242, neoverse_v1, 2139242
 	report_errata ERRATA_V1_2108267, neoverse_v1, 2108267
+	report_errata ERRATA_V1_2139242, neoverse_v1, 2139242
 	report_errata ERRATA_V1_2216392, neoverse_v1, 2216392
 	report_errata ERRATA_V1_2294912, neoverse_v1, 2294912
 	report_errata ERRATA_V1_2372203, neoverse_v1, 2372203
@@ -527,6 +527,10 @@
 	msr	SSBS, xzr
 	isb
 
+	/* Get the CPU revision and stash it in x18. */
+	bl	cpu_get_rev_var
+	mov	x18, x0
+
 #if ERRATA_V1_1618635
 	mov x0, x18
 	bl errata_neoverse_v1_1618635_wa
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
new file mode 100644
index 0000000..4ea887f
--- /dev/null
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <neoverse_v2.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse V2 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Neoverse V2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V2_BHB_LOOP_COUNT, neoverse_v2
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func neoverse_v2_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, NEOVERSE_V2_CPUPWRCTLR_EL1
+	orr	x0, x0, #NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	NEOVERSE_V2_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc neoverse_v2_core_pwr_dwn
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_cve_2022_23960
+
+func neoverse_v2_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Neoverse V2 vectors are overridden to apply
+	 * errata mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_neoverse_v2
+	msr	vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+	isb
+	ret
+endfunc neoverse_v2_reset_func
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Neoverse V2. Must follow AAPCS.
+ */
+func neoverse_v2_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata WORKAROUND_CVE_2022_23960, neoverse_v2, cve_2022_23960
+
+	ldp	x8, x30, [sp], #16
+	ret
+endfunc neoverse_v2_errata_report
+#endif
+
+	/* ---------------------------------------------
+	 * This function provides Neoverse V2-
+	 * specific register information for crash
+	 * reporting. It needs to return with x6
+	 * pointing to a list of register names in ascii
+	 * and x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.neoverse_v2_regs, "aS"
+neoverse_v2_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func neoverse_v2_cpu_reg_dump
+	adr	x6, neoverse_v2_regs
+	mrs	x8, NEOVERSE_V2_CPUECTLR_EL1
+	ret
+endfunc neoverse_v2_cpu_reg_dump
+
+declare_cpu_ops neoverse_v2, NEOVERSE_V2_MIDR, \
+	neoverse_v2_reset_func, \
+	neoverse_v2_core_pwr_dwn
diff --git a/lib/cpus/aarch64/wa_cve_2022_23960_bhb.S b/lib/cpus/aarch64/wa_cve_2022_23960_bhb.S
index e0e41cc..ceb93f1 100644
--- a/lib/cpus/aarch64/wa_cve_2022_23960_bhb.S
+++ b/lib/cpus/aarch64/wa_cve_2022_23960_bhb.S
@@ -9,11 +9,11 @@
 #if WORKAROUND_CVE_2022_23960
 	/*
 	 * This macro applies the mitigation for CVE-2022-23960.
-         * The macro saves x2-x3 to the CPU context.
+         * The macro saves x2 to the CPU context.
          * SP should point to the CPU context.
 	 */
 	.macro	apply_cve_2022_23960_bhb_wa _bhb_loop_count
-	stp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
+	str	x2, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
 
 	/* CVE-BHB-NUM loop count */
 	mov	x2, \_bhb_loop_count
@@ -24,8 +24,7 @@
 2:
 	subs	x2, x2, #1
 	bne	1b
-	dsb	sy
-	isb
-	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
+	speculation_barrier
+	ldr	x2, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
 	.endm
 #endif /* WORKAROUND_CVE_2022_23960 */
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 08871f8..b4421dd 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -307,6 +307,10 @@
 # to revisions r0p0, r1p0, and r1p1, it is still open.
 ERRATA_A77_2356587	?=0
 
+# Flag to apply erratum 1800714 workaround during reset. This erratum applies
+# to revisions <= r1p1 of the Cortex A77 cpu.
+ERRATA_A77_1800714	?=0
+
 # Flag to apply erratum 1688305 workaround during reset. This erratum applies
 # to revisions r0p0 - r1p0 of the A78 cpu.
 ERRATA_A78_1688305	?=0
@@ -544,6 +548,10 @@
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
 ERRATA_A710_2282622	?=0
 
+# Flag to apply erratum 2291219 workaround during reset. This erratum applies
+# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
+ERRATA_A710_2291219	?=0
+
 # Flag to apply erratum 2008768 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
 ERRATA_A710_2008768	?=0
@@ -588,6 +596,10 @@
 # to revision r0p0 of the Neoverse N2 cpu and is still open.
 ERRATA_N2_2280757	?=0
 
+# Flag to apply erraturm 2326639 workaroud during powerdown. This erratum
+# applies to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
+ERRATA_N2_2326639	?=0
+
 # Flag to apply erratum 2376738 workaround during reset. This erratum applies
 # to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
 ERRATA_N2_2376738	?=0
@@ -631,6 +643,10 @@
 # to revision r0p0, r1p0 and r2p0 of the Cortex-X2 cpu and is fixed in r2p1.
 ERRATA_X2_2371105	?=0
 
+# Flag to apply erratum 2313909 workaround on powerdown. This erratum applies
+# to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
+ERRATA_X3_2313909	?=0
+
 # Flag to apply erratum 1922240 workaround during reset. This erratum applies
 # to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
 ERRATA_A510_1922240	?=0
@@ -670,6 +686,10 @@
 # to revisions r0p0, r0p1, r0p2, r0p3, r1p0, and r1p1. It is fixed in r1p2.
 ERRATA_A510_2371937	?=0
 
+# Flag to apply erratum 2666669 workaround during reset. This erratum applies
+# to revisions r0p0, r0p1, r0p2, r0p3, r1p0, and r1p1. It is fixed in r1p2.
+ERRATA_A510_2666669	?=0
+
 # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
 # Applying the workaround results in higher DSU power consumption on idle.
 ERRATA_DSU_798953	?=0
@@ -912,6 +932,10 @@
 $(eval $(call assert_boolean,ERRATA_A77_2356587))
 $(eval $(call add_define,ERRATA_A77_2356587))
 
+# Process ERRATA_A77_1800714 flag
+$(eval $(call assert_boolean,ERRATA_A77_1800714))
+$(eval $(call add_define,ERRATA_A77_1800714))
+
 # Process ERRATA_A78_1688305 flag
 $(eval $(call assert_boolean,ERRATA_A78_1688305))
 $(eval $(call add_define,ERRATA_A78_1688305))
@@ -1144,6 +1168,10 @@
 $(eval $(call assert_boolean,ERRATA_A710_2282622))
 $(eval $(call add_define,ERRATA_A710_2282622))
 
+# Process ERRATA_A710_2291219 flag
+$(eval $(call assert_boolean,ERRATA_A710_2291219))
+$(eval $(call add_define,ERRATA_A710_2291219))
+
 # Process ERRATA_A710_2008768 flag
 $(eval $(call assert_boolean,ERRATA_A710_2008768))
 $(eval $(call add_define,ERRATA_A710_2008768))
@@ -1188,6 +1216,10 @@
 $(eval $(call assert_boolean,ERRATA_N2_2280757))
 $(eval $(call add_define,ERRATA_N2_2280757))
 
+# Process ERRATA_N2_2326639 flag
+$(eval $(call assert_boolean,ERRATA_N2_2326639))
+$(eval $(call add_define,ERRATA_N2_2326639))
+
 # Process ERRATA_N2_2376738 flag
 $(eval $(call assert_boolean,ERRATA_N2_2376738))
 $(eval $(call add_define,ERRATA_N2_2376738))
@@ -1228,6 +1260,10 @@
 $(eval $(call assert_boolean,ERRATA_X2_2371105))
 $(eval $(call add_define,ERRATA_X2_2371105))
 
+# Process ERRATA_X3_2313909 flag
+$(eval $(call assert_boolean,ERRATA_X3_2313909))
+$(eval $(call add_define,ERRATA_X3_2313909))
+
 # Process ERRATA_A510_1922240 flag
 $(eval $(call assert_boolean,ERRATA_A510_1922240))
 $(eval $(call add_define,ERRATA_A510_1922240))
@@ -1264,7 +1300,11 @@
 $(eval $(call assert_boolean,ERRATA_A510_2371937))
 $(eval $(call add_define,ERRATA_A510_2371937))
 
-# Process ERRATA_DSU_798953 flag
+# Process ERRATA_A510_2666669 flag
+$(eval $(call assert_boolean,ERRATA_A510_2666669))
+$(eval $(call add_define,ERRATA_A510_2666669))
+
+#Process ERRATA_DSU_798953 flag
 $(eval $(call assert_boolean,ERRATA_DSU_798953))
 $(eval $(call add_define,ERRATA_DSU_798953))
 
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index acfef80..6b88a90 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -806,9 +806,9 @@
 /* ------------------------------------------------------------------
  * The following macro is used to save and restore all the general
  * purpose and ARMv8.3-PAuth (if enabled) registers.
- * It also checks if Secure Cycle Counter is not disabled in MDCR_EL3
- * when ARMv8.5-PMU is implemented, and if called from Non-secure
- * state saves PMCR_EL0 and disables Cycle Counter.
+ * It also checks if the Secure Cycle Counter (PMCCNTR_EL0)
+ * is disabled in EL3/Secure (ARMv8.5-PMU), wherein PMCCNTR_EL0
+ * needs not to be saved/restored during world switch.
  *
  * Ideally we would only save and restore the callee saved registers
  * when a world switch occurs but that type of implementation is more
@@ -837,9 +837,17 @@
 	str	x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0]
 
 	/* ----------------------------------------------------------
-	 * Check if earlier initialization MDCR_EL3.SCCD/MCCD to 1
-	 * failed, meaning that FEAT_PMUv3p5/7 is not implemented and
-	 * PMCR_EL0 should be saved in non-secure context.
+	 * Check if earlier initialization of MDCR_EL3.SCCD/MCCD to 1
+	 * has failed.
+	 *
+	 * MDCR_EL3:
+	 * MCCD bit set, Prohibits the Cycle Counter PMCCNTR_EL0 from
+	 * counting at EL3.
+	 * SCCD bit set, Secure Cycle Counter Disable. Prohibits PMCCNTR_EL0
+	 * from counting in Secure state.
+	 * If these bits are not set, meaning that FEAT_PMUv3p5/7 is
+	 * not implemented and PMCR_EL0 should be saved in non-secure
+	 * context.
 	 * ----------------------------------------------------------
 	 */
 	mov_imm	x10, (MDCR_SCCD_BIT | MDCR_MCCD_BIT)
@@ -847,7 +855,13 @@
 	tst	x9, x10
 	bne	1f
 
-	/* Secure Cycle Counter is not disabled */
+	/* ----------------------------------------------------------
+	 * If control reaches here, it ensures the Secure Cycle
+	 * Counter (PMCCNTR_EL0) is not prohibited from counting at
+	 * EL3 and in secure states.
+	 * Henceforth, PMCR_EL0 to be saved before world switch.
+	 * ----------------------------------------------------------
+	 */
 	mrs	x9, pmcr_el0
 
 	/* Check caller's security state */
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 68aacc1..8213cbe 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +16,7 @@
 #include <arch_features.h>
 #include <bl31/interrupt_mgmt.h>
 #include <common/bl_common.h>
+#include <common/debug.h>
 #include <context.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/el3_runtime/context_mgmt.h>
@@ -204,6 +206,17 @@
 	/* Allow access to Allocation Tags when MTE is implemented. */
 	scr_el3 |= SCR_ATA_BIT;
 
+#if RAS_TRAP_NS_ERR_REC_ACCESS
+	/*
+	 * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR
+	 * and RAS ERX registers from EL1 and EL2(from any security state)
+	 * are trapped to EL3.
+	 * Set here to trap only for NS EL1/EL2
+	 *
+	 */
+	scr_el3 |= SCR_TERR_BIT;
+#endif
+
 #ifdef IMAGE_BL31
 	/*
 	 * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
@@ -229,14 +242,11 @@
 			sctlr_el2);
 
 	/*
-	 * The GICv3 driver initializes the ICC_SRE_EL2 register during
-	 * platform setup. Use the same setting for the corresponding
-	 * context register to make sure the correct bits are set when
-	 * restoring NS context.
+	 * Program the ICC_SRE_EL2 to make sure the correct bits are set
+	 * when restoring NS context.
 	 */
-	u_register_t icc_sre_el2 = read_icc_sre_el2();
-	icc_sre_el2 |= (ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT);
-	icc_sre_el2 |= (ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT);
+	u_register_t icc_sre_el2 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
+				   ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
 	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_ICC_SRE_EL2,
 			icc_sre_el2);
 #endif /* CTX_INCLUDE_EL2_REGS */
@@ -307,14 +317,6 @@
 	scr_el3 |= SCR_TRNDR_BIT;
 #endif
 
-#if RAS_TRAP_LOWER_EL_ERR_ACCESS
-	/*
-	 * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR
-	 * and RAS ERX registers from EL1 and EL2 are trapped to EL3.
-	 */
-	scr_el3 |= SCR_TERR_BIT;
-#endif
-
 #if !HANDLE_EA_EL3_FIRST
 	/*
 	 * SCR_EL3.EA: Do not route External Abort and SError Interrupt External
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index 958b623..ec8cca8 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -58,6 +58,7 @@
 	/* Set CPTR_EL3.ESM bit so we can write SMCR_EL3 without trapping. */
 	cptr_el3 = read_cptr_el3();
 	write_cptr_el3(cptr_el3 | ESM_BIT);
+	isb();
 
 	/*
 	 * Set the max LEN value and FA64 bit. This register is set up globally
@@ -73,6 +74,7 @@
 
 	/* Reset CPTR_EL3 value. */
 	write_cptr_el3(cptr_el3);
+	isb();
 
 	/* Enable SVE/FPU in addition to SME. */
 	sve_enable(context);
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
index 3038c09..351772e 100644
--- a/lib/fconf/fconf_dyn_cfg_getter.c
+++ b/lib/fconf/fconf_dyn_cfg_getter.c
@@ -12,6 +12,8 @@
 #include <lib/object_pool.h>
 #include <libfdt.h>
 
+#include <platform_def.h>
+
 /* We currently use FW, TB_FW, SOC_FW, TOS_FW, NT_FW and HW configs  */
 #define MAX_DTB_INFO	U(6)
 /*
diff --git a/lib/libc/assert.c b/lib/libc/assert.c
index c199de6..8973ed5 100644
--- a/lib/libc/assert.c
+++ b/lib/libc/assert.c
@@ -17,16 +17,7 @@
  * LOG_LEVEL_INFO, which is the default value for builds with DEBUG=1.
  */
 
-#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
-void __dead2 __assert(const char *file, unsigned int line,
-		      const char *assertion)
-{
-	printf("ASSERT: %s:%u:%s\n", file, line, assertion);
-	backtrace("assert");
-	console_flush();
-	plat_panic_handler();
-}
-#elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
+#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
 void __dead2 __assert(const char *file, unsigned int line)
 {
 	printf("ASSERT: %s:%u\n", file, line);
diff --git a/lib/libc/printf.c b/lib/libc/printf.c
index 45e153e..e52cbed 100644
--- a/lib/libc/printf.c
+++ b/lib/libc/printf.c
@@ -7,9 +7,9 @@
 #include <assert.h>
 #include <stdarg.h>
 #include <stdbool.h>
+#include <stddef.h>
 #include <stdint.h>
-
-#include <common/debug.h>
+#include <stdio.h>
 
 #define get_num_va_args(_args, _lcount)				\
 	(((_lcount) > 1)  ? va_arg(_args, long long int) :	\
@@ -43,6 +43,12 @@
 	int i = 0, count = 0;
 	unsigned int rem;
 
+	/* num_buf is only large enough for radix >= 10 */
+	if (radix < 10) {
+		assert(0);
+		return 0;
+	}
+
 	do {
 		rem = unum % radix;
 		if (rem < 0xa)
diff --git a/lib/libc/putchar.c b/lib/libc/putchar.c
index 037e28a..3472b24 100644
--- a/lib/libc/putchar.c
+++ b/lib/libc/putchar.c
@@ -6,15 +6,9 @@
 
 #include <stdio.h>
 
-#include <drivers/console.h>
-
-int putchar(int c)
+int __putchar(int c)
 {
-	int res;
-	if (console_putc((unsigned char)c) >= 0)
-		res = c;
-	else
-		res = EOF;
-
-	return res;
+	return c;
 }
+
+int putchar(int c) __attribute__((weak,alias("__putchar")));
diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c
index 12f51c0..6a2f0ba 100644
--- a/lib/libc/snprintf.c
+++ b/lib/libc/snprintf.c
@@ -6,11 +6,10 @@
 
 #include <assert.h>
 #include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
 #include <stdint.h>
 
-#include <common/debug.h>
-#include <plat/common/platform.h>
-
 #define get_num_va_args(_args, _lcount)				\
 	(((_lcount) > 1)  ? va_arg(_args, long long int) :	\
 	(((_lcount) == 1) ? va_arg(_args, long int) :		\
@@ -51,10 +50,10 @@
 	unsigned int rem;
 	char ascii_a = capitalise ? 'A' : 'a';
 
+	/* num_buf is only large enough for radix >= 10 */
 	if (radix < 10) {
-		ERROR("snprintf: unsupported radix '%u'.", radix);
-		plat_panic_handler();
-		assert(0); /* Unreachable */
+		assert(0);
+		return;
 	}
 
 	do {
@@ -218,11 +217,8 @@
 				break;
 
 			default:
-				/* Panic on any other format specifier. */
-				ERROR("snprintf: specifier with ASCII code '%d' not supported.",
-				      *fmt);
-				plat_panic_handler();
-				assert(0); /* Unreachable */
+				CHECK_AND_PUT_CHAR(s, n, chars_printed, '%');
+				CHECK_AND_PUT_CHAR(s, n, chars_printed, *fmt);
 			}
 			fmt++;
 			continue;
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index d30248f..6c87b0d 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -9,6 +9,8 @@
 #include <common/debug.h>
 #include <lib/optee_utils.h>
 
+#include <platform_def.h>
+
 /*
  * load_addr_hi and load_addr_lo: image load address.
  * image_id: 0 - pager, 1 - paged
diff --git a/lib/psa/initial_attestation.c b/lib/psa/delegated_attestation.c
similarity index 69%
rename from lib/psa/initial_attestation.c
rename to lib/psa/delegated_attestation.c
index 44498a8..399a3f1 100644
--- a/lib/psa/initial_attestation.c
+++ b/lib/psa/delegated_attestation.c
@@ -1,34 +1,73 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
  */
 
-#include <initial_attestation.h>
+#include <string.h>
+
+#include <delegated_attestation.h>
 #include <psa/client.h>
 #include <psa_manifest/sid.h>
 
 #if !PLAT_RSS_NOT_SUPPORTED
 psa_status_t
-psa_initial_attest_get_token(const uint8_t *auth_challenge,
-			     size_t         challenge_size,
-			     uint8_t       *token_buf,
-			     size_t         token_buf_size,
-			     size_t        *token_size)
+rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+				       uint32_t  key_bits,
+				       uint8_t  *key_buf,
+				       size_t    key_buf_size,
+				       size_t   *key_size,
+				       uint32_t  hash_algo)
 {
 	psa_status_t status;
 	psa_invec in_vec[] = {
-		{auth_challenge, challenge_size}
+		{&ecc_curve, sizeof(ecc_curve)},
+		{&key_bits,  sizeof(key_bits)},
+		{&hash_algo, sizeof(hash_algo)}
 	};
 	psa_outvec out_vec[] = {
-		{token_buf, token_buf_size},
+		{key_buf, key_buf_size}
 	};
 
-	status = psa_call(RSS_ATTESTATION_SERVICE_HANDLE, RSS_ATTEST_GET_TOKEN,
-			  in_vec, IOVEC_LEN(in_vec),
+	if (key_size == NULL) {
+		return PSA_ERROR_INVALID_ARGUMENT;
+	}
+
+	status = psa_call(RSS_DELEGATED_SERVICE_HANDLE,
+			  RSS_DELEGATED_ATTEST_GET_DELEGATED_KEY,
+			  in_vec,  IOVEC_LEN(in_vec),
 			  out_vec, IOVEC_LEN(out_vec));
+	if (status == PSA_SUCCESS) {
+		*key_size = out_vec[0].len;
+	}
+
+	return status;
+}
+
+psa_status_t
+rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+			       size_t         dak_pub_hash_size,
+			       uint8_t       *token_buf,
+			       size_t         token_buf_size,
+			       size_t        *token_size)
+{
+	psa_status_t status;
+	psa_invec in_vec[] = {
+		{dak_pub_hash, dak_pub_hash_size}
+	};
+	psa_outvec out_vec[] = {
+		{token_buf, token_buf_size}
+	};
+
+	if (token_size == NULL) {
+		return PSA_ERROR_INVALID_ARGUMENT;
+	}
 
+	status = psa_call(RSS_DELEGATED_SERVICE_HANDLE,
+			  RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN,
+			  in_vec, IOVEC_LEN(in_vec),
+			  out_vec, IOVEC_LEN(out_vec));
 	if (status == PSA_SUCCESS) {
 		*token_size = out_vec[0].len;
 	}
@@ -36,9 +75,16 @@
 	return status;
 }
 
+
 #else /* !PLAT_RSS_NOT_SUPPORTED */
 
-#include <string.h>
+static const uint8_t delegated_key[] = {
+	0x20, 0x11, 0xC7, 0xF0, 0x3C, 0xEE, 0x43, 0x25, 0x17, 0x6E,
+	0x52, 0x4F, 0x03, 0x3C, 0x0C, 0xE1, 0xE2, 0x1A, 0x76, 0xE6,
+	0xC1, 0xA4, 0xF0, 0xB8, 0x39, 0xAA, 0x1D, 0xF6, 0x1E, 0x0E,
+	0x8A, 0x5C, 0x8A, 0x05, 0x74, 0x0F, 0x9B, 0x69, 0xEF, 0xA7,
+	0xEB, 0x1A, 0x41, 0x85, 0xBD, 0x11, 0x7F, 0x68
+};
 
 static const uint8_t platform_token[] = {
 	0xD2, 0x84, 0x43, 0xA1, 0x01, 0x26, 0xA0, 0x59,
@@ -141,15 +187,36 @@
 	0x62, 0xBB
 };
 
+psa_status_t
+rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+				       uint32_t  key_bits,
+				       uint8_t  *key_buf,
+				       size_t    key_buf_size,
+				       size_t   *key_size,
+				       uint32_t  hash_algo)
+{
+	(void)ecc_curve;
+	(void)key_bits;
+	(void)hash_algo;
+
+	if (key_buf_size < sizeof(delegated_key)) {
+		return PSA_ERROR_BUFFER_TOO_SMALL;
+	}
+
+	(void)memcpy(key_buf, delegated_key, sizeof(delegated_key));
+	*key_size = sizeof(delegated_key);
+
+	return PSA_SUCCESS;
+}
 psa_status_t
-psa_initial_attest_get_token(const uint8_t *auth_challenge,
-			     size_t         challenge_size,
-			     uint8_t       *token_buf,
-			     size_t         token_buf_size,
-			     size_t        *token_size)
+rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+			       size_t         dak_pub_hash_size,
+			       uint8_t       *token_buf,
+			       size_t         token_buf_size,
+			       size_t        *token_size)
 {
-	(void)auth_challenge;
-	(void)challenge_size;
+	(void)dak_pub_hash;
+	(void)dak_pub_hash_size;
 
 	if (token_buf_size < sizeof(platform_token)) {
 		return PSA_ERROR_BUFFER_TOO_SMALL;
diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c
index 90e4ef3..6e9ff78 100644
--- a/lib/psa/measured_boot.c
+++ b/lib/psa/measured_boot.c
@@ -39,8 +39,10 @@
 			    const uint8_t *signer_id,
 			    size_t signer_id_size,
 			    const uint8_t *version,     /* string */
-			    uint32_t measurement_algo,
+			    size_t version_size,
 			    const uint8_t *sw_type,     /* string */
+			    size_t sw_type_size,
+			    uint32_t measurement_algo,
 			    const uint8_t *measurement_value,
 			    size_t measurement_value_size,
 			    bool lock_measurement)
@@ -49,9 +51,11 @@
 	INFO(" - slot        : %u\n", index);
 	INFO(" - signer_id   :");
 	print_byte_array(signer_id, signer_id_size);
-	INFO(" - version     : %s\n", version);
+	INFO(" - version     : %s\n",  version);
+	INFO(" - version_size: %zu\n", version_size);
+	INFO(" - sw_type     : %s\n",  sw_type);
+	INFO(" - sw_type_size: %zu\n", sw_type_size);
 	INFO(" - algorithm   : %x\n", measurement_algo);
-	INFO(" - sw_type     : %s\n", sw_type);
 	INFO(" - measurement :");
 	print_byte_array(measurement_value, measurement_value_size);
 	INFO(" - locking     : %s\n", lock_measurement ? "true" : "false");
@@ -87,18 +91,17 @@
 		{.base = measurement_value, .len = measurement_value_size}
 	};
 
-	uint32_t sw_type_size_limited;
-
 	if (sw_type != NULL) {
-		sw_type_size_limited = (sw_type_size < SW_TYPE_MAX_SIZE) ?
-					sw_type_size : SW_TYPE_MAX_SIZE;
-		memcpy(extend_iov.sw_type, sw_type, sw_type_size_limited);
+		if (sw_type_size > SW_TYPE_MAX_SIZE) {
+			return PSA_ERROR_INVALID_ARGUMENT;
+		}
+		memcpy(extend_iov.sw_type, sw_type, sw_type_size);
 	}
 
 	log_measurement(index, signer_id, signer_id_size,
-			version, measurement_algo, sw_type,
-			measurement_value, measurement_value_size,
-			lock_measurement);
+			version, version_size, sw_type, sw_type_size,
+			measurement_algo, measurement_value,
+			measurement_value_size, lock_measurement);
 
 	return psa_call(RSS_MEASURED_BOOT_HANDLE,
 			RSS_MEASURED_BOOT_EXTEND,
@@ -122,9 +125,9 @@
 				     bool lock_measurement)
 {
 	log_measurement(index, signer_id, signer_id_size,
-			version, measurement_algo, sw_type,
-			measurement_value, measurement_value_size,
-			lock_measurement);
+			version, version_size, sw_type, sw_type_size,
+			measurement_algo, measurement_value,
+			measurement_value_size, lock_measurement);
 
 	return PSA_SUCCESS;
 }
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index b60ddbb..8d736cc 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -156,25 +156,26 @@
 /*******************************************************************************
  * This function verifies that the all the other cores in the system have been
  * turned OFF and the current CPU is the last running CPU in the system.
- * Returns 1 (true) if the current CPU is the last ON CPU or 0 (false)
- * otherwise.
+ * Returns true, if the current CPU is the last ON CPU or false otherwise.
  ******************************************************************************/
-unsigned int psci_is_last_on_cpu(void)
+bool psci_is_last_on_cpu(void)
 {
 	unsigned int cpu_idx, my_idx = plat_my_core_pos();
 
-	for (cpu_idx = 0; cpu_idx < psci_plat_core_count;
-			cpu_idx++) {
+	for (cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
 		if (cpu_idx == my_idx) {
 			assert(psci_get_aff_info_state() == AFF_STATE_ON);
 			continue;
 		}
 
-		if (psci_get_aff_info_state_by_idx(cpu_idx) != AFF_STATE_OFF)
-			return 0;
+		if (psci_get_aff_info_state_by_idx(cpu_idx) != AFF_STATE_OFF) {
+			VERBOSE("core=%u other than current core=%u %s\n",
+				cpu_idx, my_idx, "running in the system");
+			return false;
+		}
 	}
 
-	return 1;
+	return true;
 }
 
 /*******************************************************************************
@@ -954,7 +955,7 @@
  * Initiate power down sequence, by calling power down operations registered for
  * this CPU.
  ******************************************************************************/
-void psci_do_pwrdown_sequence(unsigned int power_level)
+void psci_pwrdown_cpu(unsigned int power_level)
 {
 #if HW_ASSISTED_COHERENCY
 	/*
@@ -1009,11 +1010,11 @@
 
 	/* Need to wait for other cores to shutdown */
 	if (wait_ms != 0U) {
-		while ((wait_ms-- != 0U) && (psci_is_last_on_cpu() != 0U)) {
+		while ((wait_ms-- != 0U) && (!psci_is_last_on_cpu())) {
 			mdelay(1U);
 		}
 
-		if (psci_is_last_on_cpu() != 0U) {
+		if (!psci_is_last_on_cpu()) {
 			WARN("Failed to stop all cores!\n");
 			psci_print_power_domain_map();
 			return PSCI_E_DENIED;
@@ -1030,48 +1031,22 @@
  *
  * This API has following differences with psci_is_last_on_cpu
  *  1. PSCI states are locked
- *  2. It caters for "forest" topology instead of just "tree"
- *  TODO : Revisit both API's and unify them
  ******************************************************************************/
 bool psci_is_last_on_cpu_safe(void)
 {
 	unsigned int this_core = plat_my_core_pos();
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
-	unsigned int i = 0;
-
-	/*
-	 * Traverse the forest of PSCI nodes, nodes with no parents
-	 * (invalid-nodes) are the root nodes.
-	 */
-	while ((i < PSCI_NUM_NON_CPU_PWR_DOMAINS) &&
-	       (psci_non_cpu_pd_nodes[i].parent_node ==
-	       PSCI_PARENT_NODE_INVALID)) {
-		psci_get_parent_pwr_domain_nodes(
-				psci_non_cpu_pd_nodes[i].cpu_start_idx,
-				PLAT_MAX_PWR_LVL, parent_nodes);
 
-		psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+	psci_get_parent_pwr_domain_nodes(this_core, PLAT_MAX_PWR_LVL, parent_nodes);
 
-		for (unsigned int core = 0U;
-		     core < psci_non_cpu_pd_nodes[i].ncpus; core++) {
-			if (core == this_core) {
-				continue;
-			}
+	psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
 
-			if (psci_get_aff_info_state_by_idx(core) !=
-			    AFF_STATE_OFF) {
-				psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL,
-							      parent_nodes);
-				VERBOSE("core=%u other than boot core=%u %s\n",
-				       core, this_core, "running in the system");
-
-				return false;
-			}
-		}
-
+	if (!psci_is_last_on_cpu()) {
 		psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
-		i++;
+		return false;
 	}
 
+	psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+
 	return true;
 }
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 52a8b8a..a631f3f 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -158,7 +158,7 @@
 	entry_point_info_t ep;
 
 	/* Check if the current CPU is the last ON CPU in the system */
-	if (psci_is_last_on_cpu() == 0U)
+	if (!psci_is_last_on_cpu())
 		return PSCI_E_DENIED;
 
 	/* Validate the entry point and get the entry_point_info */
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index 5447045..637adb9 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -109,7 +109,7 @@
 	/*
 	 * Arch. management. Initiate power down sequence.
 	 */
-	psci_do_pwrdown_sequence(psci_find_max_off_lvl(&state_info));
+	psci_pwrdown_cpu(psci_find_max_off_lvl(&state_info));
 
 #if ENABLE_RUNTIME_INSTRUMENTATION
 	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 61bd966..1901c17 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -294,9 +294,8 @@
 unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info);
 void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl);
 void psci_print_power_domain_map(void);
-unsigned int psci_is_last_on_cpu(void);
+bool psci_is_last_on_cpu(void);
 int psci_spd_migrate_info(u_register_t *mpidr);
-void psci_do_pwrdown_sequence(unsigned int power_level);
 
 /*
  * CPU power down is directly called only when HW_ASSISTED_COHERENCY is
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index ffe3a91..f71994d 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -124,7 +124,7 @@
 	 * TODO : Introduce a mechanism to query the cache level to flush
 	 * and the cpu-ops power down to perform from the platform.
 	 */
-	psci_do_pwrdown_sequence(max_off_lvl);
+	psci_pwrdown_cpu(max_off_lvl);
 
 #if ENABLE_RUNTIME_INSTRUMENTATION
 	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
diff --git a/lib/semihosting/semihosting.c b/lib/semihosting/semihosting.c
index e0845c1..163a82d 100644
--- a/lib/semihosting/semihosting.c
+++ b/lib/semihosting/semihosting.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -64,8 +64,10 @@
 
 	result = semihosting_call(SEMIHOSTING_SYS_SEEK, (uintptr_t)&seek_block);
 
-	if (result != 0) {
+	if (result < 0) {
 		result = semihosting_call(SEMIHOSTING_SYS_ERRNO, 0);
+	} else  {
+		result = 0;
 	}
 
 	return result;
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 5e73120..65ceb7f 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -413,8 +413,8 @@
 # Select workaround for AT speculative behaviour.
 ERRATA_SPECULATIVE_AT		:= 0
 
-# Trap RAS error record access from lower EL
-RAS_TRAP_LOWER_EL_ERR_ACCESS	:= 0
+# Trap RAS error record access from Non secure
+RAS_TRAP_NS_ERR_REC_ACCESS	:= 0
 
 # Build option to create cot descriptors using fconf
 COT_DESC_IN_DTB			:= 0
diff --git a/package-lock.json b/package-lock.json
index 34e7dbd..bc86b9b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,29 +24,38 @@
       }
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
-      "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
       "dev": true,
       "dependencies": {
-        "@babel/highlight": "^7.12.13"
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.14.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
-      "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
-      "dev": true
+      "version": "7.19.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.14.0",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
-      "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.14.0",
+        "@babel/helper-validator-identifier": "^7.18.6",
         "chalk": "^2.0.0",
         "js-tokens": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/highlight/node_modules/ansi-styles": {
@@ -87,13 +96,13 @@
     "node_modules/@babel/highlight/node_modules/color-name": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
       "dev": true
     },
     "node_modules/@babel/highlight/node_modules/has-flag": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -112,16 +121,16 @@
       }
     },
     "node_modules/@commitlint/cli": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.1.0.tgz",
-      "integrity": "sha512-x5L1knvA3isRWBRVQx+Q6D45pA9139a2aZQYpxkljMG0dj4UHZkCnsYWpnGalxPxASI7nrI0KedKfS2YeQ55cQ==",
+      "version": "16.3.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.3.0.tgz",
+      "integrity": "sha512-P+kvONlfsuTMnxSwWE1H+ZcPMY3STFaHb2kAacsqoIkNx66O0T7sTpBxpxkMrFPyhkJiLJnJWMhk4bbvYD3BMA==",
       "dev": true,
       "dependencies": {
-        "@commitlint/format": "^16.0.0",
-        "@commitlint/lint": "^16.0.0",
-        "@commitlint/load": "^16.1.0",
-        "@commitlint/read": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/format": "^16.2.1",
+        "@commitlint/lint": "^16.2.4",
+        "@commitlint/load": "^16.3.0",
+        "@commitlint/read": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "lodash": "^4.17.19",
         "resolve-from": "5.0.0",
         "resolve-global": "1.0.0",
@@ -135,9 +144,9 @@
       }
     },
     "node_modules/@commitlint/config-conventional": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.0.0.tgz",
-      "integrity": "sha512-mN7J8KlKFn0kROd+q9PB01sfDx/8K/R25yITspL1No8PB4oj9M1p77xWjP80hPydqZG9OvQq+anXK3ZWeR7s3g==",
+      "version": "16.2.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.2.4.tgz",
+      "integrity": "sha512-av2UQJa3CuE5P0dzxj/o/B9XVALqYzEViHrMXtDrW9iuflrqCStWBAioijppj9URyz6ONpohJKAtSdgAOE0gkA==",
       "dev": true,
       "dependencies": {
         "conventional-changelog-conventionalcommits": "^4.3.1"
@@ -147,12 +156,12 @@
       }
     },
     "node_modules/@commitlint/config-validator": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.1.0.tgz",
-      "integrity": "sha512-2cHeZPNTuf1JWbMqyA46MkExor5HMSgv8JrdmzEakUbJHUreh35/wN00FJf57qGs134exQW2thiSQ1IJUsVx2Q==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.2.1.tgz",
+      "integrity": "sha512-hogSe0WGg7CKmp4IfNbdNES3Rq3UEI4XRPB8JL4EPgo/ORq5nrGTVzxJh78omibNuB8Ho4501Czb1Er1MoDWpw==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "ajv": "^6.12.6"
       },
       "engines": {
@@ -160,20 +169,20 @@
       }
     },
     "node_modules/@commitlint/cz-commitlint": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-16.1.0.tgz",
-      "integrity": "sha512-TThglfXEBW8TZ99dvaeto1c6hU25ONqL9qkENle2+1OFI64NgbICjLsJq7SVzJd4Jn/yZDp4xNqoV53WJPJ9aA==",
+      "version": "16.3.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-16.3.0.tgz",
+      "integrity": "sha512-Q+QLQmSIHEgzI18F3/7mqq3vwL0IN9k+Tjp9Um4adFnRXMtUTnEa0er0CXAXxWvoA/x/6nt3t7faAv2HugDIGg==",
       "dev": true,
       "dependencies": {
-        "@commitlint/ensure": "^16.0.0",
-        "@commitlint/load": "^16.1.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/ensure": "^16.2.1",
+        "@commitlint/load": "^16.3.0",
+        "@commitlint/types": "^16.2.1",
         "chalk": "^4.1.0",
         "lodash": "^4.17.21",
         "word-wrap": "^1.2.3"
       },
       "engines": {
-        "node": ">= 10"
+        "node": ">=v12"
       },
       "peerDependencies": {
         "commitizen": "^4.0.3",
@@ -181,12 +190,12 @@
       }
     },
     "node_modules/@commitlint/ensure": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.0.0.tgz",
-      "integrity": "sha512-WdMySU8DCTaq3JPf0tZFCKIUhqxaL54mjduNhu8v4D2AMUVIIQKYMGyvXn94k8begeW6iJkTf9cXBArayskE7Q==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.2.1.tgz",
+      "integrity": "sha512-/h+lBTgf1r5fhbDNHOViLuej38i3rZqTQnBTk+xEg+ehOwQDXUuissQ5GsYXXqI5uGy+261ew++sT4EA3uBJ+A==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "lodash": "^4.17.19"
       },
       "engines": {
@@ -194,21 +203,21 @@
       }
     },
     "node_modules/@commitlint/execute-rule": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.0.0.tgz",
-      "integrity": "sha512-8edcCibmBb386x5JTHSPHINwA5L0xPkHQFY8TAuDEt5QyRZY/o5DF8OPHSa5Hx2xJvGaxxuIz4UtAT6IiRDYkw==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.2.1.tgz",
+      "integrity": "sha512-oSls82fmUTLM6cl5V3epdVo4gHhbmBFvCvQGHBRdQ50H/690Uq1Dyd7hXMuKITCIdcnr9umyDkr8r5C6HZDF3g==",
       "dev": true,
       "engines": {
         "node": ">=v12"
       }
     },
     "node_modules/@commitlint/format": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.0.0.tgz",
-      "integrity": "sha512-9yp5NCquXL1jVMKL0ZkRwJf/UHdebvCcMvICuZV00NQGYSAL89O398nhqrqxlbjBhM5EZVq0VGcV5+7r3D4zAA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.2.1.tgz",
+      "integrity": "sha512-Yyio9bdHWmNDRlEJrxHKglamIk3d6hC0NkEUW6Ti6ipEh2g0BAhy8Od6t4vLhdZRa1I2n+gY13foy+tUgk0i1Q==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "chalk": "^4.0.0"
       },
       "engines": {
@@ -216,46 +225,47 @@
       }
     },
     "node_modules/@commitlint/is-ignored": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.0.0.tgz",
-      "integrity": "sha512-gmAQcwIGC/R/Lp0CEb2b5bfGC7MT5rPe09N8kOGjO/NcdNmfFSZMquwrvNJsq9hnAP0skRdHIsqwlkENkN4Lag==",
+      "version": "16.2.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.2.4.tgz",
+      "integrity": "sha512-Lxdq9aOAYCOOOjKi58ulbwK/oBiiKz+7Sq0+/SpFIEFwhHkIVugvDvWjh2VRBXmRC/x5lNcjDcYEwS/uYUvlYQ==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.0.0",
-        "semver": "7.3.5"
+        "@commitlint/types": "^16.2.1",
+        "semver": "7.3.7"
       },
       "engines": {
         "node": ">=v12"
       }
     },
     "node_modules/@commitlint/lint": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.0.0.tgz",
-      "integrity": "sha512-HNl15bRC0h+pLzbMzQC3tM0j1aESXsLYhElqKnXcf5mnCBkBkHzu6WwJW8rZbfxX+YwJmNljN62cPhmdBo8x0A==",
+      "version": "16.2.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.2.4.tgz",
+      "integrity": "sha512-AUDuwOxb2eGqsXbTMON3imUGkc1jRdtXrbbohiLSCSk3jFVXgJLTMaEcr39pR00N8nE9uZ+V2sYaiILByZVmxQ==",
       "dev": true,
       "dependencies": {
-        "@commitlint/is-ignored": "^16.0.0",
-        "@commitlint/parse": "^16.0.0",
-        "@commitlint/rules": "^16.0.0",
-        "@commitlint/types": "^16.0.0"
+        "@commitlint/is-ignored": "^16.2.4",
+        "@commitlint/parse": "^16.2.1",
+        "@commitlint/rules": "^16.2.4",
+        "@commitlint/types": "^16.2.1"
       },
       "engines": {
         "node": ">=v12"
       }
     },
     "node_modules/@commitlint/load": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.1.0.tgz",
-      "integrity": "sha512-MtlEhKjP8jAF85jjX4mw8DUUwCxKsCgAc865hhpnwxjrfBcmGP7Up2AFE/M3ZMGDmSl1X1TMybQk/zohj8Cqdg==",
+      "version": "16.3.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.3.0.tgz",
+      "integrity": "sha512-3tykjV/iwbkv2FU9DG+NZ/JqmP0Nm3b7aDwgCNQhhKV5P74JAuByULkafnhn+zsFGypG1qMtI5u+BZoa9APm0A==",
       "dev": true,
       "dependencies": {
-        "@commitlint/config-validator": "^16.1.0",
-        "@commitlint/execute-rule": "^16.0.0",
-        "@commitlint/resolve-extends": "^16.1.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/config-validator": "^16.2.1",
+        "@commitlint/execute-rule": "^16.2.1",
+        "@commitlint/resolve-extends": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
+        "@types/node": ">=12",
         "chalk": "^4.0.0",
         "cosmiconfig": "^7.0.0",
-        "cosmiconfig-typescript-loader": "^1.0.0",
+        "cosmiconfig-typescript-loader": "^2.0.0",
         "lodash": "^4.17.19",
         "resolve-from": "^5.0.0",
         "typescript": "^4.4.3"
@@ -265,21 +275,21 @@
       }
     },
     "node_modules/@commitlint/message": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.0.0.tgz",
-      "integrity": "sha512-CmK2074SH1Ws6kFMEKOKH/7hMekGVbOD6vb4alCOo2+33ZSLUIX8iNkDYyrw38Jwg6yWUhLjyQLUxREeV+QIUA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.2.1.tgz",
+      "integrity": "sha512-2eWX/47rftViYg7a3axYDdrgwKv32mxbycBJT6OQY/MJM7SUfYNYYvbMFOQFaA4xIVZt7t2Alyqslbl6blVwWw==",
       "dev": true,
       "engines": {
         "node": ">=v12"
       }
     },
     "node_modules/@commitlint/parse": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.0.0.tgz",
-      "integrity": "sha512-F9EjFlMw4MYgBEqoRrWZZKQBzdiJzPBI0qFDFqwUvfQsMmXEREZ242T4R5bFwLINWaALFLHEIa/FXEPa6QxCag==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.2.1.tgz",
+      "integrity": "sha512-2NP2dDQNL378VZYioLrgGVZhWdnJO4nAxQl5LXwYb08nEcN+cgxHN1dJV8OLJ5uxlGJtDeR8UZZ1mnQ1gSAD/g==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "conventional-changelog-angular": "^5.0.11",
         "conventional-commits-parser": "^3.2.2"
       },
@@ -288,13 +298,13 @@
       }
     },
     "node_modules/@commitlint/read": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.0.0.tgz",
-      "integrity": "sha512-H4T2zsfmYQK9B+JtoQaCXWBHUhgIJyOzWZjSfuIV9Ce69/OgHoffNpLZPF2lX6yKuDrS1SQFhI/kUCjVc/e4ew==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.2.1.tgz",
+      "integrity": "sha512-tViXGuaxLTrw2r7PiYMQOFA2fueZxnnt0lkOWqKyxT+n2XdEMGYcI9ID5ndJKXnfPGPppD0w/IItKsIXlZ+alw==",
       "dev": true,
       "dependencies": {
-        "@commitlint/top-level": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/top-level": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "fs-extra": "^10.0.0",
         "git-raw-commits": "^2.0.0"
       },
@@ -303,13 +313,13 @@
       }
     },
     "node_modules/@commitlint/resolve-extends": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.1.0.tgz",
-      "integrity": "sha512-8182s6AFoUFX6+FT1PgQDt15nO2ogdR/EN8SYVAdhNXw1rLz8kT5saB/ICw567GuRAUgFTUMGCXy3ctMOXPEDg==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.2.1.tgz",
+      "integrity": "sha512-NbbCMPKTFf2J805kwfP9EO+vV+XvnaHRcBy6ud5dF35dxMsvdJqke54W3XazXF1ZAxC4a3LBy4i/GNVBAthsEg==",
       "dev": true,
       "dependencies": {
-        "@commitlint/config-validator": "^16.1.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/config-validator": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "import-fresh": "^3.0.0",
         "lodash": "^4.17.19",
         "resolve-from": "^5.0.0",
@@ -320,15 +330,15 @@
       }
     },
     "node_modules/@commitlint/rules": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.0.0.tgz",
-      "integrity": "sha512-AOl0y2SBTdJ1bvIv8nwHvQKRT/jC1xb09C5VZwzHoT8sE8F54KDeEzPCwHQFgUcWdGLyS10kkOTAH2MyA8EIlg==",
+      "version": "16.2.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.2.4.tgz",
+      "integrity": "sha512-rK5rNBIN2ZQNQK+I6trRPK3dWa0MtaTN4xnwOma1qxa4d5wQMQJtScwTZjTJeallFxhOgbNOgr48AMHkdounVg==",
       "dev": true,
       "dependencies": {
-        "@commitlint/ensure": "^16.0.0",
-        "@commitlint/message": "^16.0.0",
-        "@commitlint/to-lines": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/ensure": "^16.2.1",
+        "@commitlint/message": "^16.2.1",
+        "@commitlint/to-lines": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "execa": "^5.0.0"
       },
       "engines": {
@@ -336,18 +346,18 @@
       }
     },
     "node_modules/@commitlint/to-lines": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.0.0.tgz",
-      "integrity": "sha512-iN/qU38TCKU7uKOg6RXLpD49wNiuI0TqMqybHbjefUeP/Jmzxa8ishryj0uLyVdrAl1ZjGeD1ukXGMTtvqz8iA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.2.1.tgz",
+      "integrity": "sha512-9/VjpYj5j1QeY3eiog1zQWY6axsdWAc0AonUUfyZ7B0MVcRI0R56YsHAfzF6uK/g/WwPZaoe4Lb1QCyDVnpVaQ==",
       "dev": true,
       "engines": {
         "node": ">=v12"
       }
     },
     "node_modules/@commitlint/top-level": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.0.0.tgz",
-      "integrity": "sha512-/Jt6NLxyFkpjL5O0jxurZPCHURZAm7cQCqikgPCwqPAH0TLgwqdHjnYipl8J+AGnAMGDip4FNLoYrtgIpZGBYw==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.2.1.tgz",
+      "integrity": "sha512-lS6GSieHW9y6ePL73ied71Z9bOKyK+Ib9hTkRsB8oZFAyQZcyRwq2w6nIa6Fngir1QW51oKzzaXfJL94qwImyw==",
       "dev": true,
       "dependencies": {
         "find-up": "^5.0.0"
@@ -357,9 +367,9 @@
       }
     },
     "node_modules/@commitlint/types": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.0.0.tgz",
-      "integrity": "sha512-+0FvYOAS39bJ4aKjnYn/7FD4DfWkmQ6G/06I4F0Gvu4KS5twirEg8mIcLhmeRDOOKn4Tp8PwpLwBiSA6npEMQA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.2.1.tgz",
+      "integrity": "sha512-7/z7pA7BM0i8XvMSBynO7xsB3mVQPUZbVn6zMIlp/a091XJ3qAXRXc+HwLYhiIdzzS5fuxxNIHZMGHVD4HJxdA==",
       "dev": true,
       "dependencies": {
         "chalk": "^4.0.0"
@@ -368,22 +378,13 @@
         "node": ">=v12"
       }
     },
-    "node_modules/@cspotcode/source-map-consumer": {
-      "version": "0.8.0",
-      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
-      "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 12"
-      }
-    },
     "node_modules/@cspotcode/source-map-support": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz",
-      "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==",
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+      "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
       "dev": true,
       "dependencies": {
-        "@cspotcode/source-map-consumer": "0.8.0"
+        "@jridgewell/trace-mapping": "0.3.9"
       },
       "engines": {
         "node": ">=12"
@@ -398,28 +399,53 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.4.14",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+      "dev": true
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.9",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+      "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.0.3",
+        "@jridgewell/sourcemap-codec": "^1.4.10"
+      }
+    },
     "node_modules/@tsconfig/node10": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
-      "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
+      "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
       "dev": true
     },
     "node_modules/@tsconfig/node12": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
-      "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+      "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
       "dev": true
     },
     "node_modules/@tsconfig/node14": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
-      "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+      "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
       "dev": true
     },
     "node_modules/@tsconfig/node16": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
-      "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
+      "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
       "dev": true
     },
     "node_modules/@types/minimist": {
@@ -429,11 +455,10 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "17.0.10",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz",
-      "integrity": "sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog==",
-      "dev": true,
-      "peer": true
+      "version": "18.8.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.3.tgz",
+      "integrity": "sha512-0os9vz6BpGwxGe9LOhgP/ncvYN5Tx1fNcd2TM3rD/aCGBkysb+ZWpXEocG24h6ZzOi13+VB8HndAQFezsSOw1w==",
+      "dev": true
     },
     "node_modules/@types/normalize-package-data": {
       "version": "2.4.1",
@@ -448,9 +473,9 @@
       "dev": true
     },
     "node_modules/acorn": {
-      "version": "8.7.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
-      "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+      "version": "8.8.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
       "dev": true,
       "bin": {
         "acorn": "bin/acorn"
@@ -471,7 +496,7 @@
     "node_modules/add-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz",
-      "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=",
+      "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==",
       "dev": true
     },
     "node_modules/ajv": {
@@ -495,7 +520,6 @@
       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
       "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "type-fest": "^0.21.3"
       },
@@ -506,19 +530,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/ansi-escapes/node_modules/type-fest": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
-      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "node_modules/ansi-regex": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -558,18 +569,27 @@
     "node_modules/array-ify": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
-      "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=",
+      "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
       "dev": true
     },
     "node_modules/arrify": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
-      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
+    "node_modules/at-least-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -594,15 +614,13 @@
           "type": "consulting",
           "url": "https://feross.org/support"
         }
-      ],
-      "peer": true
+      ]
     },
     "node_modules/bl": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
       "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "buffer": "^5.5.0",
         "inherits": "^2.0.4",
@@ -650,7 +668,6 @@
           "url": "https://feross.org/support"
         }
       ],
-      "peer": true,
       "dependencies": {
         "base64-js": "^1.3.1",
         "ieee754": "^1.1.13"
@@ -663,9 +680,9 @@
       "dev": true
     },
     "node_modules/cachedir": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.2.0.tgz",
-      "integrity": "sha512-VvxA0xhNqIIfg0V9AmJkDg91DaJwryutH5rVEZAhcNi4iJFj9f+QxmAjgK1LT9I8OgToX27fypX6/MeCXVbBjQ==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
+      "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==",
       "dev": true,
       "engines": {
         "node": ">=6"
@@ -733,7 +750,6 @@
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
       "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "restore-cursor": "^3.1.0"
       },
@@ -742,11 +758,10 @@
       }
     },
     "node_modules/cli-spinners": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz",
-      "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==",
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz",
+      "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">=6"
       },
@@ -759,28 +774,29 @@
       "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
       "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">= 10"
       }
     },
     "node_modules/cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
       "dev": true,
       "dependencies": {
         "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
+        "strip-ansi": "^6.0.1",
         "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/clone": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
-      "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
+      "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">=0.8"
       }
@@ -804,25 +820,25 @@
       "dev": true
     },
     "node_modules/commitizen": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.2.4.tgz",
-      "integrity": "sha512-LlZChbDzg3Ir3O2S7jSo/cgWp5/QwylQVr59K4xayVq8S4/RdKzSyJkghAiZZHfhh5t4pxunUoyeg0ml1q/7aw==",
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.2.5.tgz",
+      "integrity": "sha512-9sXju8Qrz1B4Tw7kC5KhnvwYQN88qs2zbiB8oyMsnXZyJ24PPGiNM3nHr73d32dnE3i8VJEXddBFIbOgYSEXtQ==",
       "dev": true,
       "dependencies": {
-        "cachedir": "2.2.0",
-        "cz-conventional-changelog": "3.2.0",
+        "cachedir": "2.3.0",
+        "cz-conventional-changelog": "3.3.0",
         "dedent": "0.7.0",
-        "detect-indent": "6.0.0",
+        "detect-indent": "6.1.0",
         "find-node-modules": "^2.1.2",
         "find-root": "1.1.0",
-        "fs-extra": "8.1.0",
-        "glob": "7.1.4",
-        "inquirer": "6.5.2",
+        "fs-extra": "9.1.0",
+        "glob": "7.2.3",
+        "inquirer": "8.2.4",
         "is-utf8": "^0.2.1",
-        "lodash": "^4.17.20",
-        "minimist": "1.2.5",
+        "lodash": "4.17.21",
+        "minimist": "1.2.6",
         "strip-bom": "4.0.0",
-        "strip-json-comments": "3.0.1"
+        "strip-json-comments": "3.1.1"
       },
       "bin": {
         "commitizen": "bin/commitizen",
@@ -830,306 +846,22 @@
         "git-cz": "bin/git-cz"
       },
       "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/commitizen/node_modules/ansi-escapes": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
-      "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/ansi-regex": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
-      "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/commitizen/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/cli-cursor": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
-      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
-      "dev": true,
-      "dependencies": {
-        "restore-cursor": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/cli-width": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
-      "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
-      "dev": true
-    },
-    "node_modules/commitizen/node_modules/color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "dev": true,
-      "dependencies": {
-        "color-name": "1.1.3"
-      }
-    },
-    "node_modules/commitizen/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "dev": true
-    },
-    "node_modules/commitizen/node_modules/cz-conventional-changelog": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.2.0.tgz",
-      "integrity": "sha512-yAYxeGpVi27hqIilG1nh4A9Bnx4J3Ov+eXy4koL3drrR+IO9GaWPsKjik20ht608Asqi8TQPf0mczhEeyAtMzg==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^2.4.1",
-        "commitizen": "^4.0.3",
-        "conventional-commit-types": "^3.0.0",
-        "lodash.map": "^4.5.1",
-        "longest": "^2.0.1",
-        "word-wrap": "^1.0.3"
-      },
-      "engines": {
-        "node": ">= 10"
-      },
-      "optionalDependencies": {
-        "@commitlint/load": ">6.1.1"
-      }
-    },
-    "node_modules/commitizen/node_modules/figures": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
-      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
-      "dev": true,
-      "dependencies": {
-        "escape-string-regexp": "^1.0.5"
-      },
-      "engines": {
-        "node": ">=4"
+        "node": ">= 12"
       }
     },
     "node_modules/commitizen/node_modules/fs-extra": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
-      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
       "dev": true,
       "dependencies": {
+        "at-least-node": "^1.0.0",
         "graceful-fs": "^4.2.0",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=6 <7 || >=8"
-      }
-    },
-    "node_modules/commitizen/node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/inquirer": {
-      "version": "6.5.2",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
-      "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-escapes": "^3.2.0",
-        "chalk": "^2.4.2",
-        "cli-cursor": "^2.1.0",
-        "cli-width": "^2.0.0",
-        "external-editor": "^3.0.3",
-        "figures": "^2.0.0",
-        "lodash": "^4.17.12",
-        "mute-stream": "0.0.7",
-        "run-async": "^2.2.0",
-        "rxjs": "^6.4.0",
-        "string-width": "^2.1.0",
-        "strip-ansi": "^5.1.0",
-        "through": "^2.3.6"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/commitizen/node_modules/is-fullwidth-code-point": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/jsonfile": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
-      "dev": true,
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/commitizen/node_modules/mimic-fn": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
-      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/mute-stream": {
-      "version": "0.0.7",
-      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
-      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
-      "dev": true
-    },
-    "node_modules/commitizen/node_modules/onetime": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
-      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
-      "dev": true,
-      "dependencies": {
-        "mimic-fn": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/restore-cursor": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
-      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
-      "dev": true,
-      "dependencies": {
-        "onetime": "^2.0.0",
-        "signal-exit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/rxjs": {
-      "version": "6.6.7",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
-      "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
-      "dev": true,
-      "dependencies": {
-        "tslib": "^1.9.0"
-      },
-      "engines": {
-        "npm": ">=2.0.0"
-      }
-    },
-    "node_modules/commitizen/node_modules/string-width": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
-      "dev": true,
-      "dependencies": {
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/string-width/node_modules/ansi-regex": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
-      "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/string-width/node_modules/strip-ansi": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/strip-ansi": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
-      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^4.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/commitizen/node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^3.0.0"
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
       },
       "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/commitizen/node_modules/tslib": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-      "dev": true
-    },
-    "node_modules/commitizen/node_modules/universalify": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4.0.0"
+        "node": ">=10"
       }
     },
     "node_modules/compare-func": {
@@ -1145,7 +877,7 @@
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
       "dev": true
     },
     "node_modules/concat-stream": {
@@ -1164,9 +896,9 @@
       }
     },
     "node_modules/conventional-changelog": {
-      "version": "3.1.24",
-      "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.24.tgz",
-      "integrity": "sha512-ed6k8PO00UVvhExYohroVPXcOJ/K1N0/drJHx/faTH37OIZthlecuLIRX/T6uOp682CAoVoFpu+sSEaeuH6Asg==",
+      "version": "3.1.25",
+      "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz",
+      "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==",
       "dev": true,
       "dependencies": {
         "conventional-changelog-angular": "^5.0.12",
@@ -1229,9 +961,9 @@
       "dev": true
     },
     "node_modules/conventional-changelog-conventionalcommits": {
-      "version": "4.6.1",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.1.tgz",
-      "integrity": "sha512-lzWJpPZhbM1R0PIzkwzGBCnAkH5RKJzJfFQZcl/D+2lsJxAwGnDKBqn/F4C1RD31GJNn8NuKWQzAZDAVXPp2Mw==",
+      "version": "4.6.3",
+      "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz",
+      "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==",
       "dev": true,
       "dependencies": {
         "compare-func": "^2.0.0",
@@ -1270,7 +1002,7 @@
     "node_modules/conventional-changelog-core/node_modules/find-up": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
-      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+      "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
       "dev": true,
       "dependencies": {
         "locate-path": "^2.0.0"
@@ -1288,7 +1020,7 @@
     "node_modules/conventional-changelog-core/node_modules/locate-path": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
-      "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+      "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
       "dev": true,
       "dependencies": {
         "p-locate": "^2.0.0",
@@ -1313,7 +1045,7 @@
     "node_modules/conventional-changelog-core/node_modules/p-locate": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
-      "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+      "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
       "dev": true,
       "dependencies": {
         "p-limit": "^1.1.0"
@@ -1322,19 +1054,10 @@
         "node": ">=4"
       }
     },
-    "node_modules/conventional-changelog-core/node_modules/p-try": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
-      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/conventional-changelog-core/node_modules/path-exists": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -1355,7 +1078,7 @@
     "node_modules/conventional-changelog-core/node_modules/pify": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+      "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -1364,7 +1087,7 @@
     "node_modules/conventional-changelog-core/node_modules/read-pkg": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
-      "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+      "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
       "dev": true,
       "dependencies": {
         "load-json-file": "^4.0.0",
@@ -1378,7 +1101,7 @@
     "node_modules/conventional-changelog-core/node_modules/read-pkg-up": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
-      "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=",
+      "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==",
       "dev": true,
       "dependencies": {
         "find-up": "^2.0.0",
@@ -1484,14 +1207,14 @@
       "link": true
     },
     "node_modules/conventional-changelog-writer": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz",
-      "integrity": "sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz",
+      "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==",
       "dev": true,
       "dependencies": {
         "conventional-commits-filter": "^2.0.7",
         "dateformat": "^3.0.0",
-        "handlebars": "^4.7.6",
+        "handlebars": "^4.7.7",
         "json-stringify-safe": "^5.0.1",
         "lodash": "^4.17.15",
         "meow": "^8.0.0",
@@ -1535,9 +1258,9 @@
       }
     },
     "node_modules/conventional-commits-parser": {
-      "version": "3.2.3",
-      "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz",
-      "integrity": "sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw==",
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz",
+      "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==",
       "dev": true,
       "dependencies": {
         "is-text-path": "^1.0.1",
@@ -1599,13 +1322,13 @@
       }
     },
     "node_modules/cosmiconfig-typescript-loader": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-1.0.4.tgz",
-      "integrity": "sha512-ulv2dvwurP/MZAIthXm69bO7EzzIUThZ6RJ1qXhdlXM6to3F+IKBL/17EnhYSG52A5N1KcAUu66vSG/3/77KrA==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-2.0.2.tgz",
+      "integrity": "sha512-KmE+bMjWMXJbkWCeY4FJX/npHuZPNr9XF9q9CIQ/bpFwi1qHfCmSiKarrCcRa0LO4fWjk93pVoeRtJAkTGcYNw==",
       "dev": true,
       "dependencies": {
         "cosmiconfig": "^7",
-        "ts-node": "^10.4.0"
+        "ts-node": "^10.8.1"
       },
       "engines": {
         "node": ">=12",
@@ -1637,21 +1360,88 @@
         "node": ">= 8"
       }
     },
-    "node_modules/cross-spawn/node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+    "node_modules/cz-conventional-changelog": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz",
+      "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==",
       "dev": true,
       "dependencies": {
-        "isexe": "^2.0.0"
+        "chalk": "^2.4.1",
+        "commitizen": "^4.0.3",
+        "conventional-commit-types": "^3.0.0",
+        "lodash.map": "^4.5.1",
+        "longest": "^2.0.1",
+        "word-wrap": "^1.0.3"
       },
-      "bin": {
-        "node-which": "bin/node-which"
+      "engines": {
+        "node": ">= 10"
+      },
+      "optionalDependencies": {
+        "@commitlint/load": ">6.1.1"
+      }
+    },
+    "node_modules/cz-conventional-changelog/node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
       },
       "engines": {
-        "node": ">= 8"
+        "node": ">=4"
       }
     },
+    "node_modules/cz-conventional-changelog/node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/cz-conventional-changelog/node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/cz-conventional-changelog/node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true
+    },
+    "node_modules/cz-conventional-changelog/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/cz-conventional-changelog/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/dargs": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz",
@@ -1673,7 +1463,7 @@
     "node_modules/decamelize": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -1682,7 +1472,7 @@
     "node_modules/decamelize-keys": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
-      "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=",
+      "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==",
       "dev": true,
       "dependencies": {
         "decamelize": "^1.1.0",
@@ -1695,7 +1485,7 @@
     "node_modules/decamelize-keys/node_modules/map-obj": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
-      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+      "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -1704,32 +1494,34 @@
     "node_modules/dedent": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
-      "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
+      "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
       "dev": true
     },
     "node_modules/defaults": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
-      "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+      "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "clone": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/detect-file": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
-      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+      "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
     "node_modules/detect-indent": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz",
-      "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
+      "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
       "dev": true,
       "engines": {
         "node": ">=8"
@@ -1830,10 +1622,19 @@
         "node": ">=6"
       }
     },
+    "node_modules/dotgitignore/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/dotgitignore/node_modules/path-exists": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -1866,7 +1667,7 @@
     "node_modules/escape-string-regexp": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
       "dev": true,
       "engines": {
         "node": ">=0.8.0"
@@ -1898,7 +1699,7 @@
     "node_modules/expand-tilde": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
-      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+      "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
       "dev": true,
       "dependencies": {
         "homedir-polyfill": "^1.0.1"
@@ -1961,13 +1762,13 @@
       }
     },
     "node_modules/find-node-modules": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.2.tgz",
-      "integrity": "sha512-x+3P4mbtRPlSiVE1Qco0Z4YLU8WFiFcuWTf3m75OV9Uzcfs2Bg+O9N+r/K0AnmINBW06KpfqKwYJbFlFq4qNug==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz",
+      "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==",
       "dev": true,
       "dependencies": {
         "findup-sync": "^4.0.0",
-        "merge": "^2.1.0"
+        "merge": "^2.1.1"
       }
     },
     "node_modules/find-root": {
@@ -2004,25 +1805,13 @@
         "resolve-dir": "^1.0.1"
       },
       "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/fs-access": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz",
-      "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=",
-      "dev": true,
-      "dependencies": {
-        "null-check": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
+        "node": ">= 8"
       }
     },
     "node_modules/fs-extra": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-      "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.0",
@@ -2036,7 +1825,7 @@
     "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
       "dev": true
     },
     "node_modules/function-bind": {
@@ -2072,6 +1861,17 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/get-pkg-repo/node_modules/cliui": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
     "node_modules/get-pkg-repo/node_modules/readable-stream": {
       "version": "2.3.7",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
@@ -2143,9 +1943,9 @@
       }
     },
     "node_modules/git-raw-commits": {
-      "version": "2.0.10",
-      "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz",
-      "integrity": "sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ==",
+      "version": "2.0.11",
+      "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz",
+      "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==",
       "dev": true,
       "dependencies": {
         "dargs": "^7.0.0",
@@ -2164,7 +1964,7 @@
     "node_modules/git-remote-origin-url": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz",
-      "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=",
+      "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==",
       "dev": true,
       "dependencies": {
         "gitconfiglocal": "^1.0.0",
@@ -2202,33 +2002,36 @@
     "node_modules/gitconfiglocal": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz",
-      "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=",
+      "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==",
       "dev": true,
       "dependencies": {
         "ini": "^1.3.2"
       }
     },
     "node_modules/glob": {
-      "version": "7.1.4",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
-      "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
       "dev": true,
       "dependencies": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
         "inherits": "2",
-        "minimatch": "^3.0.4",
+        "minimatch": "^3.1.1",
         "once": "^1.3.0",
         "path-is-absolute": "^1.0.0"
       },
       "engines": {
         "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
     "node_modules/global-dirs": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
-      "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+      "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==",
       "dev": true,
       "dependencies": {
         "ini": "^1.3.4"
@@ -2254,7 +2057,7 @@
     "node_modules/global-prefix": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
-      "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+      "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
       "dev": true,
       "dependencies": {
         "expand-tilde": "^2.0.2",
@@ -2267,10 +2070,22 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/global-prefix/node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
     "node_modules/graceful-fs": {
-      "version": "4.2.6",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
-      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+      "version": "4.2.10",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
     "node_modules/handlebars": {
@@ -2337,9 +2152,9 @@
       }
     },
     "node_modules/hosted-git-info": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz",
-      "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
       "dev": true,
       "dependencies": {
         "lru-cache": "^6.0.0"
@@ -2402,8 +2217,7 @@
           "type": "consulting",
           "url": "https://feross.org/support"
         }
-      ],
-      "peer": true
+      ]
     },
     "node_modules/import-fresh": {
       "version": "3.3.0",
@@ -2442,7 +2256,7 @@
     "node_modules/inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
       "dev": true,
       "dependencies": {
         "once": "^1.3.0",
@@ -2462,11 +2276,10 @@
       "dev": true
     },
     "node_modules/inquirer": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz",
-      "integrity": "sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ==",
+      "version": "8.2.4",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz",
+      "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "ansi-escapes": "^4.2.1",
         "chalk": "^4.1.1",
@@ -2478,25 +2291,26 @@
         "mute-stream": "0.0.8",
         "ora": "^5.4.1",
         "run-async": "^2.4.0",
-        "rxjs": "^7.2.0",
+        "rxjs": "^7.5.5",
         "string-width": "^4.1.0",
         "strip-ansi": "^6.0.0",
-        "through": "^2.3.6"
+        "through": "^2.3.6",
+        "wrap-ansi": "^7.0.0"
       },
       "engines": {
-        "node": ">=8.0.0"
+        "node": ">=12.0.0"
       }
     },
     "node_modules/is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
       "dev": true
     },
     "node_modules/is-core-module": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
-      "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+      "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
       "dev": true,
       "dependencies": {
         "has": "^1.0.3"
@@ -2508,7 +2322,7 @@
     "node_modules/is-extglob": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -2524,9 +2338,9 @@
       }
     },
     "node_modules/is-glob": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
-      "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
       "dev": true,
       "dependencies": {
         "is-extglob": "^2.1.1"
@@ -2540,7 +2354,6 @@
       "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
       "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">=8"
       }
@@ -2566,7 +2379,7 @@
     "node_modules/is-plain-obj": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
-      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -2587,7 +2400,7 @@
     "node_modules/is-text-path": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz",
-      "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=",
+      "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==",
       "dev": true,
       "dependencies": {
         "text-extensions": "^1.0.0"
@@ -2601,7 +2414,6 @@
       "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
       "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">=10"
       },
@@ -2612,7 +2424,7 @@
     "node_modules/is-utf8": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
-      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==",
       "dev": true
     },
     "node_modules/is-windows": {
@@ -2627,13 +2439,13 @@
     "node_modules/isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
       "dev": true
     },
     "node_modules/isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
     },
     "node_modules/js-tokens": {
@@ -2675,7 +2487,7 @@
     "node_modules/json-stringify-safe": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
       "dev": true
     },
     "node_modules/jsonfile": {
@@ -2693,7 +2505,7 @@
     "node_modules/jsonparse": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
-      "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
+      "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
       "dev": true,
       "engines": [
         "node >= 0.2.0"
@@ -2725,15 +2537,15 @@
       }
     },
     "node_modules/lines-and-columns": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
-      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
       "dev": true
     },
     "node_modules/load-json-file": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
-      "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+      "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.1.2",
@@ -2748,7 +2560,7 @@
     "node_modules/load-json-file/node_modules/parse-json": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
-      "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+      "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
       "dev": true,
       "dependencies": {
         "error-ex": "^1.3.1",
@@ -2761,7 +2573,7 @@
     "node_modules/load-json-file/node_modules/pify": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+      "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -2770,7 +2582,7 @@
     "node_modules/load-json-file/node_modules/strip-bom": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-      "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+      "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -2800,13 +2612,13 @@
     "node_modules/lodash.ismatch": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz",
-      "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=",
+      "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==",
       "dev": true
     },
     "node_modules/lodash.map": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz",
-      "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=",
+      "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==",
       "dev": true
     },
     "node_modules/log-symbols": {
@@ -2814,7 +2626,6 @@
       "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
       "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "chalk": "^4.1.0",
         "is-unicode-supported": "^0.1.0"
@@ -2829,7 +2640,7 @@
     "node_modules/longest": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz",
-      "integrity": "sha1-eB4YMpaqlPbU2RbcM10NF676I/g=",
+      "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -2883,6 +2694,18 @@
         "type-fest": "^0.18.0",
         "yargs-parser": "^20.2.3"
       },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/meow/node_modules/type-fest": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
+      "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+      "dev": true,
       "engines": {
         "node": ">=10"
       },
@@ -2903,13 +2726,13 @@
       "dev": true
     },
     "node_modules/micromatch": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
-      "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
       "dev": true,
       "dependencies": {
-        "braces": "^3.0.1",
-        "picomatch": "^2.2.3"
+        "braces": "^3.0.2",
+        "picomatch": "^2.3.1"
       },
       "engines": {
         "node": ">=8.6"
@@ -2934,9 +2757,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "dev": true,
       "dependencies": {
         "brace-expansion": "^1.1.7"
@@ -2946,9 +2769,9 @@
       }
     },
     "node_modules/minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
       "dev": true
     },
     "node_modules/minimist-options": {
@@ -2978,8 +2801,7 @@
       "version": "0.0.8",
       "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
       "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "node_modules/neo-async": {
       "version": "2.6.2",
@@ -3014,19 +2836,10 @@
         "node": ">=8"
       }
     },
-    "node_modules/null-check": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz",
-      "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
       "dev": true,
       "dependencies": {
         "wrappy": "1"
@@ -3052,7 +2865,6 @@
       "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
       "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "bl": "^4.1.0",
         "chalk": "^4.1.0",
@@ -3074,7 +2886,7 @@
     "node_modules/os-tmpdir": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -3111,12 +2923,12 @@
       }
     },
     "node_modules/p-try": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+      "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
       "dev": true,
       "engines": {
-        "node": ">=6"
+        "node": ">=4"
       }
     },
     "node_modules/parent-module": {
@@ -3152,7 +2964,7 @@
     "node_modules/parse-passwd": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
-      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+      "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -3170,7 +2982,7 @@
     "node_modules/path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -3201,9 +3013,9 @@
       }
     },
     "node_modules/picomatch": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz",
-      "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==",
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
       "dev": true,
       "engines": {
         "node": ">=8.6"
@@ -3215,7 +3027,7 @@
     "node_modules/pify": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -3239,7 +3051,7 @@
     "node_modules/q": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
-      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
+      "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
       "dev": true,
       "engines": {
         "node": ">=0.6.0",
@@ -3339,6 +3151,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/read-pkg-up/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/read-pkg-up/node_modules/type-fest": {
       "version": "0.8.1",
       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
@@ -3414,20 +3235,24 @@
     "node_modules/require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
     "node_modules/resolve": {
-      "version": "1.20.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
-      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+      "version": "1.22.1",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
       "dev": true,
       "dependencies": {
-        "is-core-module": "^2.2.0",
-        "path-parse": "^1.0.6"
+        "is-core-module": "^2.9.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -3436,7 +3261,7 @@
     "node_modules/resolve-dir": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
-      "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+      "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
       "dev": true,
       "dependencies": {
         "expand-tilde": "^2.0.0",
@@ -3472,7 +3297,6 @@
       "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
       "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "onetime": "^5.1.0",
         "signal-exit": "^3.0.2"
@@ -3491,13 +3315,12 @@
       }
     },
     "node_modules/rxjs": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz",
-      "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==",
+      "version": "7.5.7",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz",
+      "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "tslib": "~2.1.0"
+        "tslib": "^2.1.0"
       }
     },
     "node_modules/safe-buffer": {
@@ -3527,9 +3350,9 @@
       "dev": true
     },
     "node_modules/semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+      "version": "7.3.7",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
       "dev": true,
       "dependencies": {
         "lru-cache": "^6.0.0"
@@ -3563,9 +3386,9 @@
       }
     },
     "node_modules/signal-exit": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
-      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
       "dev": true
     },
     "node_modules/source-map": {
@@ -3604,9 +3427,9 @@
       }
     },
     "node_modules/spdx-license-ids": {
-      "version": "3.0.10",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz",
-      "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==",
+      "version": "3.0.12",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz",
+      "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
       "dev": true
     },
     "node_modules/split": {
@@ -3631,22 +3454,21 @@
       }
     },
     "node_modules/standard-version": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.3.2.tgz",
-      "integrity": "sha512-u1rfKP4o4ew7Yjbfycv80aNMN2feTiqseAhUhrrx2XtdQGmu7gucpziXe68Z4YfHVqlxVEzo4aUA0Iu3VQOTgQ==",
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz",
+      "integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==",
       "dev": true,
       "dependencies": {
         "chalk": "^2.4.2",
-        "conventional-changelog": "3.1.24",
+        "conventional-changelog": "3.1.25",
         "conventional-changelog-config-spec": "2.1.0",
-        "conventional-changelog-conventionalcommits": "4.6.1",
+        "conventional-changelog-conventionalcommits": "4.6.3",
         "conventional-recommended-bump": "6.1.0",
         "detect-indent": "^6.0.0",
         "detect-newline": "^3.1.0",
         "dotgitignore": "^2.1.0",
         "figures": "^3.1.0",
         "find-up": "^5.0.0",
-        "fs-access": "^1.0.1",
         "git-semver-tags": "^4.0.0",
         "semver": "^7.1.1",
         "stringify-package": "^1.0.1",
@@ -3685,6 +3507,17 @@
         "node": ">=4"
       }
     },
+    "node_modules/standard-version/node_modules/cliui": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
     "node_modules/standard-version/node_modules/color-convert": {
       "version": "1.9.3",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -3697,13 +3530,13 @@
     "node_modules/standard-version/node_modules/color-name": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
       "dev": true
     },
     "node_modules/standard-version/node_modules/has-flag": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -3811,12 +3644,15 @@
       }
     },
     "node_modules/strip-json-comments": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
-      "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
       "dev": true,
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/supports-color": {
@@ -3831,6 +3667,18 @@
         "node": ">=8"
       }
     },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/text-extensions": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz",
@@ -3843,7 +3691,7 @@
     "node_modules/through": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
       "dev": true
     },
     "node_modules/through2": {
@@ -3889,12 +3737,12 @@
       }
     },
     "node_modules/ts-node": {
-      "version": "10.4.0",
-      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz",
-      "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==",
+      "version": "10.9.1",
+      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
+      "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
       "dev": true,
       "dependencies": {
-        "@cspotcode/source-map-support": "0.7.0",
+        "@cspotcode/source-map-support": "^0.8.0",
         "@tsconfig/node10": "^1.0.7",
         "@tsconfig/node12": "^1.0.7",
         "@tsconfig/node14": "^1.0.0",
@@ -3905,11 +3753,13 @@
         "create-require": "^1.1.0",
         "diff": "^4.0.1",
         "make-error": "^1.1.1",
+        "v8-compile-cache-lib": "^3.0.1",
         "yn": "3.1.1"
       },
       "bin": {
         "ts-node": "dist/bin.js",
         "ts-node-cwd": "dist/bin-cwd.js",
+        "ts-node-esm": "dist/bin-esm.js",
         "ts-node-script": "dist/bin-script.js",
         "ts-node-transpile-only": "dist/bin-transpile.js",
         "ts-script": "dist/bin-script-deprecated.js"
@@ -3930,16 +3780,15 @@
       }
     },
     "node_modules/tslib": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
-      "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==",
-      "dev": true,
-      "peer": true
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+      "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
+      "dev": true
     },
     "node_modules/type-fest": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
-      "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
       "dev": true,
       "engines": {
         "node": ">=10"
@@ -3951,13 +3800,13 @@
     "node_modules/typedarray": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
       "dev": true
     },
     "node_modules/typescript": {
-      "version": "4.5.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
-      "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
+      "version": "4.8.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
+      "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -3968,9 +3817,9 @@
       }
     },
     "node_modules/uglify-js": {
-      "version": "3.14.3",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.3.tgz",
-      "integrity": "sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==",
+      "version": "3.17.3",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz",
+      "integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==",
       "dev": true,
       "optional": true,
       "bin": {
@@ -4001,7 +3850,13 @@
     "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+      "dev": true
+    },
+    "node_modules/v8-compile-cache-lib": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+      "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
       "dev": true
     },
     "node_modules/validate-npm-package-license": {
@@ -4017,23 +3872,25 @@
     "node_modules/wcwidth": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
-      "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
+      "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "defaults": "^1.0.3"
       }
     },
     "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
       "dev": true,
       "dependencies": {
         "isexe": "^2.0.0"
       },
       "bin": {
-        "which": "bin/which"
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
     "node_modules/word-wrap": {
@@ -4048,7 +3905,7 @@
     "node_modules/wordwrap": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
-      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+      "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
       "dev": true
     },
     "node_modules/wrap-ansi": {
@@ -4071,7 +3928,7 @@
     "node_modules/wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
       "dev": true
     },
     "node_modules/xtend": {
@@ -4108,18 +3965,18 @@
       }
     },
     "node_modules/yargs": {
-      "version": "17.2.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz",
-      "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==",
+      "version": "17.6.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz",
+      "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==",
       "dev": true,
       "dependencies": {
-        "cliui": "^7.0.2",
+        "cliui": "^8.0.1",
         "escalade": "^3.1.1",
         "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
-        "string-width": "^4.2.0",
+        "string-width": "^4.2.3",
         "y18n": "^5.0.5",
-        "yargs-parser": "^20.2.2"
+        "yargs-parser": "^21.0.0"
       },
       "engines": {
         "node": ">=12"
@@ -4134,6 +3991,15 @@
         "node": ">=10"
       }
     },
+    "node_modules/yargs/node_modules/yargs-parser": {
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/yn": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
@@ -4156,7 +4022,7 @@
       }
     },
     "tools/conventional-changelog-tf-a": {
-      "version": "2.6.0",
+      "version": "2.7.0",
       "dev": true,
       "license": "BSD-3-Clause",
       "dependencies": {
@@ -4169,27 +4035,27 @@
   },
   "dependencies": {
     "@babel/code-frame": {
-      "version": "7.12.13",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
-      "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
       "dev": true,
       "requires": {
-        "@babel/highlight": "^7.12.13"
+        "@babel/highlight": "^7.18.6"
       }
     },
     "@babel/helper-validator-identifier": {
-      "version": "7.14.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
-      "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+      "version": "7.19.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
       "dev": true
     },
     "@babel/highlight": {
-      "version": "7.14.0",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
-      "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
       "dev": true,
       "requires": {
-        "@babel/helper-validator-identifier": "^7.14.0",
+        "@babel/helper-validator-identifier": "^7.18.6",
         "chalk": "^2.0.0",
         "js-tokens": "^4.0.0"
       },
@@ -4226,13 +4092,13 @@
         "color-name": {
           "version": "1.1.3",
           "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+          "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
           "dev": true
         },
         "has-flag": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
           "dev": true
         },
         "supports-color": {
@@ -4247,16 +4113,16 @@
       }
     },
     "@commitlint/cli": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.1.0.tgz",
-      "integrity": "sha512-x5L1knvA3isRWBRVQx+Q6D45pA9139a2aZQYpxkljMG0dj4UHZkCnsYWpnGalxPxASI7nrI0KedKfS2YeQ55cQ==",
+      "version": "16.3.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.3.0.tgz",
+      "integrity": "sha512-P+kvONlfsuTMnxSwWE1H+ZcPMY3STFaHb2kAacsqoIkNx66O0T7sTpBxpxkMrFPyhkJiLJnJWMhk4bbvYD3BMA==",
       "dev": true,
       "requires": {
-        "@commitlint/format": "^16.0.0",
-        "@commitlint/lint": "^16.0.0",
-        "@commitlint/load": "^16.1.0",
-        "@commitlint/read": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/format": "^16.2.1",
+        "@commitlint/lint": "^16.2.4",
+        "@commitlint/load": "^16.3.0",
+        "@commitlint/read": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "lodash": "^4.17.19",
         "resolve-from": "5.0.0",
         "resolve-global": "1.0.0",
@@ -4264,141 +4130,142 @@
       }
     },
     "@commitlint/config-conventional": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.0.0.tgz",
-      "integrity": "sha512-mN7J8KlKFn0kROd+q9PB01sfDx/8K/R25yITspL1No8PB4oj9M1p77xWjP80hPydqZG9OvQq+anXK3ZWeR7s3g==",
+      "version": "16.2.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.2.4.tgz",
+      "integrity": "sha512-av2UQJa3CuE5P0dzxj/o/B9XVALqYzEViHrMXtDrW9iuflrqCStWBAioijppj9URyz6ONpohJKAtSdgAOE0gkA==",
       "dev": true,
       "requires": {
         "conventional-changelog-conventionalcommits": "^4.3.1"
       }
     },
     "@commitlint/config-validator": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.1.0.tgz",
-      "integrity": "sha512-2cHeZPNTuf1JWbMqyA46MkExor5HMSgv8JrdmzEakUbJHUreh35/wN00FJf57qGs134exQW2thiSQ1IJUsVx2Q==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.2.1.tgz",
+      "integrity": "sha512-hogSe0WGg7CKmp4IfNbdNES3Rq3UEI4XRPB8JL4EPgo/ORq5nrGTVzxJh78omibNuB8Ho4501Czb1Er1MoDWpw==",
       "dev": true,
       "requires": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "ajv": "^6.12.6"
       }
     },
     "@commitlint/cz-commitlint": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-16.1.0.tgz",
-      "integrity": "sha512-TThglfXEBW8TZ99dvaeto1c6hU25ONqL9qkENle2+1OFI64NgbICjLsJq7SVzJd4Jn/yZDp4xNqoV53WJPJ9aA==",
+      "version": "16.3.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-16.3.0.tgz",
+      "integrity": "sha512-Q+QLQmSIHEgzI18F3/7mqq3vwL0IN9k+Tjp9Um4adFnRXMtUTnEa0er0CXAXxWvoA/x/6nt3t7faAv2HugDIGg==",
       "dev": true,
       "requires": {
-        "@commitlint/ensure": "^16.0.0",
-        "@commitlint/load": "^16.1.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/ensure": "^16.2.1",
+        "@commitlint/load": "^16.3.0",
+        "@commitlint/types": "^16.2.1",
         "chalk": "^4.1.0",
         "lodash": "^4.17.21",
         "word-wrap": "^1.2.3"
       }
     },
     "@commitlint/ensure": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.0.0.tgz",
-      "integrity": "sha512-WdMySU8DCTaq3JPf0tZFCKIUhqxaL54mjduNhu8v4D2AMUVIIQKYMGyvXn94k8begeW6iJkTf9cXBArayskE7Q==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.2.1.tgz",
+      "integrity": "sha512-/h+lBTgf1r5fhbDNHOViLuej38i3rZqTQnBTk+xEg+ehOwQDXUuissQ5GsYXXqI5uGy+261ew++sT4EA3uBJ+A==",
       "dev": true,
       "requires": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "lodash": "^4.17.19"
       }
     },
     "@commitlint/execute-rule": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.0.0.tgz",
-      "integrity": "sha512-8edcCibmBb386x5JTHSPHINwA5L0xPkHQFY8TAuDEt5QyRZY/o5DF8OPHSa5Hx2xJvGaxxuIz4UtAT6IiRDYkw==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.2.1.tgz",
+      "integrity": "sha512-oSls82fmUTLM6cl5V3epdVo4gHhbmBFvCvQGHBRdQ50H/690Uq1Dyd7hXMuKITCIdcnr9umyDkr8r5C6HZDF3g==",
       "dev": true
     },
     "@commitlint/format": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.0.0.tgz",
-      "integrity": "sha512-9yp5NCquXL1jVMKL0ZkRwJf/UHdebvCcMvICuZV00NQGYSAL89O398nhqrqxlbjBhM5EZVq0VGcV5+7r3D4zAA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.2.1.tgz",
+      "integrity": "sha512-Yyio9bdHWmNDRlEJrxHKglamIk3d6hC0NkEUW6Ti6ipEh2g0BAhy8Od6t4vLhdZRa1I2n+gY13foy+tUgk0i1Q==",
       "dev": true,
       "requires": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "chalk": "^4.0.0"
       }
     },
     "@commitlint/is-ignored": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.0.0.tgz",
-      "integrity": "sha512-gmAQcwIGC/R/Lp0CEb2b5bfGC7MT5rPe09N8kOGjO/NcdNmfFSZMquwrvNJsq9hnAP0skRdHIsqwlkENkN4Lag==",
+      "version": "16.2.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.2.4.tgz",
+      "integrity": "sha512-Lxdq9aOAYCOOOjKi58ulbwK/oBiiKz+7Sq0+/SpFIEFwhHkIVugvDvWjh2VRBXmRC/x5lNcjDcYEwS/uYUvlYQ==",
       "dev": true,
       "requires": {
-        "@commitlint/types": "^16.0.0",
-        "semver": "7.3.5"
+        "@commitlint/types": "^16.2.1",
+        "semver": "7.3.7"
       }
     },
     "@commitlint/lint": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.0.0.tgz",
-      "integrity": "sha512-HNl15bRC0h+pLzbMzQC3tM0j1aESXsLYhElqKnXcf5mnCBkBkHzu6WwJW8rZbfxX+YwJmNljN62cPhmdBo8x0A==",
+      "version": "16.2.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.2.4.tgz",
+      "integrity": "sha512-AUDuwOxb2eGqsXbTMON3imUGkc1jRdtXrbbohiLSCSk3jFVXgJLTMaEcr39pR00N8nE9uZ+V2sYaiILByZVmxQ==",
       "dev": true,
       "requires": {
-        "@commitlint/is-ignored": "^16.0.0",
-        "@commitlint/parse": "^16.0.0",
-        "@commitlint/rules": "^16.0.0",
-        "@commitlint/types": "^16.0.0"
+        "@commitlint/is-ignored": "^16.2.4",
+        "@commitlint/parse": "^16.2.1",
+        "@commitlint/rules": "^16.2.4",
+        "@commitlint/types": "^16.2.1"
       }
     },
     "@commitlint/load": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.1.0.tgz",
-      "integrity": "sha512-MtlEhKjP8jAF85jjX4mw8DUUwCxKsCgAc865hhpnwxjrfBcmGP7Up2AFE/M3ZMGDmSl1X1TMybQk/zohj8Cqdg==",
+      "version": "16.3.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.3.0.tgz",
+      "integrity": "sha512-3tykjV/iwbkv2FU9DG+NZ/JqmP0Nm3b7aDwgCNQhhKV5P74JAuByULkafnhn+zsFGypG1qMtI5u+BZoa9APm0A==",
       "dev": true,
       "requires": {
-        "@commitlint/config-validator": "^16.1.0",
-        "@commitlint/execute-rule": "^16.0.0",
-        "@commitlint/resolve-extends": "^16.1.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/config-validator": "^16.2.1",
+        "@commitlint/execute-rule": "^16.2.1",
+        "@commitlint/resolve-extends": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
+        "@types/node": ">=12",
         "chalk": "^4.0.0",
         "cosmiconfig": "^7.0.0",
-        "cosmiconfig-typescript-loader": "^1.0.0",
+        "cosmiconfig-typescript-loader": "^2.0.0",
         "lodash": "^4.17.19",
         "resolve-from": "^5.0.0",
         "typescript": "^4.4.3"
       }
     },
     "@commitlint/message": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.0.0.tgz",
-      "integrity": "sha512-CmK2074SH1Ws6kFMEKOKH/7hMekGVbOD6vb4alCOo2+33ZSLUIX8iNkDYyrw38Jwg6yWUhLjyQLUxREeV+QIUA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.2.1.tgz",
+      "integrity": "sha512-2eWX/47rftViYg7a3axYDdrgwKv32mxbycBJT6OQY/MJM7SUfYNYYvbMFOQFaA4xIVZt7t2Alyqslbl6blVwWw==",
       "dev": true
     },
     "@commitlint/parse": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.0.0.tgz",
-      "integrity": "sha512-F9EjFlMw4MYgBEqoRrWZZKQBzdiJzPBI0qFDFqwUvfQsMmXEREZ242T4R5bFwLINWaALFLHEIa/FXEPa6QxCag==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.2.1.tgz",
+      "integrity": "sha512-2NP2dDQNL378VZYioLrgGVZhWdnJO4nAxQl5LXwYb08nEcN+cgxHN1dJV8OLJ5uxlGJtDeR8UZZ1mnQ1gSAD/g==",
       "dev": true,
       "requires": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "conventional-changelog-angular": "^5.0.11",
         "conventional-commits-parser": "^3.2.2"
       }
     },
     "@commitlint/read": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.0.0.tgz",
-      "integrity": "sha512-H4T2zsfmYQK9B+JtoQaCXWBHUhgIJyOzWZjSfuIV9Ce69/OgHoffNpLZPF2lX6yKuDrS1SQFhI/kUCjVc/e4ew==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.2.1.tgz",
+      "integrity": "sha512-tViXGuaxLTrw2r7PiYMQOFA2fueZxnnt0lkOWqKyxT+n2XdEMGYcI9ID5ndJKXnfPGPppD0w/IItKsIXlZ+alw==",
       "dev": true,
       "requires": {
-        "@commitlint/top-level": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/top-level": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "fs-extra": "^10.0.0",
         "git-raw-commits": "^2.0.0"
       }
     },
     "@commitlint/resolve-extends": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.1.0.tgz",
-      "integrity": "sha512-8182s6AFoUFX6+FT1PgQDt15nO2ogdR/EN8SYVAdhNXw1rLz8kT5saB/ICw567GuRAUgFTUMGCXy3ctMOXPEDg==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.2.1.tgz",
+      "integrity": "sha512-NbbCMPKTFf2J805kwfP9EO+vV+XvnaHRcBy6ud5dF35dxMsvdJqke54W3XazXF1ZAxC4a3LBy4i/GNVBAthsEg==",
       "dev": true,
       "requires": {
-        "@commitlint/config-validator": "^16.1.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/config-validator": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "import-fresh": "^3.0.0",
         "lodash": "^4.17.19",
         "resolve-from": "^5.0.0",
@@ -4406,55 +4273,49 @@
       }
     },
     "@commitlint/rules": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.0.0.tgz",
-      "integrity": "sha512-AOl0y2SBTdJ1bvIv8nwHvQKRT/jC1xb09C5VZwzHoT8sE8F54KDeEzPCwHQFgUcWdGLyS10kkOTAH2MyA8EIlg==",
+      "version": "16.2.4",
+      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.2.4.tgz",
+      "integrity": "sha512-rK5rNBIN2ZQNQK+I6trRPK3dWa0MtaTN4xnwOma1qxa4d5wQMQJtScwTZjTJeallFxhOgbNOgr48AMHkdounVg==",
       "dev": true,
       "requires": {
-        "@commitlint/ensure": "^16.0.0",
-        "@commitlint/message": "^16.0.0",
-        "@commitlint/to-lines": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/ensure": "^16.2.1",
+        "@commitlint/message": "^16.2.1",
+        "@commitlint/to-lines": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "execa": "^5.0.0"
       }
     },
     "@commitlint/to-lines": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.0.0.tgz",
-      "integrity": "sha512-iN/qU38TCKU7uKOg6RXLpD49wNiuI0TqMqybHbjefUeP/Jmzxa8ishryj0uLyVdrAl1ZjGeD1ukXGMTtvqz8iA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.2.1.tgz",
+      "integrity": "sha512-9/VjpYj5j1QeY3eiog1zQWY6axsdWAc0AonUUfyZ7B0MVcRI0R56YsHAfzF6uK/g/WwPZaoe4Lb1QCyDVnpVaQ==",
       "dev": true
     },
     "@commitlint/top-level": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.0.0.tgz",
-      "integrity": "sha512-/Jt6NLxyFkpjL5O0jxurZPCHURZAm7cQCqikgPCwqPAH0TLgwqdHjnYipl8J+AGnAMGDip4FNLoYrtgIpZGBYw==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.2.1.tgz",
+      "integrity": "sha512-lS6GSieHW9y6ePL73ied71Z9bOKyK+Ib9hTkRsB8oZFAyQZcyRwq2w6nIa6Fngir1QW51oKzzaXfJL94qwImyw==",
       "dev": true,
       "requires": {
         "find-up": "^5.0.0"
       }
     },
     "@commitlint/types": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.0.0.tgz",
-      "integrity": "sha512-+0FvYOAS39bJ4aKjnYn/7FD4DfWkmQ6G/06I4F0Gvu4KS5twirEg8mIcLhmeRDOOKn4Tp8PwpLwBiSA6npEMQA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.2.1.tgz",
+      "integrity": "sha512-7/z7pA7BM0i8XvMSBynO7xsB3mVQPUZbVn6zMIlp/a091XJ3qAXRXc+HwLYhiIdzzS5fuxxNIHZMGHVD4HJxdA==",
       "dev": true,
       "requires": {
         "chalk": "^4.0.0"
       }
     },
-    "@cspotcode/source-map-consumer": {
-      "version": "0.8.0",
-      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
-      "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
-      "dev": true
-    },
     "@cspotcode/source-map-support": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz",
-      "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==",
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+      "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
       "dev": true,
       "requires": {
-        "@cspotcode/source-map-consumer": "0.8.0"
+        "@jridgewell/trace-mapping": "0.3.9"
       }
     },
     "@hutson/parse-repository-url": {
@@ -4463,28 +4324,50 @@
       "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==",
       "dev": true
     },
+    "@jridgewell/resolve-uri": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+      "dev": true
+    },
+    "@jridgewell/sourcemap-codec": {
+      "version": "1.4.14",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+      "dev": true
+    },
+    "@jridgewell/trace-mapping": {
+      "version": "0.3.9",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+      "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+      "dev": true,
+      "requires": {
+        "@jridgewell/resolve-uri": "^3.0.3",
+        "@jridgewell/sourcemap-codec": "^1.4.10"
+      }
+    },
     "@tsconfig/node10": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
-      "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
+      "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
       "dev": true
     },
     "@tsconfig/node12": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
-      "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+      "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
       "dev": true
     },
     "@tsconfig/node14": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
-      "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+      "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
       "dev": true
     },
     "@tsconfig/node16": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
-      "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
+      "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
       "dev": true
     },
     "@types/minimist": {
@@ -4494,11 +4377,10 @@
       "dev": true
     },
     "@types/node": {
-      "version": "17.0.10",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz",
-      "integrity": "sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog==",
-      "dev": true,
-      "peer": true
+      "version": "18.8.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.3.tgz",
+      "integrity": "sha512-0os9vz6BpGwxGe9LOhgP/ncvYN5Tx1fNcd2TM3rD/aCGBkysb+ZWpXEocG24h6ZzOi13+VB8HndAQFezsSOw1w==",
+      "dev": true
     },
     "@types/normalize-package-data": {
       "version": "2.4.1",
@@ -4513,9 +4395,9 @@
       "dev": true
     },
     "acorn": {
-      "version": "8.7.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
-      "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+      "version": "8.8.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
       "dev": true
     },
     "acorn-walk": {
@@ -4527,7 +4409,7 @@
     "add-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz",
-      "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=",
+      "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==",
       "dev": true
     },
     "ajv": {
@@ -4547,18 +4429,8 @@
       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
       "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
       "dev": true,
-      "peer": true,
       "requires": {
         "type-fest": "^0.21.3"
-      },
-      "dependencies": {
-        "type-fest": {
-          "version": "0.21.3",
-          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
-          "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
-          "dev": true,
-          "peer": true
-        }
       }
     },
     "ansi-regex": {
@@ -4591,13 +4463,19 @@
     "array-ify": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
-      "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=",
+      "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
       "dev": true
     },
     "arrify": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
-      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
+      "dev": true
+    },
+    "at-least-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
       "dev": true
     },
     "balanced-match": {
@@ -4610,15 +4488,13 @@
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
       "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "bl": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
       "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
       "dev": true,
-      "peer": true,
       "requires": {
         "buffer": "^5.5.0",
         "inherits": "^2.0.4",
@@ -4649,7 +4525,6 @@
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
       "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
       "dev": true,
-      "peer": true,
       "requires": {
         "base64-js": "^1.3.1",
         "ieee754": "^1.1.13"
@@ -4662,9 +4537,9 @@
       "dev": true
     },
     "cachedir": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.2.0.tgz",
-      "integrity": "sha512-VvxA0xhNqIIfg0V9AmJkDg91DaJwryutH5rVEZAhcNi4iJFj9f+QxmAjgK1LT9I8OgToX27fypX6/MeCXVbBjQ==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
+      "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==",
       "dev": true
     },
     "callsites": {
@@ -4711,315 +4586,87 @@
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
       "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
       "dev": true,
-      "peer": true,
       "requires": {
         "restore-cursor": "^3.1.0"
       }
     },
     "cli-spinners": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz",
-      "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==",
-      "dev": true,
-      "peer": true
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz",
+      "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==",
+      "dev": true
     },
     "cli-width": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
       "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
-      "dev": true,
-      "peer": true
-    },
-    "cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
-      "dev": true,
-      "requires": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^7.0.0"
-      }
-    },
-    "clone": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
-      "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
-      "dev": true,
-      "peer": true
-    },
-    "color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "requires": {
-        "color-name": "~1.1.4"
-      }
-    },
-    "color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
-    },
-    "commitizen": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.2.4.tgz",
-      "integrity": "sha512-LlZChbDzg3Ir3O2S7jSo/cgWp5/QwylQVr59K4xayVq8S4/RdKzSyJkghAiZZHfhh5t4pxunUoyeg0ml1q/7aw==",
-      "dev": true,
-      "requires": {
-        "cachedir": "2.2.0",
-        "cz-conventional-changelog": "3.2.0",
-        "dedent": "0.7.0",
-        "detect-indent": "6.0.0",
-        "find-node-modules": "^2.1.2",
-        "find-root": "1.1.0",
-        "fs-extra": "8.1.0",
-        "glob": "7.1.4",
-        "inquirer": "6.5.2",
-        "is-utf8": "^0.2.1",
-        "lodash": "^4.17.20",
-        "minimist": "1.2.5",
-        "strip-bom": "4.0.0",
-        "strip-json-comments": "3.0.1"
-      },
-      "dependencies": {
-        "ansi-escapes": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
-          "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
-          "dev": true
-        },
-        "ansi-regex": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
-          "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "cli-cursor": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
-          "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
-          "dev": true,
-          "requires": {
-            "restore-cursor": "^2.0.0"
-          }
-        },
-        "cli-width": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
-          "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
-          "dev": true
-        },
-        "color-convert": {
-          "version": "1.9.3",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "cz-conventional-changelog": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.2.0.tgz",
-          "integrity": "sha512-yAYxeGpVi27hqIilG1nh4A9Bnx4J3Ov+eXy4koL3drrR+IO9GaWPsKjik20ht608Asqi8TQPf0mczhEeyAtMzg==",
-          "dev": true,
-          "requires": {
-            "@commitlint/load": ">6.1.1",
-            "chalk": "^2.4.1",
-            "commitizen": "^4.0.3",
-            "conventional-commit-types": "^3.0.0",
-            "lodash.map": "^4.5.1",
-            "longest": "^2.0.1",
-            "word-wrap": "^1.0.3"
-          }
-        },
-        "figures": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
-          "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
-          "dev": true,
-          "requires": {
-            "escape-string-regexp": "^1.0.5"
-          }
-        },
+    },
+    "cliui": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+      "dev": true,
+      "requires": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.1",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
+    "clone": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+      "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+      "dev": true
+    },
+    "color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "requires": {
+        "color-name": "~1.1.4"
+      }
+    },
+    "color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
+    "commitizen": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.2.5.tgz",
+      "integrity": "sha512-9sXju8Qrz1B4Tw7kC5KhnvwYQN88qs2zbiB8oyMsnXZyJ24PPGiNM3nHr73d32dnE3i8VJEXddBFIbOgYSEXtQ==",
+      "dev": true,
+      "requires": {
+        "cachedir": "2.3.0",
+        "cz-conventional-changelog": "3.3.0",
+        "dedent": "0.7.0",
+        "detect-indent": "6.1.0",
+        "find-node-modules": "^2.1.2",
+        "find-root": "1.1.0",
+        "fs-extra": "9.1.0",
+        "glob": "7.2.3",
+        "inquirer": "8.2.4",
+        "is-utf8": "^0.2.1",
+        "lodash": "4.17.21",
+        "minimist": "1.2.6",
+        "strip-bom": "4.0.0",
+        "strip-json-comments": "3.1.1"
+      },
+      "dependencies": {
         "fs-extra": {
-          "version": "8.1.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
-          "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+          "version": "9.1.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+          "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
           "dev": true,
           "requires": {
+            "at-least-node": "^1.0.0",
             "graceful-fs": "^4.2.0",
-            "jsonfile": "^4.0.0",
-            "universalify": "^0.1.0"
-          }
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-          "dev": true
-        },
-        "inquirer": {
-          "version": "6.5.2",
-          "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
-          "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
-          "dev": true,
-          "requires": {
-            "ansi-escapes": "^3.2.0",
-            "chalk": "^2.4.2",
-            "cli-cursor": "^2.1.0",
-            "cli-width": "^2.0.0",
-            "external-editor": "^3.0.3",
-            "figures": "^2.0.0",
-            "lodash": "^4.17.12",
-            "mute-stream": "0.0.7",
-            "run-async": "^2.2.0",
-            "rxjs": "^6.4.0",
-            "string-width": "^2.1.0",
-            "strip-ansi": "^5.1.0",
-            "through": "^2.3.6"
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
-          "dev": true
-        },
-        "jsonfile": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-          "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
-          "dev": true,
-          "requires": {
-            "graceful-fs": "^4.1.6"
-          }
-        },
-        "mimic-fn": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
-          "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
-          "dev": true
-        },
-        "mute-stream": {
-          "version": "0.0.7",
-          "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
-          "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
-          "dev": true
-        },
-        "onetime": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
-          "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
-          "dev": true,
-          "requires": {
-            "mimic-fn": "^1.0.0"
-          }
-        },
-        "restore-cursor": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
-          "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
-          "dev": true,
-          "requires": {
-            "onetime": "^2.0.0",
-            "signal-exit": "^3.0.2"
-          }
-        },
-        "rxjs": {
-          "version": "6.6.7",
-          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
-          "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
-          "dev": true,
-          "requires": {
-            "tslib": "^1.9.0"
-          }
-        },
-        "string-width": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
-          "dev": true,
-          "requires": {
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^4.0.0"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "3.0.1",
-              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
-              "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
-              "dev": true
-            },
-            "strip-ansi": {
-              "version": "4.0.0",
-              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-              "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
-              "dev": true,
-              "requires": {
-                "ansi-regex": "^3.0.0"
-              }
-            }
-          }
-        },
-        "strip-ansi": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
-          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^4.1.0"
-          }
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
+            "jsonfile": "^6.0.1",
+            "universalify": "^2.0.0"
           }
-        },
-        "tslib": {
-          "version": "1.14.1",
-          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-          "dev": true
-        },
-        "universalify": {
-          "version": "0.1.2",
-          "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-          "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
-          "dev": true
         }
       }
     },
@@ -5036,7 +4683,7 @@
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
       "dev": true
     },
     "concat-stream": {
@@ -5052,9 +4699,9 @@
       }
     },
     "conventional-changelog": {
-      "version": "3.1.24",
-      "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.24.tgz",
-      "integrity": "sha512-ed6k8PO00UVvhExYohroVPXcOJ/K1N0/drJHx/faTH37OIZthlecuLIRX/T6uOp682CAoVoFpu+sSEaeuH6Asg==",
+      "version": "3.1.25",
+      "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz",
+      "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==",
       "dev": true,
       "requires": {
         "conventional-changelog-angular": "^5.0.12",
@@ -5105,9 +4752,9 @@
       "dev": true
     },
     "conventional-changelog-conventionalcommits": {
-      "version": "4.6.1",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.1.tgz",
-      "integrity": "sha512-lzWJpPZhbM1R0PIzkwzGBCnAkH5RKJzJfFQZcl/D+2lsJxAwGnDKBqn/F4C1RD31GJNn8NuKWQzAZDAVXPp2Mw==",
+      "version": "4.6.3",
+      "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz",
+      "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==",
       "dev": true,
       "requires": {
         "compare-func": "^2.0.0",
@@ -5140,7 +4787,7 @@
         "find-up": {
           "version": "2.1.0",
           "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
-          "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+          "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
           "dev": true,
           "requires": {
             "locate-path": "^2.0.0"
@@ -5155,7 +4802,7 @@
         "locate-path": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
-          "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+          "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
           "dev": true,
           "requires": {
             "p-locate": "^2.0.0",
@@ -5174,22 +4821,16 @@
         "p-locate": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
-          "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+          "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
           "dev": true,
           "requires": {
             "p-limit": "^1.1.0"
           }
         },
-        "p-try": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
-          "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
-          "dev": true
-        },
         "path-exists": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
           "dev": true
         },
         "path-type": {
@@ -5204,13 +4845,13 @@
         "pify": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
           "dev": true
         },
         "read-pkg": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
-          "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+          "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
           "dev": true,
           "requires": {
             "load-json-file": "^4.0.0",
@@ -5235,7 +4876,7 @@
         "read-pkg-up": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
-          "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=",
+          "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==",
           "dev": true,
           "requires": {
             "find-up": "^2.0.0",
@@ -5312,14 +4953,14 @@
       }
     },
     "conventional-changelog-writer": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz",
-      "integrity": "sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz",
+      "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==",
       "dev": true,
       "requires": {
         "conventional-commits-filter": "^2.0.7",
         "dateformat": "^3.0.0",
-        "handlebars": "^4.7.6",
+        "handlebars": "^4.7.7",
         "json-stringify-safe": "^5.0.1",
         "lodash": "^4.17.15",
         "meow": "^8.0.0",
@@ -5353,9 +4994,9 @@
       }
     },
     "conventional-commits-parser": {
-      "version": "3.2.3",
-      "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz",
-      "integrity": "sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw==",
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz",
+      "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==",
       "dev": true,
       "requires": {
         "is-text-path": "^1.0.1",
@@ -5402,13 +5043,13 @@
       }
     },
     "cosmiconfig-typescript-loader": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-1.0.4.tgz",
-      "integrity": "sha512-ulv2dvwurP/MZAIthXm69bO7EzzIUThZ6RJ1qXhdlXM6to3F+IKBL/17EnhYSG52A5N1KcAUu66vSG/3/77KrA==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-2.0.2.tgz",
+      "integrity": "sha512-KmE+bMjWMXJbkWCeY4FJX/npHuZPNr9XF9q9CIQ/bpFwi1qHfCmSiKarrCcRa0LO4fWjk93pVoeRtJAkTGcYNw==",
       "dev": true,
       "requires": {
         "cosmiconfig": "^7",
-        "ts-node": "^10.4.0"
+        "ts-node": "^10.8.1"
       }
     },
     "create-require": {
@@ -5426,15 +5067,71 @@
         "path-key": "^3.1.0",
         "shebang-command": "^2.0.0",
         "which": "^2.0.1"
+      }
+    },
+    "cz-conventional-changelog": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz",
+      "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==",
+      "dev": true,
+      "requires": {
+        "@commitlint/load": ">6.1.1",
+        "chalk": "^2.4.1",
+        "commitizen": "^4.0.3",
+        "conventional-commit-types": "^3.0.0",
+        "lodash.map": "^4.5.1",
+        "longest": "^2.0.1",
+        "word-wrap": "^1.0.3"
       },
       "dependencies": {
-        "which": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
           "dev": true,
           "requires": {
-            "isexe": "^2.0.0"
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "color-convert": {
+          "version": "1.9.3",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+          "dev": true,
+          "requires": {
+            "color-name": "1.1.3"
+          }
+        },
+        "color-name": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+          "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
           }
         }
       }
@@ -5454,13 +5151,13 @@
     "decamelize": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
       "dev": true
     },
     "decamelize-keys": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
-      "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=",
+      "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==",
       "dev": true,
       "requires": {
         "decamelize": "^1.1.0",
@@ -5470,7 +5167,7 @@
         "map-obj": {
           "version": "1.0.1",
           "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
-          "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+          "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
           "dev": true
         }
       }
@@ -5478,15 +5175,14 @@
     "dedent": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
-      "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
+      "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
       "dev": true
     },
     "defaults": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
-      "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+      "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
       "dev": true,
-      "peer": true,
       "requires": {
         "clone": "^1.0.2"
       }
@@ -5494,13 +5190,13 @@
     "detect-file": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
-      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+      "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
       "dev": true
     },
     "detect-indent": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz",
-      "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
+      "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
       "dev": true
     },
     "detect-newline": {
@@ -5571,10 +5267,16 @@
             "p-limit": "^2.0.0"
           }
         },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
         "path-exists": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
           "dev": true
         }
       }
@@ -5603,7 +5305,7 @@
     "escape-string-regexp": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
       "dev": true
     },
     "execa": {
@@ -5626,7 +5328,7 @@
     "expand-tilde": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
-      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+      "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
       "dev": true,
       "requires": {
         "homedir-polyfill": "^1.0.1"
@@ -5674,13 +5376,13 @@
       }
     },
     "find-node-modules": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.2.tgz",
-      "integrity": "sha512-x+3P4mbtRPlSiVE1Qco0Z4YLU8WFiFcuWTf3m75OV9Uzcfs2Bg+O9N+r/K0AnmINBW06KpfqKwYJbFlFq4qNug==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz",
+      "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==",
       "dev": true,
       "requires": {
         "findup-sync": "^4.0.0",
-        "merge": "^2.1.0"
+        "merge": "^2.1.1"
       }
     },
     "find-root": {
@@ -5711,19 +5413,10 @@
         "resolve-dir": "^1.0.1"
       }
     },
-    "fs-access": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz",
-      "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=",
-      "dev": true,
-      "requires": {
-        "null-check": "^1.0.0"
-      }
-    },
     "fs-extra": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-      "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dev": true,
       "requires": {
         "graceful-fs": "^4.2.0",
@@ -5734,7 +5427,7 @@
     "fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
       "dev": true
     },
     "function-bind": {
@@ -5761,6 +5454,17 @@
         "yargs": "^16.2.0"
       },
       "dependencies": {
+        "cliui": {
+          "version": "7.0.4",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+          "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+          "dev": true,
+          "requires": {
+            "string-width": "^4.2.0",
+            "strip-ansi": "^6.0.0",
+            "wrap-ansi": "^7.0.0"
+          }
+        },
         "readable-stream": {
           "version": "2.3.7",
           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
@@ -5825,9 +5529,9 @@
       "dev": true
     },
     "git-raw-commits": {
-      "version": "2.0.10",
-      "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz",
-      "integrity": "sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ==",
+      "version": "2.0.11",
+      "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz",
+      "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==",
       "dev": true,
       "requires": {
         "dargs": "^7.0.0",
@@ -5840,7 +5544,7 @@
     "git-remote-origin-url": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz",
-      "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=",
+      "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==",
       "dev": true,
       "requires": {
         "gitconfiglocal": "^1.0.0",
@@ -5868,22 +5572,22 @@
     "gitconfiglocal": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz",
-      "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=",
+      "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==",
       "dev": true,
       "requires": {
         "ini": "^1.3.2"
       }
     },
     "glob": {
-      "version": "7.1.4",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
-      "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
       "dev": true,
       "requires": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
         "inherits": "2",
-        "minimatch": "^3.0.4",
+        "minimatch": "^3.1.1",
         "once": "^1.3.0",
         "path-is-absolute": "^1.0.0"
       }
@@ -5891,7 +5595,7 @@
     "global-dirs": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
-      "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+      "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==",
       "dev": true,
       "requires": {
         "ini": "^1.3.4"
@@ -5911,7 +5615,7 @@
     "global-prefix": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
-      "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+      "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
       "dev": true,
       "requires": {
         "expand-tilde": "^2.0.2",
@@ -5919,12 +5623,23 @@
         "ini": "^1.3.4",
         "is-windows": "^1.0.1",
         "which": "^1.2.14"
+      },
+      "dependencies": {
+        "which": {
+          "version": "1.3.1",
+          "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+          "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
       }
     },
     "graceful-fs": {
-      "version": "4.2.6",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
-      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+      "version": "4.2.10",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
     "handlebars": {
@@ -5971,9 +5686,9 @@
       }
     },
     "hosted-git-info": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz",
-      "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
       "dev": true,
       "requires": {
         "lru-cache": "^6.0.0"
@@ -6004,8 +5719,7 @@
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
       "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "import-fresh": {
       "version": "3.3.0",
@@ -6034,7 +5748,7 @@
     "inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
       "dev": true,
       "requires": {
         "once": "^1.3.0",
@@ -6054,11 +5768,10 @@
       "dev": true
     },
     "inquirer": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz",
-      "integrity": "sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ==",
+      "version": "8.2.4",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz",
+      "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==",
       "dev": true,
-      "peer": true,
       "requires": {
         "ansi-escapes": "^4.2.1",
         "chalk": "^4.1.1",
@@ -6070,22 +5783,23 @@
         "mute-stream": "0.0.8",
         "ora": "^5.4.1",
         "run-async": "^2.4.0",
-        "rxjs": "^7.2.0",
+        "rxjs": "^7.5.5",
         "string-width": "^4.1.0",
         "strip-ansi": "^6.0.0",
-        "through": "^2.3.6"
+        "through": "^2.3.6",
+        "wrap-ansi": "^7.0.0"
       }
     },
     "is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
       "dev": true
     },
     "is-core-module": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
-      "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+      "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
       "dev": true,
       "requires": {
         "has": "^1.0.3"
@@ -6094,7 +5808,7 @@
     "is-extglob": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
       "dev": true
     },
     "is-fullwidth-code-point": {
@@ -6104,9 +5818,9 @@
       "dev": true
     },
     "is-glob": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
-      "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
       "dev": true,
       "requires": {
         "is-extglob": "^2.1.1"
@@ -6116,8 +5830,7 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
       "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "is-number": {
       "version": "7.0.0",
@@ -6134,7 +5847,7 @@
     "is-plain-obj": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
-      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
       "dev": true
     },
     "is-stream": {
@@ -6146,7 +5859,7 @@
     "is-text-path": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz",
-      "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=",
+      "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==",
       "dev": true,
       "requires": {
         "text-extensions": "^1.0.0"
@@ -6156,13 +5869,12 @@
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
       "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "is-utf8": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
-      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==",
       "dev": true
     },
     "is-windows": {
@@ -6174,13 +5886,13 @@
     "isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
       "dev": true
     },
     "isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
     },
     "js-tokens": {
@@ -6219,7 +5931,7 @@
     "json-stringify-safe": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
       "dev": true
     },
     "jsonfile": {
@@ -6235,7 +5947,7 @@
     "jsonparse": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
-      "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
+      "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
       "dev": true
     },
     "JSONStream": {
@@ -6255,15 +5967,15 @@
       "dev": true
     },
     "lines-and-columns": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
-      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
       "dev": true
     },
     "load-json-file": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
-      "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+      "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
       "dev": true,
       "requires": {
         "graceful-fs": "^4.1.2",
@@ -6275,7 +5987,7 @@
         "parse-json": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
-          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
           "dev": true,
           "requires": {
             "error-ex": "^1.3.1",
@@ -6285,13 +5997,13 @@
         "pify": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
           "dev": true
         },
         "strip-bom": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
           "dev": true
         }
       }
@@ -6314,13 +6026,13 @@
     "lodash.ismatch": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz",
-      "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=",
+      "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==",
       "dev": true
     },
     "lodash.map": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz",
-      "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=",
+      "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==",
       "dev": true
     },
     "log-symbols": {
@@ -6328,7 +6040,6 @@
       "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
       "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
       "dev": true,
-      "peer": true,
       "requires": {
         "chalk": "^4.1.0",
         "is-unicode-supported": "^0.1.0"
@@ -6337,7 +6048,7 @@
     "longest": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz",
-      "integrity": "sha1-eB4YMpaqlPbU2RbcM10NF676I/g=",
+      "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==",
       "dev": true
     },
     "lru-cache": {
@@ -6378,6 +6089,14 @@
         "trim-newlines": "^3.0.0",
         "type-fest": "^0.18.0",
         "yargs-parser": "^20.2.3"
+      },
+      "dependencies": {
+        "type-fest": {
+          "version": "0.18.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
+          "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+          "dev": true
+        }
       }
     },
     "merge": {
@@ -6393,13 +6112,13 @@
       "dev": true
     },
     "micromatch": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
-      "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
       "dev": true,
       "requires": {
-        "braces": "^3.0.1",
-        "picomatch": "^2.2.3"
+        "braces": "^3.0.2",
+        "picomatch": "^2.3.1"
       }
     },
     "mimic-fn": {
@@ -6415,18 +6134,18 @@
       "dev": true
     },
     "minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "dev": true,
       "requires": {
         "brace-expansion": "^1.1.7"
       }
     },
     "minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
       "dev": true
     },
     "minimist-options": {
@@ -6450,8 +6169,7 @@
       "version": "0.0.8",
       "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
       "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "neo-async": {
       "version": "2.6.2",
@@ -6480,16 +6198,10 @@
         "path-key": "^3.0.0"
       }
     },
-    "null-check": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz",
-      "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=",
-      "dev": true
-    },
     "once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
       "dev": true,
       "requires": {
         "wrappy": "1"
@@ -6509,7 +6221,6 @@
       "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
       "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
       "dev": true,
-      "peer": true,
       "requires": {
         "bl": "^4.1.0",
         "chalk": "^4.1.0",
@@ -6525,7 +6236,7 @@
     "os-tmpdir": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
       "dev": true
     },
     "p-limit": {
@@ -6547,9 +6258,9 @@
       }
     },
     "p-try": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+      "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
       "dev": true
     },
     "parent-module": {
@@ -6576,7 +6287,7 @@
     "parse-passwd": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
-      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+      "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
       "dev": true
     },
     "path-exists": {
@@ -6588,7 +6299,7 @@
     "path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
       "dev": true
     },
     "path-key": {
@@ -6610,15 +6321,15 @@
       "dev": true
     },
     "picomatch": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz",
-      "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==",
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
       "dev": true
     },
     "pify": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
       "dev": true
     },
     "process-nextick-args": {
@@ -6636,7 +6347,7 @@
     "q": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
-      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
+      "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
       "dev": true
     },
     "quick-lru": {
@@ -6737,6 +6448,12 @@
             "p-limit": "^2.2.0"
           }
         },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
         "type-fest": {
           "version": "0.8.1",
           "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
@@ -6769,23 +6486,24 @@
     "require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
       "dev": true
     },
     "resolve": {
-      "version": "1.20.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
-      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+      "version": "1.22.1",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
       "dev": true,
       "requires": {
-        "is-core-module": "^2.2.0",
-        "path-parse": "^1.0.6"
+        "is-core-module": "^2.9.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
       }
     },
     "resolve-dir": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
-      "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+      "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
       "dev": true,
       "requires": {
         "expand-tilde": "^2.0.0",
@@ -6812,7 +6530,6 @@
       "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
       "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
       "dev": true,
-      "peer": true,
       "requires": {
         "onetime": "^5.1.0",
         "signal-exit": "^3.0.2"
@@ -6825,13 +6542,12 @@
       "dev": true
     },
     "rxjs": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz",
-      "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==",
+      "version": "7.5.7",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz",
+      "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==",
       "dev": true,
-      "peer": true,
       "requires": {
-        "tslib": "~2.1.0"
+        "tslib": "^2.1.0"
       }
     },
     "safe-buffer": {
@@ -6847,9 +6563,9 @@
       "dev": true
     },
     "semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+      "version": "7.3.7",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
       "dev": true,
       "requires": {
         "lru-cache": "^6.0.0"
@@ -6871,9 +6587,9 @@
       "dev": true
     },
     "signal-exit": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
-      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
       "dev": true
     },
     "source-map": {
@@ -6909,9 +6625,9 @@
       }
     },
     "spdx-license-ids": {
-      "version": "3.0.10",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz",
-      "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==",
+      "version": "3.0.12",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz",
+      "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
       "dev": true
     },
     "split": {
@@ -6933,22 +6649,21 @@
       }
     },
     "standard-version": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.3.2.tgz",
-      "integrity": "sha512-u1rfKP4o4ew7Yjbfycv80aNMN2feTiqseAhUhrrx2XtdQGmu7gucpziXe68Z4YfHVqlxVEzo4aUA0Iu3VQOTgQ==",
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz",
+      "integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==",
       "dev": true,
       "requires": {
         "chalk": "^2.4.2",
-        "conventional-changelog": "3.1.24",
+        "conventional-changelog": "3.1.25",
         "conventional-changelog-config-spec": "2.1.0",
-        "conventional-changelog-conventionalcommits": "4.6.1",
+        "conventional-changelog-conventionalcommits": "4.6.3",
         "conventional-recommended-bump": "6.1.0",
         "detect-indent": "^6.0.0",
         "detect-newline": "^3.1.0",
         "dotgitignore": "^2.1.0",
         "figures": "^3.1.0",
         "find-up": "^5.0.0",
-        "fs-access": "^1.0.1",
         "git-semver-tags": "^4.0.0",
         "semver": "^7.1.1",
         "stringify-package": "^1.0.1",
@@ -6975,6 +6690,17 @@
             "supports-color": "^5.3.0"
           }
         },
+        "cliui": {
+          "version": "7.0.4",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+          "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+          "dev": true,
+          "requires": {
+            "string-width": "^4.2.0",
+            "strip-ansi": "^6.0.0",
+            "wrap-ansi": "^7.0.0"
+          }
+        },
         "color-convert": {
           "version": "1.9.3",
           "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -6987,13 +6713,13 @@
         "color-name": {
           "version": "1.1.3",
           "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+          "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
           "dev": true
         },
         "has-flag": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
           "dev": true
         },
         "supports-color": {
@@ -7079,9 +6805,9 @@
       }
     },
     "strip-json-comments": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
-      "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
       "dev": true
     },
     "supports-color": {
@@ -7093,6 +6819,12 @@
         "has-flag": "^4.0.0"
       }
     },
+    "supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true
+    },
     "text-extensions": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz",
@@ -7102,7 +6834,7 @@
     "through": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
       "dev": true
     },
     "through2": {
@@ -7139,12 +6871,12 @@
       "dev": true
     },
     "ts-node": {
-      "version": "10.4.0",
-      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz",
-      "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==",
+      "version": "10.9.1",
+      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
+      "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
       "dev": true,
       "requires": {
-        "@cspotcode/source-map-support": "0.7.0",
+        "@cspotcode/source-map-support": "^0.8.0",
         "@tsconfig/node10": "^1.0.7",
         "@tsconfig/node12": "^1.0.7",
         "@tsconfig/node14": "^1.0.0",
@@ -7155,38 +6887,38 @@
         "create-require": "^1.1.0",
         "diff": "^4.0.1",
         "make-error": "^1.1.1",
+        "v8-compile-cache-lib": "^3.0.1",
         "yn": "3.1.1"
       }
     },
     "tslib": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
-      "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==",
-      "dev": true,
-      "peer": true
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+      "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
+      "dev": true
     },
     "type-fest": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
-      "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+      "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
       "dev": true
     },
     "typedarray": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
       "dev": true
     },
     "typescript": {
-      "version": "4.5.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
-      "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
+      "version": "4.8.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
+      "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
       "dev": true
     },
     "uglify-js": {
-      "version": "3.14.3",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.3.tgz",
-      "integrity": "sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==",
+      "version": "3.17.3",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz",
+      "integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==",
       "dev": true,
       "optional": true
     },
@@ -7208,9 +6940,15 @@
     "util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
       "dev": true
     },
+    "v8-compile-cache-lib": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+      "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+      "dev": true
+    },
     "validate-npm-package-license": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -7224,17 +6962,16 @@
     "wcwidth": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
-      "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
+      "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
       "dev": true,
-      "peer": true,
       "requires": {
         "defaults": "^1.0.3"
       }
     },
     "which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
       "dev": true,
       "requires": {
         "isexe": "^2.0.0"
@@ -7249,7 +6986,7 @@
     "wordwrap": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
-      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+      "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
       "dev": true
     },
     "wrap-ansi": {
@@ -7266,7 +7003,7 @@
     "wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
       "dev": true
     },
     "xtend": {
@@ -7294,18 +7031,26 @@
       "dev": true
     },
     "yargs": {
-      "version": "17.2.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz",
-      "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==",
+      "version": "17.6.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz",
+      "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==",
       "dev": true,
       "requires": {
-        "cliui": "^7.0.2",
+        "cliui": "^8.0.1",
         "escalade": "^3.1.1",
         "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
-        "string-width": "^4.2.0",
+        "string-width": "^4.2.3",
         "y18n": "^5.0.5",
-        "yargs-parser": "^20.2.2"
+        "yargs-parser": "^21.0.0"
+      },
+      "dependencies": {
+        "yargs-parser": {
+          "version": "21.1.1",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+          "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+          "dev": true
+        }
       }
     },
     "yargs-parser": {
diff --git a/plat/arm/board/fvp/fvp_drtm_addr.c b/plat/arm/board/fvp/fvp_drtm_addr.c
new file mode 100644
index 0000000..eeaa342
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_drtm_addr.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Check passed region is within Non-Secure region of DRAM
+ ******************************************************************************/
+int plat_drtm_validate_ns_region(uintptr_t region_start,
+				 size_t region_size)
+{
+	uintptr_t region_end = region_start + region_size - 1;
+
+	if (region_start >= region_end) {
+		return -1;
+	} else if ((region_start >= ARM_NS_DRAM1_BASE) &&
+		   (region_start < (ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE)) &&
+		   (region_end >= ARM_NS_DRAM1_BASE) &&
+		   (region_end < (ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE))) {
+		return 0;
+	} else if ((region_start >= ARM_DRAM2_BASE) &&
+		   (region_start < (ARM_DRAM2_BASE + ARM_DRAM2_SIZE)) &&
+		   (region_end >= ARM_DRAM2_BASE) &&
+		   (region_end < (ARM_DRAM2_BASE + ARM_DRAM2_SIZE))) {
+		return 0;
+	}
+
+	return -1;
+}
diff --git a/plat/arm/board/fvp/fvp_drtm_dma_prot.c b/plat/arm/board/fvp/fvp_drtm_dma_prot.c
new file mode 100644
index 0000000..38ff7fe
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_drtm_dma_prot.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#include <drivers/arm/smmu_v3.h>
+#include <lib/utils_def.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/**
+ * Array mentioning number of SMMUs supported by FVP
+ */
+static const uintptr_t fvp_smmus[] = {
+	PLAT_FVP_SMMUV3_BASE,
+};
+
+bool plat_has_non_host_platforms(void)
+{
+	/* FVP base platforms typically have GPU, as per FVP Reference guide */
+	return true;
+}
+
+bool plat_has_unmanaged_dma_peripherals(void)
+{
+	/*
+	 * FVP Reference guide does not show devices that are described as
+	 * DMA-capable but not managed by an SMMU in the FVP documentation.
+	 * However, the SMMU seems to have only been introduced in the RevC
+	 * revision.
+	 */
+	return (arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) == 0;
+}
+
+unsigned int plat_get_total_smmus(void)
+{
+	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) {
+		return ARRAY_SIZE(fvp_smmus);
+	} else {
+		return 0;
+	}
+}
+
+void plat_enumerate_smmus(const uintptr_t **smmus_out,
+			  size_t *smmu_count_out)
+{
+	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) {
+		*smmus_out = fvp_smmus;
+		*smmu_count_out = ARRAY_SIZE(fvp_smmus);
+	} else {
+		*smmus_out = NULL;
+		*smmu_count_out = 0;
+	}
+}
+
+/* DRTM DMA Protection Features */
+static const plat_drtm_dma_prot_features_t dma_prot_features = {
+	.max_num_mem_prot_regions = 0, /* No protection regions are present */
+	.dma_protection_support = 0x1 /* Complete DMA protection only */
+};
+
+const plat_drtm_dma_prot_features_t *plat_drtm_get_dma_prot_features(void)
+{
+	return &dma_prot_features;
+}
+
+uint64_t plat_drtm_dma_prot_get_max_table_bytes(void)
+{
+	return 0U;
+}
diff --git a/plat/arm/board/fvp/fvp_drtm_err.c b/plat/arm/board/fvp/fvp_drtm_err.c
new file mode 100644
index 0000000..95259fa
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_drtm_err.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <plat/common/platform.h>
+
+int plat_set_drtm_error(uint64_t error_code)
+{
+	/* TODO: Set DRTM error in NV-storage */
+	return 0;
+}
+
+int plat_get_drtm_error(uint64_t *error_code)
+{
+	/* TODO: Get DRTM error from NV-storage */
+	*error_code = 0;
+	return 0;
+}
diff --git a/plat/arm/board/fvp/fvp_drtm_measurement.c b/plat/arm/board/fvp/fvp_drtm_measurement.c
new file mode 100644
index 0000000..4fbedd8
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_drtm_measurement.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <drivers/measured_boot/event_log/event_log.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/* DRTM TPM Features */
+static const plat_drtm_tpm_features_t tpm_features = {
+	/* No TPM-based hashing supported. */
+	.tpm_based_hash_support = false,
+
+	/* Set to decided algorithm by Event Log driver */
+	.firmware_hash_algorithm = TPM_ALG_ID
+
+};
+
+const plat_drtm_tpm_features_t *plat_drtm_get_tpm_features(void)
+{
+	return &tpm_features;
+}
diff --git a/plat/arm/board/fvp/fvp_drtm_stub.c b/plat/arm/board/fvp/fvp_drtm_stub.c
new file mode 100644
index 0000000..e2bc516
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_drtm_stub.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdint.h>
+
+#include <services/drtm_svc.h>
+
+/*
+ * This file contains DRTM platform functions which don't really do anything on
+ * FVP but are needed for DRTM to function.
+ */
+
+uint64_t plat_drtm_get_min_size_normal_world_dce(void)
+{
+	return 0ULL;
+}
+
+uint64_t plat_drtm_get_imp_def_dlme_region_size(void)
+{
+	return 0ULL;
+}
+
+uint64_t plat_drtm_get_tcb_hash_features(void)
+{
+	return 0ULL;
+}
+
+uint64_t plat_drtm_get_tcb_hash_table_size(void)
+{
+	return 0ULL;
+}
diff --git a/plat/arm/board/fvp/fvp_err.c b/plat/arm/board/fvp/fvp_err.c
index 1f9f0dd..244659a 100644
--- a/plat/arm/board/fvp/fvp_err.c
+++ b/plat/arm/board/fvp/fvp_err.c
@@ -29,3 +29,15 @@
 	for (;;)
 		wfi();
 }
+
+void __dead2 plat_arm_system_reset(void)
+{
+	/* Write the System Configuration Control Register */
+	mmio_write_32(V2M_SYSREGS_BASE + V2M_SYS_CFGCTRL,
+		      V2M_CFGCTRL_START |
+		      V2M_CFGCTRL_RW |
+		      V2M_CFGCTRL_FUNC(V2M_FUNC_REBOOT));
+	wfi();
+	ERROR("FVP System Reset: operation not handled.\n");
+	panic();
+}
diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c
index 8f3e7b7..e780f21 100644
--- a/plat/arm/board/fvp/fvp_gicv3.c
+++ b/plat/arm/board/fvp/fvp_gicv3.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include <platform_def.h>
 
+#include <common/debug.h>
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <fconf_hw_config_getter.h>
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
index 1b0854b..4dd37a4 100644
--- a/plat/arm/board/fvp/fvp_plat_attest_token.c
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -10,294 +10,88 @@
 
 /* Using hardcoded token values for AEM FVP */
 static uint8_t platform_token[] = {
-	0xD2, 0x84, 0x40, 0xA0, 0x59, 0x08, 0xB1, 0xD9,
-	0x61, 0xA8, 0xA9, 0x0A, 0x58, 0x40, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x3A, 0x00,
-	0x01, 0x24, 0xFA, 0x58, 0x40, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
-	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x3A, 0x00, 0x01,
-	0x25, 0x00, 0x58, 0x41, 0x01, 0x0B, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x12, 0x78, 0x1C,
-	0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x61,
-	0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x43,
-	0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F, 0x31,
-	0x2E, 0x30, 0x2E, 0x30, 0x0B, 0x58, 0x19, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0x3A, 0x00, 0x01, 0x24, 0xF7, 0x78, 0x1C, 0x68,
-	0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x61, 0x72,
-	0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x43, 0x43,
-	0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F, 0x31, 0x2E,
-	0x30, 0x2E, 0x30, 0x3A, 0x00, 0x01, 0x25, 0x01,
-	0x78, 0x18, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A,
-	0x2F, 0x2F, 0x63, 0x63, 0x61, 0x5F, 0x76, 0x65,
-	0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x2E, 0x6F,
-	0x72, 0x67, 0x3A, 0x00, 0x01, 0x24, 0xF9, 0x19,
-	0x30, 0x00, 0x3A, 0x00, 0x01, 0x24, 0xFD, 0x8D,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
-	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
-	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
-	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
-	0x58, 0x40, 0xD3, 0x8A, 0x41, 0xA6, 0xC1, 0x29,
-	0x98, 0x18, 0xB5, 0x16, 0x9C, 0x21, 0x78, 0xB7,
-	0x92, 0xF8, 0x26, 0x82, 0x76, 0x2F, 0x26, 0x45,
-	0x21, 0x6D, 0x0C, 0x21, 0x06, 0xF4, 0xB5, 0xE3,
-	0xA8, 0x07, 0xD1, 0xD6, 0x8C, 0x73, 0xA5, 0xC8,
-	0x16, 0xD8, 0x30, 0x68, 0xC0, 0xA4, 0x77, 0xE2,
-	0x1E, 0xD2, 0x17, 0x86, 0xC3, 0x68, 0x82, 0xDD,
-	0x21, 0x1B, 0xA3, 0xE2, 0xC7, 0xF7, 0x06, 0x33,
-	0xB0, 0x3A
+	0xD2, 0x84, 0x40, 0xA0, 0x59, 0x02, 0x46, 0xA9,
+	0x19, 0x01, 0x09, 0x78, 0x1C, 0x68, 0x74, 0x74,
+	0x70, 0x3A, 0x2F, 0x2F, 0x61, 0x72, 0x6D, 0x2E,
+	0x63, 0x6F, 0x6D, 0x2F, 0x43, 0x43, 0x41, 0x2D,
+	0x53, 0x53, 0x44, 0x2F, 0x31, 0x2E, 0x30, 0x2E,
+	0x30, 0x0A, 0x58, 0x20, 0x07, 0x06, 0x05, 0x04,
+	0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C,
+	0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14,
+	0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C,
+	0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09, 0x5C, 0x58,
+	0x40, 0x7F, 0x45, 0x4C, 0x46, 0x02, 0x01, 0x01,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x03, 0x00, 0x3E, 0x00, 0x01, 0x00, 0x00,
+	0x00, 0x50, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0xA0, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38,
+	0x00, 0x09, 0x00, 0x40, 0x00, 0x1C, 0x00, 0x1B,
+	0x00, 0x19, 0x01, 0x00, 0x58, 0x21, 0x01, 0x07,
+	0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F,
+	0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17,
+	0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F,
+	0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19,
+	0x09, 0x61, 0x58, 0x21, 0x01, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D,
+	0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09, 0x5B,
+	0x19, 0x30, 0x03, 0x19, 0x09, 0x62, 0x67, 0x73,
+	0x68, 0x61, 0x2D, 0x32, 0x35, 0x36, 0x19, 0x09,
+	0x5F, 0x84, 0xA5, 0x01, 0x62, 0x42, 0x4C, 0x05,
+	0x58, 0x20, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
+	0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A,
+	0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12,
+	0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A,
+	0x19, 0x18, 0x04, 0x65, 0x33, 0x2E, 0x34, 0x2E,
+	0x32, 0x02, 0x58, 0x20, 0x07, 0x06, 0x05, 0x04,
+	0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C,
+	0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14,
+	0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C,
+	0x1B, 0x1A, 0x19, 0x18, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2D, 0x32, 0x35, 0x36, 0xA4, 0x01, 0x62,
+	0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D,
+	0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63, 0x31,
+	0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D,
+	0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01, 0x62,
+	0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D,
+	0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65, 0x31,
+	0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20, 0x07,
+	0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F,
+	0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17,
+	0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F,
+	0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4,
+	0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20, 0x07,
+	0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F,
+	0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17,
+	0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F,
+	0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04,
+	0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16, 0x15,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D,
+	0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09, 0x60,
+	0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76, 0x65,
+	0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x40, 0x84,
+	0x32, 0x12, 0x5B, 0x92, 0x6B, 0x20, 0xD8, 0x14,
+	0xC1, 0xC1, 0x8C, 0x3C, 0x73, 0xB8, 0x29, 0x0F,
+	0x42, 0xBC, 0x0B, 0x25, 0x87, 0x5C, 0x4F, 0xA4,
+	0xFA, 0xD9, 0xDE, 0xC1, 0x2B, 0x20, 0xED, 0xDF,
+	0x1C, 0xDD, 0x1A, 0x09, 0xBD, 0xA0, 0x25, 0x48,
+	0xC6, 0xBB, 0x99, 0xA1, 0x30, 0x4F, 0x2C, 0xDC,
+	0x89, 0xE8, 0xB7, 0xFF, 0x32, 0xE9, 0x3F, 0xBB,
+	0xC6, 0xBF, 0x9D, 0x38, 0x68, 0xE1, 0xB2,
 };
 
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index e1bf46d..1ef6c87 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -144,6 +144,8 @@
 #  else
 #   if ENABLE_RME
 #    define MAX_XLAT_TABLES		8
+#   elif DRTM_SUPPORT
+#    define MAX_XLAT_TABLES		8
 #   else
 #    define MAX_XLAT_TABLES		7
 #   endif
@@ -247,7 +249,11 @@
 #elif defined(IMAGE_BL2U)
 # define PLATFORM_STACK_SIZE		UL(0x400)
 #elif defined(IMAGE_BL31)
+# if DRTM_SUPPORT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
 #  define PLATFORM_STACK_SIZE		UL(0x800)
+# endif /* DRTM_SUPPORT */
 #elif defined(IMAGE_BL32)
 # if SPMC_AT_EL3
 #  define PLATFORM_STACK_SIZE		UL(0x1000)
@@ -397,4 +403,14 @@
  */
 #define	PLAT_ARM_EVENT_LOG_MAX_SIZE		UL(0x400)
 
+/*
+ * Maximum size of Event Log buffer used for DRTM
+ */
+#define PLAT_DRTM_EVENT_LOG_MAX_SIZE		UL(0x300)
+
+/*
+ * Number of MMAP entries used by DRTM implementation
+ */
+#define PLAT_DRTM_MMAP_ENTRIES			PLAT_ARM_MMAP_ENTRIES
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 2539712..51ba035 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -132,7 +132,7 @@
 					lib/cpus/aarch64/neoverse_n2.S		\
 					lib/cpus/aarch64/neoverse_e1.S		\
 					lib/cpus/aarch64/neoverse_v1.S		\
-					lib/cpus/aarch64/neoverse_demeter.S	\
+					lib/cpus/aarch64/neoverse_v2.S	\
 					lib/cpus/aarch64/cortex_a78_ae.S	\
 					lib/cpus/aarch64/cortex_a510.S		\
 					lib/cpus/aarch64/cortex_a710.S		\
@@ -143,6 +143,7 @@
 					lib/cpus/aarch64/cortex_a78c.S		\
 					lib/cpus/aarch64/cortex_hayes.S		\
 					lib/cpus/aarch64/cortex_hunter.S	\
+					lib/cpus/aarch64/cortex_hunter_elp_arm.S \
 					lib/cpus/aarch64/cortex_x2.S		\
 					lib/cpus/aarch64/neoverse_poseidon.S
 	endif
@@ -391,12 +392,44 @@
 				plat/arm/board/fvp/fvp_bl2_measured_boot.c	\
 				lib/psa/measured_boot.c
 
+# Note that attestation code does not depend on measured boot interfaces per se,
+# but the two features go together - attestation without boot measurements is
+# pretty much pointless...
+BL31_SOURCES		+=	lib/psa/delegated_attestation.c
+
 PLAT_INCLUDES		+=	-Iinclude/lib/psa
 
 # RSS is not supported on FVP right now. Thus, we use the mocked version
-# of PSA Measured Boot APIs. They return with success and hard-coded data.
+# of the provided PSA APIs. They return with success and hard-coded data.
 PLAT_RSS_NOT_SUPPORTED	:= 1
 
+# Even though RSS is not supported on FVP (see above), we support overriding
+# PLAT_RSS_NOT_SUPPORTED from the command line, just for the purpose of building
+# the code to detect any build regressions. The resulting firmware will not be
+# functional.
+ifneq (${PLAT_RSS_NOT_SUPPORTED},1)
+    $(warning "RSS is not supported on FVP. The firmware will not be functional.")
+    include drivers/arm/rss/rss_comms.mk
+    BL1_SOURCES		+=	${RSS_COMMS_SOURCES}
+    BL2_SOURCES		+=	${RSS_COMMS_SOURCES}
+    BL31_SOURCES	+=	${RSS_COMMS_SOURCES}		\
+				lib/psa/delegated_attestation.c
+
+    BL1_CFLAGS		+=	-DPLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=0
+    BL2_CFLAGS		+=	-DPLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=0
+    BL31_CFLAGS		+=	-DPLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=0
+endif
+
+endif
+
+ifeq (${DRTM_SUPPORT}, 1)
+BL31_SOURCES   += plat/arm/board/fvp/fvp_drtm_addr.c	\
+		  plat/arm/board/fvp/fvp_drtm_dma_prot.c	\
+		  plat/arm/board/fvp/fvp_drtm_err.c	\
+		  plat/arm/board/fvp/fvp_drtm_measurement.c	\
+		  plat/arm/board/fvp/fvp_drtm_stub.c	\
+		  plat/arm/common/arm_dyn_cfg.c		\
+		  plat/arm/board/fvp/fvp_err.c
 endif
 
 ifeq (${TRUSTED_BOARD_BOOT}, 1)
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 3265b0b..409d7a6 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -196,12 +196,6 @@
 # define PLATFORM_STACK_SIZE		UL(0x440)
 #endif
 
-/*
- * Since free SRAM space is scant, enable the ASSERTION message size
- * optimization by fixing the PLAT_LOG_LEVEL_ASSERT to LOG_LEVEL_INFO (40).
- */
-#define PLAT_LOG_LEVEL_ASSERT		40
-
 /* CCI related constants */
 #define PLAT_ARM_CCI_BASE		UL(0x2c090000)
 #define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX	4
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index 464a157..3474016 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -96,4 +96,8 @@
 #define PLAT_ARM_GICR_BASE		UL(0x301C0000)
 #endif
 
+/* Interrupt priority level for shutdown/reboot */
+#define PLAT_REBOOT_PRI		GIC_HIGHEST_SEC_PRIORITY
+#define PLAT_EHF_DESC		EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_REBOOT_PRI)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index b882dc8..9728a08 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -24,6 +24,9 @@
 GICV3_IMPL_GIC600_MULTICHIP	:=	1
 endif
 
+override CSS_SYSTEM_GRACEFUL_RESET	:= 1
+override EL3_EXCEPTION_HANDLING		:= 1
+
 include plat/arm/css/sgi/sgi-common.mk
 
 RDN2_BASE		=	plat/arm/board/rdn2
@@ -31,7 +34,7 @@
 PLAT_INCLUDES		+=	-I${RDN2_BASE}/include/
 
 SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n2.S \
-				lib/cpus/aarch64/neoverse_demeter.S
+				lib/cpus/aarch64/neoverse_v2.S
 
 PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat_v2.c
 
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 11762d4..bc4f254 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -101,7 +101,7 @@
  * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
  * plus a little space for growth.
  */
-#define PLAT_ARM_MAX_BL1_RW_SIZE	0xC000
+#define PLAT_ARM_MAX_BL1_RW_SIZE	0xD000
 
 /*
  * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
@@ -117,20 +117,19 @@
 
 /*
  * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
- * little space for growth.
+ * little space for growth. Current size is considering that TRUSTED_BOARD_BOOT
+ * and MEASURED_BOOT is enabled.
  */
-#if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE		0x20000
-#else
-# define PLAT_ARM_MAX_BL2_SIZE		0x14000
-#endif
+# define PLAT_ARM_MAX_BL2_SIZE		0x26000
+
 
 /*
  * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
  * calculated using the current BL31 PROGBITS debug size plus the sizes of
- * BL2 and BL1-RW
+ * BL2 and BL1-RW. Current size is considering that TRUSTED_BOARD_BOOT and
+ * MEASURED_BOOT is enabled.
  */
-#define PLAT_ARM_MAX_BL31_SIZE		0x3F000
+#define PLAT_ARM_MAX_BL31_SIZE		0x47000
 
 /*
  * Size of cacheable stacks
@@ -159,6 +158,13 @@
 # define PLATFORM_STACK_SIZE		0x440
 #endif
 
+/*
+ * In the current implementation the RoT Service request that requires the
+ * biggest message buffer is the RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN. The
+ * maximum required buffer size is calculated based on the platform-specific
+ * needs of this request.
+ */
+#define PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE	0x500
 
 #define TC_DEVICE_BASE			0x21000000
 #define TC_DEVICE_SIZE			0x5f000000
@@ -220,9 +226,14 @@
 #define PLAT_MAX_CPUS_PER_CLUSTER	U(8)
 #define PLAT_MAX_PE_PER_CPU		U(1)
 
+/* Message Handling Unit (MHU) base addresses */
 #define PLAT_CSS_MHU_BASE		UL(0x45400000)
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
+/* TC2: AP<->RSS MHUs */
+#define PLAT_RSS_AP_SND_MHU_BASE	UL(0x2A840000)
+#define PLAT_RSS_AP_RCV_MHU_BASE	UL(0x2A850000)
+
 #define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
 
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 1a1bc56..a9b031d 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -80,7 +80,8 @@
 # CPU libraries for TARGET_PLATFORM=2
 ifeq (${TARGET_PLATFORM}, 2)
 TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_hayes.S \
-			lib/cpus/aarch64/cortex_hunter.S
+			lib/cpus/aarch64/cortex_hunter.S \
+			lib/cpus/aarch64/cortex_hunter_elp_arm.S
 endif
 
 INTERCONNECT_SOURCES	:=	${TC_BASE}/tc_interconnect.c
@@ -94,7 +95,6 @@
 				${TC_BASE}/tc_err.c	\
 				drivers/arm/sbsa/sbsa.c
 
-
 BL2_SOURCES		+=	${TC_BASE}/tc_security.c	\
 				${TC_BASE}/tc_err.c		\
 				${TC_BASE}/tc_trusted_boot.c		\
@@ -162,6 +162,32 @@
 override ENABLE_MPMM := 1
 override ENABLE_MPMM_FCONF := 1
 
+# Include Measured Boot makefile before any Crypto library makefile.
+# Crypto library makefile may need default definitions of Measured Boot build
+# flags present in Measured Boot makefile.
+ifeq (${MEASURED_BOOT},1)
+    MEASURED_BOOT_MK := drivers/measured_boot/rss/rss_measured_boot.mk
+    $(info Including ${MEASURED_BOOT_MK})
+    include ${MEASURED_BOOT_MK}
+    $(info Including rss_comms.mk)
+    include drivers/arm/rss/rss_comms.mk
+
+    BL1_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
+				plat/arm/board/tc/tc_common_measured_boot.c \
+				plat/arm/board/tc/tc_bl1_measured_boot.c \
+				lib/psa/measured_boot.c			 \
+				${RSS_COMMS_SOURCES}
+
+    BL2_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
+				plat/arm/board/tc/tc_common_measured_boot.c \
+				plat/arm/board/tc/tc_bl2_measured_boot.c \
+				lib/psa/measured_boot.c			 \
+				${RSS_COMMS_SOURCES}
+
+PLAT_INCLUDES		+=	-Iinclude/lib/psa
+
+endif
+
 include plat/arm/common/arm_common.mk
 include plat/arm/css/common/css_common.mk
 include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/board/tc/tc_bl1_measured_boot.c b/plat/arm/board/tc/tc_bl1_measured_boot.c
new file mode 100644
index 0000000..0d29c51
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl1_measured_boot.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/arm/rss_comms.h>
+#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+/* Table with platform specific image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rss_mboot_metadata tc_rss_mboot_metadata[] = {
+	{
+		.id = FW_CONFIG_ID,
+		.slot = U(6),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = RSS_MBOOT_FW_CONFIG_STRING,
+		.lock_measurement = true },
+	{
+		.id = TB_FW_CONFIG_ID,
+		.slot = U(7),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = RSS_MBOOT_TB_FW_CONFIG_STRING,
+		.lock_measurement = true },
+	{
+		.id = BL2_IMAGE_ID,
+		.slot = U(8),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = RSS_MBOOT_BL2_STRING,
+		.lock_measurement = true },
+
+	{
+		.id = RSS_MBOOT_INVALID_ID }
+};
+
+void bl1_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSS */
+	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
+			     PLAT_RSS_AP_RCV_MHU_BASE);
+
+	rss_measured_boot_init();
+}
+
+void bl1_plat_mboot_finish(void)
+{
+	/* Nothing to do. */
+}
diff --git a/plat/arm/board/tc/tc_bl2_measured_boot.c b/plat/arm/board/tc/tc_bl2_measured_boot.c
new file mode 100644
index 0000000..7ea2c2e
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl2_measured_boot.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/arm/rss_comms.h>
+#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+
+#include <plat/common/common_def.h>
+#include <platform_def.h>
+
+/* TC specific table with image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rss_mboot_metadata tc_rss_mboot_metadata[] = {
+	{
+		.id = BL31_IMAGE_ID,
+		.slot = U(9),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = RSS_MBOOT_BL31_STRING,
+		.lock_measurement = true },
+	{
+		.id = HW_CONFIG_ID,
+		.slot = U(10),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = RSS_MBOOT_HW_CONFIG_STRING,
+		.lock_measurement = true },
+	{
+		.id = SOC_FW_CONFIG_ID,
+		.slot = U(11),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = RSS_MBOOT_SOC_FW_CONFIG_STRING,
+		.lock_measurement = true },
+	{
+		.id = RSS_MBOOT_INVALID_ID }
+};
+
+void bl2_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSS */
+	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
+			     PLAT_RSS_AP_RCV_MHU_BASE);
+
+	rss_measured_boot_init();
+}
+
+void bl2_plat_mboot_finish(void)
+{
+	/* Nothing to do. */
+}
diff --git a/plat/arm/board/tc/tc_common_measured_boot.c b/plat/arm/board/tc/tc_common_measured_boot.c
new file mode 100644
index 0000000..fe71899
--- /dev/null
+++ b/plat/arm/board/tc/tc_common_measured_boot.c
@@ -0,0 +1,35 @@
+
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/rss/rss_measured_boot.h>
+
+extern struct rss_mboot_metadata tc_rss_mboot_metadata[];
+
+struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void)
+{
+	return tc_rss_mboot_metadata;
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	int err;
+
+	/* Calculate image hash and record data in RSS */
+	err = rss_mboot_measure_and_record(image_data->image_base,
+					   image_data->image_size,
+					   image_id);
+	if (err != 0) {
+		ERROR("%s%s image id %u (%i)\n",
+		      "Failed to ", "record in RSS", image_id, err);
+	}
+
+	return err;
+}
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index a9668e1..77db023 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -135,7 +135,7 @@
 }
 #endif /* SPM_MM && defined(IMAGE_BL31) */
 
-#if TRUSTED_BOARD_BOOT
+#if TRUSTED_BOARD_BOOT || MEASURED_BOOT
 int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
 {
 	assert(heap_addr != NULL);
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 7a9e04d..7000236 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -11,6 +11,7 @@
 #include <arch.h>
 #include <bl1/bl1.h>
 #include <common/bl_common.h>
+#include <common/debug.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/utils.h>
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 946b732..fc68114 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -237,3 +237,7 @@
 }
 #endif
 
+const mmap_region_t *plat_get_addr_mmap(void)
+{
+	return plat_arm_mmap;
+}
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index bd59ec0..682a278 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -114,7 +114,7 @@
   endif
 endif
 
-# Arm Ethos-N NPU SiP service
+# Arm(R) Ethos(TM)-N NPU SiP service
 ARM_ETHOSN_NPU_DRIVER			:=	0
 $(eval $(call assert_boolean,ARM_ETHOSN_NPU_DRIVER))
 $(eval $(call add_define,ARM_ETHOSN_NPU_DRIVER))
@@ -363,6 +363,10 @@
 BL31_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
 endif
 
+ifeq (${DRTM_SUPPORT},1)
+BL31_SOURCES            +=	plat/arm/common/arm_err.c
+endif
+
 ifneq (${TRUSTED_BOARD_BOOT},0)
 
     # Include common TBB sources
@@ -406,7 +410,7 @@
 # Include Measured Boot makefile before any Crypto library makefile.
 # Crypto library makefile may need default definitions of Measured Boot build
 # flags present in Measured Boot makefile.
-ifeq (${MEASURED_BOOT},1)
+ifneq ($(filter 1,${MEASURED_BOOT} ${DRTM_SUPPORT}),)
     MEASURED_BOOT_MK := drivers/measured_boot/event_log/event_log.mk
     $(info Including ${MEASURED_BOOT_MK})
     include ${MEASURED_BOOT_MK}
@@ -415,15 +419,22 @@
         $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
     endif
 
-    BL1_SOURCES		+= 	${EVENT_LOG_SOURCES}
-    BL2_SOURCES		+= 	${EVENT_LOG_SOURCES}
+    ifeq (${MEASURED_BOOT},1)
+         BL1_SOURCES		+= 	${EVENT_LOG_SOURCES}
+         BL2_SOURCES		+= 	${EVENT_LOG_SOURCES}
+    endif
+
+    ifeq (${DRTM_SUPPORT},1)
+         BL31_SOURCES	        += 	${EVENT_LOG_SOURCES}
+    endif
 endif
 
-ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT}),)
+ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT} ${DRTM_SUPPORT}),)
     CRYPTO_SOURCES	:=	drivers/auth/crypto_mod.c 	\
 				lib/fconf/fconf_tbbr_getter.c
     BL1_SOURCES		+=	${CRYPTO_SOURCES}
     BL2_SOURCES		+=	${CRYPTO_SOURCES}
+    BL31_SOURCES	+=	drivers/auth/crypto_mod.c
 
     # We expect to locate the *.mk files under the directories specified below
     ifeq (${ARM_CRYPTOCELL_INTEG},0)
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index a62693c..c88621e 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -45,7 +45,7 @@
 	assert(heap_addr != NULL);
 	assert(heap_size != NULL);
 
-#if defined(IMAGE_BL1) || BL2_AT_EL3
+#if defined(IMAGE_BL1) || BL2_AT_EL3 || defined(IMAGE_BL31)
 
 	/* If in BL1 or BL2_AT_EL3 define a heap */
 	static unsigned char heap[TF_MBEDTLS_HEAP_SIZE];
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index 6a2a6f8..e88ea65 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 
+#include <common/debug.h>
 #if MEASURED_BOOT
 #include <common/desc_image_load.h>
 #endif
diff --git a/plat/arm/common/arm_err.c b/plat/arm/common/arm_err.c
index f80ba78..fa36e8d 100644
--- a/plat/arm/common/arm_err.c
+++ b/plat/arm/common/arm_err.c
@@ -13,3 +13,8 @@
 {
 	plat_arm_error_handler(err);
 }
+
+void __dead2 plat_system_reset(void)
+{
+	plat_arm_system_reset();
+}
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index 4a3a22e..469e22a 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include <platform_def.h>
 
+#include <common/debug.h>
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/utils.h>
diff --git a/plat/arm/common/fconf/fconf_ethosn_getter.c b/plat/arm/common/fconf/fconf_ethosn_getter.c
index 0af1a20..0b48a98 100644
--- a/plat/arm/common/fconf/fconf_ethosn_getter.c
+++ b/plat/arm/common/fconf/fconf_ethosn_getter.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
  */
@@ -12,107 +12,341 @@
 #include <libfdt.h>
 #include <plat/arm/common/fconf_ethosn_getter.h>
 
-struct ethosn_config_t ethosn_config = {.num_cores = 0};
+struct ethosn_config_t ethosn_config = {0};
 
-static uint8_t fdt_node_get_status(const void *fdt, int node)
+struct ethosn_sub_allocator_t {
+	const char *name;
+	size_t name_len;
+	uint32_t stream_id;
+};
+
+static bool fdt_node_is_enabled(const void *fdt, int node)
 {
 	int len;
-	uint8_t status = ETHOSN_STATUS_DISABLED;
 	const char *node_status;
 
 	node_status = fdt_getprop(fdt, node, "status", &len);
 	if (node_status == NULL ||
 	    (len == 5 && /* Includes null character */
 	     strncmp(node_status, "okay", 4U) == 0)) {
-		status = ETHOSN_STATUS_ENABLED;
+		return true;
 	}
 
+	return false;
+}
+
-	return status;
+static bool fdt_node_has_reserved_memory(const void *fdt, int dev_node)
+{
+	return fdt_get_property(fdt, dev_node, "memory-region", NULL) != NULL;
 }
 
+static int fdt_node_get_iommus_stream_id(const void *fdt, int node, uint32_t *stream_id)
+{
+	int err;
+	uint32_t iommus_array[2] = {0U};
+
+	err = fdt_read_uint32_array(fdt, node, "iommus", 2U, iommus_array);
+	if (err) {
+		return err;
+	}
+
+	*stream_id = iommus_array[1];
+	return 0;
+}
+
+static int fdt_node_populate_sub_allocators(const void *fdt,
+					    int alloc_node,
+					    struct ethosn_sub_allocator_t *sub_allocators,
+					    size_t num_allocs)
+{
+	int sub_node;
+	size_t i;
+	int err = -FDT_ERR_NOTFOUND;
+	uint32_t found_sub_allocators = 0U;
+
+	fdt_for_each_subnode(sub_node, fdt, alloc_node) {
+		const char *node_name;
+
+		if (!fdt_node_is_enabled(fdt, sub_node)) {
+			/* Ignore disabled node */
+			continue;
+		}
+
+		if (fdt_node_check_compatible(fdt, sub_node, "ethosn-memory") != 0) {
+			continue;
+		}
+
+		node_name = fdt_get_name(fdt, sub_node, NULL);
+		for (i = 0U; i < num_allocs; ++i) {
+			if (strncmp(node_name, sub_allocators[i].name,
+				    sub_allocators[i].name_len) != 0) {
+				continue;
+			}
+
+			err = fdt_node_get_iommus_stream_id(fdt, sub_node,
+							    &sub_allocators[i].stream_id);
+			if (err) {
+				ERROR("FCONF: Failed to get stream ID from sub-allocator %s\n",
+				      node_name);
+				return err;
+			}
+
+			++found_sub_allocators;
+			/* Nothing more to do for this node */
+			break;
+		}
+
+		/* Check that at least one of the sub-allocators matched */
+		if (i == num_allocs) {
+			ERROR("FCONF: Unknown sub-allocator %s\n", node_name);
+			return -FDT_ERR_BADSTRUCTURE;
+		}
+	}
+
+	if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
+		ERROR("FCONF: Failed to parse sub-allocators\n");
+		return -FDT_ERR_BADSTRUCTURE;
+	}
+
+	if (err == -FDT_ERR_NOTFOUND) {
+		ERROR("FCONF: No matching sub-allocator found\n");
+		return err;
+	}
+
+	if (found_sub_allocators != num_allocs) {
+		ERROR("FCONF: Not all sub-allocators were found\n");
+		return -FDT_ERR_BADSTRUCTURE;
+	}
+
+	return 0;
+}
+
+static int fdt_node_populate_main_allocator(const void *fdt,
+					    int alloc_node,
+					    struct ethosn_main_allocator_t *allocator)
+{
+	int err;
+	struct ethosn_sub_allocator_t sub_allocators[] = {
+		{.name = "firmware", .name_len = 8U},
+		{.name = "working_data", .name_len = 12U}
+	};
+
+	err = fdt_node_populate_sub_allocators(fdt, alloc_node, sub_allocators,
+					       ARRAY_SIZE(sub_allocators));
+	if (err) {
+		return err;
+	}
+
+	allocator->firmware.stream_id = sub_allocators[0].stream_id;
+	allocator->working_data.stream_id = sub_allocators[1].stream_id;
+
+	return 0;
+}
+
+static int fdt_node_populate_asset_allocator(const void *fdt,
+					    int alloc_node,
+					    struct ethosn_asset_allocator_t *allocator)
+{
+	int err;
+	struct ethosn_sub_allocator_t sub_allocators[] = {
+		{.name = "command_stream", .name_len = 14U},
+		{.name = "weight_data", .name_len = 11U},
+		{.name = "buffer_data", .name_len = 11U},
+		{.name = "intermediate_data", .name_len = 17U}
+	};
+
+	err = fdt_node_populate_sub_allocators(fdt, alloc_node, sub_allocators,
+					       ARRAY_SIZE(sub_allocators));
+	if (err) {
+		return err;
+	}
+
+
+	allocator->command_stream.stream_id = sub_allocators[0].stream_id;
+	allocator->weight_data.stream_id = sub_allocators[1].stream_id;
+	allocator->buffer_data.stream_id = sub_allocators[2].stream_id;
+	allocator->intermediate_data.stream_id = sub_allocators[3].stream_id;
+	return 0;
+}
+
+static int fdt_node_populate_core(const void *fdt,
+				  int device_node,
+				  int core_node,
+				  bool has_reserved_memory,
+				  uint32_t core_index,
+				  struct ethosn_core_t *core)
+{
+	int err;
+	int sub_node;
+	uintptr_t core_addr;
+
+	err = fdt_get_reg_props_by_index(fdt, device_node, core_index,
+					 &core_addr, NULL);
+	if (err < 0) {
+		ERROR("FCONF: Failed to read reg property for NPU core %u\n",
+		      core_index);
+		return err;
+	}
+
+	err = -FDT_ERR_NOTFOUND;
+	fdt_for_each_subnode(sub_node, fdt, core_node) {
+
+		if (!fdt_node_is_enabled(fdt, sub_node)) {
+			continue;
+		}
+
+		if (fdt_node_check_compatible(fdt,
+					      sub_node,
+					      "ethosn-main_allocator") != 0) {
+			continue;
+		}
+
+		if (has_reserved_memory) {
+			ERROR("FCONF: Main allocator not supported when using reserved memory\n");
+			return -FDT_ERR_BADSTRUCTURE;
+		}
+
+		if (err != -FDT_ERR_NOTFOUND) {
+			ERROR("FCONF: NPU core 0x%lx has more than one main allocator\n",
+			      core_addr);
+			return -FDT_ERR_BADSTRUCTURE;
+		}
+
+		err = fdt_node_populate_main_allocator(fdt, sub_node, &core->main_allocator);
+		if (err) {
+			ERROR("FCONF: Failed to parse main allocator for NPU core 0x%lx\n",
+			      core_addr);
+			return err;
+		}
+	}
+
+	if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
+		ERROR("FCONF: Failed to parse core sub nodes\n");
+		return -FDT_ERR_BADSTRUCTURE;
+	}
+
+	if (!has_reserved_memory && err) {
+		ERROR("FCONF: Main allocator not found for NPU core 0x%lx\n",
+		      core_addr);
+		return err;
+	}
+
+	core->addr = core_addr;
+
+	return 0;
+}
+
 int fconf_populate_ethosn_config(uintptr_t config)
 {
 	int ethosn_node;
+	uint32_t dev_count = 0U;
 	const void *hw_conf_dtb = (const void *)config;
 
-	/* Find offset to node with 'ethosn' compatible property */
-	INFO("Probing Arm Ethos-N NPU\n");
-	uint32_t total_core_count = 0U;
+	INFO("Probing Arm(R) Ethos(TM)-N NPU\n");
 
 	fdt_for_each_compatible_node(hw_conf_dtb, ethosn_node, "ethosn") {
+		struct ethosn_device_t *dev = &ethosn_config.devices[dev_count];
+		uint32_t dev_asset_alloc_count = 0U;
+		uint32_t dev_core_count = 0U;
+		bool has_reserved_memory;
 		int sub_node;
-		uint8_t ethosn_status;
-		uint32_t device_core_count = 0U;
 
-		/* If the Arm Ethos-N NPU is disabled the core check can be skipped */
-		ethosn_status = fdt_node_get_status(hw_conf_dtb, ethosn_node);
-		if (ethosn_status == ETHOSN_STATUS_DISABLED) {
+		if (!fdt_node_is_enabled(hw_conf_dtb, ethosn_node)) {
 			continue;
 		}
 
+		if (dev_count >= ETHOSN_DEV_NUM_MAX) {
+			ERROR("FCONF: Reached max number of NPUs\n");
+			return -FDT_ERR_BADSTRUCTURE;
+		}
+
+		has_reserved_memory = fdt_node_has_reserved_memory(hw_conf_dtb, ethosn_node);
 		fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) {
 			int err;
-			uintptr_t core_addr;
-			uint8_t core_status;
 
-			if (total_core_count >= ETHOSN_CORE_NUM_MAX) {
-				ERROR("FCONF: Reached max number of Arm Ethos-N NPU cores\n");
-				return -FDT_ERR_BADSTRUCTURE;
+			if (!fdt_node_is_enabled(hw_conf_dtb, sub_node)) {
+				/* Ignore disabled sub node */
+				continue;
 			}
 
-			/* Check that the sub node is "ethosn-core" compatible */
 			if (fdt_node_check_compatible(hw_conf_dtb,
 						      sub_node,
-						      "ethosn-core") != 0) {
-				/* Ignore incompatible sub node */
-				continue;
-			}
+						      "ethosn-core") == 0) {
 
-			core_status = fdt_node_get_status(hw_conf_dtb, sub_node);
-			if (core_status == ETHOSN_STATUS_DISABLED) {
-				continue;
-			}
+				if (dev_core_count >= ETHOSN_DEV_CORE_NUM_MAX) {
+					ERROR("FCONF: Reached max number of NPU cores for NPU %u\n",
+					      dev_count);
+					return -FDT_ERR_BADSTRUCTURE;
+				}
 
-			err = fdt_get_reg_props_by_index(hw_conf_dtb,
-							 ethosn_node,
-							 device_core_count,
-							 &core_addr,
-							 NULL);
-			if (err < 0) {
-				ERROR(
-				"FCONF: Failed to read reg property for Arm Ethos-N NPU core %u\n",
-						device_core_count);
-				return err;
-			}
+				err = fdt_node_populate_core(hw_conf_dtb,
+							     ethosn_node,
+							     sub_node,
+							     has_reserved_memory,
+							     dev_core_count,
+							     &(dev->cores[dev_core_count]));
+				if (err) {
+					return err;
+				}
+				++dev_core_count;
+			} else if (fdt_node_check_compatible(hw_conf_dtb,
+							     sub_node,
+							     "ethosn-asset_allocator") == 0) {
+
+				if (dev_asset_alloc_count >=
+				    ETHOSN_DEV_ASSET_ALLOCATOR_NUM_MAX) {
+					ERROR("FCONF: Reached max number of asset allocators for NPU %u\n",
+					      dev_count);
+					return -FDT_ERR_BADSTRUCTURE;
+				}
+
+				if (has_reserved_memory) {
+					ERROR("FCONF: Asset allocator not supported when using reserved memory\n");
+					return -FDT_ERR_BADSTRUCTURE;
+				}
 
-			INFO("NPU core probed at address 0x%lx\n", core_addr);
-			ethosn_config.core[total_core_count].addr = core_addr;
-			total_core_count++;
-			device_core_count++;
+				err = fdt_node_populate_asset_allocator(hw_conf_dtb,
+									sub_node,
+									&(dev->asset_allocators[dev_asset_alloc_count]));
+				if (err) {
+					ERROR("FCONF: Failed to parse asset allocator for NPU %u\n",
+					      dev_count);
+					return err;
+				}
+				++dev_asset_alloc_count;
+			}
 		}
 
 		if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
-			ERROR("FCONF: Failed to parse sub nodes\n");
+			ERROR("FCONF: Failed to parse sub nodes for NPU %u\n",
+			      dev_count);
+			return -FDT_ERR_BADSTRUCTURE;
+		}
+
+		if (dev_core_count == 0U) {
+			ERROR("FCONF: NPU %u must have at least one enabled core\n",
+			      dev_count);
 			return -FDT_ERR_BADSTRUCTURE;
 		}
 
-		if (device_core_count == 0U) {
-			ERROR(
-			"FCONF: Enabled Arm Ethos-N NPU device must have at least one enabled core\n");
+		if (!has_reserved_memory && dev_asset_alloc_count == 0U) {
+			ERROR("FCONF: NPU %u must have at least one asset allocator\n",
+			      dev_count);
 			return -FDT_ERR_BADSTRUCTURE;
 		}
+
+		dev->num_cores = dev_core_count;
+		dev->num_allocators = dev_asset_alloc_count;
+		dev->has_reserved_memory = has_reserved_memory;
+		++dev_count;
 	}
 
-	if (total_core_count == 0U) {
+	if (dev_count == 0U) {
 		ERROR("FCONF: Can't find 'ethosn' compatible node in dtb\n");
 		return -FDT_ERR_BADSTRUCTURE;
 	}
 
-	ethosn_config.num_cores = total_core_count;
-
-	INFO("%d NPU core%s probed\n",
-	     ethosn_config.num_cores,
-	     ethosn_config.num_cores > 1 ? "s" : "");
+	ethosn_config.num_devices = dev_count;
 
 	return 0;
 }
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index 2fbbe45..1e4851c 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -35,6 +35,7 @@
 				drivers/arm/css/scmi/scmi_common.c		\
 				drivers/arm/css/scmi/scmi_pwr_dmn_proto.c	\
 				drivers/arm/css/scmi/scmi_sys_pwr_proto.c	\
+				drivers/delay_timer/delay_timer.c		\
 				drivers/arm/css/scp/css_pm_scmi.c
 endif
 
@@ -88,3 +89,9 @@
 $(eval $(call assert_boolean,CSS_NON_SECURE_UART))
 $(eval $(call add_define,CSS_NON_SECURE_UART))
 
+# Process CSS_SYSTEM_GRACEFUL_RESET flag
+# This build option can be used on CSS platforms that require all the CPUs
+# to execute the CPU specific power down sequence to complete a warm reboot
+# sequence in which only the CPUs are power cycled.
+CSS_SYSTEM_GRACEFUL_RESET	:= 0
+$(eval $(call add_define,CSS_SYSTEM_GRACEFUL_RESET))
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 926b8ec..9b2639c 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, 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,10 +9,14 @@
 #include <platform_def.h>
 
 #include <arch_helpers.h>
+#include <bl31/interrupt_mgmt.h>
 #include <common/debug.h>
 #include <drivers/arm/css/css_scp.h>
 #include <lib/cassert.h>
 #include <plat/arm/common/plat_arm.h>
+
+#include <plat/common/platform.h>
+
 #include <plat/arm/css/common/css_pm.h>
 
 /* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
@@ -110,6 +114,9 @@
 
 	/* Enable the gic cpu interface */
 	plat_arm_gic_cpuif_enable();
+
+	/* Setup the CPU power down request interrupt for secondary core(s) */
+	css_setup_cpu_pwr_down_intr();
 }
 
 /*******************************************************************************
@@ -331,6 +338,52 @@
 	return arm_validate_power_state(power_state, output_state);
 }
 
+/*
+ * Setup the SGI interrupt that will be used trigger the execution of power
+ * down sequence for all the secondary cores. This interrupt is setup to be
+ * handled in EL3 context at a priority defined by the platform.
+ */
+void css_setup_cpu_pwr_down_intr(void)
+{
+#if CSS_SYSTEM_GRACEFUL_RESET
+	plat_ic_set_interrupt_type(CSS_CPU_PWR_DOWN_REQ_INTR, INTR_TYPE_EL3);
+	plat_ic_set_interrupt_priority(CSS_CPU_PWR_DOWN_REQ_INTR,
+			PLAT_REBOOT_PRI);
+	plat_ic_enable_interrupt(CSS_CPU_PWR_DOWN_REQ_INTR);
+#endif
+}
+
+/*
+ * For a graceful shutdown/reboot, each CPU in the system should do their power
+ * down sequence. On a PSCI shutdown/reboot request, only one CPU gets an
+ * opportunity to do the powerdown sequence. To achieve graceful reset, of all
+ * cores in the system, the CPU gets the opportunity raise warm reboot SGI to
+ * rest of the CPUs which are online. Add handler for the reboot SGI where the
+ * rest of the CPU execute the powerdown sequence.
+ */
+int css_reboot_interrupt_handler(uint32_t intr_raw, uint32_t flags,
+		void *handle, void *cookie)
+{
+	assert(intr_raw == CSS_CPU_PWR_DOWN_REQ_INTR);
+
+	/* Deactivate warm reboot SGI */
+	plat_ic_end_of_interrupt(CSS_CPU_PWR_DOWN_REQ_INTR);
+
+	/*
+	 * Disable GIC CPU interface to prevent pending interrupt from waking
+	 * up the AP from WFI.
+	 */
+	plat_arm_gic_cpuif_disable();
+	plat_arm_gic_redistif_off();
+
+	psci_pwrdown_cpu(PLAT_MAX_PWR_LVL);
+
+	dmbsy();
+
+	wfi();
+	return 0;
+}
+
 /*******************************************************************************
  * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
  * platform will take care of registering the handlers with PSCI.
diff --git a/plat/arm/css/common/sp_min/css_sp_min.mk b/plat/arm/css/common/sp_min/css_sp_min.mk
index 6523a16..ae489fd 100644
--- a/plat/arm/css/common/sp_min/css_sp_min.mk
+++ b/plat/arm/css/common/sp_min/css_sp_min.mk
@@ -15,6 +15,7 @@
 else
 BL32_SOURCES		+=	drivers/arm/css/mhu/css_mhu_doorbell.c		\
 				drivers/arm/css/scp/css_pm_scmi.c		\
+				drivers/delay_timer/delay_timer.c		\
 				drivers/arm/css/scmi/scmi_common.c		\
 				drivers/arm/css/scmi/scmi_pwr_dmn_proto.c	\
 				drivers/arm/css/scmi/scmi_sys_pwr_proto.c
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 22870c4..c1fadc6 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -19,7 +19,7 @@
 					CSS_SGI_MAX_CPUS_PER_CLUSTER *	\
 					CSS_SGI_MAX_PE_PER_CPU)
 
-#define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00040000	/* 256 KB */
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00080000	/* 512 KB */
 
 /* Remote chip address offset */
 #define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n)	\
@@ -99,10 +99,16 @@
 
 /*
  * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
- * calculated using the current BL31 PROGBITS debug size plus the sizes of
- * BL2 and BL1-RW
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of BL2
+ * and BL1-RW. CSS_SGI_BL31_SIZE - is tuned with respect to the actual BL31
+ * PROGBITS size which is around 64-68KB at the time this change is being made.
+ * A buffer of ~35KB is added to account for future expansion of the image,
+ * making it a total of 100KB.
  */
-#define PLAT_ARM_MAX_BL31_SIZE		0x48000
+#define CSS_SGI_BL31_SIZE		(100 * 1024)	/* 100 KB */
+#define PLAT_ARM_MAX_BL31_SIZE		(CSS_SGI_BL31_SIZE +		\
+						PLAT_ARM_MAX_BL2_SIZE +	\
+						PLAT_ARM_MAX_BL1_RW_SIZE)
 
 /*
  * Size of cacheable stacks
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h
index 41467f7..223ac3e 100644
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ b/plat/arm/css/sgi/include/sgi_variant.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,9 +23,9 @@
 /* SID Version values for RD-N2 variants */
 #define RD_N2_CFG1_SID_VER_PART_NUM		0x07B6
 
-/* SID Version values for RD-Edmunds */
-#define RD_EDMUNDS_SID_VER_PART_NUM		0x07F2
-#define RD_EDMUNDS_CONFIG_ID			0x1
+/* SID Version values for RD-V2 */
+#define RD_V2_SID_VER_PART_NUM			0x07F2
+#define RD_V2_CONFIG_ID				0x1
 
 /* Structure containing SGI platform variant information */
 typedef struct sgi_platform_info {
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 4af579e..6c1a2dd 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -69,7 +69,6 @@
 
 override CSS_LOAD_SCP_IMAGES	:=	0
 override NEED_BL2U		:=	no
-override ARM_BL31_IN_DRAM	:=	1
 override ARM_PLAT_MT		:=	1
 override PSCI_EXTENDED_STATE_ID	:=	1
 override ARM_RECOM_STATE_ID_ENC	:=	1
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 99f2f20..27cf183 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,8 +13,11 @@
 #include <drivers/arm/css/css_mhu_doorbell.h>
 #include <drivers/arm/css/scmi.h>
 #include <plat/arm/common/plat_arm.h>
+
 #include <plat/common/platform.h>
 
+#include <plat/arm/css/common/css_pm.h>
+
 #include <sgi_ras.h>
 #include <sgi_variant.h>
 
@@ -76,7 +79,7 @@
 	if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_EDMUNDS_SID_VER_PART_NUM ||
+		sgi_plat_info.platform_id == RD_V2_SID_VER_PART_NUM ||
 		sgi_plat_info.platform_id == RD_N2_CFG1_SID_VER_PART_NUM) {
 		if (channel_id >= ARRAY_SIZE(plat_rd_scmi_info))
 			panic();
@@ -105,6 +108,15 @@
 #if RAS_EXTENSION
 	sgi_ras_intr_handler_setup();
 #endif
+
+	/* Configure the warm reboot SGI for primary core */
+	css_setup_cpu_pwr_down_intr();
+
+#if CSS_SYSTEM_GRACEFUL_RESET
+	/* Register priority level handlers for reboot */
+	ehf_register_priority_handler(PLAT_REBOOT_PRI,
+			css_reboot_interrupt_handler);
+#endif
 }
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
diff --git a/plat/brcm/board/common/cmn_plat_def.h b/plat/brcm/board/common/cmn_plat_def.h
index 8aa7fd4..79d9a29 100644
--- a/plat/brcm/board/common/cmn_plat_def.h
+++ b/plat/brcm/board/common/cmn_plat_def.h
@@ -8,6 +8,7 @@
 #define CMN_PLAT_DEF_H
 
 #include <bcm_elog.h>
+#include <platform_def.h>
 
 #ifndef GET_LOG_LEVEL
 #define GET_LOG_LEVEL() LOG_LEVEL
@@ -57,9 +58,6 @@
 			}						 \
 		} while (0)
 
-/* Print file and line number on assert */
-#define PLAT_LOG_LEVEL_ASSERT LOG_LEVEL_INFO
-
 /*
  * The number of regions like RO(code), coherent and data required by
  * different BL stages which need to be mapped in the MMU.
diff --git a/plat/common/aarch32/platform_helpers.S b/plat/common/aarch32/platform_helpers.S
index 5b9cb59..75cc456 100644
--- a/plat/common/aarch32/platform_helpers.S
+++ b/plat/common/aarch32/platform_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,8 @@
 #include <asm_macros.S>
 
 	.weak	plat_report_exception
+	.weak	plat_report_prefetch_abort
+	.weak	plat_report_data_abort
 	.weak	plat_reset_handler
 	.weak	plat_disable_acp
 	.weak	bl1_plat_prepare_exit
@@ -28,6 +30,24 @@
 	 * each platform.
 	 * -----------------------------------------------------
 	 */
+func plat_report_prefetch_abort
+	bx	lr
+endfunc plat_report_prefetch_abort
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform.
+	 * -----------------------------------------------------
+	 */
+func plat_report_data_abort
+	bx	lr
+endfunc plat_report_data_abort
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform.
+	 * -----------------------------------------------------
+	 */
 func plat_reset_handler
 	bx	lr
 endfunc plat_reset_handler
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index e807660..8f998af 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include <arch_helpers.h>
+#include <common/debug.h>
 #include <drivers/console.h>
 #if RAS_EXTENSION
 #include <lib/extensions/ras.h>
diff --git a/plat/common/plat_gicv2.c b/plat/common/plat_gicv2.c
index 4c76f1b..0f988dc 100644
--- a/plat/common/plat_gicv2.c
+++ b/plat/common/plat_gicv2.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,6 +35,8 @@
 #pragma weak plat_ic_set_interrupt_priority
 #pragma weak plat_ic_set_interrupt_type
 #pragma weak plat_ic_raise_el3_sgi
+#pragma weak plat_ic_raise_ns_sgi
+#pragma weak plat_ic_raise_s_el1_sgi
 #pragma weak plat_ic_set_spi_routing
 
 /*
@@ -247,12 +250,44 @@
 	/* Verify that this is a secure SGI */
 	assert(plat_ic_get_interrupt_type(sgi_num) == INTR_TYPE_EL3);
 
-	gicv2_raise_sgi(sgi_num, id);
+	gicv2_raise_sgi(sgi_num, false, id);
 #else
 	assert(false);
 #endif
 }
 
+void plat_ic_raise_ns_sgi(int sgi_num, u_register_t target)
+{
+	int id;
+
+	/* Target must be a valid MPIDR in the system */
+	id = plat_core_pos_by_mpidr(target);
+	assert(id >= 0);
+
+	/* Verify that this is a non-secure SGI */
+	assert(plat_ic_get_interrupt_type(sgi_num) == INTR_TYPE_NS);
+
+	gicv2_raise_sgi(sgi_num, true, id);
+}
+
+void plat_ic_raise_s_el1_sgi(int sgi_num, u_register_t target)
+{
+#if GICV2_G0_FOR_EL3
+	assert(false);
+#else
+	int id;
+
+	/* Target must be a valid MPIDR in the system */
+	id = plat_core_pos_by_mpidr(target);
+	assert(id >= 0);
+
+	/* Verify that this is a secure EL1 SGI */
+	assert(plat_ic_get_interrupt_type(sgi_num) == INTR_TYPE_S_EL1);
+
+	gicv2_raise_sgi(sgi_num, false, id);
+#endif
+}
+
 void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
 		u_register_t mpidr)
 {
diff --git a/plat/common/plat_gicv3.c b/plat/common/plat_gicv3.c
index 4a8a7ee..e1420bb 100644
--- a/plat/common/plat_gicv3.c
+++ b/plat/common/plat_gicv3.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +10,7 @@
 
 #include <arch_helpers.h>
 #include <common/bl_common.h>
+#include <common/debug.h>
 #include <bl31/interrupt_mgmt.h>
 #include <drivers/arm/gic_common.h>
 #include <drivers/arm/gicv3.h>
@@ -39,6 +41,8 @@
 #pragma weak plat_ic_set_interrupt_priority
 #pragma weak plat_ic_set_interrupt_type
 #pragma weak plat_ic_raise_el3_sgi
+#pragma weak plat_ic_raise_ns_sgi
+#pragma weak plat_ic_raise_s_el1_sgi
 #pragma weak plat_ic_set_spi_routing
 #pragma weak plat_ic_set_interrupt_pending
 #pragma weak plat_ic_clear_interrupt_pending
@@ -242,7 +246,31 @@
 	assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) ==
 					  INTR_TYPE_EL3);
 
-	gicv3_raise_secure_g0_sgi((unsigned int)sgi_num, target);
+	gicv3_raise_sgi((unsigned int)sgi_num, GICV3_G0, target);
+}
+
+void plat_ic_raise_ns_sgi(int sgi_num, u_register_t target)
+{
+	/* Target must be a valid MPIDR in the system */
+	assert(plat_core_pos_by_mpidr(target) >= 0);
+
+	/* Verify that this is a non-secure SGI */
+	assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) ==
+					  INTR_TYPE_NS);
+
+	gicv3_raise_sgi((unsigned int)sgi_num, GICV3_G1NS, target);
+}
+
+void plat_ic_raise_s_el1_sgi(int sgi_num, u_register_t target)
+{
+	/* Target must be a valid MPIDR in the system */
+	assert(plat_core_pos_by_mpidr(target) >= 0);
+
+	/* Verify that this is a secure EL1 SGI */
+	assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) ==
+					  INTR_TYPE_S_EL1);
+
+	gicv3_raise_sgi((unsigned int)sgi_num, GICV3_G1S, target);
 }
 
 void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index fae9750..11d02f3 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -60,6 +60,11 @@
 		SMC_RET1(handle, imx_src_handler(smc_fid, x1, x2, x3, handle));
 		break;
 #endif
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+	case IMX_SIP_HAB:
+		SMC_RET1(handle, imx_hab_handler(smc_fid, x1, x2, x3, x4));
+		break;
+#endif
 	case  IMX_SIP_BUILDINFO:
 		SMC_RET1(handle, imx_buildinfo_handler(smc_fid, x1, x2, x3, x4));
 	default:
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index c6e9879..1f45985 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -27,6 +27,17 @@
 
 #define IMX_SIP_GET_SOC_INFO		0xC2000006
 
+#define IMX_SIP_HAB			0xC2000007
+#define IMX_SIP_HAB_AUTH_IMG		0x00
+#define IMX_SIP_HAB_ENTRY		0x01
+#define IMX_SIP_HAB_EXIT		0x02
+#define IMX_SIP_HAB_REPORT_EVENT	0x03
+#define IMX_SIP_HAB_REPORT_STATUS	0x04
+#define IMX_SIP_HAB_FAILSAFE		0x05
+#define IMX_SIP_HAB_CHECK_TARGET	0x06
+#define IMX_SIP_HAB_GET_VERSION		0x07
+#define IMX_SIP_HAB_AUTH_IMG_NO_DCD	0x08
+
 #define IMX_SIP_WAKEUP_SRC		0xC2000009
 #define IMX_SIP_WAKEUP_SRC_SCU		0x1
 #define IMX_SIP_WAKEUP_SRC_IRQSTEER	0x2
@@ -58,6 +69,11 @@
 		    u_register_t x2, u_register_t x3, void *handle);
 #endif
 
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+int imx_hab_handler(uint32_t smc_fid, u_register_t x1,
+		    u_register_t x2, u_register_t x3, u_register_t x4);
+#endif
+
 #if (defined(PLAT_imx8qm) || defined(PLAT_imx8qx))
 int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1,
 			u_register_t x2, u_register_t x3);
diff --git a/plat/imx/imx8m/imx8m_caam.c b/plat/imx/imx8m/imx8m_caam.c
index 644572c..a491550 100644
--- a/plat/imx/imx8m/imx8m_caam.c
+++ b/plat/imx/imx8m/imx8m_caam.c
@@ -24,7 +24,7 @@
 
 	/* config CAAM JRaMID set MID to Cortex A */
 	if (mmio_read_32(CAAM_JR0MID) == HAB_JR0_DID) {
-		NOTICE("Do not release JR0 to NS as it can be used by HAB");
+		NOTICE("Do not release JR0 to NS as it can be used by HAB\n");
 	} else {
 		mmio_write_32(CAAM_JR0MID, CAAM_NS_MID);
 	}
diff --git a/plat/imx/imx8m/imx8m_dyn_cfg_helpers.c b/plat/imx/imx8m/imx8m_dyn_cfg_helpers.c
index 8b2fdd6..5d65ef2 100644
--- a/plat/imx/imx8m/imx8m_dyn_cfg_helpers.c
+++ b/plat/imx/imx8m/imx8m_dyn_cfg_helpers.c
@@ -13,6 +13,7 @@
 #endif
 #include <common/fdt_wrappers.h>
 #include <libfdt.h>
+#include <platform_def.h>
 
 #define DTB_PROP_HW_LOG_ADDR	"tpm_event_log_addr"
 #define DTB_PROP_HW_LOG_SIZE	"tpm_event_log_size"
diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c
index 4df4f8e..d396902 100644
--- a/plat/imx/imx8m/imx8m_psci_common.c
+++ b/plat/imx/imx8m/imx8m_psci_common.c
@@ -229,8 +229,11 @@
 
 void __dead2 imx_system_off(void)
 {
-	mmio_write_32(IMX_SNVS_BASE + SNVS_LPCR, SNVS_LPCR_SRTC_ENV |
-			SNVS_LPCR_DP_EN | SNVS_LPCR_TOP);
+	uint32_t val;
+
+	val = mmio_read_32(IMX_SNVS_BASE + SNVS_LPCR);
+	val |= SNVS_LPCR_SRTC_ENV | SNVS_LPCR_DP_EN | SNVS_LPCR_TOP;
+	mmio_write_32(IMX_SNVS_BASE + SNVS_LPCR, val);
 
 	while (1)
 		;
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index ba0db0c..38fac92 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -32,12 +32,22 @@
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
 
+/*
+ * Note: DRAM region is mapped with entire size available and uses MT_RW
+ * attributes.
+ * See details in docs/plat/imx8m.rst "High Assurance Boot (HABv4)" section
+ * for explanation of this mapping scheme.
+ */
 static const mmap_region_t imx_mmap[] = {
 	MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW),
 	MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW), /* AIPS map */
 	MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_DEVICE | MT_RW), /* OCRAM_S */
 	MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW), /* DDRMIX */
 	MAP_REGION_FLAT(IMX_VPUMIX_BASE, IMX_VPUMIX_SIZE, MT_DEVICE | MT_RW), /* VPUMIX */
+	MAP_REGION_FLAT(IMX_CAAM_RAM_BASE, IMX_CAAM_RAM_SIZE, MT_MEMORY | MT_RW), /* CAMM RAM */
+	MAP_REGION_FLAT(IMX_NS_OCRAM_BASE, IMX_NS_OCRAM_SIZE, MT_MEMORY | MT_RW), /* NS OCRAM */
+	MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO), /* ROM code */
+	MAP_REGION_FLAT(IMX_DRAM_BASE, IMX_DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS), /* DRAM */
 	{0},
 };
 
@@ -134,13 +144,13 @@
 
 	imx_csu_init(csu_cfg);
 
-	imx8m_caam_init();
-
 	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
 	console_set_scope(&console, CONSOLE_FLAG_BOOT);
 
+	imx8m_caam_init();
+
 	/*
 	 * tell BL3-1 where the non-secure software image is located
 	 * and the entry state information.
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 84d86b9..930372f 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -107,9 +107,16 @@
 #define IMX_DDRPHY_BASE			U(0x3c000000)
 #define IMX_DDR_IPS_BASE		U(0x3d000000)
 #define IMX_DDR_IPS_SIZE		U(0x1800000)
+#define IMX_VPUMIX_BASE			U(0x38330000)
+#define IMX_VPUMIX_SIZE			U(0x100000)
 #define IMX_ROM_BASE			U(0x0)
-#define IMX_VPUMIX_BASE                U(0x38330000)
-#define IMX_VPUMIX_SIZE                U(0x100000)
+#define IMX_ROM_SIZE			U(0x40000)
+#define IMX_NS_OCRAM_BASE		U(0x900000)
+#define IMX_NS_OCRAM_SIZE		U(0x20000)
+#define IMX_CAAM_RAM_BASE		U(0x100000)
+#define IMX_CAAM_RAM_SIZE		U(0x10000)
+#define IMX_DRAM_BASE			U(0x40000000)
+#define IMX_DRAM_SIZE			U(0xc0000000)
 
 #define GPV_BASE			U(0x32000000)
 #define GPV_SIZE			U(0x800000)
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index e3e5c0c..ebf5c7b 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -32,6 +32,7 @@
 
 BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
+				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
 				plat/imx/imx8m/imx_rdc.c			\
 				plat/imx/imx8m/imx8m_csu.c			\
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index 5d2a64e..de30967 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -32,7 +32,9 @@
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
 
 static const mmap_region_t imx_mmap[] = {
-	GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP, {0},
+	GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP,
+	CAAM_RAM_MAP, NS_OCRAM_MAP, ROM_MAP, DRAM_MAP,
+	{0},
 };
 
 static const struct aipstz_cfg aipstz[] = {
@@ -139,13 +141,13 @@
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
 
-	imx8m_caam_init();
-
 	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
 	console_set_scope(&console, CONSOLE_FLAG_BOOT);
 
+	imx8m_caam_init();
+
 	/*
 	 * tell BL3-1 where the non-secure software image is located
 	 * and the entry state information.
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index dbb4416..d4b1717 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -94,6 +94,13 @@
 #define IMX_DDR_IPS_BASE		U(0x3d000000)
 #define IMX_DDR_IPS_SIZE		U(0x1800000)
 #define IMX_ROM_BASE			U(0x0)
+#define IMX_ROM_SIZE			U(0x40000)
+#define IMX_NS_OCRAM_BASE		U(0x900000)
+#define IMX_NS_OCRAM_SIZE		U(0x60000)
+#define IMX_CAAM_RAM_BASE		U(0x100000)
+#define IMX_CAAM_RAM_SIZE		U(0x10000)
+#define IMX_DRAM_BASE			U(0x40000000)
+#define IMX_DRAM_SIZE			U(0xc0000000)
 
 #define IMX_GIC_BASE			PLAT_GICD_BASE
 #define IMX_GIC_SIZE			U(0x200000)
@@ -140,5 +147,16 @@
 #define AIPS_MAP	MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW) /* AIPS map */
 #define OCRAM_S_MAP	MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_DEVICE | MT_RW) /* OCRAM_S */
 #define DDRC_MAP	MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */
+#define CAAM_RAM_MAP	MAP_REGION_FLAT(IMX_CAAM_RAM_BASE, IMX_CAAM_RAM_SIZE, MT_MEMORY | MT_RW) /* CAMM RAM */
+#define NS_OCRAM_MAP	MAP_REGION_FLAT(IMX_NS_OCRAM_BASE, IMX_NS_OCRAM_SIZE, MT_MEMORY | MT_RW) /* NS OCRAM */
+#define ROM_MAP		MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO) /* ROM code */
+
+/*
+ * Note: DRAM region is mapped with entire size available and uses MT_RW
+ * attributes.
+ * See details in docs/plat/imx8m.rst "High Assurance Boot (HABv4)" section
+ * for explanation of this mapping scheme.
+ */
+#define DRAM_MAP	MAP_REGION_FLAT(IMX_DRAM_BASE, IMX_DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS) /* DRAM */
 
 #endif /* platform_def.h */
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
index 0f3ad1a..c70f3a1 100644
--- a/plat/imx/imx8m/imx8mn/platform.mk
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -27,6 +27,7 @@
 
 BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
+				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
 				plat/imx/imx8m/imx_rdc.c			\
 				plat/imx/imx8m/imx8m_caam.c			\
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index d443c3d..70dd8c8 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -33,7 +33,9 @@
 
 static const mmap_region_t imx_mmap[] = {
 	GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP,
-	NOC_MAP, {0},
+	NOC_MAP, CAAM_RAM_MAP, NS_OCRAM_MAP,
+	ROM_MAP, DRAM_MAP,
+	{0},
 };
 
 static const struct aipstz_cfg aipstz[] = {
@@ -135,13 +137,13 @@
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
 
-	imx8m_caam_init();
-
 	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
 	console_set_scope(&console, CONSOLE_FLAG_BOOT);
 
+	imx8m_caam_init();
+
 	/*
 	 * tell BL3-1 where the non-secure software image is located
 	 * and the entry state information.
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index 8807f5d..1c58f48 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -111,6 +111,13 @@
 #define IMX_DDR_IPS_BASE		U(0x3d000000)
 #define IMX_DDR_IPS_SIZE		U(0x1800000)
 #define IMX_ROM_BASE			U(0x0)
+#define IMX_ROM_SIZE			U(0x40000)
+#define IMX_NS_OCRAM_BASE		U(0x900000)
+#define IMX_NS_OCRAM_SIZE		U(0x60000)
+#define IMX_CAAM_RAM_BASE		U(0x100000)
+#define IMX_CAAM_RAM_SIZE		U(0x10000)
+#define IMX_DRAM_BASE			U(0x40000000)
+#define IMX_DRAM_SIZE			U(0xc0000000)
 
 #define IMX_GIC_BASE			PLAT_GICD_BASE
 #define IMX_GIC_SIZE			U(0x200000)
@@ -178,5 +185,16 @@
 #define OCRAM_S_MAP	MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_MEMORY | MT_RW) /* OCRAM_S */
 #define DDRC_MAP	MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */
 #define NOC_MAP		MAP_REGION_FLAT(IMX_NOC_BASE, IMX_NOC_SIZE, MT_DEVICE | MT_RW) /* NOC QoS */
+#define CAAM_RAM_MAP	MAP_REGION_FLAT(IMX_CAAM_RAM_BASE, IMX_CAAM_RAM_SIZE, MT_MEMORY | MT_RW) /* CAMM RAM */
+#define NS_OCRAM_MAP	MAP_REGION_FLAT(IMX_NS_OCRAM_BASE, IMX_NS_OCRAM_SIZE, MT_MEMORY | MT_RW) /* NS OCRAM */
+#define ROM_MAP		MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO) /* ROM code */
+
+/*
+ * Note: DRAM region is mapped with entire size available and uses MT_RW
+ * attributes.
+ * See details in docs/plat/imx8m.rst "High Assurance Boot (HABv4)" section
+ * for explanation of this mapping scheme.
+ */
+#define DRAM_MAP	MAP_REGION_FLAT(IMX_DRAM_BASE, IMX_DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS) /* DRAM */
 
 #endif /* platform_def.h */
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index e8669e5..09f9ee9 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -28,6 +28,7 @@
 
 BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
+				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
 				plat/imx/imx8m/imx_rdc.c			\
 				plat/imx/imx8m/imx8m_caam.c			\
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index e998a16..59c3779 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -132,14 +132,15 @@
 
 	imx_aipstz_init(aipstz);
 
-	imx8m_caam_init();
-
 #if DEBUG_CONSOLE
 	static console_t console;
 
 	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 #endif
+
+	imx8m_caam_init();
+
 	/*
 	 * tell BL3-1 where the non-secure software image is located
 	 * and the entry state information.
diff --git a/plat/imx/imx8m/imx_hab.c b/plat/imx/imx8m/imx_hab.c
new file mode 100644
index 0000000..222046f
--- /dev/null
+++ b/plat/imx/imx8m/imx_hab.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2017-2020 NXP
+ * Copyright 2022 Leica Geosystems AG
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/runtime_svc.h>
+#include <imx_sip_svc.h>
+
+#define HAB_CID_ATF	U(2)	/* TF-A Caller ID */
+
+/* HAB Status definitions */
+enum hab_status {
+	HAB_STS_ANY = 0x00,	/* Match any status in report_event() */
+	HAB_FAILURE = 0x33,	/* Operation failed */
+	HAB_WARNING = 0x69,	/* Operation completed with warning */
+	HAB_SUCCESS = 0xf0	/* Operation completed successfully */
+};
+
+/* HAB Configuration definitions */
+enum hab_config {
+	HAB_CFG_RETURN = 0x33,	/* Field Return IC */
+	HAB_CFG_OPEN   = 0xf0,	/* Non-secure IC */
+	HAB_CFG_CLOSED = 0xcc	/* Secure IC */
+};
+
+/* HAB State definitions */
+enum hab_state {
+	HAB_STATE_INITIAL   = 0x33,	/* Initializing state (transitory) */
+	HAB_STATE_CHECK     = 0x55,	/* Check state (non-secure) */
+	HAB_STATE_NONSECURE = 0x66,	/* Non-secure state */
+	HAB_STATE_TRUSTED   = 0x99,	/* Trusted state */
+	HAB_STATE_SECURE    = 0xaa,	/* Secure state */
+	HAB_STATE_FAIL_SOFT = 0xcc,	/* Soft fail state */
+	HAB_STATE_FAIL_HARD = 0xff,	/* Hard fail state (terminal) */
+	HAB_STATE_NONE      = 0xf0	/* No security state machine */
+};
+
+/* HAB Verification Target definitions */
+enum hab_target {
+	HAB_TGT_MEMORY     = 0x0f,	/* Check memory allowed list */
+	HAB_TGT_PERIPHERAL = 0xf0,	/* Check peripheral allowed list */
+	HAB_TGT_ANY        = 0x55	/* Check memory & peripheral allowed list */
+};
+
+/* Authenticate Image Loader Callback prototype */
+typedef enum hab_status hab_loader_callback_f_t(void **, size_t *, const void *);
+
+/*
+ * HAB Rom VectorTable (RVT) structure.
+ * This table provides function pointers into the HAB library in ROM for
+ * use by post-ROM boot sequence components.
+ * Functions are ordered in the structure below based on the offsets in ROM
+ * image, and shall not be changed!
+ * Details on API allocation offsets and function description could be
+ * found in following documents from NXP:
+ * - High Assurance Boot Version 4 Application Programming Interface
+ *   Reference Manual (available in CST package)
+ * - HABv4 RVT Guidelines and Recommendations (AN12263)
+ */
+struct hab_rvt_api {
+	uint64_t	hdr;
+	enum hab_status (*entry)(void);
+	enum hab_status (*exit)(void);
+	enum hab_status (*check_target)(enum hab_target type, const void *start, size_t bytes);
+	void* (*authenticate_image)(uint8_t cid, long ivt_offset, void **start,
+		size_t *bytes, hab_loader_callback_f_t loader);
+	enum hab_status (*run_dcd)(const uint8_t *dcd);
+	enum hab_status (*run_csf)(const uint8_t *csf, uint8_t cid, uint32_t srkmask);
+	enum hab_status (*assert)(long type, const void *data, uint32_t count);
+	enum hab_status (*report_event)(enum hab_status status, uint32_t index,
+		uint8_t *event, size_t *bytes);
+	enum hab_status (*report_status)(enum hab_config *config, enum hab_state *state);
+	void (*failsafe)(void);
+	void* (*authenticate_image_no_dcd)(uint8_t cid, long ivt_offset, void **start,
+		size_t *bytes, hab_loader_callback_f_t loader);
+	uint32_t (*get_version)(void);
+	enum hab_status (*authenticate_container)(uint8_t cid, long ivt_offset, void **start,
+		size_t *bytes, hab_loader_callback_f_t loader, uint32_t srkmask, int skip_dcd);
+};
+
+struct hab_rvt_api *g_hab_rvt_api = (struct hab_rvt_api *)HAB_RVT_BASE;
+
+/*******************************************************************************
+ * Handler for servicing HAB SMC calls
+ ******************************************************************************/
+int imx_hab_handler(uint32_t smc_fid,
+			u_register_t x1,
+			u_register_t x2,
+			u_register_t x3,
+			u_register_t x4)
+{
+	switch (x1) {
+	case IMX_SIP_HAB_ENTRY:
+		return g_hab_rvt_api->entry();
+	case IMX_SIP_HAB_EXIT:
+		return g_hab_rvt_api->exit();
+	case IMX_SIP_HAB_CHECK_TARGET:
+		return g_hab_rvt_api->check_target((enum hab_target)x2,
+			(const void *)x3, (size_t)x4);
+	case IMX_SIP_HAB_AUTH_IMG:
+		return (unsigned long)g_hab_rvt_api->authenticate_image(HAB_CID_ATF,
+			x2, (void **)x3, (size_t *)x4, NULL);
+	case IMX_SIP_HAB_REPORT_EVENT:
+		return g_hab_rvt_api->report_event(HAB_FAILURE,
+			(uint32_t)x2, (uint8_t *)x3, (size_t *)x4);
+	case IMX_SIP_HAB_REPORT_STATUS:
+		return g_hab_rvt_api->report_status((enum hab_config *)x2,
+			(enum hab_state *)x3);
+	case IMX_SIP_HAB_FAILSAFE:
+		g_hab_rvt_api->failsafe();
+		break;
+	case IMX_SIP_HAB_AUTH_IMG_NO_DCD:
+		return (unsigned long)g_hab_rvt_api->authenticate_image_no_dcd(
+			HAB_CID_ATF, x2, (void **)x3, (size_t *)x4, NULL);
+	case IMX_SIP_HAB_GET_VERSION:
+		return g_hab_rvt_api->get_version();
+	default:
+		return SMC_UNK;
+	};
+
+	return SMC_OK;
+}
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index eacc4dd..facee0f 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -979,7 +979,7 @@
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	if (data_size >= src_size) {
+	if (data_size > src_size) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 778d4af..79817e6 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -236,7 +236,7 @@
 
 		/* copy response data to input buffer if applicable */
 		ret_resp_len = MBOX_RESP_LEN(mailbox_resp_ctr.payload->header);
-		if ((ret_resp_len > 0) && (response == NULL) && resp_len) {
+		if ((ret_resp_len > 0) && (response != NULL) && (resp_len != NULL)) {
 			if (*resp_len > ret_resp_len) {
 				*resp_len = ret_resp_len;
 			}
diff --git a/plat/mediatek/build_helpers/options.mk b/plat/mediatek/build_helpers/options.mk
index eb579e5..7b63a3e 100644
--- a/plat/mediatek/build_helpers/options.mk
+++ b/plat/mediatek/build_helpers/options.mk
@@ -15,3 +15,10 @@
 $(eval $(call add_defined_option,MTK_SOC))
 $(eval $(call add_defined_option,UART_CLOCK))
 $(eval $(call add_defined_option,UART_BAUDRATE))
+$(eval $(call add_defined_option,CONFIG_MTK_MCUSYS))
+$(eval $(call add_defined_option,CONFIG_MTK_PM_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_CPU_PM_SUPPORT))
+$(eval $(call add_defined_option,CONFIG_MTK_SMP_EN))
+$(eval $(call add_defined_option,CONFIG_MTK_CPU_SUSPEND_EN))
+$(eval $(call add_defined_option,CONFIG_MTK_PM_ARCH))
+$(eval $(call add_defined_option,CONFIG_MTK_CPU_PM_ARCH))
diff --git a/plat/mediatek/common/cold_boot.c b/plat/mediatek/common/cold_boot.c
deleted file mode 100644
index ff585fe..0000000
--- a/plat/mediatek/common/cold_boot.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (c) 2022, Mediatek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/el3_runtime/context_mgmt.h>
-
-/* Vendors headers */
-#include <cold_boot.h>
-#include <lib/mtk_init/mtk_init.h>
-#include <mtk_sip_svc.h>
-
-static struct kernel_info k_info;
-static entry_point_info_t bl32_image_ep_info;
-static entry_point_info_t bl33_image_ep_info;
-static bool el1_is_2nd_bootloader = true;
-static struct atf_arg_t atfarg;
-
-static int init_mtk_bl32_arg(void)
-{
-	struct mtk_bl_param_t *p_mtk_bl_param;
-	struct atf_arg_t *p_atfarg;
-
-	p_mtk_bl_param = (struct mtk_bl_param_t *) get_mtk_bl31_fw_config(BOOT_ARG_FROM_BL2);
-	if (p_mtk_bl_param == NULL) {
-		ERROR("p_mtk_bl_param is NULL!\n");
-		return -1;
-	}
-	p_atfarg = (struct atf_arg_t *)p_mtk_bl_param->atf_arg_addr;
-	if (p_atfarg == NULL) {
-		ERROR("bl32 argument is NULL!\n");
-		return -1;
-	}
-	memcpy((void *)&atfarg, (void *)p_atfarg, sizeof(struct atf_arg_t));
-	return 0;
-}
-MTK_EARLY_PLAT_INIT(init_mtk_bl32_arg);
-
-static void save_kernel_info(uint64_t pc, uint64_t r0, uint64_t r1, uint64_t k32_64)
-{
-	k_info.k32_64 = k32_64;
-	k_info.pc = pc;
-
-	if (k32_64 == LINUX_KERNEL_32) {
-		/* for 32 bits kernel */
-		k_info.r0 = 0;
-		/* machtype */
-		k_info.r1 = r0;
-		/* tags */
-		k_info.r2 = r1;
-	} else {
-		/* for 64 bits kernel */
-		k_info.r0 = r0;
-		k_info.r1 = r1;
-	}
-}
-
-static uint32_t plat_get_spsr_for_bl32_64_entry(void)
-{
-	return SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
-}
-
-#if MTK_BL33_IS_64BIT
-static uint32_t plat_get_spsr_for_bl33_entry(void)
-{
-	uint32_t spsr;
-	uint32_t mode;
-
-	mode = MODE_EL1;
-	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
-	return spsr;
-}
-#else
-static uint32_t plat_get_spsr_for_bl33_entry(void)
-{
-	unsigned int mode;
-	uint32_t spsr;
-	unsigned int ee;
-	unsigned long daif;
-
-	INFO("Secondary bootloader is AArch32\n");
-	mode = MODE32_svc;
-	ee = 0;
-	/*
-	 * TODO: Choose async. exception bits if HYP mode is not
-	 * implemented according to the values of SCR.{AW, FW} bits
-	 */
-	daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT;
-
-	spsr = SPSR_MODE32(mode, 0, ee, daif);
-	return spsr;
-}
-#endif
-
-static void populate_bl32_image_ep(entry_point_info_t *bl32_ep_instance,
-		struct mtk_bl_param_t *p_mtk_bl_param)
-{
-	entry_point_info_t *populated_ep_bl32 = bl32_ep_instance;
-
-	if (p_mtk_bl_param == NULL) {
-		ERROR("p_mtk_bl_param is NULL!\n");
-		panic();
-	}
-	SET_SECURITY_STATE(bl32_ep_instance->h.attr, SECURE);
-	SET_PARAM_HEAD(populated_ep_bl32,
-		       PARAM_EP,
-		       VERSION_1,
-		       populated_ep_bl32->h.attr);
-	populated_ep_bl32->pc = atfarg.tee_entry;
-	populated_ep_bl32->spsr = plat_get_spsr_for_bl32_64_entry();
-}
-
-static void populate_bl33_image_ep(entry_point_info_t *bl33_ep_instance,
-		struct mtk_bl_param_t *p_mtk_bl_param)
-{
-	entry_point_info_t *populated_ep_bl33 = bl33_ep_instance;
-
-	if (p_mtk_bl_param == NULL) {
-		ERROR("p_mtk_bl_param is NULL!\n");
-		panic();
-	}
-	SET_SECURITY_STATE(bl33_ep_instance->h.attr, NON_SECURE);
-	SET_PARAM_HEAD(populated_ep_bl33,
-		       PARAM_EP,
-		       VERSION_1,
-		       populated_ep_bl33->h.attr);
-	populated_ep_bl33->pc = p_mtk_bl_param->bl33_start_addr;
-	/* standardize 2nd bootloader input argument */
-	populated_ep_bl33->args.arg0 = p_mtk_bl_param->bootarg_loc;
-	/* compatible to old GZ version */
-	populated_ep_bl33->args.arg4 = p_mtk_bl_param->bootarg_loc;
-	populated_ep_bl33->args.arg5 = p_mtk_bl_param->bootarg_size;
-	populated_ep_bl33->spsr = plat_get_spsr_for_bl33_entry();
-}
-
-static int populate_bl_images_ep(struct mtk_bl_param_t *p_mtk_bl_param)
-{
-	/*
-	 * Tell BL31 where the non-trusted software image
-	 * is located and the entry state information
-	 */
-	populate_bl33_image_ep(&bl33_image_ep_info, p_mtk_bl_param);
-	populate_bl32_image_ep(&bl32_image_ep_info, p_mtk_bl_param);
-	return 0;
-}
-
-static int populate_bl_images_ep_init(void)
-{
-	return populate_bl_images_ep(get_mtk_bl31_fw_config(BOOT_ARG_FROM_BL2));
-}
-MTK_PLAT_SETUP_0_INIT(populate_bl_images_ep_init);
-
-static entry_point_info_t *bl31_plat_get_next_kernel64_ep_info(void)
-{
-	entry_point_info_t *next_image_info;
-	unsigned long el_status;
-	unsigned int mode;
-
-	el_status = 0;
-	mode = 0;
-
-	/* Kernel image is always non-secured */
-	next_image_info = &bl33_image_ep_info;
-
-	/* Figure out what mode we enter the non-secure world in */
-	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
-	el_status &= ID_AA64PFR0_ELX_MASK;
-
-	INFO("Kernel_EL %d\n", el_status?2:1);
-	if (el_status) {
-		mode = MODE_EL2;
-	} else {
-		mode = MODE_EL1;
-	}
-	INFO("Kernel is 64Bit\n");
-	next_image_info->spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
-	next_image_info->pc = k_info.pc;
-	next_image_info->args.arg0 = k_info.r0;
-	next_image_info->args.arg1 = k_info.r1;
-
-	INFO("pc=0x%lx, r0=0x%" PRIx64 ", r1=0x%" PRIx64 "\n",
-	     next_image_info->pc,
-	     next_image_info->args.arg0,
-	     next_image_info->args.arg1);
-
-	SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
-
-	/* None of the images on this platform can have 0x0 as the entrypoint */
-	if (next_image_info->pc) {
-		return next_image_info;
-	}
-
-	return NULL;
-}
-
-static entry_point_info_t *bl31_plat_get_next_kernel32_ep_info(void)
-{
-	entry_point_info_t *next_image_info;
-	unsigned int mode;
-
-	mode = 0;
-
-	/* Kernel image is always non-secured */
-	next_image_info = &bl33_image_ep_info;
-
-	/* Figure out what mode we enter the non-secure world in */
-	mode = MODE32_hyp;
-	/*
-	 * TODO: Consider the possibility of specifying the SPSR in
-	 * the FIP ToC and allowing the platform to have a say as
-	 * well.
-	 */
-
-	INFO("Kernel is 32Bit\n");
-	next_image_info->spsr = SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE,
-					    (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT));
-	next_image_info->pc = k_info.pc;
-	next_image_info->args.arg0 = k_info.r0;
-	next_image_info->args.arg1 = k_info.r1;
-	next_image_info->args.arg2 = k_info.r2;
-
-	INFO("pc=0x%lx, r0=0x%" PRIx64 ", r1=0x%" PRIx64 ", r2=0x%" PRIx64 "\n",
-	     next_image_info->pc,
-	     next_image_info->args.arg0,
-	     next_image_info->args.arg1,
-	     next_image_info->args.arg2);
-
-	SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
-
-	/* None of the images on this platform can have 0x0 as the entrypoint */
-	if (next_image_info->pc) {
-		return next_image_info;
-	}
-
-	return NULL;
-}
-
-static void bl31_prepare_kernel_entry(uint64_t k32_64)
-{
-	entry_point_info_t *next_image_info = NULL;
-	uint32_t image_type;
-
-	/* Determine which image to execute next */
-	image_type = NON_SECURE; /* bl31_get_next_image_type(); */
-
-	/* Leave 2nd bootloader then jump to kernel */
-	el1_is_2nd_bootloader = false;
-
-	/* Program EL3 registers to enable entry into the next EL */
-	if (k32_64 == LINUX_KERNEL_32) {
-		next_image_info = bl31_plat_get_next_kernel32_ep_info();
-	} else {
-		next_image_info = bl31_plat_get_next_kernel64_ep_info();
-	}
-
-	assert(next_image_info);
-	assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr));
-
-	INFO("BL31: Preparing for EL3 exit to %s world, Kernel\n",
-	     (image_type == SECURE) ? "secure" : "normal");
-	INFO("BL31: Next image address = 0x%" PRIx64 "\n",
-	     next_image_info->pc);
-	INFO("BL31: Next image spsr = 0x%x\n", next_image_info->spsr);
-	cm_init_my_context(next_image_info);
-	cm_prepare_el3_exit(image_type);
-}
-
-bool is_el1_2nd_bootloader(void)
-{
-	return el1_is_2nd_bootloader;
-}
-
-/*******************************************************************************
- * Return a pointer to the 'entry_point_info' structure of the next image for
- * the security state specified. BL33 corresponds to the non-secure image type
- * while BL32 corresponds to the secure image type. A NULL pointer is returned
- * if the image does not exist.
- ******************************************************************************/
-entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
-{
-	entry_point_info_t *next_image_info;
-
-	next_image_info = (type == NON_SECURE) ? &bl33_image_ep_info : &bl32_image_ep_info;
-
-	/* None of the images on this platform can have 0x0 as the entrypoint */
-	if (next_image_info->pc) {
-		return next_image_info;
-	}
-	return NULL;
-}
-
-u_register_t boot_to_kernel(u_register_t x1,
-			    u_register_t x2,
-			    u_register_t x3,
-			    u_register_t x4,
-			    void *handle,
-			    struct smccc_res *smccc_ret)
-{
-	static uint8_t kernel_boot_once_flag;
-
-	/* only support in booting flow */
-	if (kernel_boot_once_flag == 0) {
-		kernel_boot_once_flag = 1;
-
-		INFO("save kernel info\n");
-		save_kernel_info(x1, x2, x3, x4);
-		bl31_prepare_kernel_entry(x4);
-		INFO("el3_exit\n");
-		/*
-		 * FIXME: no better way so far to prevent from
-		 * SiP root handler wipe x0~x3 if not assign smccc_ret
-		 * return register
-		 */
-		smccc_ret->a1 = x3;
-
-		mtk_init_one_level(MTK_INIT_LVL_BL33_DEFER);
-
-#if MTK_CONSOLE_RUNTIME_DISABLE
-		INFO("Turn off BL31 console\n");
-		mtk_console_core_end();
-#endif
-
-		/* Re-assign as x0 register entering Linux kernel */
-		return x2;
-	}
-	return 0;
-}
-/* Register SiP SMC service */
-DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_BOOT, boot_to_kernel);
diff --git a/plat/mediatek/drivers/lpm/mt_lp_rm.c b/plat/mediatek/common/lpm/mt_lp_rm.c
similarity index 100%
rename from plat/mediatek/drivers/lpm/mt_lp_rm.c
rename to plat/mediatek/common/lpm/mt_lp_rm.c
diff --git a/plat/mediatek/drivers/lpm/mt_lp_rm.h b/plat/mediatek/common/lpm/mt_lp_rm.h
similarity index 100%
rename from plat/mediatek/drivers/lpm/mt_lp_rm.h
rename to plat/mediatek/common/lpm/mt_lp_rm.h
diff --git a/plat/mediatek/common/lpm/rules.mk b/plat/mediatek/common/lpm/rules.mk
new file mode 100644
index 0000000..87a212a
--- /dev/null
+++ b/plat/mediatek/common/lpm/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := lpm
+LOCAL_SRCS-y := $(LOCAL_DIR)/mt_lp_rm.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/common/mtk_smc_handlers.c b/plat/mediatek/common/mtk_smc_handlers.c
index 24b978c..51a960f 100644
--- a/plat/mediatek/common/mtk_smc_handlers.c
+++ b/plat/mediatek/common/mtk_smc_handlers.c
@@ -6,9 +6,11 @@
 
 #include <assert.h>
 #include <errno.h>
+#if MTK_SIP_KERNEL_BOOT_ENABLE
+#include <cold_boot.h>
+#endif
 #include <common/debug.h>
 #include <common/runtime_svc.h>
-#include <cold_boot.h>
 #include <lib/mtk_init/mtk_init.h>
 #include <mtk_sip_svc.h>
 
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c
new file mode 100644
index 0000000..313ad47
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <lib/spinlock.h>
+
+#include <lib/mtk_init/mtk_init.h>
+#include <lib/pm/mtk_pm.h>
+#include "mt_cpu_pm.h"
+#include "mt_cpu_pm_cpc.h"
+#include "mt_cpu_pm_mbox.h"
+#include <mt_lp_rm.h>
+#include "mt_smp.h"
+#include <mtk_mmap_pool.h>
+#include <platform_def.h>
+
+/*
+ * The locker must use the bakery locker when cache turns off.
+ * Using spin_lock will gain better performance.
+ */
+#ifdef MT_CPU_PM_USING_BAKERY_LOCK
+DEFINE_BAKERY_LOCK(mt_cpu_pm_lock);
+#define plat_cpu_pm_lock_init()	bakery_lock_init(&mt_cpu_pm_lock)
+#define plat_cpu_pm_lock()	bakery_lock_get(&mt_cpu_pm_lock)
+#define plat_cpu_pm_unlock()	bakery_lock_release(&mt_cpu_pm_lock)
+#else
+spinlock_t mt_cpu_pm_lock;
+#define plat_cpu_pm_lock_init()
+#define plat_cpu_pm_lock()	spin_lock(&mt_cpu_pm_lock)
+#define plat_cpu_pm_unlock()	spin_unlock(&mt_cpu_pm_lock)
+#endif
+
+enum mt_pwr_node {
+	MT_PWR_NONMCUSYS = 0,
+	MT_PWR_MCUSYS_PDN,
+	MT_PWR_SUSPEND,
+	MT_PWR_SYSTEM_MEM,
+	MT_PWR_SYSTEM_PLL,
+	MT_PWR_SYSTEM_BUS,
+	MT_PWR_MAX,
+};
+
+#define CPU_PM_DEPD_INIT	BIT(0)
+#define CPU_PM_DEPD_READY	BIT(1)
+#define CPU_PM_PLAT_READY	BIT(2)
+
+#ifdef CPU_PM_TINYSYS_SUPPORT
+#define CPU_PM_INIT_READY	(CPU_PM_DEPD_INIT | CPU_PM_DEPD_READY)
+#define CPU_PM_LP_READY		(CPU_PM_INIT_READY | CPU_PM_PLAT_READY)
+#else
+#define CPU_PM_LP_READY		(CPU_PM_PLAT_READY)
+#endif
+
+#if CONFIG_MTK_PM_SUPPORT
+
+#if CONFIG_MTK_CPU_SUSPEND_EN || CONFIG_MTK_SMP_EN
+static void cpupm_cpu_resume_common(const struct mtk_cpupm_pwrstate *state)
+{
+	CPU_PM_ASSERT(state != NULL);
+	mtk_cpc_core_on_hint_clr(state->info.cpuid);
+}
+#endif
+
+#if CONFIG_MTK_SMP_EN
+static int cpupm_cpu_pwr_on_prepare(unsigned int cpu, uintptr_t entry)
+{
+	struct cpu_pwr_ctrl pwr_ctrl;
+
+	PER_CPU_PWR_CTRL(pwr_ctrl, cpu);
+	mt_smp_core_bootup_address_set(&pwr_ctrl, entry);
+	mt_smp_core_init_arch(0, cpu, 1, &pwr_ctrl);
+
+	return mt_smp_power_core_on(cpu, &pwr_ctrl);
+}
+
+static void cpupm_cpu_resume_smp(const struct mtk_cpupm_pwrstate *state)
+{
+	CPU_PM_ASSERT(state != NULL);
+
+	plat_cpu_pm_lock();
+	mmio_clrbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
+			GIC_WAKEUP_IGNORE(state->info.cpuid));
+	plat_cpu_pm_unlock();
+	cpupm_cpu_resume_common(state);
+}
+
+static void cpupm_cpu_suspend_smp(const struct mtk_cpupm_pwrstate *state)
+{
+	struct cpu_pwr_ctrl pwr_ctrl;
+
+	CPU_PM_ASSERT(state != NULL);
+
+	PER_CPU_PWR_CTRL(pwr_ctrl, state->info.cpuid);
+	mt_smp_power_core_off(&pwr_ctrl);
+	mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG,
+			GIC_WAKEUP_IGNORE(state->info.cpuid));
+}
+
+static void cpupm_smp_init(unsigned int cpu, uintptr_t sec_entrypoint)
+{
+	unsigned int reg;
+	struct mtk_cpupm_pwrstate state = {
+		.info = {
+			.cpuid = cpu,
+			.mode = MTK_CPU_PM_SMP,
+		},
+		.pwr = {
+			.afflv = 0,
+			.state_id = 0,
+		},
+	};
+
+	reg = mmio_read_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG);
+	if ((reg & CPC_MCUSYS_CPC_RESET_PWR_ON_EN) != 0) {
+		INFO("[%s:%d][CPU_PM] reset pwr on is enabled then clear it!\n",
+		     __func__, __LINE__);
+		mmio_clrbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_MCUSYS_CPC_RESET_PWR_ON_EN);
+	}
+
+	cpupm_cpu_pwr_on_prepare(cpu, sec_entrypoint);
+	cpupm_cpu_resume_smp(&state);
+}
+
+static struct mtk_cpu_smp_ops cpcv3_2_cpu_smp = {
+	.init = cpupm_smp_init,
+	.cpu_pwr_on_prepare = cpupm_cpu_pwr_on_prepare,
+	.cpu_on = cpupm_cpu_resume_smp,
+	.cpu_off = cpupm_cpu_suspend_smp,
+};
+
+#endif /* CONFIG_MTK_SMP_EN */
+
+#if CONFIG_MTK_CPU_SUSPEND_EN
+#define CPUPM_READY_MS		(40000)
+#define CPUPM_ARCH_TIME_MS(ms)	(ms * 1000 * SYS_COUNTER_FREQ_IN_MHZ)
+#define CPUPM_BOOTUP_TIME_THR	CPUPM_ARCH_TIME_MS(CPUPM_READY_MS)
+
+static int mt_pwr_nodes[MT_PWR_MAX];
+static int plat_mt_lp_cpu_rc;
+static unsigned int cpu_pm_status;
+static unsigned int plat_prev_stateid;
+
+static int mcusys_prepare_suspend(const struct mtk_cpupm_pwrstate *state)
+{
+	unsigned int stateid = state->pwr.state_id;
+
+	if (mtk_cpc_mcusys_off_prepare() != CPC_SUCCESS) {
+		goto mt_pwr_mcusysoff_break;
+	}
+
+	if (!IS_PLAT_SUSPEND_ID(stateid)) {
+		if (mt_pwr_nodes[MT_PWR_SYSTEM_MEM] != 0) {
+			stateid = MT_PLAT_PWR_STATE_SYSTEM_MEM;
+		} else if (mt_pwr_nodes[MT_PWR_SYSTEM_PLL] != 0) {
+			stateid = MT_PLAT_PWR_STATE_SYSTEM_PLL;
+		} else if (mt_pwr_nodes[MT_PWR_SYSTEM_BUS] != 0) {
+			stateid = MT_PLAT_PWR_STATE_SYSTEM_BUS;
+		} else if (mt_pwr_nodes[MT_PWR_SUSPEND] != 0) {
+			stateid = MT_PLAT_PWR_STATE_SUSPEND;
+		} else {
+			stateid = MT_PLAT_PWR_STATE_MCUSYS;
+		}
+	}
+
+	plat_prev_stateid = stateid;
+	plat_mt_lp_cpu_rc = mt_lp_rm_find_and_run_constraint(0, state->info.cpuid, stateid, NULL);
+
+	if (plat_mt_lp_cpu_rc < 0) {
+		goto mt_pwr_mcusysoff_reflect;
+	}
+
+#ifdef CPU_PM_TINYSYS_SUPPORT
+	mtk_set_cpu_pm_preffered_cpu(state->info.cpuid);
+#endif
+	return MTK_CPUPM_E_OK;
+
+mt_pwr_mcusysoff_reflect:
+	mtk_cpc_mcusys_off_reflect();
+mt_pwr_mcusysoff_break:
+	plat_mt_lp_cpu_rc = -1;
+
+	return MTK_CPUPM_E_FAIL;
+}
+
+static int mcusys_prepare_resume(const struct mtk_cpupm_pwrstate *state)
+{
+	if (plat_mt_lp_cpu_rc < 0) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+	mt_lp_rm_reset_constraint(plat_mt_lp_cpu_rc, state->info.cpuid, plat_prev_stateid);
+	mtk_cpc_mcusys_off_reflect();
+	return MTK_CPUPM_E_OK;
+}
+
+static unsigned int cpupm_do_pstate_off(const mtk_pstate_type psci_state,
+					const struct mtk_cpupm_pwrstate *state)
+{
+	unsigned int pstate = MT_CPUPM_PWR_DOMAIN_CORE;
+
+	if (!state || (state->pwr.afflv > PLAT_MAX_PWR_LVL)) {
+		CPU_PM_ASSERT(0);
+	}
+
+	switch (state->pwr.state_id) {
+	case MT_PLAT_PWR_STATE_SYSTEM_MEM:
+		mt_pwr_nodes[MT_PWR_SYSTEM_MEM] += 1;
+		break;
+	case MT_PLAT_PWR_STATE_SYSTEM_PLL:
+		mt_pwr_nodes[MT_PWR_SYSTEM_PLL] += 1;
+		break;
+	case MT_PLAT_PWR_STATE_SYSTEM_BUS:
+		mt_pwr_nodes[MT_PWR_SYSTEM_BUS] += 1;
+		break;
+	case MT_PLAT_PWR_STATE_SUSPEND:
+		mt_pwr_nodes[MT_PWR_SUSPEND] += 1;
+		break;
+	default:
+		if (!IS_MT_PLAT_PWR_STATE_MCUSYS(state->pwr.state_id) &&
+		    !IS_PLAT_SYSTEM_SUSPEND(state->pwr.afflv)) {
+			plat_cpu_pm_lock();
+			mt_pwr_nodes[MT_PWR_NONMCUSYS] += 1;
+			flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_NONMCUSYS],
+					   sizeof(mt_pwr_nodes[MT_PWR_NONMCUSYS]));
+			plat_cpu_pm_unlock();
+		}
+		break;
+	}
+
+	if ((mt_pwr_nodes[MT_PWR_NONMCUSYS] == 0) && IS_PLAT_MCUSYSOFF_AFFLV(state->pwr.afflv)) {
+		/* Prepare to power down mcusys */
+		if (mcusys_prepare_suspend(state) == MTK_CPUPM_E_OK) {
+			mt_pwr_nodes[MT_PWR_MCUSYS_PDN] += 1;
+			flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_MCUSYS_PDN],
+					   sizeof(mt_pwr_nodes[MT_PWR_MCUSYS_PDN]));
+			pstate |= (MT_CPUPM_PWR_DOMAIN_MCUSYS | MT_CPUPM_PWR_DOMAIN_CLUSTER);
+		}
+	}
+
+	if (state->pwr.afflv >= PLAT_MT_CPU_SUSPEND_CLUSTER) {
+		pstate |= MT_CPUPM_PWR_DOMAIN_CLUSTER;
+	}
+
+	if (psci_get_pstate_pwrlvl(psci_state) >= PLAT_MT_CPU_SUSPEND_CLUSTER) {
+		pstate |= MT_CPUPM_PWR_DOMAIN_PERCORE_DSU;
+	}
+
+	return pstate;
+}
+
+static unsigned int cpupm_do_pstate_on(const mtk_pstate_type psci_state,
+				       const struct mtk_cpupm_pwrstate *state)
+{
+	unsigned int pstate = MT_CPUPM_PWR_DOMAIN_CORE;
+
+	CPU_PM_ASSERT(state != NULL);
+
+	if (state->pwr.afflv > PLAT_MAX_PWR_LVL) {
+		CPU_PM_ASSERT(0);
+	}
+
+	if (mt_pwr_nodes[MT_PWR_MCUSYS_PDN] != 0) {
+		mt_pwr_nodes[MT_PWR_MCUSYS_PDN] = 0;
+		flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_MCUSYS_PDN],
+				   sizeof(mt_pwr_nodes[MT_PWR_MCUSYS_PDN]));
+		pstate |= (MT_CPUPM_PWR_DOMAIN_MCUSYS | MT_CPUPM_PWR_DOMAIN_CLUSTER);
+		mcusys_prepare_resume(state);
+	}
+
+	if (state->pwr.afflv >= PLAT_MT_CPU_SUSPEND_CLUSTER) {
+		pstate |= MT_CPUPM_PWR_DOMAIN_CLUSTER;
+	}
+
+	switch (state->pwr.state_id) {
+	case MT_PLAT_PWR_STATE_SYSTEM_MEM:
+		mt_pwr_nodes[MT_PWR_SYSTEM_MEM] -= 1;
+		CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SYSTEM_MEM] >= 0);
+		break;
+	case MT_PLAT_PWR_STATE_SYSTEM_PLL:
+		mt_pwr_nodes[MT_PWR_SYSTEM_PLL] -= 1;
+		CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SYSTEM_PLL] >= 0);
+		break;
+	case MT_PLAT_PWR_STATE_SYSTEM_BUS:
+		mt_pwr_nodes[MT_PWR_SYSTEM_BUS] -= 1;
+		CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SYSTEM_BUS] >= 0);
+		break;
+	case MT_PLAT_PWR_STATE_SUSPEND:
+		mt_pwr_nodes[MT_PWR_SUSPEND] -= 1;
+		CPU_PM_ASSERT(mt_pwr_nodes[MT_PWR_SUSPEND] >= 0);
+		break;
+	default:
+		if (!IS_MT_PLAT_PWR_STATE_MCUSYS(state->pwr.state_id) &&
+		    !IS_PLAT_SYSTEM_SUSPEND(state->pwr.afflv)) {
+			plat_cpu_pm_lock();
+			mt_pwr_nodes[MT_PWR_NONMCUSYS] -= 1;
+			flush_dcache_range((uintptr_t)&mt_pwr_nodes[MT_PWR_NONMCUSYS],
+					   sizeof(mt_pwr_nodes[MT_PWR_NONMCUSYS]));
+			plat_cpu_pm_unlock();
+		}
+		break;
+	}
+
+	if (IS_PLAT_SYSTEM_SUSPEND(state->pwr.afflv) ||
+	    (IS_PLAT_SYSTEM_RETENTION(state->pwr.afflv) && (mt_pwr_nodes[MT_PWR_SUSPEND] > 0))) {
+		mtk_cpc_time_sync();
+	}
+
+	if (mt_pwr_nodes[MT_PWR_NONMCUSYS] < 0) {
+		CPU_PM_ASSERT(0);
+	}
+
+	pstate |= MT_CPUPM_PWR_DOMAIN_PERCORE_DSU;
+
+	return pstate;
+}
+
+static void cpupm_cpu_resume(const struct mtk_cpupm_pwrstate *state)
+{
+	cpupm_cpu_resume_common(state);
+}
+
+static void cpupm_mcusys_resume(const struct mtk_cpupm_pwrstate *state)
+{
+	assert(state != NULL);
+}
+
+static void cpupm_mcusys_suspend(const struct mtk_cpupm_pwrstate *state)
+{
+	assert(state != NULL);
+}
+
+static unsigned int cpupm_get_pstate(enum mt_cpupm_pwr_domain domain,
+				     const mtk_pstate_type psci_state,
+				     const struct mtk_cpupm_pwrstate *state)
+{
+	unsigned int pstate = 0;
+
+	if (state == NULL) {
+		return 0;
+	}
+
+	if (state->info.mode == MTK_CPU_PM_SMP) {
+		pstate = MT_CPUPM_PWR_DOMAIN_CORE;
+	} else {
+		if (domain == CPUPM_PWR_OFF) {
+			pstate = cpupm_do_pstate_off(psci_state, state);
+		} else if (domain == CPUPM_PWR_ON) {
+			pstate = cpupm_do_pstate_on(psci_state, state);
+		} else {
+			INFO("[%s:%d][CPU_PM] unknown pwr domain :%d\n",
+			     __func__, __LINE__, domain);
+			assert(0);
+		}
+	}
+	return pstate;
+}
+
+static int cpupm_init(void)
+{
+	int ret = MTK_CPUPM_E_OK;
+
+#ifdef CPU_PM_TINYSYS_SUPPORT
+	int status;
+
+	if ((cpu_pm_status & CPU_PM_INIT_READY) == CPU_PM_INIT_READY) {
+		return MTK_CPUPM_E_OK;
+	}
+
+	if (!(cpu_pm_status & CPU_PM_DEPD_INIT)) {
+		status = mtk_lp_depd_condition(CPUPM_MBOX_WAIT_DEV_INIT);
+		if (status == 0) {
+			plat_cpu_pm_lock();
+			cpu_pm_status |= CPU_PM_DEPD_INIT;
+			plat_cpu_pm_unlock();
+		}
+	}
+
+	if ((cpu_pm_status & CPU_PM_DEPD_INIT) && !(cpu_pm_status & CPU_PM_DEPD_READY)) {
+		status = mtk_lp_depd_condition(CPUPM_MBOX_WAIT_TASK_READY);
+		if (status == 0) {
+			plat_cpu_pm_lock();
+			cpu_pm_status |= CPU_PM_DEPD_READY;
+			plat_cpu_pm_unlock();
+		}
+	}
+
+	ret = ((cpu_pm_status & CPU_PM_INIT_READY) == CPU_PM_INIT_READY) ?
+	      MTK_CPUPM_E_OK : MTK_CPUPM_E_FAIL;
+#endif
+	return ret;
+}
+
+static int cpupm_pwr_state_valid(unsigned int afflv, unsigned int state)
+{
+	if (cpu_pm_status == CPU_PM_LP_READY) {
+		return MTK_CPUPM_E_OK;
+	}
+
+	if (cpupm_init() != MTK_CPUPM_E_OK) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+	if (read_cntpct_el0() >= (uint64_t)CPUPM_BOOTUP_TIME_THR) {
+		plat_cpu_pm_lock();
+		cpu_pm_status |= CPU_PM_PLAT_READY;
+		plat_cpu_pm_unlock();
+	}
+
+	if (!IS_PLAT_SYSTEM_SUSPEND(afflv) && (cpu_pm_status & CPU_PM_PLAT_READY) == 0) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+	return MTK_CPUPM_E_OK;
+}
+
+static struct mtk_cpu_pm_ops cpcv3_2_mcdi = {
+	.get_pstate = cpupm_get_pstate,
+	.pwr_state_valid = cpupm_pwr_state_valid,
+	.cpu_resume = cpupm_cpu_resume,
+	.mcusys_suspend = cpupm_mcusys_suspend,
+	.mcusys_resume = cpupm_mcusys_resume,
+};
+#endif /* CONFIG_MTK_CPU_SUSPEND_EN */
+
+#endif /* CONFIG_MTK_PM_SUPPORT */
+
+/*
+ * Depend on mtk pm methodology, the psci op init must
+ * be invoked after cpu pm to avoid initialization fail.
+ */
+int mt_plat_cpu_pm_init(void)
+{
+	plat_cpu_pm_lock_init();
+
+	mtk_cpc_init();
+#if CONFIG_MTK_PM_SUPPORT
+
+#if CONFIG_MTK_CPU_SUSPEND_EN
+	register_cpu_pm_ops(CPU_PM_FN, &cpcv3_2_mcdi);
+#endif /* CONFIG_MTK_CPU_SUSPEND_EN */
+
+#if CONFIG_MTK_SMP_EN
+	register_cpu_smp_ops(CPU_PM_FN, &cpcv3_2_cpu_smp);
+#endif /* CONFIG_MTK_SMP_EN */
+
+#endif /* CONFIG_MTK_PM_SUPPORT */
+
+	INFO("[%s:%d] - CPU PM INIT finished\n", __func__, __LINE__);
+	return 0;
+}
+MTK_ARCH_INIT(mt_plat_cpu_pm_init);
+
+static const mmap_region_t cpu_pm_mmap[] MTK_MMAP_SECTION = {
+#ifdef CPU_PM_TINYSYS_SUPPORT
+#if CONFIG_MTK_PM_SUPPORT && CONFIG_MTK_CPU_SUSPEND_EN
+	MAP_REGION_FLAT(CPU_EB_TCM_BASE, CPU_EB_TCM_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+#endif
+#endif
+	{0}
+};
+DECLARE_MTK_MMAP_REGIONS(cpu_pm_mmap);
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.h
new file mode 100644
index 0000000..4d99df1
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_CPU_PM_H
+#define MT_CPU_PM_H
+
+#include <assert.h>
+#include <mcucfg.h>
+#include <platform_def.h>
+
+/*
+ * After ARM v8.2, the cache will turn off automatically when powering down CPU. Therefore, there
+ * is no doubt to use the spin_lock here.
+ */
+#if !HW_ASSISTED_COHERENCY
+#define MT_CPU_PM_USING_BAKERY_LOCK
+#endif
+
+#define CPU_PM_FN (MTK_CPUPM_FN_CPUPM_GET_PWR_STATE | \
+		   MTK_CPUPM_FN_PWR_STATE_VALID | \
+		   MTK_CPUPM_FN_PWR_ON_CORE_PREPARE | \
+		   MTK_CPUPM_FN_RESUME_CORE | \
+		   MTK_CPUPM_FN_SUSPEND_MCUSYS | \
+		   MTK_CPUPM_FN_RESUME_MCUSYS | \
+		   MTK_CPUPM_FN_SMP_INIT | \
+		   MTK_CPUPM_FN_SMP_CORE_ON | \
+		   MTK_CPUPM_FN_SMP_CORE_OFF)
+
+#define CPU_PM_ASSERT(_cond) ({ \
+	if (!(_cond)) { \
+		INFO("[%s:%d] - %s\n", __func__, __LINE__, #_cond); \
+		panic(); \
+	} })
+
+#define CPC_PWR_MASK_MCUSYS_MP0		(0xC001)
+
+#define PER_CPU_PWR_DATA(ctrl, cluster, core) \
+	do { \
+		ctrl.rvbaraddr_l = CORE_RVBRADDR_##cluster##_##core##_L; \
+		ctrl.arch_addr = MCUCFG_MP0_CLUSTER_CFG5; \
+		ctrl.pwpr = SPM_MP##cluster##_CPU##core##_PWR_CON; \
+	} while (0)
+
+#define PER_CPU_PWR_CTRL(ctrl, cpu) ({ \
+	switch (cpu) { \
+	case 0: \
+		PER_CPU_PWR_DATA(ctrl, 0, 0); \
+		break; \
+	case 1: \
+		PER_CPU_PWR_DATA(ctrl, 0, 1); \
+		break; \
+	case 2: \
+		PER_CPU_PWR_DATA(ctrl, 0, 2); \
+		break; \
+	case 3: \
+		PER_CPU_PWR_DATA(ctrl, 0, 3); \
+		break; \
+	case 4: \
+		PER_CPU_PWR_DATA(ctrl, 0, 4); \
+		break; \
+	case 5: \
+		PER_CPU_PWR_DATA(ctrl, 0, 5); \
+		break; \
+	case 6: \
+		PER_CPU_PWR_DATA(ctrl, 0, 6); \
+		break; \
+	case 7: \
+		PER_CPU_PWR_DATA(ctrl, 0, 7); \
+		break; \
+	default: \
+		assert(0); \
+		break; \
+	} })
+
+
+/* MCUSYS DREQ BIG VPROC ISO control */
+#define DREQ20_BIG_VPROC_ISO		(MCUCFG_BASE + 0xad8c)
+
+/* Definition about bootup address for each core CORE_RVBRADDR_clusterid_cpuid */
+#define CORE_RVBRADDR_0_0_L		(MCUCFG_BASE + 0xc900)
+#define CORE_RVBRADDR_0_1_L		(MCUCFG_BASE + 0xc908)
+#define CORE_RVBRADDR_0_2_L		(MCUCFG_BASE + 0xc910)
+#define CORE_RVBRADDR_0_3_L		(MCUCFG_BASE + 0xc918)
+#define CORE_RVBRADDR_0_4_L		(MCUCFG_BASE + 0xc920)
+#define CORE_RVBRADDR_0_5_L		(MCUCFG_BASE + 0xc928)
+#define CORE_RVBRADDR_0_6_L		(MCUCFG_BASE + 0xc930)
+#define CORE_RVBRADDR_0_7_L		(MCUCFG_BASE + 0xc938)
+#define MCUCFG_MP0_CLUSTER_CFG5		(MCUCFG_BASE + 0xc8e4)
+
+struct cpu_pwr_ctrl {
+	unsigned int rvbaraddr_l;
+	unsigned int arch_addr;
+	unsigned int pwpr;
+};
+
+#define MCUSYS_STATUS_PDN		BIT(0)
+#define MCUSYS_STATUS_CPUSYS_PROTECT	BIT(8)
+#define MCUSYS_STATUS_MCUSYS_PROTECT	BIT(9)
+
+/* cpu_pm function ID */
+enum mt_cpu_pm_user_id {
+	MCUSYS_STATUS,
+	CPC_COMMAND,
+};
+
+/* cpu_pm lp function ID */
+enum mt_cpu_pm_lp_smc_id {
+	LP_CPC_COMMAND,
+	IRQS_REMAIN_ALLOC,
+	IRQS_REMAIN_CTRL,
+	IRQS_REMAIN_IRQ,
+	IRQS_REMAIN_WAKEUP_CAT,
+	IRQS_REMAIN_WAKEUP_SRC,
+};
+
+#endif /* MT_CPU_PM_H */
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.c
new file mode 100644
index 0000000..4cc2203
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <drivers/delay_timer.h>
+
+#include "mt_cpu_pm.h"
+#include "mt_cpu_pm_cpc.h"
+#include "mt_smp.h"
+#include <mt_timer.h>
+
+struct mtk_cpc_dev {
+	int auto_off;
+	unsigned int auto_thres_tick;
+};
+
+static struct mtk_cpc_dev cpc;
+
+static int mtk_cpc_last_core_prot(int prot_req, int resp_reg, int resp_ofs)
+{
+	unsigned int staus;
+	unsigned int retry = 0;
+
+	while (retry < RETRY_CNT_MAX) {
+		retry++;
+
+		mmio_write_32(CPC_MCUSYS_LAST_CORE_REQ, prot_req);
+
+		udelay(1);
+
+		staus = (mmio_read_32(resp_reg) >> resp_ofs) & CPC_PROT_RESP_MASK;
+
+		if (staus == PROT_SUCCESS) {
+			return CPC_SUCCESS;
+		} else if (staus == PROT_GIVEUP) {
+			return CPC_ERR_FAIL;
+		}
+	}
+
+	return CPC_ERR_TIMEOUT;
+}
+
+static int mtk_cpu_pm_mcusys_prot_aquire(void)
+{
+	return mtk_cpc_last_core_prot(MCUSYS_PROT_SET, CPC_MCUSYS_LAST_CORE_RESP, MCUSYS_RESP_OFS);
+}
+
+static void mtk_cpu_pm_mcusys_prot_release(void)
+{
+	mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, MCUSYS_PROT_CLR);
+}
+
+int mtk_cpu_pm_cluster_prot_aquire(void)
+{
+	return mtk_cpc_last_core_prot(CPUSYS_PROT_SET, CPC_MCUSYS_MP_LAST_CORE_RESP,
+				      CPUSYS_RESP_OFS);
+}
+
+void mtk_cpu_pm_cluster_prot_release(void)
+{
+	mmio_write_32(CPC_MCUSYS_PWR_ON_MASK, CPUSYS_PROT_CLR);
+}
+
+static void mtk_cpc_cluster_cnt_backup(void)
+{
+	/* single cluster */
+	uint32_t backup_cnt = mmio_read_32(CPC_CLUSTER_CNT_BACKUP);
+	uint32_t curr_cnt = mmio_read_32(CPC_MCUSYS_CLUSTER_COUNTER);
+
+	if ((curr_cnt & 0x7fff) == 0) {
+		curr_cnt = (curr_cnt >> 16) & 0x7fff;
+	} else {
+		curr_cnt = curr_cnt & 0x7fff;
+	}
+
+	mmio_write_32(CPC_CLUSTER_CNT_BACKUP, backup_cnt + curr_cnt);
+	mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, 0x3);
+}
+
+static inline void mtk_cpc_mcusys_off_enable(bool enable)
+{
+	mmio_write_32(CPC_MCUSYS_PWR_CTRL, enable ? 1 : 0);
+}
+
+void mtk_cpc_mcusys_off_reflect(void)
+{
+	mtk_cpc_mcusys_off_enable(false);
+	mtk_cpu_pm_mcusys_prot_release();
+}
+
+int mtk_cpc_mcusys_off_prepare(void)
+{
+	if (mtk_cpu_pm_mcusys_prot_aquire() != CPC_SUCCESS) {
+		return CPC_ERR_FAIL;
+	}
+
+	mtk_cpc_cluster_cnt_backup();
+	mtk_cpc_mcusys_off_enable(true);
+
+	return CPC_SUCCESS;
+}
+
+void mtk_cpc_core_on_hint_set(int cpu)
+{
+	mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_SET, BIT(cpu));
+}
+
+void mtk_cpc_core_on_hint_clr(int cpu)
+{
+	mmio_write_32(CPC_MCUSYS_CPU_ON_SW_HINT_CLR, BIT(cpu));
+}
+
+static void mtk_cpc_dump_timestamp(void)
+{
+	unsigned int id;
+
+	for (id = 0; id < CPC_TRACE_ID_NUM; id++) {
+		mmio_write_32(CPC_MCUSYS_TRACE_SEL, id);
+
+		memcpy((void *)(uintptr_t)CPC_TRACE_SRAM(id),
+		       (const void *)(uintptr_t)CPC_MCUSYS_TRACE_DATA,
+		       CPC_TRACE_SIZE);
+	}
+}
+
+void mtk_cpc_time_sync(void)
+{
+	uint64_t kt;
+	uint32_t systime_l, systime_h;
+
+	kt = sched_clock();
+	systime_l = mmio_read_32(CNTSYS_L_REG);
+	systime_h = mmio_read_32(CNTSYS_H_REG);
+
+	/* sync kernel timer to cpc */
+	mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE, (uint32_t)kt);
+	mmio_write_32(CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE, (uint32_t)(kt >> 32));
+
+	/* sync system timer to cpc */
+	mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE, systime_l);
+	mmio_write_32(CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE, systime_h);
+}
+
+static void mtk_cpc_config(unsigned int cfg, unsigned int data)
+{
+	switch (cfg) {
+	case CPC_SMC_CONFIG_PROF:
+		if (data) {
+			mmio_setbits_32(CPC_MCUSYS_CPC_DBG_SETTING, CPC_PROF_EN);
+		} else {
+			mmio_clrbits_32(CPC_MCUSYS_CPC_DBG_SETTING, CPC_PROF_EN);
+		}
+		break;
+	case CPC_SMC_CONFIG_AUTO_OFF:
+		if (data) {
+			mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_AUTO_OFF_EN);
+			cpc.auto_off = 1;
+		} else {
+			mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_AUTO_OFF_EN);
+			cpc.auto_off = 0;
+		}
+		break;
+	case CPC_SMC_CONFIG_AUTO_OFF_THRES:
+		cpc.auto_thres_tick = US_TO_TICKS(data);
+		mmio_write_32(CPC_MCUSYS_CPC_OFF_THRES, cpc.auto_thres_tick);
+		break;
+	case CPC_SMC_CONFIG_CNT_CLR:
+		mmio_write_32(CPC_MCUSYS_CLUSTER_COUNTER_CLR, 0x3);
+		break;
+	case CPC_SMC_CONFIG_TIME_SYNC:
+		mtk_cpc_time_sync();
+		break;
+	default:
+		break;
+	}
+}
+
+static unsigned int mtk_cpc_read_config(unsigned int cfg)
+{
+	unsigned int res = 0;
+
+	switch (cfg) {
+	case CPC_SMC_CONFIG_PROF:
+		res = (mmio_read_32(CPC_MCUSYS_CPC_DBG_SETTING) & CPC_PROF_EN) ? 1 : 0;
+		break;
+	case CPC_SMC_CONFIG_AUTO_OFF:
+		res = cpc.auto_off;
+		break;
+	case CPC_SMC_CONFIG_AUTO_OFF_THRES:
+		res = TICKS_TO_US(cpc.auto_thres_tick);
+		break;
+	case CPC_SMC_CONFIG_CNT_CLR:
+	default:
+		break;
+	}
+
+	return res;
+}
+
+uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2)
+{
+	uint64_t res = 0;
+
+	switch (act) {
+	case CPC_SMC_EVENT_CPC_CONFIG:
+		mtk_cpc_config((unsigned int)arg1, (unsigned int)arg2);
+		break;
+	case CPC_SMC_EVENT_READ_CONFIG:
+		res = mtk_cpc_read_config((unsigned int)arg1);
+		break;
+	case CPC_SMC_EVENT_GIC_DPG_SET:
+		/* isolated_status = x2; */
+	default:
+		break;
+	}
+
+	return res;
+}
+
+uint64_t mtk_cpc_trace_dump(uint64_t act, uint64_t arg1, uint64_t arg2)
+{
+	switch (act) {
+	case CPC_SMC_EVENT_DUMP_TRACE_DATA:
+		mtk_cpc_dump_timestamp();
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+void mtk_cpc_init(void)
+{
+#if CONFIG_MTK_SMP_EN
+	mt_smp_init();
+#endif
+	mmio_setbits_32(CPC_MCUSYS_CPC_DBG_SETTING, (CPC_DBG_EN | CPC_CALC_EN));
+
+	cpc.auto_off = 1;
+	mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, (CPC_OFF_PRE_EN |
+						      ((cpc.auto_off > 0) ? CPC_AUTO_OFF_EN : 0)));
+
+	mtk_cpc_config(CPC_SMC_CONFIG_AUTO_OFF_THRES, 8000);
+
+	/* enable CPC */
+	mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, CPC_CTRL_ENABLE);
+	mmio_setbits_32(CPC_MCUSYS_CPC_FLOW_CTRL_CFG, SSPM_CORE_PWR_ON_EN);
+}
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.h
new file mode 100644
index 0000000..3004f41
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_cpc.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_CPU_PM_CPC_H
+#define MT_CPU_PM_CPC_H
+
+#include <lib/mmio.h>
+
+#include <mcucfg.h>
+#include <platform_def.h>
+
+#define NEED_CPUSYS_PROT_WORKAROUND	(1)
+
+/* system sram registers */
+#define CPUIDLE_SRAM_REG(r)	(CPU_IDLE_SRAM_BASE + (r))
+
+/* db dump */
+#define CPC_TRACE_SIZE		(0x20)
+#define CPC_TRACE_ID_NUM	(10)
+#define CPC_TRACE_SRAM(id)	(CPUIDLE_SRAM_REG(0x10) + (id) * CPC_TRACE_SIZE)
+
+/* buckup off count */
+#define CPC_CLUSTER_CNT_BACKUP	CPUIDLE_SRAM_REG(0x1f0)
+#define CPC_MCUSYS_CNT		CPUIDLE_SRAM_REG(0x1f4)
+
+/* CPC_MCUSYS_CPC_FLOW_CTRL_CFG (0xA814): debug setting */
+#define CPC_PWR_ON_SEQ_DIS	BIT(1)
+#define CPC_PWR_ON_PRIORITY	BIT(2)
+#define CPC_AUTO_OFF_EN		BIT(5)
+#define CPC_DORMANT_WAIT_EN	BIT(14)
+#define CPC_CTRL_EN		BIT(16)
+#define CPC_OFF_PRE_EN		BIT(29)
+
+/* CPC_MCUSYS_LAST_CORE_REQ (0xA818) : last core protection */
+#define CPUSYS_PROT_SET		BIT(0)
+#define MCUSYS_PROT_SET		BIT(8)
+#define CPUSYS_PROT_CLR		BIT(8)
+#define MCUSYS_PROT_CLR		BIT(9)
+
+#define CPC_PROT_RESP_MASK	(0x3)
+#define CPUSYS_RESP_OFS		(16)
+#define MCUSYS_RESP_OFS		(30)
+
+#define RETRY_CNT_MAX		(1000)
+
+#define PROT_RETRY		(0)
+#define PROT_SUCCESS		(1)
+#define PROT_GIVEUP		(2)
+
+/* CPC_MCUSYS_CPC_DBG_SETTING (0xAB00): debug setting */
+#define CPC_PROF_EN		BIT(0)
+#define CPC_DBG_EN		BIT(1)
+#define CPC_FREEZE		BIT(2)
+#define CPC_CALC_EN		BIT(3)
+
+enum mcusys_cpc_lastcore_prot_status {
+	CPC_SUCCESS = 0,
+	CPC_ERR_FAIL,
+	CPC_ERR_TIMEOUT,
+	NF_CPC_ERR,
+};
+
+enum mcusys_cpc_smc_events {
+	CPC_SMC_EVENT_DUMP_TRACE_DATA,
+	CPC_SMC_EVENT_GIC_DPG_SET,
+	CPC_SMC_EVENT_CPC_CONFIG,
+	CPC_SMC_EVENT_READ_CONFIG,
+	NF_CPC_SMC_EVENT,
+};
+
+enum mcusys_cpc_smc_config {
+	CPC_SMC_CONFIG_PROF,
+	CPC_SMC_CONFIG_AUTO_OFF,
+	CPC_SMC_CONFIG_AUTO_OFF_THRES,
+	CPC_SMC_CONFIG_CNT_CLR,
+	CPC_SMC_CONFIG_TIME_SYNC,
+	NF_CPC_SMC_CONFIG,
+};
+
+#define US_TO_TICKS(us)		((us) * 13)
+#define TICKS_TO_US(tick)	((tick) / 13)
+
+int mtk_cpu_pm_cluster_prot_aquire(void);
+void mtk_cpu_pm_cluster_prot_release(void);
+
+void mtk_cpc_mcusys_off_reflect(void);
+int mtk_cpc_mcusys_off_prepare(void);
+
+void mtk_cpc_core_on_hint_set(int cpu);
+void mtk_cpc_core_on_hint_clr(int cpu);
+void mtk_cpc_time_sync(void);
+
+uint64_t mtk_cpc_handler(uint64_t act, uint64_t arg1, uint64_t arg2);
+uint64_t mtk_cpc_trace_dump(uint64_t act, uint64_t arg1, uint64_t arg2);
+void mtk_cpc_init(void);
+
+#endif /* MT_CPU_PM_CPC_H */
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.c
new file mode 100644
index 0000000..4d67e7b
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <lib/mmio.h>
+
+#include "mt_cpu_pm_mbox.h"
+#include <platform_def.h>
+
+#ifdef __GNUC__
+#define MCDI_LIKELY(x)		__builtin_expect(!!(x), 1)
+#define MCDI_UNLIKELY(x)	__builtin_expect(!!(x), 0)
+#else
+#define MCDI_LIKELY(x)		(x)
+#define MCDI_UNLIKELY(x)	(x)
+#endif
+
+#define MCUPM_MBOX_3_BASE		(CPU_EB_TCM_BASE + CPU_EB_MBOX3_OFFSET)
+#define MCUPM_MBOX_WRITE(id, val)	mmio_write_32(MCUPM_MBOX_3_BASE + 4 * (id), val)
+#define MCUPM_MBOX_READ(id)		mmio_read_32(MCUPM_MBOX_3_BASE + 4 * (id))
+
+void mtk_set_mcupm_pll_mode(unsigned int mode)
+{
+	if (mode < NF_MCUPM_ARMPLL_MODE) {
+		MCUPM_MBOX_WRITE(MCUPM_MBOX_ARMPLL_MODE, mode);
+	}
+}
+
+int mtk_get_mcupm_pll_mode(void)
+{
+	return MCUPM_MBOX_READ(MCUPM_MBOX_ARMPLL_MODE);
+}
+
+void mtk_set_mcupm_buck_mode(unsigned int mode)
+{
+	if (mode < NF_MCUPM_BUCK_MODE) {
+		MCUPM_MBOX_WRITE(MCUPM_MBOX_BUCK_MODE, mode);
+	}
+}
+
+int mtk_get_mcupm_buck_mode(void)
+{
+	return MCUPM_MBOX_READ(MCUPM_MBOX_BUCK_MODE);
+}
+
+void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid)
+{
+	return MCUPM_MBOX_WRITE(MCUPM_MBOX_WAKEUP_CPU, cpuid);
+}
+
+unsigned int mtk_get_cpu_pm_preffered_cpu(void)
+{
+	return MCUPM_MBOX_READ(MCUPM_MBOX_WAKEUP_CPU);
+}
+
+static int mtk_wait_mbox_init_done(void)
+{
+	int status = MCUPM_MBOX_READ(MCUPM_MBOX_TASK_STA);
+
+	if (status != MCUPM_TASK_INIT) {
+		return status;
+	}
+
+	mtk_set_mcupm_pll_mode(MCUPM_ARMPLL_OFF);
+	mtk_set_mcupm_buck_mode(MCUPM_BUCK_OFF_MODE);
+
+	MCUPM_MBOX_WRITE(MCUPM_MBOX_PWR_CTRL_EN, (MCUPM_MCUSYS_CTRL | MCUPM_CM_CTRL |
+						 MCUPM_BUCK_CTRL | MCUPM_ARMPLL_CTRL));
+
+	return status;
+}
+
+int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type)
+{
+	int status;
+
+	if (type == CPUPM_MBOX_WAIT_DEV_INIT) {
+		status = mtk_wait_mbox_init_done();
+		if (MCDI_UNLIKELY(status != MCUPM_TASK_INIT)) {
+			return -ENXIO;
+		}
+		MCUPM_MBOX_WRITE(MCUPM_MBOX_AP_READY, 1);
+	} else if (type == CPUPM_MBOX_WAIT_TASK_READY) {
+		status = MCUPM_MBOX_READ(MCUPM_MBOX_TASK_STA);
+		if (MCDI_UNLIKELY((status != MCUPM_TASK_WAIT) &&
+				  (status != MCUPM_TASK_INIT_FINISH))) {
+			return -ENXIO;
+		}
+	}
+	return 0;
+}
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.h
new file mode 100644
index 0000000..72be6bd
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_cpu_pm_mbox.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_CPU_PM_MBOX_H
+#define MT_CPU_PM_MBOX_H
+
+#include <lib/utils_def.h>
+
+/* MCUPM Mbox */
+/* AP Write */
+#define MCUPM_MBOX_AP_READY		(0)
+#define MCUPM_MBOX_RESERVED_1		(1)
+#define MCUPM_MBOX_RESERVED_2		(2)
+#define MCUPM_MBOX_RESERVED_3		(3)
+#define MCUPM_MBOX_PWR_CTRL_EN		(4)
+#define MCUPM_MBOX_L3_CACHE_MODE	(5)
+#define MCUPM_MBOX_BUCK_MODE		(6)
+#define MCUPM_MBOX_ARMPLL_MODE		(7)
+/* AP Read */
+#define MCUPM_MBOX_TASK_STA		(8)
+#define MCUPM_MBOX_RESERVED_9		(9)
+#define MCUPM_MBOX_RESERVED_10		(10)
+#define MCUPM_MBOX_RESERVED_11		(11)
+#define MCUPM_MBOX_WAKEUP_CPU		(12)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_PWR_CTRL_EN (4) */
+#define MCUPM_MCUSYS_CTRL		BIT(0)
+#define MCUPM_BUCK_CTRL			BIT(1)
+#define MCUPM_ARMPLL_CTRL		BIT(2)
+#define MCUPM_CM_CTRL			BIT(3)
+#define MCUPM_PWR_CTRL_MASK		(BIT(3) - 1)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_L3_CACHE_MODE (5) */
+#define MCUPM_L3_OFF_MODE		(0) /* default */
+#define MCUPM_L3_DORMANT_MODE		(1)
+#define NF_MCUPM_L3_MODE		(2)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_BUCK_MODE (6) */
+#define MCUPM_BUCK_NORMAL_MODE		(0) /* default */
+#define MCUPM_BUCK_LP_MODE		(1)
+#define MCUPM_BUCK_OFF_MODE		(2)
+#define NF_MCUPM_BUCK_MODE		(3)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_ARMPLL_MODE (7) */
+#define MCUPM_ARMPLL_ON			(0) /* default */
+#define MCUPM_ARMPLL_GATING		(1)
+#define MCUPM_ARMPLL_OFF		(2)
+#define NF_MCUPM_ARMPLL_MODE		(3)
+
+/* Mbox Slot: APMCU_MCUPM_MBOX_TASK_STA (9) */
+#define MCUPM_TASK_UNINIT		(0)
+#define MCUPM_TASK_INIT			(1)
+#define MCUPM_TASK_INIT_FINISH		(2)
+#define MCUPM_TASK_WAIT			(3)
+#define MCUPM_TASK_RUN			(4)
+#define MCUPM_TASK_PAUSE		(5)
+
+
+void mtk_set_mcupm_pll_mode(unsigned int mode);
+int mtk_get_mcupm_pll_mode(void);
+
+void mtk_set_mcupm_buck_mode(unsigned int mode);
+int mtk_get_mcupm_buck_mode(void);
+
+void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid);
+unsigned int mtk_get_cpu_pm_preffered_cpu(void);
+
+enum cpupm_mbox_depd_type {
+	CPUPM_MBOX_WAIT_DEV_INIT,
+	CPUPM_MBOX_WAIT_TASK_READY,
+};
+
+int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type);
+
+#endif /* MT_CPU_PM_MBOX_H */
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c
new file mode 100644
index 0000000..a1d9c31
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <plat/common/platform.h>
+
+#include <lib/pm/mtk_pm.h>
+#include <mcucfg.h>
+#include "mt_cpu_pm.h"
+#include "mt_smp.h"
+
+static inline int is_core_power_status_on(unsigned int cpuid)
+{
+	return !!(mmio_read_32(CPU_PWR_STATUS) & BIT(cpuid));
+}
+
+void mt_smp_core_init_arch(unsigned int cluster, unsigned int cpu, int arm64,
+			   struct cpu_pwr_ctrl *pwr_ctrl)
+{
+	CPU_PM_ASSERT(cluster == 0);
+	CPU_PM_ASSERT(pwr_ctrl != NULL);
+
+	/* aa64naa32 in bits[16:23] */
+	if (arm64 != 0) {
+		mmio_setbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu));
+	} else {
+		mmio_clrbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu));
+	}
+}
+
+void mt_smp_core_bootup_address_set(struct cpu_pwr_ctrl *pwr_ctrl, uintptr_t entry)
+{
+	CPU_PM_ASSERT(pwr_ctrl != NULL);
+
+	/* Set bootup address */
+	mmio_write_32(pwr_ctrl->rvbaraddr_l, entry);
+}
+
+int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl)
+{
+	unsigned int val = is_core_power_status_on(cpu_id);
+
+	CPU_PM_ASSERT(pwr_ctrl);
+
+	mmio_clrbits_32(pwr_ctrl->pwpr, RESETPWRON_CONFIG);
+	if (val == 0) {
+		/*
+		 * Set to 0 after BIG VPROC bulk powered on (configure in MCUPM) and
+		 * before big core power-on sequence.
+		 */
+		if (cpu_id >= PLAT_CPU_PM_B_BUCK_ISO_ID) {
+			mmio_write_32(DREQ20_BIG_VPROC_ISO, 0);
+		}
+
+		mmio_setbits_32(pwr_ctrl->pwpr, PWR_RST_B);
+		dsbsy();
+
+		/* set mp0_spmc_pwr_on_cpuX = 1 */
+		mmio_setbits_32(pwr_ctrl->pwpr, PWR_ON);
+
+		val = 0;
+		while (is_core_power_status_on(cpu_id) == 0) {
+			DO_SMP_CORE_ON_WAIT_TIMEOUT(val);
+			mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON);
+			mmio_setbits_32(pwr_ctrl->pwpr, PWR_ON);
+		}
+	} else {
+		INFO("[%s:%d] - core_%u haven been power on\n", __func__, __LINE__, cpu_id);
+	}
+
+	return MTK_CPUPM_E_OK;
+}
+
+int mt_smp_power_core_off(struct cpu_pwr_ctrl *pwr_ctrl)
+{
+	/* set mp0_spmc_pwr_on_cpuX = 1 */
+	mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON);
+	return MTK_CPUPM_E_OK;
+}
+
+void mt_smp_init(void)
+{
+	/* clear RESETPWRON_CONFIG of mcusys/cluster/core0 */
+	mmio_clrbits_32(SPM_MCUSYS_PWR_CON, RESETPWRON_CONFIG);
+	mmio_clrbits_32(SPM_MP0_CPUTOP_PWR_CON, RESETPWRON_CONFIG);
+}
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.h b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.h
new file mode 100644
index 0000000..4c2f8d2
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/mt_smp.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_SMP_H
+#define MT_SMP_H
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#define CPU_PWR_STATUS			(MCUCFG_BASE + 0xA840)
+
+#define SMP_CORE_TIMEOUT_MAX		(50000)
+#define DO_SMP_CORE_ON_WAIT_TIMEOUT(k_cnt) ({ \
+		CPU_PM_ASSERT(k_cnt < SMP_CORE_TIMEOUT_MAX); \
+		k_cnt++; udelay(1); })
+
+void mt_smp_core_init_arch(unsigned int cluster, unsigned int cpu, int arm64,
+			   struct cpu_pwr_ctrl *pwr_ctrl);
+void mt_smp_core_bootup_address_set(struct cpu_pwr_ctrl *pwr_ctrl, uintptr_t entry);
+int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl);
+int mt_smp_power_core_off(struct cpu_pwr_ctrl *pwr_ctrl);
+void mt_smp_init(void);
+
+#endif /* MT_SMP_H */
diff --git a/plat/mediatek/drivers/cpu_pm/cpcv3_2/rules.mk b/plat/mediatek/drivers/cpu_pm/cpcv3_2/rules.mk
new file mode 100644
index 0000000..858cf38
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/cpcv3_2/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 := cpcv${CONFIG_MTK_CPU_PM_ARCH}
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/mt_cpu_pm.c ${LOCAL_DIR}/mt_cpu_pm_cpc.c
+
+LOCAL_SRCS-$(CPU_PM_TINYSYS_SUPPORT) += ${LOCAL_DIR}/mt_cpu_pm_mbox.c
+LOCAL_SRCS-$(CONFIG_MTK_SMP_EN) += ${LOCAL_DIR}/mt_smp.c
+
+$(eval $(call add_defined_option,CPU_PM_TINYSYS_SUPPORT))
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
+
diff --git a/plat/mediatek/drivers/cpu_pm/rules.mk b/plat/mediatek/drivers/cpu_pm/rules.mk
new file mode 100644
index 0000000..8df4f21
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_pm/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 := cpu_pm
+
+SUB_RULES-${CONFIG_MTK_CPU_PM_SUPPORT} := $(LOCAL_DIR)/cpcv${CONFIG_MTK_CPU_PM_ARCH}
+
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.c b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.c
new file mode 100644
index 0000000..c054de9
--- /dev/null
+++ b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <mtk_dcm_utils.h>
+
+#define MP_CPUSYS_TOP_ADB_DCM_REG0_MASK		BIT(17)
+#define MP_CPUSYS_TOP_ADB_DCM_REG1_MASK		(BIT(15) | BIT(16) | BIT(17) | \
+						 BIT(18) | BIT(21))
+#define MP_CPUSYS_TOP_ADB_DCM_REG2_MASK		(BIT(15) | BIT(16) | BIT(17) | BIT(18))
+#define MP_CPUSYS_TOP_ADB_DCM_REG0_ON		BIT(17)
+#define MP_CPUSYS_TOP_ADB_DCM_REG1_ON		(BIT(15) | BIT(16) | BIT(17) | \
+						 BIT(18) | BIT(21))
+#define MP_CPUSYS_TOP_ADB_DCM_REG2_ON		(BIT(15) | BIT(16) | BIT(17) | BIT(18))
+#define MP_CPUSYS_TOP_ADB_DCM_REG0_OFF		(0x0 << 17)
+#define MP_CPUSYS_TOP_ADB_DCM_REG1_OFF		((0x0 << 15) | (0x0 << 16) | \
+						 (0x0 << 17) | (0x0 << 18) | \
+						 (0x0 << 21))
+#define MP_CPUSYS_TOP_ADB_DCM_REG2_OFF		((0x0 << 15) | (0x0 << 16) | \
+						 (0x0 << 17) | (0x0 << 18))
+
+bool dcm_mp_cpusys_top_adb_dcm_is_on(void)
+{
+	bool ret = true;
+
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0,
+			       MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_ADB_DCM_REG0_ON);
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4,
+			       MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
+			       MP_CPUSYS_TOP_ADB_DCM_REG1_ON);
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+			       MP_CPUSYS_TOP_ADB_DCM_REG2_MASK,
+			       MP_CPUSYS_TOP_ADB_DCM_REG2_ON);
+
+	return ret;
+}
+
+void dcm_mp_cpusys_top_adb_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_adb_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0,
+				   MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG0_ON);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4,
+				   MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG1_ON);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+				   MP_CPUSYS_TOP_ADB_DCM_REG2_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG2_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_adb_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0,
+				   MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG0_OFF);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4,
+				   MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG1_OFF);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+				   MP_CPUSYS_TOP_ADB_DCM_REG2_MASK,
+				   MP_CPUSYS_TOP_ADB_DCM_REG2_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_APB_DCM_REG0_MASK	BIT(5)
+#define MP_CPUSYS_TOP_APB_DCM_REG1_MASK	BIT(8)
+#define MP_CPUSYS_TOP_APB_DCM_REG2_MASK	BIT(16)
+#define MP_CPUSYS_TOP_APB_DCM_REG0_ON	BIT(5)
+#define MP_CPUSYS_TOP_APB_DCM_REG1_ON	BIT(8)
+#define MP_CPUSYS_TOP_APB_DCM_REG2_ON	BIT(16)
+#define MP_CPUSYS_TOP_APB_DCM_REG0_OFF	(0x0 << 5)
+#define MP_CPUSYS_TOP_APB_DCM_REG1_OFF	(0x0 << 8)
+#define MP_CPUSYS_TOP_APB_DCM_REG2_OFF	(0x0 << 16)
+
+bool dcm_mp_cpusys_top_apb_dcm_is_on(void)
+{
+	bool ret = true;
+
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+			       MP_CPUSYS_TOP_APB_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_APB_DCM_REG0_ON);
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+			       MP_CPUSYS_TOP_APB_DCM_REG1_MASK,
+			       MP_CPUSYS_TOP_APB_DCM_REG1_ON);
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+			       MP_CPUSYS_TOP_APB_DCM_REG2_MASK,
+			       MP_CPUSYS_TOP_APB_DCM_REG2_ON);
+
+	return ret;
+}
+
+void dcm_mp_cpusys_top_apb_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_apb_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG0_ON);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG1_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG1_ON);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG2_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG2_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_apb_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG0_OFF);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG1_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG1_OFF);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+				   MP_CPUSYS_TOP_APB_DCM_REG2_MASK,
+				   MP_CPUSYS_TOP_APB_DCM_REG2_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK (BIT(11) | BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON (BIT(11) | BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF ((0x0 << 11) | \
+						(0x0 << 24) | \
+						(0x0 << 25))
+
+bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+			       MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_bus_pll_div_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+				   MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_bus_pll_div_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+				   MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK	BIT(0)
+#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON	BIT(0)
+#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF	(0x0 << 0)
+
+bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+			       MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_core_stall_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_core_stall_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+				   MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_core_stall_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+				   MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK	(0xffff << 0)
+#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON	(0xffff << 0)
+#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF	(0x0 << 0)
+
+bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_MCSIC_DCM0,
+			       MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_cpubiu_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_cpubiu_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCSIC_DCM0,
+				   MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpubiu_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MCSIC_DCM0,
+				   MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK (BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON (BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF ((0x0 << 24) | (0x0 << 25))
+
+bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0,
+			       MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK (BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON (BIT(24) | BIT(25))
+#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF ((0x0 << 24) | (0x0 << 25))
+
+bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1,
+			       MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK	BIT(4)
+#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON	BIT(4)
+#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF	(0x0 << 4)
+
+bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+			       MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_fcm_stall_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_fcm_stall_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+				   MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_fcm_stall_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
+				   MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK	BIT(31)
+#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON		BIT(31)
+#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF	(0x0U << 31)
+
+bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+			       MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_last_cor_idle_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+				   MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_last_cor_idle_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
+				   MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_MISC_DCM_REG0_MASK (BIT(1) | BIT(4))
+#define MP_CPUSYS_TOP_MISC_DCM_REG0_ON (BIT(1) | BIT(4))
+#define MP_CPUSYS_TOP_MISC_DCM_REG0_OFF ((0x0 << 1) | (0x0 << 4))
+
+bool dcm_mp_cpusys_top_misc_dcm_is_on(void)
+{
+	return dcm_check_state(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+			       MP_CPUSYS_TOP_MISC_DCM_REG0_MASK,
+			       MP_CPUSYS_TOP_MISC_DCM_REG0_ON);
+}
+
+void dcm_mp_cpusys_top_misc_dcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_misc_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_MISC_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_MISC_DCM_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_misc_dcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_MISC_DCM_REG0_MASK,
+				   MP_CPUSYS_TOP_MISC_DCM_REG0_OFF);
+	}
+}
+
+#define MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK BIT(3)
+#define MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG0_ON BIT(3)
+#define MP_CPUSYS_TOP_MP0_QDCM_REG1_ON (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF ((0x0 << 3))
+#define MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF ((0x0 << 0) | (0x0 << 1) | \
+					 (0x0 << 2) | (0x0 << 3))
+
+bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void)
+{
+	bool ret = true;
+
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+			       MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
+			       MP_CPUSYS_TOP_MP0_QDCM_REG0_ON);
+	ret &= dcm_check_state(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+			       MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK,
+			       MP_CPUSYS_TOP_MP0_QDCM_REG1_ON);
+
+	return ret;
+}
+
+void dcm_mp_cpusys_top_mp0_qdcm(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'mp_cpusys_top_mp0_qdcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG0_ON);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG1_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'mp_cpusys_top_mp0_qdcm'" */
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF);
+		mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK,
+				   MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF);
+	}
+}
+
+#define CPCCFG_REG_EMI_WFIFO_REG0_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define CPCCFG_REG_EMI_WFIFO_REG0_ON (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define CPCCFG_REG_EMI_WFIFO_REG0_OFF ((0x0 << 0) | (0x0 << 1) | \
+				       (0x0 << 2) | (0x0 << 3))
+
+bool dcm_cpccfg_reg_emi_wfifo_is_on(void)
+{
+	return dcm_check_state(CPCCFG_REG_EMI_WFIFO,
+			       CPCCFG_REG_EMI_WFIFO_REG0_MASK,
+			       CPCCFG_REG_EMI_WFIFO_REG0_ON);
+}
+
+void dcm_cpccfg_reg_emi_wfifo(bool on)
+{
+	if (on) {
+		/* TINFO = "Turn ON DCM 'cpccfg_reg_emi_wfifo'" */
+		mmio_clrsetbits_32(CPCCFG_REG_EMI_WFIFO,
+				   CPCCFG_REG_EMI_WFIFO_REG0_MASK,
+				   CPCCFG_REG_EMI_WFIFO_REG0_ON);
+	} else {
+		/* TINFO = "Turn OFF DCM 'cpccfg_reg_emi_wfifo'" */
+		mmio_clrsetbits_32(CPCCFG_REG_EMI_WFIFO,
+				   CPCCFG_REG_EMI_WFIFO_REG0_MASK,
+				   CPCCFG_REG_EMI_WFIFO_REG0_OFF);
+	}
+}
diff --git a/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.h b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.h
new file mode 100644
index 0000000..5d758dd
--- /dev/null
+++ b/plat/mediatek/drivers/dcm/mt8188/mtk_dcm_utils.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_DCM_UTILS_H
+#define MTK_DCM_UTILS_H
+
+#include <stdbool.h>
+
+#include <mtk_dcm.h>
+#include <platform_def.h>
+
+/* Base */
+#define MP_CPUSYS_TOP_BASE	(MCUCFG_BASE + 0x8000)
+#define CPCCFG_REG_BASE		(MCUCFG_BASE + 0xA800)
+
+/* Register Definition */
+#define CPCCFG_REG_EMI_WFIFO		(CPCCFG_REG_BASE + 0x100)
+#define MP_CPUSYS_TOP_CPU_PLLDIV_CFG0	(MP_CPUSYS_TOP_BASE + 0x22a0)
+#define MP_CPUSYS_TOP_CPU_PLLDIV_CFG1	(MP_CPUSYS_TOP_BASE + 0x22a4)
+#define MP_CPUSYS_TOP_BUS_PLLDIV_CFG	(MP_CPUSYS_TOP_BASE + 0x22e0)
+#define MP_CPUSYS_TOP_MCSIC_DCM0	(MP_CPUSYS_TOP_BASE + 0x2440)
+#define MP_CPUSYS_TOP_MP_ADB_DCM_CFG0	(MP_CPUSYS_TOP_BASE + 0x2500)
+#define MP_CPUSYS_TOP_MP_ADB_DCM_CFG4	(MP_CPUSYS_TOP_BASE + 0x2510)
+#define MP_CPUSYS_TOP_MP_MISC_DCM_CFG0	(MP_CPUSYS_TOP_BASE + 0x2518)
+#define MP_CPUSYS_TOP_MCUSYS_DCM_CFG0	(MP_CPUSYS_TOP_BASE + 0x25c0)
+#define MP_CPUSYS_TOP_MP0_DCM_CFG0	(MP_CPUSYS_TOP_BASE + 0x4880)
+#define MP_CPUSYS_TOP_MP0_DCM_CFG7	(MP_CPUSYS_TOP_BASE + 0x489c)
+
+/* MP_CPUSYS_TOP */
+bool dcm_mp_cpusys_top_adb_dcm_is_on(void);
+void dcm_mp_cpusys_top_adb_dcm(bool on);
+bool dcm_mp_cpusys_top_apb_dcm_is_on(void);
+void dcm_mp_cpusys_top_apb_dcm(bool on);
+bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void);
+void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on);
+bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void);
+void dcm_mp_cpusys_top_core_stall_dcm(bool on);
+bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpubiu_dcm(bool on);
+bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on);
+bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void);
+void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on);
+bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void);
+void dcm_mp_cpusys_top_fcm_stall_dcm(bool on);
+bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void);
+void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on);
+bool dcm_mp_cpusys_top_misc_dcm_is_on(void);
+void dcm_mp_cpusys_top_misc_dcm(bool on);
+bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void);
+void dcm_mp_cpusys_top_mp0_qdcm(bool on);
+/* CPCCFG_REG */
+bool dcm_cpccfg_reg_emi_wfifo_is_on(void);
+void dcm_cpccfg_reg_emi_wfifo(bool on);
+
+#endif
diff --git a/plat/mediatek/drivers/dcm/mtk_dcm.c b/plat/mediatek/drivers/dcm/mtk_dcm.c
new file mode 100644
index 0000000..ca79a20
--- /dev/null
+++ b/plat/mediatek/drivers/dcm/mtk_dcm.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <mtk_dcm.h>
+#include <mtk_dcm_utils.h>
+
+static void dcm_armcore(bool mode)
+{
+	dcm_mp_cpusys_top_bus_pll_div_dcm(mode);
+	dcm_mp_cpusys_top_cpu_pll_div_0_dcm(mode);
+	dcm_mp_cpusys_top_cpu_pll_div_1_dcm(mode);
+}
+
+static void dcm_mcusys(bool on)
+{
+	dcm_mp_cpusys_top_adb_dcm(on);
+	dcm_mp_cpusys_top_apb_dcm(on);
+	dcm_mp_cpusys_top_cpubiu_dcm(on);
+	dcm_mp_cpusys_top_misc_dcm(on);
+	dcm_mp_cpusys_top_mp0_qdcm(on);
+
+	/* CPCCFG_REG */
+	dcm_cpccfg_reg_emi_wfifo(on);
+	dcm_mp_cpusys_top_last_cor_idle_dcm(on);
+}
+
+static void dcm_stall(bool on)
+{
+	dcm_mp_cpusys_top_core_stall_dcm(on);
+	dcm_mp_cpusys_top_fcm_stall_dcm(on);
+}
+
+static bool check_dcm_state(void)
+{
+	bool ret = true;
+
+	ret &= dcm_mp_cpusys_top_bus_pll_div_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on();
+
+	ret &= dcm_mp_cpusys_top_adb_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_apb_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_cpubiu_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_misc_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_mp0_qdcm_is_on();
+	ret &= dcm_cpccfg_reg_emi_wfifo_is_on();
+	ret &= dcm_mp_cpusys_top_last_cor_idle_dcm_is_on();
+
+	ret &= dcm_mp_cpusys_top_core_stall_dcm_is_on();
+	ret &= dcm_mp_cpusys_top_fcm_stall_dcm_is_on();
+
+	return ret;
+}
+
+bool dcm_check_state(uintptr_t addr, unsigned int mask, unsigned int compare)
+{
+	return ((mmio_read_32(addr) & mask) == compare);
+}
+
+int dcm_set_init(void)
+{
+	int ret;
+
+	dcm_armcore(true);
+	dcm_mcusys(true);
+	dcm_stall(true);
+
+	if (check_dcm_state() == false) {
+		ERROR("Failed to set default dcm on!!\n");
+		ret = -1;
+	} else {
+		INFO("%s, dcm pass\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+MTK_PLAT_SETUP_0_INIT(dcm_set_init);
diff --git a/plat/mediatek/drivers/dcm/mtk_dcm.h b/plat/mediatek/drivers/dcm/mtk_dcm.h
new file mode 100644
index 0000000..05f8d45
--- /dev/null
+++ b/plat/mediatek/drivers/dcm/mtk_dcm.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_DCM_H
+#define MTK_DCM_H
+
+#include <stdbool.h>
+
+bool dcm_check_state(uintptr_t addr, unsigned int mask, unsigned int compare);
+int dcm_set_init(void);
+
+#endif /* #ifndef MTK_DCM_H */
diff --git a/plat/mediatek/drivers/dcm/rules.mk b/plat/mediatek/drivers/dcm/rules.mk
new file mode 100644
index 0000000..a8ee05e
--- /dev/null
+++ b/plat/mediatek/drivers/dcm/rules.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mtk_dcm
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_dcm.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/mtk_dcm_utils.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/drivers/dfd/dfd.c b/plat/mediatek/drivers/dfd/dfd.c
new file mode 100644
index 0000000..5770d50
--- /dev/null
+++ b/plat/mediatek/drivers/dfd/dfd.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <dfd.h>
+#include <mtk_sip_svc.h>
+#include <plat_dfd.h>
+
+static u_register_t dfd_smc_dispatcher(u_register_t arg0, u_register_t arg1,
+				       u_register_t arg2, u_register_t arg3,
+				       void *handle, struct smccc_res *smccc_ret)
+{
+	int ret = MTK_SIP_E_SUCCESS;
+
+	switch (arg0) {
+	case PLAT_MTK_DFD_SETUP_MAGIC:
+		INFO("[%s] DFD setup call from kernel\n", __func__);
+		dfd_setup(arg1, arg2, arg3);
+		break;
+	case PLAT_MTK_DFD_READ_MAGIC:
+		/* only allow to access DFD register base + 0x200 */
+		if (arg1 <= 0x200) {
+			ret = mmio_read_32(MISC1_CFG_BASE + arg1);
+		}
+		break;
+	case PLAT_MTK_DFD_WRITE_MAGIC:
+		/* only allow to access DFD register base + 0x200 */
+		if (arg1 <= 0x200) {
+			sync_writel(MISC1_CFG_BASE + arg1, arg2);
+		}
+		break;
+	default:
+		ret = MTK_SIP_E_INVALID_PARAM;
+		break;
+	}
+
+	return ret;
+}
+DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_DFD, dfd_smc_dispatcher);
diff --git a/plat/mediatek/drivers/dfd/dfd.h b/plat/mediatek/drivers/dfd/dfd.h
new file mode 100644
index 0000000..c088bd0
--- /dev/null
+++ b/plat/mediatek/drivers/dfd/dfd.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DFD_H
+#define DFD_H
+
+#include <arch_helpers.h>
+#include <lib/mmio.h>
+
+void dfd_resume(void);
+void dfd_setup(uint64_t base_addr, uint64_t chain_length, uint64_t cache_dump);
+
+#endif /* DFD_H */
diff --git a/plat/mediatek/drivers/dfd/mt8188/plat_dfd.c b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.c
new file mode 100644
index 0000000..1aa68f5
--- /dev/null
+++ b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <dfd.h>
+#include <plat_dfd.h>
+
+static uint64_t dfd_cache_dump;
+static bool dfd_enabled;
+static uint64_t dfd_base_addr;
+static uint64_t dfd_chain_length;
+
+void dfd_setup(uint64_t base_addr, uint64_t chain_length, uint64_t cache_dump)
+{
+	mmio_write_32(MTK_DRM_LATCH_CTL1, MTK_DRM_LATCH_CTL1_VAL);
+	mmio_write_32(MTK_DRM_LATCH_CTL2, MTK_DRM_LATCH_CTL2_VAL);
+	mmio_write_32(MTK_WDT_LATCH_CTL2, MTK_WDT_LATCH_CTL2_VAL);
+
+	mmio_clrbits_32(DFD_O_INTRF_MCU_PWR_CTL_MASK, BIT(2));
+	mmio_setbits_32(DFD_V50_GROUP_0_63_DIFF, 0x1);
+	sync_writel(DFD_INTERNAL_CTL, 0x5);
+	mmio_setbits_32(DFD_INTERNAL_CTL, BIT(13));
+	mmio_setbits_32(DFD_INTERNAL_CTL, 0x1F << 3);
+	mmio_setbits_32(DFD_INTERNAL_CTL, 0x3 << 9);
+	mmio_setbits_32(DFD_INTERNAL_CTL, 0x3 << 19);
+
+	mmio_write_32(DFD_INTERNAL_PWR_ON, 0xB);
+	mmio_write_32(DFD_CHAIN_LENGTH0, chain_length);
+	mmio_write_32(DFD_INTERNAL_SHIFT_CLK_RATIO, 0x0);
+	mmio_write_32(DFD_INTERNAL_TEST_SO_OVER_64, 0x1);
+
+	mmio_write_32(DFD_TEST_SI_0, 0x0);
+	mmio_write_32(DFD_TEST_SI_1, 0x0);
+	mmio_write_32(DFD_TEST_SI_2, 0x0);
+	mmio_write_32(DFD_TEST_SI_3, 0x0);
+
+	sync_writel(DFD_POWER_CTL, 0xF9);
+	sync_writel(DFD_READ_ADDR, DFD_READ_ADDR_VAL);
+	sync_writel(DFD_V30_CTL, 0xD);
+
+	mmio_write_32(DFD_O_SET_BASEADDR_REG, base_addr >> 24);
+	mmio_write_32(DFD_O_REG_0, 0);
+
+	/* setup global variables for suspend and resume */
+	dfd_enabled = true;
+	dfd_base_addr = base_addr;
+	dfd_chain_length = chain_length;
+	dfd_cache_dump = cache_dump;
+
+	if ((cache_dump & DFD_CACHE_DUMP_ENABLE) != 0UL) {
+		mmio_write_32(MTK_DRM_LATCH_CTL2, MTK_DRM_LATCH_CTL2_CACHE_VAL);
+		sync_writel(DFD_V35_ENABLE, 0x1);
+		sync_writel(DFD_V35_TAP_NUMBER, 0xB);
+		sync_writel(DFD_V35_TAP_EN, DFD_V35_TAP_EN_VAL);
+		sync_writel(DFD_V35_SEQ0_0, DFD_V35_SEQ0_0_VAL);
+
+		/* Cache dump only mode */
+		sync_writel(DFD_V35_CTL, 0x1);
+		mmio_write_32(DFD_INTERNAL_NUM_OF_TEST_SO_GROUP, 0xF);
+		mmio_write_32(DFD_CHAIN_LENGTH0, DFD_CHAIN_LENGTH_VAL);
+		mmio_write_32(DFD_CHAIN_LENGTH1, DFD_CHAIN_LENGTH_VAL);
+		mmio_write_32(DFD_CHAIN_LENGTH2, DFD_CHAIN_LENGTH_VAL);
+		mmio_write_32(DFD_CHAIN_LENGTH3, DFD_CHAIN_LENGTH_VAL);
+
+		if ((cache_dump & DFD_PARITY_ERR_TRIGGER) != 0UL) {
+			sync_writel(DFD_HW_TRIGGER_MASK, 0xC);
+			mmio_setbits_32(DFD_INTERNAL_CTL, 0x1 << 4);
+		}
+	}
+	dsbsy();
+}
+
+void dfd_resume(void)
+{
+	if (dfd_enabled == true) {
+		dfd_setup(dfd_base_addr, dfd_chain_length, dfd_cache_dump);
+	}
+}
diff --git a/plat/mediatek/drivers/dfd/mt8188/plat_dfd.h b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.h
new file mode 100644
index 0000000..5b98024
--- /dev/null
+++ b/plat/mediatek/drivers/dfd/mt8188/plat_dfd.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DFD_H
+#define PLAT_DFD_H
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#define sync_writel(addr, val) do { mmio_write_32((addr), (val)); dsbsy(); } while (0)
+
+#define PLAT_MTK_DFD_SETUP_MAGIC		(0x99716150)
+#define PLAT_MTK_DFD_READ_MAGIC			(0x99716151)
+#define PLAT_MTK_DFD_WRITE_MAGIC		(0x99716152)
+
+#define MTK_DRM_LATCH_CTL1			(DRM_BASE + 0x40)
+#define MTK_DRM_LATCH_CTL2			(DRM_BASE + 0x44)
+
+#define MTK_WDT_BASE				(RGU_BASE)
+#define MTK_WDT_INTERVAL			(MTK_WDT_BASE + 0x10)
+#define MTK_WDT_LATCH_CTL2			(MTK_WDT_BASE + 0x48)
+
+#define MCU_BIU_BASE				(MCUCFG_BASE)
+#define MISC1_CFG_BASE				(MCU_BIU_BASE + 0xE040)
+#define DFD_INTERNAL_CTL			(MISC1_CFG_BASE + 0x00)
+#define DFD_INTERNAL_PWR_ON			(MISC1_CFG_BASE + 0x08)
+#define DFD_CHAIN_LENGTH0			(MISC1_CFG_BASE + 0x0C)
+#define DFD_INTERNAL_SHIFT_CLK_RATIO		(MISC1_CFG_BASE + 0x10)
+#define DFD_CHAIN_LENGTH1			(MISC1_CFG_BASE + 0x1C)
+#define DFD_CHAIN_LENGTH2			(MISC1_CFG_BASE + 0x20)
+#define DFD_CHAIN_LENGTH3			(MISC1_CFG_BASE + 0x24)
+#define DFD_INTERNAL_TEST_SO_0			(MISC1_CFG_BASE + 0x28)
+#define DFD_INTERNAL_NUM_OF_TEST_SO_GROUP	(MISC1_CFG_BASE + 0x30)
+#define DFD_INTERNAL_TEST_SO_OVER_64		(MISC1_CFG_BASE + 0x34)
+#define DFD_INTERNAL_SW_NS_TRIGGER		(MISC1_CFG_BASE + 0x3c)
+#define DFD_V30_CTL				(MISC1_CFG_BASE + 0x48)
+#define DFD_V30_BASE_ADDR			(MISC1_CFG_BASE + 0x4C)
+#define DFD_POWER_CTL				(MISC1_CFG_BASE + 0x50)
+#define DFD_TEST_SI_0				(MISC1_CFG_BASE + 0x58)
+#define DFD_TEST_SI_1				(MISC1_CFG_BASE + 0x5C)
+#define DFD_CLEAN_STATUS			(MISC1_CFG_BASE + 0x60)
+#define DFD_TEST_SI_2				(MISC1_CFG_BASE + 0x1D8)
+#define DFD_TEST_SI_3				(MISC1_CFG_BASE + 0x1DC)
+#define DFD_READ_ADDR				(MISC1_CFG_BASE + 0x1E8)
+#define DFD_HW_TRIGGER_MASK			(MISC1_CFG_BASE + 0xBC)
+
+#define DFD_V35_ENABLE				(MCU_BIU_BASE + 0xE0A8)
+#define DFD_V35_TAP_NUMBER			(MCU_BIU_BASE + 0xE0AC)
+#define DFD_V35_TAP_EN				(MCU_BIU_BASE + 0xE0B0)
+#define DFD_V35_CTL				(MCU_BIU_BASE + 0xE0B4)
+#define DFD_V35_SEQ0_0				(MCU_BIU_BASE + 0xE0C0)
+#define DFD_V35_SEQ0_1				(MCU_BIU_BASE + 0xE0C4)
+#define DFD_V50_GROUP_0_63_DIFF			(MCU_BIU_BASE + 0xE2AC)
+
+#define DFD_O_PROTECT_EN_REG			(0x10001220)
+#define DFD_O_INTRF_MCU_PWR_CTL_MASK		(0x10001A3C)
+#define DFD_O_SET_BASEADDR_REG			(0x10043000)
+#define DFD_O_REG_0				(0x10001390)
+
+#define DFD_CACHE_DUMP_ENABLE			(1U)
+#define DFD_PARITY_ERR_TRIGGER			(2U)
+
+#define DFD_V35_TAP_EN_VAL			(0x43FF)
+#define DFD_V35_SEQ0_0_VAL			(0x63668820)
+#define DFD_READ_ADDR_VAL			(0x40000008)
+#define DFD_CHAIN_LENGTH_VAL			(0xFFFFFFFF)
+
+#define MTK_WDT_LATCH_CTL2_VAL			(0x9507FFFF)
+#define MTK_WDT_INTERVAL_VAL			(0x6600000A)
+#define MTK_DRM_LATCH_CTL2_VAL			(0x950607D0)
+#define MTK_DRM_LATCH_CTL2_CACHE_VAL		(0x95065DC0)
+
+#define MTK_DRM_LATCH_CTL1_VAL			(0x95000013)
+
+#endif /* PLAT_DFD_H */
diff --git a/plat/mediatek/drivers/dfd/rules.mk b/plat/mediatek/drivers/dfd/rules.mk
new file mode 100644
index 0000000..60fbc88
--- /dev/null
+++ b/plat/mediatek/drivers/dfd/rules.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mtk_dfd
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/dfd.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/$(MTK_SOC)/plat_dfd.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/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
new file mode 100644
index 0000000..66a369e
--- /dev/null
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EMI_MPU_H
+#define EMI_MPU_H
+
+#include <emi_mpu_priv.h>
+#include <platform_def.h>
+
+#define NO_PROTECTION			(0)
+#define SEC_RW				(1)
+#define SEC_RW_NSEC_R			(2)
+#define SEC_RW_NSEC_W			(3)
+#define SEC_R_NSEC_R			(4)
+#define FORBIDDEN			(5)
+#define SEC_R_NSEC_RW			(6)
+
+#define LOCK				(1)
+#define UNLOCK				(0)
+
+#if (EMI_MPU_DGROUP_NUM == 1)
+#define SET_ACCESS_PERMISSION(apc_ary, lock, d7, d6, d5, d4, d3, d2, d1, d0) \
+do { \
+	apc_ary[1] = 0; \
+	apc_ary[0] = \
+		(((unsigned int)  d7) << 21) | (((unsigned int)  d6) << 18) | \
+		(((unsigned int)  d5) << 15) | (((unsigned int)  d4) << 12) | \
+		(((unsigned int)  d3) <<  9) | (((unsigned int)  d2) <<  6) | \
+		(((unsigned int)  d1) <<  3) |  ((unsigned int)  d0) | \
+		((unsigned int) lock << 31); \
+} while (0)
+#elif (EMI_MPU_DGROUP_NUM == 2)
+#define SET_ACCESS_PERMISSION(apc_ary, lock, d15, d14, d13, d12, d11, d10, \
+				d9, d8, d7, d6, d5, d4, d3, d2, d1, d0) \
+do { \
+	apc_ary[1] = \
+		(((unsigned int) d15) << 21) | (((unsigned int) d14) << 18) | \
+		(((unsigned int) d13) << 15) | (((unsigned int) d12) << 12) | \
+		(((unsigned int) d11) <<  9) | (((unsigned int) d10) <<  6) | \
+		(((unsigned int)  d9) <<  3) |  ((unsigned int)  d8); \
+	apc_ary[0] = \
+		(((unsigned int)  d7) << 21) | (((unsigned int)  d6) << 18) | \
+		(((unsigned int)  d5) << 15) | (((unsigned int)  d4) << 12) | \
+		(((unsigned int)  d3) <<  9) | (((unsigned int)  d2) <<  6) | \
+		(((unsigned int)  d1) <<  3) |  ((unsigned int)  d0) | \
+		((unsigned int) lock << 31); \
+} while (0)
+#endif
+
+struct emi_region_info_t {
+	unsigned long long start;
+	unsigned long long end;
+	unsigned int region;
+	unsigned int apc[EMI_MPU_DGROUP_NUM];
+};
+
+int emi_mpu_init(void);
+int emi_mpu_set_protection(struct emi_region_info_t *region_info);
+void set_emi_mpu_regions(void);
+
+#endif
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
new file mode 100644
index 0000000..27b2b07
--- /dev/null
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <emi_mpu.h>
+#include <lib/mtk_init/mtk_init.h>
+
+#if ENABLE_EMI_MPU_SW_LOCK
+static unsigned char region_lock_state[EMI_MPU_REGION_NUM];
+#endif
+
+#define EMI_MPU_START_MASK		(0x00FFFFFF)
+#define EMI_MPU_END_MASK		(0x00FFFFFF)
+#define EMI_MPU_APC_SW_LOCK_MASK	(0x00FFFFFF)
+#define EMI_MPU_APC_HW_LOCK_MASK	(0x80FFFFFF)
+
+static int _emi_mpu_set_protection(unsigned int start, unsigned int end,
+					unsigned int apc)
+{
+	unsigned int dgroup;
+	unsigned int region;
+
+	region = (start >> 24) & 0xFF;
+	start &= EMI_MPU_START_MASK;
+	dgroup = (end >> 24) & 0xFF;
+	end &= EMI_MPU_END_MASK;
+
+	if  ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) {
+		WARN("invalid region, domain\n");
+		return -1;
+	}
+
+#if ENABLE_EMI_MPU_SW_LOCK
+	if (region_lock_state[region] == 1) {
+		WARN("invalid region\n");
+		return -1;
+	}
+
+	if ((dgroup == 0) && ((apc >> 31) & 0x1)) {
+		region_lock_state[region] = 1;
+	}
+
+	apc &= EMI_MPU_APC_SW_LOCK_MASK;
+#else
+	apc &= EMI_MPU_APC_HW_LOCK_MASK;
+#endif
+
+	if ((start >= DRAM_OFFSET) && (end >= start)) {
+		start -= DRAM_OFFSET;
+		end -= DRAM_OFFSET;
+	} else {
+		WARN("invalid range\n");
+		return -1;
+	}
+
+	mmio_write_32(EMI_MPU_SA(region), start);
+	mmio_write_32(EMI_MPU_EA(region), end);
+	mmio_write_32(EMI_MPU_APC(region, dgroup), apc);
+
+#if defined(SUB_EMI_MPU_BASE)
+	mmio_write_32(SUB_EMI_MPU_SA(region), start);
+	mmio_write_32(SUB_EMI_MPU_EA(region), end);
+	mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), apc);
+#endif
+	return 0;
+}
+
+static void dump_emi_mpu_regions(void)
+{
+	int region, i;
+
+	/* Only dump 8 regions(max: EMI_MPU_REGION_NUM --> 32) */
+	for (region = 0; region < 8; ++region) {
+		INFO("region %d:\n", region);
+		INFO("\tsa: 0x%x, ea: 0x%x\n",
+		     mmio_read_32(EMI_MPU_SA(region)), mmio_read_32(EMI_MPU_EA(region)));
+
+		for (i = 0; i < EMI_MPU_DGROUP_NUM; ++i) {
+			INFO("\tapc%d: 0x%x\n", i, mmio_read_32(EMI_MPU_APC(region, i)));
+		}
+	}
+}
+
+int emi_mpu_set_protection(struct emi_region_info_t *region_info)
+{
+	unsigned int start, end;
+	int i;
+
+	if (region_info->region >= EMI_MPU_REGION_NUM) {
+		WARN("invalid region\n");
+		return -1;
+	}
+
+	start = (unsigned int)(region_info->start >> EMI_MPU_ALIGN_BITS) |
+		(region_info->region << 24);
+
+	for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) {
+		end = (unsigned int)(region_info->end >> EMI_MPU_ALIGN_BITS) | (i << 24);
+
+		if (_emi_mpu_set_protection(start, end, region_info->apc[i]) < 0) {
+			WARN("Failed to set emi mpu protection(%d, %d, %d)\n",
+			     start, end, region_info->apc[i]);
+		}
+	}
+
+	return 0;
+}
+
+int emi_mpu_init(void)
+{
+	INFO("[%s] emi mpu initialization\n", __func__);
+
+	set_emi_mpu_regions();
+	dump_emi_mpu_regions();
+
+	return 0;
+}
+MTK_PLAT_SETUP_0_INIT(emi_mpu_init);
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
new file mode 100644
index 0000000..558533d
--- /dev/null
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <emi_mpu.h>
+
+void set_emi_mpu_regions(void)
+{
+	/* TODO: set emi mpu region */
+	INFO("%s, emi mpu is not setting currently\n", __func__);
+}
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
new file mode 100644
index 0000000..1ee7397
--- /dev/null
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EMI_MPU_PRIV_H
+#define EMI_MPU_PRIV_H
+
+#define ENABLE_EMI_MPU_SW_LOCK		(1)
+
+#define EMI_MPU_CTRL			(EMI_MPU_BASE + 0x000)
+#define EMI_MPU_DBG			(EMI_MPU_BASE + 0x004)
+#define EMI_MPU_SA0			(EMI_MPU_BASE + 0x100)
+#define EMI_MPU_EA0			(EMI_MPU_BASE + 0x200)
+#define EMI_MPU_SA(region)		(EMI_MPU_SA0 + (region * 4))
+#define EMI_MPU_EA(region)		(EMI_MPU_EA0 + (region * 4))
+#define EMI_MPU_APC0			(EMI_MPU_BASE + 0x300)
+#define EMI_MPU_APC(region, dgroup)	(EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100))
+#define EMI_MPU_CTRL_D0			(EMI_MPU_BASE + 0x800)
+#define EMI_MPU_CTRL_D(domain)		(EMI_MPU_CTRL_D0 + (domain * 4))
+#define EMI_RG_MASK_D0			(EMI_MPU_BASE + 0x900)
+#define EMI_RG_MASK_D(domain)		(EMI_RG_MASK_D0 + (domain * 4))
+
+#define SUB_EMI_MPU_CTRL		(SUB_EMI_MPU_BASE + 0x000)
+#define SUB_EMI_MPU_DBG			(SUB_EMI_MPU_BASE + 0x004)
+#define SUB_EMI_MPU_SA0			(SUB_EMI_MPU_BASE + 0x100)
+#define SUB_EMI_MPU_EA0			(SUB_EMI_MPU_BASE + 0x200)
+#define SUB_EMI_MPU_SA(region)		(SUB_EMI_MPU_SA0 + (region * 4))
+#define SUB_EMI_MPU_EA(region)		(SUB_EMI_MPU_EA0 + (region * 4))
+#define SUB_EMI_MPU_APC0		(SUB_EMI_MPU_BASE + 0x300)
+#define SUB_EMI_MPU_APC(region, dgroup)	(SUB_EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100))
+#define SUB_EMI_MPU_CTRL_D0		(SUB_EMI_MPU_BASE + 0x800)
+#define SUB_EMI_MPU_CTRL_D(domain)	(SUB_EMI_MPU_CTRL_D0 + (domain * 4))
+#define SUB_EMI_RG_MASK_D0		(SUB_EMI_MPU_BASE + 0x900)
+#define SUB_EMI_RG_MASK_D(domain)	(SUB_EMI_RG_MASK_D0 + (domain * 4))
+
+#define EMI_MPU_DOMAIN_NUM		(16)
+#define EMI_MPU_REGION_NUM		(32)
+#define EMI_MPU_ALIGN_BITS		(16)
+#define DRAM_OFFSET			(0x40000000 >> EMI_MPU_ALIGN_BITS)
+
+#define EMI_MPU_DGROUP_NUM		(EMI_MPU_DOMAIN_NUM / 8)
+
+#endif
diff --git a/plat/mediatek/drivers/emi_mpu/rules.mk b/plat/mediatek/drivers/emi_mpu/rules.mk
new file mode 100644
index 0000000..ed3d777
--- /dev/null
+++ b/plat/mediatek/drivers/emi_mpu/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 := emi_mpu
+LOCAL_SRCS-y := $(LOCAL_DIR)/emi_mpu_common.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/emi_mpu.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/drivers/mcusys/mcusys.c b/plat/mediatek/drivers/mcusys/mcusys.c
new file mode 100644
index 0000000..63edb23
--- /dev/null
+++ b/plat/mediatek/drivers/mcusys/mcusys.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <mtk_mmap_pool.h>
+#include <platform_def.h>
+
+static const mmap_region_t mcusys_mmap[] MTK_MMAP_SECTION = {
+	MAP_REGION_FLAT(MCUCFG_BASE, MCUCFG_REG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	{0}
+};
+DECLARE_MTK_MMAP_REGIONS(mcusys_mmap);
diff --git a/plat/mediatek/drivers/mcusys/rules.mk b/plat/mediatek/drivers/mcusys/rules.mk
new file mode 100644
index 0000000..5438998
--- /dev/null
+++ b/plat/mediatek/drivers/mcusys/rules.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mcusys
+
+PLAT_INCLUDES += -I$(LOCAL_DIR)/$(MCUSYS_VERSION)
+
+LOCAL_SRCS-y := $(LOCAL_DIR)/mcusys.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/mcusys/v1/mcucfg.h b/plat/mediatek/drivers/mcusys/v1/mcucfg.h
new file mode 100644
index 0000000..7aced5a
--- /dev/null
+++ b/plat/mediatek/drivers/mcusys/v1/mcucfg.h
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MCUCFG_V1_H
+#define MCUCFG_V1_H
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#endif /*__ASSEMBLER__*/
+
+#include <platform_def.h>
+
+#define MP2_MISC_CONFIG_BOOT_ADDR_L(cpu)	(MCUCFG_BASE + 0x2290 + ((cpu) * 8))
+#define MP2_MISC_CONFIG_BOOT_ADDR_H(cpu)	(MCUCFG_BASE + 0x2294 + ((cpu) * 8))
+
+#define MP2_CPUCFG				(MCUCFG_BASE + 0x2208)
+
+#define MP0_CPUTOP_SPMC_CTL			(MCUCFG_BASE + 0x788)
+#define MP1_CPUTOP_SPMC_CTL			(MCUCFG_BASE + 0x78C)
+#define MP1_CPUTOP_SPMC_SRAM_CTL		(MCUCFG_BASE + 0x790)
+
+#define CPUSYSx_CPUx_SPMC_CTL(cluster, cpu)	(MCUCFG_BASE + 0x1C30 + \
+						 (cluster) * 0x2000 + (cpu) * 4)
+
+#define CPUSYS0_CPU0_SPMC_CTL			(MCUCFG_BASE + 0x1C30)
+#define CPUSYS0_CPU1_SPMC_CTL			(MCUCFG_BASE + 0x1C34)
+#define CPUSYS0_CPU2_SPMC_CTL			(MCUCFG_BASE + 0x1C38)
+#define CPUSYS0_CPU3_SPMC_CTL			(MCUCFG_BASE + 0x1C3C)
+
+#define CPUSYS1_CPU0_SPMC_CTL			(MCUCFG_BASE + 0x3C30)
+#define CPUSYS1_CPU1_SPMC_CTL			(MCUCFG_BASE + 0x3C34)
+#define CPUSYS1_CPU2_SPMC_CTL			(MCUCFG_BASE + 0x3C38)
+#define CPUSYS1_CPU3_SPMC_CTL			(MCUCFG_BASE + 0x3C3C)
+
+/* CPC related registers */
+#define CPC_MCUSYS_CPC_OFF_THRES		(MCUCFG_BASE + 0xA714)
+#define CPC_MCUSYS_PWR_CTRL			(MCUCFG_BASE + 0xA804)
+#define CPC_MCUSYS_CPC_FLOW_CTRL_CFG		(MCUCFG_BASE + 0xA814)
+#define CPC_MCUSYS_LAST_CORE_REQ		(MCUCFG_BASE + 0xA818)
+#define CPC_MCUSYS_MP_LAST_CORE_RESP		(MCUCFG_BASE + 0xA81C)
+#define CPC_MCUSYS_LAST_CORE_RESP		(MCUCFG_BASE + 0xA824)
+#define CPC_MCUSYS_PWR_ON_MASK			(MCUCFG_BASE + 0xA828)
+#define CPC_SPMC_PWR_STATUS			(MCUCFG_BASE + 0xA840)
+#define CPC_MCUSYS_CPU_ON_SW_HINT_SET		(MCUCFG_BASE + 0xA8A8)
+#define CPC_MCUSYS_CPU_ON_SW_HINT_CLR		(MCUCFG_BASE + 0xA8AC)
+#define CPC_MCUSYS_CPC_DBG_SETTING		(MCUCFG_BASE + 0xAB00)
+#define CPC_MCUSYS_CPC_KERNEL_TIME_L_BASE	(MCUCFG_BASE + 0xAB04)
+#define CPC_MCUSYS_CPC_KERNEL_TIME_H_BASE	(MCUCFG_BASE + 0xAB08)
+#define CPC_MCUSYS_CPC_SYSTEM_TIME_L_BASE	(MCUCFG_BASE + 0xAB0C)
+#define CPC_MCUSYS_CPC_SYSTEM_TIME_H_BASE	(MCUCFG_BASE + 0xAB10)
+#define CPC_MCUSYS_TRACE_SEL			(MCUCFG_BASE + 0xAB14)
+#define CPC_MCUSYS_TRACE_DATA			(MCUCFG_BASE + 0xAB20)
+#define CPC_MCUSYS_CLUSTER_COUNTER		(MCUCFG_BASE + 0xAB70)
+#define CPC_MCUSYS_CLUSTER_COUNTER_CLR		(MCUCFG_BASE + 0xAB74)
+
+/* CPC_MCUSYS_CPC_FLOW_CTRL_CFG bit control */
+#define CPC_CTRL_ENABLE				BIT(16)
+#define SSPM_CORE_PWR_ON_EN			BIT(7) /* for cpu-hotplug */
+#define SSPM_ALL_PWR_CTRL_EN			BIT(13) /* for cpu-hotplug */
+#define GIC_WAKEUP_IGNORE(cpu)			BIT(21 + cpu)
+
+#define CPC_MCUSYS_CPC_RESET_ON_KEEP_ON		BIT(17)
+#define CPC_MCUSYS_CPC_RESET_PWR_ON_EN		BIT(20)
+
+/* SPMC related registers */
+#define SPM_MCUSYS_PWR_CON			(MCUCFG_BASE + 0xD200)
+#define SPM_MP0_CPUTOP_PWR_CON			(MCUCFG_BASE + 0xD204)
+#define SPM_MP0_CPU0_PWR_CON			(MCUCFG_BASE + 0xD208)
+#define SPM_MP0_CPU1_PWR_CON			(MCUCFG_BASE + 0xD20C)
+#define SPM_MP0_CPU2_PWR_CON			(MCUCFG_BASE + 0xD210)
+#define SPM_MP0_CPU3_PWR_CON			(MCUCFG_BASE + 0xD214)
+#define SPM_MP0_CPU4_PWR_CON			(MCUCFG_BASE + 0xD218)
+#define SPM_MP0_CPU5_PWR_CON			(MCUCFG_BASE + 0xD21C)
+#define SPM_MP0_CPU6_PWR_CON			(MCUCFG_BASE + 0xD220)
+#define SPM_MP0_CPU7_PWR_CON			(MCUCFG_BASE + 0xD224)
+
+/* bit fields of SPM_*_PWR_CON */
+#define PWR_ON_ACK				BIT(31)
+#define VPROC_EXT_OFF				BIT(7)
+#define DORMANT_EN				BIT(6)
+#define RESETPWRON_CONFIG			BIT(5)
+#define PWR_CLK_DIS				BIT(4)
+#define PWR_ON					BIT(2)
+#define PWR_RST_B				BIT(0)
+
+#define SPARK2LDO				(MCUCFG_BASE + 0x2700)
+/* APB Module mcucfg */
+#define MP0_CA7_CACHE_CONFIG			(MCUCFG_BASE + 0x000)
+#define MP0_AXI_CONFIG				(MCUCFG_BASE + 0x02C)
+#define MP0_MISC_CONFIG0			(MCUCFG_BASE + 0x030)
+#define MP0_MISC_CONFIG1			(MCUCFG_BASE + 0x034)
+#define MP0_MISC_CONFIG2			(MCUCFG_BASE + 0x038)
+#define MP0_MISC_CONFIG_BOOT_ADDR(cpu)		(MCUCFG_BASE + 0x038 + ((cpu) * 8))
+#define MP0_MISC_CONFIG3			(MCUCFG_BASE + 0x03C)
+#define MP0_MISC_CONFIG9			(MCUCFG_BASE + 0x054)
+#define MP0_CA7_MISC_CONFIG			(MCUCFG_BASE + 0x064)
+
+#define MP0_RW_RSVD0				(MCUCFG_BASE + 0x06C)
+#define MP1_CA7_CACHE_CONFIG			(MCUCFG_BASE + 0x200)
+#define MP1_AXI_CONFIG				(MCUCFG_BASE + 0x22C)
+#define MP1_MISC_CONFIG0			(MCUCFG_BASE + 0x230)
+#define MP1_MISC_CONFIG1			(MCUCFG_BASE + 0x234)
+#define MP1_MISC_CONFIG2			(MCUCFG_BASE + 0x238)
+#define MP1_MISC_CONFIG_BOOT_ADDR(cpu)		(MCUCFG_BASE + 0x238 + ((cpu) * 8))
+#define MP1_MISC_CONFIG3			(MCUCFG_BASE + 0x23C)
+#define MP1_MISC_CONFIG9			(MCUCFG_BASE + 0x254)
+#define MP1_CA7_MISC_CONFIG			(MCUCFG_BASE + 0x264)
+
+#define CCI_ADB400_DCM_CONFIG			(MCUCFG_BASE + 0x740)
+#define SYNC_DCM_CONFIG				(MCUCFG_BASE + 0x744)
+
+#define MP0_CLUSTER_CFG0			(MCUCFG_BASE + 0xC8D0)
+
+#define MP0_SPMC				(MCUCFG_BASE + 0x788)
+#define MP1_SPMC				(MCUCFG_BASE + 0x78C)
+#define MP2_AXI_CONFIG				(MCUCFG_BASE + 0x220C)
+#define MP2_AXI_CONFIG_ACINACTM			BIT(0)
+#define MP2_AXI_CONFIG_AINACTS			BIT(4)
+
+#define MPx_AXI_CONFIG_ACINACTM			BIT(4)
+#define MPx_AXI_CONFIG_AINACTS			BIT(5)
+
+#define MPx_CA7_MISC_CONFIG_standbywfil2	BIT(28)
+
+#define MP0_CPU0_STANDBYWFE			BIT(20)
+#define MP0_CPU1_STANDBYWFE			BIT(21)
+#define MP0_CPU2_STANDBYWFE			BIT(22)
+#define MP0_CPU3_STANDBYWFE			BIT(23)
+
+#define MP1_CPU0_STANDBYWFE			BIT(20)
+#define MP1_CPU1_STANDBYWFE			BIT(21)
+#define MP1_CPU2_STANDBYWFE			BIT(22)
+#define MP1_CPU3_STANDBYWFE			BIT(23)
+
+#define CPUSYS0_SPARKVRETCNTRL			(MCUCFG_BASE+0x1c00)
+#define CPUSYS0_SPARKEN				(MCUCFG_BASE+0x1c04)
+#define CPUSYS0_AMUXSEL				(MCUCFG_BASE+0x1c08)
+#define CPUSYS1_SPARKVRETCNTRL			(MCUCFG_BASE+0x3c00)
+#define CPUSYS1_SPARKEN				(MCUCFG_BASE+0x3c04)
+#define CPUSYS1_AMUXSEL				(MCUCFG_BASE+0x3c08)
+
+#define MP2_PWR_RST_CTL				(MCUCFG_BASE + 0x2008)
+#define MP2_PTP3_CPUTOP_SPMC0			(MCUCFG_BASE + 0x22A0)
+#define MP2_PTP3_CPUTOP_SPMC1			(MCUCFG_BASE + 0x22A4)
+
+#define MP2_COQ					(MCUCFG_BASE + 0x22BC)
+#define MP2_COQ_SW_DIS				BIT(0)
+
+#define MP2_CA15M_MON_SEL			(MCUCFG_BASE + 0x2400)
+#define MP2_CA15M_MON_L				(MCUCFG_BASE + 0x2404)
+
+#define CPUSYS2_CPU0_SPMC_CTL			(MCUCFG_BASE + 0x2430)
+#define CPUSYS2_CPU1_SPMC_CTL			(MCUCFG_BASE + 0x2438)
+#define CPUSYS2_CPU0_SPMC_STA			(MCUCFG_BASE + 0x2434)
+#define CPUSYS2_CPU1_SPMC_STA			(MCUCFG_BASE + 0x243C)
+
+#define MP0_CA7L_DBG_PWR_CTRL			(MCUCFG_BASE + 0x068)
+#define MP1_CA7L_DBG_PWR_CTRL			(MCUCFG_BASE + 0x268)
+#define BIG_DBG_PWR_CTRL			(MCUCFG_BASE + 0x75C)
+
+#define MP2_SW_RST_B				BIT(0)
+#define MP2_TOPAON_APB_MASK			BIT(1)
+#define B_SW_HOT_PLUG_RESET			BIT(30)
+#define B_SW_PD_OFFSET				(18)
+#define B_SW_PD					(0x3F << B_SW_PD_OFFSET)
+
+#define B_SW_SRAM_SLEEPB_OFFSET			(12)
+#define B_SW_SRAM_SLEEPB			(0x3F << B_SW_SRAM_SLEEPB_OFFSET)
+
+#define B_SW_SRAM_ISOINTB			BIT(9)
+#define B_SW_ISO				BIT(8)
+#define B_SW_LOGIC_PDB				BIT(7)
+#define B_SW_LOGIC_PRE2_PDB			BIT(6)
+#define B_SW_LOGIC_PRE1_PDB			BIT(5)
+#define B_SW_FSM_OVERRIDE			BIT(4)
+#define B_SW_PWR_ON				BIT(3)
+#define B_SW_PWR_ON_OVERRIDE_EN			BIT(2)
+
+#define B_FSM_STATE_OUT_OFFSET			(6)
+#define B_FSM_STATE_OUT_MASK			(0x1F << B_FSM_STATE_OUT_OFFSET)
+#define B_SW_LOGIC_PDBO_ALL_OFF_ACK		BIT(5)
+#define B_SW_LOGIC_PDBO_ALL_ON_ACK		BIT(4)
+#define B_SW_LOGIC_PRE2_PDBO_ALL_ON_ACK		BIT(3)
+#define B_SW_LOGIC_PRE1_PDBO_ALL_ON_ACK		BIT(2)
+
+
+#define B_FSM_OFF				(0U << B_FSM_STATE_OUT_OFFSET)
+#define B_FSM_ON				(1U << B_FSM_STATE_OUT_OFFSET)
+#define B_FSM_RET				(2U << B_FSM_STATE_OUT_OFFSET)
+
+#ifndef __ASSEMBLER__
+/* cpu boot mode */
+enum mp0_coucfg_64bit_ctrl {
+	MP0_CPUCFG_64BIT_SHIFT = 12,
+	MP1_CPUCFG_64BIT_SHIFT = 28,
+	MP0_CPUCFG_64BIT = 0xfu << MP0_CPUCFG_64BIT_SHIFT,
+	MP1_CPUCFG_64BIT = 0xfu << MP1_CPUCFG_64BIT_SHIFT,
+};
+
+enum mp1_dis_rgu0_ctrl {
+	MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT = 0,
+	MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT = 4,
+	MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT = 8,
+	MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT = 12,
+	MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT = 16,
+	MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT,
+	MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT,
+	MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT,
+	MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT,
+	MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK = 0xF << MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT,
+};
+
+enum mp1_ainacts_ctrl {
+	MP1_AINACTS_SHIFT = 4,
+	MP1_AINACTS = 1U << MP1_AINACTS_SHIFT,
+};
+
+enum mp1_sw_cg_gen {
+	MP1_SW_CG_GEN_SHIFT = 12,
+	MP1_SW_CG_GEN = 1U << MP1_SW_CG_GEN_SHIFT,
+};
+
+enum mp1_l2rstdisable {
+	MP1_L2RSTDISABLE_SHIFT = 14,
+	MP1_L2RSTDISABLE = 1U << MP1_L2RSTDISABLE_SHIFT,
+};
+#endif /*__ASSEMBLER__*/
+
+#endif  /* MCUCFG_V1_H */
diff --git a/plat/mediatek/helpers/armv8_2/arch_helpers.S b/plat/mediatek/helpers/armv8_2/arch_helpers.S
new file mode 100644
index 0000000..02d8d53
--- /dev/null
+++ b/plat/mediatek/helpers/armv8_2/arch_helpers.S
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cpu_macros.S>
+#if CONFIG_MTK_MCUSYS
+#include <mcucfg.h>
+#endif
+#include <platform_def.h>
+	/*
+	 * Declare as weak function so that can be
+	 * overwritten by platform helpers
+	 */
+	.weak platform_mem_init
+	.weak plat_core_pos_by_mpidr
+	.weak plat_my_core_pos
+	.weak plat_mediatek_calc_core_pos
+	.global plat_mpidr_by_core_pos
+	.global plat_reset_handler
+
+	/* -----------------------------------------------------
+	 * unsigned long plat_mpidr_by_core_pos(uint32_t cpuid)
+	 * This function calcuate mpidr by cpu pos if cpu
+	 * topology is linear.
+	 *
+	 * Clobbers: x0-x1
+	 * -----------------------------------------------------
+	 */
+func plat_mpidr_by_core_pos
+	lsl x0, x0, #MPIDR_AFF1_SHIFT
+	mrs x1, mpidr_el1
+	and x1, x1, #MPIDR_MT_MASK
+	orr x0, x0, x1
+	ret
+endfunc plat_mpidr_by_core_pos
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_arm_calc_core_pos()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b plat_mediatek_calc_core_pos
+endfunc plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 * int plat_mediatek_calc_core_pos(u_register_t mpidr);
+	 *
+	 * In ARMv8.2, AFF2 is cluster id, AFF1 is core id and
+	 * AFF0 is thread id. There is only one cluster in ARMv8.2
+	 * and one thread in current implementation.
+	 *
+	 * With this function: CorePos = CoreID (AFF1)
+	 * we do it with x0 = (x0 >> 8) & 0xff
+	 * -----------------------------------------------------
+	 */
+func plat_mediatek_calc_core_pos
+	b plat_core_pos_by_mpidr
+endfunc plat_mediatek_calc_core_pos
+
+	/* ------------------------------------------------------
+	 * int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
+	 *
+	 * This function implements a part of the critical
+	 * interface between the psci generic layer and the
+	 * platform that allows the former to query the platform
+	 * to convert an MPIDR to a unique linear index.
+	 *
+	 * Clobbers: x0-x1
+	 * ------------------------------------------------------
+	 */
+func plat_core_pos_by_mpidr
+	mov	x1, #MPIDR_AFFLVL_MASK
+	and	x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
+	ret
+endfunc plat_core_pos_by_mpidr
+
+	/* --------------------------------------------------------
+	 * void platform_mem_init (void);
+	 *
+	 * Any memory init, relocation to be done before the
+	 * platform boots. Called very early in the boot process.
+	 * --------------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
+
+func plat_reset_handler
+#if CONFIG_MTK_MCUSYS
+	mov	x10, x30
+	bl	plat_my_core_pos
+	mov	x30, x10
+	mov     w1, #0x1
+	lsl     w1, w1, w0
+	ldr	x0, =CPC_MCUSYS_CPU_ON_SW_HINT_SET
+	str     w1, [x0]
+	dsb     sy
+#endif
+
+#if CONFIG_MTK_ECC
+	mov x10, x30
+	/* enable sequence of ecc for cpus */
+	bl disable_core_ecc
+	bl ft_ecc_clear_per_core
+	bl enable_core_ecc
+	mov x30, x10
+#endif
+
+	ret
+endfunc plat_reset_handler
diff --git a/plat/mediatek/helpers/rules.mk b/plat/mediatek/helpers/rules.mk
new file mode 100644
index 0000000..ae8068e
--- /dev/null
+++ b/plat/mediatek/helpers/rules.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := helpers
+LOCAL_SRCS-y += $(LOCAL_DIR)/$(ARCH_VERSION)/arch_helpers.S
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/include/armv8_2/arch_def.h b/plat/mediatek/include/armv8_2/arch_def.h
new file mode 100644
index 0000000..61f818f
--- /dev/null
+++ b/plat/mediatek/include/armv8_2/arch_def.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ARCH_DEF_H
+#define ARCH_DEF_H
+
+/* Topology constants */
+#define PLAT_MAX_PWR_LVL		(2)
+#define PLAT_MAX_RET_STATE		(1)
+#define PLAT_MAX_OFF_STATE		(2)
+
+#define PLATFORM_SYSTEM_COUNT		(1)
+#define PLATFORM_CLUSTER_COUNT		(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT	(8)
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	(8)
+#define PLATFORM_NUM_AFFS		(PLATFORM_SYSTEM_COUNT + \
+					 PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+/* Cachline size */
+#define CACHE_WRITEBACK_SHIFT		(6)
+#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
+
+#endif /* ARCH_DEF_H */
+
diff --git a/plat/mediatek/include/cold_boot.h b/plat/mediatek/include/cold_boot.h
deleted file mode 100644
index 6b94b57..0000000
--- a/plat/mediatek/include/cold_boot.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2022, Mediatek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef COLD_BOOT_H
-#define COLD_BOOT_H
-
-#include <stdint.h>
-
-/*******************************************************************************
- * Function and variable prototypes
- ******************************************************************************/
-#define LINUX_KERNEL_32	(0)
-#define LINUX_KERNEL_64	(1)
-#define DEVINFO_SIZE	(4)
-
-struct atf_arg_t {
-	uint32_t atf_magic;
-	uint32_t tee_support;
-	uint64_t tee_entry;
-	uint64_t tee_boot_arg_addr;
-	uint32_t hwuid[4]; /* HW Unique id for t-base used */
-	uint32_t HRID[8]; /* HW random id for t-base used */
-	uint32_t devinfo[DEVINFO_SIZE];
-};
-
-struct mtk_bl31_fw_config {
-	void *from_bl2; /* MTK boot tag */
-	void *soc_fw_config;
-	void *hw_config;
-	void *reserved;
-};
-
-enum {
-	BOOT_ARG_FROM_BL2,
-	BOOT_ARG_SOC_FW_CONFIG,
-	BOOT_ARG_HW_CONFIG,
-	BOOT_ARG_RESERVED
-};
-
-struct kernel_info {
-	uint64_t pc;
-	uint64_t r0;
-	uint64_t r1;
-	uint64_t r2;
-	uint64_t k32_64;
-};
-
-struct mtk_bl_param_t {
-	uint64_t bootarg_loc;
-	uint64_t bootarg_size;
-	uint64_t bl33_start_addr;
-	uint64_t atf_arg_addr;
-};
-
-void *get_mtk_bl31_fw_config(int index);
-bool is_el1_2nd_bootloader(void);
-
-#endif /* COLD_BOOT_H */
diff --git a/plat/mediatek/lib/pm/armv8_2/pwr_ctrl.c b/plat/mediatek/lib/pm/armv8_2/pwr_ctrl.c
new file mode 100644
index 0000000..ccd04e6
--- /dev/null
+++ b/plat/mediatek/lib/pm/armv8_2/pwr_ctrl.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/arm/gicv3.h>
+#include <lib/psci/psci.h>
+#include <lib/utils.h>
+#ifdef MTK_PUBEVENT_ENABLE
+#include <mtk_event/mtk_pubsub_events.h>
+#endif
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+#include <dfd.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <lib/pm/mtk_pm.h>
+#include <mt_gic_v3.h>
+#include <platform_def.h>
+
+#define IS_AFFLV_PUBEVENT(_pstate) \
+	((_pstate & (MT_CPUPM_PWR_DOMAIN_MCUSYS | MT_CPUPM_PWR_DOMAIN_CLUSTER)) != 0)
+
+#ifdef MTK_PUBEVENT_ENABLE
+#define MT_CPUPM_EVENT_PWR_ON(x) ({ \
+	PUBLISH_EVENT_ARG(mt_cpupm_publish_pwr_on, (const void *)(x)); })
+
+#define MT_CPUPM_EVENT_PWR_OFF(x) ({ \
+	PUBLISH_EVENT_ARG(mt_cpupm_publish_pwr_off, (const void *)(x)); })
+
+#define MT_CPUPM_EVENT_AFFLV_PWR_ON(x) ({ \
+	PUBLISH_EVENT_ARG(mt_cpupm_publish_afflv_pwr_on, (const void *)(x)); })
+
+#define MT_CPUPM_EVENT_AFFLV_PWR_OFF(x) ({ \
+	PUBLISH_EVENT_ARG(mt_cpupm_publish_afflv_pwr_off, (const void *)(x)); })
+
+#else
+#define MT_CPUPM_EVENT_PWR_ON(x) ({ (void)x; })
+#define MT_CPUPM_EVENT_PWR_OFF(x) ({ (void)x; })
+#define MT_CPUPM_EVENT_AFFLV_PWR_ON(x) ({ (void)x; })
+#define MT_CPUPM_EVENT_AFFLV_PWR_OFF(x) ({ (void)x; })
+#endif
+
+/*
+ * The cpu require to cluster power stattus
+ * [0] : The cpu require cluster power down
+ * [1] : The cpu require cluster power on
+ */
+#define coordinate_cluster(onoff) write_clusterpwrdn_el1(onoff)
+#define coordinate_cluster_pwron() coordinate_cluster(1)
+#define coordinate_cluster_pwroff() coordinate_cluster(0)
+
+/* defaultly disable all functions */
+#define MTK_CPUPM_FN_MASK_DEFAULT	(0)
+
+struct mtk_cpu_pwr_ctrl {
+	unsigned int fn_mask;
+	struct mtk_cpu_pm_ops *ops;
+	struct mtk_cpu_smp_ops *smp;
+};
+
+static struct mtk_cpu_pwr_ctrl mtk_cpu_pwr = {
+	.fn_mask = MTK_CPUPM_FN_MASK_DEFAULT,
+	.ops = NULL,
+};
+
+#define IS_CPUIDLE_FN_ENABLE(x)	((mtk_cpu_pwr.ops != NULL) && ((mtk_cpu_pwr.fn_mask & x) != 0))
+#define IS_CPUSMP_FN_ENABLE(x)	((mtk_cpu_pwr.smp != NULL) && ((mtk_cpu_pwr.fn_mask & x) != 0))
+
+/* per-cpu power state */
+static unsigned int armv8_2_power_state[PLATFORM_CORE_COUNT];
+
+#define armv8_2_get_pwr_stateid(cpu) psci_get_pstate_id(armv8_2_power_state[cpu])
+
+static unsigned int get_mediatek_pstate(unsigned int domain, unsigned int psci_state,
+					struct mtk_cpupm_pwrstate *state)
+{
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_CPUPM_GET_PWR_STATE)) {
+		return mtk_cpu_pwr.ops->get_pstate(domain, psci_state, state);
+	}
+
+	return 0;
+}
+
+unsigned int armv8_2_get_pwr_afflv(const psci_power_state_t *state_info)
+{
+	int i;
+
+	for (i = (int)PLAT_MAX_PWR_LVL; i >= (int)PSCI_CPU_PWR_LVL; i--) {
+		if (is_local_state_run(state_info->pwr_domain_state[i]) == 0) {
+			return (unsigned int) i;
+		}
+	}
+
+	return PSCI_INVALID_PWR_LVL;
+}
+
+/* MediaTek mcusys power on control interface */
+static void armv8_2_mcusys_pwr_on_common(const struct mtk_cpupm_pwrstate *state)
+{
+	mt_gic_init();
+	mt_gic_distif_restore();
+	gic_sgi_restore_all();
+
+	dfd_resume();
+
+	/* Add code here that behavior before system enter mcusys'on */
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_RESUME_MCUSYS)) {
+		mtk_cpu_pwr.ops->mcusys_resume(state);
+	}
+}
+
+/* MediaTek mcusys power down control interface */
+static void armv8_2_mcusys_pwr_dwn_common(const struct mtk_cpupm_pwrstate *state)
+{
+	mt_gic_distif_save();
+	gic_sgi_save_all();
+
+	/* Add code here that behaves before entering mcusys off */
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_SUSPEND_MCUSYS)) {
+		mtk_cpu_pwr.ops->mcusys_suspend(state);
+	}
+}
+
+/* MediaTek Cluster power on control interface */
+static void armv8_2_cluster_pwr_on_common(const struct mtk_cpupm_pwrstate *state)
+{
+	/* Add code here that behavior before system enter cluster'on */
+#if defined(MTK_CM_MGR) && !defined(MTK_FPGA_EARLY_PORTING)
+	/* init cpu stall counter */
+	init_cpu_stall_counter_all();
+#endif
+
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_RESUME_CLUSTER)) {
+		mtk_cpu_pwr.ops->cluster_resume(state);
+	}
+}
+
+/* MediaTek Cluster power down control interface */
+static void armv8_2_cluster_pwr_dwn_common(const struct mtk_cpupm_pwrstate *state)
+{
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_SUSPEND_CLUSTER)) {
+		mtk_cpu_pwr.ops->cluster_suspend(state);
+	}
+}
+
+/* MediaTek CPU power on control interface */
+static void armv8_2_cpu_pwr_on_common(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	coordinate_cluster_pwron();
+
+	gicv3_rdistif_on(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)) {
+		mt_gic_rdistif_restore_all();
+	} else {
+		mt_gic_rdistif_restore();
+	}
+}
+
+/* MediaTek CPU power down control interface */
+static void armv8_2_cpu_pwr_dwn_common(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	if ((pstate & MT_CPUPM_PWR_DOMAIN_PERCORE_DSU) != 0) {
+		coordinate_cluster_pwroff();
+	}
+
+	mt_gic_rdistif_save();
+	gicv3_cpuif_disable(plat_my_core_pos());
+	gicv3_rdistif_off(plat_my_core_pos());
+}
+
+static void armv8_2_cpu_pwr_resume(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	armv8_2_cpu_pwr_on_common(state, pstate);
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_RESUME_CORE)) {
+		mtk_cpu_pwr.ops->cpu_resume(state);
+	}
+}
+
+static void armv8_2_cpu_pwr_suspend(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_SUSPEND_CORE)) {
+		mtk_cpu_pwr.ops->cpu_suspend(state);
+	}
+	armv8_2_cpu_pwr_dwn_common(state, pstate);
+}
+
+static void armv8_2_cpu_pwr_on(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	armv8_2_cpu_pwr_on_common(state, pstate);
+
+	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_SMP_CORE_ON)) {
+		mtk_cpu_pwr.smp->cpu_on(state);
+	}
+}
+
+static void armv8_2_cpu_pwr_off(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
+{
+	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_SMP_CORE_OFF)) {
+		mtk_cpu_pwr.smp->cpu_off(state);
+	}
+	armv8_2_cpu_pwr_dwn_common(state, pstate);
+}
+
+/* MediaTek PSCI power domain */
+static int armv8_2_power_domain_on(u_register_t mpidr)
+{
+	int ret = PSCI_E_SUCCESS;
+	int cpu = plat_core_pos_by_mpidr(mpidr);
+	uintptr_t entry = plat_pm_get_warm_entry();
+
+	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_PWR_ON_CORE_PREPARE)) {
+		if (mtk_cpu_pwr.smp->cpu_pwr_on_prepare(cpu, entry) != 0) {
+			ret = PSCI_E_DENIED;
+		}
+	}
+	INFO("CPU %u power domain prepare on\n", cpu);
+	return ret;
+}
+
+/* MediaTek PSCI power domain */
+static void armv8_2_power_domain_on_finish(const psci_power_state_t *state)
+{
+	struct mt_cpupm_event_data nb;
+	unsigned int pstate = (MT_CPUPM_PWR_DOMAIN_CORE | MT_CPUPM_PWR_DOMAIN_PERCORE_DSU);
+	struct mtk_cpupm_pwrstate pm_state = {
+		.info = {
+			.cpuid = plat_my_core_pos(),
+			.mode = MTK_CPU_PM_SMP,
+		},
+		.pwr = {
+			.afflv = armv8_2_get_pwr_afflv(state),
+			.state_id = 0x0,
+		},
+	};
+
+	armv8_2_cpu_pwr_on(&pm_state, pstate);
+
+	nb.cpuid = pm_state.info.cpuid;
+	nb.pwr_domain = pstate;
+	MT_CPUPM_EVENT_PWR_ON(&nb);
+
+	INFO("CPU %u power domain on finished\n", pm_state.info.cpuid);
+}
+
+/* MediaTek PSCI power domain */
+static void armv8_2_power_domain_off(const psci_power_state_t *state)
+{
+	struct mt_cpupm_event_data nb;
+	unsigned int pstate = (MT_CPUPM_PWR_DOMAIN_CORE | MT_CPUPM_PWR_DOMAIN_PERCORE_DSU);
+	struct mtk_cpupm_pwrstate pm_state = {
+		.info = {
+			.cpuid = plat_my_core_pos(),
+			.mode = MTK_CPU_PM_SMP,
+		},
+		.pwr = {
+			.afflv = armv8_2_get_pwr_afflv(state),
+			.state_id = 0x0,
+		},
+	};
+	armv8_2_cpu_pwr_off(&pm_state, pstate);
+
+	nb.cpuid = pm_state.info.cpuid;
+	nb.pwr_domain = pstate;
+	MT_CPUPM_EVENT_PWR_OFF(&nb);
+
+	INFO("CPU %u power domain off\n", pm_state.info.cpuid);
+}
+
+/* MediaTek PSCI power domain */
+static void armv8_2_power_domain_suspend(const psci_power_state_t *state)
+{
+	unsigned int pstate = 0;
+	struct mt_cpupm_event_data nb;
+	struct mtk_cpupm_pwrstate pm_state = {
+		.info = {
+			.cpuid = plat_my_core_pos(),
+			.mode = MTK_CPU_PM_CPUIDLE,
+		},
+	};
+
+	pm_state.pwr.state_id = armv8_2_get_pwr_stateid(pm_state.info.cpuid);
+	pm_state.pwr.afflv = armv8_2_get_pwr_afflv(state);
+	pm_state.pwr.raw = state;
+
+	pstate = get_mediatek_pstate(CPUPM_PWR_OFF,
+				     armv8_2_power_state[pm_state.info.cpuid], &pm_state);
+
+	armv8_2_cpu_pwr_suspend(&pm_state, pstate);
+
+	if ((pstate & MT_CPUPM_PWR_DOMAIN_CLUSTER) != 0) {
+		armv8_2_cluster_pwr_dwn_common(&pm_state);
+	}
+
+	if ((pstate & MT_CPUPM_PWR_DOMAIN_MCUSYS) != 0) {
+		armv8_2_mcusys_pwr_dwn_common(&pm_state);
+	}
+
+	nb.cpuid = pm_state.info.cpuid;
+	nb.pwr_domain = pstate;
+	MT_CPUPM_EVENT_PWR_OFF(&nb);
+
+	if (IS_AFFLV_PUBEVENT(pstate)) {
+		MT_CPUPM_EVENT_AFFLV_PWR_OFF(&nb);
+	}
+}
+
+/* MediaTek PSCI power domain */
+static void armv8_2_power_domain_suspend_finish(const psci_power_state_t *state)
+{
+	unsigned int pstate = 0;
+	struct mt_cpupm_event_data nb;
+	struct mtk_cpupm_pwrstate pm_state = {
+		.info = {
+			.cpuid = plat_my_core_pos(),
+			.mode = MTK_CPU_PM_CPUIDLE,
+		},
+	};
+
+	pm_state.pwr.state_id = armv8_2_get_pwr_stateid(pm_state.info.cpuid);
+	pm_state.pwr.afflv = armv8_2_get_pwr_afflv(state);
+	pm_state.pwr.raw = state;
+
+	pstate = get_mediatek_pstate(CPUPM_PWR_ON,
+				     armv8_2_power_state[pm_state.info.cpuid], &pm_state);
+
+	if ((pstate & MT_CPUPM_PWR_DOMAIN_MCUSYS) != 0) {
+		armv8_2_mcusys_pwr_on_common(&pm_state);
+	}
+
+	if ((pstate & MT_CPUPM_PWR_DOMAIN_CLUSTER) != 0) {
+		armv8_2_cluster_pwr_on_common(&pm_state);
+	}
+
+	armv8_2_cpu_pwr_resume(&pm_state, pstate);
+
+	nb.cpuid = pm_state.info.cpuid;
+	nb.pwr_domain = pstate;
+	MT_CPUPM_EVENT_PWR_ON(&nb);
+
+	if (IS_AFFLV_PUBEVENT(pstate)) {
+		MT_CPUPM_EVENT_AFFLV_PWR_ON(&nb);
+	}
+}
+
+/* MediaTek PSCI power domain */
+static int armv8_2_validate_power_state(unsigned int power_state, psci_power_state_t *req_state)
+{
+	unsigned int i;
+	unsigned int pstate = psci_get_pstate_type(power_state);
+	unsigned int aff_lvl = psci_get_pstate_pwrlvl(power_state);
+	unsigned int my_core_pos = plat_my_core_pos();
+
+	if (mtk_cpu_pwr.ops == NULL) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_PWR_STATE_VALID)) {
+		if (mtk_cpu_pwr.ops->pwr_state_valid(aff_lvl, pstate) != 0) {
+			return PSCI_E_INVALID_PARAMS;
+		}
+	}
+
+	if (pstate == PSTATE_TYPE_STANDBY) {
+		req_state->pwr_domain_state[0] = PLAT_MAX_RET_STATE;
+	} else {
+		for (i = PSCI_CPU_PWR_LVL; i <= aff_lvl; i++) {
+			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+		}
+	}
+	armv8_2_power_state[my_core_pos] = power_state;
+
+	return PSCI_E_SUCCESS;
+}
+
+/* MediaTek PSCI power domain */
+#if CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND
+static void armv8_2_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	unsigned int i;
+	int ret;
+	unsigned int power_state;
+	unsigned int my_core_pos = plat_my_core_pos();
+
+	ret = mtk_cpu_pwr.ops->pwr_state_valid(PLAT_MAX_PWR_LVL,
+						PSTATE_TYPE_POWERDOWN);
+
+	if (ret != MTK_CPUPM_E_OK) {
+		/* Avoid suspend due to platform is not ready. */
+		req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] =
+						PLAT_MAX_RET_STATE;
+		for (i = PSCI_CPU_PWR_LVL + 1; i <= PLAT_MAX_PWR_LVL; i++) {
+			req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN;
+		}
+
+		power_state = psci_make_powerstate(0, PSTATE_TYPE_STANDBY, PSCI_CPU_PWR_LVL);
+	} else {
+		for (i = PSCI_CPU_PWR_LVL; i <= PLAT_MAX_PWR_LVL; i++) {
+			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+		}
+
+		power_state = psci_make_powerstate(MT_PLAT_PWR_STATE_SUSPEND,
+						   PSTATE_TYPE_POWERDOWN, PLAT_MAX_PWR_LVL);
+	}
+
+	armv8_2_power_state[my_core_pos] = power_state;
+	flush_dcache_range((uintptr_t)&armv8_2_power_state[my_core_pos],
+			   sizeof(armv8_2_power_state[my_core_pos]));
+}
+#endif
+static void armv8_2_pm_smp_init(unsigned int cpu_id, uintptr_t entry_point)
+{
+	if (entry_point == 0) {
+		ERROR("%s, warm_entry_point is null\n", __func__);
+		panic();
+	}
+	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_SMP_INIT)) {
+		mtk_cpu_pwr.smp->init(cpu_id, entry_point);
+	}
+	INFO("[%s:%d] - Initialize finished\n", __func__, __LINE__);
+}
+
+static struct plat_pm_pwr_ctrl armv8_2_pwr_ops = {
+	.pwr_domain_suspend = armv8_2_power_domain_suspend,
+	.pwr_domain_suspend_finish = armv8_2_power_domain_suspend_finish,
+	.validate_power_state = armv8_2_validate_power_state,
+#if CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND
+	.get_sys_suspend_power_state = armv8_2_get_sys_suspend_power_state,
+#endif
+};
+
+struct plat_pm_smp_ctrl armv8_2_smp_ops = {
+	.init = armv8_2_pm_smp_init,
+	.pwr_domain_on = armv8_2_power_domain_on,
+	.pwr_domain_off = armv8_2_power_domain_off,
+	.pwr_domain_on_finish = armv8_2_power_domain_on_finish,
+};
+
+#define ISSUE_CPU_PM_REG_FAIL(_success) ({ _success = false; assert(0); })
+
+#define CPM_PM_FN_CHECK(_fns, _ops, _id, _func, _result, _flag) ({ \
+	if ((_fns & _id)) { \
+		if (_ops->_func) \
+			_flag |= _id; \
+		else { \
+			ISSUE_CPU_PM_REG_FAIL(_result); \
+		} \
+	} })
+
+int register_cpu_pm_ops(unsigned int fn_flags, struct mtk_cpu_pm_ops *ops)
+{
+	bool success = true;
+	unsigned int fns = 0;
+
+	if ((ops == NULL) || (mtk_cpu_pwr.ops != NULL)) {
+		ERROR("[%s:%d] register cpu_pm fail !!\n", __FILE__, __LINE__);
+		return MTK_CPUPM_E_ERR;
+	}
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_RESUME_CORE,
+			cpu_resume, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SUSPEND_CORE,
+			cpu_suspend, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_RESUME_CLUSTER,
+			cluster_resume, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SUSPEND_CLUSTER,
+			cluster_suspend, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_RESUME_MCUSYS,
+			mcusys_resume, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SUSPEND_MCUSYS,
+			mcusys_suspend, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_CPUPM_GET_PWR_STATE,
+			get_pstate, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_PWR_STATE_VALID,
+			pwr_state_valid, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_INIT,
+			init, success, fns);
+
+	if (success) {
+		mtk_cpu_pwr.ops = ops;
+		mtk_cpu_pwr.fn_mask |= fns;
+		plat_pm_ops_setup_pwr(&armv8_2_pwr_ops);
+		INFO("[%s:%d] CPU pwr ops register success, support:0x%x\n",
+		     __func__, __LINE__, fns);
+	} else {
+		ERROR("[%s:%d] register cpu_pm ops fail !, fn:0x%x\n",
+		      __func__, __LINE__, fn_flags);
+		assert(0);
+	}
+	return MTK_CPUPM_E_OK;
+}
+
+int register_cpu_smp_ops(unsigned int fn_flags, struct mtk_cpu_smp_ops *ops)
+{
+	bool success = true;
+	unsigned int fns = 0;
+
+	if ((ops == NULL) || (mtk_cpu_pwr.smp != NULL)) {
+		ERROR("[%s:%d] register cpu_smp fail !!\n", __FILE__, __LINE__);
+		return MTK_CPUPM_E_ERR;
+	}
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SMP_INIT,
+			init, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_PWR_ON_CORE_PREPARE,
+			cpu_pwr_on_prepare, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SMP_CORE_ON,
+			cpu_on, success, fns);
+
+	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SMP_CORE_OFF,
+			cpu_off, success, fns);
+
+	if (success == true) {
+		mtk_cpu_pwr.smp = ops;
+		mtk_cpu_pwr.fn_mask |= fns;
+		plat_pm_ops_setup_smp(&armv8_2_smp_ops);
+		INFO("[%s:%d] CPU smp ops register success, support:0x%x\n",
+		     __func__, __LINE__, fns);
+	} else {
+		ERROR("[%s:%d] register cpu_smp ops fail !, fn:0x%x\n",
+		      __func__, __LINE__, fn_flags);
+		assert(0);
+	}
+	return MTK_CPUPM_E_OK;
+}
diff --git a/plat/mediatek/lib/pm/armv8_2/rules.mk b/plat/mediatek/lib/pm/armv8_2/rules.mk
new file mode 100644
index 0000000..0e065c5
--- /dev/null
+++ b/plat/mediatek/lib/pm/armv8_2/rules.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := armv${CONFIG_MTK_PM_ARCH}
+LOCAL_SRCS-y := ${LOCAL_DIR}/pwr_ctrl.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/lib/pm/mtk_pm.c b/plat/mediatek/lib/pm/mtk_pm.c
index 632a1e7..3dbeb51 100644
--- a/plat/mediatek/lib/pm/mtk_pm.c
+++ b/plat/mediatek/lib/pm/mtk_pm.c
@@ -4,15 +4,117 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <lib/psci/psci.h>
+#include <assert.h>
+#include <plat/common/platform.h>
+#include <lib/pm/mtk_pm.h>
 
-static const plat_psci_ops_t plat_psci_ops = {
-};
+#define MTK_PM_ST_SMP_READY	BIT(0)
+#define MTK_PM_ST_PWR_READY	BIT(1)
+#define MTK_PM_ST_RESET_READY	BIT(2)
+
+static uintptr_t mtk_secure_entrypoint;
+static plat_init_func mtk_plat_smp_init;
+static plat_psci_ops_t mtk_pm_ops;
+static unsigned int mtk_pm_status;
+
+uintptr_t plat_pm_get_warm_entry(void)
+{
+	return mtk_secure_entrypoint;
+}
+
+int plat_pm_ops_setup_pwr(struct plat_pm_pwr_ctrl *ops)
+{
+	if (!ops) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+#if CONFIG_MTK_CPU_SUSPEND_EN
+	if (!mtk_pm_ops.pwr_domain_suspend) {
+		mtk_pm_ops.pwr_domain_suspend = ops->pwr_domain_suspend;
+	}
+
+	if (!mtk_pm_ops.pwr_domain_suspend_finish) {
+		mtk_pm_ops.pwr_domain_suspend_finish = ops->pwr_domain_suspend_finish;
+	}
+
+	if (!mtk_pm_ops.validate_power_state) {
+		mtk_pm_ops.validate_power_state = ops->validate_power_state;
+	}
+
+	if (!mtk_pm_ops.get_sys_suspend_power_state) {
+		mtk_pm_ops.get_sys_suspend_power_state = ops->get_sys_suspend_power_state;
+	}
+
+	mtk_pm_status |= MTK_PM_ST_PWR_READY;
+#endif
+	return MTK_CPUPM_E_OK;
+}
+
+int plat_pm_ops_setup_smp(struct plat_pm_smp_ctrl *ops)
+{
+	if (!ops) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+#if CONFIG_MTK_SMP_EN
+	if (!mtk_pm_ops.pwr_domain_on) {
+		mtk_pm_ops.pwr_domain_on = ops->pwr_domain_on;
+	}
+
+	if (!mtk_pm_ops.pwr_domain_on_finish) {
+		mtk_pm_ops.pwr_domain_on_finish = ops->pwr_domain_on_finish;
+	}
+
+	if (!mtk_pm_ops.pwr_domain_off) {
+		mtk_pm_ops.pwr_domain_off = ops->pwr_domain_off;
+	}
+
+	if (!mtk_plat_smp_init) {
+		mtk_plat_smp_init = ops->init;
+	}
+
+	mtk_pm_status |= MTK_PM_ST_SMP_READY;
+#endif
+	return MTK_CPUPM_E_OK;
+}
+
+int plat_pm_ops_setup_reset(struct plat_pm_reset_ctrl *ops)
+{
+	if (!ops) {
+		return MTK_CPUPM_E_FAIL;
+	}
+
+	if (!mtk_pm_ops.system_off) {
+		mtk_pm_ops.system_off = ops->system_off;
+	}
+
+	if (!mtk_pm_ops.system_reset) {
+		mtk_pm_ops.system_reset = ops->system_reset;
+	}
+
+	if (!mtk_pm_ops.system_reset2) {
+		mtk_pm_ops.system_reset2 = ops->system_reset2;
+	}
+
+	mtk_pm_status |= MTK_PM_ST_RESET_READY;
+
+	return MTK_CPUPM_E_OK;
+}
 
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
 			const plat_psci_ops_t **psci_ops)
 {
-	*psci_ops = &plat_psci_ops;
+	*psci_ops = &mtk_pm_ops;
+	mtk_secure_entrypoint = sec_entrypoint;
+
+	if (mtk_plat_smp_init) {
+		unsigned int cpu_id = plat_my_core_pos();
 
+		mtk_plat_smp_init(cpu_id, mtk_secure_entrypoint);
+	}
+	INFO("%s, smp:(%d), pwr_ctrl:(%d), system_reset:(%d)\n", __func__,
+	     !!(mtk_pm_status & MTK_PM_ST_SMP_READY),
+	     !!(mtk_pm_status & MTK_PM_ST_PWR_READY),
+	     !!(mtk_pm_status & MTK_PM_ST_RESET_READY));
 	return 0;
 }
diff --git a/plat/mediatek/lib/pm/mtk_pm.h b/plat/mediatek/lib/pm/mtk_pm.h
new file mode 100644
index 0000000..892a0b0
--- /dev/null
+++ b/plat/mediatek/lib/pm/mtk_pm.h
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_PM_H
+#define MTK_PM_H
+#include <lib/psci/psci.h>
+
+#if MTK_PUBEVENT_ENABLE
+#include <mtk_event/mtk_pubsub_events.h>
+#endif
+
+#define MTK_CPUPM_E_OK			(0)
+#define MTK_CPUPM_E_UNKNOWN		(-1)
+#define MTK_CPUPM_E_ERR			(-2)
+#define MTK_CPUPM_E_FAIL		(-3)
+#define MTK_CPUPM_E_NOT_SUPPORT		(-4)
+
+
+#define MTK_CPUPM_FN_PWR_LOCK_AQUIRE		BIT(0)
+#define MTK_CPUPM_FN_INIT			BIT(1)
+#define MTK_CPUPM_FN_PWR_STATE_VALID		BIT(2)
+#define MTK_CPUPM_FN_PWR_ON_CORE_PREPARE	BIT(3)
+#define MTK_CPUPM_FN_SUSPEND_CORE		BIT(4)
+#define MTK_CPUPM_FN_RESUME_CORE		BIT(5)
+#define MTK_CPUPM_FN_SUSPEND_CLUSTER		BIT(6)
+#define MTK_CPUPM_FN_RESUME_CLUSTER		BIT(7)
+#define MTK_CPUPM_FN_SUSPEND_MCUSYS		BIT(8)
+#define MTK_CPUPM_FN_RESUME_MCUSYS		BIT(9)
+#define MTK_CPUPM_FN_CPUPM_GET_PWR_STATE	BIT(10)
+#define MTK_CPUPM_FN_SMP_INIT			BIT(11)
+#define MTK_CPUPM_FN_SMP_CORE_ON		BIT(12)
+#define MTK_CPUPM_FN_SMP_CORE_OFF		BIT(13)
+
+enum mtk_cpupm_pstate {
+	MTK_CPUPM_CORE_ON,
+	MTK_CPUPM_CORE_OFF,
+	MTK_CPUPM_CORE_SUSPEND,
+	MTK_CPUPM_CORE_RESUME,
+	MTK_CPUPM_CLUSTER_SUSPEND,
+	MTK_CPUPM_CLUSTER_RESUME,
+	MTK_CPUPM_MCUSYS_SUSPEND,
+	MTK_CPUPM_MCUSYS_RESUME,
+};
+
+enum mtk_cpu_pm_mode {
+	MTK_CPU_PM_CPUIDLE,
+	MTK_CPU_PM_SMP,
+};
+
+#define MT_IRQ_REMAIN_MAX	(32)
+#define MT_IRQ_REMAIN_CAT_LOG	BIT(31)
+
+struct mt_irqremain {
+	unsigned int count;
+	unsigned int irqs[MT_IRQ_REMAIN_MAX];
+	unsigned int wakeupsrc_cat[MT_IRQ_REMAIN_MAX];
+	unsigned int wakeupsrc[MT_IRQ_REMAIN_MAX];
+};
+
+typedef void (*plat_init_func)(unsigned int, uintptr_t);
+
+struct plat_pm_smp_ctrl {
+	plat_init_func init;
+	int (*pwr_domain_on)(u_register_t mpidr);
+	void (*pwr_domain_off)(const psci_power_state_t *target_state);
+	void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
+};
+
+struct plat_pm_pwr_ctrl {
+	void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
+	void (*pwr_domain_on_finish_late)(const psci_power_state_t *target_state);
+	void (*pwr_domain_suspend_finish)(const psci_power_state_t *target_state);
+	int (*validate_power_state)(unsigned int power_state, psci_power_state_t *req_state);
+	void (*get_sys_suspend_power_state)(psci_power_state_t *req_state);
+};
+
+struct plat_pm_reset_ctrl {
+	__dead2 void (*system_off)();
+	__dead2 void (*system_reset)();
+	int (*system_reset2)(int is_vendor, int reset_type, u_register_t cookie);
+};
+
+struct mtk_cpu_pm_info {
+	unsigned int cpuid;
+	unsigned int mode;
+};
+
+struct mtk_cpu_pm_state {
+	unsigned int afflv;
+	unsigned int state_id;
+	const psci_power_state_t *raw;
+};
+
+struct mtk_cpupm_pwrstate {
+	struct mtk_cpu_pm_info info;
+	struct mtk_cpu_pm_state pwr;
+};
+
+struct mtk_cpu_smp_ops {
+	void (*init)(unsigned int cpu, uintptr_t sec_entrypoint);
+	int (*cpu_pwr_on_prepare)(unsigned int cpu, uintptr_t entry);
+	void (*cpu_on)(const struct mtk_cpupm_pwrstate *state);
+	void (*cpu_off)(const struct mtk_cpupm_pwrstate *state);
+	int (*invoke)(unsigned int funcID, void *priv);
+};
+
+#define MT_CPUPM_PWR_DOMAIN_CORE		BIT(0)
+#define MT_CPUPM_PWR_DOMAIN_PERCORE_DSU		BIT(1)
+#define MT_CPUPM_PWR_DOMAIN_PERCORE_DSU_MEM	BIT(2)
+#define MT_CPUPM_PWR_DOMAIN_CLUSTER		BIT(3)
+#define MT_CPUPM_PWR_DOMAIN_MCUSYS		BIT(4)
+#define MT_CPUPM_PWR_DOMAIN_SUSPEND		BIT(5)
+
+enum mt_cpupm_pwr_domain {
+	CPUPM_PWR_ON,
+	CPUPM_PWR_OFF,
+};
+
+typedef	unsigned int mtk_pstate_type;
+
+struct mtk_cpu_pm_ops {
+	void (*init)(unsigned int cpu, uintptr_t sec_entrypoint);
+	unsigned int (*get_pstate)(enum mt_cpupm_pwr_domain domain,
+				   const mtk_pstate_type psci_state,
+				   const struct mtk_cpupm_pwrstate *state);
+	int (*pwr_state_valid)(unsigned int afflv, unsigned int state);
+	void (*cpu_suspend)(const struct mtk_cpupm_pwrstate *state);
+	void (*cpu_resume)(const struct mtk_cpupm_pwrstate *state);
+	void (*cluster_suspend)(const struct mtk_cpupm_pwrstate *state);
+	void (*cluster_resume)(const struct mtk_cpupm_pwrstate *state);
+	void (*mcusys_suspend)(const struct mtk_cpupm_pwrstate *state);
+	void (*mcusys_resume)(const struct mtk_cpupm_pwrstate *state);
+	int (*invoke)(unsigned int funcID, void *priv);
+};
+
+int register_cpu_pm_ops(unsigned int fn_flags, struct mtk_cpu_pm_ops *ops);
+int register_cpu_smp_ops(unsigned int fn_flags, struct mtk_cpu_smp_ops *ops);
+
+struct mt_cpupm_event_data {
+	unsigned int cpuid;
+	unsigned int pwr_domain;
+};
+
+/* Extension event for platform driver */
+#if MTK_PUBEVENT_ENABLE
+/* [PUB_EVENT] Core power on */
+#define MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_pwr_on, _fn)
+
+/* [PUB_EVENT] Core power off */
+#define MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_pwr_off, _fn)
+
+/* [PUB_EVENT] Cluster power on */
+#define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_ON(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_on, _fn)
+
+/* [PUB_EVENT] Cluster power off */
+#define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_OFF(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_off, _fn)
+
+/* [PUB_EVENT] Mcusys power on */
+#define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_ON(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_on, _fn)
+
+/* [PUB_EVENT] Mcusys power off */
+#define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_OFF(_fn) \
+	SUBSCRIBE_TO_EVENT(mt_cpupm_publish_afflv_pwr_off, _fn)
+
+#else
+#define MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(_fn)
+#define MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(_fn)
+#define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_ON(_fn)
+#define MT_CPUPM_SUBCRIBE_CLUSTER_PWR_OFF(_fn)
+#define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_ON(_fn)
+#define MT_CPUPM_SUBCRIBE_MCUSYS_PWR_OFF(_fn)
+#endif
+
+/*
+ * Definition c-state power domain.
+ * bit[7:4] (main state id):
+ *  - 1: Cluster.
+ *  - 2: Mcusys.
+ *  - 3: Memory.
+ *  - 4: System pll.
+ *  - 5: System bus.
+ *  - 6: SoC 26m/DCXO.
+ *  - 7: Vcore buck.
+ *  - 15: Suspend.
+ * bit[3:0] (reserved for state_id extension):
+ *  - 4: CPU buck.
+ */
+#define MT_PLAT_PWR_STATE_CLUSTER	(0x0010)
+#define MT_PLAT_PWR_STATE_MCUSYS	(0x0020)
+#define MT_PLAT_PWR_STATE_MCUSYS_BUCK	(0x0024)
+#define MT_PLAT_PWR_STATE_SYSTEM_MEM	(0x0030)
+#define MT_PLAT_PWR_STATE_SYSTEM_PLL	(0x0040)
+#define MT_PLAT_PWR_STATE_SYSTEM_BUS	(0x0050)
+#define MT_PLAT_PWR_STATE_SUSPEND	(0x00f0)
+
+#define IS_MT_PLAT_PWR_STATE(state, target_state)	((state & target_state) == target_state)
+#define IS_MT_PLAT_PWR_STATE_MCUSYS(state)  IS_MT_PLAT_PWR_STATE(state, MT_PLAT_PWR_STATE_MCUSYS)
+
+#define PLAT_MT_SYSTEM_SUSPEND		PLAT_MAX_OFF_STATE
+#define PLAT_MT_CPU_SUSPEND_CLUSTER	PLAT_MAX_RET_STATE
+#define PLAT_MT_CPU_SUSPEND_MCUSYS	PLAT_MAX_RET_STATE
+
+#define IS_PLAT_SYSTEM_SUSPEND(aff)	(aff == PLAT_MT_SYSTEM_SUSPEND)
+#define IS_PLAT_SYSTEM_RETENTION(aff)	(aff >= PLAT_MAX_RET_STATE)
+
+#define IS_PLAT_SUSPEND_ID(stateid)	(stateid == MT_PLAT_PWR_STATE_SUSPEND)
+
+#define IS_PLAT_MCUSYSOFF_AFFLV(afflv)	(afflv >= PLAT_MT_CPU_SUSPEND_MCUSYS)
+
+int plat_pm_ops_setup_pwr(struct plat_pm_pwr_ctrl *ops);
+int plat_pm_ops_setup_reset(struct plat_pm_reset_ctrl *ops);
+int plat_pm_ops_setup_smp(struct plat_pm_smp_ctrl *ops);
+uintptr_t plat_pm_get_warm_entry(void);
+
+#endif
diff --git a/plat/mediatek/lib/pm/rules.mk b/plat/mediatek/lib/pm/rules.mk
index 77d0408..29265c4 100644
--- a/plat/mediatek/lib/pm/rules.mk
+++ b/plat/mediatek/lib/pm/rules.mk
@@ -12,3 +12,6 @@
 LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_pm.c
 
 $(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
+
+SUB_RULES-$(CONFIG_MTK_PM_SUPPORT) := $(LOCAL_DIR)/armv${CONFIG_MTK_PM_ARCH}
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
diff --git a/plat/mediatek/lib/system_reset/reset_cros.c b/plat/mediatek/lib/system_reset/reset_cros.c
new file mode 100644
index 0000000..40e68ba
--- /dev/null
+++ b/plat/mediatek/lib/system_reset/reset_cros.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/gpio.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <lib/pm/mtk_pm.h>
+#include <plat_params.h>
+#include <pmic.h>
+#include <rtc.h>
+
+static void __dead2 mtk_system_reset_cros(void)
+{
+	struct bl_aux_gpio_info *gpio_reset = plat_get_mtk_gpio_reset();
+
+	INFO("MTK System Reset\n");
+
+	gpio_set_value(gpio_reset->index, gpio_reset->polarity);
+
+	wfi();
+	ERROR("MTK System Reset: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 mtk_system_off_cros(void)
+{
+	INFO("MTK System Off\n");
+
+	rtc_power_off_sequence();
+	pmic_power_off();
+
+	wfi();
+	ERROR("MTK System Off: operation not handled.\n");
+	panic();
+}
+
+static struct plat_pm_reset_ctrl lib_reset_ctrl = {
+	.system_off = mtk_system_off_cros,
+	.system_reset = mtk_system_reset_cros,
+	.system_reset2 = NULL,
+};
+
+static int lib_reset_ctrl_init(void)
+{
+	INFO("Reset init\n");
+
+	plat_pm_ops_setup_reset(&lib_reset_ctrl);
+
+	return 0;
+}
+MTK_ARCH_INIT(lib_reset_ctrl_init);
diff --git a/plat/mediatek/lib/system_reset/rules.mk b/plat/mediatek/lib/system_reset/rules.mk
new file mode 100644
index 0000000..4f20663
--- /dev/null
+++ b/plat/mediatek/lib/system_reset/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := system_reset
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/reset_cros.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/mt8186/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8186/drivers/emi_mpu/emi_mpu.c
index 989ecf1..1133c86 100644
--- a/plat/mediatek/mt8186/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8186/drivers/emi_mpu/emi_mpu.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
  */
@@ -96,5 +96,38 @@
 
 void emi_mpu_init(void)
 {
-	/* TODO: more setting for EMI MPU. */
+	struct emi_region_info_t region_info;
+
+	/* SCP DRAM */
+	region_info.start = 0x50000000ULL;
+	region_info.end = 0x5109FFFFULL;
+	region_info.region = 2;
+	SET_ACCESS_PERMISSION(region_info.apc, 1,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
+	emi_mpu_set_protection(&region_info);
+
+	/* DSP protect address */
+	region_info.start = 0x60000000ULL;	/* dram base addr */
+	region_info.end = 0x610FFFFFULL;
+	region_info.region = 3;
+	SET_ACCESS_PERMISSION(region_info.apc, 1,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
+	emi_mpu_set_protection(&region_info);
+
+	/* Forbidden All */
+	region_info.start = 0x40000000ULL;	/* dram base addr */
+	region_info.end = 0x1FFFF0000ULL;
+	region_info.region = 4;
+	SET_ACCESS_PERMISSION(region_info.apc, 1,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
+	emi_mpu_set_protection(&region_info);
 }
diff --git a/plat/mediatek/mt8186/platform.mk b/plat/mediatek/mt8186/platform.mk
index 6587970..68f4a1f 100644
--- a/plat/mediatek/mt8186/platform.mk
+++ b/plat/mediatek/mt8186/platform.mk
@@ -8,10 +8,10 @@
 MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
+                 -I${MTK_PLAT}/common/lpm                         \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/gic600/                    \
                  -I${MTK_PLAT}/drivers/gpio/                      \
-                 -I${MTK_PLAT}/drivers/lpm/                       \
                  -I${MTK_PLAT}/drivers/msdc/                      \
                  -I${MTK_PLAT}/drivers/msdc/${PLAT}               \
                  -I${MTK_PLAT}/drivers/pmic_wrap/                 \
@@ -51,10 +51,10 @@
                 ${MTK_PLAT}/common/mtk_plat_common.c                  \
                 ${MTK_PLAT}/common/mtk_sip_svc.c                      \
                 ${MTK_PLAT}/common/params_setup.c                     \
+                ${MTK_PLAT}/common/lpm/mt_lp_rm.c                     \
                 ${MTK_PLAT}/drivers/cirq/mt_cirq.c                    \
                 ${MTK_PLAT}/drivers/gic600/mt_gic_v3.c                \
                 ${MTK_PLAT}/drivers/gpio/mtgpio_common.c              \
-                ${MTK_PLAT}/drivers/lpm/mt_lp_rm.c                    \
                 ${MTK_PLAT}/drivers/msdc/mt_msdc.c                    \
                 ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init.c        \
                 ${MTK_PLAT}/drivers/rtc/rtc_common.c                  \
diff --git a/plat/mediatek/mt8188/aarch64/plat_helpers.S b/plat/mediatek/mt8188/aarch64/plat_helpers.S
deleted file mode 100644
index 7073ab1..0000000
--- a/plat/mediatek/mt8188/aarch64/plat_helpers.S
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <platform_def.h>
-
-	.globl plat_is_my_cpu_primary
-	.globl plat_my_core_pos
-	.globl plat_mediatek_calc_core_pos
-
-func plat_is_my_cpu_primary
-	mrs	x0, mpidr_el1
-	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
-	cmp	x0, #PLAT_PRIMARY_CPU
-	cset	x0, eq
-	ret
-endfunc plat_is_my_cpu_primary
-
-	/* -----------------------------------------------------
-	 *  unsigned int plat_my_core_pos(void)
-	 *  This function uses the plat_mediatek_calc_core_pos()
-	 *  definition to get the index of the calling CPU.
-	 * -----------------------------------------------------
-	 */
-func plat_my_core_pos
-	mrs	x0, mpidr_el1
-	b	plat_mediatek_calc_core_pos
-endfunc plat_my_core_pos
-
-	/* -----------------------------------------------------
-	 * unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
-	 *
-	 * With this function: CorePos = CoreID (AFF1)
-	 * we do it with x0 = (x0 >> 8) & 0xff
-	 * -----------------------------------------------------
-	 */
-func plat_mediatek_calc_core_pos
-	mov	x1, #MPIDR_AFFLVL_MASK
-	and	x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
-	ret
-endfunc plat_mediatek_calc_core_pos
diff --git a/plat/mediatek/include/mt8188/platform_def.h b/plat/mediatek/mt8188/include/platform_def.h
similarity index 86%
rename from plat/mediatek/include/mt8188/platform_def.h
rename to plat/mediatek/mt8188/include/platform_def.h
index 962d952..ee507fd 100644
--- a/plat/mediatek/include/mt8188/platform_def.h
+++ b/plat/mediatek/mt8188/include/platform_def.h
@@ -7,10 +7,13 @@
 #ifndef PLATFORM_DEF_H
 #define PLATFORM_DEF_H
 
+#include <arch_def.h>
+
 #define PLAT_PRIMARY_CPU	(0x0)
 
 #define MT_GIC_BASE		(0x0C000000)
 #define MCUCFG_BASE		(0x0C530000)
+#define MCUCFG_REG_SIZE		(0x10000)
 #define IO_PHYS			(0x10000000)
 
 /* Aggregate of all devices for MMU mapping */
@@ -23,6 +26,8 @@
  * GPIO related constants
  ******************************************************************************/
 #define GPIO_BASE		(IO_PHYS + 0x00005000)
+#define RGU_BASE		(IO_PHYS + 0x00007000)
+#define DRM_BASE		(IO_PHYS + 0x0000D000)
 #define IOCFG_RM_BASE		(IO_PHYS + 0x01C00000)
 #define IOCFG_LT_BASE		(IO_PHYS + 0x01E10000)
 #define IOCFG_LM_BASE		(IO_PHYS + 0x01E20000)
@@ -101,6 +106,12 @@
 #define DP_SEC_SIZE		(0x1000)
 
 /*******************************************************************************
+ * EMI MPU related constants
+ *******************************************************************************/
+#define EMI_MPU_BASE		(IO_PHYS + 0x00226000)
+#define SUB_EMI_MPU_BASE	(IO_PHYS + 0x00225000)
+
+/*******************************************************************************
  * System counter frequency related constants
  ******************************************************************************/
 #define SYS_COUNTER_FREQ_IN_HZ	(13000000)
@@ -116,22 +127,7 @@
  * Generic platform constants
  ******************************************************************************/
 #define PLATFORM_STACK_SIZE		(0x800)
-
 #define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
-
-#define PLAT_MAX_PWR_LVL		U(3)
-#define PLAT_MAX_RET_STATE		U(1)
-#define PLAT_MAX_OFF_STATE		U(9)
-
-#define PLATFORM_SYSTEM_COUNT		U(1)
-#define PLATFORM_MCUSYS_COUNT		U(1)
-#define PLATFORM_CLUSTER_COUNT		U(1)
-#define PLATFORM_CLUSTER0_CORE_COUNT	U(8)
-#define PLATFORM_CLUSTER1_CORE_COUNT	U(0)
-
-#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER0_CORE_COUNT)
-#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(8)
-
 #define SOC_CHIP_ID			U(0x8188)
 
 /*******************************************************************************
@@ -160,15 +156,17 @@
 #define MAX_MMAP_REGIONS		(16)
 
 /*******************************************************************************
- * Declarations and constants to access the mailboxes safely. Each mailbox is
- * aligned on the biggest cache line size in the platform. This is known only
- * to the platform as it might have a combination of integrated and external
- * caches. Such alignment ensures that two maiboxes do not sit on the same cache
- * line at any cache level. They could belong to different cpus/clusters &
- * get written while being protected by different locks causing corruption of
- * a valid mailbox address.
+ * CPU_EB TCM handling related constants
  ******************************************************************************/
-#define CACHE_WRITEBACK_SHIFT		(6)
-#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
+#define CPU_EB_TCM_BASE		(0x0C550000)
+#define CPU_EB_TCM_SIZE		(0x10000)
+#define CPU_EB_MBOX3_OFFSET	(0xFCE0)
+
+/*******************************************************************************
+ * CPU PM definitions
+ *******************************************************************************/
+#define PLAT_CPU_PM_B_BUCK_ISO_ID	(6)
+#define PLAT_CPU_PM_ILDO_ID		(6)
+#define CPU_IDLE_SRAM_BASE		(0x11B000)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt8188/plat_config.mk b/plat/mediatek/mt8188/plat_config.mk
index 0c1e7cd..cff97cb 100644
--- a/plat/mediatek/mt8188/plat_config.mk
+++ b/plat/mediatek/mt8188/plat_config.mk
@@ -29,6 +29,19 @@
 ERRATA_A78_1821534 := 1
 ERRATA_A78_2132060 := 1
 ERRATA_A78_2242635 := 1
+ERRATA_A78_2376745 := 1
+ERRATA_A78_2395406 := 1
+
+CONFIG_ARCH_ARM_V8_2 := y
+CONFIG_MTK_MCUSYS := y
+MCUSYS_VERSION := v1
+CONFIG_MTK_PM_SUPPORT := y
+CONFIG_MTK_PM_ARCH := 8_2
+CONFIG_MTK_CPU_PM_SUPPORT := y
+CONFIG_MTK_CPU_PM_ARCH := 3_2
+CONFIG_MTK_SMP_EN := y
+CONFIG_MTK_CPU_SUSPEND_EN := y
+CPU_PM_TINYSYS_SUPPORT := y
 
 MACH_MT8188 := 1
 $(eval $(call add_define,MACH_MT8188))
diff --git a/plat/mediatek/mt8188/plat_topology.c b/plat/mediatek/mt8188/plat_topology.c
deleted file mode 100644
index 9fa2855..0000000
--- a/plat/mediatek/mt8188/plat_topology.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <lib/psci/psci.h>
-
-#include <plat_helpers.h>
-#include <platform_def.h>
-
-const unsigned char mtk_power_domain_tree_desc[] = {
-	/* Number of root nodes */
-	PLATFORM_SYSTEM_COUNT,
-	/* Number of children for the root node */
-	PLATFORM_MCUSYS_COUNT,
-	/* Number of children for the mcusys node */
-	PLATFORM_CLUSTER_COUNT,
-	/* Number of children for the first cluster node */
-	PLATFORM_CLUSTER0_CORE_COUNT,
-};
-
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
-	return mtk_power_domain_tree_desc;
-}
-
-/*******************************************************************************
- * This function implements a part of the critical interface between the psci
- * generic layer and the platform that allows the former to query the platform
- * to convert an MPIDR to a unique linear index. An error code (-1) is returned
- * in case the MPIDR is invalid.
- ******************************************************************************/
-int plat_core_pos_by_mpidr(u_register_t mpidr)
-{
-	unsigned int cluster_id, cpu_id;
-
-	if ((read_mpidr() & MPIDR_MT_MASK) != 0) {
-		/* ARMv8.2 arch */
-		if ((mpidr & (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT)) != 0) {
-			return -1;
-		}
-		return plat_mediatek_calc_core_pos(mpidr);
-	}
-
-	mpidr &= MPIDR_AFFINITY_MASK;
-
-	if ((mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0) {
-		return -1;
-	}
-
-	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
-
-	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
-		return -1;
-	}
-
-	/*
-	 * Validate cpu_id by checking whether it represents a CPU in
-	 * one of the two clusters present on the platform.
-	 */
-	if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
-		return -1;
-	}
-
-	return (cpu_id + (cluster_id * 8));
-}
diff --git a/plat/mediatek/mt8188/platform.mk b/plat/mediatek/mt8188/platform.mk
index 84bcfac..b509edc 100644
--- a/plat/mediatek/mt8188/platform.mk
+++ b/plat/mediatek/mt8188/platform.mk
@@ -14,23 +14,32 @@
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common \
 		 -I${MTK_PLAT}/include \
-		 -I${MTK_PLAT}/include/${MTK_SOC} \
+		 -I${MTK_PLAT}/include/${ARCH_VERSION} \
 		 -I${MTK_PLAT} \
 		 -I${MTK_PLAT_SOC}/include \
 		 -Idrivers/arm/gic \
 
 MODULES-y += $(MTK_PLAT)/common
+MODULES-y += $(MTK_PLAT)/common/lpm
 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/cirq
+MODULES-y += $(MTK_PLAT)/drivers/cpu_pm
+MODULES-y += $(MTK_PLAT)/drivers/dcm
+MODULES-y += $(MTK_PLAT)/drivers/dfd
 MODULES-y += $(MTK_PLAT)/drivers/dp
+MODULES-y += $(MTK_PLAT)/drivers/emi_mpu
 MODULES-y += $(MTK_PLAT)/drivers/gic600
 MODULES-y += $(MTK_PLAT)/drivers/gpio
 MODULES-y += $(MTK_PLAT)/drivers/iommu
+MODULES-y += $(MTK_PLAT)/drivers/mcusys
 MODULES-y += $(MTK_PLAT)/drivers/pmic
 MODULES-y += $(MTK_PLAT)/drivers/pmic_wrap
 MODULES-y += $(MTK_PLAT)/drivers/rtc
 MODULES-y += $(MTK_PLAT)/drivers/timer
+MODULES-y += $(MTK_PLAT)/helpers
+MODULES-y += $(MTK_PLAT)/topology
 
 PLAT_BL_COMMON_SOURCES := common/desc_image_load.c \
 			  drivers/ti/uart/aarch64/16550_console.S \
@@ -47,9 +56,7 @@
 		plat/common/aarch64/crash_console_helpers.S \
 		${MTK_PLAT}/common/mtk_plat_common.c \
 		${MTK_PLAT}/common/params_setup.c \
-		${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
-		$(MTK_PLAT)/$(MTK_SOC)/plat_mmap.c \
-		$(MTK_PLAT)/$(MTK_SOC)/plat_topology.c
+		$(MTK_PLAT)/$(MTK_SOC)/plat_mmap.c
 
 include plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
 
diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk
index efc14ec..a19fc45 100644
--- a/plat/mediatek/mt8192/platform.mk
+++ b/plat/mediatek/mt8192/platform.mk
@@ -8,10 +8,10 @@
 MTK_PLAT_SOC  := ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
+                 -I${MTK_PLAT}/common/lpm/                        \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/gic600/                    \
                  -I${MTK_PLAT}/drivers/gpio/                      \
-                 -I${MTK_PLAT}/drivers/lpm/                       \
                  -I${MTK_PLAT}/drivers/pmic/                      \
                  -I${MTK_PLAT}/drivers/pmic_wrap/                 \
                  -I${MTK_PLAT}/drivers/rtc/                       \
@@ -52,10 +52,10 @@
                    ${MTK_PLAT}/common/mtk_plat_common.c                  \
                    ${MTK_PLAT}/common/mtk_sip_svc.c                      \
                    ${MTK_PLAT}/common/params_setup.c                     \
+                   ${MTK_PLAT}/common/lpm/mt_lp_rm.c                     \
                    ${MTK_PLAT}/drivers/cirq/mt_cirq.c                    \
                    ${MTK_PLAT}/drivers/gic600/mt_gic_v3.c                \
                    ${MTK_PLAT}/drivers/gpio/mtgpio_common.c              \
-                   ${MTK_PLAT}/drivers/lpm/mt_lp_rm.c                    \
                    ${MTK_PLAT}/drivers/pmic/pmic.c                       \
                    ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init_v2.c     \
                    ${MTK_PLAT}/drivers/rtc/rtc_common.c                  \
diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk
index 414d655..80dfa53 100644
--- a/plat/mediatek/mt8195/platform.mk
+++ b/plat/mediatek/mt8195/platform.mk
@@ -8,11 +8,11 @@
 MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
 
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
+                 -I${MTK_PLAT}/common/lpm/                        \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/dp/                        \
                  -I${MTK_PLAT}/drivers/gic600/                    \
                  -I${MTK_PLAT}/drivers/gpio/                      \
-                 -I${MTK_PLAT}/drivers/lpm/                       \
                  -I${MTK_PLAT}/drivers/pmic/                      \
                  -I${MTK_PLAT}/drivers/pmic_wrap/                 \
                  -I${MTK_PLAT}/drivers/rtc/                       \
@@ -52,11 +52,11 @@
                 ${MTK_PLAT}/common/mtk_plat_common.c                  \
                 ${MTK_PLAT}/common/mtk_sip_svc.c                      \
                 ${MTK_PLAT}/common/params_setup.c                     \
+                ${MTK_PLAT}/common/lpm/mt_lp_rm.c                     \
                 ${MTK_PLAT}/drivers/cirq/mt_cirq.c                    \
                 ${MTK_PLAT}/drivers/dp/mt_dp.c                        \
                 ${MTK_PLAT}/drivers/gic600/mt_gic_v3.c                \
                 ${MTK_PLAT}/drivers/gpio/mtgpio_common.c              \
-                ${MTK_PLAT}/drivers/lpm/mt_lp_rm.c                    \
                 ${MTK_PLAT}/drivers/pmic/pmic.c                       \
                 ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init_v2.c     \
                 ${MTK_PLAT}/drivers/rtc/rtc_common.c                  \
diff --git a/plat/mediatek/topology/armv8_2/topology.c b/plat/mediatek/topology/armv8_2/topology.c
new file mode 100644
index 0000000..1627bbd
--- /dev/null
+++ b/plat/mediatek/topology/armv8_2/topology.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <lib/psci/psci.h>
+#include <platform_def.h>
+
+#pragma weak plat_get_power_domain_tree_desc
+
+static const unsigned char mtk_power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	PLATFORM_SYSTEM_COUNT,
+	/* Number of children for the root node */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the first cluster node */
+	PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+/*******************************************************************************
+ * This function returns the default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return mtk_power_domain_tree_desc;
+}
diff --git a/plat/mediatek/topology/rules.mk b/plat/mediatek/topology/rules.mk
new file mode 100644
index 0000000..29f15bb
--- /dev/null
+++ b/plat/mediatek/topology/rules.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := topology
+LOCAL_SRCS-y := $(LOCAL_DIR)/$(ARCH_VERSION)/topology.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/nxp/common/nv_storage/plat_nv_storage.c b/plat/nxp/common/nv_storage/plat_nv_storage.c
index 7ec4fdb..af3b966 100644
--- a/plat/nxp/common/nv_storage/plat_nv_storage.c
+++ b/plat/nxp/common/nv_storage/plat_nv_storage.c
@@ -13,6 +13,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <platform_def.h>
 #include <common/debug.h>
 #ifndef NXP_COINED_BB
 #include <flash_info.h>
diff --git a/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c b/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c
index 2231c18..28e2dab 100644
--- a/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c
+++ b/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c
@@ -85,32 +85,36 @@
 	return 0;
 }
 
-/* DDR model number: MT40A512M8HX-093E */
+/* DDR model number: MT40A1G8SA-062E:R */
 struct dimm_params ddr_raw_timing = {
 	.n_ranks = U(1),
 	.rank_density = ULL(2147483648),
 	.capacity = ULL(2147483648),
 	.primary_sdram_width = U(32),
-	.n_row_addr = U(15),
+	.ec_sdram_width = U(4),
+	.rdimm = U(0),
+	.mirrored_dimm = U(0),
+	.n_row_addr = U(16),
 	.n_col_addr = U(10),
 	.bank_group_bits = U(2),
+	.edc_config = U(2),
 	.burst_lengths_bitmask = U(0x0c),
-	.tckmin_x_ps = 938,
-	.tckmax_ps = 1500,
-	.caslat_x = U(0x000DFA00),
+	.tckmin_x_ps = 625,
+	.tckmax_ps = 2200,
+	.caslat_x = U(0x0001FFE00),
 	.taa_ps = 13500,
 	.trcd_ps = 13500,
 	.trp_ps = 13500,
-	.tras_ps = 33000,
-	.trc_ps = 46500,
+	.tras_ps = 32000,
+	.trc_ps = 45500,
 	.twr_ps = 15000,
-	.trfc1_ps = 260000,
-	.trfc2_ps = 160000,
-	.trfc4_ps = 110000,
+	.trfc1_ps = 350000,
+	.trfc2_ps = 260000,
+	.trfc4_ps = 160000,
 	.tfaw_ps = 21000,
-	.trrds_ps = 3700,
-	.trrdl_ps = 5300,
-	.tccdl_ps = 5355,
+	.trrds_ps = 3000,
+	.trrdl_ps = 4900,
+	.tccdl_ps = 5000,
 	.refresh_rate_ps = U(7800000),
 	.rc = U(0x1f),
 };
diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c b/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c
index 6d1707c..89c9c0a 100644
--- a/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c
+++ b/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c
@@ -12,6 +12,7 @@
 #include <lib/utils.h>
 
 #include <errata.h>
+#include "platform_def.h"
 
 static const struct rc_timing rce[] = {
 	{U(1600), U(8), U(7)},
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index e0b5271..6becc32 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -259,5 +259,8 @@
 ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
-# Do not enable SVE
-ENABLE_SVE_FOR_NS	:=	0
+# Later QEMU versions support SME and SVE.
+ifneq (${ARCH},aarch32)
+	ENABLE_SVE_FOR_NS	:= 1
+	ENABLE_SME_FOR_NS	:= 1
+endif
diff --git a/plat/qemu/qemu/qemu_helpers.c b/plat/qemu/qemu/qemu_helpers.c
index 01b8249..1b31ab5 100644
--- a/plat/qemu/qemu/qemu_helpers.c
+++ b/plat/qemu/qemu/qemu_helpers.c
@@ -6,10 +6,12 @@
 
 #include <assert.h>
 
+#include <common/bl_common.h>
 #if MEASURED_BOOT
 #include <common/desc_image_load.h>
 #endif
 #include <common/fdt_wrappers.h>
+#include <platform_def.h>
 
 #include <libfdt.h>
 
diff --git a/plat/qti/common/src/qti_interrupt_svc.c b/plat/qti/common/src/qti_interrupt_svc.c
index 89cd7b5..3017dc7 100644
--- a/plat/qti/common/src/qti_interrupt_svc.c
+++ b/plat/qti/common/src/qti_interrupt_svc.c
@@ -55,6 +55,7 @@
 	 * & we don't have S-EL1 support.
 	 */
 	set_interrupt_rm_flag(flags, NON_SECURE);
+	set_interrupt_rm_flag(flags, SECURE);
 
 	/* Register handler for EL3 interrupts */
 	ret = register_interrupt_type_handler(INTR_TYPE_EL3,
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index bbfa169..f85db8d 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -574,7 +574,7 @@
 		goto err;
 	}
 
-	node = ret = fdt_add_subnode(fdt, node, "rpc@ee200000");
+	node = ret = fdt_add_subnode(fdt, node, "spi@ee200000");
 	if (ret < 0) {
 		goto err;
 	}
diff --git a/plat/rockchip/common/pmusram/cpus_on_fixed_addr.h b/plat/rockchip/common/pmusram/cpus_on_fixed_addr.h
index 34af29a..bcd2a7c 100644
--- a/plat/rockchip/common/pmusram/cpus_on_fixed_addr.h
+++ b/plat/rockchip/common/pmusram/cpus_on_fixed_addr.h
@@ -48,7 +48,7 @@
 CASSERT(__builtin_offsetof(struct psram_data_t, boot_mpidr) == PSRAM_DT_MPIDR,
 	assert_psram_dt_mpidr_offset_mistmatch);
 
-extern void *sys_sleep_flag_sram;
+extern struct psram_data_t sys_sleep_flag_sram;
 
 #endif  /* __ASSEMBLER__ */
 
diff --git a/plat/rpi/common/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c
index 86c61f7..d98ac66 100644
--- a/plat/rpi/common/rpi3_pm.c
+++ b/plat/rpi/common/rpi3_pm.c
@@ -123,15 +123,6 @@
 #endif
 }
 
-void __dead2 plat_secondary_cold_boot_setup(void);
-
-static void __dead2
-rpi3_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
-{
-	disable_mmu_el3();
-	plat_secondary_cold_boot_setup();
-}
-
 /*******************************************************************************
  * Platform handler called when a power domain is about to be turned on. The
  * mpidr determines the CPU to be turned on.
@@ -196,8 +187,9 @@
 
 	write_rmr_el3(RMR_EL3_RR_BIT | RMR_EL3_AA64_BIT);
 
-	while (1)
-		;
+	while (1) {
+		wfi();
+	}
 }
 
 /*******************************************************************************
@@ -262,7 +254,6 @@
 static const plat_psci_ops_t plat_rpi3_psci_pm_ops = {
 	.cpu_standby = rpi3_cpu_standby,
 	.pwr_domain_off = rpi3_pwr_domain_off,
-	.pwr_domain_pwr_down_wfi = rpi3_pwr_domain_pwr_down_wfi,
 	.pwr_domain_on = rpi3_pwr_domain_on,
 	.pwr_domain_on_finish = rpi3_pwr_domain_on_finish,
 	.pwr_domain_pwr_down_wfi = rpi3_pwr_down_wfi,
diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h
index a84660b..d6bfe42 100644
--- a/plat/socionext/synquacer/include/platform_def.h
+++ b/plat/socionext/synquacer/include/platform_def.h
@@ -82,7 +82,7 @@
 
 /* Alternative BL33 */
 #define PLAT_SQ_BL33_BASE		0xe0000000
-#define PLAT_SQ_BL33_SIZE		0x00100000
+#define PLAT_SQ_BL33_SIZE		0x00200000
 
 /* FWU FIP IO base */
 #define PLAT_SQ_FIP_IOBASE		0x08600000
diff --git a/plat/st/common/stm32cubeprogrammer_uart.c b/plat/st/common/stm32cubeprogrammer_uart.c
index 46ac9cf..d004dcf 100644
--- a/plat/st/common/stm32cubeprogrammer_uart.c
+++ b/plat/st/common/stm32cubeprogrammer_uart.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
  */
@@ -486,13 +486,12 @@
 
 /* Init UART: 115200, 8bit 1stop parity even and enable FIFO mode */
 const struct stm32_uart_init_s init = {
-	.baud_rate = U(115200),
+	.baud_rate = STM32MP_UART_BAUDRATE,
 	.word_length = STM32_UART_WORDLENGTH_9B,
 	.stop_bits = STM32_UART_STOPBITS_1,
 	.parity = STM32_UART_PARITY_EVEN,
 	.hw_flow_control = STM32_UART_HWCONTROL_NONE,
 	.mode = STM32_UART_MODE_TX_RX,
-	.over_sampling = STM32_UART_OVERSAMPLING_16,
 	.fifo_mode = STM32_UART_FIFOMODE_EN,
 };
 
diff --git a/plat/st/common/stm32cubeprogrammer_usb.c b/plat/st/common/stm32cubeprogrammer_usb.c
index 19a6bba..75e8038 100644
--- a/plat/st/common/stm32cubeprogrammer_usb.c
+++ b/plat/st/common/stm32cubeprogrammer_usb.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 #include <errno.h>
+#include <string.h>
 
 #include <tools_share/firmware_image_package.h>
 
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index d922d3c..eee983f 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -274,8 +274,11 @@
 #if STM32MP_EARLY_CONSOLE
 void stm32mp_setup_early_console(void)
 {
+#if defined(IMAGE_BL2) || STM32MP_RECONFIGURE_CONSOLE
 	plat_crash_console_init();
+#endif
 	set_console(STM32MP_DEBUG_USART_BASE, STM32MP_DEBUG_USART_CLK_FRQ);
+	NOTICE("Early console setup\n");
 }
 #endif /* STM32MP_EARLY_CONSOLE */
 
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 8ecb4c3..fe4ef3d 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -103,8 +103,7 @@
 #define PLAT_STM32MP_NS_IMAGE_OFFSET	BL33_BASE
 
 /* Needed by STM32CubeProgrammer support */
-#define DWL_BUFFER_BASE			(STM32MP_DDR_BASE + U(0x08000000))
-#define DWL_BUFFER_SIZE			U(0x08000000)
+#define DWL_BUFFER_SIZE			U(0x01000000)
 
 /*
  * SSBL offset in case it's stored in eMMC boot partition.
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 7203de8..def2898 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -10,6 +10,7 @@
 USE_COHERENT_MEM	:=	0
 
 STM32MP_EARLY_CONSOLE	?=	0
+STM32MP_RECONFIGURE_CONSOLE ?=	0
 STM32MP_UART_BAUDRATE	?=	115200
 
 # Allow TF-A to concatenate BL2 & BL32 binaries in a single file,
@@ -121,6 +122,9 @@
 STM32MP_USB_PROGRAMMER	?=	0
 STM32MP_UART_PROGRAMMER	?=	0
 
+# Download load address for serial boot devices
+DWL_BUFFER_BASE 	?=	0xC7000000
+
 # Device tree
 ifeq ($(STM32MP13),1)
 BL2_DTSI		:=	stm32mp13-bl2.dtsi
@@ -205,6 +209,7 @@
 		STM32MP_EMMC \
 		STM32MP_EMMC_BOOT \
 		STM32MP_RAW_NAND \
+		STM32MP_RECONFIGURE_CONSOLE \
 		STM32MP_SDMMC \
 		STM32MP_SPI_NAND \
 		STM32MP_SPI_NOR \
@@ -225,6 +230,7 @@
 
 $(eval $(call add_defines,\
 	$(sort \
+		DWL_BUFFER_BASE \
 		PLAT_PARTITION_MAX_ENTRIES \
 		PLAT_XLAT_TABLES_DYNAMIC \
 		STM32_TF_A_COPIES \
@@ -235,6 +241,7 @@
 		STM32MP_EMMC \
 		STM32MP_EMMC_BOOT \
 		STM32MP_RAW_NAND \
+		STM32MP_RECONFIGURE_CONSOLE \
 		STM32MP_SDMMC \
 		STM32MP_SPI_NAND \
 		STM32MP_SPI_NOR \
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index 8106795..325666f 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,6 +40,8 @@
  ******************************************************************************/
 void sp_min_plat_fiq_handler(uint32_t id)
 {
+	(void)plat_crash_console_init();
+
 	switch (id & INT_ID_MASK) {
 	case STM32MP1_IRQ_TZC400:
 		tzc400_init(STM32MP1_TZC_BASE);
@@ -51,7 +53,7 @@
 		panic();
 		break;
 	default:
-		ERROR("SECURE IT handler not define for it : %u", id);
+		ERROR("SECURE IT handler not define for it : %u\n", id);
 		break;
 	}
 }
@@ -119,6 +121,8 @@
 	uintptr_t dt_addr = arg1;
 #endif
 
+	stm32mp_setup_early_console();
+
 	/* Imprecise aborts can be masked in NonSecure */
 	write_scr(read_scr() | SCR_AW_BIT);
 
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 116bd5d..a74d58c 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -666,5 +666,6 @@
 #define DT_RCC_SEC_CLK_COMPAT		"st,stm32mp1-rcc-secure"
 #endif
 #define DT_SDMMC2_COMPAT		"st,stm32-sdmmc2"
+#define DT_UART_COMPAT			"st,stm32h7-uart"
 
 #endif /* STM32MP1_DEF_H */
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
index cac9752..eb8823b 100644
--- a/plat/st/stm32mp1/stm32mp1_helper.S
+++ b/plat/st/stm32mp1/stm32mp1_helper.S
@@ -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
  */
@@ -15,6 +15,8 @@
 
 	.globl	platform_mem_init
 	.globl	plat_report_exception
+	.globl	plat_report_prefetch_abort
+	.globl	plat_report_data_abort
 	.globl	plat_get_my_entrypoint
 	.globl	plat_secondary_cold_boot_setup
 	.globl	plat_reset_handler
@@ -30,20 +32,18 @@
 	bx	lr
 endfunc platform_mem_init
 
-func plat_report_exception
 #if DEBUG
+func plat_report_exception
 	mov	r8, lr
 
-	/* Test if an abort occurred */
+	/*
+	 * Test if an abort occurred
+	 * In this case the error message has already been displayed
+	 * by dedicated functions
+	 */
 	cmp	r0, #MODE32_abt
-	bne	undef_inst_lbl
-	ldr	r4, =abort_str
-	bl	asm_print_str
-	mrs	r4, lr_abt
-	sub	r4, r4, #4
-	b	print_exception_info
+	beq	1f
 
-undef_inst_lbl:
 	/* Test for an undefined instruction */
 	cmp	r0, #MODE32_und
 	bne	other_exception_lbl
@@ -69,12 +69,69 @@
 	ldr	r4, =end_error_str
 	bl	asm_print_str
 
+1:
 	bx	r8
-#else
-	bx	lr
-#endif
 endfunc plat_report_exception
 
+func plat_report_prefetch_abort
+	mov	r8, lr
+	mov	r9, r0
+
+	ldr	r4, =prefetch_abort_str
+	bl	asm_print_str
+
+	mov	r4, r9
+	sub	r4, r4, #4
+	bl	asm_print_hex
+
+	ldr	r4, =ifsr_str
+	bl	asm_print_str
+
+	ldcopr	r4, IFSR
+	bl	asm_print_hex
+
+	ldr	r4, =ifar_str
+	bl	asm_print_str
+
+	ldcopr	r4, IFAR
+	bl	asm_print_hex
+
+	ldr	r4, =end_error_str
+	bl	asm_print_str
+
+	bx	r8
+endfunc plat_report_prefetch_abort
+
+func plat_report_data_abort
+	mov	r8, lr
+	mov	r9, r0
+
+	ldr	r4, =data_abort_str
+	bl	asm_print_str
+
+	mov	r4, r9
+	sub	r4, r4, #8
+	bl	asm_print_hex
+
+	ldr	r4, =dfsr_str
+	bl	asm_print_str
+
+	ldcopr	r4, DFSR
+	bl	asm_print_hex
+
+	ldr	r4, =dfar_str
+	bl	asm_print_str
+
+	ldcopr	r4, DFAR
+	bl	asm_print_hex
+
+	ldr	r4, =end_error_str
+	bl	asm_print_str
+
+	bx	r8
+endfunc plat_report_data_abort
+#endif /* DEBUG */
+
 func plat_reset_handler
 	bx	lr
 endfunc plat_reset_handler
@@ -256,14 +313,24 @@
 
 #if DEBUG
 .section .rodata.rev_err_str, "aS"
-abort_str:
-	.asciz "\nAbort at: 0x"
+prefetch_abort_str:
+	.asciz "\nPrefetch Abort at: 0x"
+data_abort_str:
+	.asciz "\nData Abort at: 0x"
 undefined_str:
 	.asciz "\nUndefined instruction at: 0x"
 exception_start_str:
 	.asciz "\nException mode=0x"
 exception_end_str:
 	.asciz " at: 0x"
+dfsr_str:
+	.asciz " DFSR = 0x"
+dfar_str:
+	.asciz " DFAR = 0x"
+ifsr_str:
+	.asciz " IFSR = 0x"
+ifar_str:
+	.asciz " IFAR = 0x"
 end_error_str:
 	.asciz "\n\r"
 #endif
diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c
index 3892151..6e438c4 100644
--- a/plat/st/stm32mp1/stm32mp1_pm.c
+++ b/plat/st/stm32mp1/stm32mp1_pm.c
@@ -87,7 +87,7 @@
 	clk_disable(RTCAPB);
 
 	/* Generate an IT to core 1 */
-	gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, STM32MP_SECONDARY_CPU);
+	gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, false, STM32MP_SECONDARY_CPU);
 
 	return PSCI_E_SUCCESS;
 }
diff --git a/plat/xilinx/common/include/ipi.h b/plat/xilinx/common/include/ipi.h
index ac76bf0..1d62f3e 100644
--- a/plat/xilinx/common/include/ipi.h
+++ b/plat/xilinx/common/include/ipi.h
@@ -14,20 +14,20 @@
 /*********************************************************************
  * IPI mailbox status macros
  ********************************************************************/
-#define IPI_MB_STATUS_IDLE		0
-#define IPI_MB_STATUS_SEND_PENDING	1
-#define IPI_MB_STATUS_RECV_PENDING	2
+#define IPI_MB_STATUS_IDLE		(0U)
+#define IPI_MB_STATUS_SEND_PENDING	(1U)
+#define IPI_MB_STATUS_RECV_PENDING	(2U)
 
 /*********************************************************************
  * IPI mailbox call is secure or not macros
  ********************************************************************/
-#define IPI_MB_CALL_NOTSECURE	0
-#define IPI_MB_CALL_SECURE	1
+#define IPI_MB_CALL_NOTSECURE	(0U)
+#define IPI_MB_CALL_SECURE	(1U)
 
 /*********************************************************************
  * IPI secure check
  ********************************************************************/
-#define IPI_SECURE_MASK  0x1U
+#define IPI_SECURE_MASK  (0x1U)
 #define IPI_IS_SECURE(I) ((ipi_table[(I)].secure_only & \
 			   IPI_SECURE_MASK) ? 1 : 0)
 
diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h
index 5ccb774..1733930 100644
--- a/plat/xilinx/common/include/plat_startup.h
+++ b/plat/xilinx/common/include/plat_startup.h
@@ -7,6 +7,8 @@
 #ifndef PLAT_STARTUP_H
 #define PLAT_STARTUP_H
 
+#include <common/bl_common.h>
+
 /* For FSBL handover */
 enum fsbl_handoff {
 	FSBL_HANDOFF_SUCCESS = 0,
diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h
index 06efa4b..89626e5 100644
--- a/plat/xilinx/common/include/pm_common.h
+++ b/plat/xilinx/common/include/pm_common.h
@@ -27,6 +27,11 @@
 #endif
 #define PAYLOAD_ARG_SIZE	4U	/* size in bytes */
 
+#define TZ_VERSION_MAJOR	1
+#define TZ_VERSION_MINOR	0
+#define TZ_VERSION		((TZ_VERSION_MAJOR << 16) | \
+				 TZ_VERSION_MINOR)
+
 /**
  * pm_ipi - struct for capturing IPI-channel specific info
  * @local_ipi_id	Local IPI agent ID
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 318079b..6438896 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -141,7 +141,7 @@
  */
 int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
 {
-	int ret = 0;
+	int ret = 0U;
 	uint32_t status;
 
 	status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 9c9fd62..a0403cf 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -18,7 +18,7 @@
 #include "pm_defs.h"
 #include "pm_ipi.h"
 
-#define ERROR_CODE_MASK		0xFFFFU
+#define ERROR_CODE_MASK		(0xFFFFU)
 
 DEFINE_BAKERY_LOCK(pm_secure_lock);
 
diff --git a/plat/xilinx/versal/include/plat_pm_common.h b/plat/xilinx/versal/include/plat_pm_common.h
index fb4812d..4c057b8 100644
--- a/plat/xilinx/versal/include/plat_pm_common.h
+++ b/plat/xilinx/versal/include/plat_pm_common.h
@@ -19,8 +19,4 @@
 #define NON_SECURE_FLAG		1U
 #define SECURE_FLAG		0U
 
-#define VERSAL_TZ_VERSION_MAJOR		1U
-#define VERSAL_TZ_VERSION_MINOR		0U
-#define VERSAL_TZ_VERSION		((VERSAL_TZ_VERSION_MAJOR << 16U) | \
-					VERSAL_TZ_VERSION_MINOR)
 #endif /* PLAT_PM_COMMON_H */
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index a8b2c94..8087297 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -11,6 +11,10 @@
 IPI_CRC_CHECK := 0
 HARDEN_SLS_ALL := 0
 
+# A72 Erratum for SoC
+ERRATA_A72_859971 := 1
+ERRATA_A72_1319367 := 1
+
 ifdef VERSAL_ATF_MEM_BASE
     $(eval $(call add_define,VERSAL_ATF_MEM_BASE))
 
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index ecd8d08..db9fae4 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -17,7 +17,6 @@
 #include "pm_client.h"
 #include "pm_defs.h"
 #include "pm_svc_main.h"
-#include "../drivers/arm/gic/v3/gicv3_private.h"
 
 /* default shutdown/reboot scope is system(2) */
 static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
@@ -466,8 +465,6 @@
 		if (ret != 0) {
 			return PM_RET_ERROR_ARGS;
 		}
-		gicd_write_irouter(gicv3_driver_data->gicd_base,
-				  (uint32_t)PLAT_VERSAL_IPI_IRQ, MODE);
 		ret = PM_RET_SUCCESS;
 		break;
 	default:
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index e2a3cf8..c539aa7 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -17,7 +17,6 @@
 #define LIBPM_MODULE_ID		0x2U
 #define LOADER_MODULE_ID	0x7U
 
-#define MODE			0x80000000U
 #define MODULE_ID_MASK		0x0000ff00U
 /**********************************************************
  * PM API function declarations
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index 14329dc..48888e4 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -19,6 +19,9 @@
 #include "pm_client.h"
 #include "pm_ipi.h"
 #include <drivers/arm/gicv3.h>
+#include "../drivers/arm/gic/v3/gicv3_private.h"
+
+#define MODE				0x80000000U
 
 #define XSCUGIC_SGIR_EL1_INITID_SHIFT    24U
 #define INVALID_SGI    0xFFU
@@ -139,6 +142,8 @@
 	if (ret != 0) {
 		WARN("BL31: registering IPI interrupt failed\n");
 	}
+
+	gicd_write_irouter(gicv3_driver_data->gicd_base, PLAT_VERSAL_IPI_IRQ, MODE);
 	return ret;
 }
 
@@ -284,7 +289,7 @@
 
 	case PM_GET_TRUSTZONE_VERSION:
 		SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
-			 ((uint64_t)VERSAL_TZ_VERSION << 32U));
+			 ((uint64_t)TZ_VERSION << 32U));
 
 	default:
 		return (uintptr_t)0;
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_common.c b/plat/xilinx/versal_net/aarch64/versal_net_common.c
new file mode 100644
index 0000000..c78b5d0
--- /dev/null
+++ b/plat/xilinx/versal_net/aarch64/versal_net_common.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/runtime_svc.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 <plat_ipi.h>
+
+#include <plat_private.h>
+#include <versal_net_def.h>
+
+uint32_t platform_id, platform_version;
+
+/*
+ * Table of regions to map using the MMU.
+ * This doesn't include TZRAM as the 'mem_layout' argument passed to
+ * configure_mmu_elx() will give the available subset of that,
+ */
+const mmap_region_t plat_versal_net_mmap[] = {
+	MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CRF_BASE, CRF_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(IPI_BASE, IPI_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	{ 0 }
+};
+
+const mmap_region_t *plat_versal_net_get_mmap(void)
+{
+	return plat_versal_net_mmap;
+}
+
+/* For saving cpu clock for certain platform */
+uint32_t cpu_clock;
+
+char *board_name_decode(void)
+{
+	switch (platform_id) {
+	case VERSAL_NET_SPP:
+		return "IPP";
+	case VERSAL_NET_EMU:
+		return "EMU";
+	case VERSAL_NET_SILICON:
+		return "Silicon";
+	case VERSAL_NET_QEMU:
+		return "QEMU";
+	default:
+		return "Unknown";
+	}
+}
+
+void board_detection(void)
+{
+	uint32_t version;
+
+	version = mmio_read_32(PMC_TAP_VERSION);
+	platform_id = FIELD_GET(PLATFORM_MASK, version);
+	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version);
+
+	if (platform_id == VERSAL_NET_QEMU_COSIM) {
+		platform_id = VERSAL_NET_QEMU;
+	}
+
+	if ((platform_id == VERSAL_NET_SPP) ||
+	    (platform_id == VERSAL_NET_EMU) ||
+	    (platform_id == VERSAL_NET_QEMU)) {
+		/*
+		 * 9 is diff for
+		 * 0 means 0.9 version
+		 * 1 means 1.0 version
+		 * 2 means 1.1 version
+		 * etc,
+		 */
+		platform_version += 9U;
+	}
+
+	/* Make sure that console is setup to see this message */
+	VERBOSE("Platform id: %d version: %d.%d\n", platform_id,
+	      platform_version / 10U, platform_version % 10U);
+}
+
+void versal_net_config_setup(void)
+{
+	uint32_t val;
+	uintptr_t crl_base, iou_scntrs_base, psx_base;
+
+	crl_base = VERSAL_NET_CRL;
+	iou_scntrs_base = VERSAL_NET_IOU_SCNTRS;
+	psx_base = PSX_CRF;
+
+	/* Reset for system timestamp generator in FPX */
+	mmio_write_32(psx_base + PSX_CRF_RST_TIMESTAMP_OFFSET, 0);
+
+	/* Global timer init - Program time stamp reference clk */
+	val = mmio_read_32(crl_base + VERSAL_NET_CRL_TIMESTAMP_REF_CTRL_OFFSET);
+	val |= VERSAL_NET_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
+	mmio_write_32(crl_base + VERSAL_NET_CRL_TIMESTAMP_REF_CTRL_OFFSET, val);
+
+	/* Clear reset of timestamp reg */
+	mmio_write_32(crl_base + VERSAL_NET_CRL_RST_TIMESTAMP_OFFSET, 0);
+
+	/* Program freq register in System counter and enable system counter. */
+	mmio_write_32(iou_scntrs_base + VERSAL_NET_IOU_SCNTRS_BASE_FREQ_OFFSET,
+		      cpu_clock);
+	mmio_write_32(iou_scntrs_base + VERSAL_NET_IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET,
+		      VERSAL_NET_IOU_SCNTRS_CONTROL_EN);
+
+	generic_delay_timer_init();
+
+#if (TFA_NO_PM == 0)
+	/* Configure IPI data for versal_net */
+	versal_net_ipi_config_table_init();
+#endif
+}
+
+uint32_t plat_get_syscnt_freq2(void)
+{
+	return cpu_clock;
+}
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
new file mode 100644
index 0000000..48082a6
--- /dev/null
+++ b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <drivers/arm/gicv3.h>
+#include <platform_def.h>
+
+	.globl	plat_secondary_cold_boot_setup
+	.globl	plat_is_my_cpu_primary
+	.globl	platform_mem_init
+	.globl	plat_my_core_pos
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_crash_console_flush
+
+	/* -----------------------------------------------------
+	 * void plat_secondary_cold_boot_setup (void);
+	 *
+	 * This function performs any platform specific actions
+	 * needed for a secondary cpu after a cold reset e.g
+	 * mark the cpu's presence, mechanism to place it in a
+	 * holding pen etc.
+	 * TODO: Should we read the PSYS register to make sure
+	 * that the request has gone through.
+	 * -----------------------------------------------------
+	 */
+func plat_secondary_cold_boot_setup
+	mrs	x0, mpidr_el1
+
+	/*
+	 * There is no sane reason to come out of this wfi. This
+	 * cpu will be powered on and reset by the cpu_on pm api
+	 */
+	dsb	sy
+	bl	plat_panic_handler
+endfunc plat_secondary_cold_boot_setup
+
+func plat_is_my_cpu_primary
+	mov	x9, x30
+	bl	plat_my_core_pos
+	cmp	x0, #VERSAL_NET_PRIMARY_CPU
+	cset	x0, eq
+	ret	x9
+endfunc plat_is_my_cpu_primary
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_core_pos_by_mpidr()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	plat_core_pos_by_mpidr
+endfunc plat_my_core_pos
+
+	/* ---------------------------------------------------------------------
+	 * We don't need to carry out any memory initialization on Versal NET
+	 * platform. The Secure RAM is accessible straight away.
+	 * ---------------------------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
+
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Function to initialize the crash console
+	 * without a C Runtime to print crash report.
+	 * Clobber list : x0, x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+/*	mov_imm	x0, PLAT_VERSAL_NET_CRASH_UART_BASE
+	mov_imm	x1, PLAT_VERSAL_NET_CRASH_UART_CLK_IN_HZ
+	mov_imm	x2, VERSAL_NET_CONSOLE_BAUDRATE
+	b	console_pl011_core_init */
+endfunc plat_crash_console_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Function to print a character on the crash
+	 * console without a C Runtime.
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov_imm	x1, PLAT_VERSAL_NET_CRASH_UART_BASE
+	b	console_pl011_core_putc
+endfunc plat_crash_console_putc
+
+	/* ---------------------------------------------
+	 * void plat_crash_console_flush()
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * Out : void.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_flush
+	mov_imm	x0, PLAT_VERSAL_NET_CRASH_UART_BASE
+	b	console_pl011_core_flush
+endfunc plat_crash_console_flush
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
new file mode 100644
index 0000000..97080e9
--- /dev/null
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <bl31/bl31.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
+
+#include <plat_private.h>
+#include <plat_startup.h>
+#include <versal_net_def.h>
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+static console_t versal_net_runtime_console;
+
+/*
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ */
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	assert(sec_state_is_valid(type));
+
+	if (type == NON_SECURE) {
+		return &bl33_image_ep_info;
+	}
+
+	return &bl32_image_ep_info;
+}
+
+/*
+ * Set the build time defaults,if we can't find any config data.
+ */
+static inline void bl31_set_default_config(void)
+{
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+	bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+					DISABLE_ALL_EXCEPTIONS);
+}
+
+/*
+ * Perform any BL31 specific platform actions. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
+ * are lost (potentially). This needs to be done before the MMU is initialized
+ * so that the memory layout can be used while creating page tables.
+ */
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	uint32_t uart_clock;
+	int32_t rc;
+
+	board_detection();
+
+	switch (platform_id) {
+	case VERSAL_NET_SPP:
+		cpu_clock = 1000000;
+		uart_clock = 1000000;
+		break;
+	case VERSAL_NET_EMU:
+		cpu_clock = 3660000;
+		uart_clock = 25000000;
+		break;
+	case VERSAL_NET_QEMU:
+		/* Random values now */
+		cpu_clock = 100000000;
+		uart_clock = 25000000;
+		break;
+	case VERSAL_NET_SILICON:
+	default:
+		panic();
+	}
+
+	/* Initialize the console to provide early debug support */
+	rc = console_pl011_register(VERSAL_NET_UART_BASE, uart_clock,
+				    VERSAL_NET_UART_BAUDRATE,
+				    &versal_net_runtime_console);
+	if (rc == 0) {
+		panic();
+	}
+
+	console_set_scope(&versal_net_runtime_console, CONSOLE_FLAG_BOOT |
+			  CONSOLE_FLAG_RUNTIME);
+
+	NOTICE("TF-A running on Xilinx %s %d.%d\n", board_name_decode(),
+	       platform_version / 10U, platform_version % 10U);
+
+	/* Initialize the platform config for future decision making */
+	versal_net_config_setup();
+	/* There are no parameters from BL2 if BL31 is a reset vector */
+	assert(arg0 == 0U);
+	assert(arg1 == 0U);
+
+	/*
+	 * Do initial security configuration to allow DRAM/device access. On
+	 * Base VERSAL_NET only DRAM security is programmable (via TrustZone), but
+	 * other platforms might have more programmable security devices
+	 * present.
+	 */
+
+	/* Populate common information for BL32 and BL33 */
+	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+	bl31_set_default_config();
+
+	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
+	NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
+}
+
+static versal_intr_info_type_el3_t type_el3_interrupt_table[MAX_INTR_EL3];
+
+int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
+{
+	static uint32_t index;
+	uint32_t i;
+
+	/* Validate 'handler' and 'id' parameters */
+	if (handler == NULL || index >= MAX_INTR_EL3) {
+		return -EINVAL;
+	}
+
+	/* Check if a handler has already been registered */
+	for (i = 0; i < index; i++) {
+		if (id == type_el3_interrupt_table[i].id) {
+			return -EALREADY;
+		}
+	}
+
+	type_el3_interrupt_table[index].id = id;
+	type_el3_interrupt_table[index].handler = handler;
+
+	index++;
+
+	return 0;
+}
+
+static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
+					  void *handle, void *cookie)
+{
+	uint32_t intr_id;
+	uint32_t i;
+	interrupt_type_handler_t handler = NULL;
+
+	intr_id = plat_ic_get_pending_interrupt_id();
+
+	for (i = 0; i < MAX_INTR_EL3; i++) {
+		if (intr_id == type_el3_interrupt_table[i].id) {
+			handler = type_el3_interrupt_table[i].handler;
+		}
+	}
+
+	if (handler != NULL) {
+		handler(intr_id, flags, handle, cookie);
+	}
+
+	return 0;
+}
+
+void bl31_platform_setup(void)
+{
+	/* Initialize the gic cpu and distributor interfaces */
+	plat_versal_net_gic_driver_init();
+	plat_versal_net_gic_init();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	uint64_t flags = 0;
+	int32_t rc;
+
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	rc = register_interrupt_type_handler(INTR_TYPE_EL3,
+					     rdo_el3_interrupt_handler, flags);
+	if (rc != 0) {
+		panic();
+	}
+}
+
+/*
+ * Perform the very early platform specific architectural setup here.
+ */
+void bl31_plat_arch_setup(void)
+{
+	const mmap_region_t bl_regions[] = {
+		MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
+			MT_MEMORY | MT_RW | MT_SECURE),
+		MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
+				MT_CODE | MT_SECURE),
+		MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
+				MT_RO_DATA | MT_SECURE),
+		{0}
+	};
+
+	setup_page_tables(bl_regions, plat_versal_net_get_mmap());
+	enable_mmu(0);
+}
diff --git a/plat/xilinx/versal_net/include/plat_ipi.h b/plat/xilinx/versal_net/include/plat_ipi.h
new file mode 100644
index 0000000..5255f8f
--- /dev/null
+++ b/plat/xilinx/versal_net/include/plat_ipi.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Versal IPI management enums and defines */
+
+#ifndef PLAT_IPI_H
+#define PLAT_IPI_H
+
+#include <stdint.h>
+
+#include <ipi.h>
+
+/*********************************************************************
+ * IPI agent IDs macros
+ ********************************************************************/
+#define IPI_ID_PMC	1U
+#define IPI_ID_APU	2U
+#define IPI_ID_RPU0	3U
+#define IPI_ID_RPU1	4U
+#define IPI_ID_3	5U
+#define IPI_ID_4	6U
+#define IPI_ID_5	7U
+#define IPI_ID_MAX	8U
+
+/*********************************************************************
+ * IPI message buffers
+ ********************************************************************/
+#define IPI_BUFFER_BASEADDR	(0xEB3F0000U)
+
+#define IPI_BUFFER_APU_BASE	(IPI_BUFFER_BASEADDR + 0x400U)
+#define IPI_BUFFER_PMC_BASE	(IPI_BUFFER_BASEADDR + 0x200U)
+
+#define IPI_BUFFER_TARGET_APU_OFFSET	0x80U
+#define IPI_BUFFER_TARGET_PMC_OFFSET	0x40U
+
+#define IPI_BUFFER_LOCAL_BASE	IPI_BUFFER_APU_BASE
+#define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMC_BASE
+
+#define IPI_BUFFER_TARGET_LOCAL_OFFSET	IPI_BUFFER_TARGET_APU_OFFSET
+#define IPI_BUFFER_TARGET_REMOTE_OFFSET	IPI_BUFFER_TARGET_PMC_OFFSET
+
+#define IPI_BUFFER_MAX_WORDS	8
+
+#define IPI_BUFFER_REQ_OFFSET	0x0U
+#define IPI_BUFFER_RESP_OFFSET	0x20U
+
+/*********************************************************************
+ * Platform specific IPI API declarations
+ ********************************************************************/
+
+/* Configure IPI table for versal_net */
+void versal_net_ipi_config_table_init(void);
+
+#endif /* PLAT_IPI_H */
diff --git a/plat/xilinx/versal_net/include/plat_macros.S b/plat/xilinx/versal_net/include/plat_macros.S
new file mode 100644
index 0000000..fb108b6
--- /dev/null
+++ b/plat/xilinx/versal_net/include/plat_macros.S
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/arm/gicv3.h>
+
+#include "../include/platform_def.h"
+
+.section .rodata.gic_reg_name, "aS"
+/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+
+/* Applicable only to GICv3 with SRE enabled */
+icc_regs:
+	.asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", ""
+
+/* Registers common to both GICv2 and GICv3 */
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+	/* ---------------------------------------------
+	 * The below utility macro prints out relevant GIC
+	 * registers whenever an unhandled exception is
+	 * taken in BL31 on Versal NET platform.
+	 * Expects: GICD base in x16, GICC base in x17
+	 * Clobbers: x0 - x10, sp
+	 * ---------------------------------------------
+	 */
+	.macro versal_net_print_gic_regs
+	/* Check for GICv3 system register access */
+	mrs	x7, id_aa64pfr0_el1
+	ubfx	x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
+	cmp	x7, #1
+	b.ne	print_gicv2
+
+	/* Check for SRE enable */
+	mrs	x8, ICC_SRE_EL3
+	tst	x8, #ICC_SRE_SRE_BIT
+	b.eq	print_gicv2
+
+	/* Load the icc reg list to x6 */
+	adr	x6, icc_regs
+	/* Load the icc regs to gp regs used by str_in_crash_buf_print */
+	mrs	x8, ICC_HPPIR0_EL1
+	mrs	x9, ICC_HPPIR1_EL1
+	mrs	x10, ICC_CTLR_EL3
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+	b	print_gic_common
+
+print_gicv2:
+	/* Load the gicc reg list to x6 */
+	adr	x6, gicc_regs
+	/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+	ldr	w8, [x17, #GICC_HPPIR]
+	ldr	w9, [x17, #GICC_AHPPIR]
+	ldr	w10, [x17, #GICC_CTLR]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+
+print_gic_common:
+	/* Print the GICD_ISPENDR regs */
+	add	x7, x16, #GICD_ISPENDR
+	adr	x4, gicd_pend_reg
+	bl	asm_print_str
+gicd_ispendr_loop:
+	sub	x4, x7, x16
+	cmp	x4, #0x280
+	b.eq	exit_print_gic_regs
+	bl	asm_print_hex
+
+	adr	x4, spacer
+	bl	asm_print_str
+
+	ldr	x4, [x7], #8
+	bl	asm_print_hex
+
+	adr	x4, newline
+	bl	asm_print_str
+	b	gicd_ispendr_loop
+exit_print_gic_regs:
+	.endm
+
+	/* ---------------------------------------------
+	 * The below required platform porting macro
+	 * prints out relevant GIC and CCI registers
+	 * whenever an unhandled exception is taken in
+	 * BL31.
+	 * Clobbers: x0 - x10, x16, x17, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_crash_print_regs
+	/*
+	 * Empty for now to handle more platforms variant.
+	 * Uncomment it when versions are stable
+	 */
+	/*
+	mov_imm	x17, PLAT_VERSAL_NET_GICD_BASE
+	mov_imm	x16, PLAT_VERSAL_NET_GICR_BASE
+	versal_net_print_gic_regs
+	*/
+	.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/xilinx/versal_net/include/plat_pm_common.h b/plat/xilinx/versal_net/include/plat_pm_common.h
new file mode 100644
index 0000000..ad7b40f
--- /dev/null
+++ b/plat/xilinx/versal_net/include/plat_pm_common.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Contains platform specific definitions of commonly used macros data types
+ * for PU Power Management. This file should be common for all PU's.
+ */
+
+#ifndef PLAT_PM_COMMON_H
+#define PLAT_PM_COMMON_H
+
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include "pm_defs.h"
+
+#define NON_SECURE_FLAG		1U
+#define SECURE_FLAG		0U
+
+#endif /* PLAT_PM_COMMON_H */
diff --git a/plat/xilinx/versal_net/include/plat_private.h b/plat/xilinx/versal_net/include/plat_private.h
new file mode 100644
index 0000000..6a3bc19
--- /dev/null
+++ b/plat/xilinx/versal_net/include/plat_private.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PRIVATE_H
+#define PLAT_PRIVATE_H
+
+#include <bl31/interrupt_mgmt.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+typedef struct versal_intr_info_type_el3 {
+	uint32_t id;
+	interrupt_type_handler_t handler;
+} versal_intr_info_type_el3_t;
+
+void versal_net_config_setup(void);
+
+const mmap_region_t *plat_versal_net_get_mmap(void);
+
+void plat_versal_net_gic_driver_init(void);
+void plat_versal_net_gic_init(void);
+void plat_versal_net_gic_cpuif_enable(void);
+void plat_versal_net_gic_cpuif_disable(void);
+void plat_versal_net_gic_pcpu_init(void);
+void plat_versal_net_gic_save(void);
+void plat_versal_net_gic_resume(void);
+void plat_versal_net_gic_redistif_on(void);
+void plat_versal_net_gic_redistif_off(void);
+
+extern uint32_t cpu_clock, platform_id, platform_version;
+void board_detection(void);
+char *board_name_decode(void);
+uint64_t smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+		       uint64_t x4, void *cookie, void *handle, uint64_t flags);
+int32_t sip_svc_setup_init(void);
+/*
+ * Register handler to specific GIC entrance
+ * for INTR_TYPE_EL3 type of interrupt
+ */
+int request_intr_type_el3(uint32_t irq, interrupt_type_handler_t fiq_handler);
+
+#define PM_GET_CHIPID			(24U)
+#define IOCTL_OSPI_MUX_SELECT		(21U)
+
+#endif /* PLAT_PRIVATE_H */
diff --git a/plat/xilinx/versal_net/include/platform_def.h b/plat/xilinx/versal_net/include/platform_def.h
new file mode 100644
index 0000000..696771f
--- /dev/null
+++ b/plat/xilinx/versal_net/include/platform_def.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include "versal_net_def.h"
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#define PLATFORM_STACK_SIZE		U(0x440)
+
+#define PLATFORM_CLUSTER_COUNT		U(4)
+#define PLATFORM_CORE_COUNT_PER_CLUSTER	U(4) /* 4 CPUs per cluster */
+
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * PLATFORM_CORE_COUNT_PER_CLUSTER)
+
+#define PLAT_MAX_PWR_LVL		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at the top of the Trusted SRAM (just below the shared memory, if
+ * present). BL31_BASE is calculated using the current BL31 debug size plus a
+ * little space for growth.
+ */
+#ifndef VERSAL_NET_ATF_MEM_BASE
+# define BL31_BASE			U(0xBBF00000)
+# define BL31_LIMIT			U(0xBBFFFFFF)
+#else
+# define BL31_BASE			U(VERSAL_NET_ATF_MEM_BASE)
+# define BL31_LIMIT			U(VERSAL_NET_ATF_MEM_BASE + VERSAL_NET_ATF_MEM_SIZE - 1)
+# ifdef VERSAL_NET_ATF_MEM_PROGBITS_SIZE
+#  define BL31_PROGBITS_LIMIT		U(VERSAL_NET_ATF_MEM_BASE + \
+					  VERSAL_NET_ATF_MEM_PROGBITS_SIZE - 1)
+# endif
+#endif
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+#ifndef VERSAL_NET_BL32_MEM_BASE
+# define BL32_BASE			U(0x60000000)
+# define BL32_LIMIT			U(0x7FFFFFFF)
+#else
+# define BL32_BASE			U(VERSAL_NET_BL32_MEM_BASE)
+# define BL32_LIMIT			U(VERSAL_NET_BL32_MEM_BASE + VERSAL_NET_BL32_MEM_SIZE - 1)
+#endif
+
+/*******************************************************************************
+ * BL33 specific defines.
+ ******************************************************************************/
+#ifndef PRELOADED_BL33_BASE
+# define PLAT_ARM_NS_IMAGE_BASE		U(0x8000000)
+#else
+# define PLAT_ARM_NS_IMAGE_BASE		U(PRELOADED_BL33_BASE)
+#endif
+
+/*******************************************************************************
+ * TSP  specific defines.
+ ******************************************************************************/
+#define TSP_SEC_MEM_BASE		BL32_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE + 1U)
+
+/* ID of the secure physical generic timer interrupt used by the TSP */
+#define TSP_IRQ_SEC_PHY_TIMER		ARM_IRQ_SEC_PHY_TIMER
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32U)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32U)
+#if (BL31_LIMIT < PLAT_DDR_LOWMEM_MAX)
+#define MAX_MMAP_REGIONS		U(10)
+#else
+#define MAX_MMAP_REGIONS		U(9)
+#endif
+
+#define MAX_XLAT_TABLES			U(8)
+
+#define CACHE_WRITEBACK_SHIFT	U(6)
+#define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
+
+#define PLAT_VERSAL_NET_GICD_BASE	U(0xE2000000)
+#define PLAT_VERSAL_NET_GICR_BASE	U(0xE2060000)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLAT_VERSAL_IPI_IRQ	62
+
+#define PLAT_VERSAL_NET_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(VERSAL_NET_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
+#define PLAT_VERSAL_NET_G0_IRQ_PROPS(grp)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
new file mode 100644
index 0000000..8cb5bf3
--- /dev/null
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VERSAL_NET_DEF_H
+#define VERSAL_NET_DEF_H
+
+#include <plat/arm/common/smccc_def.h>
+#include <plat/common/common_def.h>
+
+#define MAX_INTR_EL3			2
+/* This part is taken from U-Boot project under GPL that's why dual license above */
+#define __bf_shf(x) (__builtin_ffsll(x) - 1U)
+#define FIELD_GET(_mask, _reg)						\
+	({								\
+		(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask));	\
+	})
+
+/* List all consoles */
+#define VERSAL_NET_CONSOLE_ID_pl011	U(1)
+#define VERSAL_NET_CONSOLE_ID_pl011_0	U(1)
+#define VERSAL_NET_CONSOLE_ID_pl011_1	U(2)
+
+#define VERSAL_NET_CONSOLE_IS(con)	(VERSAL_NET_CONSOLE_ID_ ## con == VERSAL_NET_CONSOLE)
+
+/* List all platforms */
+#define VERSAL_NET_SILICON		U(0)
+#define VERSAL_NET_SPP			U(1)
+#define VERSAL_NET_EMU			U(2)
+#define VERSAL_NET_QEMU			U(3)
+#define VERSAL_NET_QEMU_COSIM		U(7)
+
+/* For platform detection */
+#define PMC_TAP				U(0xF11A0000)
+#define PMC_TAP_VERSION			(PMC_TAP + 0x4U)
+# define PLATFORM_MASK			GENMASK(27U, 24U)
+# define PLATFORM_VERSION_MASK		GENMASK(31U, 28U)
+
+/* Global timer reset */
+#define PSX_CRF			U(0xEC200000)
+#define ACPU0_CLK_CTRL		U(0x10C)
+#define ACPU_CLK_CTRL_CLKACT	BIT(25)
+
+#define RST_APU0_OFFSET		U(0x300)
+#define RST_APU_COLD_RESET	BIT(0)
+#define RST_APU_WARN_RESET	BIT(4)
+#define RST_APU_CLUSTER_COLD_RESET	BIT(8)
+#define RST_APU_CLUSTER_WARM_RESET	BIT(9)
+
+#define PSX_CRF_RST_TIMESTAMP_OFFSET	U(0x33C)
+
+#define APU_PCLI			U(0xECB10000)
+#define APU_PCLI_CPU_STEP		U(0x30)
+#define APU_PCLI_CLUSTER_CPU_STEP	(4U * APU_PCLI_CPU_STEP)
+#define APU_PCLI_CLUSTER_OFFSET		U(0x8000)
+#define APU_PCLI_CLUSTER_STEP		U(0x1000)
+#define PCLI_PREQ_OFFSET		U(0x4)
+#define PREQ_CHANGE_REQUEST		BIT(0)
+#define PCLI_PSTATE_OFFSET		U(0x8)
+#define PCLI_PSTATE_VAL_SET		U(0x48)
+#define PCLI_PSTATE_VAL_CLEAR		U(0x38)
+
+/* Firmware Image Package */
+#define VERSAL_NET_PRIMARY_CPU		U(0)
+
+#define CORE_0_IEN_POWER_OFFSET			(0x00000018U)
+#define APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_POWER_OFFSET + \
+						 (0x30 * cpu_id)))
+#define APU_PCIL_CORE_X_IEN_POWER_MASK		(0x00000001U)
+#define CORE_0_IDS_POWER_OFFSET			(0x0000001CU)
+#define APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_POWER_OFFSET + \
+						 (0x30 * cpu_id)))
+#define APU_PCIL_CORE_X_IDS_POWER_MASK		(0x00000001U)
+#define CORE_PWRDN_EN_BIT_MASK			(0x1U)
+
+/*******************************************************************************
+ * memory map related constants
+ ******************************************************************************/
+/* IPP 1.2/SPP 0.9 mapping */
+#define DEVICE0_BASE		U(0xE8000000) /* psx, crl, iou */
+#define DEVICE0_SIZE		U(0x08000000)
+#define DEVICE1_BASE		U(0xE2000000) /* gic */
+#define DEVICE1_SIZE		U(0x00800000)
+#define DEVICE2_BASE		U(0xF1000000) /* uart, pmc_tap */
+#define DEVICE2_SIZE		U(0x01000000)
+#define CRF_BASE		U(0xFD1A0000)
+#define CRF_SIZE		U(0x00600000)
+#define IPI_BASE		U(0xEB300000)
+#define IPI_SIZE		U(0x00100000)
+
+/* CRL */
+#define VERSAL_NET_CRL					U(0xEB5E0000)
+#define VERSAL_NET_CRL_TIMESTAMP_REF_CTRL_OFFSET	U(0x14C)
+#define VERSAL_NET_CRL_RST_TIMESTAMP_OFFSET		U(0x348)
+
+#define VERSAL_NET_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT	(1U << 25U)
+
+/* IOU SCNTRS */
+#define VERSAL_NET_IOU_SCNTRS					U(0xEC920000)
+#define VERSAL_NET_IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET	U(0)
+#define VERSAL_NET_IOU_SCNTRS_BASE_FREQ_OFFSET			U(0x20)
+
+#define VERSAL_NET_IOU_SCNTRS_CONTROL_EN	U(1)
+
+#define APU_CLUSTER0		U(0xECC00000)
+#define APU_RVBAR_L_0		U(0x40)
+#define APU_RVBAR_H_0		U(0x44)
+#define APU_CLUSTER_STEP	U(0x100000)
+
+#define SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL	U(0xF1060504)
+
+/*******************************************************************************
+ * IRQ constants
+ ******************************************************************************/
+#define VERSAL_NET_IRQ_SEC_PHY_TIMER	U(29)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define VERSAL_NET_UART0_BASE		U(0xF1920000)
+#define VERSAL_NET_UART_BAUDRATE	115200
+
+#define VERSAL_NET_UART_BASE		VERSAL_NET_UART0_BASE
+
+#define PLAT_VERSAL_NET_CRASH_UART_BASE		VERSAL_NET_UART_BASE
+#define PLAT_VERSAL_NET_CRASH_UART_CLK_IN_HZ	VERSAL_NET_UART_CLOCK
+#define VERSAL_NET_CONSOLE_BAUDRATE		VERSAL_NET_UART_BAUDRATE
+
+/*******************************************************************************
+ * IPI registers and bitfields
+ ******************************************************************************/
+#define IPI0_REG_BASE		(0xEB330000U)
+#define IPI0_TRIG_BIT		(1 << 2)
+#define PMC_IPI_TRIG_BIT	(1 << 1)
+#define IPI1_REG_BASE		(0xEB340000U)
+#define IPI1_TRIG_BIT		(1 << 3)
+#define IPI2_REG_BASE		(0xEB350000U)
+#define IPI2_TRIG_BIT		(1 << 4)
+#define IPI3_REG_BASE		(0xEB360000U)
+#define IPI3_TRIG_BIT		(1 << 5)
+#define IPI4_REG_BASE		(0xEB370000U)
+#define IPI4_TRIG_BIT		(1 << 6)
+#define IPI5_REG_BASE		(0xEB380000U)
+#define IPI5_TRIG_BIT		(1 << 7)
+
+/* Processor core device IDs */
+#define PM_DEV_CLUSTER0_ACPU_0	(0x1810C0AFU)
+#define PM_DEV_CLUSTER0_ACPU_1	(0x1810C0B0U)
+#define PM_DEV_CLUSTER0_ACPU_2	(0x1810C0B1U)
+#define PM_DEV_CLUSTER0_ACPU_3	(0x1810C0B2U)
+
+#define PM_DEV_CLUSTER1_ACPU_0	(0x1810C0B3U)
+#define PM_DEV_CLUSTER1_ACPU_1	(0x1810C0B4U)
+#define PM_DEV_CLUSTER1_ACPU_2	(0x1810C0B5U)
+#define PM_DEV_CLUSTER1_ACPU_3	(0x1810C0B6U)
+
+#define PM_DEV_CLUSTER2_ACPU_0	(0x1810C0B7U)
+#define PM_DEV_CLUSTER2_ACPU_1	(0x1810C0B8U)
+#define PM_DEV_CLUSTER2_ACPU_2	(0x1810C0B9U)
+#define PM_DEV_CLUSTER2_ACPU_3	(0x1810C0BAU)
+
+#define PM_DEV_CLUSTER3_ACPU_0	(0x1810C0BBU)
+#define PM_DEV_CLUSTER3_ACPU_1	(0x1810C0BCU)
+#define PM_DEV_CLUSTER3_ACPU_2	(0x1810C0BDU)
+#define PM_DEV_CLUSTER3_ACPU_3	(0x1810C0BEU)
+
+#endif /* VERSAL_NET_DEF_H */
diff --git a/plat/xilinx/versal_net/plat_psci.c b/plat/xilinx/versal_net/plat_psci.c
new file mode 100644
index 0000000..c5833a9
--- /dev/null
+++ b/plat/xilinx/versal_net/plat_psci.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
+
+#include <plat_private.h>
+
+#define PM_RET_ERROR_NOFEATURE U(19)
+
+#define PM_IOCTL	34U
+
+static uintptr_t versal_net_sec_entry;
+
+static void zynqmp_cpu_standby(plat_local_state_t cpu_state)
+{
+	dsb();
+	wfi();
+}
+
+static int32_t zynqmp_nopmu_pwr_domain_on(u_register_t mpidr)
+{
+	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+	uint32_t cpu = cpu_id % PLATFORM_CORE_COUNT_PER_CLUSTER;
+	uint32_t cluster = cpu_id / PLATFORM_CORE_COUNT_PER_CLUSTER;
+	uintptr_t apu_cluster_base = 0, apu_pcli_base, apu_pcli_cluster = 0;
+	uintptr_t rst_apu_cluster = PSX_CRF + RST_APU0_OFFSET + (cluster * 0x4);
+
+	VERBOSE("%s: mpidr: 0x%lx, cpuid: %x, cpu: %x, cluster: %x\n",
+		__func__, mpidr, cpu_id, cpu, cluster);
+
+	if (cpu_id == -1) {
+		return PSCI_E_INTERN_FAIL;
+	}
+
+	if (platform_id == VERSAL_NET_SPP && cluster > 1) {
+		panic();
+	}
+
+	if (cluster > 3) {
+		panic();
+	}
+
+	apu_pcli_cluster = APU_PCLI + APU_PCLI_CLUSTER_OFFSET + (cluster * APU_PCLI_CLUSTER_STEP);
+	apu_cluster_base = APU_CLUSTER0 + (cluster * APU_CLUSTER_STEP);
+
+	/* Enable clock */
+	mmio_setbits_32(PSX_CRF + ACPU0_CLK_CTRL + (cluster * 0x4), ACPU_CLK_CTRL_CLKACT);
+
+	/* Enable cluster states */
+	mmio_setbits_32(apu_pcli_cluster + PCLI_PSTATE_OFFSET, PCLI_PSTATE_VAL_SET);
+	mmio_setbits_32(apu_pcli_cluster + PCLI_PREQ_OFFSET, PREQ_CHANGE_REQUEST);
+
+	/* assert core reset */
+	mmio_setbits_32(rst_apu_cluster, ((RST_APU_COLD_RESET|RST_APU_WARN_RESET) << cpu));
+
+	/* program RVBAR */
+	mmio_write_32(apu_cluster_base + APU_RVBAR_L_0 + (cpu << 3),
+		      (uint32_t)versal_net_sec_entry);
+	mmio_write_32(apu_cluster_base + APU_RVBAR_H_0 + (cpu << 3),
+		      versal_net_sec_entry >> 32);
+
+	/* de-assert core reset */
+	mmio_clrbits_32(rst_apu_cluster, ((RST_APU_COLD_RESET|RST_APU_WARN_RESET) << cpu));
+
+	/* clear cluster resets */
+	mmio_clrbits_32(rst_apu_cluster, RST_APU_CLUSTER_WARM_RESET);
+	mmio_clrbits_32(rst_apu_cluster, RST_APU_CLUSTER_COLD_RESET);
+
+	apu_pcli_base = APU_PCLI + (APU_PCLI_CPU_STEP * cpu) +
+			(APU_PCLI_CLUSTER_CPU_STEP * cluster);
+
+	mmio_write_32(apu_pcli_base + PCLI_PSTATE_OFFSET, PCLI_PSTATE_VAL_CLEAR);
+	mmio_write_32(apu_pcli_base + PCLI_PREQ_OFFSET, PREQ_CHANGE_REQUEST);
+
+	return PSCI_E_SUCCESS;
+}
+
+static void zynqmp_nopmu_pwr_domain_off(const psci_power_state_t *target_state)
+{
+}
+
+static void __dead2 zynqmp_nopmu_system_reset(void)
+{
+	while (1)
+		wfi();
+}
+
+static int32_t zynqmp_validate_ns_entrypoint(uint64_t ns_entrypoint)
+{
+	return PSCI_E_SUCCESS;
+}
+
+static void zynqmp_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+}
+
+static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	plat_versal_net_gic_pcpu_init();
+	plat_versal_net_gic_cpuif_enable();
+}
+
+static void zynqmp_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+}
+
+static void __dead2 zynqmp_system_off(void)
+{
+	while (1)
+		wfi();
+}
+
+static int32_t zynqmp_validate_power_state(uint32_t power_state, psci_power_state_t *req_state)
+{
+	return PSCI_E_SUCCESS;
+}
+
+static void zynqmp_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] = PLAT_MAX_OFF_STATE;
+	req_state->pwr_domain_state[1] = PLAT_MAX_OFF_STATE;
+}
+
+static const struct plat_psci_ops versal_net_nopmc_psci_ops = {
+	.cpu_standby			= zynqmp_cpu_standby,
+	.pwr_domain_on			= zynqmp_nopmu_pwr_domain_on,
+	.pwr_domain_off			= zynqmp_nopmu_pwr_domain_off,
+	.system_reset			= zynqmp_nopmu_system_reset,
+	.validate_ns_entrypoint		= zynqmp_validate_ns_entrypoint,
+	.pwr_domain_suspend		= zynqmp_pwr_domain_suspend,
+	.pwr_domain_on_finish		= zynqmp_pwr_domain_on_finish,
+	.pwr_domain_suspend_finish	= zynqmp_pwr_domain_suspend_finish,
+	.system_off			= zynqmp_system_off,
+	.validate_power_state		= zynqmp_validate_power_state,
+	.get_sys_suspend_power_state	= zynqmp_get_sys_suspend_power_state,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int32_t plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			    const struct plat_psci_ops **psci_ops)
+{
+	versal_net_sec_entry = sec_entrypoint;
+
+	VERBOSE("Setting up entry point %lx\n", versal_net_sec_entry);
+
+	*psci_ops = &versal_net_nopmc_psci_ops;
+
+	return 0;
+}
+
+int sip_svc_setup_init(void)
+{
+	return 0;
+}
+
+static int32_t no_pm_ioctl(uint32_t device_id, uint32_t ioctl_id,
+			   uint32_t arg1, uint32_t arg2)
+{
+	VERBOSE("%s: ioctl_id: %x, arg1: %x\n", __func__, ioctl_id, arg1);
+	if (ioctl_id == IOCTL_OSPI_MUX_SELECT) {
+		mmio_write_32(SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL, arg1);
+		return 0;
+	}
+	return PM_RET_ERROR_NOFEATURE;
+}
+
+static uint64_t no_pm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+			      uint64_t x4, void *cookie, void *handle, uint64_t flags)
+{
+	int32_t ret;
+	uint32_t arg[4], api_id;
+
+	arg[0] = (uint32_t)x1;
+	arg[1] = (uint32_t)(x1 >> 32);
+	arg[2] = (uint32_t)x2;
+	arg[3] = (uint32_t)(x2 >> 32);
+
+	api_id = smc_fid & FUNCID_NUM_MASK;
+	VERBOSE("%s: smc_fid: %x, api_id=0x%x\n", __func__, smc_fid, api_id);
+
+	switch (api_id) {
+	case PM_IOCTL:
+	{
+		ret = no_pm_ioctl(arg[0], arg[1], arg[2], arg[3]);
+		SMC_RET1(handle, (uint64_t)ret);
+	}
+	case PM_GET_CHIPID:
+	{
+		uint32_t idcode, version;
+
+		idcode  = mmio_read_32(PMC_TAP);
+		version = mmio_read_32(PMC_TAP_VERSION);
+		SMC_RET2(handle, ((uint64_t)idcode << 32), version);
+	}
+	default:
+		WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+uint64_t smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4,
+		     void *cookie, void *handle, uint64_t flags)
+{
+	return no_pm_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+}
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
new file mode 100644
index 0000000..8beaa9a
--- /dev/null
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
+
+#include <plat_private.h>
+#include "pm_api_sys.h"
+#include "pm_client.h"
+#include <pm_common.h>
+#include "pm_svc_main.h"
+#include "versal_net_def.h"
+
+static uintptr_t versal_net_sec_entry;
+
+static int32_t versal_net_pwr_domain_on(u_register_t mpidr)
+{
+	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+	const struct pm_proc *proc;
+
+	VERBOSE("%s: mpidr: 0x%lx, cpuid: %x\n",
+		__func__, mpidr, cpu_id);
+
+	if (cpu_id == -1) {
+		return PSCI_E_INTERN_FAIL;
+	}
+
+	proc = pm_get_proc(cpu_id);
+	if (!proc) {
+		return PSCI_E_INTERN_FAIL;
+	}
+
+	pm_req_wakeup(proc->node_id, (versal_net_sec_entry & 0xFFFFFFFFU) | 0x1U,
+		      versal_net_sec_entry >> 32, 0, 0);
+
+	/* Clear power down request */
+	pm_client_wakeup(proc);
+
+	return PSCI_E_SUCCESS;
+}
+
+/**
+ * versal_net_pwr_domain_off() - This function performs actions to turn off core
+ *
+ * @param target_state	Targeted state
+ */
+static void versal_net_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+	const struct pm_proc *proc = pm_get_proc(cpu_id);
+
+	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
+		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
+			__func__, i, target_state->pwr_domain_state[i]);
+	}
+
+	/* Prevent interrupts from spuriously waking up this cpu */
+	plat_versal_net_gic_cpuif_disable();
+
+	/*
+	 * Send request to PMC to power down the appropriate APU CPU
+	 * core.
+	 * According to PSCI specification, CPU_off function does not
+	 * have resume address and CPU core can only be woken up
+	 * invoking CPU_on function, during which resume address will
+	 * be set.
+	 */
+	pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
+			SECURE_FLAG);
+}
+
+/**
+ * versal_net_system_reset() - This function sends the reset request
+ * to firmware for the system to reset.  This function does not return.
+ */
+static void __dead2 versal_net_system_reset(void)
+{
+	/* Send the system reset request to the PMC */
+	pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
+			  pm_get_shutdown_scope(), SECURE_FLAG);
+
+	while (1) {
+		wfi();
+	}
+}
+
+/**
+ * versal_net_pwr_domain_suspend() - This function sends request to PMC to suspend
+ * core.
+ *
+ * @param target_state	Targeted state
+ */
+static void versal_net_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	uint32_t state;
+	uint32_t cpu_id = plat_my_core_pos();
+	const struct pm_proc *proc = pm_get_proc(cpu_id);
+
+	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
+		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
+			__func__, i, target_state->pwr_domain_state[i]);
+	}
+
+	plat_versal_net_gic_cpuif_disable();
+
+	if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
+		plat_versal_net_gic_save();
+	}
+
+	state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
+		PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
+
+	/* Send request to PMC to suspend this core */
+	pm_self_suspend(proc->node_id, MAX_LATENCY, state, versal_net_sec_entry,
+			SECURE_FLAG);
+
+	/* TODO: disable coherency */
+}
+
+static void versal_net_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	(void)target_state;
+
+	/* Enable the gic cpu interface */
+	plat_versal_net_gic_pcpu_init();
+
+	/* Program the gic per-cpu distributor or re-distributor interface */
+	plat_versal_net_gic_cpuif_enable();
+}
+
+/**
+ * versal_net_pwr_domain_suspend_finish() - This function performs actions to finish
+ * suspend procedure.
+ *
+ * @param target_state	Targeted state
+ */
+static void versal_net_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+	const struct pm_proc *proc = pm_get_proc(cpu_id);
+
+	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
+			__func__, i, target_state->pwr_domain_state[i]);
+
+	/* Clear the APU power control register for this cpu */
+	pm_client_wakeup(proc);
+
+	/* TODO: enable coherency */
+
+	/* APU was turned off, so restore GIC context */
+	if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
+		plat_versal_net_gic_resume();
+	}
+
+	plat_versal_net_gic_cpuif_enable();
+}
+
+/**
+ * versal_net_system_off() - This function sends the system off request
+ * to firmware.  This function does not return.
+ */
+static void __dead2 versal_net_system_off(void)
+{
+	/* Send the power down request to the PMC */
+	pm_system_shutdown(XPM_SHUTDOWN_TYPE_SHUTDOWN,
+			  pm_get_shutdown_scope(), SECURE_FLAG);
+
+	while (1) {
+		wfi();
+	}
+}
+
+/**
+ * versal_net_validate_power_state() - This function ensures that the power state
+ * parameter in request is valid.
+ *
+ * @param power_state		Power state of core
+ * @param req_state		Requested state
+ *
+ * @return Returns status, either PSCI_E_SUCCESS or reason
+ */
+static int32_t versal_net_validate_power_state(unsigned int power_state,
+					       psci_power_state_t *req_state)
+{
+	VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
+
+	int32_t pstate = psci_get_pstate_type(power_state);
+
+	assert(req_state);
+
+	/* Sanity check the requested state */
+	if (pstate == PSTATE_TYPE_STANDBY) {
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
+	} else {
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
+	}
+
+	/* We expect the 'state id' to be zero */
+	if (psci_get_pstate_id(power_state)) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+/**
+ * versal_net_get_sys_suspend_power_state() - Get power state for system suspend
+ *
+ * @param req_state	Requested state
+ */
+static void versal_net_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] = PLAT_MAX_OFF_STATE;
+	req_state->pwr_domain_state[1] = PLAT_MAX_OFF_STATE;
+}
+
+static const struct plat_psci_ops versal_net_nopmc_psci_ops = {
+	.pwr_domain_on                  = versal_net_pwr_domain_on,
+	.pwr_domain_off                 = versal_net_pwr_domain_off,
+	.pwr_domain_on_finish           = versal_net_pwr_domain_on_finish,
+	.pwr_domain_suspend             = versal_net_pwr_domain_suspend,
+	.pwr_domain_suspend_finish      = versal_net_pwr_domain_suspend_finish,
+	.system_off                     = versal_net_system_off,
+	.system_reset                   = versal_net_system_reset,
+	.validate_power_state           = versal_net_validate_power_state,
+	.get_sys_suspend_power_state    = versal_net_get_sys_suspend_power_state,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int32_t plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			    const struct plat_psci_ops **psci_ops)
+{
+	versal_net_sec_entry = sec_entrypoint;
+
+	VERBOSE("Setting up entry point %lx\n", versal_net_sec_entry);
+
+	*psci_ops = &versal_net_nopmc_psci_ops;
+
+	return 0;
+}
+
+int32_t sip_svc_setup_init(void)
+{
+	return pm_setup();
+}
+
+uint64_t smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4,
+		     void *cookie, void *handle, uint64_t flags)
+{
+	return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+}
diff --git a/plat/xilinx/versal_net/plat_topology.c b/plat/xilinx/versal_net/plat_topology.c
new file mode 100644
index 0000000..7f985b0
--- /dev/null
+++ b/plat/xilinx/versal_net/plat_topology.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <plat/common/platform.h>
+
+#include <plat_private.h>
+#include <platform_def.h>
+
+static const uint8_t plat_power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	1,
+	/* Number of clusters */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the first cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the second cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the third cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the fourth cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+};
+
+const uint8_t *plat_get_power_domain_tree_desc(void)
+{
+	return plat_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	uint32_t cluster_id, cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+
+	cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
+	cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		return -3;
+	}
+
+	/*
+	 * Validate cpu_id by checking whether it represents a CPU in
+	 * one of the two clusters present on the platform.
+	 */
+	if (cpu_id >= PLATFORM_CORE_COUNT_PER_CLUSTER) {
+		return -1;
+	}
+
+	return (cpu_id + (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER));
+}
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
new file mode 100644
index 0000000..b3d56bc
--- /dev/null
+++ b/plat/xilinx/versal_net/platform.mk
@@ -0,0 +1,102 @@
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+# Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+PLAT_PATH := plat/xilinx/versal_net
+
+# A78 Erratum for SoC
+ERRATA_A78_AE_1941500 := 1
+ERRATA_A78_AE_1951502 := 1
+ERRATA_A78_AE_2376748 := 1
+ERRATA_A78_AE_2395408 := 1
+
+override PROGRAMMABLE_RESET_ADDRESS := 1
+PSCI_EXTENDED_STATE_ID := 1
+SEPARATE_CODE_AND_RODATA := 1
+override RESET_TO_BL31 := 1
+PL011_GENERIC_UART := 1
+GIC_ENABLE_V4_EXTN :=  0
+GICV3_SUPPORT_GIC600 := 1
+TFA_NO_PM := 0
+
+override CTX_INCLUDE_AARCH32_REGS    := 0
+
+ifdef TFA_NO_PM
+   $(eval $(call add_define,TFA_NO_PM))
+endif
+
+ifdef VERSAL_NET_ATF_MEM_BASE
+    $(eval $(call add_define,VERSAL_NET_ATF_MEM_BASE))
+
+    ifndef VERSAL_NET_ATF_MEM_SIZE
+        $(error "VERSAL_NET_ATF_BASE defined without VERSAL_NET_ATF_SIZE")
+    endif
+    $(eval $(call add_define,VERSAL_NET_ATF_MEM_SIZE))
+
+    ifdef VERSAL_NET_ATF_MEM_PROGBITS_SIZE
+        $(eval $(call add_define,VERSAL_NET_ATF_MEM_PROGBITS_SIZE))
+    endif
+endif
+
+ifdef VERSAL_NET_BL32_MEM_BASE
+    $(eval $(call add_define,VERSAL_NET_BL32_MEM_BASE))
+
+    ifndef VERSAL_NET_BL32_MEM_SIZE
+        $(error "VERSAL_NET_BL32_BASE defined without VERSAL_NET_BL32_SIZE")
+    endif
+    $(eval $(call add_define,VERSAL_NET_BL32_MEM_SIZE))
+endif
+
+USE_COHERENT_MEM := 0
+HW_ASSISTED_COHERENCY := 1
+
+VERSAL_NET_CONSOLE	?=	pl011
+$(eval $(call add_define_val,VERSAL_NET_CONSOLE,VERSAL_NET_CONSOLE_ID_${VERSAL_NET_CONSOLE}))
+
+PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
+				-Iplat/xilinx/common/include/			\
+				-Iplat/xilinx/common/ipi_mailbox_service/	\
+				-I${PLAT_PATH}/include/				\
+				-Iplat/xilinx/versal/pm_service/
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+include lib/libfdt/libfdt.mk
+
+PLAT_BL_COMMON_SOURCES	:=	\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				${GICV3_SOURCES}				\
+				drivers/arm/pl011/aarch64/pl011_console.S	\
+				plat/arm/common/arm_common.c			\
+				plat/common/plat_gicv3.c			\
+				${PLAT_PATH}/aarch64/versal_net_helpers.S	\
+				${PLAT_PATH}/aarch64/versal_net_common.c
+
+BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
+				lib/cpus/aarch64/cortex_a78_ae.S		\
+				lib/cpus/aarch64/cortex_a78.S			\
+				plat/common/plat_psci_common.c
+ifeq ($(TFA_NO_PM), 0)
+BL31_SOURCES		+=	plat/xilinx/versal/pm_service/pm_api_sys.c	\
+				plat/xilinx/common/pm_service/pm_ipi.c		\
+				${PLAT_PATH}/plat_psci_pm.c			\
+				plat/xilinx/versal/pm_service/pm_svc_main.c	\
+				${PLAT_PATH}/pm_service/pm_client.c		\
+				${PLAT_PATH}/versal_net_ipi.c
+else
+BL31_SOURCES		+=	${PLAT_PATH}/plat_psci.c
+endif
+BL31_SOURCES		+=	plat/xilinx/common/plat_startup.c		\
+				plat/xilinx/common/ipi.c			\
+				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
+				${PLAT_PATH}/bl31_versal_net_setup.c		\
+				${PLAT_PATH}/plat_topology.c			\
+				common/fdt_fixup.c				\
+				${LIBFDT_SRCS}					\
+				${PLAT_PATH}/sip_svc_setup.c			\
+				${PLAT_PATH}/versal_net_gicv3.c			\
+				${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/xilinx/versal_net/pm_service/pm_client.c b/plat/xilinx/versal_net/pm_service/pm_client.c
new file mode 100644
index 0000000..6487324
--- /dev/null
+++ b/plat/xilinx/versal_net/pm_service/pm_client.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * APU specific definition of processors in the subsystem as well as functions
+ * for getting information about and changing state of the APU.
+ */
+
+#include <assert.h>
+
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+
+#include <plat_ipi.h>
+#include <platform_def.h>
+#include "pm_api_sys.h"
+#include "pm_client.h"
+#include <versal_net_def.h>
+
+#define UNDEFINED_CPUID		(~0)
+
+DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7)
+DEFINE_BAKERY_LOCK(pm_client_secure_lock);
+
+static const struct pm_ipi apu_ipi = {
+	.local_ipi_id = IPI_ID_APU,
+	.remote_ipi_id = IPI_ID_PMC,
+	.buffer_base = IPI_BUFFER_APU_BASE,
+};
+
+/* Order in pm_procs_all array must match cpu ids */
+static const struct pm_proc pm_procs_all[] = {
+	{
+		.node_id = PM_DEV_CLUSTER0_ACPU_0,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER0_ACPU_1,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER0_ACPU_2,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER0_ACPU_3,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER1_ACPU_0,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER1_ACPU_1,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER1_ACPU_2,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER1_ACPU_3,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER2_ACPU_0,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER2_ACPU_1,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER2_ACPU_2,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER2_ACPU_3,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER3_ACPU_0,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER3_ACPU_1,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER3_ACPU_2,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	},
+	{
+		.node_id = PM_DEV_CLUSTER3_ACPU_3,
+		.ipi = &apu_ipi,
+		.pwrdn_mask = 0,
+	}
+};
+
+const struct pm_proc *primary_proc = &pm_procs_all[0];
+
+/**
+ * pm_get_proc() - returns pointer to the proc structure
+ * @param cpuid	id of the cpu whose proc struct pointer should be returned
+ *
+ * @return pointer to a proc structure if proc is found, otherwise NULL
+ */
+const struct pm_proc *pm_get_proc(uint32_t cpuid)
+{
+	if (cpuid < ARRAY_SIZE(pm_procs_all)) {
+		return &pm_procs_all[cpuid];
+	}
+
+	NOTICE("ERROR: cpuid: %d proc NULL\n", cpuid);
+	return NULL;
+}
+
+/**
+ * pm_client_suspend() - Client-specific suspend actions
+ *
+ * This function should contain any PU-specific actions
+ * required prior to sending suspend request to PMU
+ * Actions taken depend on the state system is suspending to.
+ *
+ * @param proc	processor which need to suspend
+ * @param state	desired suspend state
+ */
+void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+	uintptr_t val;
+
+	bakery_lock_get(&pm_client_secure_lock);
+
+	/* TODO: Set wakeup source */
+
+	val = read_cpu_pwrctrl_val();
+	val |= CORE_PWRDN_EN_BIT_MASK;
+	write_cpu_pwrctrl_val(val);
+
+	isb();
+
+	mmio_write_32(APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id),
+		      APU_PCIL_CORE_X_IEN_POWER_MASK);
+
+	bakery_lock_release(&pm_client_secure_lock);
+}
+
+/**
+ * pm_get_cpuid() - get the local cpu ID for a global node ID
+ * @param nid	node id of the processor
+ *
+ * @return the cpu ID (starting from 0) for the subsystem
+ */
+static uint32_t pm_get_cpuid(uint32_t nid)
+{
+	for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
+		if (pm_procs_all[i].node_id == nid) {
+			return i;
+		}
+	}
+	return UNDEFINED_CPUID;
+}
+
+/**
+ * pm_client_wakeup() - Client-specific wakeup actions
+ *
+ * This function should contain any PU-specific actions
+ * required for waking up another APU core
+ *
+ * @param proc	Processor which need to wakeup
+ */
+void pm_client_wakeup(const struct pm_proc *proc)
+{
+	uint32_t cpuid = pm_get_cpuid(proc->node_id);
+
+	if (cpuid == UNDEFINED_CPUID) {
+		return;
+	}
+
+	bakery_lock_get(&pm_client_secure_lock);
+
+	/* TODO: clear powerdown bit for affected cpu */
+
+	bakery_lock_release(&pm_client_secure_lock);
+}
+
+/**
+ * pm_client_abort_suspend() - Client-specific abort-suspend actions
+ *
+ * This function should contain any PU-specific actions
+ * required for aborting a prior suspend request
+ */
+void pm_client_abort_suspend(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+	uintptr_t val;
+
+	/* Enable interrupts at processor level (for current cpu) */
+	gicv3_cpuif_enable(plat_my_core_pos());
+
+	bakery_lock_get(&pm_client_secure_lock);
+
+	/* Clear powerdown request */
+	val = read_cpu_pwrctrl_val();
+	val &= ~CORE_PWRDN_EN_BIT_MASK;
+	write_cpu_pwrctrl_val(val);
+
+	isb();
+
+	/* Disabled power down interrupt */
+	mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id),
+			APU_PCIL_CORE_X_IDS_POWER_MASK);
+
+	bakery_lock_release(&pm_client_secure_lock);
+}
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
new file mode 100644
index 0000000..0e3940f
--- /dev/null
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <tools_share/uuid.h>
+
+#include "ipi_mailbox_svc.h"
+#include "plat_private.h"
+#include "pm_svc_main.h"
+
+/* SMC function IDs for SiP Service queries */
+#define VERSAL_NET_SIP_SVC_CALL_COUNT	(0x8200ff00U)
+#define VERSAL_NET_SIP_SVC_UID		(0x8200ff01U)
+#define VERSAL_NET_SIP_SVC_VERSION	(0x8200ff03U)
+
+/* SiP Service Calls version numbers */
+#define SIP_SVC_VERSION_MAJOR		(0U)
+#define SIP_SVC_VERSION_MINOR		(1U)
+
+/* These macros are used to identify PM calls from the SMC function ID */
+#define PM_FID_MASK	0xf000u
+#define PM_FID_VALUE	0u
+#define IPI_FID_VALUE	0x1000u
+#define is_pm_fid(_fid)	(((_fid) & PM_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE)
+
+/* SiP Service UUID */
+DEFINE_SVC_UUID2(versal_net_sip_uuid,
+		0x80d4c25a, 0xebaf, 0x11eb, 0x94, 0x68,
+		0x0b, 0x4e, 0x3b, 0x8f, 0xc3, 0x60);
+
+/**
+ * sip_svc_setup() - Setup SiP Service
+ */
+static int32_t sip_svc_setup(void)
+{
+	return sip_svc_setup_init();
+}
+
+/*
+ * sip_svc_smc_handler() - Top-level SiP Service SMC handler
+ *
+ * Handler for all SiP SMC calls. Handles standard SIP requests
+ * and calls PM SMC handler if the call is for a PM-API function.
+ */
+static uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
+			     u_register_t x1,
+			     u_register_t x2,
+			     u_register_t x3,
+			     u_register_t x4,
+			     void *cookie,
+			     void *handle,
+			     u_register_t flags)
+{
+	/* Let PM SMC handler deal with PM-related requests */
+	if (is_pm_fid(smc_fid)) {
+		return smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
+				flags);
+	}
+
+	/* Let IPI SMC handler deal with IPI-related requests if platform */
+	if (is_ipi_fid(smc_fid)) {
+		return ipi_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+	}
+
+	/* Let PM SMC handler deal with PM-related requests */
+	switch (smc_fid) {
+	case VERSAL_NET_SIP_SVC_CALL_COUNT:
+		/* PM functions + default functions */
+		SMC_RET1(handle, 2);
+
+	case VERSAL_NET_SIP_SVC_UID:
+		SMC_UUID_RET(handle, versal_net_sip_uuid);
+
+	case VERSAL_NET_SIP_SVC_VERSION:
+		SMC_RET2(handle, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR);
+
+	default:
+		WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+/* Register PM Service Calls as runtime service */
+DECLARE_RT_SVC(
+		sip_svc,
+		OEN_SIP_START,
+		OEN_SIP_END,
+		SMC_TYPE_FAST,
+		sip_svc_setup,
+		sip_svc_smc_handler);
diff --git a/plat/xilinx/versal_net/versal_net_gicv3.c b/plat/xilinx/versal_net/versal_net_gicv3.c
new file mode 100644
index 0000000..b7ac6ab
--- /dev/null
+++ b/plat/xilinx/versal_net/versal_net_gicv3.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/interrupt_props.h>
+#include <drivers/arm/gicv3.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+
+#include <plat_private.h>
+#include <platform_def.h>
+
+/******************************************************************************
+ * The following functions are defined as weak to allow a platform to override
+ * the way the GICv3 driver is initialised and used.
+ *****************************************************************************/
+#pragma weak plat_versal_net_gic_driver_init
+#pragma weak plat_versal_net_gic_init
+#pragma weak plat_versal_net_gic_cpuif_enable
+#pragma weak plat_versal_net_gic_cpuif_disable
+#pragma weak plat_versal_net_gic_pcpu_init
+#pragma weak plat_versal_net_gic_redistif_on
+#pragma weak plat_versal_net_gic_redistif_off
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+static const uintptr_t gicr_base_addrs[2] = {
+	PLAT_VERSAL_NET_GICR_BASE,	/* GICR Base address of the primary CPU */
+	0U				/* Zero Termination */
+};
+
+/* List of zero terminated GICR frame addresses which CPUs will probe */
+static const uintptr_t *gicr_frames;
+
+static const interrupt_prop_t versal_net_interrupt_props[] = {
+	PLAT_VERSAL_NET_G1S_IRQ_PROPS(INTR_GROUP1S),
+	PLAT_VERSAL_NET_G0_IRQ_PROPS(INTR_GROUP0)
+};
+
+/*
+ * We save and restore the GICv3 context on system suspend. Allocate the
+ * data in the designated EL3 Secure carve-out memory.
+ */
+static gicv3_redist_ctx_t rdist_ctx __section("versal_net_el3_tzc_dram");
+static gicv3_dist_ctx_t dist_ctx __section("versal_net_el3_tzc_dram");
+
+/*
+ * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
+ * to core position.
+ *
+ * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
+ * values read from GICR_TYPER don't have an MT field. To reuse the same
+ * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
+ * that read from GICR_TYPER.
+ *
+ * Assumptions:
+ *
+ *   - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
+ *   - No CPUs implemented in the system use affinity level 3.
+ */
+static uint32_t versal_net_gicv3_mpidr_hash(u_register_t mpidr)
+{
+	mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
+	return plat_core_pos_by_mpidr(mpidr);
+}
+
+static const gicv3_driver_data_t versal_net_gic_data __unused = {
+	.gicd_base = PLAT_VERSAL_NET_GICD_BASE,
+	.gicr_base = 0U,
+	.interrupt_props = versal_net_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(versal_net_interrupt_props),
+	.rdistif_num = PLATFORM_CORE_COUNT,
+	.rdistif_base_addrs = rdistif_base_addrs,
+	.mpidr_to_core_pos = versal_net_gicv3_mpidr_hash
+};
+
+void __init plat_versal_net_gic_driver_init(void)
+{
+	/*
+	 * The GICv3 driver is initialized in EL3 and does not need
+	 * to be initialized again in SEL1. This is because the S-EL1
+	 * can use GIC system registers to manage interrupts and does
+	 * not need GIC interface base addresses to be configured.
+	 */
+#if IMAGE_BL31
+	gicv3_driver_init(&versal_net_gic_data);
+	gicr_frames = gicr_base_addrs;
+
+	if (gicv3_rdistif_probe(gicr_frames[0]) == -1) {
+		ERROR("No GICR base frame found for Primary CPU\n");
+		panic();
+	}
+#endif
+}
+
+/******************************************************************************
+ * Versal NET common helper to initialize the GIC. Only invoked by BL31
+ *****************************************************************************/
+void __init plat_versal_net_gic_init(void)
+{
+	gicv3_distif_init();
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * Versal NET common helper to enable the GIC CPU interface
+ *****************************************************************************/
+void plat_versal_net_gic_cpuif_enable(void)
+{
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * Versal NET common helper to disable the GIC CPU interface
+ *****************************************************************************/
+void plat_versal_net_gic_cpuif_disable(void)
+{
+	gicv3_cpuif_disable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * Versal NET common helper to initialize the per-cpu redistributor interface in
+ * GICv3
+ *****************************************************************************/
+void plat_versal_net_gic_pcpu_init(void)
+{
+	int32_t result;
+	const uintptr_t *plat_gicr_frames = gicr_frames;
+
+	do {
+		result = gicv3_rdistif_probe(*plat_gicr_frames);
+
+		/* If the probe is successful, no need to proceed further */
+		if (result == 0) {
+			break;
+		}
+
+		plat_gicr_frames++;
+	} while (*plat_gicr_frames != 0U);
+
+	if (result == -1) {
+		ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
+		panic();
+	}
+
+	gicv3_rdistif_init(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * Versal NET common helpers to power GIC redistributor interface
+ *****************************************************************************/
+void plat_versal_net_gic_redistif_on(void)
+{
+	gicv3_rdistif_on(plat_my_core_pos());
+}
+
+void plat_versal_net_gic_redistif_off(void)
+{
+	gicv3_rdistif_off(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * Versal NET common helper to save & restore the GICv3 on resume from system
+ * suspend
+ *****************************************************************************/
+void plat_versal_net_gic_save(void)
+{
+	/*
+	 * If an ITS is available, save its context before
+	 * the Redistributor using:
+	 * gicv3_its_save_disable(gits_base, &its_ctx[i])
+	 * Additionnaly, an implementation-defined sequence may
+	 * be required to save the whole ITS state.
+	 */
+
+	/*
+	 * Save the GIC Redistributors and ITS contexts before the
+	 * Distributor context. As we only handle SYSTEM SUSPEND API,
+	 * we only need to save the context of the CPU that is issuing
+	 * the SYSTEM SUSPEND call, i.e. the current CPU.
+	 */
+	gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
+
+	/* Save the GIC Distributor context */
+	gicv3_distif_save(&dist_ctx);
+
+	/*
+	 * From here, all the components of the GIC can be safely powered down
+	 * as long as there is an alternate way to handle wakeup interrupt
+	 * sources.
+	 */
+}
+
+void plat_versal_net_gic_resume(void)
+{
+	/* Restore the GIC Distributor context */
+	gicv3_distif_init_restore(&dist_ctx);
+
+	/*
+	 * Restore the GIC Redistributor and ITS contexts after the
+	 * Distributor context. As we only handle SYSTEM SUSPEND API,
+	 * we only need to restore the context of the CPU that issued
+	 * the SYSTEM SUSPEND call.
+	 */
+	gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
+
+	/*
+	 * If an ITS is available, restore its context after
+	 * the Redistributor using:
+	 * gicv3_its_restore(gits_base, &its_ctx[i])
+	 * An implementation-defined sequence may be required to
+	 * restore the whole ITS state. The ITS must also be
+	 * re-enabled after this sequence has been executed.
+	 */
+}
diff --git a/plat/xilinx/versal_net/versal_net_ipi.c b/plat/xilinx/versal_net/versal_net_ipi.c
new file mode 100644
index 0000000..26ded89
--- /dev/null
+++ b/plat/xilinx/versal_net/versal_net_ipi.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Versal NET IPI agent registers access management
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+
+#include <ipi.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
+
+/* versal_net ipi configuration table */
+static const struct ipi_config versal_net_ipi_table[IPI_ID_MAX] = {
+	/* A72 IPI */
+	[IPI_ID_APU] = {
+		.ipi_bit_mask = IPI0_TRIG_BIT,
+		.ipi_reg_base = IPI0_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* PMC IPI */
+	[IPI_ID_PMC] = {
+		.ipi_bit_mask = PMC_IPI_TRIG_BIT,
+		.ipi_reg_base = IPI0_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* RPU0 IPI */
+	[IPI_ID_RPU0] = {
+		.ipi_bit_mask = IPI1_TRIG_BIT,
+		.ipi_reg_base = IPI1_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* RPU1 IPI */
+	[IPI_ID_RPU1] = {
+		.ipi_bit_mask = IPI2_TRIG_BIT,
+		.ipi_reg_base = IPI2_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI3 IPI */
+	[IPI_ID_3] = {
+		.ipi_bit_mask = IPI3_TRIG_BIT,
+		.ipi_reg_base = IPI3_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI4 IPI */
+	[IPI_ID_4] = {
+		.ipi_bit_mask = IPI4_TRIG_BIT,
+		.ipi_reg_base = IPI4_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI5 IPI */
+	[IPI_ID_5] = {
+		.ipi_bit_mask = IPI5_TRIG_BIT,
+		.ipi_reg_base = IPI5_REG_BASE,
+		.secure_only = 0,
+	},
+};
+
+/* versal_net_ipi_config_table_init() - Initialize versal_net IPI configuration data
+ *
+ * @ipi_config_table  - IPI configuration table
+ * @ipi_total - Total number of IPI available
+ *
+ */
+void versal_net_ipi_config_table_init(void)
+{
+	ipi_config_table_init(versal_net_ipi_table, ARRAY_SIZE(versal_net_ipi_table));
+}
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 66bbf30..c2d22c2 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -40,7 +40,7 @@
 # define BL31_BASE			U(0xfffea000)
 # define BL31_LIMIT			U(0x100000000)
 #else
-# define BL31_BASE			U(0xfff5a000)
+# define BL31_BASE			U(0xfffe5000)
 # define BL31_LIMIT			U(0x100000000)
 #endif
 #else
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index dd82bc0..05adbd0 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -11,11 +12,20 @@
 ZYNQMP_WDT_RESTART := 0
 IPI_CRC_CHECK := 0
 override RESET_TO_BL31 := 1
-override GICV2_G0_FOR_EL3 := 1
 override WARMBOOT_ENABLE_DCACHE_EARLY := 1
 
 EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
 
+# pncd SPD requires secure SGI to be handled at EL1
+ifeq (${SPD},pncd)
+ifeq (${ZYNQMP_WDT_RESTART},1)
+$(error "Error: ZYNQMP_WDT_RESTART and SPD=pncd are incompatible")
+endif
+override GICV2_G0_FOR_EL3 := 0
+else
+override GICV2_G0_FOR_EL3 := 1
+endif
+
 # Do not enable SVE
 ENABLE_SVE_FOR_NS	:= 0
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index c6bed7d..e61310a 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -21,51 +21,51 @@
 #include "pm_common.h"
 #include "pm_ipi.h"
 
-#define CLK_NODE_MAX			U(6)
+#define CLK_NODE_MAX			(6U)
 
-#define CLK_PARENTS_ID_LEN		U(16)
-#define CLK_TOPOLOGY_NODE_OFFSET	U(16)
-#define CLK_TOPOLOGY_PAYLOAD_LEN	U(12)
-#define CLK_PARENTS_PAYLOAD_LEN		U(12)
-#define CLK_TYPE_SHIFT			U(2)
-#define CLK_CLKFLAGS_SHIFT		U(8)
-#define CLK_TYPEFLAGS_SHIFT		U(24)
-#define CLK_TYPEFLAGS2_SHIFT		U(4)
-#define CLK_TYPEFLAGS_BITS_MASK		U(0xFF)
-#define CLK_TYPEFLAGS2_BITS_MASK	U(0x0F00)
-#define CLK_TYPEFLAGS_BITS		U(8)
+#define CLK_PARENTS_ID_LEN		(16U)
+#define CLK_TOPOLOGY_NODE_OFFSET	(16U)
+#define CLK_TOPOLOGY_PAYLOAD_LEN	(12U)
+#define CLK_PARENTS_PAYLOAD_LEN		(12U)
+#define CLK_TYPE_SHIFT			(2U)
+#define CLK_CLKFLAGS_SHIFT		(8U)
+#define CLK_TYPEFLAGS_SHIFT		(24U)
+#define CLK_TYPEFLAGS2_SHIFT		(4U)
+#define CLK_TYPEFLAGS_BITS_MASK		(0xFFU)
+#define CLK_TYPEFLAGS2_BITS_MASK	(0x0F00U)
+#define CLK_TYPEFLAGS_BITS		(8U)
 
 #define CLK_EXTERNAL_PARENT	(PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN)
 
-#define NA_MULT					U(0)
-#define NA_DIV					U(0)
-#define NA_SHIFT				U(0)
-#define NA_WIDTH				U(0)
-#define NA_CLK_FLAGS				U(0)
-#define NA_TYPE_FLAGS				U(0)
+#define NA_MULT					(0U)
+#define NA_DIV					(0U)
+#define NA_SHIFT				(0U)
+#define NA_WIDTH				(0U)
+#define NA_CLK_FLAGS				(0U)
+#define NA_TYPE_FLAGS				(0U)
 
 /* PLL nodes related definitions */
-#define PLL_PRESRC_MUX_SHIFT			U(20)
-#define PLL_PRESRC_MUX_WIDTH			U(3)
-#define PLL_POSTSRC_MUX_SHIFT			U(24)
-#define PLL_POSTSRC_MUX_WIDTH			U(3)
-#define PLL_DIV2_MUX_SHIFT			U(16)
-#define PLL_DIV2_MUX_WIDTH			U(1)
-#define PLL_BYPASS_MUX_SHIFT			U(3)
-#define PLL_BYPASS_MUX_WIDTH			U(1)
+#define PLL_PRESRC_MUX_SHIFT			(20U)
+#define PLL_PRESRC_MUX_WIDTH			(3U)
+#define PLL_POSTSRC_MUX_SHIFT			(24U)
+#define PLL_POSTSRC_MUX_WIDTH			(3U)
+#define PLL_DIV2_MUX_SHIFT			(16U)
+#define PLL_DIV2_MUX_WIDTH			(1U)
+#define PLL_BYPASS_MUX_SHIFT			(3U)
+#define PLL_BYPASS_MUX_WIDTH			(1U)
 
 /* Peripheral nodes related definitions */
 /* Peripheral Clocks */
-#define PERIPH_MUX_SHIFT			U(0)
-#define PERIPH_MUX_WIDTH			U(3)
-#define PERIPH_DIV1_SHIFT			U(8)
-#define PERIPH_DIV1_WIDTH			U(6)
-#define PERIPH_DIV2_SHIFT			U(16)
-#define PERIPH_DIV2_WIDTH			U(6)
-#define PERIPH_GATE_SHIFT			U(24)
-#define PERIPH_GATE_WIDTH			U(1)
+#define PERIPH_MUX_SHIFT			(0U)
+#define PERIPH_MUX_WIDTH			(3U)
+#define PERIPH_DIV1_SHIFT			(8U)
+#define PERIPH_DIV1_WIDTH			(6U)
+#define PERIPH_DIV2_SHIFT			(16U)
+#define PERIPH_DIV2_WIDTH			(6U)
+#define PERIPH_GATE_SHIFT			(24U)
+#define PERIPH_GATE_WIDTH			(1U)
 
-#define USB_GATE_SHIFT				U(25)
+#define USB_GATE_SHIFT				(25U)
 
 /* External clock related definitions */
 
@@ -87,20 +87,20 @@
 
 
 #define PLLCTRL_BP_MASK				BIT(3)
-#define PLLCTRL_RESET_MASK			U(1)
-#define PLL_FRAC_OFFSET				U(8)
-#define PLL_FRAC_MODE				U(1)
-#define PLL_INT_MODE				U(0)
-#define PLL_FRAC_MODE_MASK			U(0x80000000)
-#define PLL_FRAC_MODE_SHIFT			U(31)
-#define PLL_FRAC_DATA_MASK			U(0xFFFF)
-#define PLL_FRAC_DATA_SHIFT			U(0)
-#define PLL_FBDIV_MASK				U(0x7F00)
-#define PLL_FBDIV_WIDTH				U(7)
-#define PLL_FBDIV_SHIFT				U(8)
+#define PLLCTRL_RESET_MASK			(1U)
+#define PLL_FRAC_OFFSET				(8U)
+#define PLL_FRAC_MODE				(1U)
+#define PLL_INT_MODE				(0U)
+#define PLL_FRAC_MODE_MASK			(0x80000000U)
+#define PLL_FRAC_MODE_SHIFT			(31U)
+#define PLL_FRAC_DATA_MASK			(0xFFFFU)
+#define PLL_FRAC_DATA_SHIFT			(0U)
+#define PLL_FBDIV_MASK				(0x7F00U)
+#define PLL_FBDIV_WIDTH				(7U)
+#define PLL_FBDIV_SHIFT				(8U)
 
-#define CLK_PLL_RESET_ASSERT			U(1)
-#define CLK_PLL_RESET_RELEASE			U(2)
+#define CLK_PLL_RESET_ASSERT			(1U)
+#define CLK_PLL_RESET_RELEASE			(2U)
 #define CLK_PLL_RESET_PULSE	(CLK_PLL_RESET_ASSERT | CLK_PLL_RESET_RELEASE)
 
 /* Common topology definitions */
@@ -2400,7 +2400,7 @@
 {
 	unsigned int i;
 
-	for (i = 0; i < ARRAY_SIZE(pm_clk_invalid_list); i++)
+	for (i = 0U; i < ARRAY_SIZE(pm_clk_invalid_list); i++)
 		if (pm_clk_invalid_list[i] == clock_id)
 			return 0;
 
@@ -2672,9 +2672,9 @@
 		if (nodes[i].type == div_type) {
 			if (CLK_DIVIDER_POWER_OF_TWO &
 					nodes[i].typeflags) {
-				*max_div = (1 << (BIT(nodes[i].width) - 1));
+				*max_div = (1U << (BIT(nodes[i].width) - 1U));
 			} else {
-				*max_div = BIT(nodes[i].width) - 1;
+				*max_div = BIT(nodes[i].width) - 1U;
 			}
 			return PM_RET_SUCCESS;
 		}
@@ -2815,7 +2815,7 @@
  */
 enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll)
 {
-	if (!pll) {
+	if (pll == NULL) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -2838,7 +2838,7 @@
  */
 enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll)
 {
-	if (!pll) {
+	if (pll == NULL) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -2862,7 +2862,7 @@
 	enum pm_ret_status status;
 	enum pm_pll_mode mode;
 
-	if (!pll || !state) {
+	if ((pll == NULL) || !state) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -2896,7 +2896,7 @@
 					   enum clock_id clock_id,
 					   uint32_t parent_index)
 {
-	if (!pll) {
+	if (pll == NULL) {
 		return PM_RET_ERROR_ARGS;
 	}
 	if (pll->pre_src == clock_id) {
@@ -2929,7 +2929,7 @@
 					   enum clock_id clock_id,
 					   uint32_t *parent_index)
 {
-	if (!pll) {
+	if (pll == NULL) {
 		return PM_RET_ERROR_ARGS;
 	}
 	if (pll->pre_src == clock_id) {
@@ -2966,7 +2966,7 @@
 {
 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if (!pll || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) {
+	if ((pll == NULL) || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) {
 		return PM_RET_ERROR_ARGS;
 	}
 	pll->mode = mode;
@@ -2988,7 +2988,7 @@
 {
 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if (!pll || !mode) {
+	if ((pll == NULL) || !mode) {
 		return PM_RET_ERROR_ARGS;
 	}
 	*mode = pll->mode;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index bc15592..cc0dacc 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -15,19 +15,19 @@
 
 #include "pm_common.h"
 
-#define CLK_NAME_LEN		U(15)
-#define MAX_PARENTS		U(100)
+#define CLK_NAME_LEN		(15U)
+#define MAX_PARENTS		(100U)
 #define CLK_NA_PARENT		-1
 #define CLK_DUMMY_PARENT	-2
 
 /* Flags for parent id */
-#define PARENT_CLK_SELF		U(0)
-#define PARENT_CLK_NODE1	U(1)
-#define PARENT_CLK_NODE2	U(2)
-#define PARENT_CLK_NODE3	U(3)
-#define PARENT_CLK_NODE4	U(4)
-#define PARENT_CLK_EXTERNAL	U(5)
-#define PARENT_CLK_MIO0_MIO77	U(6)
+#define PARENT_CLK_SELF		(0U)
+#define PARENT_CLK_NODE1	(1U)
+#define PARENT_CLK_NODE2	(2U)
+#define PARENT_CLK_NODE3	(3U)
+#define PARENT_CLK_NODE4	(4U)
+#define PARENT_CLK_EXTERNAL	(5U)
+#define PARENT_CLK_MIO0_MIO77	(6U)
 
 #define CLK_SET_RATE_GATE	BIT(0) /* must be gated across rate change */
 #define CLK_SET_PARENT_GATE	BIT(1) /* must be gated across re-parent */
@@ -57,224 +57,224 @@
 
 //CLock Ids
 enum clock_id {
-	CLK_IOPLL,
-	CLK_RPLL,
-	CLK_APLL,
-	CLK_DPLL,
-	CLK_VPLL,
-	CLK_IOPLL_TO_FPD,
-	CLK_RPLL_TO_FPD,
-	CLK_APLL_TO_LPD,
-	CLK_DPLL_TO_LPD,
-	CLK_VPLL_TO_LPD,
-	CLK_ACPU,
-	CLK_ACPU_HALF,
-	CLK_DBG_FPD,
-	CLK_DBG_LPD,
-	CLK_DBG_TRACE,
-	CLK_DBG_TSTMP,
-	CLK_DP_VIDEO_REF,
-	CLK_DP_AUDIO_REF,
-	CLK_DP_STC_REF,
-	CLK_GDMA_REF,
-	CLK_DPDMA_REF,
-	CLK_DDR_REF,
-	CLK_SATA_REF,
-	CLK_PCIE_REF,
-	CLK_GPU_REF,
-	CLK_GPU_PP0_REF,
-	CLK_GPU_PP1_REF,
-	CLK_TOPSW_MAIN,
-	CLK_TOPSW_LSBUS,
-	CLK_GTGREF0_REF,
-	CLK_LPD_SWITCH,
-	CLK_LPD_LSBUS,
-	CLK_USB0_BUS_REF,
-	CLK_USB1_BUS_REF,
-	CLK_USB3_DUAL_REF,
-	CLK_USB0,
-	CLK_USB1,
-	CLK_CPU_R5,
-	CLK_CPU_R5_CORE,
-	CLK_CSU_SPB,
-	CLK_CSU_PLL,
-	CLK_PCAP,
-	CLK_IOU_SWITCH,
-	CLK_GEM_TSU_REF,
-	CLK_GEM_TSU,
-	CLK_GEM0_TX,
-	CLK_GEM1_TX,
-	CLK_GEM2_TX,
-	CLK_GEM3_TX,
-	CLK_GEM0_RX,
-	CLK_GEM1_RX,
-	CLK_GEM2_RX,
-	CLK_GEM3_RX,
-	CLK_QSPI_REF,
-	CLK_SDIO0_REF,
-	CLK_SDIO1_REF,
-	CLK_UART0_REF,
-	CLK_UART1_REF,
-	CLK_SPI0_REF,
-	CLK_SPI1_REF,
-	CLK_NAND_REF,
-	CLK_I2C0_REF,
-	CLK_I2C1_REF,
-	CLK_CAN0_REF,
-	CLK_CAN1_REF,
-	CLK_CAN0,
-	CLK_CAN1,
-	CLK_DLL_REF,
-	CLK_ADMA_REF,
-	CLK_TIMESTAMP_REF,
-	CLK_AMS_REF,
-	CLK_PL0_REF,
-	CLK_PL1_REF,
-	CLK_PL2_REF,
-	CLK_PL3_REF,
-	CLK_FPD_WDT,
-	CLK_IOPLL_INT,
-	CLK_IOPLL_PRE_SRC,
-	CLK_IOPLL_HALF,
-	CLK_IOPLL_INT_MUX,
-	CLK_IOPLL_POST_SRC,
-	CLK_RPLL_INT,
-	CLK_RPLL_PRE_SRC,
-	CLK_RPLL_HALF,
-	CLK_RPLL_INT_MUX,
-	CLK_RPLL_POST_SRC,
-	CLK_APLL_INT,
-	CLK_APLL_PRE_SRC,
-	CLK_APLL_HALF,
-	CLK_APLL_INT_MUX,
-	CLK_APLL_POST_SRC,
-	CLK_DPLL_INT,
-	CLK_DPLL_PRE_SRC,
-	CLK_DPLL_HALF,
-	CLK_DPLL_INT_MUX,
-	CLK_DPLL_POST_SRC,
-	CLK_VPLL_INT,
-	CLK_VPLL_PRE_SRC,
-	CLK_VPLL_HALF,
-	CLK_VPLL_INT_MUX,
-	CLK_VPLL_POST_SRC,
-	CLK_CAN0_MIO,
-	CLK_CAN1_MIO,
-	CLK_ACPU_FULL,
-	CLK_GEM0_REF,
-	CLK_GEM1_REF,
-	CLK_GEM2_REF,
-	CLK_GEM3_REF,
-	CLK_GEM0_REF_UNGATED,
-	CLK_GEM1_REF_UNGATED,
-	CLK_GEM2_REF_UNGATED,
-	CLK_GEM3_REF_UNGATED,
-	CLK_LPD_WDT,
-	END_OF_OUTPUT_CLKS,
+	CLK_IOPLL = (0U),
+	CLK_RPLL  = (1U),
+	CLK_APLL  = (2U),
+	CLK_DPLL  = (3U),
+	CLK_VPLL  = (4U),
+	CLK_IOPLL_TO_FPD = (5U),
+	CLK_RPLL_TO_FPD = (6U),
+	CLK_APLL_TO_LPD = (7U),
+	CLK_DPLL_TO_LPD = (8U),
+	CLK_VPLL_TO_LPD = (9U),
+	CLK_ACPU = (10U),
+	CLK_ACPU_HALF = (11U),
+	CLK_DBG_FPD = (12U),
+	CLK_DBG_LPD = (13U),
+	CLK_DBG_TRACE = (14U),
+	CLK_DBG_TSTMP = (15U),
+	CLK_DP_VIDEO_REF = (16U),
+	CLK_DP_AUDIO_REF = (17U),
+	CLK_DP_STC_REF = (18U),
+	CLK_GDMA_REF = (19U),
+	CLK_DPDMA_REF = (20U),
+	CLK_DDR_REF = (21U),
+	CLK_SATA_REF = (22U),
+	CLK_PCIE_REF = (23U),
+	CLK_GPU_REF = (24U),
+	CLK_GPU_PP0_REF = (25U),
+	CLK_GPU_PP1_REF = (26U),
+	CLK_TOPSW_MAIN = (27U),
+	CLK_TOPSW_LSBUS = (28U),
+	CLK_GTGREF0_REF = (29U),
+	CLK_LPD_SWITCH = (30U),
+	CLK_LPD_LSBUS = (31U),
+	CLK_USB0_BUS_REF = (32U),
+	CLK_USB1_BUS_REF = (33U),
+	CLK_USB3_DUAL_REF = (34U),
+	CLK_USB0 = (35U),
+	CLK_USB1 = (36U),
+	CLK_CPU_R5 = (37U),
+	CLK_CPU_R5_CORE = (38U),
+	CLK_CSU_SPB = (39U),
+	CLK_CSU_PLL = (40U),
+	CLK_PCAP = (41U),
+	CLK_IOU_SWITCH = (42U),
+	CLK_GEM_TSU_REF = (43U),
+	CLK_GEM_TSU = (44U),
+	CLK_GEM0_TX = (45U),
+	CLK_GEM1_TX = (46U),
+	CLK_GEM2_TX = (47U),
+	CLK_GEM3_TX = (48U),
+	CLK_GEM0_RX = (49U),
+	CLK_GEM1_RX = (50U),
+	CLK_GEM2_RX = (51U),
+	CLK_GEM3_RX = (52U),
+	CLK_QSPI_REF = (53U),
+	CLK_SDIO0_REF = (54U),
+	CLK_SDIO1_REF = (55U),
+	CLK_UART0_REF = (56U),
+	CLK_UART1_REF = (57U),
+	CLK_SPI0_REF = (58U),
+	CLK_SPI1_REF = (59U),
+	CLK_NAND_REF = (60U),
+	CLK_I2C0_REF = (61U),
+	CLK_I2C1_REF = (62U),
+	CLK_CAN0_REF = (63U),
+	CLK_CAN1_REF = (64U),
+	CLK_CAN0 = (65U),
+	CLK_CAN1 = (66U),
+	CLK_DLL_REF = (67U),
+	CLK_ADMA_REF = (68U),
+	CLK_TIMESTAMP_REF = (69U),
+	CLK_AMS_REF = (70U),
+	CLK_PL0_REF = (71U),
+	CLK_PL1_REF = (72U),
+	CLK_PL2_REF = (73U),
+	CLK_PL3_REF = (74U),
+	CLK_FPD_WDT = (75U),
+	CLK_IOPLL_INT = (76U),
+	CLK_IOPLL_PRE_SRC = (77U),
+	CLK_IOPLL_HALF = (78U),
+	CLK_IOPLL_INT_MUX = (79U),
+	CLK_IOPLL_POST_SRC = (80U),
+	CLK_RPLL_INT = (81U),
+	CLK_RPLL_PRE_SRC = (82U),
+	CLK_RPLL_HALF = (83U),
+	CLK_RPLL_INT_MUX = (84U),
+	CLK_RPLL_POST_SRC = (85U),
+	CLK_APLL_INT = (86U),
+	CLK_APLL_PRE_SRC = (87U),
+	CLK_APLL_HALF = (88U),
+	CLK_APLL_INT_MUX = (89U),
+	CLK_APLL_POST_SRC = (90U),
+	CLK_DPLL_INT = (91U),
+	CLK_DPLL_PRE_SRC = (92U),
+	CLK_DPLL_HALF = (93U),
+	CLK_DPLL_INT_MUX = (94U),
+	CLK_DPLL_POST_SRC = (95U),
+	CLK_VPLL_INT = (96U),
+	CLK_VPLL_PRE_SRC = (97U),
+	CLK_VPLL_HALF = (98U),
+	CLK_VPLL_INT_MUX = (99U),
+	CLK_VPLL_POST_SRC = (100U),
+	CLK_CAN0_MIO = (101U),
+	CLK_CAN1_MIO = (102U),
+	CLK_ACPU_FULL = (103U),
+	CLK_GEM0_REF = (104U),
+	CLK_GEM1_REF = (105U),
+	CLK_GEM2_REF = (106U),
+	CLK_GEM3_REF = (107U),
+	CLK_GEM0_REF_UNGATED = (108U),
+	CLK_GEM1_REF_UNGATED = (109U),
+	CLK_GEM2_REF_UNGATED = (110U),
+	CLK_GEM3_REF_UNGATED = (111U),
+	CLK_LPD_WDT = (112U),
+	END_OF_OUTPUT_CLKS = (113U),
 };
 
-#define CLK_MAX_OUTPUT_CLK (unsigned int)(END_OF_OUTPUT_CLKS)
+#define CLK_MAX_OUTPUT_CLK END_OF_OUTPUT_CLKS
 
 //External clock ids
 enum {
 	EXT_CLK_PSS_REF = END_OF_OUTPUT_CLKS,
-	EXT_CLK_VIDEO,
-	EXT_CLK_PSS_ALT_REF,
-	EXT_CLK_AUX_REF,
-	EXT_CLK_GT_CRX_REF,
-	EXT_CLK_SWDT0,
-	EXT_CLK_SWDT1,
-	EXT_CLK_GEM0_TX_EMIO,
-	EXT_CLK_GEM1_TX_EMIO,
-	EXT_CLK_GEM2_TX_EMIO,
-	EXT_CLK_GEM3_TX_EMIO,
-	EXT_CLK_GEM0_RX_EMIO,
-	EXT_CLK_GEM1_RX_EMIO,
-	EXT_CLK_GEM2_RX_EMIO,
-	EXT_CLK_GEM3_RX_EMIO,
-	EXT_CLK_MIO50_OR_MIO51,
-	EXT_CLK_MIO0,
-	EXT_CLK_MIO1,
-	EXT_CLK_MIO2,
-	EXT_CLK_MIO3,
-	EXT_CLK_MIO4,
-	EXT_CLK_MIO5,
-	EXT_CLK_MIO6,
-	EXT_CLK_MIO7,
-	EXT_CLK_MIO8,
-	EXT_CLK_MIO9,
-	EXT_CLK_MIO10,
-	EXT_CLK_MIO11,
-	EXT_CLK_MIO12,
-	EXT_CLK_MIO13,
-	EXT_CLK_MIO14,
-	EXT_CLK_MIO15,
-	EXT_CLK_MIO16,
-	EXT_CLK_MIO17,
-	EXT_CLK_MIO18,
-	EXT_CLK_MIO19,
-	EXT_CLK_MIO20,
-	EXT_CLK_MIO21,
-	EXT_CLK_MIO22,
-	EXT_CLK_MIO23,
-	EXT_CLK_MIO24,
-	EXT_CLK_MIO25,
-	EXT_CLK_MIO26,
-	EXT_CLK_MIO27,
-	EXT_CLK_MIO28,
-	EXT_CLK_MIO29,
-	EXT_CLK_MIO30,
-	EXT_CLK_MIO31,
-	EXT_CLK_MIO32,
-	EXT_CLK_MIO33,
-	EXT_CLK_MIO34,
-	EXT_CLK_MIO35,
-	EXT_CLK_MIO36,
-	EXT_CLK_MIO37,
-	EXT_CLK_MIO38,
-	EXT_CLK_MIO39,
-	EXT_CLK_MIO40,
-	EXT_CLK_MIO41,
-	EXT_CLK_MIO42,
-	EXT_CLK_MIO43,
-	EXT_CLK_MIO44,
-	EXT_CLK_MIO45,
-	EXT_CLK_MIO46,
-	EXT_CLK_MIO47,
-	EXT_CLK_MIO48,
-	EXT_CLK_MIO49,
-	EXT_CLK_MIO50,
-	EXT_CLK_MIO51,
-	EXT_CLK_MIO52,
-	EXT_CLK_MIO53,
-	EXT_CLK_MIO54,
-	EXT_CLK_MIO55,
-	EXT_CLK_MIO56,
-	EXT_CLK_MIO57,
-	EXT_CLK_MIO58,
-	EXT_CLK_MIO59,
-	EXT_CLK_MIO60,
-	EXT_CLK_MIO61,
-	EXT_CLK_MIO62,
-	EXT_CLK_MIO63,
-	EXT_CLK_MIO64,
-	EXT_CLK_MIO65,
-	EXT_CLK_MIO66,
-	EXT_CLK_MIO67,
-	EXT_CLK_MIO68,
-	EXT_CLK_MIO69,
-	EXT_CLK_MIO70,
-	EXT_CLK_MIO71,
-	EXT_CLK_MIO72,
-	EXT_CLK_MIO73,
-	EXT_CLK_MIO74,
-	EXT_CLK_MIO75,
-	EXT_CLK_MIO76,
-	EXT_CLK_MIO77,
-	END_OF_CLKS,
+	EXT_CLK_VIDEO = (114U),
+	EXT_CLK_PSS_ALT_REF = (115U),
+	EXT_CLK_AUX_REF = (116U),
+	EXT_CLK_GT_CRX_REF = (117U),
+	EXT_CLK_SWDT0 = (118U),
+	EXT_CLK_SWDT1 = (119U),
+	EXT_CLK_GEM0_TX_EMIO = (120U),
+	EXT_CLK_GEM1_TX_EMIO = (121U),
+	EXT_CLK_GEM2_TX_EMIO = (122U),
+	EXT_CLK_GEM3_TX_EMIO = (123U),
+	EXT_CLK_GEM0_RX_EMIO = (124U),
+	EXT_CLK_GEM1_RX_EMIO = (125U),
+	EXT_CLK_GEM2_RX_EMIO = (126U),
+	EXT_CLK_GEM3_RX_EMIO = (127U),
+	EXT_CLK_MIO50_OR_MIO51 = (128U),
+	EXT_CLK_MIO0 = (129U),
+	EXT_CLK_MIO1 = (130U),
+	EXT_CLK_MIO2 = (131U),
+	EXT_CLK_MIO3 = (132U),
+	EXT_CLK_MIO4 = (133U),
+	EXT_CLK_MIO5 = (134U),
+	EXT_CLK_MIO6 = (135U),
+	EXT_CLK_MIO7 = (136U),
+	EXT_CLK_MIO8 = (137U),
+	EXT_CLK_MIO9 = (138U),
+	EXT_CLK_MIO10 = (139U),
+	EXT_CLK_MIO11 = (140U),
+	EXT_CLK_MIO12 = (141U),
+	EXT_CLK_MIO13 = (142U),
+	EXT_CLK_MIO14 = (143U),
+	EXT_CLK_MIO15 = (144U),
+	EXT_CLK_MIO16 = (145U),
+	EXT_CLK_MIO17 = (146U),
+	EXT_CLK_MIO18 = (147U),
+	EXT_CLK_MIO19 = (148U),
+	EXT_CLK_MIO20 = (149U),
+	EXT_CLK_MIO21 = (150U),
+	EXT_CLK_MIO22 = (151U),
+	EXT_CLK_MIO23 = (152U),
+	EXT_CLK_MIO24 = (153U),
+	EXT_CLK_MIO25 = (154U),
+	EXT_CLK_MIO26 = (155U),
+	EXT_CLK_MIO27 = (156U),
+	EXT_CLK_MIO28 = (157U),
+	EXT_CLK_MIO29 = (158U),
+	EXT_CLK_MIO30 = (159U),
+	EXT_CLK_MIO31 = (160U),
+	EXT_CLK_MIO32 = (161U),
+	EXT_CLK_MIO33 = (162U),
+	EXT_CLK_MIO34 = (163U),
+	EXT_CLK_MIO35 = (164U),
+	EXT_CLK_MIO36 = (165U),
+	EXT_CLK_MIO37 = (166U),
+	EXT_CLK_MIO38 = (167U),
+	EXT_CLK_MIO39 = (168U),
+	EXT_CLK_MIO40 = (169U),
+	EXT_CLK_MIO41 = (170U),
+	EXT_CLK_MIO42 = (171U),
+	EXT_CLK_MIO43 = (172U),
+	EXT_CLK_MIO44 = (173U),
+	EXT_CLK_MIO45 = (174U),
+	EXT_CLK_MIO46 = (175U),
+	EXT_CLK_MIO47 = (176U),
+	EXT_CLK_MIO48 = (177U),
+	EXT_CLK_MIO49 = (178U),
+	EXT_CLK_MIO50 = (179U),
+	EXT_CLK_MIO51 = (180U),
+	EXT_CLK_MIO52 = (181U),
+	EXT_CLK_MIO53 = (182U),
+	EXT_CLK_MIO54 = (183U),
+	EXT_CLK_MIO55 = (184U),
+	EXT_CLK_MIO56 = (185U),
+	EXT_CLK_MIO57 = (186U),
+	EXT_CLK_MIO58 = (187U),
+	EXT_CLK_MIO59 = (188U),
+	EXT_CLK_MIO60 = (189U),
+	EXT_CLK_MIO61 = (190U),
+	EXT_CLK_MIO62 = (191U),
+	EXT_CLK_MIO63 = (192U),
+	EXT_CLK_MIO64 = (193U),
+	EXT_CLK_MIO65 = (194U),
+	EXT_CLK_MIO66 = (195U),
+	EXT_CLK_MIO67 = (196U),
+	EXT_CLK_MIO68 = (197U),
+	EXT_CLK_MIO69 = (198U),
+	EXT_CLK_MIO70 = (199U),
+	EXT_CLK_MIO71 = (200U),
+	EXT_CLK_MIO72 = (201U),
+	EXT_CLK_MIO73 = (202U),
+	EXT_CLK_MIO74 = (203U),
+	EXT_CLK_MIO75 = (204U),
+	EXT_CLK_MIO76 = (205U),
+	EXT_CLK_MIO77 = (206U),
+	END_OF_CLKS = (207U),
 };
 
-#define CLK_MAX (unsigned int)(END_OF_CLKS)
+#define CLK_MAX END_OF_CLKS
 
 //CLock types
 #define CLK_TYPE_OUTPUT 0U
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index 48e1b8d..c0bfd51 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -759,7 +759,7 @@
 		}
 		ret = check_api_dependency(ioctl_id);
 		if (ret == PM_RET_SUCCESS) {
-			bit_mask[ioctl_id / 32] |= BIT(ioctl_id % 32);
+			bit_mask[ioctl_id / 32U] |= BIT(ioctl_id % 32U);
 		}
 	}
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 0192f81..8f37341 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -27,7 +27,7 @@
 };
 
 /* Max groups for one pin */
-#define MAX_PIN_GROUPS	U(13)
+#define MAX_PIN_GROUPS	(13U)
 
 struct zynqmp_pin_group {
 	uint16_t (*groups)[];
@@ -2037,7 +2037,7 @@
 {
 	uint16_t grps;
 	uint16_t end_of_grp_offset;
-	unsigned int i;
+	uint16_t i;
 
 	if (fid >= MAX_FUNCTION) {
 		return PM_RET_ERROR_ARGS;
@@ -2048,7 +2048,7 @@
 	grps = pinctrl_functions[fid].group_base;
 	end_of_grp_offset = grps + pinctrl_functions[fid].group_size;
 
-	for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
+	for (i = 0U; i < NUM_GROUPS_PER_RESP; i++) {
 		if ((grps + index + i) >= end_of_grp_offset) {
 			break;
 		}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
index b3159c2..5c4cb45 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
@@ -13,76 +13,76 @@
 
 #include "pm_common.h"
 
-#define FUNCTION_NAME_LEN		U(16)
-#define GROUPS_PAYLOAD_LEN		U(12)
-#define NUM_GROUPS_PER_RESP		U(6)
+#define FUNCTION_NAME_LEN		(16U)
+#define GROUPS_PAYLOAD_LEN		(12U)
+#define NUM_GROUPS_PER_RESP		(6U)
 #define END_OF_FUNCTION			"END_OF_FUNCTION"
 #define END_OF_GROUPS			-1
 #define PINCTRL_GRP_RESERVED		-2
 
 //pinctrl function ids
 enum {
-	PINCTRL_FUNC_CAN0,
-	PINCTRL_FUNC_CAN1,
-	PINCTRL_FUNC_ETHERNET0,
-	PINCTRL_FUNC_ETHERNET1,
-	PINCTRL_FUNC_ETHERNET2,
-	PINCTRL_FUNC_ETHERNET3,
-	PINCTRL_FUNC_GEMTSU0,
-	PINCTRL_FUNC_GPIO0,
-	PINCTRL_FUNC_I2C0,
-	PINCTRL_FUNC_I2C1,
-	PINCTRL_FUNC_MDIO0,
-	PINCTRL_FUNC_MDIO1,
-	PINCTRL_FUNC_MDIO2,
-	PINCTRL_FUNC_MDIO3,
-	PINCTRL_FUNC_QSPI0,
-	PINCTRL_FUNC_QSPI_FBCLK,
-	PINCTRL_FUNC_QSPI_SS,
-	PINCTRL_FUNC_SPI0,
-	PINCTRL_FUNC_SPI1,
-	PINCTRL_FUNC_SPI0_SS,
-	PINCTRL_FUNC_SPI1_SS,
-	PINCTRL_FUNC_SDIO0,
-	PINCTRL_FUNC_SDIO0_PC,
-	PINCTRL_FUNC_SDIO0_CD,
-	PINCTRL_FUNC_SDIO0_WP,
-	PINCTRL_FUNC_SDIO1,
-	PINCTRL_FUNC_SDIO1_PC,
-	PINCTRL_FUNC_SDIO1_CD,
-	PINCTRL_FUNC_SDIO1_WP,
-	PINCTRL_FUNC_NAND0,
-	PINCTRL_FUNC_NAND0_CE,
-	PINCTRL_FUNC_NAND0_RB,
-	PINCTRL_FUNC_NAND0_DQS,
-	PINCTRL_FUNC_TTC0_CLK,
-	PINCTRL_FUNC_TTC0_WAV,
-	PINCTRL_FUNC_TTC1_CLK,
-	PINCTRL_FUNC_TTC1_WAV,
-	PINCTRL_FUNC_TTC2_CLK,
-	PINCTRL_FUNC_TTC2_WAV,
-	PINCTRL_FUNC_TTC3_CLK,
-	PINCTRL_FUNC_TTC3_WAV,
-	PINCTRL_FUNC_UART0,
-	PINCTRL_FUNC_UART1,
-	PINCTRL_FUNC_USB0,
-	PINCTRL_FUNC_USB1,
-	PINCTRL_FUNC_SWDT0_CLK,
-	PINCTRL_FUNC_SWDT0_RST,
-	PINCTRL_FUNC_SWDT1_CLK,
-	PINCTRL_FUNC_SWDT1_RST,
-	PINCTRL_FUNC_PMU0,
-	PINCTRL_FUNC_PCIE0,
-	PINCTRL_FUNC_CSU0,
-	PINCTRL_FUNC_DPAUX0,
-	PINCTRL_FUNC_PJTAG0,
-	PINCTRL_FUNC_TRACE0,
-	PINCTRL_FUNC_TRACE0_CLK,
-	PINCTRL_FUNC_TESTSCAN0,
-	END_FUNCTION,
+	PINCTRL_FUNC_CAN0 = (0U),
+	PINCTRL_FUNC_CAN1 = (1U),
+	PINCTRL_FUNC_ETHERNET0 = (2U),
+	PINCTRL_FUNC_ETHERNET1 = (3U),
+	PINCTRL_FUNC_ETHERNET2 = (4U),
+	PINCTRL_FUNC_ETHERNET3 = (5U),
+	PINCTRL_FUNC_GEMTSU0 = (6U),
+	PINCTRL_FUNC_GPIO0 = (7U),
+	PINCTRL_FUNC_I2C0 = (8U),
+	PINCTRL_FUNC_I2C1 = (9U),
+	PINCTRL_FUNC_MDIO0 = (10U),
+	PINCTRL_FUNC_MDIO1 = (11U),
+	PINCTRL_FUNC_MDIO2 = (12U),
+	PINCTRL_FUNC_MDIO3 = (13U),
+	PINCTRL_FUNC_QSPI0 = (14U),
+	PINCTRL_FUNC_QSPI_FBCLK = (15U),
+	PINCTRL_FUNC_QSPI_SS = (16U),
+	PINCTRL_FUNC_SPI0 = (17U),
+	PINCTRL_FUNC_SPI1 = (18U),
+	PINCTRL_FUNC_SPI0_SS = (19U),
+	PINCTRL_FUNC_SPI1_SS = (20U),
+	PINCTRL_FUNC_SDIO0 = (21U),
+	PINCTRL_FUNC_SDIO0_PC = (22U),
+	PINCTRL_FUNC_SDIO0_CD = (23U),
+	PINCTRL_FUNC_SDIO0_WP = (24U),
+	PINCTRL_FUNC_SDIO1 = (25U),
+	PINCTRL_FUNC_SDIO1_PC = (26U),
+	PINCTRL_FUNC_SDIO1_CD = (27U),
+	PINCTRL_FUNC_SDIO1_WP = (28U),
+	PINCTRL_FUNC_NAND0 = (29U),
+	PINCTRL_FUNC_NAND0_CE = (30U),
+	PINCTRL_FUNC_NAND0_RB = (31U),
+	PINCTRL_FUNC_NAND0_DQS = (32U),
+	PINCTRL_FUNC_TTC0_CLK = (33U),
+	PINCTRL_FUNC_TTC0_WAV = (34U),
+	PINCTRL_FUNC_TTC1_CLK = (35U),
+	PINCTRL_FUNC_TTC1_WAV = (36U),
+	PINCTRL_FUNC_TTC2_CLK = (37U),
+	PINCTRL_FUNC_TTC2_WAV = (38U),
+	PINCTRL_FUNC_TTC3_CLK = (39U),
+	PINCTRL_FUNC_TTC3_WAV = (40U),
+	PINCTRL_FUNC_UART0 = (41U),
+	PINCTRL_FUNC_UART1 = (42U),
+	PINCTRL_FUNC_USB0 = (43U),
+	PINCTRL_FUNC_USB1 = (44U),
+	PINCTRL_FUNC_SWDT0_CLK = (45U),
+	PINCTRL_FUNC_SWDT0_RST = (46U),
+	PINCTRL_FUNC_SWDT1_CLK = (47U),
+	PINCTRL_FUNC_SWDT1_RST = (48U),
+	PINCTRL_FUNC_PMU0 = (49U),
+	PINCTRL_FUNC_PCIE0 = (50U),
+	PINCTRL_FUNC_CSU0 = (51U),
+	PINCTRL_FUNC_DPAUX0 = (52U),
+	PINCTRL_FUNC_PJTAG0 = (53U),
+	PINCTRL_FUNC_TRACE0 = (54U),
+	PINCTRL_FUNC_TRACE0_CLK = (55U),
+	PINCTRL_FUNC_TESTSCAN0 = (56U),
+	END_FUNCTION = (57U),
 };
 
-#define MAX_FUNCTION (unsigned int)(END_FUNCTION)
+#define MAX_FUNCTION END_FUNCTION
 
 // pinctrl pin numbers
 enum {
@@ -164,10 +164,10 @@
 	PINCTRL_PIN_75,
 	PINCTRL_PIN_76,
 	PINCTRL_PIN_77,
-	END_PINS,
+	END_PINS = (78U),
 };
 
-#define MAX_PIN (unsigned int)(END_PINS)
+#define MAX_PIN END_PINS
 
 // pinctrl group ids
 enum  {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index d3e9a34..9ba9475 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -126,7 +126,7 @@
 				    uint32_t address_high,
 				    uint32_t size,
 				    uint32_t flags);
-unsigned int pm_get_shutdown_scope(void);
+uint32_t pm_get_shutdown_scope(void);
 void pm_get_callbackdata(uint32_t *data, size_t count);
 enum pm_ret_status pm_ioctl(enum pm_node_id nid,
 			    uint32_t ioctl_id,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 34b931e..a853e38 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -25,12 +25,12 @@
 #include "pm_client.h"
 #include "pm_ipi.h"
 
-#define IRQ_MAX		84
-#define NUM_GICD_ISENABLER	((IRQ_MAX >> 5) + 1)
-#define UNDEFINED_CPUID		(~0)
+#define IRQ_MAX		84U
+#define NUM_GICD_ISENABLER	((IRQ_MAX >> 5U) + 1U)
+#define UNDEFINED_CPUID		(~0U)
 
-#define PM_SUSPEND_MODE_STD		0
-#define PM_SUSPEND_MODE_POWER_OFF	1
+#define PM_SUSPEND_MODE_STD		0U
+#define PM_SUSPEND_MODE_POWER_OFF	1U
 
 DEFINE_BAKERY_LOCK(pm_client_secure_lock);
 
@@ -69,7 +69,7 @@
 };
 
 /* Interrupt to PM node ID map */
-static enum pm_node_id irq_node_map[IRQ_MAX + 1] = {
+static enum pm_node_id irq_node_map[IRQ_MAX + 1U] = {
 	NODE_UNKNOWN,
 	NODE_UNKNOWN,
 	NODE_UNKNOWN,
@@ -177,13 +177,13 @@
 {
 	uint32_t reg_num;
 	uint8_t pm_wakeup_nodes_set[NODE_MAX];
-	uintptr_t isenabler1 = BASE_GICD_BASE + GICD_ISENABLER + 4;
+	uintptr_t isenabler1 = BASE_GICD_BASE + GICD_ISENABLER + 4U;
 
 	/* In case of power-off suspend, only NODE_EXTERN must be set */
 	if (suspend_mode == PM_SUSPEND_MODE_POWER_OFF) {
 		enum pm_ret_status ret;
 
-		ret = pm_set_wakeup_source(NODE_APU, NODE_EXTERN, 1);
+		ret = pm_set_wakeup_source(NODE_APU, NODE_EXTERN, 1U);
 		/**
 		 * If NODE_EXTERN could not be set as wake source, proceed with
 		 * standard suspend (no one will wake the system otherwise)
@@ -195,11 +195,11 @@
 
 	zeromem(&pm_wakeup_nodes_set, sizeof(pm_wakeup_nodes_set));
 
-	for (reg_num = 0; reg_num < NUM_GICD_ISENABLER; reg_num++) {
+	for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) {
 		uint32_t base_irq = reg_num << ISENABLER_SHIFT;
-		uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
+		uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2U));
 
-		if (!reg) {
+		if (reg == 0) {
 			continue;
 		}
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index bf5ecfe..e335b94 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -256,19 +256,19 @@
  * @PM_RET_ERROR_NODE_USED:	node is already in use
  */
 enum pm_ret_status {
-	PM_RET_SUCCESS,
-	PM_RET_ERROR_ARGS = 1,
-	PM_RET_ERROR_NOTSUPPORTED = 4,
-	PM_RET_ERROR_NOT_ENABLED = 29,
-	PM_RET_ERROR_INTERNAL = 2000,
-	PM_RET_ERROR_CONFLICT = 2001,
-	PM_RET_ERROR_ACCESS = 2002,
-	PM_RET_ERROR_INVALID_NODE = 2003,
-	PM_RET_ERROR_DOUBLE_REQ = 2004,
-	PM_RET_ERROR_ABORT_SUSPEND = 2005,
-	PM_RET_ERROR_TIMEOUT = 2006,
-	PM_RET_ERROR_NODE_USED = 2007,
-	PM_RET_ERROR_NO_FEATURE = 2008
+	PM_RET_SUCCESS = (0U),
+	PM_RET_ERROR_ARGS = (1U),
+	PM_RET_ERROR_NOTSUPPORTED = (4U),
+	PM_RET_ERROR_NOT_ENABLED = (29U),
+	PM_RET_ERROR_INTERNAL = (2000U),
+	PM_RET_ERROR_CONFLICT = (2001U),
+	PM_RET_ERROR_ACCESS = (2002U),
+	PM_RET_ERROR_INVALID_NODE = (2003U),
+	PM_RET_ERROR_DOUBLE_REQ = (2004U),
+	PM_RET_ERROR_ABORT_SUSPEND = (2005U),
+	PM_RET_ERROR_TIMEOUT = (2006U),
+	PM_RET_ERROR_NODE_USED = (2007U),
+	PM_RET_ERROR_NO_FEATURE = (2008U)
 };
 
 /**
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 82da57c..b91878e 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -267,7 +267,7 @@
 	uint32_t api_id;
 
 	/* Handle case where PM wasn't initialized properly */
-	if (!pm_up)
+	if (pm_up == 0)
 		SMC_RET1(handle, SMC_UNK);
 
 	pm_arg[0] = (uint32_t)x1;
@@ -293,10 +293,10 @@
 	case PM_REQ_WAKEUP:
 	{
 		/* Use address flag is encoded in the 1st bit of the low-word */
-		uint32_t set_addr = pm_arg[1] & 0x1;
-		uint64_t address = (uint64_t)pm_arg[2] << 32;
+		uint32_t set_addr = pm_arg[1] & 0x1U;
+		uint64_t address = (uint64_t)pm_arg[2] << 32U;
 
-		address |= pm_arg[1] & (~0x1);
+		address |= pm_arg[1] & (~0x1U);
 		ret = pm_req_wakeup(pm_arg[0], set_addr, address,
 				    pm_arg[3]);
 		SMC_RET1(handle, (uint64_t)ret);
@@ -330,7 +330,7 @@
 	case PM_GET_API_VERSION:
 		/* Check is PM API version already verified */
 		if (pm_ctx.api_version >= PM_VERSION) {
-			if (!ipi_irq_flag) {
+			if (ipi_irq_flag == 0U) {
 				/*
 				 * Enable IPI IRQ
 				 * assume the rich OS is OK to handle callback IRQs now.
@@ -338,7 +338,7 @@
 				 * the GIC.
 				 */
 				pm_ipi_irq_enable(primary_proc);
-				ipi_irq_flag = 1;
+				ipi_irq_flag = 1U;
 			}
 			SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
 				 ((uint64_t)pm_ctx.api_version << 32));
@@ -439,12 +439,12 @@
 		uint32_t value;
 
 		ret = pm_clock_getparent(pm_arg[0], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case PM_GET_TRUSTZONE_VERSION:
 		SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
-			 ((uint64_t)ZYNQMP_TZ_VERSION << 32));
+			 ((uint64_t)ZYNQMP_TZ_VERSION << 32U));
 
 	case PM_SET_SUSPEND_MODE:
 		ret = pm_set_suspend_mode(pm_arg[0]);
@@ -464,7 +464,7 @@
 	{
 		ret = pm_secure_image(pm_arg[0], pm_arg[1], pm_arg[2],
 				      pm_arg[3], &result[0]);
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32),
+		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
 			 result[1]);
 	}
 
@@ -474,7 +474,7 @@
 
 		ret = pm_fpga_read(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
 				   &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case PM_SECURE_AES:
@@ -482,7 +482,7 @@
 		uint32_t value;
 
 		ret = pm_aes_engine(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case PM_PLL_SET_PARAMETER:
@@ -494,7 +494,7 @@
 		uint32_t value;
 
 		ret = pm_pll_get_parameter(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32));
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32U));
 	}
 
 	case PM_PLL_SET_MODE:
@@ -506,7 +506,7 @@
 		uint32_t mode;
 
 		ret = pm_pll_get_mode(pm_arg[0], &mode);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32));
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32U));
 	}
 
 	case PM_REGISTER_ACCESS:
@@ -515,7 +515,7 @@
 
 		ret = pm_register_access(pm_arg[0], pm_arg[1], pm_arg[2],
 					 pm_arg[3], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case PM_EFUSE_ACCESS:
@@ -525,12 +525,12 @@
 #if defined(ZYNQMP_SECURE_EFUSES)
 		if (is_caller_non_secure(flags)) {
 			SMC_RET1(handle,
-				 (((uint64_t)PM_RET_ERROR_NOT_ENABLED) << 32) |
+				 (((uint64_t)PM_RET_ERROR_NOT_ENABLED) << 32U) |
 				 (uint64_t)PM_RET_ERROR_ACCESS);
 		}
 #endif
 		ret = pm_efuse_access(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case PM_FPGA_GET_VERSION:
@@ -541,8 +541,8 @@
 		PM_PACK_PAYLOAD5(payload, smc_fid & FUNCID_NUM_MASK,
 				 pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
 		ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, 3U);
-		SMC_RET2(handle, (uint64_t)ret | (uint64_t)ret_payload[0] << 32,
-			 (uint64_t)ret_payload[1] | (uint64_t)ret_payload[2] << 32);
+		SMC_RET2(handle, (uint64_t)ret | (uint64_t)ret_payload[0] << 32U,
+			 (uint64_t)ret_payload[1] | (uint64_t)ret_payload[2] << 32U);
 	}
 
 	case PM_FEATURE_CHECK:
@@ -552,8 +552,8 @@
 
 		ret = pm_feature_check(pm_arg[0], &version, bit_mask,
 				       ARRAY_SIZE(bit_mask));
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)version << 32),
-			 (uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32));
+		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)version << 32U),
+			 (uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32U));
 	}
 
 	default:
@@ -562,8 +562,8 @@
 				 pm_arg[2], pm_arg[3], pm_arg[4]);
 		ret = pm_ipi_send_sync(primary_proc, payload, result,
 				       PAYLOAD_ARG_CNT);
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32),
-			 (uint64_t)result[1] | ((uint64_t)result[2] << 32));
+		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
+			 (uint64_t)result[1] | ((uint64_t)result[2] << 32U));
 	}
 }
 
@@ -595,7 +595,7 @@
 		uint32_t value;
 
 		ret = em_set_action(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case EM_REMOVE_ACTION:
@@ -603,7 +603,7 @@
 		uint32_t value;
 
 		ret = em_remove_action(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	case EM_SEND_ERRORS:
@@ -611,7 +611,7 @@
 		uint32_t value;
 
 		ret = em_send_errors(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
 	}
 
 	default:
diff --git a/services/spd/pncd/pncd.mk b/services/spd/pncd/pncd.mk
new file mode 100644
index 0000000..0f8eb25
--- /dev/null
+++ b/services/spd/pncd/pncd.mk
@@ -0,0 +1,24 @@
+# Copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+PNCD_DIR		:=	services/spd/pncd
+SPD_INCLUDES		:=	-Iinclude/bl32/pnc
+SPD_INCLUDES		+=	-Iinclude/common/
+
+SPD_SOURCES		:=	services/spd/pncd/pncd_common.c		\
+				services/spd/pncd/pncd_helpers.S	\
+				services/spd/pncd/pncd_main.c
+
+NEED_BL32		:=	yes
+
+# The following constants need to be defined:
+#   - SPD_PNCD_NS_IRQ: IRQ number used to notify NS world when SMC_ACTION_FROM_S is received
+#   - SPD_PNCD_S_IRQ: IRQ number used to notify S world when SMC_ACTION_FROM_NS is received
+$(eval $(call assert_numerics, SPD_PNCD_NS_IRQ SPD_PNCD_S_IRQ))
+
+$(eval $(call add_defines,\
+    $(sort \
+        SPD_PNCD_NS_IRQ \
+        SPD_PNCD_S_IRQ \
+)))
diff --git a/services/spd/pncd/pncd_common.c b/services/spd/pncd/pncd_common.c
new file mode 100644
index 0000000..6fdb629
--- /dev/null
+++ b/services/spd/pncd/pncd_common.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+
+#include "pncd_private.h"
+
+/*******************************************************************************
+ * Given a secure payload entrypoint info pointer, entry point PC & pointer to a
+ * context data structure, this function will initialize pnc context and entry
+ * point info for the secure payload
+ ******************************************************************************/
+void pncd_init_pnc_ep_state(struct entry_point_info *pnc_entry_point,
+				uint64_t pc,
+				pnc_context_t *pnc_ctx)
+{
+	uint32_t ep_attr;
+
+	/* Passing a NULL context is a critical programming error */
+	assert(pnc_ctx);
+	assert(pnc_entry_point);
+	assert(pc);
+
+	/* Associate this context with the current cpu */
+	pnc_ctx->mpidr = read_mpidr();
+
+	cm_set_context(&pnc_ctx->cpu_ctx, SECURE);
+
+	/* initialise an entrypoint to set up the CPU context */
+	ep_attr = SECURE | EP_ST_ENABLE;
+	if (read_sctlr_el3() & SCTLR_EE_BIT) {
+		ep_attr |= EP_EE_BIG;
+	}
+	SET_PARAM_HEAD(pnc_entry_point, PARAM_EP, VERSION_1, ep_attr);
+
+	pnc_entry_point->pc = pc;
+	pnc_entry_point->spsr = SPSR_64(MODE_EL1,
+					MODE_SP_ELX,
+					DISABLE_ALL_EXCEPTIONS);
+	memset(&pnc_entry_point->args, 0, sizeof(pnc_entry_point->args));
+}
+
+/*******************************************************************************
+ * This function takes an SP context pointer and:
+ * 1. Applies the S-EL1 system register context from pnc_ctx->cpu_ctx.
+ * 2. Saves the current C runtime state (callee saved registers) on the stack
+ *    frame and saves a reference to this state.
+ * 3. Calls el3_exit() so that the EL3 system and general purpose registers
+ *    from the pnc_ctx->cpu_ctx are used to enter the secure payload image.
+ ******************************************************************************/
+uint64_t pncd_synchronous_sp_entry(pnc_context_t *pnc_ctx)
+{
+	assert(pnc_ctx != NULL);
+	assert(pnc_ctx->c_rt_ctx == 0U);
+
+	/* Apply the Secure EL1 system register context and switch to it */
+	assert(cm_get_context(SECURE) == &pnc_ctx->cpu_ctx);
+	cm_el1_sysregs_context_restore(SECURE);
+#if CTX_INCLUDE_FPREGS
+	fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
+#endif
+	cm_set_next_eret_context(SECURE);
+
+	return pncd_enter_sp(&pnc_ctx->c_rt_ctx);
+}
+
+
+/*******************************************************************************
+ * This function takes an SP context pointer and:
+ * 1. Saves the S-EL1 system register context tp pnc_ctx->cpu_ctx.
+ * 2. Restores the current C runtime state (callee saved registers) from the
+ *    stack frame using the reference to this state saved in pncd_enter_sp().
+ * 3. It does not need to save any general purpose or EL3 system register state
+ *    as the generic smc entry routine should have saved those.
+ ******************************************************************************/
+void pncd_synchronous_sp_exit(pnc_context_t *pnc_ctx, uint64_t ret)
+{
+	assert(pnc_ctx != NULL);
+	/* Save the Secure EL1 system register context */
+	assert(cm_get_context(SECURE) == &pnc_ctx->cpu_ctx);
+	cm_el1_sysregs_context_save(SECURE);
+#if CTX_INCLUDE_FPREGS
+	fpregs_context_save(get_fpregs_ctx(cm_get_context(SECURE)));
+#endif
+
+	assert(pnc_ctx->c_rt_ctx != 0);
+	pncd_exit_sp(pnc_ctx->c_rt_ctx, ret);
+
+	/* Should never reach here */
+	panic();
+}
diff --git a/services/spd/pncd/pncd_helpers.S b/services/spd/pncd/pncd_helpers.S
new file mode 100644
index 0000000..736b30f
--- /dev/null
+++ b/services/spd/pncd/pncd_helpers.S
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include "pncd_private.h"
+
+	.global	pncd_enter_sp
+	/* ---------------------------------------------
+	 * This function is called with SP_EL0 as stack.
+	 * Here we stash our EL3 callee-saved registers
+	 * on to the stack as a part of saving the C
+	 * runtime and enter the secure payload.
+	 * 'x0' contains a pointer to the memory where
+	 * the address of the C runtime context is to be
+	 * saved.
+	 * ---------------------------------------------
+	 */
+func pncd_enter_sp
+	/* Make space for the registers that we're going to save */
+	mov	x3, sp
+	str	x3, [x0, #0]
+	sub	sp, sp, #PNCD_C_RT_CTX_SIZE
+
+	/* Save callee-saved registers on to the stack */
+	stp	x19, x20, [sp, #PNCD_C_RT_CTX_X19]
+	stp	x21, x22, [sp, #PNCD_C_RT_CTX_X21]
+	stp	x23, x24, [sp, #PNCD_C_RT_CTX_X23]
+	stp	x25, x26, [sp, #PNCD_C_RT_CTX_X25]
+	stp	x27, x28, [sp, #PNCD_C_RT_CTX_X27]
+	stp	x29, x30, [sp, #PNCD_C_RT_CTX_X29]
+
+	/* ---------------------------------------------
+	 * Everything is setup now. el3_exit() will
+	 * use the secure context to restore to the
+	 * general purpose and EL3 system registers to
+	 * ERET into the secure payload.
+	 * ---------------------------------------------
+	 */
+	b	el3_exit
+endfunc pncd_enter_sp
+
+	/* ---------------------------------------------
+	 * This function is called 'x0' pointing to a C
+	 * runtime context saved in pncd_enter_sp(). It
+	 * restores the saved registers and jumps to
+	 * that runtime with 'x0' as the new sp. This
+	 * destroys the C runtime context that had been
+	 * built on the stack below the saved context by
+	 * the caller. Later the second parameter 'x1'
+	 * is passed as return value to the caller
+	 * ---------------------------------------------
+	 */
+	.global pncd_exit_sp
+func pncd_exit_sp
+	/* Restore the previous stack */
+	mov	sp, x0
+
+	/* Restore callee-saved registers on to the stack */
+	ldp	x19, x20, [x0, #(PNCD_C_RT_CTX_X19 - PNCD_C_RT_CTX_SIZE)]
+	ldp	x21, x22, [x0, #(PNCD_C_RT_CTX_X21 - PNCD_C_RT_CTX_SIZE)]
+	ldp	x23, x24, [x0, #(PNCD_C_RT_CTX_X23 - PNCD_C_RT_CTX_SIZE)]
+	ldp	x25, x26, [x0, #(PNCD_C_RT_CTX_X25 - PNCD_C_RT_CTX_SIZE)]
+	ldp	x27, x28, [x0, #(PNCD_C_RT_CTX_X27 - PNCD_C_RT_CTX_SIZE)]
+	ldp	x29, x30, [x0, #(PNCD_C_RT_CTX_X29 - PNCD_C_RT_CTX_SIZE)]
+
+	/* ---------------------------------------------
+	 * This should take us back to the instruction
+	 * after the call to the last pncd_enter_sp().
+	 * Place the second parameter to x0 so that the
+	 * caller will see it as a return value from the
+	 * original entry call
+	 * ---------------------------------------------
+	 */
+	mov	x0, x1
+	ret
+endfunc pncd_exit_sp
diff --git a/services/spd/pncd/pncd_main.c b/services/spd/pncd/pncd_main.c
new file mode 100644
index 0000000..99c4aa1
--- /dev/null
+++ b/services/spd/pncd/pncd_main.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*******************************************************************************
+ * This is the Secure Payload Dispatcher (SPD). The dispatcher is meant to be a
+ * plug-in component to the Secure Monitor, registered as a runtime service. The
+ * SPD is expected to be a functional extension of the Secure Payload (SP) that
+ * executes in Secure EL1. The Secure Monitor will delegate all SMCs targeting
+ * the Trusted OS/Applications range to the dispatcher. The SPD will either
+ * handle the request locally or delegate it to the Secure Payload. It is also
+ * responsible for initialising and maintaining communication with the SP.
+ ******************************************************************************/
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <bl31/interrupt_mgmt.h>
+#include <bl_common.h>
+#include <common/debug.h>
+#include <common/ep_info.h>
+#include <drivers/arm/gic_common.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+#include <pnc.h>
+#include "pncd_private.h"
+#include <runtime_svc.h>
+#include <tools_share/uuid.h>
+
+/*******************************************************************************
+ * Structure to keep track of ProvenCore state
+ ******************************************************************************/
+static pnc_context_t pncd_sp_context;
+
+static bool ree_info;
+static uint64_t ree_base_addr;
+static uint64_t ree_length;
+static uint64_t ree_tag;
+
+static bool pnc_initialized;
+
+static spinlock_t smc_handler_lock;
+
+static int pncd_init(void);
+
+static void context_save(unsigned long security_state)
+{
+	assert(sec_state_is_valid(security_state));
+
+	cm_el1_sysregs_context_save((uint32_t) security_state);
+#if CTX_INCLUDE_FPREGS
+	fpregs_context_save(get_fpregs_ctx(cm_get_context(security_state)));
+#endif
+}
+
+static void *context_restore(unsigned long security_state)
+{
+	void *handle;
+
+	assert(sec_state_is_valid(security_state));
+
+	/* Get a reference to the next context */
+	handle = cm_get_context((uint32_t) security_state);
+	assert(handle);
+
+	/* Restore state */
+	cm_el1_sysregs_context_restore((uint32_t) security_state);
+#if CTX_INCLUDE_FPREGS
+	fpregs_context_restore(get_fpregs_ctx(cm_get_context(security_state)));
+#endif
+
+	cm_set_next_eret_context((uint32_t) security_state);
+
+	return handle;
+}
+
+static uint64_t pncd_sel1_interrupt_handler(uint32_t id,
+		uint32_t flags, void *handle, void *cookie);
+
+/*******************************************************************************
+ * Switch context to the specified security state and return the targeted
+ * handle. Note that the context may remain unchanged if the switch is not
+ * allowed.
+ ******************************************************************************/
+void *pncd_context_switch_to(unsigned long security_state)
+{
+	unsigned long sec_state_from =
+	    security_state == SECURE ? NON_SECURE : SECURE;
+
+	assert(sec_state_is_valid(security_state));
+
+	/* Check if this is the first world switch */
+	if (!pnc_initialized) {
+		int rc;
+		uint32_t flags;
+
+		assert(sec_state_from == SECURE);
+
+		INFO("PnC initialization done\n");
+
+		/*
+		 * Register an interrupt handler for S-EL1 interrupts
+		 * when generated during code executing in the
+		 * non-secure state.
+		 */
+		flags = 0U;
+		set_interrupt_rm_flag(flags, NON_SECURE);
+		rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+				pncd_sel1_interrupt_handler,
+				flags);
+		if (rc != 0) {
+			ERROR("Failed to register S-EL1 interrupt handler (%d)\n",
+			      rc);
+			panic();
+		}
+
+		context_save(SECURE);
+
+		pnc_initialized = true;
+
+		/*
+		 * Release the lock before restoring the EL3 context to
+		 * bl31_main.
+		 */
+		spin_unlock(&smc_handler_lock);
+
+		/*
+		 * SP reports completion. The SPD must have initiated
+		 * the original request through a synchronous entry
+		 * into the SP. Jump back to the original C runtime
+		 * context.
+		 */
+		pncd_synchronous_sp_exit(&pncd_sp_context, (uint64_t) 0x0);
+
+		/* Unreachable */
+		ERROR("Returned from pncd_synchronous_sp_exit... Should not happen\n");
+		panic();
+	}
+
+	/* Check that the world switch is allowed */
+	if (read_mpidr() != pncd_sp_context.mpidr) {
+		if (sec_state_from == SECURE) {
+			/*
+			 * Secure -> Non-Secure world switch initiated on a CPU where there
+			 * should be no Trusted OS running
+			 */
+			WARN("Secure to Non-Secure switch requested on CPU where ProvenCore is not supposed to be running...\n");
+		}
+
+		/*
+		 * Secure or Non-Secure world wants to switch world but there is no Secure
+		 * software on this core
+		 */
+		return cm_get_context((uint32_t) sec_state_from);
+	}
+
+	context_save(sec_state_from);
+
+	return context_restore(security_state);
+}
+
+/*******************************************************************************
+ * This function is the handler registered for S-EL1 interrupts by the PNCD. It
+ * validates the interrupt and upon success arranges entry into the PNC at
+ * 'pnc_sel1_intr_entry()' for handling the interrupt.
+ ******************************************************************************/
+static uint64_t pncd_sel1_interrupt_handler(uint32_t id,
+		uint32_t flags,
+		void *handle,
+		void *cookie)
+{
+	/* Check the security state when the exception was generated */
+	assert(get_interrupt_src_ss(flags) == NON_SECURE);
+
+	/* Sanity check the pointer to this cpu's context */
+	assert(handle == cm_get_context(NON_SECURE));
+
+	/* switch to PnC */
+	handle = pncd_context_switch_to(SECURE);
+
+	assert(handle != NULL);
+
+	SMC_RET0(handle);
+}
+
+#pragma weak plat_pncd_setup
+int plat_pncd_setup(void)
+{
+	return 0;
+}
+
+/*******************************************************************************
+ * Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type
+ * (aarch32/aarch64) if not already known and initialises the context for entry
+ * into the SP for its initialisation.
+ ******************************************************************************/
+static int pncd_setup(void)
+{
+	entry_point_info_t *pnc_ep_info;
+
+	/*
+	 * Get information about the Secure Payload (BL32) image. Its
+	 * absence is a critical failure.
+	 *
+	 * TODO: Add support to conditionally include the SPD service
+	 */
+	pnc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
+	if (!pnc_ep_info) {
+		WARN("No PNC provided by BL2 boot loader, Booting device without PNC initialization. SMC`s destined for PNC will return SMC_UNK\n");
+		return 1;
+	}
+
+	/*
+	 * If there's no valid entry point for SP, we return a non-zero value
+	 * signalling failure initializing the service. We bail out without
+	 * registering any handlers
+	 */
+	if (!pnc_ep_info->pc) {
+		return 1;
+	}
+
+	pncd_init_pnc_ep_state(pnc_ep_info,
+			pnc_ep_info->pc,
+			&pncd_sp_context);
+
+	/*
+	 * All PNCD initialization done. Now register our init function with
+	 * BL31 for deferred invocation
+	 */
+	bl31_register_bl32_init(&pncd_init);
+	bl31_set_next_image_type(NON_SECURE);
+
+	return plat_pncd_setup();
+}
+
+/*******************************************************************************
+ * This function passes control to the Secure Payload image (BL32) for the first
+ * time on the primary cpu after a cold boot. It assumes that a valid secure
+ * context has already been created by pncd_setup() which can be directly used.
+ * It also assumes that a valid non-secure context has been initialised by PSCI
+ * so it does not need to save and restore any non-secure state. This function
+ * performs a synchronous entry into the Secure payload. The SP passes control
+ * back to this routine through a SMC.
+ ******************************************************************************/
+static int32_t pncd_init(void)
+{
+	entry_point_info_t *pnc_entry_point;
+	uint64_t rc = 0;
+
+	/*
+	 * Get information about the Secure Payload (BL32) image. Its
+	 * absence is a critical failure.
+	 */
+	pnc_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
+	assert(pnc_entry_point);
+
+	cm_init_my_context(pnc_entry_point);
+
+	/*
+	 * Arrange for an entry into the test secure payload. It will be
+	 * returned via PNC_ENTRY_DONE case
+	 */
+	rc = pncd_synchronous_sp_entry(&pncd_sp_context);
+
+	/*
+	 * If everything went well at this point, the return value should be 0.
+	 */
+	return rc == 0;
+}
+
+#pragma weak plat_pncd_smc_handler
+/*******************************************************************************
+ * This function is responsible for handling the platform-specific SMCs in the
+ * Trusted OS/App range as defined in the SMC Calling Convention Document.
+ ******************************************************************************/
+uintptr_t plat_pncd_smc_handler(uint32_t smc_fid,
+		u_register_t x1,
+		u_register_t x2,
+		u_register_t x3,
+		u_register_t x4,
+		void *cookie,
+		void *handle,
+		u_register_t flags)
+{
+	(void) smc_fid;
+	(void) x1;
+	(void) x2;
+	(void) x3;
+	(void) x4;
+	(void) cookie;
+	(void) flags;
+
+	SMC_RET1(handle, SMC_UNK);
+}
+
+/*******************************************************************************
+ * This function is responsible for handling all SMCs in the Trusted OS/App
+ * range as defined in the SMC Calling Convention Document. It is also
+ * responsible for communicating with the Secure payload to delegate work and
+ * return results back to the non-secure state. Lastly it will also return any
+ * information that the secure payload needs to do the work assigned to it.
+ *
+ * It should only be called with the smc_handler_lock held.
+ ******************************************************************************/
+static uintptr_t pncd_smc_handler_unsafe(uint32_t smc_fid,
+		u_register_t x1,
+		u_register_t x2,
+		u_register_t x3,
+		u_register_t x4,
+		void *cookie,
+		void *handle,
+		u_register_t flags)
+{
+	uint32_t ns;
+
+	/* Determine which security state this SMC originated from */
+	ns = is_caller_non_secure(flags);
+
+	assert(ns != 0 || read_mpidr() == pncd_sp_context.mpidr);
+
+	switch (smc_fid) {
+	case SMC_CONFIG_SHAREDMEM:
+		if (ree_info) {
+			/* Do not Yield */
+			SMC_RET0(handle);
+		}
+
+		/*
+		 * Fetch the physical base address (x1) and size (x2) of the
+		 * shared memory allocated by the Non-Secure world. This memory
+		 * will be used by PNC to communicate with the Non-Secure world.
+		 * Verifying the validity of these values is up to the Trusted
+		 * OS.
+		 */
+		ree_base_addr = x1 | (x2 << 32);
+		ree_length = x3;
+		ree_tag = x4;
+
+		INFO("IN SMC_CONFIG_SHAREDMEM: addr=%lx, length=%lx, tag=%lx\n",
+		     (unsigned long) ree_base_addr,
+		     (unsigned long) ree_length,
+		     (unsigned long) ree_tag);
+
+		if ((ree_base_addr % 0x200000) != 0) {
+			SMC_RET1(handle, SMC_UNK);
+		}
+
+		if ((ree_length % 0x200000) != 0) {
+			SMC_RET1(handle, SMC_UNK);
+		}
+
+		ree_info = true;
+
+		/* Do not Yield */
+		SMC_RET4(handle, 0, 0, 0, 0);
+
+		break;
+
+	case SMC_GET_SHAREDMEM:
+		if (ree_info) {
+			x1 = (1U << 16) | ree_tag;
+			x2 = ree_base_addr & 0xFFFFFFFF;
+			x3 = (ree_base_addr >> 32) & 0xFFFFFFFF;
+			x4 = ree_length & 0xFFFFFFFF;
+			SMC_RET4(handle, x1, x2, x3, x4);
+		} else {
+			SMC_RET4(handle, 0, 0, 0, 0);
+		}
+
+		break;
+
+	case SMC_ACTION_FROM_NS:
+		if (ns == 0) {
+			SMC_RET1(handle, SMC_UNK);
+		}
+
+		if (SPD_PNCD_S_IRQ < MIN_PPI_ID) {
+			plat_ic_raise_s_el1_sgi(SPD_PNCD_S_IRQ,
+						pncd_sp_context.mpidr);
+		} else {
+			plat_ic_set_interrupt_pending(SPD_PNCD_S_IRQ);
+		}
+
+		SMC_RET0(handle);
+
+		break;
+
+	case SMC_ACTION_FROM_S:
+		if (ns != 0) {
+			SMC_RET1(handle, SMC_UNK);
+		}
+
+		if (SPD_PNCD_NS_IRQ < MIN_PPI_ID) {
+			/*
+			 * NS SGI is sent to the same core as the one running
+			 * PNC
+			 */
+			plat_ic_raise_ns_sgi(SPD_PNCD_NS_IRQ, read_mpidr());
+		} else {
+			plat_ic_set_interrupt_pending(SPD_PNCD_NS_IRQ);
+		}
+
+		SMC_RET0(handle);
+
+		break;
+
+	case SMC_YIELD:
+		assert(handle == cm_get_context(ns != 0 ? NON_SECURE : SECURE));
+		handle = pncd_context_switch_to(ns != 0 ? SECURE : NON_SECURE);
+
+		assert(handle != NULL);
+
+		SMC_RET0(handle);
+
+		break;
+
+	default:
+		INFO("Unknown smc: %x\n", smc_fid);
+		break;
+	}
+
+	return plat_pncd_smc_handler(smc_fid, x1, x2, x3, x4,
+				     cookie, handle, flags);
+}
+
+static uintptr_t pncd_smc_handler(uint32_t smc_fid,
+		u_register_t x1,
+		u_register_t x2,
+		u_register_t x3,
+		u_register_t x4,
+		void *cookie,
+		void *handle,
+		u_register_t flags)
+{
+	uintptr_t ret;
+
+	/* SMC handling is serialized */
+	spin_lock(&smc_handler_lock);
+	ret = pncd_smc_handler_unsafe(smc_fid, x1, x2, x3, x4, cookie, handle,
+								  flags);
+	spin_unlock(&smc_handler_lock);
+
+	return ret;
+}
+
+/* Define a SPD runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+	pncd_fast,
+	OEN_TOS_START,
+	OEN_TOS_END,
+	SMC_TYPE_FAST,
+	pncd_setup,
+	pncd_smc_handler
+);
+
+/* Define a SPD runtime service descriptor for standard SMC calls */
+DECLARE_RT_SVC(
+	pncd_std,
+	OEN_TOS_START,
+	OEN_TOS_END,
+	SMC_TYPE_YIELD,
+	NULL,
+	pncd_smc_handler
+);
diff --git a/services/spd/pncd/pncd_private.h b/services/spd/pncd/pncd_private.h
new file mode 100644
index 0000000..8c9b634
--- /dev/null
+++ b/services/spd/pncd/pncd_private.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PNCD_PRIVATE_H__
+#define __PNCD_PRIVATE_H__
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#endif /* __ASSEMBLER __ */
+
+#include <context.h>
+#ifndef __ASSEMBLER__
+#include <lib/cassert.h>
+#endif /* __ASSEMBLER __ */
+
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Constants that allow assembler code to preserve callee-saved registers of the
+ * C runtime context while performing a security state switch.
+ ******************************************************************************/
+#define PNCD_C_RT_CTX_X19		U(0x0)
+#define PNCD_C_RT_CTX_X20		U(0x8)
+#define PNCD_C_RT_CTX_X21		U(0x10)
+#define PNCD_C_RT_CTX_X22		U(0x18)
+#define PNCD_C_RT_CTX_X23		U(0x20)
+#define PNCD_C_RT_CTX_X24		U(0x28)
+#define PNCD_C_RT_CTX_X25		U(0x30)
+#define PNCD_C_RT_CTX_X26		U(0x38)
+#define PNCD_C_RT_CTX_X27		U(0x40)
+#define PNCD_C_RT_CTX_X28		U(0x48)
+#define PNCD_C_RT_CTX_X29		U(0x50)
+#define PNCD_C_RT_CTX_X30		U(0x58)
+#define PNCD_C_RT_CTX_SIZE		U(0x60)
+#define PNCD_C_RT_CTX_ENTRIES		(PNCD_C_RT_CTX_SIZE >> DWORD_SHIFT)
+
+#ifndef __ASSEMBLER__
+
+/* AArch64 callee saved general purpose register context structure. */
+DEFINE_REG_STRUCT(c_rt_regs, PNCD_C_RT_CTX_ENTRIES);
+
+/*
+ * Compile time assertion to ensure that both the compiler and linker
+ * have the same double word aligned view of the size of the C runtime
+ * register context.
+ */
+CASSERT(sizeof(c_rt_regs_t) == PNCD_C_RT_CTX_SIZE,
+		assert_spd_c_rt_regs_size_mismatch);
+
+/*******************************************************************************
+ * Structure which helps the SPD to maintain the per-cpu state of the SP.
+ * 'mpidr'          - mpidr of the CPU running PNC
+ * 'c_rt_ctx'       - stack address to restore C runtime context from after
+ *                    returning from a synchronous entry into the SP.
+ * 'cpu_ctx'        - space to maintain SP architectural state
+ ******************************************************************************/
+typedef struct pnc_context {
+	uint64_t mpidr;
+	uint64_t c_rt_ctx;
+	cpu_context_t cpu_ctx;
+} pnc_context_t;
+
+/*******************************************************************************
+ * Function & Data prototypes
+ ******************************************************************************/
+uint64_t pncd_enter_sp(uint64_t *c_rt_ctx);
+void __dead2 pncd_exit_sp(uint64_t c_rt_ctx, uint64_t ret);
+uint64_t pncd_synchronous_sp_entry(pnc_context_t *pnc_ctx);
+void __dead2 pncd_synchronous_sp_exit(pnc_context_t *pnc_ctx, uint64_t ret);
+void pncd_init_pnc_ep_state(struct entry_point_info *pnc_ep,
+				uint64_t pc,
+				pnc_context_t *pnc_ctx);
+#endif /* __ASSEMBLER__ */
+
+#endif /* __PNCD_PRIVATE_H__ */
diff --git a/services/std_svc/drtm/drtm_dma_prot.c b/services/std_svc/drtm/drtm_dma_prot.c
new file mode 100644
index 0000000..48317fd
--- /dev/null
+++ b/services/std_svc/drtm/drtm_dma_prot.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ * DRTM DMA protection.
+ *
+ * Authors:
+ *      Lucian Paul-Trifu <lucian.paultrifu@gmail.com>
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/arm/smmu_v3.h>
+#include "drtm_dma_prot.h"
+#include "drtm_main.h"
+#include "drtm_remediation.h"
+#include <plat/common/platform.h>
+#include <smccc_helpers.h>
+
+/*
+ *  ________________________  LAUNCH success        ________________________
+ * |        Initial         | -------------------> |      Prot engaged      |
+ * |````````````````````````|                      |````````````````````````|
+ * |  request.type == NONE  |                      |  request.type != NONE  |
+ * |                        | <------------------- |                        |
+ * `________________________'        UNPROTECT_MEM `________________________'
+ *
+ * Transitions that are not shown correspond to ABI calls that do not change
+ * state and result in an error being returned to the caller.
+ */
+static struct dma_prot active_prot = {
+	.type = PROTECT_NONE,
+};
+
+/* Version-independent type. */
+typedef struct drtm_dl_dma_prot_args_v1 struct_drtm_dl_dma_prot_args;
+
+/*
+ * This function checks that platform supports complete DMA protection.
+ * and returns false - if the platform supports complete DMA protection.
+ * and returns true - if the platform does not support complete DMA protection.
+ */
+bool drtm_dma_prot_init(void)
+{
+	bool must_init_fail = false;
+	const uintptr_t *smmus;
+	size_t num_smmus = 0;
+	unsigned int total_smmus;
+
+	/* Warns presence of non-host platforms */
+	if (plat_has_non_host_platforms()) {
+		WARN("DRTM: the platform includes trusted DMA-capable devices"
+				" (non-host platforms)\n");
+	}
+
+	/*
+	 * DLME protection is uncertain on platforms with peripherals whose
+	 * DMA is not managed by an SMMU. DRTM doesn't work on such platforms.
+	 */
+	if (plat_has_unmanaged_dma_peripherals()) {
+		ERROR("DRTM: this platform does not provide DMA protection\n");
+		must_init_fail = true;
+	}
+
+	/*
+	 * Check that the platform reported all SMMUs.
+	 * It is acceptable if the platform doesn't have any SMMUs when it
+	 * doesn't have any DMA-capable devices.
+	 */
+	total_smmus = plat_get_total_smmus();
+	plat_enumerate_smmus(&smmus, &num_smmus);
+	if (num_smmus != total_smmus) {
+		ERROR("DRTM: could not discover all SMMUs\n");
+		must_init_fail = true;
+	}
+
+	return must_init_fail;
+}
+
+/*
+ * Checks that the DMA protection arguments are valid and that the given
+ * protected regions are covered by DMA protection.
+ */
+enum drtm_retc drtm_dma_prot_check_args(const struct_drtm_dl_dma_prot_args *a,
+					int a_dma_prot_type,
+					drtm_mem_region_t p)
+{
+	switch ((enum dma_prot_type)a_dma_prot_type) {
+	case PROTECT_MEM_ALL:
+		if (a->dma_prot_table_paddr || a->dma_prot_table_size) {
+			ERROR("DRTM: invalid launch due to inconsistent"
+			      " DMA protection arguments\n");
+			return MEM_PROTECT_INVALID;
+		}
+		/*
+		 * Full DMA protection ought to ensure that the DLME and NWd
+		 * DCE regions are protected, no further checks required.
+		 */
+		return SUCCESS;
+
+	default:
+		ERROR("DRTM: invalid launch due to unsupported DMA protection type\n");
+		return MEM_PROTECT_INVALID;
+	}
+}
+
+enum drtm_retc drtm_dma_prot_engage(const struct_drtm_dl_dma_prot_args *a,
+				    int a_dma_prot_type)
+{
+	const uintptr_t *smmus;
+	size_t num_smmus = 0;
+
+	if (active_prot.type != PROTECT_NONE) {
+		ERROR("DRTM: launch denied as previous DMA protection"
+		      " is still engaged\n");
+		return DENIED;
+	}
+
+	if (a_dma_prot_type == PROTECT_NONE) {
+		return SUCCESS;
+		/* Only PROTECT_MEM_ALL is supported currently. */
+	} else if (a_dma_prot_type != PROTECT_MEM_ALL) {
+		ERROR("%s(): unimplemented DMA protection type\n", __func__);
+		panic();
+	}
+
+	/*
+	 * Engage SMMUs in accordance with the request we have previously received.
+	 * Only PROTECT_MEM_ALL is implemented currently.
+	 */
+	plat_enumerate_smmus(&smmus, &num_smmus);
+	for (const uintptr_t *smmu = smmus; smmu < smmus+num_smmus; smmu++) {
+		/*
+		 * TODO: Invalidate SMMU's Stage-1 and Stage-2 TLB entries.  This ensures
+		 * that any outstanding device transactions are completed, see Section
+		 * 3.21.1, specification IHI_0070_C_a for an approximate reference.
+		 */
+		int rc = smmuv3_ns_set_abort_all(*smmu);
+		if (rc != 0) {
+			ERROR("DRTM: SMMU at PA 0x%lx failed to engage DMA protection"
+			      " rc=%d\n", *smmu, rc);
+			return INTERNAL_ERROR;
+		}
+	}
+
+	/*
+	 * TODO: Restrict DMA from the GIC.
+	 *
+	 * Full DMA protection may be achieved as follows:
+	 *
+	 * With a GICv3:
+	 * - Set GICR_CTLR.EnableLPIs to 0, for each GICR;
+	 *   GICR_CTLR.RWP == 0 must be the case before finishing, for each GICR.
+	 * - Set GITS_CTLR.Enabled to 0;
+	 *   GITS_CTLR.Quiescent == 1 must be the case before finishing.
+	 *
+	 * In addition, with a GICv4:
+	 * - Set GICR_VPENDBASER.Valid to 0, for each GICR;
+	 *   GICR_CTLR.RWP == 0 must be the case before finishing, for each GICR.
+	 *
+	 * Alternatively, e.g. if some bit values cannot be changed at runtime,
+	 * this procedure should return an error if the LPI Pending and
+	 * Configuration tables overlap the regions being protected.
+	 */
+
+	active_prot.type = a_dma_prot_type;
+
+	return SUCCESS;
+}
+
+/*
+ * Undo what has previously been done in drtm_dma_prot_engage(), or enter
+ * remediation if it is not possible.
+ */
+enum drtm_retc drtm_dma_prot_disengage(void)
+{
+	const uintptr_t *smmus;
+	size_t num_smmus = 0;
+	const char *err_str = "cannot undo PROTECT_MEM_ALL SMMU config";
+
+	if (active_prot.type == PROTECT_NONE) {
+		return SUCCESS;
+		/* Only PROTECT_MEM_ALL is supported currently. */
+	} else if (active_prot.type != PROTECT_MEM_ALL) {
+		ERROR("%s(): unimplemented DMA protection type\n", __func__);
+		panic();
+	}
+
+	/*
+	 * For PROTECT_MEM_ALL, undo the SMMU configuration for "abort all" mode
+	 * done during engage().
+	 */
+	/* Simply enter remediation for now. */
+	(void)smmus;
+	(void)num_smmus;
+	drtm_enter_remediation(1ULL, err_str);
+
+	/* TODO: Undo GIC DMA restrictions. */
+
+	active_prot.type = PROTECT_NONE;
+
+	return SUCCESS;
+}
+
+uint64_t drtm_unprotect_mem(void *ctx)
+{
+	enum drtm_retc ret;
+
+	switch (active_prot.type) {
+	case PROTECT_NONE:
+		ERROR("DRTM: invalid UNPROTECT_MEM, no DMA protection has"
+		      " previously been engaged\n");
+		ret = DENIED;
+		break;
+
+	case PROTECT_MEM_ALL:
+		/*
+		 * UNPROTECT_MEM is a no-op for PROTECT_MEM_ALL:  DRTM must not touch
+		 * the NS SMMU as it is expected that the DLME has configured it.
+		 */
+		active_prot.type = PROTECT_NONE;
+
+		ret = SUCCESS;
+		break;
+
+	default:
+		ret = drtm_dma_prot_disengage();
+		break;
+	}
+
+	SMC_RET1(ctx, ret);
+}
+
+void drtm_dma_prot_serialise_table(uint8_t *dst, size_t *size_out)
+{
+	if (active_prot.type == PROTECT_NONE) {
+		return;
+	} else if (active_prot.type != PROTECT_MEM_ALL) {
+		ERROR("%s(): unimplemented DMA protection type\n", __func__);
+		panic();
+	}
+
+	struct __packed descr_table_1 {
+		drtm_memory_region_descriptor_table_t header;
+		drtm_mem_region_t regions[1];
+	} prot_table = {
+		.header = {
+			.revision = 1,
+			.num_regions = sizeof(((struct descr_table_1 *)NULL)->regions) /
+				sizeof(((struct descr_table_1 *)NULL)->regions[0])
+		},
+		.regions = {
+			{.region_address = 0, PAGES_AND_TYPE(UINT64_MAX, 0x3)},
+		}
+	};
+
+	memcpy(dst, &prot_table, sizeof(prot_table));
+	*size_out = sizeof(prot_table);
+}
diff --git a/services/std_svc/drtm/drtm_dma_prot.h b/services/std_svc/drtm/drtm_dma_prot.h
new file mode 100644
index 0000000..79dc9cb
--- /dev/null
+++ b/services/std_svc/drtm/drtm_dma_prot.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ */
+#ifndef DRTM_DMA_PROT_H
+#define DRTM_DMA_PROT_H
+
+#include <stdint.h>
+#include <plat/common/platform.h>
+#include <services/drtm_svc.h>
+
+struct __packed drtm_dl_dma_prot_args_v1 {
+	uint64_t dma_prot_table_paddr;
+	uint64_t dma_prot_table_size;
+};
+
+/* Values for DRTM_PROTECT_MEMORY */
+enum dma_prot_type {
+	PROTECT_NONE    = -1,
+	PROTECT_MEM_ALL = 0,
+	PROTECT_MEM_REGION = 2,
+};
+
+struct dma_prot {
+	enum dma_prot_type type;
+};
+
+#define DRTM_MEM_REGION_PAGES_AND_TYPE(pages, type) \
+	(((uint64_t)(pages) & (((uint64_t)1 << 52) - 1)) \
+	 | (((uint64_t)(type) & 0x7) << 52))
+
+#define PAGES_AND_TYPE(pages, type) \
+		.region_size_type = DRTM_MEM_REGION_PAGES_AND_TYPE(pages, type)
+
+/* Opaque / encapsulated type. */
+typedef struct drtm_dl_dma_prot_args_v1 drtm_dl_dma_prot_args_v1_t;
+
+bool drtm_dma_prot_init(void);
+enum drtm_retc drtm_dma_prot_check_args(const drtm_dl_dma_prot_args_v1_t *a,
+					int a_dma_prot_type,
+					drtm_mem_region_t p);
+enum drtm_retc drtm_dma_prot_engage(const drtm_dl_dma_prot_args_v1_t *a,
+				    int a_dma_prot_type);
+enum drtm_retc drtm_dma_prot_disengage(void);
+uint64_t drtm_unprotect_mem(void *ctx);
+void drtm_dma_prot_serialise_table(uint8_t *dst, size_t *size_out);
+
+#endif /* DRTM_DMA_PROT_H */
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c
new file mode 100644
index 0000000..e0f5c17
--- /dev/null
+++ b/services/std_svc/drtm/drtm_main.c
@@ -0,0 +1,838 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ * DRTM service
+ *
+ * Authors:
+ *	Lucian Paul-Trifu <lucian.paultrifu@gmail.com>
+ *	Brian Nezvadovitz <brinez@microsoft.com> 2021-02-01
+ */
+
+#include <stdint.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/auth/crypto_mod.h>
+#include "drtm_main.h"
+#include "drtm_measurements.h"
+#include "drtm_remediation.h"
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/psci/psci_lib.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include <services/drtm_svc.h>
+#include <services/sdei.h>
+#include <platform_def.h>
+
+/* Structure to store DRTM features specific to the platform. */
+static drtm_features_t plat_drtm_features;
+
+/* DRTM-formatted memory map. */
+static drtm_memory_region_descriptor_table_t *plat_drtm_mem_map;
+
+/* DLME header */
+struct_dlme_data_header dlme_data_hdr_init;
+
+/* Minimum data memory requirement */
+uint64_t dlme_data_min_size;
+
+int drtm_setup(void)
+{
+	bool rc;
+	const plat_drtm_tpm_features_t *plat_tpm_feat;
+	const plat_drtm_dma_prot_features_t *plat_dma_prot_feat;
+
+	INFO("DRTM service setup\n");
+
+	/* Read boot PE ID from MPIDR */
+	plat_drtm_features.boot_pe_id = read_mpidr_el1() & MPIDR_AFFINITY_MASK;
+
+	rc = drtm_dma_prot_init();
+	if (rc) {
+		return INTERNAL_ERROR;
+	}
+
+	/*
+	 * initialise the platform supported crypto module that will
+	 * be used by the DRTM-service to calculate hash of DRTM-
+	 * implementation specific components
+	 */
+	crypto_mod_init();
+
+	/* Build DRTM-compatible address map. */
+	plat_drtm_mem_map = drtm_build_address_map();
+	if (plat_drtm_mem_map == NULL) {
+		return INTERNAL_ERROR;
+	}
+
+	/* Get DRTM features from platform hooks. */
+	plat_tpm_feat = plat_drtm_get_tpm_features();
+	if (plat_tpm_feat == NULL) {
+		return INTERNAL_ERROR;
+	}
+
+	plat_dma_prot_feat = plat_drtm_get_dma_prot_features();
+	if (plat_dma_prot_feat == NULL) {
+		return INTERNAL_ERROR;
+	}
+
+	/*
+	 * Add up minimum DLME data memory.
+	 *
+	 * For systems with complete DMA protection there is only one entry in
+	 * the protected regions table.
+	 */
+	if (plat_dma_prot_feat->dma_protection_support ==
+			ARM_DRTM_DMA_PROT_FEATURES_DMA_SUPPORT_COMPLETE) {
+		dlme_data_min_size =
+			sizeof(drtm_memory_region_descriptor_table_t) +
+			sizeof(drtm_mem_region_t);
+		dlme_data_hdr_init.dlme_prot_regions_size = dlme_data_min_size;
+	} else {
+		/*
+		 * TODO set protected regions table size based on platform DMA
+		 * protection configuration
+		 */
+		panic();
+	}
+
+	dlme_data_hdr_init.dlme_addr_map_size = drtm_get_address_map_size();
+	dlme_data_hdr_init.dlme_tcb_hashes_table_size =
+				plat_drtm_get_tcb_hash_table_size();
+	dlme_data_hdr_init.dlme_impdef_region_size =
+				plat_drtm_get_imp_def_dlme_region_size();
+
+	dlme_data_min_size += dlme_data_hdr_init.dlme_addr_map_size +
+			      PLAT_DRTM_EVENT_LOG_MAX_SIZE +
+			      dlme_data_hdr_init.dlme_tcb_hashes_table_size +
+			      dlme_data_hdr_init.dlme_impdef_region_size;
+
+	dlme_data_min_size = page_align(dlme_data_min_size, UP)/PAGE_SIZE;
+
+	/* Fill out platform DRTM features structure */
+	/* Only support default PCR schema (0x1) in this implementation. */
+	ARM_DRTM_TPM_FEATURES_SET_PCR_SCHEMA(plat_drtm_features.tpm_features,
+		ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_DEFAULT);
+	ARM_DRTM_TPM_FEATURES_SET_TPM_HASH(plat_drtm_features.tpm_features,
+		plat_tpm_feat->tpm_based_hash_support);
+	ARM_DRTM_TPM_FEATURES_SET_FW_HASH(plat_drtm_features.tpm_features,
+		plat_tpm_feat->firmware_hash_algorithm);
+	ARM_DRTM_MIN_MEM_REQ_SET_MIN_DLME_DATA_SIZE(plat_drtm_features.minimum_memory_requirement,
+		dlme_data_min_size);
+	ARM_DRTM_MIN_MEM_REQ_SET_DCE_SIZE(plat_drtm_features.minimum_memory_requirement,
+		plat_drtm_get_min_size_normal_world_dce());
+	ARM_DRTM_DMA_PROT_FEATURES_SET_MAX_REGIONS(plat_drtm_features.dma_prot_features,
+		plat_dma_prot_feat->max_num_mem_prot_regions);
+	ARM_DRTM_DMA_PROT_FEATURES_SET_DMA_SUPPORT(plat_drtm_features.dma_prot_features,
+		plat_dma_prot_feat->dma_protection_support);
+	ARM_DRTM_TCB_HASH_FEATURES_SET_MAX_NUM_HASHES(plat_drtm_features.tcb_hash_features,
+		plat_drtm_get_tcb_hash_features());
+
+	return 0;
+}
+
+static inline void invalidate_icache_all(void)
+{
+	__asm__ volatile("ic      ialluis");
+	dsb();
+	isb();
+}
+
+static inline uint64_t drtm_features_tpm(void *ctx)
+{
+	SMC_RET2(ctx, 1ULL, /* TPM feature is supported */
+		 plat_drtm_features.tpm_features);
+}
+
+static inline uint64_t drtm_features_mem_req(void *ctx)
+{
+	SMC_RET2(ctx, 1ULL, /* memory req Feature is supported */
+		 plat_drtm_features.minimum_memory_requirement);
+}
+
+static inline uint64_t drtm_features_boot_pe_id(void *ctx)
+{
+	SMC_RET2(ctx, 1ULL, /* Boot PE feature is supported */
+		 plat_drtm_features.boot_pe_id);
+}
+
+static inline uint64_t drtm_features_dma_prot(void *ctx)
+{
+	SMC_RET2(ctx, 1ULL, /* DMA protection feature is supported */
+		 plat_drtm_features.dma_prot_features);
+}
+
+static inline uint64_t drtm_features_tcb_hashes(void *ctx)
+{
+	SMC_RET2(ctx, 1ULL, /* TCB hash feature is supported */
+		 plat_drtm_features.tcb_hash_features);
+}
+
+static enum drtm_retc drtm_dl_check_caller_el(void *ctx)
+{
+	uint64_t spsr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_SPSR_EL3);
+	uint64_t dl_caller_el;
+	uint64_t dl_caller_aarch;
+
+	dl_caller_el = spsr_el3 >> MODE_EL_SHIFT & MODE_EL_MASK;
+	dl_caller_aarch = spsr_el3 >> MODE_RW_SHIFT & MODE_RW_MASK;
+
+	/* Caller's security state is checked from drtm_smc_handle function */
+
+	/* Caller can be NS-EL2/EL1 */
+	if (dl_caller_el == MODE_EL3) {
+		ERROR("DRTM: invalid launch from EL3\n");
+		return DENIED;
+	}
+
+	if (dl_caller_aarch != MODE_RW_64) {
+		ERROR("DRTM: invalid launch from non-AArch64 execution state\n");
+		return DENIED;
+	}
+
+	return SUCCESS;
+}
+
+static enum drtm_retc drtm_dl_check_cores(void)
+{
+	bool running_on_single_core;
+	uint64_t this_pe_aff_value = read_mpidr_el1() & MPIDR_AFFINITY_MASK;
+
+	if (this_pe_aff_value != plat_drtm_features.boot_pe_id) {
+		ERROR("DRTM: invalid launch on a non-boot PE\n");
+		return DENIED;
+	}
+
+	running_on_single_core = psci_is_last_on_cpu_safe();
+	if (!running_on_single_core) {
+		ERROR("DRTM: invalid launch due to non-boot PE not being turned off\n");
+		return DENIED;
+	}
+
+	return SUCCESS;
+}
+
+static enum drtm_retc drtm_dl_prepare_dlme_data(const struct_drtm_dl_args *args)
+{
+	int rc;
+	uint64_t dlme_data_paddr;
+	size_t dlme_data_max_size;
+	uintptr_t dlme_data_mapping;
+	struct_dlme_data_header *dlme_data_hdr;
+	uint8_t *dlme_data_cursor;
+	size_t dlme_data_mapping_bytes;
+	size_t serialised_bytes_actual;
+
+	dlme_data_paddr = args->dlme_paddr + args->dlme_data_off;
+	dlme_data_max_size = args->dlme_size - args->dlme_data_off;
+
+	/*
+	 * The capacity of the given DLME data region is checked when
+	 * the other dynamic launch arguments are.
+	 */
+	if (dlme_data_max_size < dlme_data_min_size) {
+		ERROR("%s: assertion failed:"
+		      " dlme_data_max_size (%ld) < dlme_data_total_bytes_req (%ld)\n",
+		      __func__, dlme_data_max_size, dlme_data_min_size);
+		panic();
+	}
+
+	/* Map the DLME data region as NS memory. */
+	dlme_data_mapping_bytes = ALIGNED_UP(dlme_data_max_size, DRTM_PAGE_SIZE);
+	rc = mmap_add_dynamic_region_alloc_va(dlme_data_paddr,
+					      &dlme_data_mapping,
+					      dlme_data_mapping_bytes,
+					      MT_RW_DATA | MT_NS |
+					      MT_SHAREABILITY_ISH);
+	if (rc != 0) {
+		WARN("DRTM: %s: mmap_add_dynamic_region() failed rc=%d\n",
+		     __func__, rc);
+		return INTERNAL_ERROR;
+	}
+	dlme_data_hdr = (struct_dlme_data_header *)dlme_data_mapping;
+	dlme_data_cursor = (uint8_t *)dlme_data_hdr + sizeof(*dlme_data_hdr);
+
+	memcpy(dlme_data_hdr, (const void *)&dlme_data_hdr_init,
+	       sizeof(*dlme_data_hdr));
+
+	/* Set the header version and size. */
+	dlme_data_hdr->version = 1;
+	dlme_data_hdr->this_hdr_size = sizeof(*dlme_data_hdr);
+
+	/* Prepare DLME protected regions. */
+	drtm_dma_prot_serialise_table(dlme_data_cursor,
+				      &serialised_bytes_actual);
+	assert(serialised_bytes_actual ==
+	       dlme_data_hdr->dlme_prot_regions_size);
+	dlme_data_cursor += serialised_bytes_actual;
+
+	/* Prepare DLME address map. */
+	if (plat_drtm_mem_map != NULL) {
+		memcpy(dlme_data_cursor, plat_drtm_mem_map,
+		       dlme_data_hdr->dlme_addr_map_size);
+	} else {
+		WARN("DRTM: DLME address map is not in the cache\n");
+	}
+	dlme_data_cursor += dlme_data_hdr->dlme_addr_map_size;
+
+	/* Prepare DRTM event log for DLME. */
+	drtm_serialise_event_log(dlme_data_cursor, &serialised_bytes_actual);
+	assert(serialised_bytes_actual <= PLAT_DRTM_EVENT_LOG_MAX_SIZE);
+	dlme_data_hdr->dlme_tpm_log_size = serialised_bytes_actual;
+	dlme_data_cursor += serialised_bytes_actual;
+
+	/*
+	 * TODO: Prepare the TCB hashes for DLME, currently its size
+	 * 0
+	 */
+	dlme_data_cursor += dlme_data_hdr->dlme_tcb_hashes_table_size;
+
+	/* Implementation-specific region size is unused. */
+	dlme_data_cursor += dlme_data_hdr->dlme_impdef_region_size;
+
+	/*
+	 * Prepare DLME data size, includes all data region referenced above
+	 * alongwith the DLME data header
+	 */
+	dlme_data_hdr->dlme_data_size = dlme_data_cursor - (uint8_t *)dlme_data_hdr;
+
+	/* Unmap the DLME data region. */
+	rc = mmap_remove_dynamic_region(dlme_data_mapping, dlme_data_mapping_bytes);
+	if (rc != 0) {
+		ERROR("%s(): mmap_remove_dynamic_region() failed"
+		      " unexpectedly rc=%d\n", __func__, rc);
+		panic();
+	}
+
+	return SUCCESS;
+}
+
+/*
+ * Note: accesses to the dynamic launch args, and to the DLME data are
+ * little-endian as required, thanks to TF-A BL31 init requirements.
+ */
+static enum drtm_retc drtm_dl_check_args(uint64_t x1,
+					 struct_drtm_dl_args *a_out)
+{
+	uint64_t dlme_start, dlme_end;
+	uint64_t dlme_img_start, dlme_img_ep, dlme_img_end;
+	uint64_t dlme_data_start, dlme_data_end;
+	uintptr_t va_mapping;
+	size_t va_mapping_size;
+	struct_drtm_dl_args *a;
+	struct_drtm_dl_args args_buf;
+	int rc;
+
+	if (x1 % DRTM_PAGE_SIZE != 0) {
+		ERROR("DRTM: parameters structure is not "
+		      DRTM_PAGE_SIZE_STR "-aligned\n");
+		return INVALID_PARAMETERS;
+	}
+
+	va_mapping_size = ALIGNED_UP(sizeof(struct_drtm_dl_args), DRTM_PAGE_SIZE);
+
+	/* check DRTM parameters are within NS address region */
+	rc = plat_drtm_validate_ns_region(x1, va_mapping_size);
+	if (rc != 0) {
+		ERROR("DRTM: parameters lies within secure memory\n");
+		return INVALID_PARAMETERS;
+	}
+
+	rc = mmap_add_dynamic_region_alloc_va(x1, &va_mapping, va_mapping_size,
+					      MT_MEMORY | MT_NS | MT_RO |
+					      MT_SHAREABILITY_ISH);
+	if (rc != 0) {
+		WARN("DRTM: %s: mmap_add_dynamic_region() failed rc=%d\n",
+		      __func__, rc);
+		return INTERNAL_ERROR;
+	}
+	a = (struct_drtm_dl_args *)va_mapping;
+
+	/* Sanitize cache of data passed in args by the DCE Preamble. */
+	flush_dcache_range(va_mapping, va_mapping_size);
+
+	args_buf = *a;
+
+	rc = mmap_remove_dynamic_region(va_mapping, va_mapping_size);
+	if (rc) {
+		ERROR("%s(): mmap_remove_dynamic_region() failed unexpectedly"
+		      " rc=%d\n", __func__, rc);
+		panic();
+	}
+	a = &args_buf;
+
+	if (a->version != 1) {
+		ERROR("DRTM: parameters structure incompatible with major version %d\n",
+		      ARM_DRTM_VERSION_MAJOR);
+		return NOT_SUPPORTED;
+	}
+
+	if (!(a->dlme_img_off < a->dlme_size &&
+	      a->dlme_data_off < a->dlme_size)) {
+		ERROR("DRTM: argument offset is outside of the DLME region\n");
+		return INVALID_PARAMETERS;
+	}
+	dlme_start = a->dlme_paddr;
+	dlme_end = a->dlme_paddr + a->dlme_size;
+	dlme_img_start = a->dlme_paddr + a->dlme_img_off;
+	dlme_img_ep = dlme_img_start + a->dlme_img_ep_off;
+	dlme_img_end = dlme_img_start + a->dlme_img_size;
+	dlme_data_start = a->dlme_paddr + a->dlme_data_off;
+	dlme_data_end = dlme_end;
+
+	/* Check the DLME regions arguments. */
+	if ((dlme_start % DRTM_PAGE_SIZE) != 0) {
+		ERROR("DRTM: argument DLME region is not "
+		      DRTM_PAGE_SIZE_STR "-aligned\n");
+		return INVALID_PARAMETERS;
+	}
+
+	if (!(dlme_start < dlme_end &&
+	      dlme_start <= dlme_img_start && dlme_img_start < dlme_img_end &&
+	      dlme_start <= dlme_data_start && dlme_data_start < dlme_data_end)) {
+		ERROR("DRTM: argument DLME region is discontiguous\n");
+		return INVALID_PARAMETERS;
+	}
+
+	if (dlme_img_start < dlme_data_end && dlme_data_start < dlme_img_end) {
+		ERROR("DRTM: argument DLME regions overlap\n");
+		return INVALID_PARAMETERS;
+	}
+
+	/* Check the DLME image region arguments. */
+	if ((dlme_img_start % DRTM_PAGE_SIZE) != 0) {
+		ERROR("DRTM: argument DLME image region is not "
+		      DRTM_PAGE_SIZE_STR "-aligned\n");
+		return INVALID_PARAMETERS;
+	}
+
+	if (!(dlme_img_start <= dlme_img_ep && dlme_img_ep < dlme_img_end)) {
+		ERROR("DRTM: DLME entry point is outside of the DLME image region\n");
+		return INVALID_PARAMETERS;
+	}
+
+	if ((dlme_img_ep % 4) != 0) {
+		ERROR("DRTM: DLME image entry point is not 4-byte-aligned\n");
+		return INVALID_PARAMETERS;
+	}
+
+	/* Check the DLME data region arguments. */
+	if ((dlme_data_start % DRTM_PAGE_SIZE) != 0) {
+		ERROR("DRTM: argument DLME data region is not "
+		      DRTM_PAGE_SIZE_STR "-aligned\n");
+		return INVALID_PARAMETERS;
+	}
+
+	if (dlme_data_end - dlme_data_start < dlme_data_min_size) {
+		ERROR("DRTM: argument DLME data region is short of %lu bytes\n",
+		      dlme_data_min_size - (size_t)(dlme_data_end - dlme_data_start));
+		return INVALID_PARAMETERS;
+	}
+
+	/* check DLME region (paddr + size) is within a NS address region */
+	rc = plat_drtm_validate_ns_region(dlme_start, (size_t)a->dlme_size);
+	if (rc != 0) {
+		ERROR("DRTM: DLME region lies within secure memory\n");
+		return INVALID_PARAMETERS;
+	}
+
+	/* Check the Normal World DCE region arguments. */
+	if (a->dce_nwd_paddr != 0) {
+		uint32_t dce_nwd_start = a->dce_nwd_paddr;
+		uint32_t dce_nwd_end = dce_nwd_start + a->dce_nwd_size;
+
+		if (!(dce_nwd_start < dce_nwd_end)) {
+			ERROR("DRTM: argument Normal World DCE region is dicontiguous\n");
+			return INVALID_PARAMETERS;
+		}
+
+		if (dce_nwd_start < dlme_end && dlme_start < dce_nwd_end) {
+			ERROR("DRTM: argument Normal World DCE regions overlap\n");
+			return INVALID_PARAMETERS;
+		}
+	}
+
+	/*
+	 * Map and sanitize the cache of data range passed by DCE Preamble. This
+	 * is required to avoid / defend against racing with cache evictions
+	 */
+	va_mapping_size = ALIGNED_UP((dlme_end - dlme_start), DRTM_PAGE_SIZE);
+	rc = mmap_add_dynamic_region_alloc_va(dlme_img_start, &va_mapping, va_mapping_size,
+					      MT_MEMORY | MT_NS | MT_RO |
+					      MT_SHAREABILITY_ISH);
+	if (rc != 0) {
+		ERROR("DRTM: %s: mmap_add_dynamic_region_alloc_va() failed rc=%d\n",
+		      __func__, rc);
+		return INTERNAL_ERROR;
+	}
+	flush_dcache_range(va_mapping, va_mapping_size);
+
+	rc = mmap_remove_dynamic_region(va_mapping, va_mapping_size);
+	if (rc) {
+		ERROR("%s(): mmap_remove_dynamic_region() failed unexpectedly"
+		      " rc=%d\n", __func__, rc);
+		panic();
+	}
+
+	*a_out = *a;
+	return SUCCESS;
+}
+
+static void drtm_dl_reset_dlme_el_state(enum drtm_dlme_el dlme_el)
+{
+	uint64_t sctlr;
+
+	/*
+	 * TODO: Set PE state according to the PSCI's specification of the initial
+	 * state after CPU_ON, or to reset values if unspecified, where they exist,
+	 * or define sensible values otherwise.
+	 */
+
+	switch (dlme_el) {
+	case DLME_AT_EL1:
+		sctlr = read_sctlr_el1();
+		break;
+
+	case DLME_AT_EL2:
+		sctlr = read_sctlr_el2();
+		break;
+
+	default: /* Not reached */
+		ERROR("%s(): dlme_el has the unexpected value %d\n",
+		      __func__, dlme_el);
+		panic();
+	}
+
+	sctlr &= ~(/* Disable DLME's EL MMU, since the existing page-tables are untrusted. */
+		   SCTLR_M_BIT
+		   | SCTLR_EE_BIT               /* Little-endian data accesses. */
+		  );
+
+	sctlr |= SCTLR_C_BIT | SCTLR_I_BIT; /* Allow instruction and data caching. */
+
+	switch (dlme_el) {
+	case DLME_AT_EL1:
+		write_sctlr_el1(sctlr);
+		break;
+
+	case DLME_AT_EL2:
+		write_sctlr_el2(sctlr);
+		break;
+	}
+}
+
+static void drtm_dl_reset_dlme_context(enum drtm_dlme_el dlme_el)
+{
+	void *ns_ctx = cm_get_context(NON_SECURE);
+	gp_regs_t *gpregs = get_gpregs_ctx(ns_ctx);
+	uint64_t spsr_el3 = read_ctx_reg(get_el3state_ctx(ns_ctx), CTX_SPSR_EL3);
+
+	/* Reset all gpregs, including SP_EL0. */
+	memset(gpregs, 0, sizeof(*gpregs));
+
+	/* Reset SP_ELx. */
+	switch (dlme_el) {
+	case DLME_AT_EL1:
+		write_sp_el1(0);
+		break;
+
+	case DLME_AT_EL2:
+		write_sp_el2(0);
+		break;
+	}
+
+	/*
+	 * DLME's async exceptions are masked to avoid a NWd attacker's timed
+	 * interference with any state we established trust in or measured.
+	 */
+	spsr_el3 |= SPSR_DAIF_MASK << SPSR_DAIF_SHIFT;
+
+	write_ctx_reg(get_el3state_ctx(ns_ctx), CTX_SPSR_EL3, spsr_el3);
+}
+
+static void drtm_dl_prepare_eret_to_dlme(const struct_drtm_dl_args *args, enum drtm_dlme_el dlme_el)
+{
+	void *ctx = cm_get_context(NON_SECURE);
+	uint64_t dlme_ep = DL_ARGS_GET_DLME_ENTRY_POINT(args);
+	uint64_t spsr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_SPSR_EL3);
+
+	/* Next ERET is to the DLME's EL. */
+	spsr_el3 &= ~(MODE_EL_MASK << MODE_EL_SHIFT);
+	switch (dlme_el) {
+	case DLME_AT_EL1:
+		spsr_el3 |= MODE_EL1 << MODE_EL_SHIFT;
+		break;
+
+	case DLME_AT_EL2:
+		spsr_el3 |= MODE_EL2 << MODE_EL_SHIFT;
+		break;
+	}
+
+	/* Next ERET is to the DLME entry point. */
+	cm_set_elr_spsr_el3(NON_SECURE, dlme_ep, spsr_el3);
+}
+
+static uint64_t drtm_dynamic_launch(uint64_t x1, void *handle)
+{
+	enum drtm_retc ret = SUCCESS;
+	enum drtm_retc dma_prot_ret;
+	struct_drtm_dl_args args;
+	/* DLME should be highest NS exception level */
+	enum drtm_dlme_el dlme_el = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
+
+	/* Ensure that only boot PE is powered on */
+	ret = drtm_dl_check_cores();
+	if (ret != SUCCESS) {
+		SMC_RET1(handle, ret);
+	}
+
+	/*
+	 * Ensure that execution state is AArch64 and the caller
+	 * is highest non-secure exception level
+	 */
+	ret = drtm_dl_check_caller_el(handle);
+	if (ret != SUCCESS) {
+		SMC_RET1(handle, ret);
+	}
+
+	ret = drtm_dl_check_args(x1, &args);
+	if (ret != SUCCESS) {
+		SMC_RET1(handle, ret);
+	}
+
+	/* Ensure that there are no SDEI event registered */
+#if SDEI_SUPPORT
+	if (sdei_get_registered_event_count() != 0) {
+		SMC_RET1(handle, DENIED);
+	}
+#endif /* SDEI_SUPPORT */
+
+	/*
+	 * Engage the DMA protections.  The launch cannot proceed without the DMA
+	 * protections due to potential TOC/TOU vulnerabilities w.r.t. the DLME
+	 * region (and to the NWd DCE region).
+	 */
+	ret = drtm_dma_prot_engage(&args.dma_prot_args,
+				   DL_ARGS_GET_DMA_PROT_TYPE(&args));
+	if (ret != SUCCESS) {
+		SMC_RET1(handle, ret);
+	}
+
+	/*
+	 * The DMA protection is now engaged.  Note that any failure mode that
+	 * returns an error to the DRTM-launch caller must now disengage DMA
+	 * protections before returning to the caller.
+	 */
+
+	ret = drtm_take_measurements(&args);
+	if (ret != SUCCESS) {
+		goto err_undo_dma_prot;
+	}
+
+	ret = drtm_dl_prepare_dlme_data(&args);
+	if (ret != SUCCESS) {
+		goto err_undo_dma_prot;
+	}
+
+	/*
+	 * Note that, at the time of writing, the DRTM spec allows a successful
+	 * launch from NS-EL1 to return to a DLME in NS-EL2.  The practical risk
+	 * of a privilege escalation, e.g. due to a compromised hypervisor, is
+	 * considered small enough not to warrant the specification of additional
+	 * DRTM conduits that would be necessary to maintain OSs' abstraction from
+	 * the presence of EL2 were the dynamic launch only be allowed from the
+	 * highest NS EL.
+	 */
+
+	dlme_el = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
+
+	drtm_dl_reset_dlme_el_state(dlme_el);
+	drtm_dl_reset_dlme_context(dlme_el);
+
+	drtm_dl_prepare_eret_to_dlme(&args, dlme_el);
+
+	/*
+	 * As per DRTM beta0 spec table #28 invalidate the instruction cache
+	 * before jumping to the DLME. This is required to defend against
+	 * potentially-malicious cache contents.
+	 */
+	invalidate_icache_all();
+
+	/* Return the DLME region's address in x0, and the DLME data offset in x1.*/
+	SMC_RET2(handle, args.dlme_paddr, args.dlme_data_off);
+
+err_undo_dma_prot:
+	dma_prot_ret = drtm_dma_prot_disengage();
+	if (dma_prot_ret != SUCCESS) {
+		ERROR("%s(): drtm_dma_prot_disengage() failed unexpectedly"
+		      " rc=%d\n", __func__, ret);
+		panic();
+	}
+
+	SMC_RET1(handle, ret);
+}
+
+uint64_t drtm_smc_handler(uint32_t smc_fid,
+			  uint64_t x1,
+			  uint64_t x2,
+			  uint64_t x3,
+			  uint64_t x4,
+			  void *cookie,
+			  void *handle,
+			  uint64_t flags)
+{
+	/* Check that the SMC call is from the Normal World. */
+	if (!is_caller_non_secure(flags)) {
+		SMC_RET1(handle, NOT_SUPPORTED);
+	}
+
+	switch (smc_fid) {
+	case ARM_DRTM_SVC_VERSION:
+		INFO("DRTM service handler: version\n");
+		/* Return the version of current implementation */
+		SMC_RET1(handle, ARM_DRTM_VERSION);
+		break;	/* not reached */
+
+	case ARM_DRTM_SVC_FEATURES:
+		if (((x1 >> ARM_DRTM_FUNC_SHIFT) & ARM_DRTM_FUNC_MASK) ==
+		    ARM_DRTM_FUNC_ID) {
+			/* Dispatch function-based queries. */
+			switch (x1 & FUNCID_MASK) {
+			case ARM_DRTM_SVC_VERSION:
+				SMC_RET1(handle, SUCCESS);
+				break;	/* not reached */
+
+			case ARM_DRTM_SVC_FEATURES:
+				SMC_RET1(handle, SUCCESS);
+				break;	/* not reached */
+
+			case ARM_DRTM_SVC_UNPROTECT_MEM:
+				SMC_RET1(handle, SUCCESS);
+				break;	/* not reached */
+
+			case ARM_DRTM_SVC_DYNAMIC_LAUNCH:
+				SMC_RET1(handle, SUCCESS);
+				break;	/* not reached */
+
+			case ARM_DRTM_SVC_CLOSE_LOCALITY:
+				WARN("ARM_DRTM_SVC_CLOSE_LOCALITY feature %s",
+				     "is not supported\n");
+				SMC_RET1(handle, NOT_SUPPORTED);
+				break;	/* not reached */
+
+			case ARM_DRTM_SVC_GET_ERROR:
+				SMC_RET1(handle, SUCCESS);
+				break;	/* not reached */
+
+			case ARM_DRTM_SVC_SET_ERROR:
+				SMC_RET1(handle, SUCCESS);
+				break;	/* not reached */
+
+			case ARM_DRTM_SVC_SET_TCB_HASH:
+				WARN("ARM_DRTM_SVC_TCB_HASH feature %s",
+				     "is not supported\n");
+				SMC_RET1(handle, NOT_SUPPORTED);
+				break;	/* not reached */
+
+			case ARM_DRTM_SVC_LOCK_TCB_HASH:
+				WARN("ARM_DRTM_SVC_LOCK_TCB_HASH feature %s",
+				     "is not supported\n");
+				SMC_RET1(handle, NOT_SUPPORTED);
+				break;	/* not reached */
+
+			default:
+				ERROR("Unknown DRTM service function\n");
+				SMC_RET1(handle, NOT_SUPPORTED);
+				break;	/* not reached */
+			}
+		} else {
+			/* Dispatch feature-based queries. */
+			switch (x1 & ARM_DRTM_FEAT_ID_MASK) {
+			case ARM_DRTM_FEATURES_TPM:
+				INFO("++ DRTM service handler: TPM features\n");
+				return drtm_features_tpm(handle);
+				break;	/* not reached */
+
+			case ARM_DRTM_FEATURES_MEM_REQ:
+				INFO("++ DRTM service handler: Min. mem."
+				     " requirement features\n");
+				return drtm_features_mem_req(handle);
+				break;	/* not reached */
+
+			case ARM_DRTM_FEATURES_DMA_PROT:
+				INFO("++ DRTM service handler: "
+				     "DMA protection features\n");
+				return drtm_features_dma_prot(handle);
+				break;	/* not reached */
+
+			case ARM_DRTM_FEATURES_BOOT_PE_ID:
+				INFO("++ DRTM service handler: "
+				     "Boot PE ID features\n");
+				return drtm_features_boot_pe_id(handle);
+				break;	/* not reached */
+
+			case ARM_DRTM_FEATURES_TCB_HASHES:
+				INFO("++ DRTM service handler: "
+				     "TCB-hashes features\n");
+				return drtm_features_tcb_hashes(handle);
+				break;	/* not reached */
+
+			default:
+				ERROR("Unknown ARM DRTM service feature\n");
+				SMC_RET1(handle, NOT_SUPPORTED);
+				break;	/* not reached */
+			}
+		}
+
+	case ARM_DRTM_SVC_UNPROTECT_MEM:
+		INFO("DRTM service handler: unprotect mem\n");
+		return drtm_unprotect_mem(handle);
+		break;	/* not reached */
+
+	case ARM_DRTM_SVC_DYNAMIC_LAUNCH:
+		INFO("DRTM service handler: dynamic launch\n");
+		return drtm_dynamic_launch(x1, handle);
+		break;	/* not reached */
+
+	case ARM_DRTM_SVC_CLOSE_LOCALITY:
+		WARN("DRTM service handler: close locality %s\n",
+		     "is not supported");
+		SMC_RET1(handle, NOT_SUPPORTED);
+		break;	/* not reached */
+
+	case ARM_DRTM_SVC_GET_ERROR:
+		INFO("DRTM service handler: get error\n");
+		drtm_get_error(handle);
+		break;	/* not reached */
+
+	case ARM_DRTM_SVC_SET_ERROR:
+		INFO("DRTM service handler: set error\n");
+		drtm_set_error(x1, handle);
+		break;	/* not reached */
+
+	case ARM_DRTM_SVC_SET_TCB_HASH:
+		WARN("DRTM service handler: set TCB hash %s\n",
+		     "is not supported");
+		SMC_RET1(handle, NOT_SUPPORTED);
+		break;  /* not reached */
+
+	case ARM_DRTM_SVC_LOCK_TCB_HASH:
+		WARN("DRTM service handler: lock TCB hash %s\n",
+		     "is not supported");
+		SMC_RET1(handle, NOT_SUPPORTED);
+		break;  /* not reached */
+
+	default:
+		ERROR("Unknown DRTM service function: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+		break;	/* not reached */
+	}
+
+	/* not reached */
+	SMC_RET1(handle, SMC_UNK);
+}
diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h
new file mode 100644
index 0000000..baa37ae
--- /dev/null
+++ b/services/std_svc/drtm/drtm_main.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ */
+#ifndef DRTM_MAIN_H
+#define DRTM_MAIN_H
+
+#include <stdint.h>
+
+#include <assert.h>
+#include <lib/smccc.h>
+
+#include "drtm_dma_prot.h"
+
+#define ALIGNED_UP(x, a) __extension__ ({ \
+	__typeof__(a) _a = (a); \
+	__typeof__(a) _one = 1; \
+	assert(IS_POWER_OF_TWO(_a)); \
+	((x) + (_a - _one)) & ~(_a - _one); \
+})
+
+#define ALIGNED_DOWN(x, a) __extension__ ({ \
+	__typeof__(a) _a = (a); \
+	__typeof__(a) _one = 1; \
+	assert(IS_POWER_OF_TWO(_a)); \
+	(x) & ~(_a - _one); \
+})
+
+#define DRTM_PAGE_SIZE		(4 * (1 << 10))
+#define DRTM_PAGE_SIZE_STR	"4-KiB"
+
+#define DL_ARGS_GET_DMA_PROT_TYPE(a)    (((a)->features >> 3) & 0x7U)
+#define DL_ARGS_GET_PCR_SCHEMA(a)	(((a)->features >> 1) & 0x3U)
+#define DL_ARGS_GET_DLME_ENTRY_POINT(a)	\
+		(((a)->dlme_paddr + (a)->dlme_img_off + (a)->dlme_img_ep_off))
+
+enum drtm_dlme_el {
+	DLME_AT_EL1 = MODE_EL1,
+	DLME_AT_EL2 = MODE_EL2
+};
+
+enum drtm_retc {
+	SUCCESS = SMC_OK,
+	NOT_SUPPORTED = SMC_UNK,
+	INVALID_PARAMETERS = -2,
+	DENIED = -3,
+	NOT_FOUND = -4,
+	INTERNAL_ERROR = -5,
+	MEM_PROTECT_INVALID = -6,
+};
+
+typedef struct {
+	uint64_t tpm_features;
+	uint64_t minimum_memory_requirement;
+	uint64_t dma_prot_features;
+	uint64_t boot_pe_id;
+	uint64_t tcb_hash_features;
+} drtm_features_t;
+
+struct __packed drtm_dl_args_v1 {
+	uint16_t version;	/* Must be 1. */
+	uint8_t __res[2];
+	uint32_t features;
+	uint64_t dlme_paddr;
+	uint64_t dlme_size;
+	uint64_t dlme_img_off;
+	uint64_t dlme_img_ep_off;
+	uint64_t dlme_img_size;
+	uint64_t dlme_data_off;
+	uint64_t dce_nwd_paddr;
+	uint64_t dce_nwd_size;
+	drtm_dl_dma_prot_args_v1_t dma_prot_args;
+} __aligned(__alignof(uint16_t /* First member's type, `uint16_t version' */));
+
+struct __packed dlme_data_header_v1 {
+	uint16_t version;	/* Must be 1. */
+	uint16_t this_hdr_size;
+	uint8_t __res[4];
+	uint64_t dlme_data_size;
+	uint64_t dlme_prot_regions_size;
+	uint64_t dlme_addr_map_size;
+	uint64_t dlme_tpm_log_size;
+	uint64_t dlme_tcb_hashes_table_size;
+	uint64_t dlme_impdef_region_size;
+} __aligned(__alignof(uint16_t /* First member's type, `uint16_t version'. */));
+
+typedef struct dlme_data_header_v1 struct_dlme_data_header;
+
+drtm_memory_region_descriptor_table_t *drtm_build_address_map(void);
+uint64_t drtm_get_address_map_size(void);
+
+/*
+ * Version-independent type.  May be used to avoid excessive line of code
+ * changes when migrating to new struct versions.
+ */
+typedef struct drtm_dl_args_v1 struct_drtm_dl_args;
+
+#endif /* DRTM_MAIN_H */
diff --git a/services/std_svc/drtm/drtm_measurements.c b/services/std_svc/drtm/drtm_measurements.c
new file mode 100644
index 0000000..a8f2b32
--- /dev/null
+++ b/services/std_svc/drtm/drtm_measurements.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ * DRTM measurements into TPM PCRs.
+ *
+ * Authors:
+ *      Lucian Paul-Trifu <lucian.paultrifu@gmail.com>
+ *
+ */
+#include <assert.h>
+
+#include <common/debug.h>
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/measured_boot/event_log/event_log.h>
+#include "drtm_main.h"
+#include "drtm_measurements.h"
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+/* Event Log buffer */
+static uint8_t drtm_event_log[PLAT_DRTM_EVENT_LOG_MAX_SIZE];
+
+/*
+ * Calculate and write hash of various payloads as per DRTM specification
+ * to Event Log.
+ *
+ * @param[in] data_base         Address of data
+ * @param[in] data_size         Size of data
+ * @param[in] event_type        Type of Event
+ * @param[in] event_name        Name of the Event
+ * @return:
+ *      0 = success
+ *    < 0 = error
+ */
+static int drtm_event_log_measure_and_record(uintptr_t data_base,
+					     uint32_t data_size,
+					     uint32_t event_type,
+					     const char *event_name,
+					     unsigned int pcr)
+{
+	int rc;
+	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
+	event_log_metadata_t metadata = {0};
+
+	metadata.name = event_name;
+	metadata.pcr = pcr;
+
+	/*
+	 * Measure the payloads requested by D-CRTM and DCE commponents
+	 * Hash algorithm decided by the Event Log driver at build-time
+	 */
+	rc = event_log_measure(data_base, data_size, hash_data);
+	if (rc != 0) {
+		return rc;
+	}
+
+	/* Record the mesasurement in the EventLog buffer */
+	event_log_record(hash_data, event_type, &metadata);
+
+	return 0;
+}
+
+/*
+ * Initialise Event Log global variables, used during the recording
+ * of various payload measurements into the Event Log buffer
+ *
+ * @param[in] event_log_start           Base address of Event Log buffer
+ * @param[in] event_log_finish          End address of Event Log buffer,
+ *                                      it is a first byte past end of the
+ *                                      buffer
+ */
+static void drtm_event_log_init(uint8_t *event_log_start,
+				uint8_t *event_log_finish)
+{
+	event_log_buf_init(event_log_start, event_log_finish);
+	event_log_write_specid_event();
+}
+
+enum drtm_retc drtm_take_measurements(const struct_drtm_dl_args *a)
+{
+	int rc;
+	uintptr_t dlme_img_mapping;
+	uint64_t dlme_img_ep;
+	size_t dlme_img_mapping_bytes;
+	uint8_t drtm_null_data = 0U;
+	uint8_t pcr_schema = DL_ARGS_GET_PCR_SCHEMA(a);
+	const char *drtm_event_arm_sep_data = "ARM_DRTM";
+
+	/* Initialise the EventLog driver */
+	drtm_event_log_init(drtm_event_log, drtm_event_log +
+			    sizeof(drtm_event_log));
+
+	/**
+	 * Measurements extended into PCR-17.
+	 *
+	 * PCR-17: Measure the DCE image.  Extend digest of (char)0 into PCR-17
+	 * since the D-CRTM and the DCE are not separate.
+	 */
+	rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data,
+					       sizeof(drtm_null_data),
+					       DRTM_EVENT_ARM_DCE, NULL,
+					       PCR_17);
+	CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE));
+
+	/* PCR-17: Measure the PCR schema DRTM launch argument. */
+	rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema,
+					       sizeof(pcr_schema),
+					       DRTM_EVENT_ARM_PCR_SCHEMA,
+					       NULL, PCR_17);
+	CHECK_RC(rc,
+		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA));
+
+	/* PCR-17: Measure the enable state of external-debug, and trace. */
+	/*
+	 * TODO: Measure the enable state of external-debug and trace.  This should
+	 * be returned through a platform-specific hook.
+	 */
+
+	/* PCR-17: Measure the security lifecycle state. */
+	/*
+	 * TODO: Measure the security lifecycle state.  This is an implementation-
+	 * defined value, retrieved through an implementation-defined mechanisms.
+	 */
+
+	/*
+	 * PCR-17: Optionally measure the NWd DCE.
+	 * It is expected that such subsequent DCE stages are signed and verified.
+	 * Whether they are measured in addition to signing is implementation
+	 * -defined.
+	 * Here the choice is to not measure any NWd DCE, in favour of PCR value
+	 * resilience to any NWd DCE updates.
+	 */
+
+	/* PCR-17: End of DCE measurements. */
+	rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data,
+					       strlen(drtm_event_arm_sep_data),
+					       DRTM_EVENT_ARM_SEPARATOR, NULL,
+					       PCR_17);
+	CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR));
+
+	/**
+	 * Measurements extended into PCR-18.
+	 *
+	 * PCR-18: Measure the PCR schema DRTM launch argument.
+	 */
+	rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema,
+					       sizeof(pcr_schema),
+					       DRTM_EVENT_ARM_PCR_SCHEMA,
+					       NULL, PCR_18);
+	CHECK_RC(rc,
+		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA));
+
+	/*
+	 * PCR-18: Measure the public key used to verify DCE image(s) signatures.
+	 * Extend digest of (char)0, since we do not expect the NWd DCE to be
+	 * present.
+	 */
+	assert(a->dce_nwd_size == 0);
+	rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data,
+					       sizeof(drtm_null_data),
+					       DRTM_EVENT_ARM_DCE_PUBKEY,
+					       NULL, PCR_18);
+	CHECK_RC(rc,
+		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE_PUBKEY));
+
+	/* PCR-18: Measure the DLME image. */
+	dlme_img_mapping_bytes = page_align(a->dlme_img_size, UP);
+	rc = mmap_add_dynamic_region_alloc_va(a->dlme_paddr + a->dlme_img_off,
+					      &dlme_img_mapping,
+					      dlme_img_mapping_bytes, MT_RO_DATA | MT_NS);
+	if (rc) {
+		WARN("DRTM: %s: mmap_add_dynamic_region() failed rc=%d\n",
+		     __func__, rc);
+		return INTERNAL_ERROR;
+	}
+
+	rc = drtm_event_log_measure_and_record(dlme_img_mapping, a->dlme_img_size,
+					       DRTM_EVENT_ARM_DLME, NULL,
+					       PCR_18);
+	CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME));
+
+	rc = mmap_remove_dynamic_region(dlme_img_mapping, dlme_img_mapping_bytes);
+	CHECK_RC(rc, mmap_remove_dynamic_region);
+
+	/* PCR-18: Measure the DLME image entry point. */
+	dlme_img_ep = DL_ARGS_GET_DLME_ENTRY_POINT(a);
+	drtm_event_log_measure_and_record((uintptr_t)&dlme_img_ep,
+					  sizeof(dlme_img_ep),
+					  DRTM_EVENT_ARM_DLME_EP, NULL,
+					  PCR_18);
+	CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME_EP));
+
+	/* PCR-18: End of DCE measurements. */
+	rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data,
+					       strlen(drtm_event_arm_sep_data),
+					       DRTM_EVENT_ARM_SEPARATOR, NULL,
+					       PCR_18);
+	CHECK_RC(rc,
+		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR));
+	/*
+	 * If the DCE is unable to log a measurement because there is no available
+	 * space in the event log region, the DCE must extend a hash of the value
+	 * 0xFF (1 byte in size) into PCR[17] and PCR[18] and enter remediation.
+	 */
+
+	return SUCCESS;
+}
+
+void drtm_serialise_event_log(uint8_t *dst, size_t *event_log_size_out)
+{
+	*event_log_size_out = event_log_get_cur_size(drtm_event_log);
+	memcpy(dst, drtm_event_log, *event_log_size_out);
+}
diff --git a/services/std_svc/drtm/drtm_measurements.h b/services/std_svc/drtm/drtm_measurements.h
new file mode 100644
index 0000000..6d7a84e
--- /dev/null
+++ b/services/std_svc/drtm/drtm_measurements.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ */
+#ifndef DRTM_MEASUREMENTS_H
+#define DRTM_MEASUREMENTS_H
+
+#include <stdint.h>
+
+#include "drtm_main.h"
+#include <platform_def.h>
+
+#define DRTM_EVENT_ARM_BASE		0x9000U
+#define DRTM_EVENT_TYPE(n)		(DRTM_EVENT_ARM_BASE + (unsigned int)(n))
+
+#define DRTM_EVENT_ARM_PCR_SCHEMA	DRTM_EVENT_TYPE(1)
+#define DRTM_EVENT_ARM_DCE		DRTM_EVENT_TYPE(2)
+#define DRTM_EVENT_ARM_DCE_PUBKEY	DRTM_EVENT_TYPE(3)
+#define DRTM_EVENT_ARM_DLME		DRTM_EVENT_TYPE(4)
+#define DRTM_EVENT_ARM_DLME_EP		DRTM_EVENT_TYPE(5)
+#define DRTM_EVENT_ARM_DEBUG_CONFIG	DRTM_EVENT_TYPE(6)
+#define DRTM_EVENT_ARM_NONSECURE_CONFIG	DRTM_EVENT_TYPE(7)
+#define DRTM_EVENT_ARM_DCE_SECONDARY	DRTM_EVENT_TYPE(8)
+#define DRTM_EVENT_ARM_TZFW		DRTM_EVENT_TYPE(9)
+#define DRTM_EVENT_ARM_SEPARATOR	DRTM_EVENT_TYPE(10)
+
+#define CHECK_RC(rc, func_call) { \
+	if (rc != 0) { \
+		ERROR("%s(): " #func_call "failed unexpectedly rc=%d\n",  \
+		      __func__, rc);  \
+		panic();  \
+	}  \
+}
+
+enum drtm_retc drtm_take_measurements(const struct_drtm_dl_args *a);
+void drtm_serialise_event_log(uint8_t *dst, size_t *event_log_size_out);
+
+#endif /* DRTM_MEASUREMENTS_H */
diff --git a/services/std_svc/drtm/drtm_remediation.c b/services/std_svc/drtm/drtm_remediation.c
new file mode 100644
index 0000000..696b4ea
--- /dev/null
+++ b/services/std_svc/drtm/drtm_remediation.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ * DRTM support for DRTM error remediation.
+ *
+ */
+#include <inttypes.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include "drtm_main.h"
+#include <plat/common/platform.h>
+
+uint64_t drtm_set_error(uint64_t x1, void *ctx)
+{
+	int rc;
+
+	rc = plat_set_drtm_error(x1);
+
+	if (rc != 0) {
+		SMC_RET1(ctx, INTERNAL_ERROR);
+	}
+
+	SMC_RET1(ctx, SUCCESS);
+}
+
+uint64_t drtm_get_error(void *ctx)
+{
+	uint64_t error_code;
+	int rc;
+
+	rc = plat_get_drtm_error(&error_code);
+
+	if (rc != 0) {
+		SMC_RET1(ctx, INTERNAL_ERROR);
+	}
+
+	SMC_RET2(ctx, SUCCESS, error_code);
+}
+
+void drtm_enter_remediation(uint64_t err_code, const char *err_str)
+{
+	int rc = plat_set_drtm_error(err_code);
+
+	if (rc != 0) {
+		ERROR("%s(): drtm_error_set() failed unexpectedly rc=%d\n",
+		      __func__, rc);
+		panic();
+	}
+
+	ERROR("DRTM: entering remediation of error:\n%" PRIu64 "\t\'%s\'\n",
+	       err_code, err_str);
+
+	ERROR("%s(): system reset is not yet supported\n", __func__);
+	plat_system_reset();
+}
diff --git a/services/std_svc/drtm/drtm_remediation.h b/services/std_svc/drtm/drtm_remediation.h
new file mode 100644
index 0000000..8f965f1
--- /dev/null
+++ b/services/std_svc/drtm/drtm_remediation.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ */
+#ifndef DRTM_REMEDIATION_H
+#define DRTM_REMEDIATION_H
+
+uint64_t drtm_set_error(uint64_t x1, void *ctx);
+uint64_t drtm_get_error(void *ctx);
+
+void drtm_enter_remediation(uint64_t error_code, const char *error_str);
+
+#endif /* DRTM_REMEDIATION_H */
diff --git a/services/std_svc/drtm/drtm_res_address_map.c b/services/std_svc/drtm/drtm_res_address_map.c
new file mode 100644
index 0000000..8636706
--- /dev/null
+++ b/services/std_svc/drtm/drtm_res_address_map.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <plat/common/platform.h>
+#include <services/drtm_svc.h>
+#include <platform_def.h>
+
+/* Address map revision generated by this code. */
+#define DRTM_ADDRESS_MAP_REVISION	U(0x0001)
+
+/* Amount of space needed for address map based on PLAT_DRTM_MMAP_ENTRIES */
+#define DRTM_ADDRESS_MAP_SIZE (sizeof(drtm_memory_region_descriptor_table_t) + \
+			       (sizeof(drtm_mem_region_t) * \
+				PLAT_DRTM_MMAP_ENTRIES))
+
+/* Allocate space for DRTM-formatted address map to be constructed. */
+static uint8_t drtm_address_map[DRTM_ADDRESS_MAP_SIZE];
+
+static uint64_t drtm_address_map_size;
+
+drtm_memory_region_descriptor_table_t *drtm_build_address_map(void)
+{
+	/* Set up pointer to DRTM memory map. */
+	drtm_memory_region_descriptor_table_t *map =
+		(drtm_memory_region_descriptor_table_t *)drtm_address_map;
+
+	/* Get the platform memory map. */
+	const mmap_region_t *mmap = plat_get_addr_mmap();
+	unsigned int i;
+
+	/* Set up header for address map structure. */
+	map->revision = DRTM_ADDRESS_MAP_REVISION;
+	map->reserved = 0x0000;
+
+	/* Iterate through mmap and generate DRTM address map. */
+	for (i = 0U; mmap[i].base_pa != 0UL; i++) {
+		/* Set PA of region. */
+		map->region[i].region_address = mmap[i].base_pa;
+
+		/* Set size of region (in 4kb chunks). */
+		map->region[i].region_size_type = 0;
+		ARM_DRTM_REGION_SIZE_TYPE_SET_4K_PAGE_NUM(
+			map->region[i].region_size_type,
+			mmap[i].size / PAGE_SIZE_4KB);
+
+		/* Set type and cacheability. */
+		switch (MT_TYPE(mmap[i].attr)) {
+		case MT_DEVICE:
+			ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(
+				map->region[i].region_size_type,
+				ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_DEVICE);
+			break;
+		case MT_NON_CACHEABLE:
+			ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(
+				map->region[i].region_size_type,
+				ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NCAR);
+			ARM_DRTM_REGION_SIZE_TYPE_SET_CACHEABILITY(
+				map->region[i].region_size_type,
+				ARM_DRTM_REGION_SIZE_TYPE_CACHEABILITY_NC);
+			break;
+		case MT_MEMORY:
+			ARM_DRTM_REGION_SIZE_TYPE_SET_REGION_TYPE(
+				map->region[i].region_size_type,
+				ARM_DRTM_REGION_SIZE_TYPE_REGION_TYPE_NORMAL);
+			break;
+		default:
+			return NULL;
+		}
+	}
+
+	map->num_regions = i;
+
+	/* Store total size of address map. */
+	drtm_address_map_size = sizeof(drtm_memory_region_descriptor_table_t);
+	drtm_address_map_size += (i * sizeof(drtm_mem_region_t));
+
+	return map;
+}
+
+uint64_t drtm_get_address_map_size(void)
+{
+	return drtm_address_map_size;
+}
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 7cb76de..6bd9fdf 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -242,10 +242,12 @@
  * Forward SMC to the other security state
  ******************************************************************************/
 static uint64_t	rmmd_smc_forward(uint32_t src_sec_state,
-					uint32_t dst_sec_state, uint64_t x0,
-					uint64_t x1, uint64_t x2, uint64_t x3,
-					uint64_t x4, void *handle)
+				 uint32_t dst_sec_state, uint64_t x0,
+				 uint64_t x1, uint64_t x2, uint64_t x3,
+				 uint64_t x4, void *handle)
 {
+	cpu_context_t *ctx = cm_get_context(dst_sec_state);
+
 	/* Save incoming security state */
 	cm_el1_sysregs_context_save(src_sec_state);
 	cm_el2_sysregs_context_save(src_sec_state);
@@ -256,19 +258,21 @@
 	cm_set_next_eret_context(dst_sec_state);
 
 	/*
-	 * As per SMCCCv1.1, we need to preserve x4 to x7 unless
+	 * As per SMCCCv1.2, we need to preserve x4 to x7 unless
 	 * being used as return args. Hence we differentiate the
 	 * onward and backward path. Support upto 8 args in the
 	 * onward path and 4 args in return path.
+	 * Register x4 will be preserved by RMM in case it is not
+	 * used in return path.
 	 */
 	if (src_sec_state == NON_SECURE) {
-		SMC_RET8(cm_get_context(dst_sec_state), x0, x1, x2, x3, x4,
-				SMC_GET_GP(handle, CTX_GPREG_X5),
-				SMC_GET_GP(handle, CTX_GPREG_X6),
-				SMC_GET_GP(handle, CTX_GPREG_X7));
-	} else {
-		SMC_RET4(cm_get_context(dst_sec_state), x0, x1, x2, x3);
+		SMC_RET8(ctx, x0, x1, x2, x3, x4,
+			 SMC_GET_GP(handle, CTX_GPREG_X5),
+			 SMC_GET_GP(handle, CTX_GPREG_X6),
+			 SMC_GET_GP(handle, CTX_GPREG_X7));
 	}
+
+	SMC_RET5(ctx, x0, x1, x2, x3, x4);
 }
 
 /*******************************************************************************
@@ -276,8 +280,8 @@
  * either forwarded to the other security state or handled by the RMM dispatcher
  ******************************************************************************/
 uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
-				uint64_t x3, uint64_t x4, void *cookie,
-				void *handle, uint64_t flags)
+			  uint64_t x3, uint64_t x4, void *cookie,
+			  void *handle, uint64_t flags)
 {
 	uint32_t src_sec_state;
 
@@ -311,10 +315,12 @@
 	}
 
 	switch (smc_fid) {
-	case RMM_RMI_REQ_COMPLETE:
-		return rmmd_smc_forward(REALM, NON_SECURE, x1,
-					x2, x3, x4, 0, handle);
+	case RMM_RMI_REQ_COMPLETE: {
+		uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
 
+		return rmmd_smc_forward(REALM, NON_SECURE, x1,
+					x2, x3, x4, x5, handle);
+	}
 	default:
 		WARN("RMMD: Unsupported RMM call 0x%08x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
diff --git a/services/std_svc/sdei/sdei_event.c b/services/std_svc/sdei/sdei_event.c
index 0b608e1..e0c7971 100644
--- a/services/std_svc/sdei/sdei_event.c
+++ b/services/std_svc/sdei/sdei_event.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
  */
@@ -99,3 +99,24 @@
 
 	return NULL;
 }
+
+/*
+ * Return the total number of currently registered SDEI events.
+ */
+int sdei_get_registered_event_count(void)
+{
+	const sdei_mapping_t *mapping;
+	sdei_ev_map_t *map;
+	unsigned int i;
+	unsigned int j;
+	int count = 0;
+
+	/* Add up reg counts for each mapping. */
+	for_each_mapping_type(i, mapping) {
+		iterate_mapping(mapping, j, map) {
+			count += map->reg_count;
+		}
+	}
+
+	return count;
+}
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
index d62be91..5233650 100644
--- a/services/std_svc/spm/el3_spmc/spmc.h
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -9,6 +9,7 @@
 
 #include <stdint.h>
 
+#include <common/bl_common.h>
 #include <lib/psci/psci.h>
 #include <lib/spinlock.h>
 #include <services/el3_spmc_logical_sp.h>
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 07fecb6..d21a622 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -7,6 +7,7 @@
 #ifndef SPMD_PRIVATE_H
 #define SPMD_PRIVATE_H
 
+#include <common/bl_common.h>
 #include <context.h>
 
 /*******************************************************************************
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index b1e3db9..08d16e2 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -13,6 +13,7 @@
 #include <lib/pmf/pmf.h>
 #include <lib/psci/psci.h>
 #include <lib/runtime_instr.h>
+#include <services/drtm_svc.h>
 #include <services/pci_svc.h>
 #include <services/rmmd_svc.h>
 #include <services/sdei.h>
@@ -75,6 +76,12 @@
 
 	trng_setup();
 
+#if DRTM_SUPPORT
+	if (drtm_setup() != 0) {
+		ret = 1;
+	}
+#endif /* DRTM_SUPPORT */
+
 	return ret;
 }
 
@@ -186,6 +193,13 @@
 	}
 #endif
 
+#if DRTM_SUPPORT
+	if (is_drtm_fid(smc_fid)) {
+		return drtm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
+					flags);
+	}
+#endif /* DRTM_SUPPORT */
+
 	switch (smc_fid) {
 	case ARM_STD_SVC_CALL_COUNT:
 		/*
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index 814d051..f3af584 100644
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -90,7 +90,7 @@
 def is_line_in_sp_gen(line, args :dict):
     with open(args["sp_gen_mk"], "r") as f:
         sppkg_rule = [l for l in f if line in l]
-    return len(sppkg_rule) is not 0
+    return len(sppkg_rule) != 0
 
 def get_file_from_layout(node):
     ''' Helper to fetch a file path from sp_layout.json. '''
@@ -196,11 +196,11 @@
     ''' Generate arguments for the FIP Tool. '''
     if "uuid" in sp_layout[sp]:
         # Extract the UUID from the JSON file if the SP entry has a 'uuid' field
-        uuid_std = uuid.UUID(data[key]['uuid'])
+        uuid_std = uuid.UUID(sp_layout[sp]['uuid'])
     else:
         with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
             uuid_lines = [l for l in pm_f if 'uuid' in l]
-        assert(len(uuid_lines) is 1)
+        assert(len(uuid_lines) == 1)
         # The uuid field in SP manifest is the little endian representation
         # mapped to arguments as described in SMCCC section 5.3.
         # Convert each unsigned integer value to a big endian representation