Merge changes from topic "advk-serror" into integration

* changes:
  fix(plat/marvell/a3k): disable HANDLE_EA_EL3_FIRST by default
  fix(plat/marvell/a3k): update information about PCIe abort hack
diff --git a/Makefile b/Makefile
index b4bebf1..8411355 100644
--- a/Makefile
+++ b/Makefile
@@ -525,6 +525,10 @@
         ifeq ($(TS_SP_FW_CONFIG),1)
             DTC_CPPFLAGS	+=	-DTS_SP_FW_CONFIG
         endif
+
+        ifneq ($(ARM_BL2_SP_LIST_DTS),)
+            DTC_CPPFLAGS += -DARM_BL2_SP_LIST_DTS=$(ARM_BL2_SP_LIST_DTS)
+        endif
     else
         # All other SPDs in spd directory
         SPD_DIR := spd
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index bc277a7..bde6d97 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -281,6 +281,19 @@
 -  ``ERRATA_A78_1821534``: This applies errata 1821534 workaround to Cortex-A78
    CPU. This needs to be enabled for revisions r0p0 and r1p0.
 
+-  ``ERRATA_A78_1952683``: This applies errata 1952683 workaround to Cortex-A78
+   CPU. This needs to be enabled for revision r0p0, it is fixed in r1p0.
+
+For Cortex-A78 AE, the following errata build flags are defined :
+
+- ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to Cortex-A78
+   AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This erratum is
+   still open.
+
+- ``ERRATA_A78_AE_1951502`` : This applies errata 1951502 workaround to Cortex-A78
+  AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This erratum is
+  still open.
+
 For Neoverse N1, the following errata build flags are defined :
 
 -  ``ERRATA_N1_1073348``: This applies errata 1073348 workaround to Neoverse-N1
@@ -323,6 +336,11 @@
    CPU. This needs to be enabled for revisions r3p0, r3p1, r4p0, and r4p1, for
    revisions r0p0, r1p0, and r2p0 there is no workaround.
 
+For Neoverse N2, the following errata build flags are defined :
+
+-  ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU, it is still open.
+
 For Neoverse V1, the following errata build flags are defined :
 
 -  ``ERRATA_V1_1774420``: This applies errata 1774420 workaround to Neoverse-V1
@@ -353,6 +371,38 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the
    CPU.  It is still open.
 
+For Cortex-A710, the following errata build flags are defined :
+
+-  ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
+   Cortex-A710 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
+   r2p0 of the CPU. It is still open.
+
+-  ``ERRATA_A710_2081180``: This applies errata 2081180 workaround to
+   Cortex-A710 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
+   r2p0 of the CPU. It is still open.
+
+-  ``ERRATA_A710_2055002``: This applies errata 2055002 workaround to
+   Cortex-A710 CPU. This needs to be enabled for revisions r1p0, r2p0 of the CPU
+   and is still open.
+
+-  ``ERRATA_A710_2017096``: This applies errata 2017096 workaround to
+   Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
+   of the CPU and is still open.
+
+For Neoverse N2, the following errata build flags are defined :
+
+-  ``ERRATA_N2_2067956``: This applies errata 2067956 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+-  ``ERRATA_N2_2025414``: This applies errata 2025414 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+-  ``ERRATA_N2_2189731``: This applies errata 2189731 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
+-  ``ERRATA_N2_2138956``: This applies errata 2138956 workaround to Neoverse-N2
+   CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+
 DSU Errata Workarounds
 ----------------------
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 901a72a..bac8847 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -790,6 +790,11 @@
    GIC-600, so is safe to select even for a GIC500 implementation.
    This option defaults to 0.
 
+- ``GICV3_SUPPORT_GIC600AE_FMU``: Add support for the Fault Management Unit
+   for GIC-600 AE. Enabling this option will introduce support to initialize
+   the FMU. Platforms should call the init function during boot to enable the
+   FMU and its safety mechanisms. This option defaults to 0.
+
 -  ``GICV3_IMPL_GIC600_MULTICHIP``: Selects GIC-600 variant with multichip
    functionality. This option defaults to 0
 
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index d4fa98d..74251bd 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -100,6 +100,9 @@
 -  ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the
    SPMC Core manifest. Valid when ``SPD=spmd`` is selected.
 
+-  ``ARM_BL2_SP_LIST_DTS``: Path to DTS file snippet to override the hardcoded
+   SP nodes in tb_fw_config.
+
 -  ``OPTEE_SP_FW_CONFIG``: DTC build flag to include OP-TEE as SP in tb_fw_config
    device tree. This flag is defined only when ``ARM_SPMC_MANIFEST_DTS`` manifest
    file name contains pattern optee_sp.
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 4dc9ecd..5848005 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -27,6 +27,7 @@
    imx8
    imx8m
    ls1043a
+   nxp/index
    poplar
    qemu
    qemu-sbsa
diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst
index b10fb3a..b125144 100644
--- a/docs/plat/marvell/armada/build.rst
+++ b/docs/plat/marvell/armada/build.rst
@@ -62,6 +62,7 @@
             - a80x0_mcbin  - MacchiatoBin
             - a80x0_puzzle - IEI Puzzle-M801
             - t9130        - CN913x
+            - t9130_cex7_eval - CN913x CEx7 Evaluation Board
 
 - DEBUG
 
@@ -136,6 +137,19 @@
         The parameter is optional, its default value is ``plat/marvell/armada/a8k/common/ble``
         which uses TF-A in-tree BLE implementation.
 
+- MSS_SUPPORT
+
+        When ``MSS_SUPPORT=1``, then TF-A includes support for Management SubSystem (MSS).
+        When enabled it is required to specify path to the MSS firmware image via ``SCP_BL2``
+        option.
+
+        This option is by default enabled.
+
+- SCP_BL2
+
+        Specify path to the MSS fimware image binary which will run on Cortex-M3 coprocessor.
+        It is available in Marvell binaries-marvell git repository. Required when ``MSS_SUPPORT=1``.
+
 
 Armada37x0 specific build options:
 
@@ -428,10 +442,15 @@
 
     https://gitlab.nic.cz/turris/mox-boot-builder.git
 
-Armada70x0 and Armada80x0 Builds require installation of an additional component
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Armada70x0, Armada80x0 and CN913x Builds require installation of additional components
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 (1) DDR initialization library sources (mv_ddr) available at the following repository
     (use the "master" branch):
 
     https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git
+
+(2) MSS Management SubSystem Firmware available at the following repository
+    (use the "binaries-marvell-armada-SDK10.0.1.0" branch):
+
+    https://github.com/MarvellEmbeddedProcessors/binaries-marvell.git
diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst
index 02ff38b..391c7c8 100644
--- a/docs/plat/nvidia-tegra.rst
+++ b/docs/plat/nvidia-tegra.rst
@@ -19,7 +19,7 @@
 multi-processing (HMP) solution designed to optimize performance and
 efficiency.
 
-T186 has Dual NVIDIA Denver 2 ARM® CPU cores, plus Quad ARM Cortex®-A57 cores,
+T186 has Dual NVIDIA Denver2 ARM® CPU cores, plus Quad ARM Cortex®-A57 cores,
 in a coherent multiprocessor configuration. The Denver 2 and Cortex-A57 cores
 support ARMv8, executing both 64-bit Aarch64 code, and 32-bit Aarch32 code
 including legacy ARMv7 applications. The Denver 2 processors each have 128 KB
@@ -29,20 +29,6 @@
 high speed coherency fabric connects these two processor complexes and allows
 heterogeneous multi-processing with all six cores if required.
 
