Merge "fix(versal-net): populate gic v3 rdist data statically" into integration
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 25c4269..6b57c0e 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -53,7 +53,7 @@
     consistency with the versioning schemes used in other parts of RMM.
 
 This document specifies the 0.1 version of Boot Interface ABI and RMM-EL3
-services specification and the 0.1 version of the Boot Manifest.
+services specification and the 0.2 version of the Boot Manifest.
 
 .. _rmm_el3_boot_interface:
 
@@ -71,7 +71,7 @@
 
 The Boot Interface ABI defines a set of register conventions and
 also a memory based manifest file to pass information from EL3 to RMM. The
-boot manifest and the associated platform data in it can be dynamically created
+Boot Manifest and the associated platform data in it can be dynamically created
 by EL3 and there is no restriction on how the data can be obtained (e.g by DTB,
 hoblist or other).
 
@@ -99,7 +99,7 @@
    x0,Linear index of this PE. This index starts from 0 and must be less than the maximum number of CPUs to be supported at runtime (see x2).
    x1,Version for this Boot Interface as defined in :ref:`rmm_el3_ifc_versioning`.
    x2,Maximum number of CPUs to be supported at runtime. RMM should ensure that it can support this maximum number.
-   x3,Base address for the shared buffer used for communication between EL3 firmware and RMM. This buffer must be of 4KB size (1 page). The boot manifest must be present at the base of this shared buffer during cold boot.
+   x3,Base address for the shared buffer used for communication between EL3 firmware and RMM. This buffer must be of 4KB size (1 page). The Boot Manifest must be present at the base of this shared buffer during cold boot.
 
 During cold boot, EL3 firmware needs to allocate a 4KB page that will be
 passed to RMM in x3. This memory will be used as shared buffer for communication
@@ -162,8 +162,8 @@
    ``E_RMM_BOOT_CPUS_OUT_OF_RAGE``,Number of CPUs reported by EL3 larger than maximum supported by RMM,-3
    ``E_RMM_BOOT_CPU_ID_OUT_OF_RAGE``,Current CPU Id is higher or equal than the number of CPUs supported by RMM,-4
    ``E_RMM_BOOT_INVALID_SHARED_BUFFER``,Invalid pointer to shared memory area,-5
-   ``E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED``,Version reported by the boot manifest not supported by RMM,-6
-   ``E_RMM_BOOT_MANIFEST_DATA_ERROR``,Error parsing core boot manifest,-7
+   ``E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED``,Version reported by the Boot Manifest not supported by RMM,-6
+   ``E_RMM_BOOT_MANIFEST_DATA_ERROR``,Error parsing core Boot Manifest,-7
 
 For any error detected in RMM during cold or warm boot, RMM will return back to
 EL3 using ``RMM_BOOT_COMPLETE`` SMC with an appropriate error code. It is
@@ -177,25 +177,28 @@
 Boot Manifest
 ~~~~~~~~~~~~~
 
-During cold boot, EL3 Firmware passes a memory boot manifest to RMM containing
+During cold boot, EL3 Firmware passes a memory Boot Manifest to RMM containing
 platform information.
 
-This boot manifest is versioned independently of the boot interface, to help
-evolve the boot manifest independent of the rest of Boot Manifest.
-The current version for the boot manifest is ``v0.1`` and the rules explained
+This Boot Manifest is versioned independently of the Boot Interface, to help
+evolve the former independent of the latter.
+The current version for the Boot Manifest is ``v0.2`` and the rules explained
 in :ref:`rmm_el3_ifc_versioning` apply on this version as well.
 
-The boot manifest is divided into two different components:
+The Boot Manifest v0.2 has the following fields:
 
-   - Core Manifest: This is the generic parameters passed to RMM by EL3 common to all platforms.
-   - Platform data: This is defined by the platform owner and contains information specific to that platform.
+   - version : Version of the Manifest (v0.2)
+   - plat_data : Pointer to the platform specific data and not specified by this
+     document. These data are optional and can be NULL.
+   - plat_dram : Structure encoding the NS DRAM information on the platform. This
+     field is also optional and platform can choose to zero out this structure if
+     RMM does not need EL3 to send this information during the boot.
 
-For the current version of the manifest, the core manifest contains a pointer
-to the platform data. EL3 must ensure that the whole boot manifest,
-including the platform data, if available, fits inside the RMM EL3 shared
-buffer.
+For the current version of the Boot Manifest, the core manifest contains a pointer
+to the platform data. EL3 must ensure that the whole Boot Manifest, including
+the platform data, if available, fits inside the RMM EL3 shared buffer.
 
-For the type specification of the RMM Boot Manifest v0.1, refer to
+For the data structure specification of Boot Manifest, refer to
 :ref:`rmm_el3_manifest_struct`
 
 .. _runtime_services_and_interface:
@@ -525,19 +528,59 @@
 RMM-EL3 Boot Manifest structure
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The RMM-EL3 Boot Manifest structure contains platform boot information passed
-from EL3 to RMM. The width of the Boot Manifest is 128 bits
-
-.. image:: ../resources/diagrams/rmm_el3_manifest_struct.png
+The RMM-EL3 Boot Manifest v0.2 structure contains platform boot information passed
+from EL3 to RMM. The size of the Boot Manifest is 40 bytes.
 
 The members of the RMM-EL3 Boot Manifest structure are shown in the following
 table:
 
-.. csv-table::
-   :header: "Name", "Range", "Type", Description
-   :widths: 2 1 1 4
++-----------+--------+----------------+----------------------------------------+
+|   Name    | Offset |     Type       |               Description              |
++===========+========+================+========================================+
+| version   |   0    |   uint32_t     | Boot Manifest version                  |
++-----------+--------+----------------+----------------------------------------+
+| padding   |   4    |   uint32_t     | Reserved, set to 0                     |
++-----------+--------+----------------+----------------------------------------+
+| plat_data |   8    |   uintptr_t    | Pointer to Platform Data section       |
++-----------+--------+----------------+----------------------------------------+
+| plat_dram |   16   | ns_dram_info   | NS DRAM Layout Info structure          |
++-----------+--------+----------------+----------------------------------------+
+
+.. _ns_dram_info_struct:
+
+NS DRAM Layout Info structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+NS DRAM Layout Info structure contains information about platform Non-secure
+DRAM layout. The members of this structure are shown in the table below:
+
++-----------+--------+----------------+----------------------------------------+
+|   Name    | Offset |     Type       |               Description              |
++===========+========+================+========================================+
+| num_banks |   0    |   uint64_t     | Number of NS DRAM banks                |
++-----------+--------+----------------+----------------------------------------+
+| banks     |   8    | ns_dram_bank * | Pointer to 'ns_dram_bank'[] array      |
++-----------+--------+----------------+----------------------------------------+
+| checksum  |   16   |   uint64_t     | Checksum                               |
++-----------+--------+----------------+----------------------------------------+
+
+Checksum is calculated as two's complement sum of 'num_banks', 'banks' pointer
+and DRAM banks data array pointed by it.
+
+.. _ns_dram_bank_struct:
+
+NS DRAM Bank structure
+~~~~~~~~~~~~~~~~~~~~~~
+
+NS DRAM Bank structure contains information about each Non-secure DRAM bank:
+
++-----------+--------+----------------+----------------------------------------+
+|   Name    | Offset |     Type       |               Description              |
++===========+========+================+========================================+
+|   base    |   0    |   uintptr_t    | Base address                           |
++-----------+--------+----------------+----------------------------------------+
+|   size    |   8    |   uint64_t     | Size of bank in bytes                  |
++-----------+--------+----------------+----------------------------------------+
+
+
 