--  .. rubric:: T210
-      :name: t210
-
-T210 has Quad Arm® Cortex®-A57 cores in a switched configuration with a
-companion set of quad Arm Cortex-A53 cores. The Cortex-A57 and A53 cores
-support Armv8-A, executing both 64-bit Aarch64 code, and 32-bit Aarch32 code
-including legacy Armv7-A applications. The Cortex-A57 processors each have
-48 KB Instruction and 32 KB Data Level 1 caches; and have a 2 MB shared
-Level 2 unified cache. The Cortex-A53 processors each have 32 KB Instruction
-and 32 KB Data Level 1 caches; and have a 512 KB shared Level 2 unified cache.
-
--  .. rubric:: T132
-      :name: t132
-
 Denver is NVIDIA's own custom-designed, 64-bit, dual-core CPU which is
 fully Armv8-A architecture compatible. Each of the two Denver cores
 implements a 7-way superscalar microarchitecture (up to 7 concurrent
@@ -68,6 +54,17 @@
 to extensive power-gating and dynamic voltage and clock scaling based on
 workloads.
 
+-  .. rubric:: T210
+      :name: t210
+
+T210 has Quad Arm® Cortex®-A57 cores in a switched configuration with a
+companion set of quad Arm Cortex-A53 cores. The Cortex-A57 and A53 cores
+support Armv8-A, executing both 64-bit Aarch64 code, and 32-bit Aarch32 code
+including legacy Armv7-A applications. The Cortex-A57 processors each have
+48 KB Instruction and 32 KB Data Level 1 caches; and have a 2 MB shared
+Level 2 unified cache. The Cortex-A53 processors each have 32 KB Instruction
+and 32 KB Data Level 1 caches; and have a 512 KB shared Level 2 unified cache.
+
 Directory structure
 -------------------
 
@@ -89,7 +86,6 @@
 
 These are the supported Trusted OS' by Tegra platforms.
 
-- Tegra132: TLK
 - Tegra210: TLK and Trusty
 - Tegra186: Trusty
 - Tegra194: Trusty
@@ -110,7 +106,7 @@
 .. code:: shell
 
     CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- make PLAT=tegra \
-    TARGET_SOC=<target-soc e.g. t194|t186|t210|t132> SPD=<dispatcher e.g. trusty|tlkd>
+    TARGET_SOC=<target-soc e.g. t194|t186|t210> SPD=<dispatcher e.g. trusty|tlkd>
     bl31
 
 Platforms wanting to use different TZDRAM\_BASE, can add ``TZDRAM_BASE=<value>``
diff --git a/docs/plat/nxp/index.rst b/docs/plat/nxp/index.rst
new file mode 100644
index 0000000..8546887
--- /dev/null
+++ b/docs/plat/nxp/index.rst
@@ -0,0 +1,17 @@
+NXP Reference Development Platforms
+===================================
+
+.. toctree::
+   :maxdepth: 1
+   :caption: Contents
+
+   nxp-layerscape
+   nxp-ls-fuse-prov
+   nxp-ls-tbbr
+
+This chapter holds documentation related to NXP reference development platforms.
+It includes details on image flashing, fuse provisioning and trusted board boot-up.
+
+--------------
+
+*Copyright (c) 2021, NXP Limited. All rights reserved.*
diff --git a/docs/plat/nxp/nxp-layerscape.rst b/docs/plat/nxp/nxp-layerscape.rst
new file mode 100644
index 0000000..3d98354
--- /dev/null
+++ b/docs/plat/nxp/nxp-layerscape.rst
@@ -0,0 +1,232 @@
+NXP SoCs - Overview
+=====================
+.. section-numbering::
+    :suffix: .
+
+The QorIQ family of ARM based SoCs that are supported on TF-A are:
+
+1. LX2160ARDB:
+        Platform Name:
+
+        a. lx2160ardb (Board details can be fetched from the link: `lx2160ardb`_)
+
+
+Table of supported boot-modes by each platform & platform that needs FIP-DDR:
+-----------------------------------------------------------------------------
+
++---+-----------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
+|   |     BOOT_MODE-->|  sd   |  qspi  |  nor  | nand  | emmc  | flexspi_nor | flexspi_nand | fip_ddr needed  |
+|   |                 |       |        |       |       |       |             |              |                 |
+|   |     PLAT        |       |        |       |       |       |             |              |                 |
++===+=================+=======+========+=======+=======+=======+=============+==============+=================+
+| 1.| lx2160ardb      |  yes  |        |       |       |  yes  |   yes       |              |       yes       |
++---+-----------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
+
+Boot Sequence
+-------------
+::
+
++                           Secure World        |     Normal World
++ EL0                                           |
++                                               |
++ EL1                           BL32(Tee OS)    |     kernel
++                                ^ |            |       ^
++                                | |            |       |
++ EL2                            | |            |     BL33(u-boot)
++                                | |            |      ^
++                                | v            |     /
++ EL3        BootROM --> BL2 --> BL31 ---------------/
++
+
+Boot Sequence with FIP-DDR
+--------------------------
+::
+
++                           Secure World        |     Normal World
++ EL0                                           |
++                                               |
++ EL1               fip-ddr     BL32(Tee OS)    |     kernel
++                     ^ |         ^ |           |       ^
++                     | |         | |           |       |
++ EL2                 | |         | |           |     BL33(u-boot)
++                     | |         | |           |      ^
++                     | v         | v           |     /
++ EL3     BootROM --> BL2 -----> BL31 ---------------/
++
+
+
+How to build
+=============
+
+Code Locations
+--------------
+
+-  OP-TEE:
+   `link <https://source.codeaurora.org/external/qoriq/qoriq-components/optee_os>`__
+
+-  U-Boot:
+   `link <https://source.codeaurora.org/external/qoriq/qoriq-components/u-boot>`__
+
+-  RCW:
+   `link <https://source.codeaurora.org/external/qoriq/qoriq-components/rcw>`__
+
+-  ddr-phy-binary: Required by platforms that need fip-ddr.
+   `link <https:://github.com/NXP/ddr-phy-binary>`__
+
+-  cst: Required for TBBR.
+   `link <https:://source.codeaurora.org/external/qoriq/qoriq-components/cst>`__
+
+Build Procedure
+---------------
+
+-  Fetch all the above repositories into local host.
+
+-  Prepare AARCH64 toolchain and set the environment variable "CROSS_COMPILE".
+
+   .. code:: shell
+
+       export CROSS_COMPILE=.../bin/aarch64-linux-gnu-
+
+-  Build RCW. Refer README from the respective cloned folder for more details.
+
+-  Build u-boot and OPTee firstly, and get binary images: u-boot.bin and tee.bin.
+   For u-boot you can use the <platform>_tfa_defconfig for build.
+
+-  Copy/clone the repo "ddr-phy-binary" to the tfa directory for platform needing ddr-fip.
+
+-  Below are the steps to build TF-A images for the supported platforms.
+
+Compilation steps without BL32
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+BUILD BL2:
+
+-To compile
+   .. code:: shell
+
+       make PLAT=$PLAT \
+       BOOT_MODE=<platform_supported_boot_mode> \
+       RCW=$RCW_BIN \
+       pbl
+
+BUILD FIP:
+
+   .. code:: shell
+
+       make PLAT=$PLAT \
+       BOOT_MODE=<platform_supported_boot_mode> \
+       RCW=$RCW_BIN \
+       BL33=$UBOOT_SECURE_BIN \
+       pbl \
+       fip
+
+Compilation steps with BL32
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+BUILD BL2:
+
+-To compile
+   .. code:: shell
+
+       make PLAT=$PLAT \
+       BOOT_MODE=<platform_supported_boot_mode> \
+       RCW=$RCW_BIN \
+       BL32=$TEE_BIN SPD=opteed\
+       pbl
+
+BUILD FIP:
+
+   .. code:: shell
+
+       make PLAT=$PLAT \
+       BOOT_MODE=<platform_supported_boot_mode> \
+       RCW=$RCW_BIN \
+       BL32=$TEE_BIN SPD=opteed\
+       BL33=$UBOOT_SECURE_BIN \
+       pbl \
+       fip
+
+
+BUILD fip-ddr (Mandatory for certain platforms, refer table above):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+-To compile additional fip-ddr for selected platforms(Refer above table if the platform needs fip-ddr).
+   .. code:: shell
+
+	make PLAT=<platform_name> fip-ddr
+
+
+Deploy ATF Images
+=================
+
+Note: The size in the standard uboot commands for copy to nor, qspi, nand or sd
+should be modified based on the binary size of the image to be copied.
+
+-  Deploy ATF images on flexspi-Nor flash Alt Bank from U-Boot prompt.
+   --  Commands to flash images for bl2_xxx.pbl and fip.bin.
+
+   .. code:: shell
+
+        tftp 82000000  $path/bl2_flexspi_nor.pbl;
+        i2c mw 66 50 20;sf probe 0:0; sf erase 0 +$filesize; sf write 0x82000000 0x0 $filesize;
+
+        tftp 82000000  $path/fip.bin;
+        i2c mw 66 50 20;sf probe 0:0; sf erase 0x100000 +$filesize; sf write 0x82000000 0x100000 $filesize;
+
+   --  Next step is valid for platform where FIP-DDR is needed.
+
+   .. code:: shell
+
+        tftp 82000000  $path/ddr_fip.bin;
+        i2c mw 66 50 20;sf probe 0:0; sf erase 0x800000 +$filesize; sf write 0x82000000 0x800000 $filesize;
+
+   --  Then reset to alternate bank to boot up ATF.
+
+   .. code:: shell
+
+        qixisreset altbank;
+
+-  Deploy ATF images on SD/eMMC from U-Boot prompt.
+   -- file_size_in_block_sizeof_512 = (Size_of_bytes_tftp / 512)
+
+   .. code:: shell
+
+        mmc dev <idx>; (idx = 1 for eMMC; idx = 0 for SD)
+
+        tftp 82000000  $path/bl2_<sd>_or_<emmc>.pbl;
+        mmc write 82000000 8 <file_size_in_block_sizeof_512>;
+
+        tftp 82000000  $path/fip.bin;
+        mmc write 82000000 0x800 <file_size_in_block_sizeof_512>;
+
+    --  Next step is valid for platform that needs FIP-DDR.
+
+   .. code:: shell
+
+        tftp 82000000  $path/ddr_fip.bin;
+        mmc write 82000000 0x4000 <file_size_in_block_sizeof_512>;
+
+   --  Then reset to sd/emmc to boot up ATF from sd/emmc as boot-source.
+
+   .. code:: shell
+
+        qixisreset <sd or emmc>;
+
+Trusted Board Boot:
+===================
+
+For TBBR, the binary name changes:
+
++-------------+--------------------------+---------+-------------------+
+|  Boot Type  |           BL2            |   FIP   |      FIP-DDR      |
++=============+==========================+=========+===================+
+| Normal Boot |  bl2_<boot_mode>.pbl     | fip.bin | ddr_fip.bin       |
++-------------+--------------------------+---------+-------------------+
+| TBBR Boot   |  bl2_<boot_mode>_sec.pbl | fip.bin | ddr_fip_sec.bin   |
++-------------+--------------------------+---------+-------------------+
+
+Refer `nxp-ls-tbbr.rst`_ for detailed user steps.
+
+
+.. _lx2160ardb: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-communication-process/layerscape-lx2160a-multicore-communications-processor:LX2160A
+.. _nxp-ls-tbbr.rst: ./nxp-ls-tbbr.rst
diff --git a/docs/plat/nxp/nxp-ls-fuse-prov.rst b/docs/plat/nxp/nxp-ls-fuse-prov.rst
new file mode 100644
index 0000000..64e1c6f
--- /dev/null
+++ b/docs/plat/nxp/nxp-ls-fuse-prov.rst
@@ -0,0 +1,271 @@
+
+Steps to blow fuses on NXP LS SoC:
+==================================
+
+
+- Enable POVDD
+  -- Refer board GSG(Getting Started Guide) for the steps to enable POVDD.
+  -- Once the POVDD is enabled, make sure to set variable POVDD_ENABLE := yes, in the platform.mk.
+
++---+-----------------+-----------+------------+-----------------+-----------------------------+
+|   |   Platform      |  Jumper   |  Switch    | LED to Verify   |  Through GPIO Pin (=number) |
++===+=================+===========+============+=================+=============================+
+| 1.| lx2160ardb      |  J9       |            |                 |             no              |
++---+-----------------+-----------+------------+-----------------+-----------------------------+
+| 2.| lx2160aqds      |  J35      |            |                 |             no              |
++---+-----------------+-----------+------------+-----------------+-----------------------------+
+| 3.| lx2162aqds      |  J35      | SW9[4] = 1 |    D15          |             no              |
++---+-----------------+-----------+------------+-----------------+-----------------------------+
+
+- SFP registers to be written to:
+
++---+----------------------------------+----------------------+----------------------+
+|   |   Platform                       |   OTPMKR0..OTPMKR7   |   SRKHR0..SRKHR7     |
++===+==================================+======================+======================+
+| 1.| lx2160ardb/lx2160aqds/lx2162aqds | 0x1e80234..0x1e80250 | 0x1e80254..0x1e80270 |
++---+----------------------------------+----------------------+----------------------+
+
+- At U-Boot prompt, verify that SNVS register - HPSR, whether OTPMK was written, already:
+
++---+----------------------------------+-------------------------------------------+---------------+
+|   |   Platform                       |           OTPMK_ZERO_BIT(=value)          | SNVS_HPSR_REG |
++===+==================================+===========================================+===============+
+| 1.| lx2160ardb/lx2160aqds/lx2162aqds | 27 (= 1 means not blown, =0 means blown)  | 0x01E90014    |
++---+----------------------------------+-------------------------------------------+---------------+
+
+From u-boot prompt:
+
+  --  Check for the OTPMK.
+   .. code:: shell
+
+        md $SNVS_HPSR_REG
+
+      Command Output:
+          01e90014: 88000900
+
+          In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap).
+                       +0       +4       +8       +C
+          [0x01E90014] 88000900
+
+          Note: OTPMK_ZERO_BIT is 1, indicating that the OTPMK is not blown.
+
+  --  Check for the SRK Hash.
+   .. code:: shell
+
+        md $SRKHR0 0x10
+
+      Command Output:
+          01e80254: 00000000 00000000 00000000 00000000    ................
+          01e80264: 00000000 00000000 00000000 00000000    ................
+
+          Note: Zero means that SRK hash is not blown.
+
+- If not blown, then from the U-Boot prompt, using following commands:
+  --  Provision the OTPMK.
+
+   .. code:: shell
+
+        mw.l $OTPMKR0  <OTMPKR_0_32Bit_val>
+        mw.l $OTPMKR1  <OTMPKR_1_32Bit_val>
+        mw.l $OTPMKR2  <OTMPKR_2_32Bit_val>
+        mw.l $OTPMKR3  <OTMPKR_3_32Bit_val>
+        mw.l $OTPMKR4  <OTMPKR_4_32Bit_val>
+        mw.l $OTPMKR5  <OTMPKR_5_32Bit_val>
+        mw.l $OTPMKR6  <OTMPKR_6_32Bit_val>
+        mw.l $OTPMKR7  <OTMPKR_7_32Bit_val>
+
+  --  Provision the SRK Hash.
+
+   .. code:: shell
+
+        mw.l $SRKHR0  <SRKHR_0_32Bit_val>
+        mw.l $SRKHR1  <SRKHR_1_32Bit_val>
+        mw.l $SRKHR2  <SRKHR_2_32Bit_val>
+        mw.l $SRKHR3  <SRKHR_3_32Bit_val>
+        mw.l $SRKHR4  <SRKHR_4_32Bit_val>
+        mw.l $SRKHR5  <SRKHR_5_32Bit_val>
+        mw.l $SRKHR6  <SRKHR_6_32Bit_val>
+        mw.l $SRKHR7  <SRKHR_7_32Bit_val>
+
+      Note: SRK Hash should be carefully written keeping in mind the SFP Block Endianness.
+
+- At U-Boot prompt, verify that SNVS registers for OTPMK are correctly written:
+
+  --  Check for the OTPMK.
+   .. code:: shell
+
+        md $SNVS_HPSR_REG
+
+      Command Output:
+          01e90014: 80000900
+
+          OTPMK_ZERO_BIT is zero, indicating that the OTPMK is blown.
+
+          Note: In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap).
+
+   .. code:: shell
+
+        md $OTPMKR0 0x10
+
+      Command Output:
+          01e80234: ffffffff ffffffff ffffffff ffffffff    ................
+          01e80244: ffffffff ffffffff ffffffff ffffffff    ................
+
+          Note: OTPMK will never be visible in plain.
+
+  --  Check for the SRK Hash. For example, if following SRK hash is written:
+
+       SFP SRKHR0 = fdc2fed4
+       SFP SRKHR1 = 317f569e
+       SFP SRKHR2 = 1828425c
+       SFP SRKHR3 = e87b5cfd
+       SFP SRKHR4 = 34beab8f
+       SFP SRKHR5 = df792a70
+       SFP SRKHR6 = 2dff85e1
+       SFP SRKHR7 = 32a29687,
+
+       then following would be the value on dumping SRK hash.
+
+   .. code:: shell
+
+        md $SRKHR0 0x10
+
+      Command Output:
+          01e80254: d4fec2fd 9e567f31 5c422818 fd5c7be8    ....1.V..(B\.{\.
+          01e80264: 8fabbe34 702a79df e185ff2d 8796a232    4....y*p-...2...
+
+          Note: SRK Hash is visible in plain based on the SFP Block Endianness.
+
+- Caution: Donot proceed to the next step, until you are sure that OTPMK and SRKH are correctly blown from above steps.
+  -- After the next step, there is no turning back.
+  -- Fuses will be burnt, which cannot be undo.
+
+- Write SFP_INGR[INST] with the PROGFB(0x2) instruction to blow the fuses.
+  -- User need to save the SRK key pair and OTPMK Key forever, to continue using this board.
+
++---+----------------------------------+-------------------------------------------+-----------+
+|   |   Platform                       | SFP_INGR_REG | SFP_WRITE_DATE_FRM_MIRROR_REG_TO_FUSE  |
++===+==================================+=======================================================+
+| 1.| lx2160ardb/lx2160aqds/lx2162aqds | 0x01E80020   |    0x2                                 |
++---+----------------------------------+--------------+----------------------------------------+
+
+   .. code:: shell
+
+        md $SFP_INGR_REG  $SFP_WRITE_DATE_FRM_MIRROR_REG_TO_FUSE
+
+- On reset, if the SFP register were read from u-boot, it will show the following:
+  --  Check for the OTPMK.
+
+   .. code:: shell
+
+        md $SNVS_HPSR_REG
+
+      Command Output:
+          01e90014: 80000900
+
+          In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap).
+                       +0       +4       +8       +C
+          [0x01E90014] 80000900
+
+          Note: OTPMK_ZERO_BIT is zero, indicating that the OTPMK is blown.
+
+   .. code:: shell
+
+        md $OTPMKR0 0x10
+
+      Command Output:
+          01e80234: ffffffff ffffffff ffffffff ffffffff    ................
+          01e80244: ffffffff ffffffff ffffffff ffffffff    ................
+
+          Note: OTPMK will never be visible in plain.
+
+  -- SRK Hash
+
+   .. code:: shell
+
+        md $SRKHR0 0x10
+
+      Command Output:
+          01e80254: d4fec2fd 9e567f31 5c422818 fd5c7be8    ....1.V..(B\.{\.
+          01e80264: 8fabbe34 702a79df e185ff2d 8796a232    4....y*p-...2...
+
+          Note: SRK Hash is visible in plain based on the SFP Block Endianness.
+
+Second method to do the fuse provsioning:
+=========================================
+
+This method is used for quick way to provision fuses.
+Typically used by those who needs to provision number of boards.
+
+- Enable POVDD:
+  -- Refer the table above to enable POVDD.
+
+     Note: If GPIO Pin supports enabling POVDD, it can be done through the below input_fuse_file.
+
+  -- Once the POVDD is enabled, make sure to set variable POVDD_ENABLE := yes, in the platform.mk.
+
+- User need to populate the "input_fuse_file", corresponding to the platform for:
+
+  -- OTPMK
+  -- SRKH
+
+  Table of fuse provisioning input file for every supported platform:
+
++---+----------------------------------+-----------------------------------------------------------------+
+|   |   Platform                       |                        FUSE_PROV_FILE                           |
++===+==================================+=================================================================+
+| 1.| lx2160ardb/lx2160aqds/lx2162aqds | ${CST_DIR}/input_files/gen_fusescr/ls2088_1088/input_fuse_file  |
++---+----------------------------------+--------------+--------------------------------------------------+
+
+- Create the TF-A binary with FUSE_PROG=1.
+
+   .. code:: shell
+
+        make PLAT=$PLAT FUSE_PROG=1\
+          BOOT_MODE=<platform_supported_boot_mode> \
+          RCW=$RCW_BIN \
+          BL32=$TEE_BIN SPD=opteed\
+          BL33=$UBOOT_SECURE_BIN \
+          pbl \
+          fip \
+          fip_fuse \
+          FUSE_PROV_FILE=../../apps/security/cst/input_files/gen_fusescr/ls2088_1088/input_fuse_file
+
+- Deployment:
+  -- Refer the nxp-layerscape.rst for deploying TF-A images.
+  -- Deploying fip_fuse.bin:
+
+       For Flexspi-Nor:
+
+   .. code:: shell
+
+        tftp 82000000  $path/fuse_fip.bin;
+        i2c mw 66 50 20;sf probe 0:0; sf erase 0x880000 +$filesize; sf write 0x82000000 0x880000 $filesize;
+
+      For SD or eMMC [file_size_in_block_sizeof_512 = (Size_of_bytes_tftp / 512)]:
+
+   .. code:: shell
+
+        tftp 82000000  $path/fuse_fip.bin;
+        mmc write 82000000 0x4408 <file_size_in_block_sizeof_512>;
+
+- Valiation:
+
++---+----------------------------------+---------------------------------------------------+
+|   |   Platform                       |    Error_Register        | Error_Register_Address |
++===+==================================+===================================================+
+| 1.| lx2160ardb/lx2160aqds/lx2162aqds | DCFG scratch 4 register  |     0x01EE020C         |
++---+----------------------------------+---------------------------------------------------+
+
+   At the U-Boot prompt, check DCFG scratch 4 register for any error.
+
+   .. code:: shell
+
+        md $Error_Register_Address 1
+
+      Command Ouput:
+          01ee020c: 00000000
+
+      Note:
+       - 0x00000000 shows no error, then fuse provisioning is successful.
+       - For non-zero value, refer the code header file ".../drivers/nxp/sfp/sfp_error_codes.h"
diff --git a/docs/plat/nxp/nxp-ls-tbbr.rst b/docs/plat/nxp/nxp-ls-tbbr.rst
new file mode 100644
index 0000000..43e15f7
--- /dev/null
+++ b/docs/plat/nxp/nxp-ls-tbbr.rst
@@ -0,0 +1,210 @@
+
+--------------
+NXP Platforms:
+--------------
+TRUSTED_BOARD_BOOT option can be enabled by specifying TRUSTED_BOARD_BOOT=1 on command line during make.
+
+
+
+Bare-Minimum Preparation to run  TBBR on NXP Platforms:
+=======================================================
+- OTPMK(One Time Programable Key) needs to be burnt in fuses.
+  -- It is the 256 bit key that stores a secret value used by the NXP SEC 4.0 IP in Trusted or Secure mode.
+
+     Note: It is primarily for the purpose of decrypting additional secrets stored in system non-volatile memory.
+
+  -- NXP CST tool gives an option to generate it.
+
+   Use the below command from directory 'cst', with correct options.
+
+   .. code:: shell
+
+     ./gen_otpmk_drbg
+
+- SRKH (Super Root Key Hash) needs to be burnt in fuses.
+  -- It is the 256 bit hash of the list of the public keys of the SRK key pair.
+  -- NXP CST tool gives an option to generate the RSA key pair and its hash.
+
+   Use the below command from directory 'cst', with correct options.
+
+   .. code:: shell
+
+     ./gen_keys
+
+Refer fuse frovisioning readme 'nxp-ls-fuse-prov.rst' for steps to blow these keys.
+
+
+
+Two options are provided for TRUSTED_BOARD_BOOT:
+================================================
+
+-------------------------------------------------------------------------
+Option 1: CoT using X 509 certificates
+-------------------------------------------------------------------------
+
+- This CoT is as provided by ARM.
+
+- To use this option user needs to specify mbedtld dir path in MBEDTLS_DIR.
+
+- To generate CSF header, path of CST repository needs to be specified as CST_DIR
+
+- CSF header is embedded to each of the BL2 image.
+
+- GENERATE_COT=1 adds the tool 'cert_create' to the build environment to generate:
+  -- X509 Certificates as (.crt) files.
+  -- X509 Pem key file as (.pem) files.
+
+- SAVE_KEYS=1 saves the keys and certificates, if GENERATE_COT=1.
+  -- For this to work, file name for cert and keys are provided as part of  compilation or build command.
+
+     --- default file names will be used, incase not provided as part compilation or build command.
+     --- default folder 'BUILD_PLAT' will be used to store them.
+
+- ROTPK for x.509 certificates is generated and embedded in bl2.bin and
+  verified as part of CoT by Boot ROM during secure boot.
+
+- Compilation steps:
+
+All Images
+   .. code:: shell
+
+       make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 MBEDTLS_DIR=$MBEDTLS_PATH CST_DIR=$CST_DIR_PATH \
+       BOOT_MODE=<platform_supported_boot_mode> \
+       RCW=$RCW_BIN \
+       BL32=$TEE_BIN SPD=opteed\
+       BL33=$UBOOT_SECURE_BIN \
+       pbl \
+       fip
+
+Additional FIP_DDR Image (For NXP platforms like lx2160a)
+   .. code:: shell
+
+       make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 MBEDTLS_DIR=$MBEDTLS_PATH fip_ddr
+
+      Note: make target 'fip_ddr' should never be combine with other make target 'fip', 'pbl' & 'bl2'.
+
+-------------------------------------------------------------------------
+Option 2: CoT using NXP CSF headers.
+-------------------------------------------------------------------------
+
+- This option is automatically selected when TRUSTED_BOARD_BOOT is set but MBEDTLS_DIR path is not specified.
+
+- CSF header is embedded to each of the BL31, BL32 and  BL33 image.
+
+- To generate CSF header, path of CST repository needs to be specified as CST_DIR
+
+- Default input files for CSF header generation is added in this repo.
+
+- Default input file requires user to generate RSA key pair named
+  -- srk.pri, and
+  -- srk.pub, and add them in ATF repo.
+  -- These keys can be generated using gen_keys tool of CST.
+
+- To change the input file , user can use the options BL33_INPUT_FILE, BL32_INPUT_FILE, BL31_INPUT_FILE
+
+- There are 2 paths in secure boot flow :
+  -- Development Mode (sb_en in RCW = 1, SFP->OSPR, ITS = 0)
+
+     --- In this flow , even on ROTPK comparison failure, flow would continue.
+     --- However SNVS is transitioned to non-secure state
+
+  -- Production mode (SFP->OSPR, ITS = 1)
+
+     --- Any failure is fatal failure
+
+- Compilation steps:
+
+All Images
+   .. code:: shell
+
+       make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 CST_DIR=$CST_DIR_PATH \
+       BOOT_MODE=<platform_supported_boot_mode> \
+       RCW=$RCW_BIN \
+       BL32=$TEE_BIN SPD=opteed\
+       BL33=$UBOOT_SECURE_BIN \
+       pbl \
+       fip
+
+Additional FIP_DDR Image (For NXP platforms like lx2160a)
+   .. code:: shell
+
+       make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 CST_DIR=$CST_DIR_PATH fip_ddr
+
+- Compilation Steps with build option for generic image processing filters to prepend CSF header:
+  --  Generic image processing filters to prepend CSF header
+
+      BL32_INPUT_FILE = < file name>
+      BL33_INPUT_FILE = <file name>
+
+   .. code:: shell
+
+       make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 CST_DIR=$CST_DIR_PATH \
+       BOOT_MODE=<platform_supported_boot_mode> \
+       RCW=$RCW_BIN \
+       BL32=$TEE_BIN SPD=opteed\
+       BL33=$UBOOT_SECURE_BIN \
+       BL33_INPUT_FILE = <ip file> \
+       BL32_INPUT_FILE = <ip_file> \
+       BL31_INPUT_FILE = <ip file> \
+       pbl \
+       fip
+
+
+Deploy ATF Images
+=================
+Same steps as mentioned in the readme "nxp-layerscape.rst".
+
+
+
+Verification to check if Secure state is achieved:
+==================================================
+
++---+----------------+-----------------+------------------------+----------------------------------+-------------------------------+
+|   |   Platform     |  SNVS_HPSR_REG  | SYS_SECURE_BIT(=value) | SYSTEM_SECURE_CONFIG_BIT(=value) | SSM_STATE                     |
++===+================+=================+========================+==================================+===============================+
+| 1.| lx2160ardb  or |    0x01E90014   | 15                     | 14-12                            | 11-8                          |
+|   | lx2160aqds  or |                 | ( = 1, BootROM Booted) | ( = 010 means Intent to Secure,  | (=1111 means secure boot)     |
+|   | lx2162aqds     |                 |                        | ( = 000 Unsecure)                | (=1011 means Non-secure Boot) |
++---+----------------+-----------------+------------------------+----------------------------------+-------------------------------+
+
+- Production mode (SFP->OSPR, ITS = 1)
+  -- Linux prompt will successfully come. if the TBBR is successful.
+
+     --- Else, Linux boot will be successful.
+
+  -- For secure-boot status, read SNVS Register $SNVS_HPSR_REG from u-boot prompt:
+
+   .. code:: shell
+
+        md $SNVS_HPSR_REG
+
+      Command Output:
+          1e90014: 8000AF00
+
+          In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap).
+                       +0       +4       +8       +C
+          [0x01E90014] 8000AF00
+
+
+- Development Mode (sb_en in RCW = 1, SFP->OSPR, ITS = 0)
+  -- Refer the SoC specific table to read the register to interpret whether the secure boot is achieved or not.
+  -- Using JTAG (in development environment only, using CW tap):
+
+     --- For secure-boot status, read SNVS Register $SNVS_HPSR_REG
+
+   .. code:: shell
+
+        ccs::display_regs 86 0x01E90014 4 0 1
+
+      Command Output:
+          Using the SAP chain position number 86, following is the output.
+
+                       +0       +4       +8       +C
+          [0x01E90014] 8000AF00
+
+          Note: Chain position number will vary from one SoC to other SoC.
+
+- Interpretation of the value:
+
+  -- 0xA indicates BootROM booted, with intent to secure.
+  -- 0xF = secure boot, as SSM_STATE.
diff --git a/docs/resources/diagrams/plantuml/spm_dfd.puml b/docs/resources/diagrams/plantuml/spm_dfd.puml
new file mode 100644
index 0000000..ad4996e
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/spm_dfd.puml
@@ -0,0 +1,82 @@
+/'
+ ' Copyright (c) 2021, Arm Limited. All rights reserved.
+ '
+ ' SPDX-License-Identifier: BSD-3-Clause
+ '/
+
+/'
+TF-A SPMC Data Flow Diagram
+'/
+
+@startuml
+digraph tfa_dfd {
+
+    # Allow arrows to end on cluster boundaries
+    compound=true
+
+    # Default settings for edges and nodes
+    edge [minlen=2 color="#8c1b07"]
+    node [fillcolor="#ffb866" style=filled shape=box fixedsize=true width=1.6 height=0.7]
+
+    # Nodes outside of the trust boundary
+    nsec [label="NS Client"]
+    ddr  [label="External memory (DDR)"]
+
+    # Trust boundary cluster
+    subgraph cluster_trusted {
+        graph [style=dashed color="#f22430"]
+
+        # HW IPs cluster
+        subgraph cluster_ip {
+            label ="Hardware IPs";
+            graph [style=filled color="#000000" fillcolor="#ffd29e"]
+
+            rank="same"
+            gic [label="GIC" width=1.2 height=0.5]
+            smmu [label="SMMU" width=1.2 height=0.5]
+            uart [label="UART" width=1.2 height=0.5]
+	    pe [label="PE" width=1.2 height=0.5]
+        }
+
+        # TF-A cluster
+        subgraph cluster_tfa {
+            label ="EL3 monitor";
+            graph [style=filled color="#000000" fillcolor="#faf9cd"]
+
+            bl31 [label="BL31" fillcolor="#ddffb3"];
+            spmd [label="SPMD" fillcolor="#ddffb3" height=1]
+        }
+
+        # SPMC cluster
+        subgraph cluster_spmc {
+            label ="SPMC";
+            graph [style=filled color="#000000" fillcolor="#faf9cd"]
+
+            spmc [label="SPMC" fillcolor="#ddffb3" height=1]
+        }
+	bl2 [label="BL2" width=1.2 height=0.5]
+    }
+
+    # Secure Partitions cluster
+    subgraph cluster_sp {
+        label ="Secure Partitions";
+        graph [style=filled color="#000000" fillcolor="#faf9cd"]
+
+        sp1 [label="SP1" fillcolor="#ddffb3" height=1]
+        sp2 [label="SP2" fillcolor="#ddffb3" height=1]
+        spn [label="SP..." fillcolor="#ddffb3" height=1]
+    }
+
+    # Interactions between nodes
+    sp1 -> spmc [dir="both" label="DF1"]
+    spmc -> spmd [dir="both" label="DF2"]
+    spmd -> nsec [dir="both" label="DF3"]
+    sp1 -> sp2 [dir="both" label="DF4"]
+    spmc -> smmu [lhead=cluster_spmc label="DF5"]
+    bl2 -> spmc [lhead=cluster_spmc label="DF6"]
+    bl2 -> spn [lhead=cluster_spmc label="DF6"]
+    sp1 -> ddr [dir="both"  label="DF7"]
+    spmc -> ddr [dir="both"  label="DF7"]
+}
+
+@enduml
diff --git a/docs/resources/diagrams/spm-threat-model-trust-boundaries.png b/docs/resources/diagrams/spm-threat-model-trust-boundaries.png
new file mode 100644
index 0000000..58898c5
--- /dev/null
+++ b/docs/resources/diagrams/spm-threat-model-trust-boundaries.png
Binary files differ
diff --git a/docs/threat_model/index.rst b/docs/threat_model/index.rst
index e8f09b9..b5ede69 100644
--- a/docs/threat_model/index.rst
+++ b/docs/threat_model/index.rst
@@ -1,5 +1,12 @@
 Threat Model
-=============
+============
+
+Threat modeling is an important part of Secure Development Lifecycle (SDL)
+that helps us identify potential threats and mitigations affecting a system.
+
+In the next sections, we first give a description of the target of evaluation
+using a data flow diagram. Then we provide a list of threats we have identified
+based on the data flow diagram and potential threat mitigations.
 
 .. toctree::
    :maxdepth: 1
@@ -7,6 +14,7 @@
    :numbered:
 
    threat_model
+   threat_model_spm
 
 --------------
 
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 9cee104..9f26487 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -1,13 +1,10 @@
-*****************
-Introduction
-*****************
-Threat modeling is an important part of Secure Development Lifecycle (SDL)
-that helps us identify potential threats and mitigations affecting a system.
+Generic threat model
+********************
 
-This document provides a generic threat model for TF-A firmware. In the
-next sections, we first give a description of the target of evaluation
-using a data flow diagram. Then we provide a list of threats we have
-identified based on the data flow diagram and potential threat mitigations.
+************************
+Introduction
+************************
+This document provides a generic threat model for TF-A firmware.
 
 ************************
 Target of Evaluation
@@ -781,4 +778,4 @@
 .. _Trusted Board Boot (TBB): https://trustedfirmware-a.readthedocs.io/en/latest/design/trusted-board-boot.html
 .. _TF-A error handling policy: https://trustedfirmware-a.readthedocs.io/en/latest/process/coding-guidelines.html#error-handling-and-robustness
 .. _Secure Development Guidelines: https://trustedfirmware-a.readthedocs.io/en/latest/process/security-hardening.html#secure-development-guidelines
-.. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
\ No newline at end of file
+.. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
diff --git a/docs/threat_model/threat_model_spm.rst b/docs/threat_model/threat_model_spm.rst
new file mode 100644
index 0000000..96d33a2
--- /dev/null
+++ b/docs/threat_model/threat_model_spm.rst
@@ -0,0 +1,617 @@
+SPMC threat model
+*****************
+
+************************
+Introduction
+************************
+This document provides a threat model for the TF-A `Secure Partition Manager`_
+(SPM) implementation or more generally the S-EL2 reference firmware running on
+systems implementing the FEAT_SEL2 (formerly Armv8.4 Secure EL2) architecture
+extension. The SPM implementation is based on the `Arm Firmware Framework for
+Armv8-A`_ specification.
+
+In brief, the broad FF-A specification and S-EL2 firmware implementation
+provide:
+
+- Isolation of mutually mistrusting SW components, or endpoints in the FF-A
+  terminology.
+- Distinct sandboxes in the secure world called secure partitions. This permits
+  isolation of services from multiple vendors.
+- A standard protocol for communication and memory sharing between FF-A
+  endpoints.
+- Mutual isolation of the normal world and the secure world (e.g. a Trusted OS
+  is prevented to map an arbitrary NS physical memory region such as the kernel
+  or the Hypervisor).
+
+************************
+Target of Evaluation
+************************
+In this threat model, the target of evaluation is the S-EL2 firmware or the
+``Secure Partition Manager Core`` component (SPMC).
+The monitor and SPMD at EL3 are covered by the `Generic TF-A threat model`_.
+
+The scope for this threat model is:
+
+- The TF-A implementation for the S-EL2 SPMC based on the Hafnium hypervisor
+  running in the secure world of TrustZone (at S-EL2 exception level).
+  The threat model is not related to the normal world Hypervisor or VMs.
+  The S-EL1 SPMC solution is not covered.
+- The implementation complies with the FF-A v1.0 specification.
+- Secure partitions are statically provisioned at boot time.
+- Focus on the run-time part of the life-cycle (no specific emphasis on boot
+  time, factory firmware provisioning, firmware udpate etc.)
+- Not covering advanced or invasive physical attacks such as decapsulation,
+  FIB etc.
+- Assumes secure boot or in particular TF-A trusted boot (TBBR or dual CoT) is
+  enabled. An attacker cannot boot arbitrary images that are not approved by the
+  SiP or platform providers.
+
+Data Flow Diagram
+======================
+Figure 1 shows a high-level data flow diagram for the SPM split into an SPMD
+component at EL3 and an SPMC component at S-EL2. The SPMD mostly acts as a
+relayer/pass-through between the normal world and the secure world. It is
+assumed to expose small attack surface.
+
+A description of each diagram element is given in Table 1. In the diagram, the
+red broken lines indicate trust boundaries.
+
+Components outside of the broken lines are considered untrusted.
+
+.. uml:: ../resources/diagrams/plantuml/spm_dfd.puml
+  :caption: Figure 1: SPMC Data Flow Diagram
+
+.. table:: Table 1: SPMC Data Flow Diagram Description
+
+  +---------------------+--------------------------------------------------------+
+  | Diagram Element     | Description                                            |
+  +=====================+========================================================+
+  | ``DF1``             | SP to SPMC communication. FF-A function invocation or  |
+  |                     | implementation-defined Hypervisor call.                |
+  +---------------------+--------------------------------------------------------+
+  | ``DF2``             | SPMC to SPMD FF-A call.                                |
+  +---------------------+--------------------------------------------------------+
+  | ``DF3``             | SPMD to NS forwarding.                                 |
+  +---------------------+--------------------------------------------------------+
+  | ``DF4``             | SP to SP FF-A direct message request/response.         |
+  |                     | Note as a matter of simplifying the diagram            |
+  |                     | the SP to SP communication happens through the SPMC    |
+  |                     | (SP1 performs a direct message request to the          |
+  |                     | SPMC targeting SP2 as destination. And similarly for   |
+  |                     | the direct message response from SP2 to SP1).          |
+  +---------------------+--------------------------------------------------------+
+  | ``DF5``             | HW control.                                            |
+  +---------------------+--------------------------------------------------------+
+  | ``DF6``             | Bootloader image loading.                              |
+  +---------------------+--------------------------------------------------------+
+  | ``DF7``             | External memory access.                                |
+  +---------------------+--------------------------------------------------------+
+
+*********************
+Threat Analysis
+*********************
+
+This threat model follows a similar methodology to the `Generic TF-A threat model`_.
+The following sections define:
+
+- Trust boundaries
+- Assets
+- Theat agents
+- Threat types
+
+Trust boundaries
+============================
+
+- Normal world is untrusted.
+- Secure world and normal world are separate trust boundaries.
+- EL3 monitor, SPMD and SPMC are trusted.
+- Bootloaders (in particular BL1/BL2 if using TF-A) and run-time BL31 are
+  implicitely trusted by the usage of secure boot.
+- EL3 monitor, SPMD, SPMC do not trust SPs.
+
+.. figure:: ../resources/diagrams/spm-threat-model-trust-boundaries.png
+
+    Figure 2: Trust boundaries
+
+Assets
+============================
+
+The following assets are identified:
+
+- SPMC state.
+- SP state.
+- Information exchange between endpoints (partition messages).
+- SPMC secrets (e.g. pointer authentication key when enabled)
+- SP secrets (e.g. application keys).
+- Scheduling cycles.
+- Shared memory.
+
+Threat Agents
+============================
+
+The following threat agents are identified:
+
+- NS-Endpoint identifies a non-secure endpoint: normal world client at NS-EL2
+  (Hypervisor) or NS-EL1 (VM or OS kernel).
+- S-Endpoint identifies a secure endpoint typically a secure partition.
+- Hardware attacks (non-invasive) requiring a physical access to the device,
+  such as bus probing or DRAM stress.
+
+Threat types
+============================
+
+The following threat categories as exposed in the `Generic TF-A threat model`_
+are re-used:
+
+- Spoofing
+- Tampering
+- Repudiation
+- Information disclosure
+- Denial of service
+- Elevation of privileges
+
+Similarly this threat model re-uses the same threat risk ratings. The risk
+analysis is evaluated based on the environment being ``Server`` or ``Mobile``.
+
+Threat Assessment
+============================
+
+The following threats are identified by applying STRIDE analysis on each diagram
+element of the data flow diagram.
+
++------------------------+----------------------------------------------------+
+| ID                     | 01                                                 |
++========================+====================================================+
+| ``Threat``             | **An endpoint impersonates the sender or receiver  |
+|                        | FF-A ID in a direct request/response invocation.** |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2, DF3, DF4                                 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMD, SPMC                                         |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP state                                           |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Spoofing                                           |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------++----------------+---------------+
+| ``Impact``             | Critical(5)      | Critical(5)     |               |
++------------------------+------------------++----------------+---------------+
+| ``Likelihood``         | Critical(5)      | Critical(5)     |               |
++------------------------+------------------++----------------+---------------+
+| ``Total Risk Rating``  | Critical(25)     | Critical(25)    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC does not mitigate this threat.       |
+|                        | The guidance below is left for a system integrator |
+|                        | to implemented as necessary.                       |
+|                        | The SPMC must enforce checks in the direct message |
+|                        | request/response interfaces such an endpoint cannot|
+|                        | spoof the origin and destination worlds (e.g. a NWd|
+|                        | originated message directed to the SWd cannot use a|
+|                        | SWd ID as the sender ID).                          |
+|                        | Additionally a software component residing in the  |
+|                        | SPMC can be added for the purpose of direct        |
+|                        | request/response filtering.                        |
+|                        | It can be configured with the list of known IDs    |
+|                        | and about which interaction can occur between one  |
+|                        | and another endpoint (e.g. which NWd endpoint ID   |
+|                        | sends a direct request to which SWd endpoint ID).  |
+|                        | This component checks the sender/receiver fields   |
+|                        | for a legitimate communication between endpoints.  |
+|                        | A similar component can exist in the OS kernel     |
+|                        | driver, or Hypervisor although it remains untrusted|
+|                        | by the SPMD/SPMC.                                  |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 02                                                 |
++========================+====================================================+
+| ``Threat``             | **Tampering with memory shared between an endpoint |
+|                        | and the SPMC.**                                    |
+|                        | A malicious endpoint may attempt tampering with its|
+|                        | RX/TX buffer contents while the SPMC is processing |
+|                        | it (TOCTOU).                                       |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF3, DF4, DF7                                 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | Shared memory, Information exchange                |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Tampering                                          |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | High (4)         | High (4)        |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | High (4)         | High (4)        |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | High (16)        | High (16)       |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | In context of FF-A v1.0 this is the case of sharing|
+|                        | the RX/TX buffer pair and usage in the             |
+|                        | PARTITION_INFO_GET or mem sharing primitives.      |
+|                        | The SPMC must copy the contents of the TX buffer   |
+|                        | to an internal temporary buffer before processing  |
+|                        | its contents. The SPMC must implement hardened     |
+|                        | input validation on data transmitted through the TX|
+|                        | buffer by an untrusted endpoint.                   |
+|                        | The TF-A SPMC mitigates this threat by enforcing   |
+|                        | checks on data transmitted through RX/TX buffers.  |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 03                                                 |
++========================+====================================================+
+| ``Threat``             | **An endpoint may tamper with its own state or the |
+|                        | state of another endpoint.**                       |
+|                        | A malicious endpoint may attempt violating:        |
+|                        | - its own or another SP state by using an unusual  |
+|                        | combination (or out-of-order) FF-A function        |
+|                        | invocations.                                       |
+|                        | This can also be an endpoint emitting              |
+|                        | FF-A function invocations to another endpoint while|
+|                        | the latter in not in a state to receive it (e.g. a |
+|                        | SP sends a direct request to the normal world early|
+|                        | while the normal world is not booted yet).         |
+|                        | - the SPMC state itself by employing unexpected    |
+|                        | transitions in FF-A memory sharing, direct requests|
+|                        | and responses, or handling of interrupts.          |
+|                        | This can be led by random stimuli injection or     |
+|                        | fuzzing.                                           |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2, DF3, DF4                                 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMD, SPMC                                         |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP state, SPMC state                               |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Tampering                                          |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | High (4)         | High (4)        |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | High (12)        | High (12)       |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The SPMC may be vulnerable to invalid state        |
+|                        | transitions for itself or while handling an SP     |
+|                        | state. The FF-A v1.1 specification provides a      |
+|                        | guidance on those state transitions (run-time      |
+|                        | model). The TF-A SPMC will be hardened in future   |
+|                        | releases to follow this guidance.                  |
+|                        | Additionally The TF-A SPMC mitigates the threat by |
+|                        | runs of the Arm `FF-A ACS`_ compliance test suite. |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 04                                                 |
++========================+====================================================+
+| ``Threat``             | *An attacker may attempt injecting errors by the   |
+|                        | use of external DRAM stress techniques.**          |
+|                        | A malicious agent may attempt toggling an SP       |
+|                        | Stage-2 MMU descriptor bit within the page tables  |
+|                        | that the SPMC manages. This can happen in Rowhammer|
+|                        | types of attack.                                   |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF7                                                |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP or SPMC state                                   |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | Hardware attack                                    |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Tampering                                          |
++------------------------+------------------+---------------+-----------------+
+| ``Application``        |   ``Server``     |  ``Mobile``   |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Impact``             | High (4)         | High (4)	    |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Likelihood``         | Low (2)          | Medium (3)    |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Total Risk Rating``  | Medium (8)       | High (12)	    |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Mitigations``        | The TF-A SPMC does not provide mitigations to this |
+|                        | type of attack. It can be addressed by the use of  |
+|                        | dedicated HW circuity or hardening at the chipset  |
+|                        | or platform level left to the integrator.          |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 05                                                 |
++========================+====================================================+
+| ``Threat``             | **Protection of the SPMC from a DMA capable device |
+|                        | upstream to an SMMU.**                             |
+|                        | A device may attempt to tamper with the internal   |
+|                        | SPMC code/data sections.                           |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF5                                                |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC or SP state                                   |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Tampering, Elevation of privileges                 |
++------------------------+------------------+---------------+-----------------+
+| ``Application``        |   ``Server``     |  ``Mobile``   |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Impact``             | High (4)         | High (4)      |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)    |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Total Risk Rating``  | High (12)        | High (12)     |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Mitigations``        | A platform may prefer assigning boot time,         |
+|                        | statically alocated memory regions through the SMMU|
+|                        | configuration and page tables. The FF-A v1.1       |
+|                        | specification provisions this capability through   |
+|                        | static DMA isolation.                              |
+|                        | The TF-A SPMC does not mitigate this threat.       |
+|                        | It will adopt the static DMA isolation approach in |
+|                        | a future release.                                  |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 06                                                 |
++========================+====================================================+
+| ``Threat``             | **Replay fragments of past communication between   |
+|                        | endpoints.**                                       |
+|                        | A malicious endpoint may replay a message exchange |
+|                        | that occured between two legitimate endpoint as    |
+|                        | a matter of triggering a malfunction or extracting |
+|                        | secrets from the receiving endpoint. In particular |
+|                        | the memory sharing operation with fragmented       |
+|                        | messages between an endpoint and the SPMC may be   |
+|                        | replayed by a malicious agent as a matter of       |
+|                        | getting access or gaining permissions to a memory  |
+|                        | region which does not belong to this agent.        |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF2, DF3                                           |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | Information exchange                               |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Repdudiation                                       |
++------------------------+------------------+---------------+-----------------+
+| ``Application``        |   ``Server``     |  ``Mobile``   |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Impact``             | Medium (3)       | Medium (3)    |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Likelihood``         | High (4)         | High (4)	    |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Total Risk Rating``  | High (12)        | High (12)     |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Mitigations``        | The TF-A SPMC does not mitigate this threat.       |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 07                                                 |
++========================+====================================================+
+| ``Threat``             | **A malicious endpoint may attempt to extract data |
+|                        | or state information by the use of invalid or      |
+|                        | incorrect input arguments.**                       |
+|                        | Lack of input parameter validation or side effects |
+|                        | of maliciously forged input parameters might affect|
+|                        | the SPMC.                                          |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2, DF3, DF4                                 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMD, SPMC                                         |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP secrets, SPMC secrets, SP state, SPMC state     |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Information discolure                              |
++------------------------+------------------+---------------+-----------------+
+| ``Application``        |   ``Server``     |  ``Mobile``   |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Impact``             | High (4)         | High (4)      |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)    |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Total Risk Rating``  | High (12)        | High (12)     |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Mitigations``        | Secure Partitions must follow security standards   |
+|                        | and best practises as a way to mitigate the risk   |
+|                        | of common vulnerabilities to be exploited.         |
+|                        | The use of software (canaries) or hardware         |
+|                        | hardening techniques (XN, WXN, BTI, pointer        |
+|                        | authentication, MTE) helps detecting and stopping  |
+|                        | an exploitation early.                             |
+|                        | The TF-A SPMC mitigates this threat by implementing|
+|                        | stack protector, pointer authentication, BTI, XN,  |
+|                        | WXN, security hardening techniques.                |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 08                                                 |
++========================+====================================================+
+| ``Threat``             | **A malicious endpoint may forge a direct message  |
+|                        | request such that it reveals the internal state of |
+|                        | another endpoint through the direct message        |
+|                        | response.**                                        |
+|                        | The secure partition or SPMC replies to a partition|
+|                        | message by a direct message response with          |
+|                        | information which may reveal its internal state    |
+|                        | (.e.g. partition message response outside of       |
+|                        | allowed bounds).                                   |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2, DF3, DF4                                 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC or SP state                                   |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Information discolure                              |
++------------------------+------------------+---------------+-----------------+
+| ``Application``        |   ``Server``     |  ``Mobile``   |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Impact``             | Medium (3)       | Medium (3)    |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Likelihood``         | Low (2)          | Low (2)	    |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Total Risk Rating``  | Medium (6)       | Medium (6)    |                 |
++------------------------+------------------+---------------+-----------------+
+| ``Mitigations``        | For the specific case of direct requests targetting|
+|                        | the SPMC, the latter is hardened to prevent        |
+|                        | its internal state or the state of an SP to be     |
+|                        | revealed through a direct message response.        |
+|                        | Further FF-A v1.1 guidance about run time models   |
+|                        | and partition states will be implemented in future |
+|                        | TF-A SPMC releases.                                |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 09                                                 |
++========================+====================================================+
+| ``Threat``             | **Probing the FF-A communication between           |
+|                        | endpoints.**                                       |
+|                        | SPMC and SPs are typically loaded to external      |
+|                        | memory (protected by a TrustZone memory            |
+|                        | controller). A malicious agent may use non invasive|
+|                        | methods to probe the external memory bus and       |
+|                        | extract the traffic between an SP and the SPMC or  |
+|                        | among SPs when shared buffers are held in external |
+|                        | memory.                                            |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF7                                                |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP/SPMC state, SP/SPMC secrets                     |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | Hardware attack                                    |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Information disclosure                             |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Low (2)          | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (6)       | Medium (9)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | It is expected the platform or chipset provides    |
+|                        | guarantees in protecting the DRAM contents.        |
+|                        | The TF-A SPMC does not mitigate this class of      |
+|                        | attack and this is left to the integrator.         |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 10                                                 |
++========================+====================================================+
+| ``Threat``             | **A malicious agent may attempt revealing the SPMC |
+|                        | state or secrets by the use of software-based cache|
+|                        | side-channel attack techniques.**                  |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF7                                                |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SP or SPMC state                                   |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Information disclosure                             |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Low (2)          | Low (2)         |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (6)       | Medium (6)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | From an integration perspective it is assumed      |
+|                        | platforms consuming the SPMC component at S-EL2    |
+|                        | (hence implementing the Armv8.4 FEAT_SEL2          |
+|                        | architecture extension) implement mitigations to   |
+|                        | Spectre, Meltdown or other cache timing            |
+|                        | side-channel type of attacks.                      |
+|                        | The TF-A SPMC implements one mitigation (barrier   |
+|                        | preventing speculation past exeception returns).   |
+|                        | The SPMC may be hardened further with SW           |
+|                        | mitigations (e.g. speculation barriers) for the    |
+|                        | cases not covered in HW. Usage of hardened         |
+|                        | compilers and appropriate options, code inspection |
+|                        | are recommended ways to mitigate Spectre types of  |
+|                        | attacks. For non-hardened cores, the usage of      |
+|                        | techniques such a kernel page table isolation can  |
+|                        | help mitigating Meltdown type of attacks.          |
++------------------------+----------------------------------------------------+
+
++------------------------+----------------------------------------------------+
+| ID                     | 11                                                 |
++========================+====================================================+
+| ``Threat``             | **A malicious endpoint may attempt flooding the    |
+|                        | SPMC with requests targetting a service within an  |
+|                        | endpoint such that it denies another endpoint to   |
+|                        | access this service.**                             |
+|                        | Similarly, the malicious endpoint may target a     |
+|                        | a service within an endpoint such that the latter  |
+|                        | is unable to request services from another         |
+|                        | endpoint.                                          |
++------------------------+----------------------------------------------------+
+| ``Diagram Elements``   | DF1, DF2, DF3, DF4                                 |
++------------------------+----------------------------------------------------+
+| ``Affected TF-A        | SPMC                                               |
+| Components``           |                                                    |
++------------------------+----------------------------------------------------+
+| ``Assets``             | SPMC state                                         |
++------------------------+----------------------------------------------------+
+| ``Threat Agent``       | NS-Endpoint, S-Endpoint                            |
++------------------------+----------------------------------------------------+
+| ``Threat Type``        | Denial of service                                  |
++------------------------+------------------+-----------------+---------------+
+| ``Application``        |   ``Server``     |   ``Mobile``    |               |
++------------------------+------------------+-----------------+---------------+
+| ``Impact``             | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Likelihood``         | Medium (3)       | Medium (3)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Total Risk Rating``  | Medium (9)       | Medium (9)      |               |
++------------------------+------------------+-----------------+---------------+
+| ``Mitigations``        | The TF-A SPMC does not mitigate this threat.       |
+|                        | Bounding the time for operations to complete can   |
+|                        | be achieved by the usage of a trusted watchdog.    |
+|                        | Other quality of service monitoring can be achieved|
+|                        | in the SPMC such as counting a number of operations|
+|                        | in a limited timeframe.                            |
++------------------------+----------------------------------------------------+
+
+--------------
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
+
+.. _Arm Firmware Framework for Armv8-A: https://developer.arm.com/docs/den0077/latest
+.. _Secure Partition Manager: ../components/secure-partition-manager.html
+.. _Generic TF-A threat model: ./threat_model.html#threat-analysis
+.. _FF-A ACS: https://github.com/ARM-software/ff-a-acs/releases
diff --git a/drivers/arm/gic/v3/gic600ae_fmu.c b/drivers/arm/gic/v3/gic600ae_fmu.c
new file mode 100644
index 0000000..13979fa
--- /dev/null
+++ b/drivers/arm/gic/v3/gic600ae_fmu.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Driver for GIC-600AE Fault Management Unit
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gic600ae_fmu.h>
+#include <drivers/arm/gicv3.h>
+
+/* GIC-600 AE FMU specific register offsets */
+
+/* GIC-600 AE FMU specific macros */
+#define FMU_ERRIDR_NUM			U(44)
+#define FMU_ERRIDR_NUM_MASK		U(0xFFFF)
+
+/* Safety mechanisms for GICD block */
+static char *gicd_sm_info[] = {
+	"Reserved",
+	"GICD dual lockstep error",
+	"GICD AXI4 slave interface error",
+	"GICD-PPI AXI4-Stream interface error",
+	"GICD-ITS AXI4-Stream interface error",
+	"GICD-SPI-Collator AXI4-Stream interface error",
+	"GICD AXI4 master interface error",
+	"SPI RAM DED error",
+	"SGI RAM DED error",
+	"Reserved",
+	"LPI RAM DED error",
+	"GICD-remote-GICD AXI4-Stream interface error",
+	"GICD Q-Channel interface error",
+	"GICD P-Channel interface error",
+	"SPI RAM address decode error",
+	"SGI RAM address decode error",
+	"Reserved",
+	"LPI RAM address decode error",
+	"FMU dual lockstep error",
+	"FMU ping ACK error",
+	"FMU APB parity error",
+	"GICD-Wake AXI4-Stream interface error",
+	"GICD PageOffset or Chip ID error",
+	"MBIST REQ error",
+	"SPI RAM SEC error",
+	"SGI RAM SEC error",
+	"Reserved",
+	"LPI RAM SEC error",
+	"User custom SM0 error",
+	"User custom SM1 error",
+	"GICD-ITS Monolithic switch error",
+	"GICD-ITS Q-Channel interface error",
+	"GICD-ITS Monolithic interface error",
+	"GICD FMU ClkGate override"
+};
+
+/* Safety mechanisms for PPI block */
+static char *ppi_sm_info[] = {
+	"Reserved",
+	"PPI dual lockstep error",
+	"PPI-GICD AXI4-Stream interface error",
+	"PPI-CPU-IF AXI4-Stream interface error",
+	"PPI Q-Channel interface error",
+	"PPI RAM DED error",
+	"PPI RAM address decode error",
+	"PPI RAM SEC error",
+	"PPI User0 SM",
+	"PPI User1 SM",
+	"MBIST REQ error",
+	"PPI interrupt parity protection error",
+	"PPI FMU ClkGate override"
+};
+
+/* Safety mechanisms for ITS block */
+static char *its_sm_info[] = {
+	"Reserved",
+	"ITS dual lockstep error",
+	"ITS-GICD AXI4-Stream interface error",
+	"ITS AXI4 slave interface error",
+	"ITS AXI4 master interface error",
+	"ITS Q-Channel interface error",
+	"ITS RAM DED error",
+	"ITS RAM address decode error",
+	"Bypass ACE switch error",
+	"ITS RAM SEC error",
+	"ITS User0 SM",
+	"ITS User1 SM",
+	"ITS-GICD Monolithic interface error",
+	"MBIST REQ error",
+	"ITS FMU ClkGate override"
+};
+
+/* Safety mechanisms for SPI Collator block */
+static char *spicol_sm_info[] = {
+	"Reserved",
+	"SPI Collator dual lockstep error",
+	"SPI-Collator-GICD AXI4-Stream interface error",
+	"SPI Collator Q-Channel interface error",
+	"SPI Collator Q-Channel clock error",
+	"SPI interrupt parity error"
+};
+
+/* Safety mechanisms for Wake Request block */
+static char *wkrqst_sm_info[] = {
+	"Reserved",
+	"Wake dual lockstep error",
+	"Wake-GICD AXI4-Stream interface error"
+};
+
+/*
+ * Initialization sequence for the FMU
+ *
+ * 1. enable error detection for error records that are passed in the blk_present_mask
+ * 2. enable MBIST REQ and FMU Clk Gate override safety mechanisms for error records
+ *    that are present on the platform
+ *
+ * The platforms are expected to pass `errctlr_ce_en` and `errctlr_ue_en`.
+ */
+void gic600_fmu_init(uint64_t base, uint64_t blk_present_mask,
+		     bool errctlr_ce_en, bool errctlr_ue_en)
+{
+	unsigned int num_blk = gic_fmu_read_erridr(base) & FMU_ERRIDR_NUM_MASK;
+	uint64_t errctlr;
+	uint32_t smen;
+
+	INFO("GIC600-AE FMU supports %d error records\n", num_blk);
+
+	assert(num_blk == FMU_ERRIDR_NUM);
+
+	/* sanitize block present mask */
+	blk_present_mask &= FMU_BLK_PRESENT_MASK;
+
+	/* Enable error detection for all error records */
+	for (unsigned int i = 0U; i < num_blk; i++) {
+
+		/* Skip next steps if the block is not present */
+		if ((blk_present_mask & BIT(i)) == 0U) {
+			continue;
+		}
+
+		/* Read the error record control register */
+		errctlr = gic_fmu_read_errctlr(base, i);
+
+		/* Enable error reporting and logging, if it is disabled */
+		if ((errctlr & FMU_ERRCTLR_ED_BIT) == 0U) {
+			errctlr |= FMU_ERRCTLR_ED_BIT;
+		}
+
+		/* Enable client provided ERRCTLR settings */
+		errctlr |= (errctlr_ce_en ? (FMU_ERRCTLR_CI_BIT | FMU_ERRCTLR_CE_EN_BIT) : 0);
+		errctlr |= (errctlr_ue_en ? FMU_ERRCTLR_UI_BIT : 0U);
+
+		gic_fmu_write_errctlr(base, i, errctlr);
+	}
+
+	/*
+	 * Enable MBIST REQ error and FMU CLK gate override safety mechanisms for
+	 * all blocks
+	 *
+	 * GICD, SMID 23 and SMID 33
+	 * PPI, SMID 10 and SMID 12
+	 * ITS, SMID 13 and SMID 14
+	 */
+	if ((blk_present_mask & BIT(FMU_BLK_GICD)) != 0U) {
+		smen = (GICD_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
+			(FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT);
+		gic_fmu_write_smen(base, smen);
+
+		smen = (GICD_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
+			(FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT);
+		gic_fmu_write_smen(base, smen);
+	}
+
+	for (unsigned int i = FMU_BLK_PPI0; i < FMU_BLK_PPI31; i++) {
+		if ((blk_present_mask & BIT(i)) != 0U) {
+			smen = (PPI_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
+				(i << FMU_SMEN_BLK_SHIFT);
+			gic_fmu_write_smen(base, smen);
+
+			smen = (PPI_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
+				(i << FMU_SMEN_BLK_SHIFT);
+			gic_fmu_write_smen(base, smen);
+		}
+	}
+
+	for (unsigned int i = FMU_BLK_ITS0; i < FMU_BLK_ITS7; i++) {
+		if ((blk_present_mask & BIT(i)) != 0U) {
+			smen = (ITS_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
+				(i << FMU_SMEN_BLK_SHIFT);
+			gic_fmu_write_smen(base, smen);
+
+			smen = (ITS_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
+				(i << FMU_SMEN_BLK_SHIFT);
+			gic_fmu_write_smen(base, smen);
+		}
+	}
+}
+
+/*
+ * This function enable the GICD background ping engine. The GICD sends ping
+ * messages to each remote GIC block, and expects a PING_ACK back within the
+ * specified timeout. Pings need to be enabled after programming the timeout
+ * value.
+ */
+void gic600_fmu_enable_ping(uint64_t base, uint64_t blk_present_mask,
+		unsigned int timeout_val, unsigned int interval_diff)
+{
+	/*
+	 * Populate the PING Mask to skip a specific block while generating
+	 * background ping messages and enable the ping mechanism.
+	 */
+	gic_fmu_write_pingmask(base, ~blk_present_mask);
+	gic_fmu_write_pingctlr(base, (interval_diff << FMU_PINGCTLR_INTDIFF_SHIFT) |
+		(timeout_val << FMU_PINGCTLR_TIMEOUTVAL_SHIFT) | FMU_PINGCTLR_EN_BIT);
+}
+
+/* Print the safety mechanism description for a given block */
+void gic600_fmu_print_sm_info(uint64_t base, unsigned int blk, unsigned int smid)
+{
+	if (blk == FMU_BLK_GICD && smid <= FMU_SMID_GICD_MAX) {
+		INFO("GICD, SMID %d: %s\n", smid, gicd_sm_info[smid]);
+	}
+
+	if (blk == FMU_BLK_SPICOL && smid <= FMU_SMID_SPICOL_MAX) {
+		INFO("SPI Collator, SMID %d: %s\n", smid, spicol_sm_info[smid]);
+	}
+
+	if (blk == FMU_BLK_WAKERQ && (smid <= FMU_SMID_WAKERQ_MAX)) {
+		INFO("Wake Request, SMID %d: %s\n", smid, wkrqst_sm_info[smid]);
+	}
+
+	if (((blk >= FMU_BLK_ITS0) && (blk <= FMU_BLK_ITS7)) && (smid <= FMU_SMID_ITS_MAX)) {
+		INFO("ITS, SMID %d: %s\n", smid, its_sm_info[smid]);
+	}
+
+	if (((blk >= FMU_BLK_PPI0) && (blk <= FMU_BLK_PPI31)) && (smid <= FMU_SMID_PPI_MAX)) {
+		INFO("PPI, SMID %d: %s\n", smid, ppi_sm_info[smid]);
+	}
+}
diff --git a/drivers/arm/gic/v3/gic600ae_fmu_helpers.c b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c
new file mode 100644
index 0000000..84f7292
--- /dev/null
+++ b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <drivers/arm/gic600ae_fmu.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#define GICFMU_IDLE_TIMEOUT_US		U(2000000)
+
+/* Macro to write 32-bit FMU registers */
+#define GIC_FMU_WRITE_32(base, reg, val) \
+	do { \
+		/* \
+		 * This register receives the unlock key that is required for \
+		 * writes to FMU registers to be successful. \
+		 */ \
+		mmio_write_32(base + GICFMU_KEY, 0xBE); \
+		/* Perform the actual write */ \
+		mmio_write_32((base) + (reg), (val)); \
+	} while (false)
+
+/* Macro to write 64-bit FMU registers */
+#define GIC_FMU_WRITE_64(base, reg, n, val) \
+	do { \
+		/* \
+		 * This register receives the unlock key that is required for \
+		 * writes to FMU registers to be successful. \
+		 */ \
+		mmio_write_32(base + GICFMU_KEY, 0xBE); \
+		/* \
+		 * APB bus is 32-bit wide; so split the 64-bit write into \
+		 * two 32-bit writes \
+		 */ \
+		mmio_write_32((base) + reg##_LO + (n * 64), (val)); \
+		mmio_write_32((base) + reg##_HI + (n * 64), (val)); \
+	} while (false)
+
+/* Helper function to wait until FMU is ready to accept the next command */
+static void wait_until_fmu_is_idle(uintptr_t base)
+{
+	uint64_t timeout_ref = timeout_init_us(GICFMU_IDLE_TIMEOUT_US);
+	uint64_t status;
+
+	/* wait until status is 'busy' */
+	do {
+		status = (gic_fmu_read_status(base) & BIT(0));
+
+		if (timeout_elapsed(timeout_ref)) {
+			ERROR("GIC600 AE FMU is not responding\n");
+			panic();
+		}
+	} while (status == U(0));
+}
+
+#define GIC_FMU_WRITE_ON_IDLE_32(base, reg, val) \
+	do { \
+		/* Wait until FMU is ready */ \
+		wait_until_fmu_is_idle(base); \
+		/* Actual register write */ \
+		GIC_FMU_WRITE_32(base, reg, val); \
+		/* Wait until FMU is ready */ \
+		wait_until_fmu_is_idle(base); \
+	} while (false)
+
+#define GIC_FMU_WRITE_ON_IDLE_64(base, reg, n, val) \
+	do { \
+		/* Wait until FMU is ready */ \
+		wait_until_fmu_is_idle(base); \
+		/* Actual register write */ \
+		GIC_FMU_WRITE_64(base, reg, n, val); \
+		/* Wait until FMU is ready */ \
+		wait_until_fmu_is_idle(base); \
+	} while (false)
+
+/*******************************************************************************
+ * GIC FMU functions for accessing the Fault Management Unit registers
+ ******************************************************************************/
+
+/*
+ * Accessors to read the Error Record Feature Register bits corresponding
+ * to an error record 'n'
+ */
+uint64_t gic_fmu_read_errfr(uintptr_t base, unsigned int n)
+{
+	/*
+	 * APB bus is 32-bit wide; so split the 64-bit read into
+	 * two 32-bit reads
+	 */
+	uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRFR_LO + n * 64U);
+
+	reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRFR_HI + n * 64U) << 32);
+	return reg_val;
+}
+
+/*
+ * Accessors to read the Error Record Control Register bits corresponding
+ * to an error record 'n'
+ */
+uint64_t gic_fmu_read_errctlr(uintptr_t base, unsigned int n)
+{
+	/*
+	 * APB bus is 32-bit wide; so split the 64-bit read into
+	 * two 32-bit reads
+	 */
+	uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRCTLR_LO + n * 64U);
+
+	reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRCTLR_HI + n * 64U) << 32);
+	return reg_val;
+}
+
+/*
+ * Accessors to read the Error Record Primary Status Register bits
+ * corresponding to an error record 'n'
+ */
+uint64_t gic_fmu_read_errstatus(uintptr_t base, unsigned int n)
+{
+	/*
+	 * APB bus is 32-bit wide; so split the 64-bit read into
+	 * two 32-bit reads
+	 */
+	uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRSTATUS_LO + n * 64U);
+
+	reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRSTATUS_HI + n * 64U) << 32);
+	return reg_val;
+}
+
+/*
+ * Accessors to read the Error Group Status Register
+ */
+uint64_t gic_fmu_read_errgsr(uintptr_t base)
+{
+	/*
+	 * APB bus is 32-bit wide; so split the 64-bit read into
+	 * two 32-bit reads
+	 */
+	uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRGSR_LO);
+
+	reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRGSR_HI) << 32);
+	return reg_val;
+}
+
+/*
+ * Accessors to read the Ping Control Register
+ */
+uint32_t gic_fmu_read_pingctlr(uintptr_t base)
+{
+	return mmio_read_32(base + GICFMU_PINGCTLR);
+}
+
+/*
+ * Accessors to read the Ping Now Register
+ */
+uint32_t gic_fmu_read_pingnow(uintptr_t base)
+{
+	return mmio_read_32(base + GICFMU_PINGNOW);
+}
+
+/*
+ * Accessors to read the Ping Mask Register
+ */
+uint64_t gic_fmu_read_pingmask(uintptr_t base)
+{
+	/*
+	 * APB bus is 32-bit wide; so split the 64-bit read into
+	 * two 32-bit reads
+	 */
+	uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_PINGMASK_LO);
+
+	reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_PINGMASK_HI) << 32);
+	return reg_val;
+}
+
+/*
+ * Accessors to read the FMU Status Register
+ */
+uint32_t gic_fmu_read_status(uintptr_t base)
+{
+	return mmio_read_32(base + GICFMU_STATUS);
+}
+
+/*
+ * Accessors to read the Error Record ID Register
+ */
+uint32_t gic_fmu_read_erridr(uintptr_t base)
+{
+	return mmio_read_32(base + GICFMU_ERRIDR);
+}
+
+/*
+ * Accessors to write a 64 bit value to the Error Record Control Register
+ */
+void gic_fmu_write_errctlr(uintptr_t base, unsigned int n, uint64_t val)
+{
+	GIC_FMU_WRITE_64(base, GICFMU_ERRCTLR, n, val);
+}
+
+/*
+ * Accessors to write a 64 bit value to the Error Record Primary Status
+ * Register
+ */
+void gic_fmu_write_errstatus(uintptr_t base, unsigned int n, uint64_t val)
+{
+	/* Wait until FMU is ready before writing */
+	GIC_FMU_WRITE_ON_IDLE_64(base, GICFMU_ERRSTATUS, n, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Ping Control Register
+ */
+void gic_fmu_write_pingctlr(uintptr_t base, uint32_t val)
+{
+	GIC_FMU_WRITE_32(base, GICFMU_PINGCTLR, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Ping Now Register
+ */
+void gic_fmu_write_pingnow(uintptr_t base, uint32_t val)
+{
+	/* Wait until FMU is ready before writing */
+	GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_PINGNOW, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Safety Mechanism Enable Register
+ */
+void gic_fmu_write_smen(uintptr_t base, uint32_t val)
+{
+	/* Wait until FMU is ready before writing */
+	GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_SMEN, val);
+}
+
+/*
+ * Accessors to write a 32 bit value to the Safety Mechanism Inject Error
+ * Register
+ */
+void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val)
+{
+	/* Wait until FMU is ready before writing */
+	GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_SMINJERR, val);
+}
+
+/*
+ * Accessors to write a 64 bit value to the Ping Mask Register
+ */
+void gic_fmu_write_pingmask(uintptr_t base, uint64_t val)
+{
+	GIC_FMU_WRITE_64(base, GICFMU_PINGMASK, 0, val);
+}
diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk
index a2fc16f..d7e3536 100644
--- a/drivers/arm/gic/v3/gicv3.mk
+++ b/drivers/arm/gic/v3/gicv3.mk
@@ -1,11 +1,13 @@
 #
 # Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 # Default configuration values
 GICV3_SUPPORT_GIC600		?=	0
+GICV3_SUPPORT_GIC600AE_FMU	?=	0
 GICV3_IMPL_GIC600_MULTICHIP	?=	0
 GICV3_OVERRIDE_DISTIF_PWR_OPS	?=	0
 GIC_ENABLE_V4_EXTN		?=	0
@@ -16,6 +18,11 @@
 			drivers/arm/gic/v3/gicdv3_helpers.c	\
 			drivers/arm/gic/v3/gicrv3_helpers.c
 
+ifeq (${GICV3_SUPPORT_GIC600AE_FMU}, 1)
+GICV3_SOURCES	+=	drivers/arm/gic/v3/gic600ae_fmu.c	\
+			drivers/arm/gic/v3/gic600ae_fmu_helpers.c
+endif
+
 ifeq (${GICV3_OVERRIDE_DISTIF_PWR_OPS}, 0)
 GICV3_SOURCES	+=	drivers/arm/gic/v3/arm_gicv3_common.c
 endif
@@ -29,6 +36,10 @@
 $(eval $(call assert_boolean,GICV3_SUPPORT_GIC600))
 $(eval $(call add_define,GICV3_SUPPORT_GIC600))
 
+# Set GIC-600AE FMU support
+$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600AE_FMU))
+$(eval $(call add_define,GICV3_SUPPORT_GIC600AE_FMU))
+
 # Set GICv4 extension
 $(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN))
 $(eval $(call add_define,GIC_ENABLE_V4_EXTN))
diff --git a/drivers/nxp/dcfg/dcfg.c b/drivers/nxp/dcfg/dcfg.c
index 2e813e7..a988c5d 100644
--- a/drivers/nxp/dcfg/dcfg.c
+++ b/drivers/nxp/dcfg/dcfg.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 NXP
+ * Copyright 2020-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -43,20 +43,12 @@
 
 	reg = gur_in32(dcfg_init_info->g_nxp_dcfg_addr + DCFG_SVR_OFFSET);
 
-	soc_info.mfr_id = (reg & SVR_MFR_ID_MASK) >> SVR_MFR_ID_SHIFT;
-#if defined(CONFIG_CHASSIS_3_2)
-	soc_info.family = (reg & SVR_FAMILY_MASK) >> SVR_FAMILY_SHIFT;
-	soc_info.dev_id = (reg & SVR_DEV_ID_MASK) >> SVR_DEV_ID_SHIFT;
-#endif
+	soc_info.svr_reg.val = reg;
+
 	/* zero means SEC enabled. */
 	soc_info.sec_enabled =
 		(((reg & SVR_SEC_MASK) >> SVR_SEC_SHIFT) == 0) ? true : false;
 
-	soc_info.personality = (reg & SVR_PERSONALITY_MASK)
-				>> SVR_PERSONALITY_SHIFT;
-	soc_info.maj_ver = (reg & SVR_MAJ_VER_MASK) >> SVR_MAJ_VER_SHIFT;
-	soc_info.min_ver = reg & SVR_MIN_VER_MASK;
-
 	soc_info.is_populated = true;
 	return (const soc_info_t *) &soc_info;
 }