-   ``Version Minor``,15:0,uint16_t,Version Minor part of the Boot Manifest Version.
-   ``Version Major``,30:16,uint16_t,Version Major part of the Boot Manifest Version.
-   ``RES0``,31,bit,Reserved. Set to 0.
-   ``Platform Data``,127:64,Address,Pointer to the Platform Data section of the Boot Manifest.
diff --git a/docs/components/spd/optee-dispatcher.rst b/docs/components/spd/optee-dispatcher.rst
index 63baccc..81476f1 100644
--- a/docs/components/spd/optee-dispatcher.rst
+++ b/docs/components/spd/optee-dispatcher.rst
@@ -6,9 +6,26 @@
 To build and execute OP-TEE follow the instructions at
 `OP-TEE build.git`_
 
+There are two different modes for loading the OP-TEE OS. The default mode will
+load it as the BL32 payload during boot, and is the recommended technique for
+platforms to use. There is also another technique that will load OP-TEE OS after
+boot via an SMC call by enabling the option for OPTEE_ALLOW_SMC_LOAD that was
+specifically added for ChromeOS. Loading OP-TEE via an SMC call may be insecure
+depending upon the platform configuration. If using that option, be sure to
+understand the risks involved with allowing the Trusted OS to be loaded this
+way. ChromeOS uses a boot flow where it verifies the signature of the firmware
+before executing it, and then only if the signature is valid will the 'secrets'
+used by the TEE become accessible. The firmware then verifies the signature of
+the kernel using depthcharge, and the kernel verifies the rootfs using
+dm-verity.  The SMC call to load OP-TEE is then invoked immediately after the
+kernel finishes loading and before any attack vectors can be opened up by
+mounting writable filesystems or opening network/device connections. this
+ensures the platform is 'closed' and running signed code through the point where
+OP-TEE is loaded.
+
 --------------
 
-*Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
 
 .. _OP-TEE OS: https://github.com/OP-TEE/build
 .. _OP-TEE build.git: https://github.com/OP-TEE/build
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index 5d2e663..5d04639 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -14,6 +14,11 @@
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net bl31
 ```
 
+To build TF-A for JTAG DCC console:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net VERSAL_NET_CONSOLE=dcc bl31
+```
+
 Xilinx Versal NET platform specific build options
 -------------------------------------------------
 
@@ -23,8 +28,9 @@
 *   `VERSAL_NET_BL32_MEM_SIZE`: Specifies the size of the memory region of the bl32 binary.
 
 *   `VERSAL_NET_CONSOLE`: Select the console driver. Options:
-    -   `pl011`, `pl011_0`: ARM pl011 UART 0
+    -   `pl011`, `pl011_0`: ARM pl011 UART 0 (default)
     -   `pl011_1`         : ARM pl011 UART 1
+    -   `dcc`             : JTAG Debug Communication Channel(DCC)
 
 *   `TFA_NO_PM` : Platform Management support.
     -    0 : Enable Platform Management (Default)
diff --git a/docs/resources/diagrams/rmm_el3_manifest_struct.dia b/docs/resources/diagrams/rmm_el3_manifest_struct.dia
deleted file mode 100644
index 7b7a9c2..0000000
--- a/docs/resources/diagrams/rmm_el3_manifest_struct.dia
+++ /dev/null
Binary files differ
diff --git a/docs/resources/diagrams/rmm_el3_manifest_struct.png b/docs/resources/diagrams/rmm_el3_manifest_struct.png
deleted file mode 100644
index 8b5776c..0000000
--- a/docs/resources/diagrams/rmm_el3_manifest_struct.png
+++ /dev/null
Binary files differ
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 99bbb3a..0e967ba 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -918,9 +918,54 @@
 | Mitigations            | | Yes / Platform specific                           |
 +------------------------+-----------------------------------------------------+
 
++------------------------+-----------------------------------------------------+
+| ID                     | 14                                                  |
++========================+=====================================================+
+| Threat                 | | **Security vulnerabilities in the Non-secure OS   |
+|                        |   can lead to secure world compromise if the option |
+|                        |   OPTEE_ALLOW_SMC_LOAD is enabled.**                |
+|                        |                                                     |
+|                        | | This option trusts the non-secure world up until  |
+|                        |   the point it issues the SMC call to load the      |
+|                        |   Secure BL32 payload. If a compromise occurs       |
+|                        |   before the SMC call is invoked, then arbitrary    |
+|                        |   code execution in S-EL1 can occur or arbitrary    |
+|                        |   memory in EL3 can be overwritten.                 |
++------------------------+-----------------------------------------------------+
+| Diagram Elements       | DF5                                                 |
++------------------------+-----------------------------------------------------+
+| Affected TF-A          | BL31, BL32                                          |
+| Components             |                                                     |
++------------------------+-----------------------------------------------------+
+| Assets                 | Code Execution, Sensitive Data                      |
++------------------------+-----------------------------------------------------+
+| Threat Agent           | NSCode                                              |
++------------------------+-----------------------------------------------------+
+| Threat Type            | Tampering, Information Disclosure,                  |
+|                        | Elevation of privilege                              |
++------------------------+-----------------+-----------------+-----------------+
+| Application            | Server          | IoT             | Mobile          |
++------------------------+-----------------+-----------------+-----------------+
+| Impact                 | Critical (5)    | Critical (5)    | Critical (5)    |
++------------------------+-----------------+-----------------+-----------------+
+| Likelihood             | Low (2)         | Low (2)         | Low (2)         |
++------------------------+-----------------+-----------------+-----------------+
+| Total Risk Rating      | Medium (10)     | Medium (10)     | Medium (10)     |
++------------------------+-----------------+-----------------+-----------------+
+| Mitigations            | When enabling the option OPTEE_ALLOW_SMC_LOAD,      |
+|                        | the non-secure OS must be considered a closed       |
+|                        | platform up until the point the SMC can be invoked  |
+|                        | to load OP-TEE.                                     |
++------------------------+-----------------------------------------------------+
+| Mitigations            | | None in TF-A itself. This option is only used by  |
+| implemented?           |   ChromeOS currently which has other mechanisms to  |
+|                        |   to mitigate this threat which are described in    |
+|                        |   `OP-TEE Dispatcher`_.                             |
++------------------------+-----------------------------------------------------+
+
 --------------
 
-*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
 
 
 .. _STRIDE threat analysis technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
@@ -932,3 +977,4 @@
 .. _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/