diff --git a/drivers/nxp/ddr/phy-gen2/phy.c b/drivers/nxp/ddr/phy-gen2/phy.c
index 97de1ae..9c84b00 100644
--- a/drivers/nxp/ddr/phy-gen2/phy.c
+++ b/drivers/nxp/ddr/phy-gen2/phy.c
@@ -672,7 +672,7 @@
 
 #ifdef DDR_PLL_FIX
 	soc_info = get_soc_info();
-	if (soc_info->maj_ver == 1) {
+	if (soc_info->svr_reg.bf.maj_ver == 1) {
 		ps_count[0] = 0x520; /* seq0bdly0 */
 		ps_count[1] = 0xa41; /* seq0bdly1 */
 		ps_count[2] = 0x668a; /* seq0bdly2 */
@@ -1093,8 +1093,8 @@
 
 #ifdef ERRATA_DDR_A011396
 	/* Only apply to DDRC 5.05.00 */
-	soc_info = get_soc_info(NXP_DCFG_ADDR);
-	if ((soc_info->maj_ver == 1U) && (ip_rev == U(0x50500))) {
+	soc_info = get_soc_info();
+	if ((soc_info->svr_reg.bf.maj_ver == 1U) && (ip_rev == U(0x50500))) {
 		phy_io_write16(phy,
 				t_master | csr_dfi_rd_data_cs_dest_map_addr,
 				0U);
@@ -1890,8 +1890,8 @@
 		prog_pll_ctrl2(phy, input);
 #ifdef DDR_PLL_FIX
 		soc_info = get_soc_info();
-		debug("SOC_SI_REV = %x\n", soc_info->maj_ver);
-		if (soc_info->maj_ver == 1) {
+		debug("SOC_SI_REV = %x\n", soc_info->svr_reg.bf.maj_ver);
+		if (soc_info->svr_reg.bf.maj_ver == 1) {
 			prog_pll_pwr_dn(phy, input);
 
 			/*Enable FFE aka TxEqualizationMode for rev1 SI*/
@@ -2601,8 +2601,8 @@
 		}
 
 #ifdef NXP_APPLY_MAX_CDD
-		soc_info = get_soc_info(NXP_DCFG_ADDR);
-		if (soc_info->maj_ver == 2) {
+		soc_info = get_soc_info();
+		if (soc_info->svr_reg.bf.maj_ver == 2) {
 			tcfg0 = regs->timing_cfg[0];
 			tcfg4 = regs->timing_cfg[4];
 			rank = findrank(conf->cs_in_use);
diff --git a/include/drivers/arm/gic600ae_fmu.h b/include/drivers/arm/gic600ae_fmu.h
new file mode 100644
index 0000000..691ffc7
--- /dev/null
+++ b/include/drivers/arm/gic600ae_fmu.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GIC600AE_FMU_H
+#define GIC600AE_FMU_H
+
+/*******************************************************************************
+ * GIC600-AE FMU register offsets and constants
+ ******************************************************************************/
+#define GICFMU_ERRFR_LO		U(0x000)
+#define GICFMU_ERRFR_HI		U(0x004)
+#define GICFMU_ERRCTLR_LO	U(0x008)
+#define GICFMU_ERRCTLR_HI	U(0x00C)
+#define GICFMU_ERRSTATUS_LO	U(0x010)
+#define GICFMU_ERRSTATUS_HI	U(0x014)
+#define GICFMU_ERRGSR_LO	U(0xE00)
+#define GICFMU_ERRGSR_HI	U(0xE04)
+#define GICFMU_KEY		U(0xEA0)
+#define GICFMU_PINGCTLR		U(0xEA4)
+#define GICFMU_PINGNOW		U(0xEA8)
+#define GICFMU_SMEN		U(0xEB0)
+#define GICFMU_SMINJERR		U(0xEB4)
+#define GICFMU_PINGMASK_LO	U(0xEC0)
+#define GICFMU_PINGMASK_HI	U(0xEC4)
+#define GICFMU_STATUS		U(0xF00)
+#define GICFMU_ERRIDR		U(0xFC8)
+
+/* ERRCTLR bits */
+#define FMU_ERRCTLR_ED_BIT	BIT(0)
+#define FMU_ERRCTLR_CE_EN_BIT	BIT(1)
+#define FMU_ERRCTLR_UI_BIT	BIT(2)
+#define FMU_ERRCTLR_CI_BIT	BIT(3)
+
+/* SMEN constants */
+#define FMU_SMEN_BLK_SHIFT	U(8)
+#define FMU_SMEN_SMID_SHIFT	U(24)
+
+/* Error record IDs */
+#define FMU_BLK_GICD		U(0)
+#define FMU_BLK_SPICOL		U(1)
+#define FMU_BLK_WAKERQ		U(2)
+#define FMU_BLK_ITS0		U(4)
+#define FMU_BLK_ITS1		U(5)
+#define FMU_BLK_ITS2		U(6)
+#define FMU_BLK_ITS3		U(7)
+#define FMU_BLK_ITS4		U(8)
+#define FMU_BLK_ITS5		U(9)
+#define FMU_BLK_ITS6		U(10)
+#define FMU_BLK_ITS7		U(11)
+#define FMU_BLK_PPI0		U(12)
+#define FMU_BLK_PPI1		U(13)
+#define FMU_BLK_PPI2		U(14)
+#define FMU_BLK_PPI3		U(15)
+#define FMU_BLK_PPI4		U(16)
+#define FMU_BLK_PPI5		U(17)
+#define FMU_BLK_PPI6		U(18)
+#define FMU_BLK_PPI7		U(19)
+#define FMU_BLK_PPI8		U(20)
+#define FMU_BLK_PPI9		U(21)
+#define FMU_BLK_PPI10		U(22)
+#define FMU_BLK_PPI11		U(23)
+#define FMU_BLK_PPI12		U(24)
+#define FMU_BLK_PPI13		U(25)
+#define FMU_BLK_PPI14		U(26)
+#define FMU_BLK_PPI15		U(27)
+#define FMU_BLK_PPI16		U(28)
+#define FMU_BLK_PPI17		U(29)
+#define FMU_BLK_PPI18		U(30)
+#define FMU_BLK_PPI19		U(31)
+#define FMU_BLK_PPI20		U(32)
+#define FMU_BLK_PPI21		U(33)
+#define FMU_BLK_PPI22		U(34)
+#define FMU_BLK_PPI23		U(35)
+#define FMU_BLK_PPI24		U(36)
+#define FMU_BLK_PPI25		U(37)
+#define FMU_BLK_PPI26		U(38)
+#define FMU_BLK_PPI27		U(39)
+#define FMU_BLK_PPI28		U(40)
+#define FMU_BLK_PPI29		U(41)
+#define FMU_BLK_PPI30		U(42)
+#define FMU_BLK_PPI31		U(43)
+#define FMU_BLK_PRESENT_MASK	U(0xFFFFFFFFFFF)
+
+/* Safety Mechamism limit */
+#define FMU_SMID_GICD_MAX	U(33)
+#define FMU_SMID_SPICOL_MAX	U(5)
+#define FMU_SMID_WAKERQ_MAX	U(2)
+#define FMU_SMID_ITS_MAX	U(14)
+#define FMU_SMID_PPI_MAX	U(12)
+
+/* MBIST Safety Mechanism ID */
+#define GICD_MBIST_REQ_ERROR	U(23)
+#define GICD_FMU_CLKGATE_ERROR	U(33)
+#define PPI_MBIST_REQ_ERROR	U(10)
+#define PPI_FMU_CLKGATE_ERROR	U(12)
+#define ITS_MBIST_REQ_ERROR	U(13)
+#define ITS_FMU_CLKGATE_ERROR	U(14)
+
+/* ERRSTATUS bits */
+#define FMU_ERRSTATUS_V_BIT	BIT(30)
+#define FMU_ERRSTATUS_UE_BIT	BIT(29)
+#define FMU_ERRSTATUS_OV_BIT	BIT(27)
+#define FMU_ERRSTATUS_CE_BITS	(BIT(25) | BIT(24))
+#define FMU_ERRSTATUS_CLEAR	(FMU_ERRSTATUS_V_BIT | FMU_ERRSTATUS_UE_BIT | \
+				 FMU_ERRSTATUS_OV_BIT | FMU_ERRSTATUS_CE_BITS)
+
+/* PINGCTLR constants */
+#define FMU_PINGCTLR_INTDIFF_SHIFT	U(16)
+#define FMU_PINGCTLR_TIMEOUTVAL_SHIFT	U(4)
+#define FMU_PINGCTLR_EN_BIT		BIT(0)
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+
+/*******************************************************************************
+ * GIC600 FMU EL3 driver API
+ ******************************************************************************/
+uint64_t gic_fmu_read_errfr(uintptr_t base, unsigned int n);
+uint64_t gic_fmu_read_errctlr(uintptr_t base, unsigned int n);
+uint64_t gic_fmu_read_errstatus(uintptr_t base, unsigned int n);
+uint64_t gic_fmu_read_errgsr(uintptr_t base);
+uint32_t gic_fmu_read_pingctlr(uintptr_t base);
+uint32_t gic_fmu_read_pingnow(uintptr_t base);
+uint64_t gic_fmu_read_pingmask(uintptr_t base);
+uint32_t gic_fmu_read_status(uintptr_t base);
+uint32_t gic_fmu_read_erridr(uintptr_t base);
+void gic_fmu_write_errctlr(uintptr_t base, unsigned int n, uint64_t val);
+void gic_fmu_write_errstatus(uintptr_t base, unsigned int n, uint64_t val);
+void gic_fmu_write_pingctlr(uintptr_t base, uint32_t val);
+void gic_fmu_write_pingnow(uintptr_t base, uint32_t val);
+void gic_fmu_write_smen(uintptr_t base, uint32_t val);
+void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val);
+void gic_fmu_write_pingmask(uintptr_t base, uint64_t val);
+
+void gic600_fmu_init(uint64_t base, uint64_t blk_present_mask, bool errctlr_ce_en, bool errctlr_ue_en);
+void gic600_fmu_enable_ping(uint64_t base, uint64_t blk_present_mask,
+		unsigned int timeout_val, unsigned int interval_diff);
+void gic600_fmu_print_sm_info(uint64_t base, unsigned int blk, unsigned int smid);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* GIC600AE_FMU_H */
diff --git a/include/drivers/nxp/dcfg/dcfg.h b/include/drivers/nxp/dcfg/dcfg.h
index 3f4855a..524450a 100644
--- a/include/drivers/nxp/dcfg/dcfg.h
+++ b/include/drivers/nxp/dcfg/dcfg.h
@@ -27,23 +27,41 @@
 #endif
 
 typedef struct {
-	bool is_populated;
-	uint8_t mfr_id;
-#if defined(CONFIG_CHASSIS_3_2)
-	uint8_t family;
-	uint8_t dev_id;
+	union {
+		uint32_t val;
+		struct {
+			uint32_t min_ver:4;
+			uint32_t maj_ver:4;
+#if defined(CONFIG_CHASSIS_3) || defined(CONFIG_CHASSIS_3_2)
+			uint32_t personality:6;
+			uint32_t rsv1:2;
+#elif defined(CONFIG_CHASSIS_2)
+			uint32_t personality:8;
+
 #endif
-	uint8_t personality;
+#if defined(CONFIG_CHASSIS_3) || defined(CONFIG_CHASSIS_3_2)
+			uint32_t dev_id:6;
+			uint32_t rsv2:2;
+			uint32_t family:4;
+#elif defined(CONFIG_CHASSIS_2)
+			uint32_t dev_id:12;
+#endif
+			uint32_t mfr_id;
+		} __packed bf;
+		struct {
+			uint32_t maj_min:8;
+			uint32_t version; /* SoC version without major and minor info */
+		} __packed bf_ver;
+	} __packed svr_reg;
 	bool sec_enabled;
-	uint8_t maj_ver;
-	uint8_t min_ver;
+	bool is_populated;
 } soc_info_t;
 
 typedef struct {
 	bool is_populated;
 	uint8_t ocram_present;
 	uint8_t ddrc1_present;
-#if defined(CONFIG_CHASSIS_3_2)
+#if defined(CONFIG_CHASSIS_3) || defined(CONFIG_CHASSIS_3_2)
 	uint8_t ddrc2_present;
 #endif
 } devdisr5_info_t;
diff --git a/include/drivers/nxp/dcfg/dcfg_lsch2.h b/include/drivers/nxp/dcfg/dcfg_lsch2.h
index 2838aca..1e56729 100644
--- a/include/drivers/nxp/dcfg/dcfg_lsch2.h
+++ b/include/drivers/nxp/dcfg/dcfg_lsch2.h
@@ -34,12 +34,10 @@
 
 #define SVR_MFR_ID_MASK			0xF0000000
 #define SVR_MFR_ID_SHIFT		28
-#define SVR_FAMILY_MASK			0xF000000
-#define SVR_FAMILY_SHIFT		24
-#define SVR_DEV_ID_MASK			0x3F0000
+#define SVR_DEV_ID_MASK			0xFFF0000
 #define SVR_DEV_ID_SHIFT		16
-#define SVR_PERSONALITY_MASK		0x3E00
-#define SVR_PERSONALITY_SHIFT		9
+#define SVR_PERSONALITY_MASK		0xFF00
+#define SVR_PERSONALITY_SHIFT		8
 #define SVR_SEC_MASK			0x100
 #define SVR_SEC_SHIFT			8
 #define SVR_MAJ_VER_MASK		0xF0
diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h
index 44c540c..8b011aa 100644
--- a/include/lib/cpus/aarch64/cortex_a710.h
+++ b/include/lib/cpus/aarch64/cortex_a710.h
@@ -13,6 +13,7 @@
  * CPU Extended Control register specific definitions
  ******************************************************************************/
 #define CORTEX_A710_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_A710_CPUECTLR_EL1_PFSTIDIS_BIT                   (ULL(1) << 8)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
@@ -20,4 +21,10 @@
 #define CORTEX_A710_CPUPWRCTLR_EL1				S3_0_C15_C2_7
 #define CORTEX_A710_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A710_CPUACTLR_EL1 				S3_0_C15_C1_0
+#define CORTEX_A710_CPUACTLR_EL1_BIT_46 			(ULL(1) << 46)
+
 #endif /* CORTEX_A710_H */
diff --git a/include/lib/cpus/aarch64/cortex_a78_ae.h b/include/lib/cpus/aarch64/cortex_a78_ae.h
index 24ae7ee..0c8adcf 100644
--- a/include/lib/cpus/aarch64/cortex_a78_ae.h
+++ b/include/lib/cpus/aarch64/cortex_a78_ae.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,4 +12,10 @@
 
 #define CORTEX_A78_AE_MIDR U(0x410FD420)
 
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A78_AE_CPUECTLR_EL1			CORTEX_A78_CPUECTLR_EL1
+#define CORTEX_A78_AE_CPUECTLR_EL1_BIT_8		CORTEX_A78_CPUECTLR_EL1_BIT_8
+
 #endif /* CORTEX_A78_AE_H */
diff --git a/include/lib/cpus/aarch64/cortex_demeter.h b/include/lib/cpus/aarch64/cortex_demeter.h
new file mode 100644
index 0000000..9dd0987
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_demeter.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_DEMETER_H
+#define CORTEX_DEMETER_H
+
+#define CORTEX_DEMETER_MIDR				U(0x410FD4F0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_DEMETER_CPUECTLR_EL1			S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_DEMETER_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define CORTEX_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+
+#endif /* CORTEX_DEMETER_H */
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index 7cbd8c1..948f965 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,11 +21,24 @@
  ******************************************************************************/
 #define NEOVERSE_N2_CPUECTLR_EL1		S3_0_C15_C1_4
 #define NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT	(ULL(1) << 0)
+#define NEOVERSE_N2_CPUECTLR_EL1_PFSTIDIS_BIT	(ULL(1) << 8)
 
 /*******************************************************************************
  * CPU Auxiliary Control register specific definitions.
  ******************************************************************************/
+#define NEOVERSE_N2_CPUACTLR_EL1		S3_0_C15_C1_0
+#define NEOVERSE_N2_CPUACTLR_EL1_BIT_46	        (ULL(1) << 46)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 2 specific definitions.
+ ******************************************************************************/
 #define NEOVERSE_N2_CPUACTLR2_EL1		S3_0_C15_C1_1
 #define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2		(ULL(1) << 2)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register 5 specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_N2_CPUACTLR5_EL1		S3_0_C15_C8_0
+#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_44	(ULL(1) << 44)
+
 #endif /* NEOVERSE_N2_H */
diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h
index 5426135..3d57a5c 100644
--- a/include/lib/el3_runtime/cpu_data.h
+++ b/include/lib/el3_runtime/cpu_data.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -125,7 +125,7 @@
 #if ENABLE_PAUTH
 CASSERT(CPU_DATA_APIAKEY_OFFSET == __builtin_offsetof
 	(cpu_data_t, apiakey),
-	assert_cpu_data_crash_stack_offset_mismatch);
+	assert_cpu_data_pauth_stack_offset_mismatch);
 #endif
 
 #if CRASH_REPORTING
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 4f979f8..75b7647 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -21,6 +21,145 @@
 #error "Cortex A710 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+/* --------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 1987031.
+ * This applies to revision r0p0, r1p0 and r2p0 of Cortex-A710. It is still
+ * open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a710_1987031_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_1987031
+	cbz	x0, 1f
+
+	/* Apply instruction patching sequence */
+	ldr x0,=0x6
+	msr S3_6_c15_c8_0,x0
+	ldr x0,=0xF3A08002
+	msr S3_6_c15_c8_2,x0
+	ldr x0,=0xFFF0F7FE
+	msr S3_6_c15_c8_3,x0
+	ldr x0,=0x40000001003ff
+	msr S3_6_c15_c8_1,x0
+	ldr x0,=0x7
+	msr S3_6_c15_c8_0,x0
+	ldr x0,=0xBF200000
+	msr S3_6_c15_c8_2,x0
+	ldr x0,=0xFFEF0000
+	msr S3_6_c15_c8_3,x0
+	ldr x0,=0x40000001003f3
+	msr S3_6_c15_c8_1,x0
+	isb
+1:
+	ret	x17
+endfunc errata_a710_1987031_wa
+
+func check_errata_1987031
+	/* Applies to r0p0, r1p0 and r2p0 */
+	mov	x1, #0x20
+	b	cpu_rev_var_ls
+endfunc check_errata_1987031
+
+/* --------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2081180.
+ * This applies to revision r0p0, r1p0 and r2p0 of Cortex-A710.
+ * It is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a710_2081180_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2081180
+	cbz	x0, 1f
+
+	/* Apply instruction patching sequence */
+	ldr	x0,=0x3
+	msr	S3_6_c15_c8_0,x0
+	ldr	x0,=0xF3A08002
+	msr	S3_6_c15_c8_2,x0
+	ldr	x0,=0xFFF0F7FE
+	msr	S3_6_c15_c8_3,x0
+	ldr	x0,=0x10002001003FF
+	msr	S3_6_c15_c8_1,x0
+	ldr	x0,=0x4
+	msr	S3_6_c15_c8_0,x0
+	ldr	x0,=0xBF200000
+	msr	S3_6_c15_c8_2,x0
+	ldr	x0,=0xFFEF0000
+	msr	S3_6_c15_c8_3,x0
+	ldr	x0,=0x10002001003F3
+	msr	S3_6_c15_c8_1,x0
+	isb
+1:
+	ret	x17
+endfunc errata_a710_2081180_wa
+
+func check_errata_2081180
+	/* Applies to r0p0, r1p0 and r2p0 */
+	mov	x1, #0x20
+	b	cpu_rev_var_ls
+endfunc check_errata_2081180
+
+/* ---------------------------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2055002.
+ * This applies to revision r1p0, r2p0 of Cortex-A710 and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ---------------------------------------------------------------------
+ */
+func errata_a710_2055002_wa
+	/* Compare x0 against revision r2p0 */
+	mov	x17, x30
+	bl	check_errata_2055002
+	cbz	x0, 1f
+	mrs	x1, CORTEX_A710_CPUACTLR_EL1
+	orr	x1, x1, CORTEX_A710_CPUACTLR_EL1_BIT_46
+	msr	CORTEX_A710_CPUACTLR_EL1, x1
+1:
+	ret	x17
+endfunc errata_a710_2055002_wa
+
+func check_errata_2055002
+	/* Applies to r1p0, r2p0 */
+	mov	x1, #0x20
+	b	cpu_rev_var_ls
+endfunc check_errata_2055002
+
+/* -------------------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2017096.
+ * This applies to revisions r0p0, r1p0 and r2p0 of Cortex-A710.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * -------------------------------------------------------------
+ */
+func errata_a710_2017096_wa
+	/* Compare x0 against revision r0p0 to r2p0 */
+	mov     x17, x30
+	bl      check_errata_2017096
+	cbz     x0, 1f
+	mrs     x1, CORTEX_A710_CPUECTLR_EL1
+	orr     x1, x1, CORTEX_A710_CPUECTLR_EL1_PFSTIDIS_BIT
+	msr     CORTEX_A710_CPUECTLR_EL1, x1
+
+1:
+	ret     x17
+endfunc errata_a710_2017096_wa
+
+func check_errata_2017096
+	/* Applies to r0p0, r1p0, r2p0 */
+	mov     x1, #0x20
+	b       cpu_rev_var_ls
+endfunc check_errata_2017096
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -37,20 +176,60 @@
 	ret
 endfunc cortex_a710_core_pwr_dwn
 
-	/*
-	 * Errata printing function for Cortex A710. Must follow AAPCS.
-	 */
 #if REPORT_ERRATA
+	/*
+	 * Errata printing function for Cortex-A710. Must follow AAPCS.
+	 */
 func cortex_a710_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 ERRATA_A710_1987031, cortex_a710, 1987031
+	report_errata ERRATA_A710_2081180, cortex_a710, 2081180
+	report_errata ERRATA_A710_2055002, cortex_a710, 2055002
+	report_errata ERRATA_A710_2017096, cortex_a710, 2017096
+
+	ldp	x8, x30, [sp], #16
 	ret
 endfunc cortex_a710_errata_report
 #endif
 
 func cortex_a710_reset_func
+	mov	x19, x30
+
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+
+	bl	cpu_get_rev_var
+	mov	x18, x0
+
+#if ERRATA_A710_1987031
+	mov	x0, x18
+	bl	errata_a710_1987031_wa
+#endif
+
+#if ERRATA_A710_2081180
+	mov	x0, x18
+	bl	errata_a710_2081180_wa
+#endif
+
+#if ERRATA_A710_2055002
+	mov	x0, x18
+	bl	errata_a710_2055002_wa
+#endif
+
+#if ERRATA_A710_2017096
+	mov     x0, x18
+	bl      errata_a710_2017096_wa
+#endif
 	isb
-	ret
+	ret	x19
 endfunc cortex_a710_reset_func
 
 	/* ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 8c5a45a..3a74571 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -154,6 +154,50 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_1821534
 
+/* --------------------------------------------------
+ * Errata Workaround for Cortex A78 Errata 1952683.
+ * This applies to revision r0p0.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78_1952683_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_1952683
+	cbz	x0, 1f
+
+	ldr	x0,=0x5
+	msr	S3_6_c15_c8_0,x0
+	ldr	x0,=0xEEE10A10
+	msr	S3_6_c15_c8_2,x0
+	ldr	x0,=0xFFEF0FFF
+	msr	S3_6_c15_c8_3,x0
+	ldr	x0,=0x0010F000
+	msr	S3_6_c15_c8_4,x0
+	ldr	x0,=0x0010F000
+	msr	S3_6_c15_c8_5,x0
+	ldr	x0,=0x40000080023ff
+	msr	S3_6_c15_c8_1,x0
+	ldr	x0,=0x6
+	msr	S3_6_c15_c8_0,x0
+	ldr	x0,=0xEE640F34
+	msr	S3_6_c15_c8_2,x0
+	ldr	x0,=0xFFEF0FFF
+	msr	S3_6_c15_c8_3,x0
+	ldr	x0,=0x40000080023ff
+	msr	S3_6_c15_c8_1,x0
+	isb
+1:
+	ret	x17
+endfunc errata_a78_1952683_wa
+
+func check_errata_1952683
+	/* Applies to r0p0 only */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_1952683
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A78
 	 * -------------------------------------------------
@@ -183,6 +227,11 @@
 	bl	errata_a78_1821534_wa
 #endif
 
+#if ERRATA_A78_1952683
+	mov	x0, x18
+	bl	errata_a78_1952683_wa
+#endif
+
 #if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
@@ -241,6 +290,7 @@
 	report_errata ERRATA_A78_1941498, cortex_a78, 1941498
 	report_errata ERRATA_A78_1951500, cortex_a78, 1951500
 	report_errata ERRATA_A78_1821534, cortex_a78, 1821534
+	report_errata ERRATA_A78_1952683, cortex_a78, 1952683
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index 9aff9ac..421c174 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,12 +17,108 @@
 #error "cortex_a78_ae must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
+/* --------------------------------------------------
+ * Errata Workaround for A78 AE Erratum 1941500.
+ * This applies to revisions r0p0 and r0p1 of A78 AE.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78_ae_1941500_wa
+	/* Compare x0 against revisions r0p0 - r0p1 */
+	mov	x17, x30
+	bl	check_errata_1941500
+	cbz	x0, 1f
+
+	/* Set bit 8 in ECTLR_EL1 */
+	mrs	x0, CORTEX_A78_AE_CPUECTLR_EL1
+	bic	x0, x0, #CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
+	msr	CORTEX_A78_AE_CPUECTLR_EL1, x0
+	isb
+1:
+	ret	x17
+endfunc errata_a78_ae_1941500_wa
+
+func check_errata_1941500
+	/* Applies to revisions r0p0 and r0p1. */
+	mov	x1, #CPU_REV(0, 0)
+	mov	x2, #CPU_REV(0, 1)
+	b	cpu_rev_var_range
+endfunc check_errata_1941500
+
+/* --------------------------------------------------
+ * Errata Workaround for A78 AE Erratum 1951502.
+ * This applies to revisions r0p0 and r0p1 of A78 AE.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78_ae_1951502_wa
+	/* Compare x0 against revisions r0p0 - r0p1 */
+	mov	x17, x30
+	bl	check_errata_1951502
+	cbz	x0, 1f
+
+	msr	S3_6_c15_c8_0, xzr
+	ldr	x0, =0x10E3900002
+	msr	S3_6_c15_c8_2, x0
+	ldr	x0, =0x10FFF00083
+	msr	S3_6_c15_c8_3, x0
+	ldr	x0, =0x2001003FF
+	msr	S3_6_c15_c8_1, x0
+
+	mov	x0, #1
+	msr	S3_6_c15_c8_0, x0
+	ldr	x0, =0x10E3800082
+	msr	S3_6_c15_c8_2, x0
+	ldr	x0, =0x10FFF00083
+	msr	S3_6_c15_c8_3, x0
+	ldr	x0, =0x2001003FF
+	msr	S3_6_c15_c8_1, x0
+
+	mov	x0, #2
+	msr	S3_6_c15_c8_0, x0
+	ldr	x0, =0x10E3800200
+	msr	S3_6_c15_c8_2, x0
+	ldr	x0, =0x10FFF003E0
+	msr	S3_6_c15_c8_3, x0
+	ldr	x0, =0x2001003FF
+	msr	S3_6_c15_c8_1, x0
+
+	isb
+1:
+	ret	x17
+endfunc errata_a78_ae_1951502_wa
+
+func check_errata_1951502
+	/* Applies to revisions r0p0 and r0p1. */
+	mov	x1, #CPU_REV(0, 0)
+	mov	x2, #CPU_REV(0, 1)
+	b	cpu_rev_var_range
+endfunc check_errata_1951502
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A78-AE
 	 * -------------------------------------------------
 	 */
-#if ENABLE_AMU
 func cortex_a78_ae_reset_func
+	mov	x19, x30
+	bl	cpu_get_rev_var
+	mov	x18, x0
+
+#if ERRATA_A78_AE_1941500
+	mov	x0, x18
+	bl	errata_a78_ae_1941500_wa
+#endif
+
+#if ERRATA_A78_AE_1951502
+	mov	x0, x18
+	bl	errata_a78_ae_1951502_wa
+#endif
+
+#if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
 	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
@@ -39,11 +136,12 @@
 	/* Enable group1 counters */
 	mov	x0, #CORTEX_A78_AMU_GROUP1_MASK
 	msr	CPUAMCNTENSET1_EL0, x0
+#endif
+
 	isb
 
-	ret
+	ret	x19
 endfunc cortex_a78_ae_reset_func
-#endif
 
 	/* -------------------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -66,6 +164,19 @@
 	 */
 #if REPORT_ERRATA
 func cortex_a78_ae_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 ERRATA_A78_AE_1941500, cortex_a78_ae, 1941500
+	report_errata ERRATA_A78_AE_1951502, cortex_a78_ae, 1951502
+
+	ldp	x8, x30, [sp], #16
 	ret
 endfunc cortex_a78_ae_errata_report
 #endif
@@ -89,12 +200,6 @@
 	ret
 endfunc cortex_a78_ae_cpu_reg_dump
 
-#if ENABLE_AMU
-#define A78_AE_RESET_FUNC cortex_a78_ae_reset_func
-#else
-#define A78_AE_RESET_FUNC CPU_NO_RESET_FUNC
-#endif
-
 declare_cpu_ops cortex_a78_ae, CORTEX_A78_AE_MIDR, \
-	A78_AE_RESET_FUNC, \
+	cortex_a78_ae_reset_func, \
 	cortex_a78_ae_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_demeter.S b/lib/cpus/aarch64/cortex_demeter.S
new file mode 100644
index 0000000..9ad8b86
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_demeter.S
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021, 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_demeter.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex Demeter must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex Demeter supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_demeter_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	mrs	x0, CORTEX_DEMETER_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_DEMETER_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_demeter_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex Demeter. Must follow AAPCS.
+ */
+func cortex_demeter_errata_report
+	ret
+endfunc cortex_demeter_errata_report
+#endif
+
+func cortex_demeter_reset_func
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+	isb
+	ret
+endfunc cortex_demeter_reset_func
+
+	/* ---------------------------------------------
+	 * This function provides Cortex 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.cortex_demeter_regs, "aS"
+cortex_demeter_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_demeter_cpu_reg_dump
+	adr	x6, cortex_demeter_regs
+	mrs	x8, CORTEX_DEMETER_CPUECTLR_EL1
+	ret
+endfunc cortex_demeter_cpu_reg_dump
+
+declare_cpu_ops cortex_demeter, CORTEX_DEMETER_MIDR, \
+	cortex_demeter_reset_func, \
+	cortex_demeter_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 8d646cb..9e7bbf7 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,11 +19,177 @@
 #error "Neoverse-N2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-	/* -------------------------------------------------
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2002655.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_n2_2002655_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2002655
+	cbz	x0, 1f
+
+	/* Apply instruction patching sequence */
+	ldr x0,=0x6
+	msr S3_6_c15_c8_0,x0
+	ldr x0,=0xF3A08002
+	msr S3_6_c15_c8_2,x0
+	ldr x0,=0xFFF0F7FE
+	msr S3_6_c15_c8_3,x0
+	ldr x0,=0x40000001003ff
+	msr S3_6_c15_c8_1,x0
+	ldr x0,=0x7
+	msr S3_6_c15_c8_0,x0
+	ldr x0,=0xBF200000
+	msr S3_6_c15_c8_2,x0
+	ldr x0,=0xFFEF0000
+	msr S3_6_c15_c8_3,x0
+	ldr x0,=0x40000001003f3
+	msr S3_6_c15_c8_1,x0
+	isb
+1:
+	ret	x17
+endfunc errata_n2_2002655_wa
+
+func check_errata_2002655
+	/* Applies to r0p0 */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_2002655
+
+/* ---------------------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2067956.
+ * This applies to revision r0p0 of Neoverse N2 and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ---------------------------------------------------------------
+ */
+func errata_n2_2067956_wa
+	/* Compare x0 against revision r0p0 */
+	mov	x17, x30
+	bl	check_errata_2067956
+	cbz	x0, 1f
+	mrs	x1, NEOVERSE_N2_CPUACTLR_EL1
+	orr	x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_46
+	msr	NEOVERSE_N2_CPUACTLR_EL1, x1
+1:
+	ret	x17
+endfunc errata_n2_2067956_wa
+
+func check_errata_2067956
+	/* Applies to r0p0 */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_2067956
+
+/* ---------------------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2025414.
+ * This applies to revision r0p0 of Neoverse N2 and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ---------------------------------------------------------------
+ */
+func errata_n2_2025414_wa
+	/* Compare x0 against revision r0p0 */
+	mov     x17, x30
+	bl      check_errata_2025414
+	cbz     x0, 1f
+	mrs     x1, NEOVERSE_N2_CPUECTLR_EL1
+	orr     x1, x1, NEOVERSE_N2_CPUECTLR_EL1_PFSTIDIS_BIT
+	msr     NEOVERSE_N2_CPUECTLR_EL1, x1
+
+1:
+	ret     x17
+endfunc errata_n2_2025414_wa
+
+func check_errata_2025414
+	/* Applies to r0p0 */
+	mov     x1, #0x00
+	b       cpu_rev_var_ls
+endfunc check_errata_2025414
+
+/* ---------------------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2189731.
+ * This applies to revision r0p0 of Neoverse N2 and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ---------------------------------------------------------------
+ */
+func errata_n2_2189731_wa
+	/* Compare x0 against revision r0p0 */
+	mov     x17, x30
+	bl      check_errata_2189731
+	cbz     x0, 1f
+	mrs     x1, NEOVERSE_N2_CPUACTLR5_EL1
+	orr     x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_44
+	msr     NEOVERSE_N2_CPUACTLR5_EL1, x1
+
+1:
+	ret     x17
+endfunc errata_n2_2189731_wa
+
+func check_errata_2189731
+	/* Applies to r0p0 */
+	mov     x1, #0x00
+	b       cpu_rev_var_ls
+endfunc check_errata_2189731
+
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2138956.
+ * This applies to revision r0p0 of Neoverse N2. it is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_n2_2138956_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2138956
+	cbz	x0, 1f
+
+	/* Apply instruction patching sequence */
+	ldr	x0,=0x3
+	msr	S3_6_c15_c8_0,x0
+	ldr	x0,=0xF3A08002
+	msr	S3_6_c15_c8_2,x0
+	ldr	x0,=0xFFF0F7FE
+	msr	S3_6_c15_c8_3,x0
+	ldr	x0,=0x10002001003FF
+	msr	S3_6_c15_c8_1,x0
+	ldr	x0,=0x4
+	msr	S3_6_c15_c8_0,x0
+	ldr	x0,=0xBF200000
+	msr	S3_6_c15_c8_2,x0
+	ldr	x0,=0xFFEF0000
+	msr	S3_6_c15_c8_3,x0
+	ldr	x0,=0x10002001003F3
+	msr	S3_6_c15_c8_1,x0
+	isb
+1:
+	ret	x17
+endfunc errata_n2_2138956_wa
+
+func check_errata_2138956
+	/* Applies to r0p0 */
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_2138956
+
+	/* -------------------------------------------
 	 * The CPU Ops reset function for Neoverse N2.
-	 * -------------------------------------------------
+	 * -------------------------------------------
 	 */
 func neoverse_n2_reset_func
+	mov	x19, x30
+
 	/* Check if the PE implements SSBS */
 	mrs	x0, id_aa64pfr1_el1
 	tst	x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT)
@@ -37,6 +203,27 @@
 	orr	x0, x0, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_2
 	msr	NEOVERSE_N2_CPUACTLR2_EL1, x0
 
+#if ERRATA_N2_2067956
+	mov	x0, x18
+	bl	errata_n2_2067956_wa
+#endif
+
+#if ERRATA_N2_2025414
+	mov     x0, x18
+	bl      errata_n2_2025414_wa
+#endif
+
+#if ERRATA_N2_2189731
+	mov     x0, x18
+	bl      errata_n2_2189731_wa
+#endif
+
+
+#if ERRATA_N2_2138956
+	mov	x0, x18
+	bl	errata_n2_2138956_wa
+#endif
+
 #if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, cptr_el3
@@ -53,20 +240,28 @@
 
 #if NEOVERSE_Nx_EXTERNAL_LLC
 	/* Some systems may have External LLC, core needs to be made aware */
-	mrs     x0, NEOVERSE_N2_CPUECTLR_EL1
-	orr     x0, x0, NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT
-	msr     NEOVERSE_N2_CPUECTLR_EL1, x0
+	mrs	x0, NEOVERSE_N2_CPUECTLR_EL1
+	orr	x0, x0, NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT
+	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
 #endif
 
 	isb
-	ret
+	ret	x19
 endfunc neoverse_n2_reset_func
 
 func neoverse_n2_core_pwr_dwn
-	/* ---------------------------------------------
+	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * No need to do cache maintenance here.
-	 * ---------------------------------------------
+	 * ---------------------------------------------------
 	 */
 	mrs	x0, NEOVERSE_N2_CPUPWRCTLR_EL1
 	orr	x0, x0, #NEOVERSE_N2_CORE_PWRDN_EN_BIT
@@ -80,7 +275,22 @@
  * Errata printing function for Neoverse N2 cores. Must follow AAPCS.
  */
 func neoverse_n2_errata_report
-	/* No errata reported for Neoverse N2 cores */
+	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 ERRATA_N2_2002655, neoverse_n2, 2002655
+	report_errata ERRATA_N2_2067956, neoverse_n2, 2067956
+	report_errata ERRATA_N2_2025414, neoverse_n2, 2025414
+        report_errata ERRATA_N2_2189731, neoverse_n2, 2189731
+	report_errata ERRATA_N2_2138956, neoverse_n2, 2138956
+
+	ldp	x8, x30, [sp], #16
 	ret
 endfunc neoverse_n2_errata_report
 #endif
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 050a56e..6103a5a 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1,6 +1,6 @@
 #
 # Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+# Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -311,10 +311,22 @@
 # well but there is no workaround for that revision.
 ERRATA_A78_1951500	?=0
 
+# Flag to apply erratum 1941500 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
+ERRATA_A78_AE_1941500	?=0
+
+# Flag to apply erratum 1951502 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
+ERRATA_A78_AE_1951502	?=0
+
 # Flag to apply erratum 1821534 workaround during reset. This erratum applies
 # to revisions r0p0 and r1p0 of the A78 cpu.
 ERRATA_A78_1821534	?=0
 
+# Flag to apply erratum 1952683 workaround during reset. This erratum applies
+# to revision r0p0 of the A78 cpu and was fixed in the revision r1p0.
+ERRATA_A78_1952683	?=0
+
 # Flag to apply T32 CLREX workaround during reset. This erratum applies
 # only to r0p0 and r1p0 of the Neoverse N1 cpu.
 ERRATA_N1_1043202	?=0
@@ -372,6 +384,10 @@
 # exists in revisions r0p0, r1p0, and r2p0 as well but there is no workaround.
 ERRATA_N1_1946160	?=0
 
+# Flag to apply erratum 2002655 workaround during reset. This erratum applies
+# to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
+ERRATA_N2_2002655	?=0
+
 # Flag to apply erratum 1774420 workaround during reset.  This erratum applies
 # to revisions r0p0 and r1p0 of the Neoverse V1 core, and was fixed in r1p1.
 ERRATA_V1_1774420	?=0
@@ -401,6 +417,38 @@
 # to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
 ERRATA_V1_2139242   ?=0
 
+# Flag to apply erratum 1987031 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
+ERRATA_A710_1987031	?=0
+
+# Flag to apply erratum 2081180 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
+ERRATA_A710_2081180	?=0
+
+# Flag to apply erratum 2067956 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2067956	?=0
+
+# Flag to apply erratum 2025414 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2025414	?=0
+
+# Flag to apply erratum 2189731 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2189731	?=0
+
+# Flag to apply erratum 2138956 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu and is still open.
+ERRATA_N2_2138956	?=0
+
+# Flag to apply erratum 2055002 workaround during reset. This erratum applies
+# to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open.
+ERRATA_A710_2055002	?=0
+
+# Flag to apply erratum 2017096 workaround during reset. This erratum applies
+# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
+ERRATA_A710_2017096	?=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
@@ -646,10 +694,22 @@
 $(eval $(call assert_boolean,ERRATA_A78_1951500))
 $(eval $(call add_define,ERRATA_A78_1951500))
 
+# Process ERRATA_A78_AE_1941500 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
+$(eval $(call add_define,ERRATA_A78_AE_1941500))
+
+# Process ERRATA_A78_AE_1951502 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_1951502))
+$(eval $(call add_define,ERRATA_A78_AE_1951502))
+
 # Process ERRATA_A78_1821534 flag
 $(eval $(call assert_boolean,ERRATA_A78_1821534))
 $(eval $(call add_define,ERRATA_A78_1821534))
 
+# Process ERRATA_A78_1952683 flag
+$(eval $(call assert_boolean,ERRATA_A78_1952683))
+$(eval $(call add_define,ERRATA_A78_1952683))
+
 # Process ERRATA_N1_1043202 flag
 $(eval $(call assert_boolean,ERRATA_N1_1043202))
 $(eval $(call add_define,ERRATA_N1_1043202))
@@ -706,6 +766,10 @@
 $(eval $(call assert_boolean,ERRATA_N1_1946160))
 $(eval $(call add_define,ERRATA_N1_1946160))
 
+# Process ERRATA_N2_2002655 flag
+$(eval $(call assert_boolean,ERRATA_N2_2002655))
+$(eval $(call add_define,ERRATA_N2_2002655))
+
 # Process ERRATA_V1_1774420 flag
 $(eval $(call assert_boolean,ERRATA_V1_1774420))
 $(eval $(call add_define,ERRATA_V1_1774420))
@@ -734,6 +798,38 @@
 $(eval $(call assert_boolean,ERRATA_V1_2139242))
 $(eval $(call add_define,ERRATA_V1_2139242))
 
+# Process ERRATA_A710_1987031 flag
+$(eval $(call assert_boolean,ERRATA_A710_1987031))
+$(eval $(call add_define,ERRATA_A710_1987031))
+
+# Process ERRATA_A710_2081180 flag
+$(eval $(call assert_boolean,ERRATA_A710_2081180))
+$(eval $(call add_define,ERRATA_A710_2081180))
+
+# Process ERRATA_N2_2067956 flag
+$(eval $(call assert_boolean,ERRATA_N2_2067956))
+$(eval $(call add_define,ERRATA_N2_2067956))
+
+# Process ERRATA_N2_2025414 flag
+$(eval $(call assert_boolean,ERRATA_N2_2025414))
+$(eval $(call add_define,ERRATA_N2_2025414))
+
+# Process ERRATA_N2_2189731 flag
+$(eval $(call assert_boolean,ERRATA_N2_2189731))
+$(eval $(call add_define,ERRATA_N2_2189731))
+
+# Process ERRATA_N2_2138956 flag
+$(eval $(call assert_boolean,ERRATA_N2_2138956))
+$(eval $(call add_define,ERRATA_N2_2138956))
+
+# Process ERRATA_A710_2055002 flag
+$(eval $(call assert_boolean,ERRATA_A710_2055002))
+$(eval $(call add_define,ERRATA_A710_2055002))
+
+# Process ERRATA_A710_2017096 flag
+$(eval $(call assert_boolean,ERRATA_A710_2017096))
+$(eval $(call add_define,ERRATA_A710_2017096))
+
 # Process ERRATA_DSU_798953 flag
 $(eval $(call assert_boolean,ERRATA_DSU_798953))
 $(eval $(call add_define,ERRATA_DSU_798953))
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index 56a2ad6..49951e0 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -25,7 +25,8 @@
 
 #else	/* !SUNXI_BL31_IN_DRAM */
 
-#define BL31_BASE			(SUNXI_SRAM_A2_BASE + 0x4000)
+#define BL31_BASE			(SUNXI_SRAM_A2_BASE + \
+					 SUNXI_SRAM_A2_BL31_OFFSET)
 #define BL31_LIMIT			(SUNXI_SRAM_A2_BASE + \
 					 SUNXI_SRAM_A2_SIZE - SUNXI_SCP_SIZE)
 
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index f036816..ec50887 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -18,5 +18,6 @@
 #define SUNXI_SOC_H5			0x1718
 #define SUNXI_SOC_H6			0x1728
 #define SUNXI_SOC_H616			0x1823
+#define SUNXI_SOC_R329			0x1851
 
 #endif /* SUNXI_DEF_H */
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 72bfbd9..14049e8 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -128,6 +128,9 @@
 	case SUNXI_SOC_H616:
 		soc_name = "H616";
 		break;
+	case SUNXI_SOC_R329:
+		soc_name = "R329";
+		break;
 	default:
 		soc_name = "unknown";
 		break;
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index 420b507..46e7090 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -42,6 +42,7 @@
 	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xe0);
 	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x80);
 	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x00);
+	udelay(1);
 }
 
 /* We can't turn ourself off like this, but it works for other cores. */
@@ -75,7 +76,8 @@
 	/* Assert CPU power-on reset */
 	mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
 	/* Set CPU to start in AArch64 mode */
-	mmio_setbits_32(SUNXI_CPUCFG_CLS_CTRL_REG0(cluster), BIT(24 + core));
+	mmio_setbits_32(SUNXI_AA64nAA32_REG(cluster),
+			BIT(SUNXI_AA64nAA32_OFFSET + core));
 	/* Apply power to the CPU */
 	sunxi_cpu_enable_power(cluster, core);
 	/* Release the core output clamps */
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
index c3eeadb..aed3585 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
@@ -33,4 +33,7 @@
 #define SUNXI_R_CPUCFG_SS_ENTRY_REG	(SUNXI_R_CPUCFG_BASE + 0x01a8)
 #define SUNXI_R_CPUCFG_HP_FLAG_REG	(SUNXI_R_CPUCFG_BASE + 0x01ac)
 
+#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET		24
+
 #endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
index 6c847d3..6d10921 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
@@ -15,6 +15,7 @@
 #define SUNXI_SRAM_A1_BASE		0x00010000
 #define SUNXI_SRAM_A1_SIZE		0x00008000
 #define SUNXI_SRAM_A2_BASE		0x00040000