+.. _OP-TEE Dispatcher: https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/components/spd/optee-dispatcher.rst
diff --git a/include/lib/optee_utils.h b/include/lib/optee_utils.h
index 06378eb..8224d50 100644
--- a/include/lib/optee_utils.h
+++ b/include/lib/optee_utils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,4 +17,40 @@
 	image_info_t *pager_image_info,
 	image_info_t *paged_image_info);
 
+/*
+ * load_addr_hi and load_addr_lo: image load address.
+ * image_id: 0 - pager, 1 - paged
+ * size: image size in bytes.
+ */
+typedef struct optee_image {
+	uint32_t load_addr_hi;
+	uint32_t load_addr_lo;
+	uint32_t image_id;
+	uint32_t size;
+} optee_image_t;
+
+#define OPTEE_PAGER_IMAGE_ID		0
+#define OPTEE_PAGED_IMAGE_ID		1
+
+#define OPTEE_MAX_NUM_IMAGES		2u
+
+#define TEE_MAGIC_NUM_OPTEE		0x4554504f
+/*
+ * magic: header magic number.
+ * version: OPTEE header version:
+ *		1 - not supported
+ *		2 - supported
+ * arch: OPTEE os architecture type: 0 - AARCH32, 1 - AARCH64.
+ * flags: unused currently.
+ * nb_images: number of images.
+ */
+typedef struct optee_header {
+	uint32_t magic;
+	uint8_t version;
+	uint8_t arch;
+	uint16_t flags;
+	uint32_t nb_images;
+	optee_image_t optee_image_list[];
+} optee_header_t;
+
 #endif /* OPTEE_UTILS_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 36b1bdb..7cd32b1 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -235,6 +235,8 @@
 #define ARM_DRAM2_SIZE			PLAT_ARM_DRAM2_SIZE
 #define ARM_DRAM2_END			(ARM_DRAM2_BASE +		\
 					 ARM_DRAM2_SIZE - 1U)
+/* Number of DRAM banks */
+#define ARM_DRAM_NUM_BANKS		2UL
 
 #define ARM_IRQ_SEC_PHY_TIMER		29
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 3351036..8543ac7 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -11,7 +11,7 @@
 
 #include <lib/psci/psci.h>
 #if defined(SPD_spmd)
- #include <services/spm_core_manifest.h>
+#include <services/spm_core_manifest.h>
 #endif
 #if ENABLE_RME
 #include <services/rmm_core_manifest.h>
@@ -37,6 +37,7 @@
 struct mmap_region;
 struct spm_mm_boot_info;
 struct sp_res_desc;
+struct rmm_manifest;
 enum fw_enc_status_t;
 
 /*******************************************************************************
@@ -322,7 +323,7 @@
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type);
 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
-int plat_rmmd_load_manifest(rmm_manifest_t *manifest);
+int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
 #endif
 
 /*******************************************************************************
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
index 7edef46..b89de9f 100644
--- a/include/services/rmm_core_manifest.h
+++ b/include/services/rmm_core_manifest.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,7 @@
 #include <lib/cassert.h>
 
 #define RMMD_MANIFEST_VERSION_MAJOR		U(0)
-#define RMMD_MANIFEST_VERSION_MINOR		U(1)
+#define RMMD_MANIFEST_VERSION_MINOR		U(2)
 
 /*
  * Manifest version encoding:
@@ -22,29 +22,57 @@
  *	- Bits [30:16] Major version
  *	- Bits [15:0] Minor version
  */
-#define _RMMD_MANIFEST_VERSION(_major, _minor)				\
+#define SET_RMMD_MANIFEST_VERSION(_major, _minor)		\
 	((((_major) & 0x7FFF) << 16) | ((_minor) & 0xFFFF))
 
-#define RMMD_MANIFEST_VERSION _RMMD_MANIFEST_VERSION(			\
-				RMMD_MANIFEST_VERSION_MAJOR,		\
+#define RMMD_MANIFEST_VERSION	SET_RMMD_MANIFEST_VERSION(	\
+				RMMD_MANIFEST_VERSION_MAJOR,	\
 				RMMD_MANIFEST_VERSION_MINOR)
 
-#define RMMD_GET_MANIFEST_VERSION_MAJOR(_version)			\
+#define RMMD_GET_MANIFEST_VERSION_MAJOR(_version)		\
 	((_version >> 16) & 0x7FFF)
 
-#define RMMD_GET_MANIFEST_VERSION_MINOR(_version)			\
+#define RMMD_GET_MANIFEST_VERSION_MINOR(_version)		\
 	(_version & 0xFFFF)
 
-/* Boot manifest core structure as per v0.1 */
-typedef struct rmm_manifest {
-	uint32_t version;	/* Manifest version */
-	uint32_t padding;	/* RES0 */
-	uintptr_t plat_data;	/* Manifest platform data */
-} rmm_manifest_t;
+/* NS DRAM bank structure */
+struct ns_dram_bank {
+	uintptr_t base;			/* Base address */
+	uint64_t size;			/* Size of bank */
+};
+
+CASSERT(offsetof(struct ns_dram_bank, base) == 0UL,
+			rmm_manifest_base_unaligned);
+CASSERT(offsetof(struct ns_dram_bank, size) == 8UL,
+			rmm_manifest_size_unaligned);
+
+/* NS DRAM layout info structure */
+struct ns_dram_info {
+	uint64_t num_banks;		/* Number of NS DRAM banks */
+	struct ns_dram_bank *banks;	/* Pointer to ns_dram_bank[] */
+	uint64_t checksum;		/* Checksum of ns_dram_info data */
+};
+
+CASSERT(offsetof(struct ns_dram_info, num_banks) == 0UL,
+			rmm_manifest_num_banks_unaligned);
+CASSERT(offsetof(struct ns_dram_info, banks) == 8UL,
+			rmm_manifest_dram_data_unaligned);
+CASSERT(offsetof(struct ns_dram_info, checksum) == 16UL,
+			rmm_manifest_checksum_unaligned);
+
+/* Boot manifest core structure as per v0.2 */
+struct rmm_manifest {
+	uint32_t version;		/* Manifest version */
+	uint32_t padding;		/* RES0 */
+	uintptr_t plat_data;		/* Manifest platform data */
+	struct ns_dram_info plat_dram;	/* Platform NS DRAM data */
+};
 
-CASSERT(offsetof(rmm_manifest_t, version) == 0,
-				rmm_manifest_t_version_unaligned);
-CASSERT(offsetof(rmm_manifest_t, plat_data) == 8,
-				rmm_manifest_t_plat_data_unaligned);
+CASSERT(offsetof(struct rmm_manifest, version) == 0UL,
+			rmm_manifest_version_unaligned);
+CASSERT(offsetof(struct rmm_manifest, plat_data) == 8UL,
+			rmm_manifest_plat_data_unaligned);
+CASSERT(offsetof(struct rmm_manifest, plat_dram) == 16UL,
+			rmm_manifest_plat_dram_unaligned);
 
 #endif /* RMM_CORE_MANIFEST_H */
diff --git a/include/services/trp/platform_trp.h b/include/services/trp/platform_trp.h
index 1c963c8..756e9db 100644
--- a/include/services/trp/platform_trp.h
+++ b/include/services/trp/platform_trp.h
@@ -9,9 +9,11 @@
 
 #include <services/rmm_core_manifest.h>
 
+struct rmm_manifest;
+
 /*******************************************************************************
  * Mandatory TRP functions (only if platform contains a TRP)
  ******************************************************************************/
-void trp_early_platform_setup(rmm_manifest_t *manifest);
+void trp_early_platform_setup(struct rmm_manifest *manifest);
 
 #endif /* PLATFORM_TRP_H */
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index 6c87b0d..25272fc 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,42 +11,6 @@
 
 #include <platform_def.h>
 
-/*
- * load_addr_hi and load_addr_lo: image load address.
- * image_id: 0 - pager, 1 - paged
- * size: image size in bytes.
- */
-typedef struct optee_image {
-	uint32_t load_addr_hi;
-	uint32_t load_addr_lo;
-	uint32_t image_id;
-	uint32_t size;
-} optee_image_t;
-
-#define OPTEE_PAGER_IMAGE_ID		0
-#define OPTEE_PAGED_IMAGE_ID		1
-
-#define OPTEE_MAX_NUM_IMAGES		2u
-
-#define TEE_MAGIC_NUM_OPTEE		0x4554504f
-/*
- * magic: header magic number.
- * version: OPTEE header version:
- *		1 - not supported
- *		2 - supported
- * arch: OPTEE os architecture type: 0 - AARCH32, 1 - AARCH64.
- * flags: unused currently.
- * nb_images: number of images.
- */
-typedef struct optee_header {
-	uint32_t magic;
-	uint8_t version;
-	uint8_t arch;
-	uint16_t flags;
-	uint32_t nb_images;
-	optee_image_t optee_image_list[];
-} optee_header_t;
-
 /*******************************************************************************
  * Check if it is a valid tee header
  * Return true if valid
diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
index 45e3b7e..43dc17b 100644
--- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,15 @@
 struct hw_topology_t soc_topology;
 struct uart_serial_config_t uart_serial_config;
 struct cpu_timer_t cpu_timer;
+struct ns_dram_layout dram_layout;
+
+/*
+ * Each NS DRAM bank entry is 'reg' node property which is
+ * a sequence of (address, length) pairs of 32-bit values.
+ */
+#define DRAM_ENTRY_SIZE		(4UL * sizeof(uint32_t))
+
+CASSERT(ARM_DRAM_NUM_BANKS == 2UL, ARM_DRAM_NUM_BANKS_mismatch);
 
 #define ILLEGAL_ADDR	ULL(~0)
 
@@ -293,7 +302,58 @@
 	return 0;
 }
 
+int fconf_populate_dram_layout(uintptr_t config)
+{
+	int node, len;
+	const uint32_t *reg;
+
+	/* Necessary to work with libfdt APIs */
+	const void *hw_config_dtb = (const void *)config;
+
+	/* Find 'memory' node */
+	node = fdt_node_offset_by_prop_value(hw_config_dtb, -1, "device_type",
+					     "memory", sizeof("memory"));
+	if (node < 0) {
+		WARN("FCONF: Unable to locate 'memory' node\n");
+		return node;
+	}
+
+	reg = fdt_getprop(hw_config_dtb, node, "reg", &len);
+	if (reg == NULL) {
+		ERROR("FCONF failed to read 'reg' property\n");
+		return len;
+	}
+
+	switch (len) {
+	case DRAM_ENTRY_SIZE:
+		/* 1 DRAM bank */
+		dram_layout.num_banks = 1UL;
+		break;
+	case 2UL * DRAM_ENTRY_SIZE:
+		/* 2 DRAM banks */
+		dram_layout.num_banks = 2UL;
+		break;
+	default:
+		ERROR("FCONF: Invalid 'memory' node\n");
+		return -FDT_ERR_BADLAYOUT;
+	}
+
+	for (unsigned long i = 0UL; i < dram_layout.num_banks; i++) {
+		int err = fdt_get_reg_props_by_index(
+				hw_config_dtb, node, (int)i,
+				&dram_layout.dram_bank[i].base,
+				(size_t *)&dram_layout.dram_bank[i].size);
+		if (err < 0) {
+			ERROR("FCONF: Failed to read 'reg' property #%lu of 'memory' node\n", i);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
 FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config);
 FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
 FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config);
 FCONF_REGISTER_POPULATOR(HW_CONFIG, cpu_timer, fconf_populate_cpu_timer);
+FCONF_REGISTER_POPULATOR(HW_CONFIG, dram_layout, fconf_populate_dram_layout);
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index f5d9940..c7bf93e 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,19 +12,19 @@
 #include <drivers/arm/gicv2.h>
 #include <drivers/arm/sp804_delay_timer.h>
 #include <drivers/generic_delay_timer.h>
+#include <fconf_hw_config_getter.h>
 #include <lib/mmio.h>
 #include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <platform_def.h>
 #include <services/arm_arch_svc.h>
-#if ENABLE_RME
 #include <services/rmm_core_manifest.h>
-#endif
 #if SPM_MM
 #include <services/spm_mm_partition.h>
 #endif
 
 #include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/arm_pas_def.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -531,15 +531,73 @@
 	return (size_t)RMM_SHARED_SIZE;
 }
 
-int plat_rmmd_load_manifest(rmm_manifest_t *manifest)
+int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 {
+	uint64_t checksum, num_banks;
+	struct ns_dram_bank *bank_ptr;
+
 	assert(manifest != NULL);
 
+	/* Get number of DRAM banks */
+	num_banks = FCONF_GET_PROPERTY(hw_config, dram_layout, num_banks);
+	assert(num_banks <= ARM_DRAM_NUM_BANKS);
+
 	manifest->version = RMMD_MANIFEST_VERSION;
 	manifest->padding = 0U; /* RES0 */
 	manifest->plat_data = (uintptr_t)NULL;
+	manifest->plat_dram.num_banks = num_banks;
+
+	/*
+	 * Array ns_dram_banks[] follows ns_dram_info structure:
+	 *
+	 * +-----------------------------------+
+	 * |  offset  |   field   |  comment   |
+	 * +----------+-----------+------------+
+	 * |    0     |  version  | 0x00000002 |
+	 * +----------+-----------+------------+
+	 * |    4     |  padding  | 0x00000000 |
+	 * +----------+-----------+------------+
+	 * |    8     | plat_data |    NULL    |
+	 * +----------+-----------+------------+
+	 * |    16    | num_banks |            |
+	 * +----------+-----------+            |
+	 * |    24    |   banks   | plat_dram  |
+	 * +----------+-----------+            |
+	 * |    32    | checksum  |            |
+	 * +----------+-----------+------------+
+	 * |    40    |  base 0   |            |
+	 * +----------+-----------+   bank[0]  |
+	 * |    48    |  size 0   |            |
+	 * +----------+-----------+------------+
+	 * |    56    |  base 1   |            |
+	 * +----------+-----------+   bank[1]  |
+	 * |    64    |  size 1   |            |
+	 * +----------+-----------+------------+
+	 */
+	bank_ptr = (struct ns_dram_bank *)
+			((uintptr_t)&manifest->plat_dram.checksum +
+			sizeof(manifest->plat_dram.checksum));
+
+	manifest->plat_dram.banks = bank_ptr;
+
+	/* Calculate checksum of plat_dram structure */
+	checksum = num_banks + (uint64_t)bank_ptr;
+
+	/* Store FVP DRAM banks data in Boot Manifest */
+	for (unsigned long i = 0UL; i < num_banks; i++) {
+		uintptr_t base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base);
+		uint64_t size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size);
+
+		bank_ptr[i].base = base;
+		bank_ptr[i].size = size;
+
+		/* Update checksum */
+		checksum += base + size;
+	}
+
+	/* Checksum must be 0 */
+	manifest->plat_dram.checksum = ~checksum + 1UL;
 
 	return 0;
 }