+#define SUNXI_SRAM_A2_BL31_OFFSET	0x00004000
 #define SUNXI_SRAM_A2_SIZE		0x00014000
 #define SUNXI_SRAM_C_BASE		0x00018000
 #define SUNXI_SRAM_C_SIZE		0x0001c000
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
index a2b94af..5bfda5d 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_cpucfg.h
@@ -29,4 +29,7 @@
 #define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
 #define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
 
+#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET		24
+
 #endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
index 2d7b098..58216d8 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
@@ -15,6 +15,7 @@
 #define SUNXI_SRAM_A1_BASE		0x00020000
 #define SUNXI_SRAM_A1_SIZE		0x00008000
 #define SUNXI_SRAM_A2_BASE		0x00100000
+#define SUNXI_SRAM_A2_BL31_OFFSET	0x00004000
 #define SUNXI_SRAM_A2_SIZE		0x00018000
 #define SUNXI_SRAM_C_BASE		0x00028000
 #define SUNXI_SRAM_C_SIZE		0x0001e000
diff --git a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
index a637554..dab663b 100644
--- a/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
+++ b/plat/allwinner/sun50i_h616/include/sunxi_cpucfg.h
@@ -29,4 +29,7 @@
 #define SUNXI_PWR_SW_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0140)
 #define SUNXI_CONFIG_DELAY_REG		(SUNXI_R_CPUCFG_BASE + 0x0144)
 
+#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_CLS_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET		24
+
 #endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_ccu.h b/plat/allwinner/sun50i_r329/include/sunxi_ccu.h
new file mode 100644
index 0000000..0e6b543
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/include/sunxi_ccu.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CCU_H
+#define SUNXI_CCU_H
+
+#define SUNXI_CCU_SEC_SWITCH_REG	(SUNXI_CCU_BASE + 0x0f00)
+
+#define SUNXI_R_PRCM_SEC_SWITCH_REG	(SUNXI_R_PRCM_BASE + 0x0290)
+
+#endif /* SUNXI_CCU_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
new file mode 100644
index 0000000..9478f32
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/include/sunxi_cpucfg.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_CPUCFG_H
+#define SUNXI_CPUCFG_H
+
+#include <sunxi_mmap.h>
+
+/* c = cluster, n = core */
+#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0010)
+#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0014)
+#define SUNXI_CPUCFG_CACHE_CFG_REG	(SUNXI_C0_CPUXCFG_BASE + 0x0024)
+#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_C0_CPUXCFG_BASE + 0x00c0)
+
+#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_C0_CPUXCFG_BASE + 0x0000)
+#define SUNXI_CPUCFG_GEN_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0000)
+#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x0040 + (n) * 8)
+#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x0044 + (n) * 8)
+
+#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0040 + (c) * 4)
+#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0044 + (c) * 4)
+#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_CPUCFG_BASE + 0x0050 + \
+					(c) * 0x10 + (n) * 4)
+
+#define SUNXI_AA64nAA32_REG		SUNXI_CPUCFG_GEN_CTRL_REG0
+#define SUNXI_AA64nAA32_OFFSET		4
+
+#endif /* SUNXI_CPUCFG_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_mmap.h b/plat/allwinner/sun50i_r329/include/sunxi_mmap.h
new file mode 100644
index 0000000..a4469b5
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/include/sunxi_mmap.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_MMAP_H
+#define SUNXI_MMAP_H
+
+/* Memory regions */
+#define SUNXI_ROM_BASE			0x00000000
+#define SUNXI_ROM_SIZE			0x00010000
+/*
+ * In fact all SRAM from 0x100000 is SRAM A2. However as it's too big for
+ * firmware, and the user manual gives a tip on a 2*64K/27*64K partition,
+ * only use the first 2*64K for firmwares now, with the SPL using the first
+ * 64K and BL3-1 using the second one.
+ *
+ * Only the used 2*64K SRAM is defined here, to prevent a gaint translation
+ * table to be generated.
+ */
+#define SUNXI_SRAM_BASE			0x00100000
+#define SUNXI_SRAM_SIZE			0x00020000
+#define SUNXI_SRAM_A1_BASE		0x00100000
+#define SUNXI_SRAM_A1_SIZE		0x00010000
+#define SUNXI_SRAM_A2_BASE		0x00110000
+#define SUNXI_SRAM_A2_BL31_OFFSET	0x00000000
+#define SUNXI_SRAM_A2_SIZE		0x00010000
+#define SUNXI_DEV_BASE			0x01000000
+#define SUNXI_DEV_SIZE			0x09000000
+#define SUNXI_DRAM_BASE			0x40000000
+#define SUNXI_DRAM_VIRT_BASE		0x0a000000
+
+/* Memory-mapped devices */
+#define SUNXI_WDOG_BASE			0x020000a0
+#define SUNXI_R_WDOG_BASE		SUNXI_WDOG_BASE
+#define SUNXI_PIO_BASE			0x02000400
+#define SUNXI_SPC_BASE			0x02000800
+#define SUNXI_CCU_BASE			0x02001000
+#define SUNXI_UART0_BASE		0x02500000
+#define SUNXI_SYSCON_BASE		0x03000000
+#define SUNXI_DMA_BASE			0x03002000
+#define SUNXI_SID_BASE			0x03006000
+#define SUNXI_GICD_BASE			0x03021000
+#define SUNXI_GICC_BASE			0x03022000
+#define SUNXI_SPI0_BASE			0x04025000
+#define SUNXI_R_CPUCFG_BASE		0x07000400
+#define SUNXI_R_PRCM_BASE		0x07010000
+#define SUNXI_R_PIO_BASE		0x07022000
+#define SUNXI_R_UART_BASE		0x07080000
+#define SUNXI_R_I2C_BASE		0x07081400
+#define SUNXI_CPUCFG_BASE		0x08100000
+#define SUNXI_C0_CPUXCFG_BASE		0x09010000
+
+#endif /* SUNXI_MMAP_H */
diff --git a/plat/allwinner/sun50i_r329/include/sunxi_spc.h b/plat/allwinner/sun50i_r329/include/sunxi_spc.h
new file mode 100644
index 0000000..2c87bca
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/include/sunxi_spc.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_SPC_H
+#define SUNXI_SPC_H
+
+/* Get by REing stock ATF and checking initialization loop boundary */
+#define SUNXI_SPC_NUM_PORTS		11
+
+#define SUNXI_SPC_DECPORT_STA_REG(p)	(SUNXI_SPC_BASE + 0x0000 + 0x10 * (p))
+#define SUNXI_SPC_DECPORT_SET_REG(p)	(SUNXI_SPC_BASE + 0x0004 + 0x10 * (p))
+#define SUNXI_SPC_DECPORT_CLR_REG(p)	(SUNXI_SPC_BASE + 0x0008 + 0x10 * (p))
+
+#endif /* SUNXI_SPC_H */
diff --git a/plat/allwinner/sun50i_r329/platform.mk b/plat/allwinner/sun50i_r329/platform.mk
new file mode 100644
index 0000000..05d7cde
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/platform.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2021 Sipeed
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Without a management processor there is no SCPI support.
+SUNXI_PSCI_USE_SCPI	:=	0
+SUNXI_PSCI_USE_NATIVE	:=	1
+
+# The differences between the platforms are covered by the include files.
+include plat/allwinner/common/allwinner-common.mk
+
+# the above could be overwritten on the command line
+ifeq (${SUNXI_PSCI_USE_SCPI}, 1)
+    $(error "R329 does not support SCPI PSCI ops")
+endif
+
+# Put NOBITS memory in the first 64K of SRAM A2, overwriting U-Boot's SPL.
+SEPARATE_NOBITS_REGION	:=	1
diff --git a/plat/allwinner/sun50i_r329/sunxi_power.c b/plat/allwinner/sun50i_r329/sunxi_power.c
new file mode 100644
index 0000000..96a24d5
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/sunxi_power.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021 Sipeed
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <sunxi_mmap.h>
+#include <sunxi_cpucfg.h>
+#include <sunxi_private.h>
+
+int sunxi_pmic_setup(uint16_t socid, const void *fdt)
+{
+	/* Currently known hardware has no PMIC */
+
+	return 0;
+}
+
+void sunxi_power_down(void)
+{
+}
+
+void sunxi_cpu_power_off_self(void)
+{
+	/* TODO: It's still unknown whether CPUIDLE exists on R329 */
+}
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index f1fd777..f80ea2f 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -32,6 +32,8 @@
 FPGA_PRELOADED_CMD_LINE := 0x1000
 $(eval $(call add_define,FPGA_PRELOADED_CMD_LINE))
 
+ENABLE_AMU		:=	1
+
 # Treating this as a memory-constrained port for now
 USE_COHERENT_MEM	:=	0
 
diff --git a/plat/arm/board/diphda/platform.mk b/plat/arm/board/diphda/platform.mk
index 5ff0862..8b89cee 100644
--- a/plat/arm/board/diphda/platform.mk
+++ b/plat/arm/board/diphda/platform.mk
@@ -59,6 +59,13 @@
 			${DIPHDA_CPU_LIBS}					\
 			${DIPHDA_GIC_SOURCES}
 
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+	ifneq (${ENABLE_STACK_PROTECTOR},none)
+		DIPHDA_SECURITY_SOURCES := plat/arm/board/diphda/common/diphda_stack_protector.c
+		BL2_SOURCES += ${DIPHDA_SECURITY_SOURCES}
+		BL31_SOURCES += ${DIPHDA_SECURITY_SOURCES}
+	endif
+endif
 
 FDT_SOURCES		+=	plat/arm/board/diphda/common/fdts/diphda_spmc_manifest.dts
 DIPHDA_TOS_FW_CONFIG	:=	${BUILD_PLAT}/fdts/diphda_spmc_manifest.dtb
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 62ab27c..08d3c32 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -4,6 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <lib/libc/cdefs.h>
+
 /dts-v1/;
 
 / {
@@ -74,6 +76,10 @@
 
 	secure-partitions {
 		compatible = "arm,sp";
+
+#ifdef ARM_BL2_SP_LIST_DTS
+	#include __XSTRING(ARM_BL2_SP_LIST_DTS)
+#else
 #ifdef OPTEE_SP_FW_CONFIG
 		op-tee {
 			uuid = "486178e0-e7f8-11e3-bc5e-0002a5d5c51b";
@@ -104,6 +110,7 @@
 			owner = "Plat";
 		};
 #endif
+#endif /* ARM_BL2_SP_LIST_DTS */
 	};
 
 #if COT_DESC_IN_DTB
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 10258ad..3c70eed 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -135,6 +135,7 @@
 					lib/cpus/aarch64/cortex_a710.S	\
 					lib/cpus/aarch64/cortex_makalu.S	\
 					lib/cpus/aarch64/cortex_makalu_elp_arm.S \
+					lib/cpus/aarch64/cortex_demeter.S	\
 					lib/cpus/aarch64/cortex_a65.S		\
 					lib/cpus/aarch64/cortex_a65ae.S		\
 					lib/cpus/aarch64/cortex_a78c.S
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index 30a0c5c..194814f 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -44,6 +44,8 @@
 #define TZC_NSAID_ALL_AP		U(0)
 #define TZC_NSAID_PCI			U(1)
 #define TZC_NSAID_HDLCD0		U(2)
+#define TZC_NSAID_DMA			U(5)
+#define TZC_NSAID_DMA2			U(8)
 #define TZC_NSAID_CLCD			U(7)
 #define TZC_NSAID_AP			U(9)
 #define TZC_NSAID_VIRTIO		U(15)
@@ -52,6 +54,8 @@
 		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
 		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
 		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI))    | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA))    | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA2))   | \
 		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP))     | \
 		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD))   | \
 		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
diff --git a/plat/arm/board/tc/fdts/tc_fw_config.dts b/plat/arm/board/tc/fdts/tc_fw_config.dts
index 4b6abd4..a84c7f8 100644
--- a/plat/arm/board/tc/fdts/tc_fw_config.dts
+++ b/plat/arm/board/tc/fdts/tc_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,7 +26,7 @@
 
 		hw-config {
 			load-address = <0x0 0x83000000>;
-			max-size = <0x01000000>;
+			max-size = <0x8000>;
 			id = <HW_CONFIG_ID>;
 		};
 	};
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index c8edd2f..ccabced 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -55,6 +55,14 @@
 						TC_TZC_DRAM1_BASE,	\
 						TC_TZC_DRAM1_SIZE,	\
 						MT_MEMORY | MT_RW | MT_SECURE)
+
+#define PLAT_HW_CONFIG_DTB_BASE	ULL(0x83000000)
+#define PLAT_HW_CONFIG_DTB_SIZE	ULL(0x8000)
+
+#define PLAT_DTB_DRAM_NS MAP_REGION_FLAT(	\
+					PLAT_HW_CONFIG_DTB_BASE,	\
+					PLAT_HW_CONFIG_DTB_SIZE,	\
+					MT_MEMORY | MT_RO | MT_NS)
 /*
  * Max size of SPMC is 2MB for tc. With SPMD enabled this value corresponds to
  * max size of BL32 image.
@@ -122,7 +130,7 @@
  * calculated using the current BL31 PROGBITS debug size plus the sizes of
  * BL2 and BL1-RW
  */
-#define PLAT_ARM_MAX_BL31_SIZE		0x3B000
+#define PLAT_ARM_MAX_BL31_SIZE		0x3F000
 
 /*
  * Size of cacheable stacks
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 8db764c..7ebf639 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -31,6 +31,9 @@
 # GIC-600 configuration
 GICV3_SUPPORT_GIC600	:=	1
 
+# Enable SVE
+ENABLE_SVE_FOR_NS	:=	1
+ENABLE_SVE_FOR_SWD	:=	1
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
@@ -77,6 +80,7 @@
 BL2_SOURCES		+=	${TC_BASE}/tc_security.c	\
 				${TC_BASE}/tc_err.c		\
 				${TC_BASE}/tc_trusted_boot.c		\
+				${TC_BASE}/tc_bl2_setup.c		\
 				lib/utils/mem_region.c			\
 				drivers/arm/tzc/tzc400.c		\
 				plat/arm/common/arm_tzc400.c		\
@@ -87,6 +91,9 @@
 				${ENT_GIC_SOURCES}			\
 				${TC_BASE}/tc_bl31_setup.c	\
 				${TC_BASE}/tc_topology.c	\
+				common/fdt_wrappers.c			\
+				lib/fconf/fconf.c			\
+				lib/fconf/fconf_dyn_cfg_getter.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
diff --git a/plat/arm/board/tc/tc_bl2_setup.c b/plat/arm/board/tc/tc_bl2_setup.c
new file mode 100644
index 0000000..74ef569
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl2_setup.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2021, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+
+#include <plat/arm/common/plat_arm.h>
+
+/*******************************************************************************
+ * This function returns the list of executable images
+ ******************************************************************************/
+struct bl_params *plat_get_next_bl_params(void)
+{
+	struct bl_params *arm_bl_params = arm_get_next_bl_params();
+
+	const struct dyn_cfg_dtb_info_t *fw_config_info;
+	bl_mem_params_node_t *param_node;
+	uintptr_t fw_config_base = 0U;
+	entry_point_info_t *ep_info;
+
+	/* Get BL31 image node */
+	param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
+	assert(param_node != NULL);
+
+	/* Get fw_config load address */
+	fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
+	assert(fw_config_info != NULL);
+
+	fw_config_base = fw_config_info->config_addr;
+	assert(fw_config_base != 0U);
+
+	/*
+	 * Get the entry point info of BL31 image and override
+	 * arg1 of entry point info with fw_config base address
+	 */
+	ep_info = &param_node->ep_info;
+	ep_info->args.arg1 = (uint32_t)fw_config_base;
+
+	return arm_bl_params;
+}
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index ecec26c..0523ef8 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,8 @@
 #include <common/debug.h>
 #include <drivers/arm/css/css_mhu_doorbell.h>
 #include <drivers/arm/css/scmi.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -42,6 +44,9 @@
 				u_register_t arg2, u_register_t arg3)
 {
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+
+	/* Fill the properties struct with the info from the config dtb */
+	fconf_populate("FW_CONFIG", arg1);
 }
 
 void tc_bl31_common_platform_setup(void)
@@ -53,3 +58,16 @@
 {
 	return css_scmi_override_pm_ops(ops);
 }
+
+void __init bl31_plat_arch_setup(void)
+{
+	arm_bl31_plat_arch_setup();
+
+	/* HW_CONFIG was also loaded by BL2 */
+	const struct dyn_cfg_dtb_info_t *hw_config_info;
+
+	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+	assert(hw_config_info != NULL);
+
+	fconf_populate("HW_CONFIG", hw_config_info->config_addr);
+}
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index 3863a0a..a9668e1 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -63,6 +63,7 @@
 	ARM_MAP_SHARED_RAM,
 	V2M_MAP_IOFPGA,
 	TC_MAP_DEVICE,
+	PLAT_DTB_DRAM_NS,
 #if SPM_MM
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk
index 773b912..30e6280 100644
--- a/plat/marvell/armada/a8k/common/a8k_common.mk
+++ b/plat/marvell/armada/a8k/common/a8k_common.mk
@@ -80,7 +80,7 @@
 				drivers/arm/gic/v2/gicv2_helpers.c	\
 				plat/common/plat_gicv2.c
 
-PLAT_INCLUDES		:=	-I$(BOARD_DIR)				\
+PLAT_INCLUDES		+=	-I$(BOARD_DIR)				\
 				-I$(BOARD_DIR)/board			\
 				-I$(CURDIR)/drivers/marvell		\
 				-I$(PLAT_COMMON_BASE)/include		\
@@ -89,8 +89,10 @@
 PLAT_BL_COMMON_SOURCES	:=	$(PLAT_COMMON_BASE)/aarch64/a8k_common.c \
 				drivers/ti/uart/aarch64/16550_console.S
 
+ifndef BLE_PORTING_SOURCES
 BLE_PORTING_SOURCES	:=	$(BOARD_DIR)/board/dram_port.c \
 				$(BOARD_DIR)/board/marvell_plat_config.c
+endif
 
 MARVELL_MOCHI_DRV	+=	$(MARVELL_DRV_BASE)/mochi/cp110_setup.c
 
@@ -125,7 +127,9 @@
 MARVELL_DRV		+=	$(MARVELL_DRV_BASE)/mg_conf_cm3/mg_conf_cm3.c
 endif
 
+ifndef BL31_PORTING_SOURCES
 BL31_PORTING_SOURCES	:=	$(BOARD_DIR)/board/marvell_plat_config.c
+endif
 
 ifeq ($(SYSTEM_POWER_SUPPORT),1)
 BL31_PORTING_SOURCES	+=	$(BOARD_DIR)/board/system_power.c