-
-#endif
+#endif	/* ENABLE_RME */
diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
index ca85f7a..b7a1247 100644
--- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h
+++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,12 +8,16 @@
 #define FCONF_HW_CONFIG_GETTER_H
 
 #include <lib/fconf/fconf.h>
+#include <services/rmm_core_manifest.h>
+
+#include <plat/arm/common/arm_def.h>
 
 /* Hardware Config related getter */
 #define hw_config__gicv3_config_getter(prop) gicv3_config.prop
 #define hw_config__topology_getter(prop) soc_topology.prop
 #define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop
 #define hw_config__cpu_timer_getter(prop) cpu_timer.prop
+#define hw_config__dram_layout_getter(prop) dram_layout.prop
 
 struct gicv3_config_t {
 	uint64_t gicd_base;
@@ -36,13 +40,21 @@
 	uint32_t clock_freq;
 };
 
+struct ns_dram_layout {
+	uint64_t num_banks;
+	struct ns_dram_bank dram_bank[ARM_DRAM_NUM_BANKS];
+};
+
 int fconf_populate_gicv3_config(uintptr_t config);
 int fconf_populate_topology(uintptr_t config);
 int fconf_populate_uart_config(uintptr_t config);
 int fconf_populate_cpu_timer(uintptr_t config);
+int fconf_populate_dram_layout(uintptr_t config);
 
 extern struct gicv3_config_t gicv3_config;
 extern struct hw_topology_t soc_topology;
 extern struct uart_serial_config_t uart_serial_config;
 extern struct cpu_timer_t cpu_timer;
+extern struct ns_dram_layout dram_layout;
+
 #endif /* FCONF_HW_CONFIG_GETTER_H */
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index 85e6e3a..927ffef 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -21,6 +21,7 @@
 fdt     fdt_setprop_inplace
 fdt     fdt_check_header
 fdt     fdt_node_offset_by_compatible
+fdt     fdt_node_offset_by_prop_value
 fdt     fdt_setprop_inplace_namelen_partial
 fdt     fdt_first_subnode
 fdt     fdt_next_subnode
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 02e419a..b142b62 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,16 +18,14 @@
 #include <drivers/partition/partition.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
-#if ENABLE_RME
 #include <lib/gpt_rme/gpt_rme.h>
-#endif /* ENABLE_RME */
 #ifdef SPD_opteed
 #include <lib/optee_utils.h>
 #endif
 #include <lib/utils.h>
 #if ENABLE_RME
 #include <plat/arm/common/arm_pas_def.h>
-#endif /* ENABLE_RME */
+#endif
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -131,7 +129,6 @@
 }
 
 #if ENABLE_RME
-
 static void arm_bl2_plat_gpt_setup(void)
 {
 	/*
@@ -171,7 +168,6 @@
 		panic();
 	}
 }
-
 #endif /* ENABLE_RME */
 
 /*******************************************************************************
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index cf403b1..19efdd3 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -13,9 +13,7 @@
 #include <drivers/console.h>
 #include <lib/debugfs.h>
 #include <lib/extensions/ras.h>
-#if ENABLE_RME
 #include <lib/gpt_rme/gpt_rme.h>
-#endif
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/arm/common/plat_arm.h>
diff --git a/plat/arm/common/trp/arm_trp_setup.c b/plat/arm/common/trp/arm_trp_setup.c
index aeacd10..0406321 100644
--- a/plat/arm/common/trp/arm_trp_setup.c
+++ b/plat/arm/common/trp/arm_trp_setup.c
@@ -26,7 +26,7 @@
  ******************************************************************************/
 static console_t arm_trp_runtime_console;
 
-static int arm_trp_process_manifest(rmm_manifest_t *manifest)
+static int arm_trp_process_manifest(struct rmm_manifest *manifest)
 {
 	/* padding field on the manifest must be RES0 */
 	assert(manifest->padding == 0U);
@@ -38,12 +38,12 @@
 	}
 
 	trp_boot_manifest_version = manifest->version;
-	flush_dcache_range((uintptr_t)manifest, sizeof(rmm_manifest_t));
+	flush_dcache_range((uintptr_t)manifest, sizeof(struct rmm_manifest));
 
 	return 0;
 }
 