diff --git a/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/board/marvell_plat_config.c b/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/board/marvell_plat_config.c
new file mode 100644
index 0000000..5bae8eb
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/board/marvell_plat_config.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ * Copyright (C) 2021 Semihalf.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <armada_common.h>
+#include <mvebu_def.h>
+
+/*
+ * If bootrom is currently at BLE there's no need to include the memory
+ * maps structure at this point
+ */
+#ifndef IMAGE_BLE
+
+/*****************************************************************************
+ * AMB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win amb_memory_map_cp0[] = {
+	/* CP0 SPI1 CS0 Direct Mode access */
+	{0xef00,	0x1000000,	AMB_SPI1_CS0_ID},
+};
+
+struct addr_map_win amb_memory_map_cp1[] = {
+	/* CP1 SPI1 CS0 Direct Mode access */
+	{0xe800,	0x1000000,	AMB_SPI1_CS0_ID},
+};
+
+int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size,
+			       uintptr_t base)
+{
+	switch (base) {
+	case MVEBU_CP_REGS_BASE(0):
+		*win = amb_memory_map_cp0;
+		*size = ARRAY_SIZE(amb_memory_map_cp0);
+		return 0;
+	case MVEBU_CP_REGS_BASE(1):
+		*win = amb_memory_map_cp1;
+		*size = ARRAY_SIZE(amb_memory_map_cp1);
+		return 0;
+	case MVEBU_CP_REGS_BASE(2):
+	default:
+		*size = 0;
+		*win = 0;
+		return 1;
+	}
+}
+#endif
+
+/*****************************************************************************
+ * IO WIN Configuration
+ *****************************************************************************
+ */
+struct addr_map_win io_win_memory_map[] = {
+#if (CP_COUNT > 1)
+	/* SB (MCi0) internal regs */
+	{0x00000000f4000000,		0x2000000,	MCI_0_TID},
+	/* SB (MCi0) PCIe0-2 on CP1 */
+	{0x00000000e2000000,		0x7000000,	MCI_0_TID},
+	/*
+	 * Due to lack of sufficient number of IO windows registers,
+	 * below CP1 PCIE configuration must be performed in the
+	 * later firmware stages. It should replace the MCI 0 indirect
+	 * window, which becomes no longer needed.
+	 */
+	/* {0x0000000890000000,		0x30000000,	MCI_0_TID}, */
+#if (CP_COUNT > 2)
+	/* SB (MCi1) internal regs */
+	{0x00000000f6000000,		0x2000000,	MCI_1_TID},
+	/* SB (MCi1) PCIe0-2 on CP2 */
+	{0x00000000e9000000,		0x6000000,	MCI_1_TID},
+	/*
+	 * Due to lack of sufficient number of IO windows registers,
+	 * below CP2 PCIE configuration must be performed in the
+	 * later firmware stages. It should replace the MCI 1 indirect
+	 * window, which becomes no longer needed.
+	 */
+	/* {0x00000008c0000000,		0x30000000,	MCI_1_TID}, */
+#endif
+#endif
+#ifndef IMAGE_BLE
+	/* MCI 0 indirect window */
+	{MVEBU_MCI_REG_BASE_REMAP(0),	0x100000,	MCI_0_TID},
+	/* MCI 1 indirect window */
+	{MVEBU_MCI_REG_BASE_REMAP(1),	0x100000,	MCI_1_TID},
+#endif
+};
+
+/* Global Control Register - window default target */
+uint32_t marvell_get_io_win_gcr_target(int ap_index)
+{
+	/*
+	 * PIDI == iMCIP AP to SB internal MoChi connection.
+	 * In other words CP0
+	 */
+	return PIDI_TID;
+}
+
+int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win,
+				  uint32_t *size)
+{
+	*win = io_win_memory_map;
+	if (*win == NULL)
+		*size = 0;
+	else
+		*size = ARRAY_SIZE(io_win_memory_map);
+
+	return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * IOB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win iob_memory_map_cp0[] = {
+	/* SPI1_CS0 (RUNIT) window */
+	{0x00000000ef000000,	0x1000000,	RUNIT_TID},
+	/* PEX2_X1 window */
+	{0x00000000e1000000,	0x1000000,	PEX2_TID},
+	/* PEX1_X1 window */
+	{0x00000000e0000000,	0x1000000,	PEX1_TID},
+	/* PEX0_X4 window */
+	{0x00000000c0000000,	0x20000000,	PEX0_TID},
+	{0x0000000800000000,	0x90000000,	PEX0_TID},
+};
+
+struct addr_map_win iob_memory_map_cp1[] = {
+	/* SPI1_CS0 (RUNIT) window */
+	{0x00000000e8000000,	0x1000000,	RUNIT_TID},
+	/* PEX2_X1 window */
+	{0x00000000e6000000,	0x2000000,	PEX2_TID},
+	{0x00000008b0000000,	0x10000000,	PEX2_TID},
+	/* PEX1_X1 window */
+	{0x00000000e4000000,	0x2000000,	PEX1_TID},
+	{0x00000008a0000000,	0x10000000,	PEX1_TID},
+	/* PEX0_X2 window */
+	{0x00000000e2000000,	0x2000000,	PEX0_TID},
+	{0x0000000890000000,	0x10000000,	PEX0_TID},
+};
+
+struct addr_map_win iob_memory_map_cp2[] = {
+
+	/* PEX2_X1 window */
+	{0x00000000ed000000,	0x2000000,	PEX2_TID},
+	{0x00000008e0000000,	0x10000000,	PEX2_TID},
+	/* PEX1_X1 window */
+	{0x00000000eb000000,	0x2000000,	PEX1_TID},
+	{0x00000008d0000000,	0x10000000,	PEX1_TID},
+	/* PEX0_X1 window */
+	{0x00000000e9000000,	0x2000000,	PEX0_TID},
+	{0x00000008c0000000,	0x10000000,	PEX0_TID},
+};
+
+int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size,
+			       uintptr_t base)
+{
+	switch (base) {
+	case MVEBU_CP_REGS_BASE(0):
+		*win = iob_memory_map_cp0;
+		*size = ARRAY_SIZE(iob_memory_map_cp0);
+		return 0;
+	case MVEBU_CP_REGS_BASE(1):
+		*win = iob_memory_map_cp1;
+		*size = ARRAY_SIZE(iob_memory_map_cp1);
+		return 0;
+	case MVEBU_CP_REGS_BASE(2):
+		*win = iob_memory_map_cp2;
+		*size = ARRAY_SIZE(iob_memory_map_cp2);
+		return 0;
+	default:
+		*size = 0;
+		*win = 0;
+		return 1;
+	}
+}
+#endif
+
+/*****************************************************************************
+ * CCU Configuration
+ *****************************************************************************
+ */
+struct addr_map_win ccu_memory_map[] = {	/* IO window */
+#ifdef IMAGE_BLE
+	{0x00000000f2000000,	0x6000000,	IO_0_TID}, /* IO window */
+#else
+#if LLC_SRAM
+	{PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID},
+#endif
+	{0x00000000f2000000,	0xe000000,	IO_0_TID}, /* IO window */
+	{0x00000000c0000000,	0x30000000,	IO_0_TID}, /* IO window */
+	{0x0000000800000000,	0x100000000,    IO_0_TID}, /* IO window */
+	{0x0000002000000000,	0x70e000000,	IO_0_TID}, /* IO for CV-OS */
+#endif
+};
+
+uint32_t marvell_get_ccu_gcr_target(int ap)
+{
+	return DRAM_0_TID;
+}
+
+int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win,
+			       uint32_t *size)
+{
+	*win = ccu_memory_map;
+	*size = ARRAY_SIZE(ccu_memory_map);
+
+	return 0;
+}
+
+#ifdef IMAGE_BLE
+/*****************************************************************************
+ * SKIP IMAGE Configuration
+ *****************************************************************************
+ */
+void *plat_get_skip_image_data(void)
+{
+	/* No recovery button on CN-9130 board? */
+	return NULL;
+}
+#endif
diff --git a/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/platform.mk b/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/platform.mk
new file mode 100644
index 0000000..ee55455
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/platform.mk
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+# Copyright (C) 2021 Semihalf.
+#
+# SPDX-License-Identifier:	BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PCI_EP_SUPPORT		:=	0
+
+CP_NUM			:=	1
+$(eval $(call add_define,CP_NUM))
+
+DOIMAGE_SEC     	:=	tools/doimage/secure/sec_img_7K.cfg
+
+MARVELL_MOCHI_DRV	:=	drivers/marvell/mochi/ap807_setup.c
+
+BOARD_DIR		:=	$(shell dirname $(lastword $(MAKEFILE_LIST)))
+
+#
+# CN913X CEx7 Evaluation Board shares the DRAM connectivity
+# and SerDes settings with the CN913X DB - reuse relevant
+# board-specific files.
+#
+T9130_DIR		:=	$(BOARD_DIR)/../t9130
+PLAT_INCLUDES		:=	-I$(T9130_DIR)				\
+				-I$(T9130_DIR)/board
+BLE_PORTING_SOURCES	:=	$(T9130_DIR)/board/dram_port.c		\
+				$(BOARD_DIR)/board/marvell_plat_config.c
+
+include plat/marvell/armada/a8k/common/a8k_common.mk
+
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index 3894b74..f3aa3ea 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -82,13 +82,6 @@
 	return (tegra_get_chipid() >> PRE_SI_PLATFORM_SHIFT) & PRE_SI_PLATFORM_MASK;
 }
 
-bool tegra_chipid_is_t132(void)
-{
-	uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
-
-	return (chip_id == TEGRA_CHIPID_TEGRA13);
-}
-
 bool tegra_chipid_is_t186(void)
 {
 	uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
deleted file mode 100644
index 6b87655..0000000
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TEGRA_DEF_H
-#define TEGRA_DEF_H
-
-#include <lib/utils_def.h>
-
-/*******************************************************************************
- * Platform BL31 specific defines.
- ******************************************************************************/
-#define BL31_SIZE			U(0x40000)
-
-/*******************************************************************************
- * This value is used by the PSCI implementation during the `SYSTEM_SUSPEND`
- * call as the `state-id` field in the 'power state' parameter.
- ******************************************************************************/
-#define PSTATE_ID_SOC_POWERDN	U(0xD)
-
-/*******************************************************************************
- * Platform power states (used by PSCI framework)
- *
- * - PLAT_MAX_RET_STATE should be less than lowest PSTATE_ID
- * - PLAT_MAX_OFF_STATE should be greater than the highest PSTATE_ID
- ******************************************************************************/
-#define PLAT_MAX_RET_STATE		U(1)
-#define PLAT_MAX_OFF_STATE		(PSTATE_ID_SOC_POWERDN + U(1))
-
-/*******************************************************************************
- * Chip specific page table and MMU setup constants
- ******************************************************************************/
-#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 35)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 35)
-
-/*******************************************************************************
- * GIC memory map
- ******************************************************************************/
-#define TEGRA_GICD_BASE			U(0x50041000)
-#define TEGRA_GICC_BASE			U(0x50042000)
-
-/*******************************************************************************
- * Tegra micro-seconds timer constants
- ******************************************************************************/
-#define TEGRA_TMRUS_BASE		U(0x60005010)
-#define TEGRA_TMRUS_SIZE		U(0x1000)
-
-/*******************************************************************************
- * Tegra Clock and Reset Controller constants
- ******************************************************************************/
-#define TEGRA_CAR_RESET_BASE		U(0x60006000)
-#define TEGRA_GPU_RESET_REG_OFFSET	U(0x28C)
-#define TEGRA_GPU_RESET_GPU_SET_OFFSET	U(0x290)
-#define  GPU_RESET_BIT			(U(1) << 24)
-#define  GPU_SET_BIT			(U(1) << 24)
-
-/*******************************************************************************
- * Tegra Flow Controller constants
- ******************************************************************************/
-#define TEGRA_FLOWCTRL_BASE		U(0x60007000)
-
-/*******************************************************************************
- * Tegra Secure Boot Controller constants
- ******************************************************************************/
-#define TEGRA_SB_BASE			U(0x6000C200)
-
-/*******************************************************************************
- * Tegra Exception Vectors constants
- ******************************************************************************/
-#define TEGRA_EVP_BASE			U(0x6000F000)
-
-/*******************************************************************************
- * Tegra Miscellaneous register constants
- ******************************************************************************/
-#define TEGRA_MISC_BASE			U(0x70000000)
-#define  HARDWARE_REVISION_OFFSET	U(0x804)
-
-/*******************************************************************************
- * Tegra UART controller base addresses
- ******************************************************************************/
-#define TEGRA_UARTA_BASE		U(0x70006000)
-#define TEGRA_UARTB_BASE		U(0x70006040)
-#define TEGRA_UARTC_BASE		U(0x70006200)
-#define TEGRA_UARTD_BASE		U(0x70006300)
-#define TEGRA_UARTE_BASE		U(0x70006400)
-
-/*******************************************************************************
- * Tegra Power Mgmt Controller constants
- ******************************************************************************/
-#define TEGRA_PMC_BASE			U(0x7000E400)
-
-/*******************************************************************************
- * Tegra Memory Controller constants
- ******************************************************************************/
-#define TEGRA_MC_BASE			U(0x70019000)
-
-/* Memory Controller Interrupt Status */
-#define MC_INTSTATUS			0x00U
-
-/* TZDRAM carveout configuration registers */
-#define MC_SECURITY_CFG0_0		U(0x70)
-#define MC_SECURITY_CFG1_0		U(0x74)
-#define MC_SECURITY_CFG3_0		U(0x9BC)
-
-/* Video Memory carveout configuration registers */
-#define MC_VIDEO_PROTECT_BASE_HI	U(0x978)
-#define MC_VIDEO_PROTECT_BASE_LO	U(0x648)
-#define MC_VIDEO_PROTECT_SIZE_MB	U(0x64c)
-#define MC_VIDEO_PROTECT_REG_CTRL	U(0x650)
-#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED	U(3)
-
-/*******************************************************************************
- * Tegra TZRAM constants
- ******************************************************************************/
-#define TEGRA_TZRAM_BASE		U(0x7C010000)
-#define TEGRA_TZRAM_SIZE		U(0x10000)
-
-/*******************************************************************************
- * Tegra DRAM memory base address
- ******************************************************************************/
-#define TEGRA_DRAM_BASE			ULL(0x80000000)
-#define TEGRA_DRAM_END			ULL(0x27FFFFFFF)
-
-#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h
index b8297fd..ab51dfe 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -49,7 +49,6 @@
 /*
  * Tegra chip ID identifiers
  */
-bool tegra_chipid_is_t132(void);
 bool tegra_chipid_is_t186(void);
 bool tegra_chipid_is_t210(void);
 bool tegra_chipid_is_t210_b01(void);
diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
deleted file mode 100644
index 0e2edf0..0000000
--- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <platform_def.h>
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <drivers/delay_timer.h>
-#include <denver.h>
-#include <lib/mmio.h>
-#include <lib/psci/psci.h>
-
-#include <flowctrl.h>
-#include <pmc.h>
-#include <tegra_def.h>
-#include <tegra_private.h>
-
-/*
- * Register used to clear CPU reset signals. Each CPU has two reset
- * signals: CPU reset (3:0) and Core reset (19:16)
- */
-#define CPU_CMPLX_RESET_CLR		0x344
-#define CPU_CORE_RESET_MASK		0x10001
-
-/* Clock and Reset controller registers for system clock's settings */
-#define SCLK_RATE			0x30
-#define SCLK_BURST_POLICY		0x28
-#define SCLK_BURST_POLICY_DEFAULT	0x10000000
-
-static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER];
-
-plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
-					     const plat_local_state_t *states,
-					     uint32_t ncpu)
-{
-	plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
-	uint32_t num_cpu = ncpu;
-	const plat_local_state_t *local_state = states;
-
-	(void)lvl;
-
-	assert(ncpu != 0U);
-
-	do {
-		temp = *local_state;
-		if ((temp < target)) {
-			target = temp;
-		}
-		--num_cpu;
-		local_state++;
-	} while (num_cpu != 0U);
-
-	return target;
-}
-
-int32_t tegra_soc_validate_power_state(unsigned int power_state,
-					psci_power_state_t *req_state)
-{
-	int state_id = psci_get_pstate_id(power_state);
-	int cpu = read_mpidr() & MPIDR_CPU_MASK;
-
-	/*
-	 * Sanity check the requested state id, power level and CPU number.
-	 * Currently T132 only supports SYSTEM_SUSPEND on last standing CPU
-	 * i.e. CPU 0
-	 */
-	if ((state_id != PSTATE_ID_SOC_POWERDN) || (cpu != 0)) {
-		ERROR("unsupported state id @ power level\n");
-		return PSCI_E_INVALID_PARAMS;
-	}
-
-	/* Set lower power states to PLAT_MAX_OFF_STATE */
-	for (uint32_t i = MPIDR_AFFLVL0; i < PLAT_MAX_PWR_LVL; i++)
-		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
-
-	/* Set the SYSTEM_SUSPEND state-id */
-	req_state->pwr_domain_state[PLAT_MAX_PWR_LVL] =
-		PSTATE_ID_SOC_POWERDN;
-
-	return PSCI_E_SUCCESS;
-}
-
-int tegra_soc_pwr_domain_on(u_register_t mpidr)
-{
-	int cpu = mpidr & MPIDR_CPU_MASK;
-	uint32_t mask = CPU_CORE_RESET_MASK << cpu;
-
-	if (cpu_powergate_mask[cpu] == 0) {
-
-		/* Deassert CPU reset signals */
-		mmio_write_32(TEGRA_CAR_RESET_BASE + CPU_CMPLX_RESET_CLR, mask);
-
-		/* Power on CPU using PMC */
-		tegra_pmc_cpu_on(cpu);
-
-		/* Fill in the CPU powergate mask */
-		cpu_powergate_mask[cpu] = 1;
-
-	} else {
-		/* Power on CPU using Flow Controller */
-		tegra_fc_cpu_on(cpu);
-	}
-
-	return PSCI_E_SUCCESS;
-}
-
-int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
-{
-	/*
-	 * Lock scratch registers which hold the CPU vectors
-	 */
-	tegra_pmc_lock_cpu_vectors();
-
-	return PSCI_E_SUCCESS;
-}
-
-int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
-{
-	uint64_t val;
-
-	tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
-
-	/* Disable DCO operations */
-	denver_disable_dco();
-
-	/* Power down the CPU */
-	val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
-	write_actlr_el1(val | DENVER_CPU_STATE_POWER_DOWN);
-
-	return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
-{
-	(void)cpu_state;
-	return PSCI_E_SUCCESS;
-}
-
-int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
-{
-	uint64_t val;
-
-#if ENABLE_ASSERTIONS
-	int cpu = read_mpidr() & MPIDR_CPU_MASK;
-
-	/* SYSTEM_SUSPEND only on CPU0 */
-	assert(cpu == 0);
-#endif
-
-	/* Allow restarting CPU #1 using PMC on suspend exit */
-	cpu_powergate_mask[1] = 0;
-
-	/* Program FC to enter suspend state */
-	tegra_fc_cpu_powerdn(read_mpidr());
-
-	/* Disable DCO operations */
-	denver_disable_dco();
-
-	/* Program the suspend state ID */
-	val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
-	write_actlr_el1(val | target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]);
-
-	return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
-{
-	return PSCI_E_NOT_SUPPORTED;
-}
-
-int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
-{
-	return PSCI_E_SUCCESS;
-}
-
-int tegra_soc_prepare_system_reset(void)
-{
-	/*
-	 * Set System Clock (SCLK) to POR default so that the clock source
-	 * for the PMC APB clock would not be changed due to system reset.
-	 */
-	mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_BURST_POLICY,
-		       SCLK_BURST_POLICY_DEFAULT);
-	mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_RATE, 0);
-
-	/* Wait 1 ms to make sure clock source/device logic is stabilized. */
-	mdelay(1);
-
-	/*
-	 * Program the PMC in order to restart the system.
-	 */
-	tegra_pmc_system_reset();
-
-	return PSCI_E_SUCCESS;
-}
-
-__dead2 void tegra_soc_prepare_system_off(void)
-{
-	ERROR("Tegra System Off: operation not handled.\n");
-	panic();
-}
diff --git a/plat/nvidia/tegra/soc/t132/plat_secondary.c b/plat/nvidia/tegra/soc/t132/plat_secondary.c
deleted file mode 100644
index f46ad3b..0000000
--- a/plat/nvidia/tegra/soc/t132/plat_secondary.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <denver.h>
-#include <lib/mmio.h>
-#include <lib/psci/psci.h>
-#include <plat/common/platform.h>
-
-#include <pmc.h>
-#include <tegra_def.h>
-
-#define SB_CSR				0x0
-#define  SB_CSR_NS_RST_VEC_WR_DIS	(1 << 1)
-
-/* AARCH64 CPU reset vector */
-#define SB_AA64_RESET_LOW		0x30	/* width = 31:0 */
-#define SB_AA64_RESET_HI		0x34	/* width = 11:0 */
-
-/* AARCH32 CPU reset vector */
-#define EVP_CPU_RESET_VECTOR		0x100
-
-extern void tegra_secure_entrypoint(void);
-
-/*
- * For T132, CPUs reset to AARCH32, so the reset vector is first
- * armv8_trampoline which does a warm reset to AARCH64 and starts
- * execution at the address in SB_AA64_RESET_LOW/SB_AA64_RESET_HI.
- */
-__aligned(8) const uint32_t armv8_trampoline[] = {
-	0xE3A00003,		/* mov	r0, #3 */
-	0xEE0C0F50,		/* mcr	p15, 0, r0, c12, c0, 2 */
-	0xEAFFFFFE,		/* b	. */
-};
-
-/*******************************************************************************
- * Setup secondary CPU vectors
- ******************************************************************************/
-void plat_secondary_setup(void)
-{
-	uint32_t val;
-	uint64_t reset_addr = (uint64_t)tegra_secure_entrypoint;
-
-	/*
-	 * For T132, CPUs reset to AARCH32, so the reset vector is first
-	 * armv8_trampoline, which does a warm reset to AARCH64 and starts
-	 * execution at the address in SCRATCH34/SCRATCH35.
-	 */
-	INFO("Setting up T132 CPU boot\n");
-
-	/* initial AARCH32 reset address */
-	tegra_pmc_write_32(PMC_SECURE_SCRATCH22,
-		(unsigned long)&armv8_trampoline);
-
-	/* set AARCH32 exception vector (read to flush) */
-	mmio_write_32(TEGRA_EVP_BASE + EVP_CPU_RESET_VECTOR,
-		(unsigned long)&armv8_trampoline);
-	val = mmio_read_32(TEGRA_EVP_BASE + EVP_CPU_RESET_VECTOR);
-
-	/* setup secondary CPU vector */
-	mmio_write_32(TEGRA_SB_BASE + SB_AA64_RESET_LOW,
-			(reset_addr & 0xFFFFFFFF) | 1);
-	val = reset_addr >> 32;
-	mmio_write_32(TEGRA_SB_BASE + SB_AA64_RESET_HI, val & 0x7FF);
-
-	/* configure PMC */
-	tegra_pmc_cpu_setup(reset_addr);
-	tegra_pmc_lock_cpu_vectors();
-}
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
deleted file mode 100644
index 49e8b5d..0000000
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <assert.h>
-#include <common/bl_common.h>
-#include <drivers/console.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <memctrl.h>
-#include <plat/common/platform.h>
-#include <tegra_def.h>
-#include <tegra_platform.h>
-#include <tegra_private.h>
-
-/* sets of MMIO ranges setup */
-#define MMIO_RANGE_0_ADDR	0x50000000
-#define MMIO_RANGE_1_ADDR	0x60000000
-#define MMIO_RANGE_2_ADDR	0x70000000
-#define MMIO_RANGE_SIZE		0x200000
-
-/*
- * Table of regions to map using the MMU.
- */
-static const mmap_region_t tegra_mmap[] = {
-	MAP_REGION_FLAT(MMIO_RANGE_0_ADDR, MMIO_RANGE_SIZE,
-			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(MMIO_RANGE_1_ADDR, MMIO_RANGE_SIZE,
-			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(MMIO_RANGE_2_ADDR, MMIO_RANGE_SIZE,
-			MT_DEVICE | MT_RW | MT_SECURE),
-	{0}
-};
-
-/*******************************************************************************
- * Set up the pagetables as per the platform memory map & initialize the MMU
- ******************************************************************************/
-const mmap_region_t *plat_get_mmio_map(void)
-{
-	/* MMIO space */
-	return tegra_mmap;
-}
-
-/*******************************************************************************
- * The Tegra power domain tree has a single system level power domain i.e. a
- * single root node. The first entry in the power domain descriptor specifies
- * the number of power domains at the highest power level.
- *******************************************************************************
- */
-const unsigned char tegra_power_domain_tree_desc[] = {
-	/* No of root nodes */
-	1,
-	/* No of clusters */
-	PLATFORM_CLUSTER_COUNT,
-	/* No of CPU cores */
-	PLATFORM_CORE_COUNT,
-};
-
-/*******************************************************************************
- * This function returns the Tegra default topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
-	return tegra_power_domain_tree_desc;
-}
-
-unsigned int plat_get_syscnt_freq2(void)
-{
-	return 12000000;
-}
-
-/*******************************************************************************
- * Maximum supported UART controllers
- ******************************************************************************/
-#define TEGRA132_MAX_UART_PORTS		5
-
-/*******************************************************************************
- * This variable holds the UART port base addresses
- ******************************************************************************/
-static uint32_t tegra132_uart_addresses[TEGRA132_MAX_UART_PORTS + 1] = {
-	0,	/* undefined - treated as an error case */
-	TEGRA_UARTA_BASE,
-	TEGRA_UARTB_BASE,
-	TEGRA_UARTC_BASE,
-	TEGRA_UARTD_BASE,
-	TEGRA_UARTE_BASE,
-};
-
-/*******************************************************************************
- * Enable console corresponding to the console ID
- ******************************************************************************/
-void plat_enable_console(int32_t id)
-{
-	static console_t uart_console;
-	uint32_t console_clock;
-
-	if ((id > 0) && (id < TEGRA132_MAX_UART_PORTS)) {
-		/*
-		 * Reference clock used by the FPGAs is a lot slower.
-		 */
-		if (tegra_platform_is_fpga()) {
-			console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
-		} else {
-			console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
-		}
-
-		(void)console_16550_register(tegra132_uart_addresses[id],
-					     console_clock,
-					     TEGRA_CONSOLE_BAUDRATE,
-					     &uart_console);
-		console_set_scope(&uart_console, CONSOLE_FLAG_BOOT |
-			CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
-	}
-}
-
-/*******************************************************************************
- * Initialize the GIC and SGIs
- ******************************************************************************/
-void plat_gic_setup(void)
-{
-	tegra_gic_setup(NULL, 0);
-	tegra_gic_init();
-}
-
-/*******************************************************************************
- * Return pointer to the BL31 params from previous bootloader
- ******************************************************************************/
-struct tegra_bl31_params *plat_get_bl31_params(void)
-{
-	return NULL;
-}
-
-/*******************************************************************************
- * Return pointer to the BL31 platform params from previous bootloader
- ******************************************************************************/
-plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
-{
-	return NULL;
-}
-
-/*******************************************************************************
- * Handler for early platform setup
- ******************************************************************************/
-void plat_early_platform_setup(void)
-{
-	plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
-
-	/* Verify chip id is t132 */
-	assert(tegra_chipid_is_t132());
-
-	/*
-	 * Do initial security configuration to allow DRAM/device access.
-	 */
-	tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
-			(uint32_t)plat_params->tzdram_size);
-}
-
-/*******************************************************************************
- * Handler for late platform setup
- ******************************************************************************/
-void plat_late_platform_setup(void)
-{
-	; /* do nothing */
-}
-
-/*******************************************************************************
- * Handler to indicate support for System Suspend
- ******************************************************************************/
-bool plat_supports_system_suspend(void)
-{
-	return true;
-}
-
-/*******************************************************************************
- * Platform specific runtime setup.
- ******************************************************************************/
-void plat_runtime_setup(void)
-{
-	/*
-	 * During cold boot, it is observed that the arbitration
-	 * bit is set in the Memory controller leading to false
-	 * error interrupts in the non-secure world. To avoid
-	 * this, clean the interrupt status register before
-	 * booting into the non-secure world
-	 */
-	tegra_memctrl_clear_pending_interrupts();
-
-	/*
-	 * During boot, USB3 and flash media (SDMMC/SATA) devices need
-	 * access to IRAM. Because these clients connect to the MC and
-	 * do not have a direct path to the IRAM, the MC implements AHB
-	 * redirection during boot to allow path to IRAM. In this mode
-	 * accesses to a programmed memory address aperture are directed
-	 * to the AHB bus, allowing access to the IRAM. This mode must be
-	 * disabled before we jump to the non-secure world.
-	 */
-	tegra_memctrl_disable_ahb_redirection();
-}
diff --git a/plat/nvidia/tegra/soc/t132/plat_sip_calls.c b/plat/nvidia/tegra/soc/t132/plat_sip_calls.c
deleted file mode 100644
index 90c6bb2..0000000
--- a/plat/nvidia/tegra/soc/t132/plat_sip_calls.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <lib/el3_runtime/context_mgmt.h>
-
-#include <tegra_private.h>
-
-#define NS_SWITCH_AARCH32	1
-#define SCR_RW_BITPOS		__builtin_ctz(SCR_RW_BIT)
-
-/*******************************************************************************
- * Tegra132 SiP SMCs
- ******************************************************************************/
-#define TEGRA_SIP_AARCH_SWITCH			0x82000004
-
-/*******************************************************************************
- * SPSR settings for AARCH32/AARCH64 modes
- ******************************************************************************/
-#define SPSR32		SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, \
-			DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT)
-#define SPSR64		SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS)
-
-/*******************************************************************************
- * This function is responsible for handling all T132 SiP calls
- ******************************************************************************/
-int plat_sip_handler(uint32_t smc_fid,
-		     uint64_t x1,
-		     uint64_t x2,
-		     uint64_t x3,
-		     uint64_t x4,
-		     const void *cookie,
-		     void *handle,
-		     uint64_t flags)
-{
-	switch (smc_fid) {
-
-	case TEGRA_SIP_AARCH_SWITCH:
-
-		/* clean up the high bits */
-		x1 = (uint32_t)x1;
-		x2 = (uint32_t)x2;
-
-		if (!x1 || x2 > NS_SWITCH_AARCH32) {
-			ERROR("%s: invalid parameters\n", __func__);
-			return -EINVAL;
-		}
-
-		/* x1 = ns entry point */
-		cm_set_elr_spsr_el3(NON_SECURE, x1,
-			(x2 == NS_SWITCH_AARCH32) ? SPSR32 : SPSR64);
-
-		/* switch NS world mode */
-		cm_write_scr_el3_bit(NON_SECURE, SCR_RW_BITPOS, !x2);
-
-		INFO("CPU switched to AARCH%s mode\n",
-			(x2 == NS_SWITCH_AARCH32) ? "32" : "64");
-		return 0;
-
-	default:
-		ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
-		break;
-	}
-
-	return -ENOTSUP;
-}
diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk
deleted file mode 100644
index 9534c07..0000000
--- a/plat/nvidia/tegra/soc/t132/platform_t132.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-TZDRAM_BASE			:= 0xF5C00000
-$(eval $(call add_define,TZDRAM_BASE))
-
-PLATFORM_CLUSTER_COUNT		:= 1
-$(eval $(call add_define,PLATFORM_CLUSTER_COUNT))
-
-PLATFORM_MAX_CPUS_PER_CLUSTER	:= 2
-$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
-
-MAX_XLAT_TABLES			:= 3
-$(eval $(call add_define,MAX_XLAT_TABLES))
-
-MAX_MMAP_REGIONS		:= 8
-$(eval $(call add_define,MAX_MMAP_REGIONS))
-
-# platform files
-PLAT_INCLUDES		+=	-Iplat/nvidia/tegra/include/t132
-
-BL31_SOURCES		+=	${TEGRA_GICv2_SOURCES}			\
-				drivers/ti/uart/aarch64/16550_console.S	\
-				lib/cpus/aarch64/denver.S		\
-				${TEGRA_DRIVERS}/flowctrl/flowctrl.c	\
-				${TEGRA_DRIVERS}/memctrl/memctrl_v1.c	\
-				${TEGRA_DRIVERS}/pmc/pmc.c		\
-				${SOC_DIR}/plat_psci_handlers.c		\
-				${SOC_DIR}/plat_sip_calls.c		\
-				${SOC_DIR}/plat_setup.c			\
-				${SOC_DIR}/plat_secondary.c
diff --git a/plat/nxp/common/setup/include/plat_common.h b/plat/nxp/common/setup/include/plat_common.h
index 18d36ca..97a9cb7 100644
--- a/plat/nxp/common/setup/include/plat_common.h
+++ b/plat/nxp/common/setup/include/plat_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -10,7 +10,9 @@
 
 #include <stdbool.h>
 
+#include <dcfg.h>
 #include <lib/el3_runtime/cpu_data.h>
+
 #include <platform_def.h>
 
 #ifdef IMAGE_BL31
@@ -129,18 +131,19 @@
 #endif
 );
 