-void arm_trp_early_platform_setup(rmm_manifest_t *manifest)
+void arm_trp_early_platform_setup(struct rmm_manifest *manifest)
 {
 	int rc;
 
@@ -66,10 +66,9 @@
 
 	console_set_scope(&arm_trp_runtime_console,
 			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
-
 }
 
-void trp_early_platform_setup(rmm_manifest_t *manifest)
+void trp_early_platform_setup(struct rmm_manifest *manifest)
 {
 	arm_trp_early_platform_setup(manifest);
 }
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index f55cde9..ed7f270 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,7 +35,7 @@
 
 static void versal_print_platform_name(void)
 {
-	NOTICE("ATF running on Xilinx %s\n", PLATFORM_NAME);
+	NOTICE("TF-A running on %s\n", PLATFORM_NAME);
 }
 
 void versal_config_setup(void)
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index c9942d6..a7bae72 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <common/debug.h>
 #include <common/fdt_fixup.h>
 #include <common/fdt_wrappers.h>
+#include <drivers/arm/dcc.h>
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <lib/mmio.h>
@@ -28,7 +29,6 @@
 
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
-static console_t versal_net_runtime_console;
 
 /*
  * Return a pointer to the 'entry_point_info' structure of the next image for
@@ -95,18 +95,30 @@
 		panic();
 	}
 
-	/* Initialize the console to provide early debug support */
-	rc = console_pl011_register(VERSAL_NET_UART_BASE, uart_clock,
+	if (VERSAL_NET_CONSOLE_IS(pl011_0) || VERSAL_NET_CONSOLE_IS(pl011_1)) {
+		static console_t versal_net_runtime_console;
+
+		/* Initialize the console to provide early debug support */
+		rc = console_pl011_register(VERSAL_NET_UART_BASE, uart_clock,
 				    VERSAL_NET_UART_BAUDRATE,
 				    &versal_net_runtime_console);
-	if (rc == 0) {
-		panic();
-	}
+		if (rc == 0) {
+			panic();
+		}
 
-	console_set_scope(&versal_net_runtime_console, CONSOLE_FLAG_BOOT |
-			  CONSOLE_FLAG_RUNTIME);
+		console_set_scope(&versal_net_runtime_console, CONSOLE_FLAG_BOOT |
+				CONSOLE_FLAG_RUNTIME);
+	} else if (VERSAL_NET_CONSOLE_IS(dcc)) {
+		/* Initialize the dcc console for debug.
+		 * dcc is over jtag and does not configures uart0 or uart1.
+		 */
+		rc = console_dcc_register();
+		if (rc == 0) {
+			panic();
+		}
+	}
 
-	NOTICE("TF-A running on Xilinx %s %d.%d\n", board_name_decode(),
+	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
 	       platform_version / 10U, platform_version % 10U);
 
 	/* Initialize the platform config for future decision making */
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index 14e63d5..9d1b7c2 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,7 @@
 #define VERSAL_NET_CONSOLE_ID_pl011	U(1)
 #define VERSAL_NET_CONSOLE_ID_pl011_0	U(1)
 #define VERSAL_NET_CONSOLE_ID_pl011_1	U(2)
+#define VERSAL_NET_CONSOLE_ID_dcc	U(3)
 
 #define VERSAL_NET_CONSOLE_IS(con)	(VERSAL_NET_CONSOLE_ID_ ## con == VERSAL_NET_CONSOLE)
 
@@ -142,12 +143,11 @@
 
 #define VERSAL_NET_UART_BAUDRATE	115200
 
-#if VERSAL_NET_CONSOLE_IS(pl011) || VERSAL_NET_CONSOLE_IS(pl011_0)
-#define VERSAL_NET_UART_BASE		VERSAL_NET_UART0_BASE
-#elif VERSAL_NET_CONSOLE_IS(pl011_1)
+#if VERSAL_NET_CONSOLE_IS(pl011_1)
 #define VERSAL_NET_UART_BASE		VERSAL_NET_UART1_BASE
 #else
-# error "invalid VERSAL_NET_CONSOLE"
+/* Default console is UART0 */
+#define VERSAL_NET_UART_BASE            VERSAL_NET_UART0_BASE
 #endif
 
 #define PLAT_VERSAL_NET_CRASH_UART_BASE		VERSAL_NET_UART_BASE
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index 622ae98..28e3295 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -53,7 +53,7 @@
 HW_ASSISTED_COHERENCY := 1
 
 VERSAL_NET_CONSOLE	?=	pl011
-ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1))
+ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc))
 else
   $(error Please define VERSAL_NET_CONSOLE)
 endif
@@ -72,6 +72,7 @@
 include lib/libfdt/libfdt.mk
 
 PLAT_BL_COMMON_SOURCES	:=	\
+				drivers/arm/dcc/dcc_console.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${GICV3_SOURCES}				\
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 7bdd5bd..30af4d5 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -303,10 +304,10 @@
 	maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
 		 ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
 	if (tmp != maskid) {
-		ERROR("Incorrect XILINX IDCODE 0x%x, maskid 0x%x\n", id, maskid);
+		ERROR("Incorrect IDCODE 0x%x, maskid 0x%x\n", id, maskid);
 		return "UNKN";
 	}
-	VERBOSE("Xilinx IDCODE 0x%x\n", id);
+	VERBOSE("IDCODE 0x%x\n", id);
 	return zynqmp_get_silicon_idcode_name();
 }
 
diff --git a/services/spd/opteed/opteed.mk b/services/spd/opteed/opteed.mk
index 643b054..477b45d 100644
--- a/services/spd/opteed/opteed.mk
+++ b/services/spd/opteed/opteed.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -16,3 +16,19 @@
 
 # required so that optee code can control access to the timer registers
 NS_TIMER_SWITCH		:=	1
+
+# WARNING: This enables loading of OP-TEE via an SMC, which can be potentially
+# insecure. This removes the boundary between the startup of the secure and
+# non-secure worlds until the point where this SMC is invoked. Only use this
+# setting if you can ensure that the non-secure OS can remain trusted up until
+# the point where this SMC is invoked.
+OPTEE_ALLOW_SMC_LOAD		:=	0
+ifeq ($(OPTEE_ALLOW_SMC_LOAD),1)
+ifeq ($(PLAT_XLAT_TABLES_DYNAMIC),0)
+$(error When OPTEE_ALLOW_SMC_LOAD=1, PLAT_XLAT_TABLES_DYNAMIC must also be 1)
+endif
+$(warning "OPTEE_ALLOW_SMC_LOAD is enabled which may result in an insecure \
+	platform")
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+$(eval $(call add_define,OPTEE_ALLOW_SMC_LOAD))
+endif
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 160a693..ff2aee0 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +16,7 @@
  ******************************************************************************/
 #include <assert.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <stddef.h>
 
 #include <arch_helpers.h>
@@ -24,12 +25,13 @@
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/optee_utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <tools_share/uuid.h>
 
 #include "opteed_private.h"
 #include "teesmc_opteed.h"
-#include "teesmc_opteed_macros.h"
 
 /*******************************************************************************
  * Address of the entrypoint vector table in OPTEE. It is
@@ -43,7 +45,16 @@
 optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
 uint32_t opteed_rw;
 
+#if OPTEE_ALLOW_SMC_LOAD
+static bool opteed_allow_load;
+#else
 static int32_t opteed_init(void);
+#endif
+
+uint64_t dual32to64(uint32_t high, uint32_t low)
+{
+	return ((uint64_t)high << 32) | low;
+}
 
 /*******************************************************************************
  * This function is the handler registered for S-EL1 interrupts by the
@@ -93,6 +104,11 @@
  ******************************************************************************/
 static int32_t opteed_setup(void)
 {
+#if OPTEE_ALLOW_SMC_LOAD
+	opteed_allow_load = true;
+	INFO("Delaying OP-TEE setup until we receive an SMC call to load it\n");
+	return 0;
+#else
 	entry_point_info_t *optee_ep_info;
 	uint32_t linear_id;
 	uint64_t opteed_pageable_part;
@@ -142,6 +158,7 @@
 	bl31_register_bl32_init(&opteed_init);
 
 	return 0;
+#endif  /* OPTEE_ALLOW_SMC_LOAD */
 }
 
 /*******************************************************************************
@@ -153,18 +170,12 @@
  * non-secure state. This function performs a synchronous entry into
  * OPTEE. OPTEE passes control back to this routine through a SMC.
  ******************************************************************************/