-
 /* Structure to define SoC personality */
 struct soc_type {
 	char name[10];
-	uint32_t personality;
-	uint32_t num_clusters;
-	uint32_t cores_per_cluster;
+	uint32_t version;
+	uint8_t num_clusters;
+	uint8_t cores_per_cluster;
 };
+void get_cluster_info(const struct soc_type *soc_list, uint8_t ps_count,
+		uint8_t *num_clusters, uint8_t *cores_per_cluster);
 
 #define SOC_ENTRY(n, v, ncl, nc) {	\
 		.name = #n,		\
-		.personality = SVR_##v,	\
+		.version = SVR_##v,	\
 		.num_clusters = (ncl),	\
 		.cores_per_cluster = (nc)}
 
diff --git a/plat/nxp/common/setup/ls_common.c b/plat/nxp/common/setup/ls_common.c
index a6946e1..e7ae060 100644
--- a/plat/nxp/common/setup/ls_common.c
+++ b/plat/nxp/common/setup/ls_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -238,3 +238,27 @@
 {
 	return plat_ls_mmap;
 }
+
+/*
+ * This function get the number of clusters and cores count per cluster
+ * in the SoC.
+ */
+void get_cluster_info(const struct soc_type *soc_list, uint8_t ps_count,
+		uint8_t *num_clusters, uint8_t *cores_per_cluster)
+{
+	const soc_info_t *soc_info = get_soc_info();
+	*num_clusters = NUMBER_OF_CLUSTERS;
+	*cores_per_cluster = CORES_PER_CLUSTER;
+	unsigned int i;
+
+	for (i = 0U; i < ps_count; i++) {
+		if (soc_list[i].version == soc_info->svr_reg.bf_ver.version) {
+			*num_clusters = soc_list[i].num_clusters;
+			*cores_per_cluster = soc_list[i].cores_per_cluster;
+			break;
+		}
+	}
+
+	VERBOSE("NUM of cluster = 0x%x, Cores per cluster = 0x%x\n",
+			*num_clusters, *cores_per_cluster);
+}
diff --git a/plat/nxp/common/soc_errata/errata.c b/plat/nxp/common/soc_errata/errata.c
new file mode 100644
index 0000000..fb1818a
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <common/debug.h>
+
+#include "errata_list.h"
+
+void soc_errata(void)
+{
+#ifdef ERRATA_SOC_A050426
+	INFO("SoC workaround for Errata A050426 was applied\n");
+	erratum_a050426();
+#endif
+	/*
+	 * The following DDR Erratas workaround are implemented in DDR driver,
+	 * but print information here.
+	 */
+#if ERRATA_DDR_A011396
+	INFO("SoC workaround for DDR Errata A011396 was applied\n");
+#endif
+#if ERRATA_DDR_A050450
+	INFO("SoC workaround for DDR Errata A050450 was applied\n");
+#endif
+}
diff --git a/plat/nxp/common/soc_errata/errata.h b/plat/nxp/common/soc_errata/errata.h
new file mode 100644
index 0000000..b543b4b
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2020-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef ERRATA_H
+#define ERRATA_H
+
+void soc_errata(void);
+
+#endif /* ERRATA_H */
diff --git a/plat/nxp/common/soc_errata/errata.mk b/plat/nxp/common/soc_errata/errata.mk
new file mode 100644
index 0000000..2942615
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata.mk
@@ -0,0 +1,23 @@
+#
+# Copyright 2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform Errata Build flags.
+# These should be enabled by the platform if the erratum workaround needs to be
+# applied.
+
+ERRATA := \
+  ERRATA_SOC_A050426
+
+define enable_errata
+  $(1) ?= 0
+  ifeq ($$($(1)),1)
+    $$(eval $$(call add_define,$(1)))
+    BL2_SOURCES += $(PLAT_COMMON_PATH)/soc_errata/errata_a$(shell echo $(1)|awk -F '_A' '{print $$NF}').c
+  endif
+endef
+
+$(foreach e,$(ERRATA),$(eval $(call enable_errata,$(strip $(e)))))
+
+BL2_SOURCES += $(PLAT_COMMON_PATH)/soc_errata/errata.c
diff --git a/plat/nxp/soc-lx2160a/erratas_soc.c b/plat/nxp/common/soc_errata/errata_a050426.c
similarity index 98%
rename from plat/nxp/soc-lx2160a/erratas_soc.c
rename to plat/nxp/common/soc_errata/errata_a050426.c
index 8f3aa9f..13a0000 100644
--- a/plat/nxp/soc-lx2160a/erratas_soc.c
+++ b/plat/nxp/common/soc_errata/errata_a050426.c
@@ -7,7 +7,6 @@
 
 #include <mmio.h>
 
-#ifdef ERRATA_SOC_A050426
 void erratum_a050426(void)
 {
 	uint32_t i, val3, val4;
@@ -411,8 +410,6 @@
 	}
 
 	/* Disable BIST */
-
 	mmio_write_32(0x700117E60, val3);
 	mmio_write_32(0x700117E90, val4);
 }
-#endif
diff --git a/plat/nxp/common/soc_errata/errata_list.h b/plat/nxp/common/soc_errata/errata_list.h
new file mode 100644
index 0000000..74d2315
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_list.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef ERRATA_LIST_H
+#define ERRATA_LIST_H
+
+#ifdef ERRATA_SOC_A050426
+void erratum_a050426(void);
+#endif
+
+#endif /* ERRATA_LIST_H */
diff --git a/plat/nxp/soc-lx2160a/erratas_soc.mk b/plat/nxp/soc-lx2160a/erratas_soc.mk
deleted file mode 100644
index 07bed03..0000000
--- a/plat/nxp/soc-lx2160a/erratas_soc.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright 2020 NXP
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-# Platform Errata Build flags.
-# These should be enabled by the platform if the erratum workaround needs to be
-# applied.
-
-# Flag to apply erratum 50426 workaround during reset.
-ERRATA_SOC_A050426	?= 0
-
-# Process ERRATA_SOC_A050426 flag
-ifeq (${ERRATA_SOC_A050426}, 1)
-INCL_SOC_ERRATA_SOURCES	:= yes
-$(eval $(call add_define,ERRATA_SOC_A050426))
-endif
-
-ifeq (${INCL_SOC_ERRATA_SOURCES},yes)
-BL2_SOURCES	+= 	${PLAT_SOC_PATH}/erratas_soc.c
-endif
diff --git a/plat/nxp/soc-lx2160a/include/errata.h b/plat/nxp/soc-lx2160a/include/errata.h
deleted file mode 100644
index 937824a..0000000
--- a/plat/nxp/soc-lx2160a/include/errata.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright 2020 NXP
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef ERRATA_H
-#define ERRATA_H
-
-#ifdef ERRATA_SOC_A050426
-void erratum_a050426(void);
-#endif
-
-#endif /* ERRATA_H */
diff --git a/plat/nxp/soc-lx2160a/include/soc.h b/plat/nxp/soc-lx2160a/include/soc.h
index bd23620..7cc4a03 100644
--- a/plat/nxp/soc-lx2160a/include/soc.h
+++ b/plat/nxp/soc-lx2160a/include/soc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2021 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -52,11 +52,10 @@
 #define FLEXSPI_NOR		0xf
 /* End: Macros used by soc.c: get_boot_dev */
 
-/* bits */
-/* SVR Definition */
-#define SVR_LX2160A		0x04
-#define SVR_LX2120A		0x14
-#define SVR_LX2080A		0x05
+/* SVR Definition (not include major and minor rev) */
+#define SVR_LX2160A		0x873601
+#define SVR_LX2120A		0x873621
+#define SVR_LX2080A		0x873603
 
 /* Number of cores in platform */
 /* Used by common code for array initialization */
diff --git a/plat/nxp/soc-lx2160a/soc.c b/plat/nxp/soc-lx2160a/soc.c
index e0a2fe9..2209fda 100644
--- a/plat/nxp/soc-lx2160a/soc.c
+++ b/plat/nxp/soc-lx2160a/soc.c
@@ -82,28 +82,6 @@
 	.master_to_rn_id_map = master_to_rn_id_map
 };
 
-/*******************************************************************************
- * This function returns the number of clusters in the SoC
- ******************************************************************************/
-static unsigned int get_num_cluster(void)
-{
-	const soc_info_t *soc_info = get_soc_info();
-	uint32_t num_clusters = NUMBER_OF_CLUSTERS;
-	unsigned int i;
-
-	for (i = 0U; i < ARRAY_SIZE(soc_list); i++) {
-		if (soc_list[i].personality == soc_info->personality) {
-			num_clusters = soc_list[i].num_clusters;
-			break;
-		}
-	}
-
-	VERBOSE("NUM of cluster = 0x%x\n", num_clusters);
-
-	return num_clusters;
-}
-
-
 /******************************************************************************
  * Function returns the base counter frequency
  * after reading the first entry at CNTFID0 (0x20 offset).
@@ -142,8 +120,10 @@
 static void soc_interconnect_config(void)
 {
 	unsigned long long val = 0x0U;
+	uint8_t num_clusters, cores_per_cluster;
 
-	uint32_t num_clusters = get_num_cluster();
+	get_cluster_info(soc_list, ARRAY_SIZE(soc_list),
+			&num_clusters, &cores_per_cluster);
 
 	if (num_clusters == 6U) {
 		ccn_init(&plat_six_cluster_ccn_desc);
@@ -271,9 +251,7 @@
 				MT_DEVICE | MT_RW | MT_NS);
 	}
 
-#ifdef ERRATA_SOC_A050426
-	erratum_a050426();
-#endif
+	soc_errata();
 
 #if (TRUSTED_BOARD_BOOT) || defined(POLICY_FUSE_PROVISION)
 	sfp_init(NXP_SFP_ADDR);
@@ -466,7 +444,12 @@
  ******************************************************************************/
 void soc_init(void)
 {
-	 /* low-level init of the soc */
+	uint8_t num_clusters, cores_per_cluster;
+
+	get_cluster_info(soc_list, ARRAY_SIZE(soc_list),
+			&num_clusters, &cores_per_cluster);
+
+	/* low-level init of the soc */
 	soc_init_start();
 	soc_init_percpu();
 	_init_global_data();
@@ -478,8 +461,6 @@
 		panic();
 	}
 
-	uint32_t num_clusters = get_num_cluster();
-
 	if (num_clusters == 6U) {
 		ccn_init(&plat_six_cluster_ccn_desc);
 	} else {
diff --git a/plat/nxp/soc-lx2160a/soc.mk b/plat/nxp/soc-lx2160a/soc.mk
index 8ab1430..75a3af2 100644
--- a/plat/nxp/soc-lx2160a/soc.mk
+++ b/plat/nxp/soc-lx2160a/soc.mk
@@ -99,7 +99,8 @@
 PLAT_INCLUDES		+=	-I${PLAT_COMMON_PATH}/include/default\
 				-I${BOARD_PATH}\
 				-I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\
-				-I${PLAT_SOC_PATH}/include
+				-I${PLAT_SOC_PATH}/include\
+				-I${PLAT_COMMON_PATH}/soc_errata
 
 ifeq (${SECURE_BOOT},yes)
 include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk
@@ -138,7 +139,7 @@
 include ${PLAT_DRIVERS_PATH}/drivers.mk
 
  # Adding SoC specific files
-include ${PLAT_SOC_PATH}/erratas_soc.mk
+include ${PLAT_COMMON_PATH}/soc_errata/errata.mk
 
 PLAT_INCLUDES		+=	${NV_STORAGE_INCLUDES}\
 				${WARM_RST_INCLUDES}
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index 0891d80..c02eff9 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -80,8 +80,8 @@
 #define SEC_ROM_BASE			0x00000000
 #define SEC_ROM_SIZE			0x00020000
 
-#define NS_DRAM0_BASE			0x40000000
-#define NS_DRAM0_SIZE			0xc0000000
+#define NS_DRAM0_BASE			ULL(0x40000000)
+#define NS_DRAM0_SIZE			ULL(0xc0000000)
 
 #define SEC_SRAM_BASE			0x0e000000
 #define SEC_SRAM_SIZE			0x00060000
diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c
index cfacd1f..5259859 100644
--- a/plat/rpi/rpi4/rpi4_bl31_setup.c
+++ b/plat/rpi/rpi4/rpi4_bl31_setup.c
@@ -201,6 +201,44 @@
 	enable_mmu_el3(0);
 }
 
+/*
+ * Remove the FDT /memreserve/ entry that covers the region at the very
+ * beginning of memory (if that exists). This is where the secondaries
+ * originally spin, but we pull them out there.
+ * Having overlapping /reserved-memory and /memreserve/ regions confuses
+ * the Linux kernel, so we need to get rid of this one.
+ */
+static void remove_spintable_memreserve(void *dtb)
+{
+	uint64_t addr, size;
+	int regions = fdt_num_mem_rsv(dtb);
+	int i;
+
+	for (i = 0; i < regions; i++) {
+		if (fdt_get_mem_rsv(dtb, i, &addr, &size) != 0) {
+			return;
+		}
+		if (size == 0U) {
+			return;
+		}
+		/* We only look for the region at the beginning of DRAM. */
+		if (addr != 0U) {
+			continue;
+		}
+		/*
+		 * Currently the region in the existing DTs is exactly 4K
+		 * in size. Should this value ever change, there is probably
+		 * a reason for that, so inform the user about this.
+		 */
+		if (size == 4096U) {
+			fdt_del_mem_rsv(dtb, i);
+			return;
+		}
+		WARN("Keeping unknown /memreserve/ region at 0, size: %lld\n",
+		     size);
+	}
+}
+
 static void rpi4_prepare_dtb(void)
 {
 	void *dtb = (void *)rpi4_get_dtb_address();
@@ -227,7 +265,11 @@
 		return;
 	}
 
-	/* Reserve memory used by Trusted Firmware. */
+	/*
+	 * Remove the original reserved region (used for the spintable), and
+	 * replace it with a region describing the whole of Trusted Firmware.
+	 */
+	remove_spintable_memreserve(dtb);
 	if (fdt_add_reserved_memory(dtb, "atf@0", 0, 0x80000))
 		WARN("Failed to add reserved memory nodes to DT.\n");
 
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 3e179fb..b4c42fc 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -153,8 +153,6 @@
 
 #ifdef AARCH32_SP_OPTEE
 	INFO("BL2 runs OP-TEE setup\n");
-	/* Initialize tzc400 after DDR initialization */
-	stm32mp1_security_setup();
 #else
 	INFO("BL2 runs SP_MIN setup\n");
 #endif
@@ -384,4 +382,9 @@
 
 	return err;
 }
+
+void bl2_el3_plat_prepare_exit(void)
+{
+	stm32mp1_security_setup();
+}
 #endif
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index f165fb0..9c5af88 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -677,6 +677,10 @@
 	case IOCTL_AFI:
 		ret = pm_ioctl_afi(arg1, arg2);
 		break;
+	case IOCTL_SET_FEATURE_CONFIG:
+	case IOCTL_GET_FEATURE_CONFIG:
+		ret = pm_feature_config(ioctl_id, arg1, arg2, value);
+		break;
 	default:
 		ret = PM_RET_ERROR_NOTSUPPORTED;
 		break;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
index 337f732..f18dc00 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -15,28 +15,43 @@
 
 //ioctl id
 enum {
-	IOCTL_GET_RPU_OPER_MODE,
-	IOCTL_SET_RPU_OPER_MODE,
-	IOCTL_RPU_BOOT_ADDR_CONFIG,
-	IOCTL_TCM_COMB_CONFIG,
-	IOCTL_SET_TAPDELAY_BYPASS,
-	IOCTL_SET_SGMII_MODE,
-	IOCTL_SD_DLL_RESET,
-	IOCTL_SET_SD_TAPDELAY,
+	IOCTL_GET_RPU_OPER_MODE = 0,
+	IOCTL_SET_RPU_OPER_MODE = 1,
+	IOCTL_RPU_BOOT_ADDR_CONFIG = 2,
+	IOCTL_TCM_COMB_CONFIG = 3,
+	IOCTL_SET_TAPDELAY_BYPASS = 4,
+	IOCTL_SET_SGMII_MODE = 5,
+	IOCTL_SD_DLL_RESET = 6,
+	IOCTL_SET_SD_TAPDELAY = 7,
 	 /* Ioctl for clock driver */
-	IOCTL_SET_PLL_FRAC_MODE,
-	IOCTL_GET_PLL_FRAC_MODE,
-	IOCTL_SET_PLL_FRAC_DATA,
-	IOCTL_GET_PLL_FRAC_DATA,
-	IOCTL_WRITE_GGS,
-	IOCTL_READ_GGS,
-	IOCTL_WRITE_PGGS,
-	IOCTL_READ_PGGS,
+	IOCTL_SET_PLL_FRAC_MODE = 8,
+	IOCTL_GET_PLL_FRAC_MODE = 9,
+	IOCTL_SET_PLL_FRAC_DATA = 10,
+	IOCTL_GET_PLL_FRAC_DATA = 11,
+	IOCTL_WRITE_GGS = 12,
+	IOCTL_READ_GGS = 13,
+	IOCTL_WRITE_PGGS = 14,
+	IOCTL_READ_PGGS = 15,
 	/* IOCTL for ULPI reset */
-	IOCTL_ULPI_RESET,
+	IOCTL_ULPI_RESET = 16,
 	/* Set healthy bit value */
-	IOCTL_SET_BOOT_HEALTH_STATUS,
-	IOCTL_AFI,
+	IOCTL_SET_BOOT_HEALTH_STATUS = 17,
+	IOCTL_AFI = 18,
+	/* Probe counter read/write */
+	IOCTL_PROBE_COUNTER_READ = 19,
+	IOCTL_PROBE_COUNTER_WRITE = 20,
+	IOCTL_OSPI_MUX_SELECT = 21,
+	/* IOCTL for USB power request */
+	IOCTL_USB_SET_STATE = 22,
+	/* IOCTL to get last reset reason */
+	IOCTL_GET_LAST_RESET_REASON = 23,
+	/* AI engine NPI ISR clear */
+	IOCTL_AIE_ISR_CLEAR = 24,
+	/* Register SGI to ATF */
+	IOCTL_REGISTER_SGI = 25,
+	/* Runtime feature configuration */
+	IOCTL_SET_FEATURE_CONFIG = 26,
+	IOCTL_GET_FEATURE_CONFIG = 27,
 };
 
 //RPU operation mode
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index 62260bc..5d9408c 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -1648,3 +1648,36 @@
 	EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS);
 	return pm_ipi_send_sync(primary_proc, payload, value, 1);
 }
+
+/**
+ * pm_feature_config() - feature configuration at runtime
+ *
+ * This function is used to send IPI request to PMUFW to configure feature
+ * at runtime. The feature can be enable or disable as well as the feature
+ * can be configure at runtime using an IOCTL call.
+ *
+ * @ioctl_id	The ioctl id for the feature configuration
+ * @config_id	The config id of the feature to be configured
+ * @value	The value to be configured
+ * @response	Return to reference pointer
+ *
+ * @return      Returns 0 on success or error value on failure
+ */
+enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
+				     unsigned int config_id,
+				     unsigned int value,
+				     unsigned int *response)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMU */
+	PM_PACK_PAYLOAD5(payload, PM_IOCTL, 0, ioctl_id, config_id, value);
+
+	if (ioctl_id == IOCTL_GET_FEATURE_CONFIG) {
+		return pm_ipi_send_sync(primary_proc, payload, response, 1);
+	} else if (ioctl_id == IOCTL_SET_FEATURE_CONFIG) {
+		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+	} else {
+		return PM_RET_ERROR_ARGS;
+	}
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index b0c2652..ca07cef 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -202,4 +202,9 @@
 enum pm_ret_status em_remove_action(unsigned int *value);
 enum pm_ret_status em_send_errors(unsigned int *value);
 
+enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
+				     unsigned int config_id,
+				     unsigned int value,
+				     unsigned int *response);
+
 #endif /* PM_API_SYS_H */