-static int32_t opteed_init(void)
+static int32_t
+opteed_init_with_entry_point(entry_point_info_t *optee_entry_point)
 {
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
-	entry_point_info_t *optee_entry_point;
 	uint64_t rc;
-
-	/*
-	 * Get information about the OPTEE (BL32) image. Its
-	 * absence is a critical failure.
-	 */
-	optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
 	assert(optee_entry_point);
 
 	cm_init_my_context(optee_entry_point);
@@ -179,7 +190,116 @@
 	return rc;
 }
 
+#if !OPTEE_ALLOW_SMC_LOAD
+static int32_t opteed_init(void)
+{
+	entry_point_info_t *optee_entry_point;
+	/*
+	 * Get information about the OP-TEE (BL32) image. Its
+	 * absence is a critical failure.
+	 */
+	optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
+	return opteed_init_with_entry_point(optee_entry_point);
+}
+#endif  /* !OPTEE_ALLOW_SMC_LOAD */
 
+#if OPTEE_ALLOW_SMC_LOAD
+/*******************************************************************************
+ * This function is responsible for handling the SMC that loads the OP-TEE
+ * binary image via a non-secure SMC call. It takes the size and physical
+ * address of the payload as parameters.
+ ******************************************************************************/
+static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa)
+{
+	uintptr_t data_va = data_pa;
+	uint64_t mapped_data_pa;
+	uintptr_t mapped_data_va;
+	uint64_t data_map_size;
+	int32_t rc;
+	optee_header_t *image_header;
+	uint8_t *image_ptr;
+	uint64_t target_pa;
+	uint64_t target_end_pa;
+	uint64_t image_pa;
+	uintptr_t image_va;
+	optee_image_t *curr_image;
+	uintptr_t target_va;
+	uint64_t target_size;
+	entry_point_info_t optee_ep_info;
+	uint32_t linear_id = plat_my_core_pos();
+
+	mapped_data_pa = page_align(data_pa, DOWN);
+	mapped_data_va = mapped_data_pa;
+	data_map_size = page_align(data_size + (mapped_data_pa - data_pa), UP);
+
+	rc = mmap_add_dynamic_region(mapped_data_pa, mapped_data_va,
+				     data_map_size, MT_MEMORY | MT_RO | MT_NS);
+	if (rc != 0) {
+		return rc;
+	}
+
+	image_header = (optee_header_t *)data_va;
+	if (image_header->magic != TEE_MAGIC_NUM_OPTEE ||
+	    image_header->version != 2 || image_header->nb_images != 1) {
+		mmap_remove_dynamic_region(mapped_data_va, data_map_size);
+		return -EINVAL;
+	}
+
+	image_ptr = (uint8_t *)data_va + sizeof(optee_header_t) +
+			sizeof(optee_image_t);
+	if (image_header->arch == 1) {
+		opteed_rw = OPTEE_AARCH64;
+	} else {
+		opteed_rw = OPTEE_AARCH32;
+	}
+
+	curr_image = &image_header->optee_image_list[0];
+	image_pa = dual32to64(curr_image->load_addr_hi,
+			      curr_image->load_addr_lo);
+	image_va = image_pa;
+	target_end_pa = image_pa + curr_image->size;
+
+	/* Now also map the memory we want to copy it to. */
+	target_pa = page_align(image_pa, DOWN);
+	target_va = target_pa;
+	target_size = page_align(target_end_pa, UP) - target_pa;
+
+	rc = mmap_add_dynamic_region(target_pa, target_va, target_size,
+				     MT_MEMORY | MT_RW | MT_SECURE);
+	if (rc != 0) {
+		mmap_remove_dynamic_region(mapped_data_va, data_map_size);
+		return rc;
+	}
+
+	INFO("Loaded OP-TEE via SMC: size %d addr 0x%" PRIx64 "\n",
+	     curr_image->size, image_va);
+
+	memcpy((void *)image_va, image_ptr, curr_image->size);
+	flush_dcache_range(target_pa, target_size);
+
+	mmap_remove_dynamic_region(mapped_data_va, data_map_size);
+	mmap_remove_dynamic_region(target_va, target_size);
+
+	/* Save the non-secure state */
+	cm_el1_sysregs_context_save(NON_SECURE);
+
+	opteed_init_optee_ep_state(&optee_ep_info,
+				   opteed_rw,
+				   image_pa,
+				   0,
+				   0,
+				   0,
+				   &opteed_sp_context[linear_id]);
+	rc = opteed_init_with_entry_point(&optee_ep_info);
+
+	/* Restore non-secure state */
+	cm_el1_sysregs_context_restore(NON_SECURE);
+	cm_set_next_eret_context(NON_SECURE);
+
+	return rc;
+}
+#endif  /* OPTEE_ALLOW_SMC_LOAD */
+
 /*******************************************************************************
  * This function is responsible for handling all SMCs in the Trusted OS/App
  * range from the non-secure state as defined in the SMC Calling Convention
@@ -207,6 +327,34 @@
 	 */
 
 	if (is_caller_non_secure(flags)) {
+#if OPTEE_ALLOW_SMC_LOAD
+		if (smc_fid == NSSMC_OPTEED_CALL_LOAD_IMAGE) {
+			/*
+			 * TODO: Consider wiping the code for SMC loading from
+			 * memory after it has been invoked similar to what is
+			 * done under RECLAIM_INIT, but extended to happen
+			 * later.
+			 */
+			if (!opteed_allow_load) {
+				SMC_RET1(handle, -EPERM);
+			}
+
+			opteed_allow_load = false;
+			uint64_t data_size = dual32to64(x1, x2);
+			uint64_t data_pa = dual32to64(x3, x4);
+			if (!data_size || !data_pa) {
+				/*
+				 * This is invoked when the OP-TEE image didn't
+				 * load correctly in the kernel but we want to
+				 * block off loading of it later for security
+				 * reasons.
+				 */
+				SMC_RET1(handle, -EINVAL);
+			}
+			SMC_RET1(handle, opteed_handle_smc_load(
+					data_size, data_pa));
+		}
+#endif  /* OPTEE_ALLOW_SMC_LOAD */
 		/*
 		 * This is a fresh request from the non-secure client.
 		 * The parameters are in x1 and x2. Figure out which
@@ -219,8 +367,18 @@
 
 		/*
 		 * We are done stashing the non-secure context. Ask the
-		 * OPTEE to do the work now.
+		 * OP-TEE to do the work now. If we are loading vi an SMC,
+		 * then we also need to init this CPU context if not done
+		 * already.
 		 */
+		if (optee_vector_table == NULL) {
+			SMC_RET1(handle, -EINVAL);
+		}
+
+		if (get_optee_pstate(optee_ctx->state) ==
+		    OPTEE_PSTATE_UNKNOWN) {
+			opteed_cpu_on_finish_handler(0);
+		}
 
 		/*
 		 * Verify if there is a valid context to use, copy the
diff --git a/services/spd/opteed/opteed_pm.c b/services/spd/opteed/opteed_pm.c
index 719eeb7..fa724a1 100644
--- a/services/spd/opteed/opteed_pm.c
+++ b/services/spd/opteed/opteed_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,6 +32,10 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		return 0;
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
@@ -65,6 +69,10 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		return;
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
@@ -92,7 +100,7 @@
  * after initialising minimal architectural state that guarantees safe
  * execution.
  ******************************************************************************/
-static void opteed_cpu_on_finish_handler(u_register_t unused)
+void opteed_cpu_on_finish_handler(u_register_t unused)
 {
 	int32_t rc = 0;
 	uint32_t linear_id = plat_my_core_pos();
@@ -100,7 +108,8 @@
 	entry_point_info_t optee_on_entrypoint;
 
 	assert(optee_vector_table);
-	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_OFF);
+	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_OFF ||
+	       get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN);
 
 	opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw,
 				(uint64_t)&optee_vector_table->cpu_on_entry,
@@ -134,6 +143,10 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		return;
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_SUSPEND);
 
@@ -173,6 +186,14 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	/*
+	 * OP-TEE must have been initialized in order to reach this location so
+	 * it is safe to init the CPU context if not already done for this core.
+	 */
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		opteed_cpu_on_finish_handler(0);
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
@@ -193,6 +214,14 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
+	/*
+	 * OP-TEE must have been initialized in order to reach this location so
+	 * it is safe to init the CPU context if not already done for this core.
+	 */
+	if (get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_UNKNOWN) {
+		opteed_cpu_on_finish_handler(0);
+	}
+
 	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
diff --git a/services/spd/opteed/opteed_private.h b/services/spd/opteed/opteed_private.h
index 242154f..ab6e4cd 100644
--- a/services/spd/opteed/opteed_private.h
+++ b/services/spd/opteed/opteed_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,9 +18,10 @@
  * OPTEE PM state information e.g. OPTEE is suspended, uninitialised etc
  * and macros to access the state information in the per-cpu 'state' flags
  ******************************************************************************/
-#define OPTEE_PSTATE_OFF		0
-#define OPTEE_PSTATE_ON			1
-#define OPTEE_PSTATE_SUSPEND		2
+#define OPTEE_PSTATE_OFF		1
+#define OPTEE_PSTATE_ON			2
+#define OPTEE_PSTATE_SUSPEND		3
+#define OPTEE_PSTATE_UNKNOWN		0
 #define OPTEE_PSTATE_SHIFT		0
 #define OPTEE_PSTATE_MASK		0x3
 #define get_optee_pstate(state)	((state >> OPTEE_PSTATE_SHIFT) & \
@@ -153,6 +154,7 @@
 				uint64_t mem_limit,
 				uint64_t dt_addr,
 				optee_context_t *optee_ctx);
+void opteed_cpu_on_finish_handler(u_register_t unused);
 
 extern optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
 extern uint32_t opteed_rw;
diff --git a/services/spd/opteed/teesmc_opteed.h b/services/spd/opteed/teesmc_opteed.h
index c82b58a..eae3ed2 100644
--- a/services/spd/opteed/teesmc_opteed.h
+++ b/services/spd/opteed/teesmc_opteed.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,8 +9,10 @@
 #ifndef TEESMC_OPTEED_H
 #define TEESMC_OPTEED_H
 
+#include "teesmc_opteed_macros.h"
+
 /*
- * This file specifies SMC function IDs used when returning from TEE to the
+ * This section specifies SMC function IDs used when returning from TEE to the
  * secure monitor.
  *
  * All SMC Function IDs indicates SMC32 Calling Convention but will carry
@@ -120,4 +122,39 @@
 #define TEESMC_OPTEED_RETURN_SYSTEM_RESET_DONE \
 	TEESMC_OPTEED_RV(TEESMC_OPTEED_FUNCID_RETURN_SYSTEM_RESET_DONE)
 
+/*
+ * This section specifies SMC function IDs used when the secure monitor is
+ * invoked from the non-secure world.
+ */
+
+/*
+ * Load OP-TEE image from the payload specified in the registers.
+ *
+ * WARNING: Use this cautiously as it could lead to insecure loading of the
+ * Trusted OS. Further details are in opteed.mk.
+ *
+ * Call register usage:
+ * x0 SMC Function ID, OPTEE_SMC_CALL_LOAD_IMAGE
+ * x1 Upper 32bit of a 64bit size for the payload
+ * x2 Lower 32bit of a 64bit size for the payload
+ * x3 Upper 32bit of the physical address for the payload
+ * x4 Lower 32bit of the physical address for the payload
+ *
+ * The payload consists of a optee_header struct that contains optee_image
+ * structs in a flex array, immediately following that in memory is the data
+ * referenced by the optee_image structs.
+ * Example:
+ *
+ * struct optee_header (with n images specified)
+ * image 0 data
+ * image 1 data
+ * ...
+ * image n-1 data
+ *
+ * Returns 0 on success and an error code otherwise.
+ */
+#define NSSMC_OPTEED_FUNCID_LOAD_IMAGE 2
+#define NSSMC_OPTEED_CALL_LOAD_IMAGE \
+	NSSMC_OPTEED_CALL(NSSMC_OPTEED_FUNCID_LOAD_IMAGE)
+
 #endif /*TEESMC_OPTEED_H*/
diff --git a/services/spd/opteed/teesmc_opteed_macros.h b/services/spd/opteed/teesmc_opteed_macros.h
index 9d8a169..ad3ed75 100644
--- a/services/spd/opteed/teesmc_opteed_macros.h
+++ b/services/spd/opteed/teesmc_opteed_macros.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,4 +14,10 @@
 		 (62 << FUNCID_OEN_SHIFT) | \
 		 ((func_num) & FUNCID_NUM_MASK))
 
+#define NSSMC_OPTEED_CALL(func_num) \
+		((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+		((SMC_32) << FUNCID_CC_SHIFT) | \
+		(50 << FUNCID_OEN_SHIFT) | \
+		((func_num) & FUNCID_NUM_MASK))
+
 #endif /* TEESMC_OPTEED_MACROS_H */
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 6bd9fdf..e12eae7 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -171,7 +171,7 @@
 	uint32_t ep_attr;
 	unsigned int linear_id = plat_my_core_pos();
 	rmmd_rmm_context_t *rmm_ctx = &rmm_context[linear_id];
-	rmm_manifest_t *manifest;
+	struct rmm_manifest *manifest;
 	int rc;
 
 	/* Make sure RME is supported. */
@@ -206,7 +206,7 @@
 					((void *)shared_buf_base != NULL));
 
 	/* Load the boot manifest at the beginning of the shared area */
-	manifest = (rmm_manifest_t *)shared_buf_base;
+	manifest = (struct rmm_manifest *)shared_buf_base;
 	rc = plat_rmmd_load_manifest(manifest);
 	if (rc != 0) {
 		ERROR("Error loading RMM Boot Manifest (%i)\n", rc);
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 196bc11..4eb3e12 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -62,7 +62,7 @@
 			   sizeof(trp_shared_region_start));
 
 	/* Perform early platform-specific setup */
-	trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start);
+	trp_early_platform_setup((struct rmm_manifest *)trp_shared_region_start);
 }
 
 int trp_validate_warmboot_args(uint64_t x0, uint64_t x1,