Merge "fix(build): allow warnings when using lld" into integration
diff --git a/.gitignore b/.gitignore
index 1f4efb6..ab2c0c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,8 @@
 tools/stm32image/stm32image
 tools/stm32image/stm32image.exe
 tools/sptool/__pycache__/
+tools/encrypt_fw/encrypt_fw
+tools/encrypt_fw/encrypt_fw.exe
 
 # GNU GLOBAL files
 GPATH
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 0000000..afcb1f6
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# shellcheck source=./_/husky.sh
+. "$(dirname "$0")/_/husky.sh"
+
+"$(dirname "$0")/pre-commit.copyright" "$@"
diff --git a/.husky/pre-commit.copyright b/.husky/pre-commit.copyright
new file mode 100755
index 0000000..b5087a7
--- /dev/null
+++ b/.husky/pre-commit.copyright
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+# A hook script that checks if files staged for commit have updated Arm copyright year.
+# In case they are not - updates the years and prompts user to add them to the change.
+# This hook is called on "git commit" after changes have been staged, but before commit
+# message has to be provided.
+
+RED="\033[00;31m"
+YELLOW="\033[00;33m"
+BLANK="\033[00;00m"
+
+FILES=`git diff --cached --name-only HEAD`
+YEAR_NOW=`date +"%Y"`
+
+YEAR_RGX="[0-9][0-9][0-9][0-9]"
+ARM_RGX="\(ARM\|Arm\|arm\)"
+
+exit_code=0
+
+function user_warning() {
+	echo -e "Copyright of $RED$FILE$BLANK is out of date"
+	echo -e "Updated copyright to"
+	grep -nr "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE"
+	echo
+}
+
+while read -r FILE; do
+	if [ -z "$FILE" ]
+	then
+		break
+	fi
+	# Check if correct copyright notice is in file.
+	# To reduce false positives, we assume files with no
+	# copyright notice do not require it.
+	if ! grep "opyright.*$YEAR_NOW.*$ARM_RGX" "$FILE">/dev/null 2>&1
+	then
+		# If it is "from_date - to_date" type of entry - change to_date entry.
+		if grep "opyright.*$YEAR_RGX.*-.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
+		then
+			exit_code=1
+			sed -i "s/\(opyright.*\)$YEAR_RGX\(.*$ARM_RGX\)/\1$(date +"%Y")\2/" $FILE
+			user_warning
+		# If it is single "date" type of entry - add the copyright extension to current year.
+		elif grep "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
+		then
+			exit_code=1
+			sed -i "s/\(opyright.*$YEAR_RGX\)\(.*$ARM_RGX\)/\1-$(date +"%Y")\2/" $FILE
+			user_warning
+		fi
+	fi
+done <<< "$FILES"
+
+if [ $exit_code -eq 1 ]
+then
+	echo -e "$RED""Please stage updated files$BLANK before commiting or use$YELLOW git commit --no-verify$BLANK to skip copyright check"
+fi
+exit $exit_code
diff --git a/Makefile b/Makefile
index 8f859fc..5780832 100644
--- a/Makefile
+++ b/Makefile
@@ -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
 #
@@ -153,6 +153,9 @@
 ENABLE_FEAT_ECV = 1
 ENABLE_FEAT_FGT = 1
 
+# RME enables CSV2_2 extension by default.
+ENABLE_FEAT_CSV2_2 = 1
+
 endif
 
 # USE_SPINLOCK_CAS requires AArch64 build
@@ -653,12 +656,16 @@
 ifeq ($(ENABLE_PIE),1)
 ifeq ($(BL2_AT_EL3),1)
 ifneq ($(BL2_IN_XIP_MEM),1)
+	BL2_CPPFLAGS	+=	-fpie
 	BL2_CFLAGS	+=	-fpie
 	BL2_LDFLAGS	+=	$(PIE_LDFLAGS)
 endif
 endif
-	BL31_CFLAGS	+=	-fpie
+	BL31_CPPFLAGS	+=	-fpie
+	BL31_CFLAGS 	+=	-fpie
 	BL31_LDFLAGS	+=	$(PIE_LDFLAGS)
+
+	BL32_CPPFLAGS	+=	-fpie
 	BL32_CFLAGS	+=	-fpie
 	BL32_LDFLAGS	+=	$(PIE_LDFLAGS)
 endif
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index c4ec5fe..124358c 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -5,9 +5,8 @@
  */
 
 /*
- * The .data section gets copied from ROM to RAM at runtime.
- * Its LMA should be 16-byte aligned to allow efficient copying of 16-bytes
- * aligned regions in it.
+ * The .data section gets copied from ROM to RAM at runtime. Its LMA should be
+ * 16-byte aligned to allow efficient copying of 16-bytes aligned regions in it.
  * Its VMA must be page-aligned as it marks the first read/write page.
  */
 #define DATA_ALIGN	16
@@ -24,23 +23,26 @@
     RAM (rwx): ORIGIN = BL1_RW_BASE, LENGTH = BL1_RW_LIMIT - BL1_RW_BASE
 }
 
-SECTIONS
-{
+SECTIONS {
     . = BL1_RO_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL1_RO_BASE address is not aligned on a page boundary.")
+        "BL1_RO_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *bl1_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >ROM
 
-    /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
     .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
     } >ROM
@@ -51,51 +53,57 @@
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         /*
          * No need to pad out the .rodata section to a page boundary. Next is
          * the .data section, which can mapped in ROM with the same memory
          * attributes as the .rodata section.
          *
-         * Pad out to 16 bytes though as .data section needs to be 16 byte
-         * aligned and lld does not align the LMA to the aligment specified
+         * Pad out to 16 bytes though as .data section needs to be 16-byte
+         * aligned and lld does not align the LMA to the alignment specified
          * on the .data section.
          */
         __RODATA_END__ = .;
-         . = ALIGN(16);
+
+        . = ALIGN(16);
     } >ROM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *bl1_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END__ = .;
 
         /*
-         * Pad out to 16 bytes as .data section needs to be 16 byte aligned and
-         * lld does not align the LMA to the aligment specified on the .data
-         * section.
+         * Pad out to 16 bytes as the .data section needs to be 16-byte aligned
+         * and lld does not align the LMA to the alignment specified on the
+         * .data section.
          */
-         . = ALIGN(16);
+        . = ALIGN(16);
     } >ROM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-           "cpu_ops not defined for this platform.")
+        "cpu_ops not defined for this platform.")
 
     . = BL1_RW_BASE;
+
     ASSERT(BL1_RW_BASE == ALIGN(PAGE_SIZE),
-           "BL1_RW_BASE address is not aligned on a page boundary.")
+        "BL1_RW_BASE address is not aligned on a page boundary.")
 
     DATA_SECTION >RAM AT>ROM
+
     __DATA_RAM_START__ = __DATA_START__;
     __DATA_RAM_END__ = __DATA_END__;
 
@@ -105,24 +113,26 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
-     * memory attributes for the coherent data page tables.
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data. This is required to set up the correct memory
+     * attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
     __BL1_RAM_START__ = ADDR(.data);
     __BL1_RAM_END__ = .;
@@ -135,15 +145,16 @@
      * of BL1's actual content in Trusted ROM.
      */
     __BL1_ROM_END__ =  __DATA_ROM_START__ + __DATA_SIZE__;
+
     ASSERT(__BL1_ROM_END__ <= BL1_RO_LIMIT,
-           "BL1's ROM content has exceeded its limit.")
+        "BL1's ROM content has exceeded its limit.")
 
     __BSS_SIZE__ = SIZEOF(.bss);
 
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL1_RW_LIMIT, "BL1's RW section has exceeded its limit.")
 }
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index 9f63fd5..0c43f13 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -29,4 +29,4 @@
 BL1_SOURCES		+=	bl1/bl1_fwu.c
 endif
 
-BL1_LINKERFILE		:=	bl1/bl1.ld.S
+BL1_DEFAULT_LINKER_SCRIPT_SOURCE := bl1/bl1.ld.S
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index 80cf7db..3df8f07 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -15,28 +15,31 @@
     RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
 }
 
-
-SECTIONS
-{
+SECTIONS {
     . = BL2_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2_BASE address is not aligned on a page boundary.")
+        "BL2_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
 #if ENABLE_RME
         *bl2_rme_entrypoint.o(.text*)
 #else /* ENABLE_RME */
         *bl2_entrypoint.o(.text*)
 #endif /* ENABLE_RME */
+
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
-    /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
     .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
     } >RAM
@@ -47,39 +50,41 @@
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *bl2_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     STACK_SECTION >RAM
@@ -88,29 +93,27 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL2_END__ = .;
 
@@ -119,7 +122,7 @@
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
 }
diff --git a/bl2/bl2.mk b/bl2/bl2.mk
index 7a973e5..a18abab 100644
--- a/bl2/bl2.mk
+++ b/bl2/bl2.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -23,12 +23,12 @@
 				bl2/${ARCH}/bl2_el3_exceptions.S	\
 				bl2/${ARCH}/bl2_run_next_image.S	\
 				${GPT_LIB_SRCS}
-BL2_LINKERFILE		:=	bl2/bl2.ld.S
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2.ld.S
 
 else ifeq (${BL2_AT_EL3},0)
 # Normal operation, no RME, no BL2 at EL3
 BL2_SOURCES		+=	bl2/${ARCH}/bl2_entrypoint.S
-BL2_LINKERFILE		:=	bl2/bl2.ld.S
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2.ld.S
 
 else
 # BL2 at EL3, no RME
@@ -46,5 +46,5 @@
 BL2_SOURCES		+=	lib/cpus/aarch64/dsu_helpers.S
 endif
 
-BL2_LINKERFILE		:=	bl2/bl2_el3.ld.S
+BL2_DEFAULT_LINKER_SCRIPT_SOURCE := bl2/bl2_el3.ld.S
 endif
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index c95706c..0c2764e 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -15,140 +15,158 @@
 #if BL2_IN_XIP_MEM
     ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
     RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
-#else
+#else /* BL2_IN_XIP_MEM */
     RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
-#endif
+#endif /* BL2_IN_XIP_MEM */
+
 #if SEPARATE_BL2_NOLOAD_REGION
     RAM_NOLOAD (rw!a): ORIGIN = BL2_NOLOAD_START, LENGTH = BL2_NOLOAD_LIMIT - BL2_NOLOAD_START
-#else
-#define RAM_NOLOAD RAM
-#endif
+#else /* SEPARATE_BL2_NOLOAD_REGION */
+#   define RAM_NOLOAD RAM
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
 }
 
 #if !BL2_IN_XIP_MEM
-#define ROM RAM
-#endif
+#   define ROM RAM
+#endif /* !BL2_IN_XIP_MEM */
 
-SECTIONS
-{
+SECTIONS {
 #if BL2_IN_XIP_MEM
     . = BL2_RO_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2_RO_BASE address is not aligned on a page boundary.")
-#else
+        "BL2_RO_BASE address is not aligned on a page boundary.")
+#else /* BL2_IN_XIP_MEM */
     . = BL2_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2_BASE address is not aligned on a page boundary.")
-#endif
+        "BL2_BASE address is not aligned on a page boundary.")
+#endif /* BL2_IN_XIP_MEM */
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
-	__TEXT_RESIDENT_START__ = .;
-	*bl2_el3_entrypoint.o(.text*)
-	*(.text.asm.*)
-	__TEXT_RESIDENT_END__ = .;
+        __TEXT_RESIDENT_START__ = .;
+
+        *bl2_el3_entrypoint.o(.text*)
+        *(.text.asm.*)
+
+        __TEXT_RESIDENT_END__ = .;
+
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
-     } >ROM
+    } >ROM
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >ROM
 
     ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
-          "Resident part of BL2 has exceeded its limit.")
-#else
+        "Resident part of BL2 has exceeded its limit.")
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
-	__TEXT_RESIDENT_START__ = .;
-	*bl2_el3_entrypoint.o(.text*)
-	*(.text.asm.*)
-	__TEXT_RESIDENT_END__ = .;
+        __TEXT_RESIDENT_START__ = .;
+
+        *bl2_el3_entrypoint.o(.text*)
+        *(.text.asm.*)
+
+        __TEXT_RESIDENT_END__ = .;
+
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
 
         __RO_END__ = .;
     } >ROM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-          "cpu_ops not defined for this platform.")
+        "cpu_ops not defined for this platform.")
 
 #if BL2_IN_XIP_MEM
     . = BL2_RW_BASE;
+
     ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
            "BL2_RW_BASE address is not aligned on a page boundary.")
-#endif
+#endif /* BL2_IN_XIP_MEM */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM AT>ROM
+
     __DATA_RAM_START__ = __DATA_START__;
     __DATA_RAM_END__ = __DATA_END__;
 
     RELA_SECTION >RAM
+
 #if SEPARATE_BL2_NOLOAD_REGION
     SAVED_ADDR = .;
+
     . = BL2_NOLOAD_START;
+
     __BL2_NOLOAD_START__ = .;
-#endif
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
+
     STACK_SECTION >RAM_NOLOAD
     BSS_SECTION >RAM_NOLOAD
     XLAT_TABLE_SECTION >RAM_NOLOAD
+
 #if SEPARATE_BL2_NOLOAD_REGION
     __BL2_NOLOAD_END__ = .;
+
     . = SAVED_ADDR;
-#endif
+#endif /* SEPARATE_BL2_NOLOAD_REGION */
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
+
         *(tzfw_coherent_mem)
+
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL2_END__ = .;
 
@@ -165,23 +183,24 @@
 
     /*
      * The .data section is the last PROGBITS section so its end marks the end
-     * of BL2's RO content in XIP memory..
+     * of BL2's RO content in XIP memory.
      */
     __BL2_ROM_END__ =  __DATA_ROM_START__ + __DATA_SIZE__;
+
     ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
            "BL2's RO content has exceeded its limit.")
-#endif
-    __BSS_SIZE__ = SIZEOF(.bss);
+#endif /* BL2_IN_XIP_MEM */
 
+    __BSS_SIZE__ = SIZEOF(.bss);
 
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
 #if BL2_IN_XIP_MEM
     ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
-#else
+#else /* BL2_IN_XIP_MEM */
     ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
-#endif
+#endif /* BL2_IN_XIP_MEM */
 }
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index a7752a4..0f06dfd 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -17,67 +17,69 @@
     RAM (rwx): ORIGIN = BL2U_BASE, LENGTH = BL2U_LIMIT - BL2U_BASE
 }
 
-
-SECTIONS
-{
+SECTIONS {
     . = BL2U_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL2U_BASE address is not aligned on a page boundary.")
+        "BL2U_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *bl2u_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
-     } >RAM
+    } >RAM
 
-     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
-     .ARM.extab . : {
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
+    .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
-     } >RAM
+    } >RAM
 
-     .ARM.exidx . : {
+    .ARM.exidx . : {
         *(.ARM.exidx* .gnu.linkonce.armexidx.*)
-     } >RAM
+    } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *bl2u_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     STACK_SECTION >RAM
@@ -86,29 +88,27 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL2U_END__ = .;
 
diff --git a/bl2u/bl2u.mk b/bl2u/bl2u.mk
index b4d7634..9f29bde 100644
--- a/bl2u/bl2u.mk
+++ b/bl2u/bl2u.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,4 +12,4 @@
 BL2U_SOURCES		+=	common/aarch64/early_exceptions.S
 endif
 
-BL2U_LINKERFILE		:=	bl2u/bl2u.ld.S
+BL2U_DEFAULT_LINKER_SCRIPT_SOURCE := bl2u/bl2u.ld.S
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 309e752..5d3139b 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -11,137 +11,145 @@
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(bl31_entrypoint)
 
-
 MEMORY {
     RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE
+
 #if SEPARATE_NOBITS_REGION
     NOBITS (rw!a): ORIGIN = BL31_NOBITS_BASE, LENGTH = BL31_NOBITS_LIMIT - BL31_NOBITS_BASE
-#else
-#define NOBITS RAM
-#endif
+#else /* SEPARATE_NOBITS_REGION */
+#   define NOBITS RAM
+#endif /* SEPARATE_NOBITS_REGION */
 }
 
 #ifdef PLAT_EXTRA_LD_SCRIPT
-#include <plat.ld.S>
-#endif
+#   include <plat.ld.S>
+#endif /* PLAT_EXTRA_LD_SCRIPT */
 
-SECTIONS
-{
+SECTIONS {
     . = BL31_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL31_BASE address is not aligned on a page boundary.")
+        "BL31_BASE address is not aligned on a page boundary.")
 
     __BL31_START__ = .;
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *bl31_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(SORT(.text*)))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-#if PLAT_EXTRA_RODATA_INCLUDES
-#include <plat.ld.rodata.inc>
-#endif
+#   if PLAT_EXTRA_RODATA_INCLUDES
+#       include <plat.ld.rodata.inc>
+#   endif /* PLAT_EXTRA_RODATA_INCLUDES */
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *bl31_entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
+
         /*
          * Memory page(s) mapped to this section will be marked as read-only,
-         * executable.  No RW data from the next section must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-           "cpu_ops not defined for this platform.")
+        "cpu_ops not defined for this platform.")
 
 #if SPM_MM
-#ifndef SPM_SHIM_EXCEPTIONS_VMA
-#define SPM_SHIM_EXCEPTIONS_VMA         RAM
-#endif
+#   ifndef SPM_SHIM_EXCEPTIONS_VMA
+#       define SPM_SHIM_EXCEPTIONS_VMA RAM
+#   endif /* SPM_SHIM_EXCEPTIONS_VMA */
 
     /*
      * Exception vectors of the SPM shim layer. They must be aligned to a 2K
-     * address, but we need to place them in a separate page so that we can set
-     * individual permissions to them, so the actual alignment needed is 4K.
+     * address but we need to place them in a separate page so that we can set
+     * individual permissions on them, so the actual alignment needed is the
+     * page size.
      *
      * There's no need to include this into the RO section of BL31 because it
      * doesn't need to be accessed by BL31.
      */
     spm_shim_exceptions : ALIGN(PAGE_SIZE) {
         __SPM_SHIM_EXCEPTIONS_START__ = .;
+
         *(.spm_shim_exceptions)
+
         . = ALIGN(PAGE_SIZE);
+
         __SPM_SHIM_EXCEPTIONS_END__ = .;
     } >SPM_SHIM_EXCEPTIONS_VMA AT>RAM
 
     PROVIDE(__SPM_SHIM_EXCEPTIONS_LMA__ = LOADADDR(spm_shim_exceptions));
+
     . = LOADADDR(spm_shim_exceptions) + SIZEOF(spm_shim_exceptions);
-#endif
+#endif /* SPM_MM */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
 
 #ifdef BL31_PROGBITS_LIMIT
     ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.")
-#endif
+#endif /* BL31_PROGBITS_LIMIT */
 
 #if SEPARATE_NOBITS_REGION
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
     . = ALIGN(PAGE_SIZE);
+
     __RW_END__ = .;
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
 
     . = BL31_NOBITS_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL31 NOBITS base address is not aligned on a page boundary.")
+        "BL31 NOBITS base address is not aligned on a page boundary.")
 
     __NOBITS_START__ = .;
-#endif
+#endif /* SEPARATE_NOBITS_REGION */
 
     STACK_SECTION >NOBITS
     BSS_SECTION >NOBITS
@@ -149,49 +157,44 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
+
         /*
-         * Bakery locks are stored in coherent memory
-         *
-         * Each lock's data is contiguous and fully allocated by the compiler
+         * Bakery locks are stored in coherent memory. Each lock's data is
+         * contiguous and fully allocated by the compiler.
          */
         *(bakery_lock)
         *(tzfw_coherent_mem)
+
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure the rest of
+         * the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >NOBITS
-#endif
+#endif /* USE_COHERENT_MEM */
 
 #if SEPARATE_NOBITS_REGION
-    /*
-     * Define a linker symbol to mark end of the NOBITS memory area for this
-     * image.
-     */
     __NOBITS_END__ = .;
 
     ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.")
-#else
-    /*
-     * Define a linker symbol to mark end of the RW memory area for this
-     * image.
-     */
+#else /* SEPARATE_NOBITS_REGION */
     __RW_END__ = .;
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
-#endif
+#endif /* SEPARATE_NOBITS_REGION */
 
     /DISCARD/ : {
         *(.dynsym .dynstr .hash .gnu.hash)
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index ac15f9f..e6609fe 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -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
 #
@@ -157,7 +157,7 @@
 				${MBEDTLS_SOURCES}
 endif
 
-BL31_LINKERFILE		:=	bl31/bl31.ld.S
+BL31_DEFAULT_LINKER_SCRIPT_SOURCE := bl31/bl31.ld.S
 
 # Flag used to indicate if Crash reporting via console should be included
 # in BL31. This defaults to being present in DEBUG builds only
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 475affa..59e164a 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -16,130 +16,132 @@
 }
 
 #ifdef PLAT_SP_MIN_EXTRA_LD_SCRIPT
-#include <plat_sp_min.ld.S>
-#endif
+#   include <plat_sp_min.ld.S>
+#endif /* PLAT_SP_MIN_EXTRA_LD_SCRIPT */
 
-SECTIONS
-{
+SECTIONS {
     . = BL32_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL32_BASE address is not aligned on a page boundary.")
+        "BL32_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
-     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
-     .ARM.extab . : {
+    /* .ARM.extab and .ARM.exidx are only added because Clang needs them */
+    .ARM.extab . : {
         *(.ARM.extab* .gnu.linkonce.armextab.*)
-     } >RAM
+    } >RAM
 
-     .ARM.exidx . : {
+    .ARM.exidx . : {
         *(.ARM.exidx* .gnu.linkonce.armexidx.*)
-     } >RAM
+    } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *entrypoint.o(.text*)
         *(SORT_BY_ALIGNMENT(.text*))
         *(SORT_BY_ALIGNMENT(.rodata*))
 
-	RODATA_COMMON
+        RODATA_COMMON
 
-        /* Place pubsub sections for events */
         . = ALIGN(8);
-#include <lib/el3_runtime/pubsub_events.h>
+
+#   include <lib/el3_runtime/pubsub_events.h>
 
         *(.vectors)
+
         __RO_END_UNALIGNED__ = .;
 
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure that the rest
+         * of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
-           "cpu_ops not defined for this platform.")
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+        "cpu_ops not defined for this platform.")
+
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
 
 #ifdef BL32_PROGBITS_LIMIT
     ASSERT(. <= BL32_PROGBITS_LIMIT, "BL32 progbits has exceeded its limit.")
-#endif
+#endif /* BL32_PROGBITS_LIMIT */
 
     STACK_SECTION >RAM
     BSS_SECTION >RAM
     XLAT_TABLE_SECTION >RAM
 
-     __BSS_SIZE__ = SIZEOF(.bss);
+    __BSS_SIZE__ = SIZEOF(.bss);
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
+
         /*
-         * Bakery locks are stored in coherent memory
-         *
-         * Each lock's data is contiguous and fully allocated by the compiler
+         * Bakery locks are stored in coherent memory. Each lock's data is
+         * contiguous and fully allocated by the compiler.
          */
         *(bakery_lock)
         *(tzfw_coherent_mem)
+
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure that the rest
+         * of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
 
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark the end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
-
     __BL32_END__ = .;
 
     /DISCARD/ : {
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index ab1287d..b2f4e4c 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -54,7 +54,7 @@
 BL32_SOURCES		+=	lib/extensions/trf/aarch32/trf.c
 endif
 
-BL32_LINKERFILE	:=	bl32/sp_min/sp_min.ld.S
+BL32_DEFAULT_LINKER_SCRIPT_SOURCE := bl32/sp_min/sp_min.ld.S
 
 # Include the platform-specific SP_MIN Makefile
 # If no platform-specific SP_MIN Makefile exists, it means SP_MIN is not supported
diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S
index d86ae55..1e9cb88 100644
--- a/bl32/tsp/tsp.ld.S
+++ b/bl32/tsp/tsp.ld.S
@@ -11,71 +11,73 @@
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(tsp_entrypoint)
 
-
 MEMORY {
     RAM (rwx): ORIGIN = TSP_SEC_MEM_BASE, LENGTH = TSP_SEC_MEM_SIZE
 }
 
-
-SECTIONS
-{
+SECTIONS {
     . = BL32_BASE;
+
     ASSERT(. == ALIGN(PAGE_SIZE),
-           "BL32_BASE address is not aligned on a page boundary.")
+        "BL32_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
+
         *tsp_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
+
         . = ALIGN(PAGE_SIZE);
+
         __TEXT_END__ = .;
     } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
+
         *(.rodata*)
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         . = ALIGN(PAGE_SIZE);
+
         __RODATA_END__ = .;
     } >RAM
-#else
+#else /* SEPARATE_CODE_AND_RODATA */
     ro . : {
         __RO_START__ = .;
+
         *tsp_entrypoint.o(.text*)
         *(.text*)
         *(.rodata*)
 
-	RODATA_COMMON
+        RODATA_COMMON
 
         *(.vectors)
 
         __RO_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked as
-         * read-only, executable.  No RW data from the next section must
-         * creep in.  Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as read-only,
+         * executable. No RW data from the next section must creep in. Ensure
+         * that the rest of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __RO_END__ = .;
     } >RAM
-#endif
+#endif /* SEPARATE_CODE_AND_RODATA */
 
-    /*
-     * Define a linker symbol to mark start of the RW memory area for this
-     * image.
-     */
-    __RW_START__ = . ;
+    __RW_START__ = .;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
 
 #ifdef TSP_PROGBITS_LIMIT
     ASSERT(. <= TSP_PROGBITS_LIMIT, "TSP progbits has exceeded its limit.")
-#endif
+#endif /* TSP_PROGBITS_LIMIT */
 
     STACK_SECTION >RAM
     BSS_SECTION >RAM
@@ -83,29 +85,27 @@
 
 #if USE_COHERENT_MEM
     /*
-     * The base address of the coherent memory section must be page-aligned (4K)
-     * to guarantee that the coherent data are stored on their own pages and
-     * are not mixed with normal data.  This is required to set up the correct
-     * memory attributes for the coherent data page tables.
+     * The base address of the coherent memory section must be page-aligned to
+     * guarantee that the coherent data are stored on their own pages and are
+     * not mixed with normal data. This is required to set up the correct memory
+     * attributes for the coherent data page tables.
      */
     coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
+
         /*
-         * Memory page(s) mapped to this section will be marked
-         * as device memory.  No other unexpected data must creep in.
-         * Ensure the rest of the current memory page is unused.
+         * Memory page(s) mapped to this section will be marked as device
+         * memory. No other unexpected data must creep in. Ensure that the rest
+         * of the current memory page is unused.
          */
         . = ALIGN(PAGE_SIZE);
+
         __COHERENT_RAM_END__ = .;
     } >RAM
-#endif
+#endif /* USE_COHERENT_MEM */
 
-    /*
-     * Define a linker symbol to mark the end of the RW memory area for this
-     * image.
-     */
     __RW_END__ = .;
     __BL32_END__ = .;
 
@@ -114,10 +114,11 @@
     }
 
     __BSS_SIZE__ = SIZEOF(.bss);
+
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
+#endif /* USE_COHERENT_MEM */
 
     ASSERT(. <= BL32_LIMIT, "BL32 image has exceeded its limit.")
 }
diff --git a/bl32/tsp/tsp.mk b/bl32/tsp/tsp.mk
index c31b9b5..cfffbdb 100644
--- a/bl32/tsp/tsp.mk
+++ b/bl32/tsp/tsp.mk
@@ -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
 #
@@ -22,7 +22,7 @@
 				common/aarch64/early_exceptions.S	\
 				lib/locks/exclusive/aarch64/spinlock.S
 
-BL32_LINKERFILE		:=	bl32/tsp/tsp.ld.S
+BL32_DEFAULT_LINKER_SCRIPT_SOURCE := bl32/tsp/tsp.ld.S
 
 # This flag determines if the TSPD initializes BL32 in tspd_init() (synchronous
 # method) or configures BL31 to pass control to BL32 instead of BL33
diff --git a/bl32/tsp/tsp_ffa_main.c b/bl32/tsp/tsp_ffa_main.c
index 2c53977..268d329 100644
--- a/bl32/tsp/tsp_ffa_main.c
+++ b/bl32/tsp/tsp_ffa_main.c
@@ -201,7 +201,7 @@
 	/* Only expecting to be sent memory from NWd so map accordingly. */
 	mem_attrs |= MT_NS;
 
-	for (uint32_t i = 0U; i < composite->address_range_count; i++) {
+	for (int32_t i = 0; i < (int32_t)composite->address_range_count; i++) {
 		size_t size = composite->address_range_array[i].page_count * PAGE_SIZE;
 
 		ptr = (char *) composite->address_range_array[i].address;
@@ -211,7 +211,7 @@
 				size, mem_attrs);
 
 		if (ret != 0) {
-			ERROR("Failed [%u] mmap_add_dynamic_region %u (%lx) (%lx) (%x)!\n",
+			ERROR("Failed [%d] mmap_add_dynamic_region %u (%lx) (%lx) (%x)!\n",
 				i, ret,
 				(uint64_t)composite->address_range_array[i].address,
 				size, mem_attrs);
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 1b065b1..783b660 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -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
  */
@@ -206,9 +206,9 @@
 	assert(cells <= 2U);
 
 	if (cells == 2U)
-		*(uint64_t *)value = cpu_to_fdt64(*(uint64_t *)value);
+		*(fdt64_t *)value = cpu_to_fdt64(*(uint64_t *)value);
 	else
-		*(uint32_t *)value = cpu_to_fdt32(*(uint32_t *)value);
+		*(fdt32_t *)value = cpu_to_fdt32(*(uint32_t *)value);
 
 	len = (int)cells * 4;
 
@@ -392,7 +392,7 @@
  * to a global address with help of various helper functions.
  ******************************************************************************/
 
-static bool fdtw_xlat_hit(const uint32_t *value, int child_addr_size,
+static bool fdtw_xlat_hit(const fdt32_t *value, int child_addr_size,
 		int parent_addr_size, int range_size, uint64_t base_address,
 		uint64_t *translated_addr)
 {
@@ -427,7 +427,7 @@
 				int local_bus, uint64_t base_address)
 {
 	uint64_t translated_addr;
-	const uint32_t *next_entry;
+	const fdt32_t *next_entry;
 	int parent_bus_node, nxlat_entries, length;
 	int self_addr_cells, parent_addr_cells, self_size_cells, ncells_xlat;
 
@@ -460,7 +460,7 @@
 
 	assert(nxlat_entries > 0);
 
-	next_entry = (const uint32_t *)ranges_prop->data;
+	next_entry = (const fdt32_t *)ranges_prop->data;
 
 	/* Iterate over the entries in the "ranges" */
 	for (int i = 0; i < nxlat_entries; i++) {
diff --git a/docs/components/fconf/fconf_properties.rst b/docs/components/fconf/fconf_properties.rst
index 20cc758..3479576 100644
--- a/docs/components/fconf/fconf_properties.rst
+++ b/docs/components/fconf/fconf_properties.rst
@@ -20,7 +20,9 @@
 
 - load-address [mandatory]
     - value type: <u64>
-    - Physical loading base address of the configuration.
+    - Physical loading base address of the configuration. 
+      If secondary-load-address is also provided (see below), then this is the
+      primary load address.
 
 - max-size [mandatory]
     - value type: <u32>
@@ -30,10 +32,11 @@
     - value type: <u32>
     - Image ID of the configuration.
 
-- ns-load-address [optional]
+- secondary-load-address [optional]
     - value type: <u64>
-    - Physical loading base address of the configuration in the non-secure
-      memory.
-      Only needed by those configuration files which require being loaded
-      in secure memory (at load-address) as well as in non-secure memory
-      e.g. HW_CONFIG
+    - A platform uses this physical address to copy the configuration to
+      another location during the boot-flow.
+
+--------------
+
+*Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst
index 2ea8012..919eea5 100644
--- a/docs/components/realm-management-extension.rst
+++ b/docs/components/realm-management-extension.rst
@@ -13,7 +13,7 @@
 The following diagram shows an Arm CCA software architecture with TF-A as the
 EL3 firmware. In the Arm CCA architecture there are two additional security
 states and address spaces: ``Root`` and ``Realm``. TF-A firmware runs in the
-Root world. In the realm world, a Realm Management Monitor firmware (RMM)
+Root world. In the realm world, a Realm Management Monitor firmware (`RMM`_)
 manages the execution of Realm VMs and their interaction with the hypervisor.
 
 .. image:: ../resources/diagrams/arm-cca-software-arch.png
@@ -44,7 +44,7 @@
 In a typical TF-A boot flow, BL2 runs at Secure-EL1. However when RME is
 enabled, TF-A runs in the Root world at EL3. Therefore, the boot flow is
 modified to run BL2 at EL3 when RME is enabled. In addition to this, a
-Realm-world firmware (RMM) is loaded by BL2 in the Realm physical address
+Realm-world firmware (`RMM`_) is loaded by BL2 in the Realm physical address
 space.
 
 The boot flow when RME is enabled looks like the following:
@@ -70,57 +70,85 @@
 RMM Dispatcher (RMMD)
 ************************
 RMMD is a new standard runtime service that handles the switch to the Realm
-world. It initializes the RMM and handles Realm Management Interface (RMI)
-SMC calls from Non-secure and Realm worlds.
+world. It initializes the `RMM`_ and handles Realm Management Interface (RMI)
+SMC calls from Non-secure.
 
-There is a contract between RMM and RMMD that defines the arguments that the
+There is a contract between `RMM`_ and RMMD that defines the arguments that the
 former needs to take in order to initialize and also the possible return values.
-This contract is defined in the RMM Boot Interface, which can be found at
+This contract is defined in the `RMM`_ Boot Interface, which can be found at
 :ref:`rmm_el3_boot_interface`.
 
 There is also a specification of the runtime services provided by TF-A
-to RMM. This can be found at :ref:`runtime_services_and_interface`.
+to `RMM`_. This can be found at :ref:`runtime_services_and_interface`.
 
 Test Realm Payload (TRP)
 *************************
 TRP is a small test payload that runs at R-EL2 and implements a subset of
 the Realm Management Interface (RMI) commands to primarily test EL3 firmware
 and the interface between R-EL2 and EL3. When building TF-A with RME enabled,
-if a path to an RMM image is not provided, TF-A builds the TRP by default
-and uses it as RMM image.
+if the path to an RMM image is not provided, TF-A builds the TRP by default
+and uses it as the R-EL2 payload.
 
 Building and running TF-A with RME
-------------------------------------
+----------------------------------
 
 This section describes how you can build and run TF-A with RME enabled.
-We assume you have all the :ref:`Prerequisites` to build TF-A.
+We assume you have read the :ref:`Prerequisites` to build TF-A.
 
 The following instructions show you how to build and run TF-A with RME
-for two scenarios:
+on FVP for two scenarios:
 
-- Three-world execution: TF-A with TF-A Tests or Linux.
+- Three-world execution:  This is the configuration to use if Secure
+  world functionality is not needed. TF-A is tested with the following
+  software entities in each world as listed below:
 
-  - NS (TF-A Test or Linux),
+  - NS Host (RME capable Linux or TF-A Tests),
   - Root (TF-A)
-  - Realm (RMM or TRP)
+  - R-EL2 (`RMM`_ or TRP)
 
-- Four-world execution: TF-A, Hafnium and TF-A Tests or Linux.
+- Four-world execution: This is the configuration to use if both Secure
+  and Realm world functionality is needed. TF-A is tested with the following
+  software entities in each world as listed below:
 
-  - NS (TF-A Test or Linux),
+  - NS Host (RME capable Linux or TF-A Tests),
   - Root (TF-A)
-  - Realm (RMM or TRP)
-  - SPM (Hafnium)
+  - R-EL2 (`RMM`_ or TRP)
+  - S-EL2 (Hafnium SPM)
 
 To run the tests, you need an FVP model. Please use the :ref:`latest version
-<Arm Fixed Virtual Platforms (FVP)>` of *FVP_Base_RevC-2xAEMvA* model.
+<Arm Fixed Virtual Platforms (FVP)>` of *FVP_Base_RevC-2xAEMvA* model. If NS
+Host is Linux, then the below instructions assume that a suitable RME enabled
+kernel image and associated root filesystem are available.
 
-Three World Testing with TF-A Tests
-*************************************
+Three-world execution
+*********************
 
-**1. Obtain and build TF-A Tests with Realm Payload**
+**1. Clone and build RMM Image**
 
-The full set of instructions to setup build host and build options for
-TF-A-Tests can be found in the `TFTF Getting Started`_.
+Please refer to the `RMM Getting Started`_ on how to setup
+Host Environment and build `RMM`_. The build commands assume that
+an AArch64 toolchain and CMake executable are available in the
+shell PATH variable and CROSS_COMPILE variable has been setup
+appropriately.
+
+To clone `RMM`_ and build using the default build options for FVP:
+
+.. code:: shell
+
+ git clone --recursive https://git.trustedfirmware.org/TF-RMM/tf-rmm.git
+ cd tf-rmm
+ cmake -DRMM_CONFIG=fvp_defcfg -S . -B build
+ cmake --build build
+
+This will generate **rmm.img** in **build/Release** folder.
+
+**2. Clone and build TF-A Tests with Realm Payload**
+
+This step is only needed if NS Host is TF-A Tests. The full set
+of instructions to setup build host and build options for
+TF-A-Tests can be found in the `TFTF Getting Started`_. TF-A Tests
+can test Realm world with either `RMM`_ or TRP in R-EL2. In the TRP case,
+some tests which are not applicable will be skipped.
 
 Use the following instructions to build TF-A with `TF-A Tests`_ as the
 non-secure payload (BL33).
@@ -134,37 +162,23 @@
 This produces a TF-A Tests binary (**tftf.bin**) with Realm payload packaged
 and **sp_layout.json** in the **build/fvp/debug** directory.
 
-**2. Obtain and build RMM Image**
-
-Please refer to the `RMM Getting Started`_ on how to setup
-Host Environment and build RMM.
-
-The below command shows how to build RMM using the default build options for FVP.
-
-.. code:: shell
-
- git clone --recursive https://git.trustedfirmware.org/TF-RMM/tf-rmm.git
- cd tf-rmm
- cmake -DRMM_CONFIG=fvp_defcfg -S . -B build
- cmake --build build
-
-This will generate **rmm.img** in **build** folder.
 
-**3. Build TF-A**
+**3. Build RME Enabled TF-A**
 
 The `TF-A Getting Started`_ has the necessary instructions to setup Host
 machine and build TF-A.
 
 To build for RME, set ``ENABLE_RME`` build option to 1 and provide the path to
-the RMM binary using the ``RMM`` build option.
-Currently, this feature is only supported for the FVP platform.
+the `RMM`_ binary ``rmm.img`` using ``RMM`` build option.
 
 .. note::
 
  ENABLE_RME build option is currently experimental.
 
+.. note::
+
-If the ``RMM`` option is not used, then the Test Realm Payload (TRP) in TF-A
-will be built and used as the RMM.
+ If the ``RMM`` option is not specified, TF-A builds the TRP to load and
+ run at R-EL2.
 
 .. code:: shell
 
@@ -176,16 +190,42 @@
  RMM=<path/to/rmm.img> \
  FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
  DEBUG=1 \
- BL33=<path/to/tftf.bin> \
+ BL33=<path/to/bl33> \
+ all fip
+
+``BL33`` can point to a Non Secure Bootloader like UEFI/U-Boot or
+the TF-A Tests binary(**tftf.bin**) from the previous step.
+
+This produces **bl1.bin** and **fip.bin** binaries in the **build/fvp/debug**
+directory.
+
+TF-A can also directly boot Linux kernel on the FVP. The kernel needs to be
+`preloaded` to a suitable memory location and this needs to be specified via
+``PRELOADED_BL33_BASE`` build option. Also TF-A should implement the Linux
+kernel register conventions for boot and this can be set using the
+``ARM_LINUX_KERNEL_AS_BL33`` option.
+
+.. code-block:: shell
+
+ cd trusted-firmware-a
+ make CROSS_COMPILE=aarch64-none-elf- \
+ PLAT=fvp \
+ ENABLE_RME=1 \
+ RMM=<path/to/rmm.img> \
+ FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
+ DEBUG=1 \
+ ARM_LINUX_KERNEL_AS_BL33=1 \
+ PRELOADED_BL33_BASE=0x84000000 \
  all fip
 
+The above command assumes that the Linux kernel will be placed in FVP
+memory at 0x84000000 via suitable FVP option (see the next step).
+
-This produces **bl1.bin** and **fip.bin** binaries in the **build/fvp/debug** directory.
+.. _fvp_3_world_cmd:
 
-Running the tests for a 3 world FVP setup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+**4. Running FVP for 3 world setup**
 
-Use the following command to run the tests on FVP. TF-A Tests should boot
-and run the default tests including Realm world tests.
+Use the following command to run the tests on FVP.
 
 .. code:: shell
 
@@ -239,12 +279,33 @@
  -C cluster1.restriction_on_speculative_execution_aarch32=2     \
  -C pctl.startup=0.0.0.0                                        \
  -C bp.smsc_91c111.enabled=1                                    \
- -C bp.hostbridge.userNetworking=1
+ -C bp.hostbridge.userNetworking=1                              \
+ -C bp.virtioblockdevice.image_path=<path/to/rootfs.ext4>
 
-The bottom of the output from *uart0* should look something like the following.
+The ``bp.virtioblockdevice.image_path`` option presents the rootfs as a
+virtio block device to Linux kernel. It can be ignored if NS Host is
+TF-A-Tests or rootfs is accessed by some other mechanism.
+
+If TF-A was built to expect a preloaded Linux kernel, then use the following
+FVP argument to load the kernel image at the expected address.
 
 .. code-block:: shell
 
+ --data cluster0.cpu0=<path_to_kernel_Image>@0x84000000         \
+
+
+.. tip::
+ Tips to boot and run Linux faster on the FVP :
+  1. Set the FVP option ``cache_state_modelled`` to 0.
+  2. Disable the CPU Idle driver in Linux either by setting the kernel command line
+     parameter "cpuidle.off=1" or by disabling the ``CONFIG_CPU_IDLE`` kernel config.
+
+If the NS Host is TF-A-Tests, then the default test suite in TFTF
+will execute on the FVP and this includes Realm world tests. The
+tail of the output from *uart0* should look something like the following.
+
+.. code-block:: shell
+
  ...
 
  > Test suite 'FF-A Interrupt'
@@ -263,52 +324,19 @@
                                                                 Passed
  ...
 
-Building TF-A with RME enabled Linux Kernel
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If an RME enabled Linux kernel and filesystem is available for testing,
-and a suitable NS boot loader is not available, then this option can be used to
-launch kernel directly after BL31:
-
-.. code-block:: shell
-
- cd trusted-firmware-a
- make CROSS_COMPILE=aarch64-none-elf- \
- PLAT=fvp \
- ENABLE_RME=1 \
- RMM=<path/to/rmm.img> \
- FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
- DEBUG=1 \
- ARM_LINUX_KERNEL_AS_BL33=1 \
- PRELOADED_BL33_BASE=0x84000000 \
- all fip
-
-Boot and run the RME enabled Linux Kernel
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Use the following additional arguments to boot the kernel on FVP.
-
-.. code-block:: shell
-
- --data cluster0.cpu0=<path_to_kernel_Image>@0x84000000         \
- -C bp.virtioblockdevice.image_path=<path_to_rootfs.ext4>
-
-.. tip::
-
- Set the FVP option `cache_state_modelled=0` to run Linux based tests much faster.
-
-Four-world execution with Hafnium and TF-A Tests
-*************************************************
+Four-world execution
+********************
 
 Four-world execution involves software components in each security state: root,
 secure, realm and non-secure. This section describes how to build TF-A
 with four-world support.
 
-We use TF-A as the root firmware, `Hafnium SPM`_ is the reference Secure world component
-and the software components for the other 2 worlds (Realm and Non-Secure)
-are as described in the previous section.
+We use TF-A as the root firmware, `Hafnium SPM`_ is the reference Secure world
+component running at S-EL2. `RMM`_ can be built as described in previous
+section. The examples below assume TF-A-Tests as the NS Host and utilize SPs
+from TF-A-Tests.
 
-**1. Obtain and build Hafnium**
+**1. Obtain and build Hafnium SPM**
 
 .. code:: shell
 
@@ -342,11 +370,12 @@
 The Hafnium binary should be located at
 *out/reference/secure_aem_v8a_fvp_clang/hafnium.bin*
 
-**2. Build TF-A**
+**2. Build RME enabled TF-A with SPM**
 
 Build TF-A with RME as well as SPM enabled.
 
-Use sp_layout.json previously generated in tf-a-test build.
+Use the ``sp_layout.json`` previously generated in TF-A Tests
+build to run SP tests.
 
 .. code:: shell
 
@@ -355,7 +384,6 @@
  ENABLE_RME=1 \
  FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
  SPD=spmd \
- SPMD_SPM_AT_SEL2=1 \
  BRANCH_PROTECTION=1 \
  CTX_INCLUDE_PAUTH_REGS=1 \
  DEBUG=1 \
@@ -365,11 +393,11 @@
  RMM=<path/to/rmm.img> \
  all fip
 
-Running the tests for a 4 world FVP setup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+**3. Running the FVP for a 4 world setup**
 
-Use the following arguments in addition to
-`Running the tests for a 3 world FVP setup`_ to run tests for 4 world setup.
+Use the following arguments in addition to the FVP options mentioned in
+:ref:`4. Running FVP for 3 world setup <fvp_3_world_cmd>` to run tests for
+4 world setup.
 
 .. code:: shell
 
@@ -388,4 +416,5 @@
 .. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io/en/latest
 .. _TFTF Getting Started: https://trustedfirmware-a-tests.readthedocs.io/en/latest/getting_started/index.html
 .. _Hafnium SPM: https://www.trustedfirmware.org/projects/hafnium
-.. _RMM Getting Started: https://git.trustedfirmware.org/TF-RMM/tf-rmm.git/tree/docs/getting_started/index.rst
+.. _RMM Getting Started: https://tf-rmm.readthedocs.io/en/latest/getting_started/index.html
+.. _RMM: https://www.trustedfirmware.org/projects/tf-rmm/
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/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 8a8445d..9db29e6 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -321,6 +321,10 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
    it is still open.
 
+-  ``ERRATA_A78_2779479``: This applies erratum 2779479 workaround to Cortex-A78
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 and
+   it is still open.
+
 For Cortex-A78 AE, the following errata build flags are defined :
 
 - ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to
@@ -357,6 +361,10 @@
   Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
   erratum is still open.
 
+- ``ERRATA_A78C_2772121`` : This applies errata 2772121 workaround to
+  Cortex-A78C CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2.
+  This erratum is still open.
+
 For Cortex-X1 CPU, the following errata build flags are defined:
 
 - ``ERRATA_X1_1821534`` : This applies errata 1821534 workaround to Cortex-X1
@@ -468,6 +476,10 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 of the
    CPU. It is still open.
 
+-  ``ERRATA_V1_2779461``: This applies erratum 2779461 workaround to Neoverse-V1
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, r1p2 of the
+   CPU. It is still open.
+
 For Cortex-A710, the following errata build flags are defined :
 
 -  ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -661,7 +673,7 @@
    Cortex-A510 CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2,
    r0p3 and r1p0, it is fixed in r1p1.
 
-- ``ERRATA_A510_2347730``: This applies errata 2347730 workaround to
+-  ``ERRATA_A510_2347730``: This applies errata 2347730 workaround to
    Cortex-A510 CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2,
    r0p3, r1p0 and r1p1. It is fixed in r1p2.
 
@@ -673,6 +685,10 @@
    Cortex-A510 CPU. This needs to applied for revisions r0p0, r0p1, r0p2,
    r0p3, r1p0, r1p1. It is fixed in r1p2.
 
+-  ``ERRATA_A510_2684597``: This applies erratum 2684597 workaround to
+   Cortex-A510 CPU. This needs to be applied to revision r0p0, r0p1, r0p2,
+   r0p3, r1p0, r1p1 and r1p2. It is fixed in r1p3.
+
 DSU Errata Workarounds
 ----------------------
 
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index 3e20c07..3d82e69 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -9,6 +9,7 @@
    context_mgmt_rework
    measured_boot_poc
    drtm_poc
+   rss
 
 --------------
 
diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst
index 3ae539b..2e25057 100644
--- a/docs/design_documents/measured_boot_poc.rst
+++ b/docs/design_documents/measured_boot_poc.rst
@@ -6,7 +6,7 @@
 security state can be attested later.
 
 The current implementation of the driver included in Trusted Firmware-A
-(TF-A) stores the measurements into a `TGC event log`_ in secure
+(TF-A) stores the measurements into a `TCG event log`_ in secure
 memory. No other means of recording measurements (such as a discrete TPM) is
 supported right now.
 
@@ -24,7 +24,7 @@
    platforms might have different needs and configurations (e.g. different
    SHA algorithms) and they might also use different types of TPM services
    (or even a different type of service to provide the attestation)
-   and therefore the instuctions given here might not apply in such scenarios.
+   and therefore the instructions given here might not apply in such scenarios.
 
 Components
 ~~~~~~~~~~
@@ -497,11 +497,11 @@
 
 --------------
 
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
 
 .. _OP-TEE Toolkit: https://github.com/OP-TEE/build
 .. _ms-tpm-20-ref: https://github.com/microsoft/ms-tpm-20-ref
 .. _Get and build the solution: https://optee.readthedocs.io/en/latest/building/gits/build.html#get-and-build-the-solution
 .. _Armv8-A Foundation Platform (For Linux Hosts Only): https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models
 .. _tpm2-tools: https://github.com/tpm2-software/tpm2-tools
-.. _TGC event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/
+.. _TCG event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/
diff --git a/docs/design_documents/rss.rst b/docs/design_documents/rss.rst
new file mode 100644
index 0000000..2be8067
--- /dev/null
+++ b/docs/design_documents/rss.rst
@@ -0,0 +1,611 @@
+Runtime Security Subsystem (RSS)
+================================
+
+This document focuses on the relationship between the Runtime Security Subsystem
+(RSS) and the application processor (AP). According to the ARM reference design
+the RSS is an independent core next to the AP and the SCP on the same die. It
+provides fundamental security guarantees and runtime services for the rest of
+the system (e.g.: trusted boot, measured boot, platform attestation,
+key management, and key derivation).
+
+At power up RSS boots first from its private ROM code. It validates and loads
+its own images and the initial images of SCP and AP. When AP and SCP are
+released from reset and their initial code is loaded then they continue their
+own boot process, which is the same as on non-RSS systems. Please refer to the
+``RSS documentation`` [1]_ for more details about the RSS boot flow.
+
+The last stage of the RSS firmware is a persistent, runtime component. Much
+like AP_BL31, this is a passive entity which has no periodical task to do and
+just waits for external requests from other subsystems. RSS and other
+subsystems can communicate with each other over message exchange. RSS waits
+in idle for the incoming request, handles them, and sends a response then goes
+back to idle.
+
+RSS communication layer
+-----------------------
+
+The communication between RSS and other subsystems are primarily relying on the
+Message Handling Unit (MHU) module. The number of MHU interfaces between RSS
+and other cores is IMPDEF. Besides MHU other modules also could take part in
+the communication. RSS is capable of mapping the AP memory to its address space.
+Thereby either RSS core itself or a DMA engine if it is present, can move the
+data between memory belonging to RSS or AP. In this way, a bigger amount of data
+can be transferred in a short time.
+
+The MHU comes in pairs. There is a sender and receiver side. They are connected
+to each other. An MHU interface consists of two pairs of MHUs, one sender and
+one receiver on both sides. Bidirectional communication is possible over an
+interface. One pair provides message sending from AP to RSS and the other pair
+from RSS to AP. The sender and receiver are connected via channels. There is an
+IMPDEF number of channels (e.g: 4-16) between a sender and a receiver module.
+
+The RSS communication layer provides two ways for message exchange:
+
+- ``Embedded messaging``: The full message, including header and payload, are
+  exchanged over the MHU channels. A channel is capable of delivering a single
+  word. The sender writes the data to the channel register on its side and the
+  receiver can read the data from the channel on the other side. One dedicated
+  channel is used for signalling. It does not deliver any payload it is just
+  meant for signalling that the sender loaded the data to the channel registers
+  so the receiver can read them. The receiver uses the same channel to signal
+  that data was read. Signalling happens via IRQ. If the message is longer than
+  the data fit to the channel registers then the message is sent over in
+  multiple rounds. Both, sender and receiver allocate a local buffer for the
+  messages. Data is copied from/to these buffers to/from the channel registers.
+- ``Pointer-access messaging``: The message header and the payload are
+  separated and they are conveyed in different ways. The header is sent
+  over the channels, similar to the embedded messaging but the payload is
+  copied over by RSS core (or by DMA) between the sender and the receiver. This
+  could be useful in the case of long messages because transaction time is less
+  compared to the embedded messaging mode. Small payloads are copied by the RSS
+  core because setting up DMA would require more CPU cycles. The payload is
+  either copied into an internal buffer or directly read-written by RSS. Actual
+  behavior depends on RSS setup, whether the partition supports memory-mapped
+  ``iovec``. Therefore, the sender must handle both cases and prevent access to
+  the memory, where payload data lives, while the RSS handles the request.
+
+The RSS communication layer supports both ways of messaging in parallel. It is
+decided at runtime based on the message size which way to transfer the message.
+
+.. code-block:: bash
+
+    +----------------------------------------------+       +-------------------+
+    |                                              |       |                   |
+    |                      AP                      |       |                   |
+    |                                              |  +--->|       SRAM        |
+    +----------------------------------------------|  |    |                   |
+    |              BL1 / BL2 / BL31                |  |    |                   |
+    +----------------------------------------------+  |    +-------------------+
+             |                           ^            |        ^           ^
+             |  send                 IRQ | receive    |direct  |           |
+             V                           |            |access  |           |
+    +--------------------+    +--------------------+  |        |           |
+    |      MHU sender    |    |    MHU receiver    |  |        | Copy data |
+    +--------------------+    +--------------------+  |        |           |
+       | |           | |          | |           | |   |        |           |
+       | | channels  | |          | | channels  | |   |        |           |
+       | | e.g: 4-16 | |          | | e.g: 4-16 | |   |        V           |
+    +--------------------+    +--------------------+  |    +-------+       |
+    |     MHU receiver   |    |     MHU sender     |  | +->|  DMA  |       |
+    +--------------------+    +--------------------+  | |  +-------+       |
+             |                           ^            | |      ^           |
+        IRQ  |  receive                  | send       | |      | Copy data |
+             V                           |            | |      V           V
+    +----------------------------------------------+  | |  +-------------------+
+    |                                              |--+-+  |                   |
+    |                  RSS                         |       |      SRAM         |
+    |                                              |       |                   |
+    +----------------------------------------------+       +-------------------+
+
+.. Note::
+
+    The RSS communication layer is not prepared for concurrent execution. The
+    current use case only requires message exchange during the boot phase. In
+    the boot phase, only a single core is running and the rest of the cores are
+    in reset.
+
+Message structure
+^^^^^^^^^^^^^^^^^
+A description of the message format can be found in the ``RSS communication
+design`` [2]_ document.
+
+Source files
+^^^^^^^^^^^^
+- RSS comms:  ``drivers/arm/rss``
+- MHU driver: ``drivers/arm/mhu``
+
+
+API for communication over MHU
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The API is defined in these header files:
+
+- ``include/drivers/arm/rss_comms.h``
+- ``include/drivers/arm/mhu.h``
+
+RSS provided runtime services
+-----------------------------
+
+RSS provides the following runtime services:
+
+- ``Measured boot``: Securely store the firmware measurements which were
+  computed during the boot process and the associated metadata (image
+  description, measurement algorithm, etc.). More info on measured boot service
+  in RSS can be found in the ``measured_boot_integration_guide`` [3]_ .
+- ``Delegated attestation``: Query the platform attestation token and derive a
+  delegated attestation key. More info on the delegated attestation service
+  in RSS can be found in the ``delegated_attestation_integration_guide`` [4]_ .
+- ``OTP assets management``: RSS provides access for AP to assets in OTP.
+  These are keys for image signature verification and non-volatile counters
+  for anti-rollback protection. Only RSS has direct access to the OTP. Public
+  keys used by AP during the trusted boot process can be requested from RSS.
+  Furthermore, AP can request RSS to increase a non-volatile counter. Please
+  refer to the ``RSS key management`` [5]_ document for more details.
+
+Runtime service API
+^^^^^^^^^^^^^^^^^^^
+The RSS provided runtime services implement a PSA aligned API. The parameter
+encoding follows the PSA client protocol described in the
+``Firmware Framework for M`` [6]_ document in chapter 4.4. The implementation is
+restricted to the static handle use case therefore only the ``psa_call`` API is
+implemented.
+
+
+Software and API layers
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+    +----------------+         +---------------------+
+    |   BL1 / BL2    |         |       BL31          |
+    +----------------+         +---------------------+
+      |                         |
+      | extend_measurement()    | get_delegated_key()
+      |                         | get_platform_token()
+      V                         V
+    +----------------+         +---------------------+
+    |  PSA protocol  |         |    PSA protocol     |
+    +----------------+         +---------------------+
+         |                               |
+         | psa_call()                    | psa_call()
+         |                               |
+         V                               V
+    +------------------------------------------------+
+    |         RSS communication protocol             |
+    +------------------------------------------------+
+         |                     ^
+         | mhu_send_data()     | mhu_receive_data()
+         |                     |
+         V                     |
+    +------------------------------------------------+
+    |                 MHU driver                     |
+    +------------------------------------------------+
+               |                      ^
+               | Register access      | IRQ
+               V                      |
+    +------------------------------------------------+
+    |             MHU HW on AP side                  |
+    +------------------------------------------------+
+                         ^
+                         | Physical wires
+                         |
+                         V
+    +------------------------------------------------+
+    |             MHU HW on RSS side                 |
+    +------------------------------------------------+
+             |                        ^
+             | IRQ                    | Register access
+             V                        |
+    +------------------------------------------------+
+    |                 MHU driver                     |
+    +------------------------------------------------+
+             |                        |
+             V                        V
+    +---------------+       +------------------------+
+    | Measured boot |       | Delegated attestation  |
+    | service       |       | service                |
+    +---------------+       +------------------------+
+
+
+RSS based Measured Boot
+-----------------------
+
+Measured Boot is the process of cryptographically measuring (computing the hash
+value of a binary) the code and critical data used at boot time. The
+measurement must be stored in a tamper-resistant way, so the security state
+of the device can be attested later to an external party. RSS provides a runtime
+service which is meant to store measurements and associated metadata alongside.
+
+Data is stored in internal SRAM which is only accessible by the secure runtime
+firmware of RSS. Data is stored in so-called measurement slots. A platform has
+IMPDEF number of measurement slots. The measurement storage follows extend
+semantics. This means that measurements are not stored directly (as it was
+taken) instead they contribute to the current value of the measurement slot.
+The extension implements this logic, where ``||`` stands for concatenation:
+
+.. code-block:: bash
+
+    new_value_of_measurement_slot = Hash(old_value_of_measurement_slot || measurement)
+
+Supported hash algorithms: sha-256, sha-512
+
+Measured Boot API
+^^^^^^^^^^^^^^^^^
+
+Defined here:
+
+- ``include/lib/psa/measured_boot.h``
+
+.. code-block:: c
+
+    psa_status_t
+    rss_measured_boot_extend_measurement(uint8_t        index,
+                                         const uint8_t *signer_id,
+                                         size_t         signer_id_size,
+                                         const uint8_t *version,
+                                         size_t         version_size,
+                                         uint32_t       measurement_algo,
+                                         const uint8_t *sw_type,
+                                         size_t         sw_type_size,
+                                         const uint8_t *measurement_value,
+                                         size_t         measurement_value_size,
+                                         bool           lock_measurement);
+
+Measured Boot Metadata
+^^^^^^^^^^^^^^^^^^^^^^
+
+The following metadata can be stored alongside the measurement:
+
+- ``Signer-id``: Mandatory. The hash of the firmware image signing public key.
+- ``Measurement algorithm``: Optional. The hash algorithm which was used to
+  compute the measurement (e.g.: sha-256, etc.).
+- ``Version info``: Optional. The firmware version info (e.g.: 2.7).
+- ``SW type``: Optional. Short text description (e.g.: BL1, BL2, BL31, etc.)
+
+.. Note::
+    Signer-id and version info is not implemented in TF-A yet.
+
+The caller must specify in which measurement slot to extend a certain
+measurement and metadata. A measurement slot can be extended by multiple
+measurements. The default value is IMPDEF. All measurement slot is cleared at
+reset, there is no other way to clear them. In the reference implementation,
+the measurement slots are initialized to 0. At the first call to extend the
+measurement in a slot, the extend operation uses the default value of the
+measurement slot. All upcoming extend operation on the same slot contributes
+to the previous value of that measurement slot.
+
+The following rules are kept when a slot is extended multiple times:
+
+- ``Signer-id`` must be the same as the previous call(s), otherwise a
+  PSA_ERROR_NOT_PERMITTED error code is returned.
+
+- ``Measurement algorithm``: must be the same as the previous call(s),
+  otherwise, a PSA_ERROR_NOT_PERMITTED error code is returned.
+
+In case of error no further action is taken (slot is not locked). If there is
+a valid data in a sub-sequent call then measurement slot will be extended. The
+rest of the metadata is handled as follows when a measurement slot is extended
+multiple times:
+
+- ``SW type``: Cleared.
+- ``Version info``: Cleared.
+
+.. Note::
+
+    Extending multiple measurements in the same slot leads to some metadata
+    information loss. Since RSS is not constrained on special HW resources to
+    store the measurements and metadata, therefore it is worth considering to
+    store all of them one by one in distinct slots. However, they are one-by-one
+    included in the platform attestation token. So, the number of distinct
+    firmware image measurements has an impact on the size of the attestation
+    token.
+
+The allocation of the measurement slot among RSS, Root and Realm worlds is
+platform dependent. The platform must provide an allocation of the measurement
+slot at build time. An example can be found in
+``tf-a/plat/arm/board/tc/tc_bl1_measured_boot.c``
+Furthermore, the memory, which holds the metadata is also statically allocated
+in RSS memory. Some of the fields have a static value (measurement algorithm),
+and some of the values have a dynamic value (measurement value) which is updated
+by the bootloaders when the firmware image is loaded and measured. The metadata
+structure is defined in
+``include/drivers/measured_boot/rss/rss_measured_boot.h``.
+
+.. code-block:: c
+
+    struct rss_mboot_metadata {
+            unsigned int id;
+            uint8_t slot;
+            uint8_t signer_id[SIGNER_ID_MAX_SIZE];
+            size_t  signer_id_size;
+            uint8_t version[VERSION_MAX_SIZE];
+            size_t  version_size;
+            uint8_t sw_type[SW_TYPE_MAX_SIZE];
+            size_t  sw_type_size;
+            bool    lock_measurement;
+    };
+
+Build time config options
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``MEASURED_BOOT``: Enable measured boot. It depends on the platform
+  implementation whether RSS or TPM (or both) backend based measured boot is
+  enabled.
+- ``MBOOT_RSS_HASH_ALG``: Determine the hash algorithm to measure the images.
+  The default value is sha-256.
+
+Measured boot flow
+^^^^^^^^^^^^^^^^^^
+
+.. figure:: ../resources/diagrams/rss_measured_boot_flow.svg
+  :align: center
+
+Sample console log
+^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 6
+    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - version     :
+    INFO:     - version_size: 0
+    INFO:     - sw_type     : FW_CONFIG
+    INFO:     - sw_type_size: 10
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : aa ea d3 a7 a8 e2 ab 7d 13 a6 cb 34 99 10 b9 a1
+    INFO:                   : 1b 9f a0 52 c5 a8 b1 d7 76 f2 c1 c1 ef ca 1a df
+    INFO:     - locking     : true
+    INFO:    FCONF: Config file with image ID:31 loaded at address = 0x4001010
+    INFO:    Loading image id=24 at address 0x4001300
+    INFO:    Image id=24 loaded: 0x4001300 - 0x400153a
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 7
+    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - version     :
+    INFO:     - version_size: 0
+    INFO:     - sw_type     : TB_FW_CONFIG
+    INFO:     - sw_type_size: 13
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : 05 b9 dc 98 62 26 a7 1c 2d e5 bb af f0 90 52 28
+    INFO:                   : f2 24 15 8a 3a 56 60 95 d6 51 3a 7a 1a 50 9b b7
+    INFO:     - locking     : true
+    INFO:    FCONF: Config file with image ID:24 loaded at address = 0x4001300
+    INFO:    BL1: Loading BL2
+    INFO:    Loading image id=1 at address 0x404d000
+    INFO:    Image id=1 loaded: 0x404d000 - 0x406412a
+    INFO:    Measured boot extend measurement:
+    INFO:     - slot        : 8
+    INFO:     - signer_id   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:     - version     :
+    INFO:     - version_size: 0
+    INFO:     - sw_type     : BL_2
+    INFO:     - sw_type_size: 5
+    INFO:     - algorithm   : 2000009
+    INFO:     - measurement : 53 a1 51 75 25 90 fb a1 d9 b8 c8 34 32 3a 01 16
+    INFO:                   : c9 9e 74 91 7d 28 02 56 3f 5c 40 94 37 58 50 68
+    INFO:     - locking     : true
+
+Delegated Attestation
+---------------------
+
+Delegated Attestation Service was mainly developed to support the attestation
+flow on the ``ARM Confidential Compute Architecture`` (ARM CCA) [7]_.
+The detailed description of the delegated attestation service can be found in
+the ``Delegated Attestation Service Integration Guide`` [4]_ document.
+
+In the CCA use case, the Realm Management Monitor (RMM) relies on the delegated
+attestation service of the RSS to get a realm attestation key and the CCA
+platform token. BL31 does not use the service for its own purpose, only calls
+it on behalf of RMM. The access to MHU interface and thereby to RSS is
+restricted to BL31 only. Therefore, RMM does not have direct access, all calls
+need to go through BL31. The RMM dispatcher module of the BL31 is responsible
+for delivering the calls between the two parties.
+
+.. Note::
+     Currently the connection between the RMM dispatcher and the PSA/RSS layer
+     is not yet implemented. RMM dispatcher just returns hard coded data.
+
+Delegated Attestation API
+^^^^^^^^^^^^^^^^^^^^^^^^^
+Defined here:
+
+- ``include/lib/psa/delegated_attestation.h``
+
+.. code-block:: c
+
+    psa_status_t
+    rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+                                           uint32_t  key_bits,
+                                           uint8_t  *key_buf,
+                                           size_t    key_buf_size,
+                                           size_t   *key_size,
+                                           uint32_t  hash_algo);
+
+    psa_status_t
+    rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+                                   size_t         dak_pub_hash_size,
+                                   uint8_t       *token_buf,
+                                   size_t         token_buf_size,
+                                   size_t        *token_size);
+
+Attestation flow
+^^^^^^^^^^^^^^^^
+
+.. figure:: ../resources/diagrams/rss_attestation_flow.svg
+  :align: center
+
+Sample attestation token
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Binary format:
+
+.. code-block:: bash
+
+    INFO:    DELEGATED ATTEST TEST START
+    INFO:    Get delegated attestation key start
+    INFO:    Get delegated attest key succeeds, len: 48
+    INFO:    Delegated attest key:
+    INFO:            0d 2a 66 61 d4 89 17 e1 70 c6 73 56 df f4 11 fd
+    INFO:            7d 1f 3b 8a a3 30 3d 70 4c d9 06 c3 c7 ef 29 43
+    INFO:            0f ee b5 e7 56 e0 71 74 1b c4 39 39 fd 85 f6 7b
+    INFO:    Get platform token start
+    INFO:    Get platform token succeeds, len: 1086
+    INFO:    Platform attestation token:
+    INFO:            d2 84 44 a1 01 38 22 a0 59 03 d1 a9 0a 58 20 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19
+    INFO:            01 00 58 21 01 cb 8c 79 f7 a0 0a 6c ce 12 66 f8
+    INFO:            64 45 48 42 0e c5 10 bf 84 ee 22 18 b9 8f 11 04
+    INFO:            c7 22 31 9d fb 19 09 5c 58 20 aa aa aa aa aa aa
+    INFO:            aa aa bb bb bb bb bb bb bb bb cc cc cc cc cc cc
+    INFO:            cc cc dd dd dd dd dd dd dd dd 19 09 5b 19 30 00
+    INFO:            19 09 5f 89 a4 05 58 20 bf e6 d8 6f 88 26 f4 ff
+    INFO:            97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d a2 6a
+    INFO:            df 34 c3 29 48 9a dc 38 04 67 31 2e 36 2e 30 2b
+    INFO:            30 01 64 52 54 5f 30 02 58 20 90 27 f2 46 ab 31
+    INFO:            85 36 46 c4 d7 c6 60 ed 31 0d 3c f0 14 de f0 6c
+    INFO:            24 0b de b6 7a 84 fc 3f 5b b7 a4 05 58 20 b3 60
+    INFO:            ca f5 c9 8c 6b 94 2a 48 82 fa 9d 48 23 ef b1 66
+    INFO:            a9 ef 6a 6e 4a a3 7c 19 19 ed 1f cc c0 49 04 67
+    INFO:            30 2e 30 2e 30 2b 30 01 64 52 54 5f 31 02 58 20
+    INFO:            52 13 15 d4 9d b2 cf 54 e4 99 37 44 40 68 f0 70
+    INFO:            7d 73 64 ae f7 08 14 b0 f7 82 ad c6 17 db a3 91
+    INFO:            a4 05 58 20 bf e6 d8 6f 88 26 f4 ff 97 fb 96 c4
+    INFO:            e6 fb c4 99 3e 46 19 fc 56 5d a2 6a df 34 c3 29
+    INFO:            48 9a dc 38 04 67 31 2e 35 2e 30 2b 30 01 64 52
+    INFO:            54 5f 32 02 58 20 8e 5d 64 7e 6f 6c c6 6f d4 4f
+    INFO:            54 b6 06 e5 47 9a cc 1b f3 7f ce 87 38 49 c5 92
+    INFO:            d8 2f 85 2e 85 42 a4 05 58 20 bf e6 d8 6f 88 26
+    INFO:            f4 ff 97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d
+    INFO:            a2 6a df 34 c3 29 48 9a dc 38 04 67 31 2e 35 2e
+    INFO:            30 2b 30 01 60 02 58 20 b8 01 65 a7 78 8b c6 59
+    INFO:            42 8d 33 10 85 d1 49 0a dc 9e c3 ee df 85 1b d2
+    INFO:            f0 73 73 6a 0c 07 11 b8 a4 05 58 20 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 04 60 01 6a
+    INFO:            46 57 5f 43 4f 4e 46 49 47 00 02 58 20 21 9e a0
+    INFO:            13 82 e6 d7 97 5a 11 13 a3 5f 45 39 68 b1 d9 a3
+    INFO:            ea 6a ab 84 23 3b 8c 06 16 98 20 ba b9 a4 05 58
+    INFO:            20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 04 60 01 6d 54 42 5f 46 57 5f 43 4f 4e 46 49
+    INFO:            47 00 02 58 20 41 39 f6 c2 10 84 53 c5 17 ae 9a
+    INFO:            e5 be c1 20 7b cc 24 24 f3 9d 20 a8 fb c7 b3 10
+    INFO:            e3 ee af 1b 05 a4 05 58 20 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 04 60 01 65 42 4c 5f
+    INFO:            32 00 02 58 20 5c 96 20 e1 e3 3b 0f 2c eb c1 8e
+    INFO:            1a 02 a6 65 86 dd 34 97 a7 4c 98 13 bf 74 14 45
+    INFO:            2d 30 28 05 c3 a4 05 58 20 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 04 60 01 6e 53 45 43
+    INFO:            55 52 45 5f 52 54 5f 45 4c 33 00 02 58 20 f6 fb
+    INFO:            62 99 a5 0c df db 02 0b 72 5b 1c 0b 63 6e 94 ee
+    INFO:            66 50 56 3a 29 9c cb 38 f0 ec 59 99 d4 2e a4 05
+    INFO:            58 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    INFO:            00 00 04 60 01 6a 48 57 5f 43 4f 4e 46 49 47 00
+    INFO:            02 58 20 98 5d 87 21 84 06 33 9d c3 1f 91 f5 68
+    INFO:            8d a0 5a f0 d7 7e 20 51 ce 3b f2 a5 c3 05 2e 3c
+    INFO:            8b 52 31 19 01 09 78 1c 68 74 74 70 3a 2f 2f 61
+    INFO:            72 6d 2e 63 6f 6d 2f 43 43 41 2d 53 53 44 2f 31
+    INFO:            2e 30 2e 30 19 09 62 71 6e 6f 74 2d 68 61 73 68
+    INFO:            2d 65 78 74 65 6e 64 65 64 19 09 61 44 ef be ad
+    INFO:            de 19 09 60 77 77 77 77 2e 74 72 75 73 74 65 64
+    INFO:            66 69 72 6d 77 61 72 65 2e 6f 72 67 58 60 29 4e
+    INFO:            4a d3 98 1e 3b 70 9f b6 66 ed 47 33 0e 99 f0 b1
+    INFO:            c3 f2 bc b2 1d b0 ae 90 0c c4 82 ff a2 6f ae 45
+    INFO:            f6 87 09 4a 09 21 77 ec 36 1c 53 b8 a7 9b 8e f7
+    INFO:            27 eb 7a 09 da 6f fb bf cb fd b3 e5 e9 36 91 b1
+    INFO:            92 13 c1 30 16 b4 5c 49 5e c0 c1 b9 01 5c 88 2c
+    INFO:            f8 2f 3e a4 a2 6d e4 9d 31 6a 06 f7 a7 73
+    INFO:    DELEGATED ATTEST TEST END
+
+JSON format:
+
+.. code-block:: JSON
+
+    {
+        "CCA_PLATFORM_CHALLENGE": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+        "CCA_PLATFORM_INSTANCE_ID": "b'01CB8C79F7A00A6CCE1266F8644548420EC510BF84EE2218B98F1104C722319DFB'",
+        "CCA_PLATFORM_IMPLEMENTATION_ID": "b'AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD'",
+        "CCA_PLATFORM_LIFECYCLE": "secured_3000",
+        "CCA_PLATFORM_SW_COMPONENTS": [
+            {
+                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
+                "SW_COMPONENT_VERSION": "1.6.0+0",
+                "SW_COMPONENT_TYPE": "RT_0",
+                "MEASUREMENT_VALUE": "b'9027F246AB31853646C4D7C660ED310D3CF014DEF06C240BDEB67A84FC3F5BB7'"
+            },
+            {
+                "SIGNER_ID": "b'B360CAF5C98C6B942A4882FA9D4823EFB166A9EF6A6E4AA37C1919ED1FCCC049'",
+                "SW_COMPONENT_VERSION": "0.0.0+0",
+                "SW_COMPONENT_TYPE": "RT_1",
+                "MEASUREMENT_VALUE": "b'521315D49DB2CF54E49937444068F0707D7364AEF70814B0F782ADC617DBA391'"
+            },
+            {
+                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
+                "SW_COMPONENT_VERSION": "1.5.0+0",
+                "SW_COMPONENT_TYPE": "RT_2",
+                "MEASUREMENT_VALUE": "b'8E5D647E6F6CC66FD44F54B606E5479ACC1BF37FCE873849C592D82F852E8542'"
+            },
+            {
+                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
+                "SW_COMPONENT_VERSION": "1.5.0+0",
+                "SW_COMPONENT_TYPE": "",
+                "MEASUREMENT_VALUE": "b'B80165A7788BC659428D331085D1490ADC9EC3EEDF851BD2F073736A0C0711B8'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "FW_CONFIG\u0000",
+                "MEASUREMENT_VALUE": "b'219EA01382E6D7975A1113A35F453968B1D9A3EA6AAB84233B8C06169820BAB9'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "TB_FW_CONFIG\u0000",
+                "MEASUREMENT_VALUE": "b'4139F6C2108453C517AE9AE5BEC1207BCC2424F39D20A8FBC7B310E3EEAF1B05'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "BL_2\u0000",
+                "MEASUREMENT_VALUE": "b'5C9620E1E33B0F2CEBC18E1A02A66586DD3497A74C9813BF7414452D302805C3'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "SECURE_RT_EL3\u0000",
+                "MEASUREMENT_VALUE": "b'F6FB6299A50CDFDB020B725B1C0B636E94EE6650563A299CCB38F0EC5999D42E'"
+            },
+            {
+                "SIGNER_ID": "b'0000000000000000000000000000000000000000000000000000000000000000'",
+                "SW_COMPONENT_VERSION": "",
+                "SW_COMPONENT_TYPE": "HW_CONFIG\u0000",
+                "MEASUREMENT_VALUE": "b'985D87218406339DC31F91F5688DA05AF0D77E2051CE3BF2A5C3052E3C8B5231'"
+            }
+        ],
+        "CCA_ATTESTATION_PROFILE": "http://arm.com/CCA-SSD/1.0.0",
+        "CCA_PLATFORM_HASH_ALGO_ID": "not-hash-extended",
+        "CCA_PLATFORM_CONFIG": "b'EFBEADDE'",
+        "CCA_PLATFORM_VERIFICATION_SERVICE": "www.trustedfirmware.org"
+    }
+
+References
+----------
+
+.. [1] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/readme.html
+.. [2] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/rss_comms.html
+.. [3] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/measured_boot/measured_boot_integration_guide.rst
+.. [4] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/delegated_attestation/delegated_attest_integration_guide.rst
+.. [5] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/rss_key_management.html
+.. [6] https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4&hash=3BFD6F3E687F324672F18E5BE9F08EDC48087C93
+.. [7] https://developer.arm.com/documentation/DEN0096/A_a/?lang=en
+
+--------------
+
+*Copyright (c) 2023, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 3723294..5b49d2e 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -31,12 +31,18 @@
    You will need the targets ``arm-none-eabi`` and ``aarch64-none-elf`` for
    AArch32 and AArch64 builds respectively.
 
-- Clang >= 14.0.0
-- Arm Compiler >= 6.18
+- Clang == 14.0.0
+- Arm Compiler == 6.18
 
 In addition, a native compiler is required to build the supporting tools.
 
 .. note::
+   Versions greater than the ones specified are likely but not guaranteed to
+   work. This is predominantly because TF-A carries its own copy of compiler-rt,
+   which may be older than the version expected by the compiler. Fixes and bug
+   reports are always welcome.
+
+.. note::
    The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
    Cygwin, and Msys (MinGW) shells, using version 5.3.1 of the GNU toolchain.
 
diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst
index eab3e4d..7418669 100644
--- a/docs/perf/psci-performance-juno.rst
+++ b/docs/perf/psci-performance-juno.rst
@@ -286,7 +286,7 @@
 
 --------------
 
-*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.*
 
-.. _Juno R1 platform: https://static.docs.arm.com/100122/0100/arm_versatile_express_juno_r1_development_platform_(v2m_juno_r1)_technical_reference_manual_100122_0100_05_en.pdf
+.. _Juno R1 platform: https://developer.arm.com/documentation/100122/latest/
 .. _TF master as of 31/01/2017: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?id=c38b36d
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index 91e681f..d741d58 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -241,7 +241,7 @@
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
 
 .. _Linaro release software stack: http://releases.linaro.org/members/arm/platforms/
 .. _Juno platform software user guide: https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/juno/user-guide.rst
@@ -250,4 +250,3 @@
 .. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
 .. _Juno Getting Started Guide: https://developer.arm.com/documentation/den0928/f/?lang=en
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
-.. _Juno Arm Development Platform: http://www.arm.com/products/tools/development-boards/versatile-express/juno-arm-development-platform.php
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/process/security.rst b/docs/process/security.rst
index e15783b..f1e7a9d 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -9,10 +9,8 @@
 vulnerabilities and inform users as best we can about all possible issues.
 
 We disclose TF-A vulnerabilities as Security Advisories, all of which are listed
-at the bottom of this page. Any new ones will, additionally, be announced as
-issues in the project's `issue tracker`_ with the ``security-advisory`` tag. You
-can receive notification emails for these by watching the "Trusted Firmware-A"
-project at https://developer.trustedfirmware.org/.
+at the bottom of this page. Any new ones will, additionally, be announced on the
+TF-A project's `mailing list`_.
 
 Found a Security Issue?
 -----------------------
@@ -86,4 +84,4 @@
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
diff --git a/docs/requirements.in b/docs/requirements.in
index 5d771e5..ae20b7d 100644
--- a/docs/requirements.in
+++ b/docs/requirements.in
@@ -1,5 +1,5 @@
-myst-parser==0.15.2
+myst-parser==0.18.1
 pip-tools==6.4.0
-sphinx==4.2.0
-sphinx-rtd-theme==1.0.0
-sphinxcontrib-plantuml==0.22
+sphinx==5.3.0
+sphinx-rtd-theme==1.1.1
+sphinxcontrib-plantuml==0.24.1
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 03b1189..1ed78d0 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,71 +1,71 @@
 #
-# This file is autogenerated by pip-compile with python 3.8
-# To update, run:
+# This file is autogenerated by pip-compile with Python 3.8
+# by the following command:
 #
-#    pip-compile
+#    pip-compile docs/requirements.in
 #
 alabaster==0.7.12
     # via sphinx
-attrs==21.2.0
-    # via markdown-it-py
-babel==2.9.1
+babel==2.11.0
     # via sphinx
-certifi==2021.5.30
+certifi==2022.12.7
     # via requests
-charset-normalizer==2.0.4
+charset-normalizer==2.1.1
     # via requests
-click==8.0.1
+click==8.1.3
     # via pip-tools
-docutils==0.16
+docutils==0.17.1
     # via
     #   myst-parser
     #   sphinx
     #   sphinx-rtd-theme
-idna==3.2
+idna==3.4
     # via requests
-imagesize==1.2.0
+imagesize==1.4.1
+    # via sphinx
+importlib-metadata==6.0.0
     # via sphinx
-jinja2==3.0.1
+jinja2==3.1.2
     # via
     #   myst-parser
     #   sphinx
-markdown-it-py==1.1.0
+markdown-it-py==2.1.0
     # via
     #   mdit-py-plugins
     #   myst-parser
-markupsafe==2.0.1
+markupsafe==2.1.1
     # via jinja2
-mdit-py-plugins==0.2.8
+mdit-py-plugins==0.3.3
     # via myst-parser
-myst-parser==0.15.2
-    # via -r requirements.in
-packaging==21.0
+mdurl==0.1.2
+    # via markdown-it-py
+myst-parser==0.18.1
+    # via -r docs/requirements.in
+packaging==23.0
     # via sphinx
-pep517==0.11.0
+pep517==0.13.0
     # via pip-tools
 pip-tools==6.4.0
-    # via -r requirements.in
-pygments==2.10.0
+    # via -r docs/requirements.in
+pygments==2.14.0
     # via sphinx
-pyparsing==2.4.7
-    # via packaging
-pytz==2021.1
+pytz==2022.7
     # via babel
 pyyaml==6.0
     # via myst-parser
-requests==2.26.0
+requests==2.28.1
     # via sphinx
-snowballstemmer==2.1.0
+snowballstemmer==2.2.0
     # via sphinx
-sphinx==4.2.0
+sphinx==5.3.0
     # via
-    #   -r requirements.in
+    #   -r docs/requirements.in
     #   myst-parser
     #   sphinx-rtd-theme
     #   sphinxcontrib-plantuml
-sphinx-rtd-theme==1.0.0
-    # via -r requirements.in
-sphinxcontrib-applehelp==1.0.2
+sphinx-rtd-theme==1.1.1
+    # via -r docs/requirements.in
+sphinxcontrib-applehelp==1.0.3
     # via sphinx
 sphinxcontrib-devhelp==1.0.2
     # via sphinx
@@ -73,18 +73,22 @@
     # via sphinx
 sphinxcontrib-jsmath==1.0.1
     # via sphinx
-sphinxcontrib-plantuml==0.22
-    # via -r requirements.in
+sphinxcontrib-plantuml==0.24.1
+    # via -r docs/requirements.in
 sphinxcontrib-qthelp==1.0.3
     # via sphinx
 sphinxcontrib-serializinghtml==1.1.5
     # via sphinx
-tomli==1.2.1
+tomli==2.0.1
     # via pep517
-urllib3==1.26.6
+typing-extensions==4.4.0
+    # via myst-parser
+urllib3==1.26.13
     # via requests
-wheel==0.37.0
+wheel==0.38.4
     # via pip-tools
+zipp==3.11.0
+    # via importlib-metadata
 
 # The following packages are considered to be unsafe in a requirements file:
 # pip
diff --git a/docs/resources/diagrams/plantuml/rss_attestation_flow.puml b/docs/resources/diagrams/plantuml/rss_attestation_flow.puml
new file mode 100644
index 0000000..aca5c01
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/rss_attestation_flow.puml
@@ -0,0 +1,39 @@
+@startuml
+skinparam ParticipantPadding 10
+skinparam BoxPadding 10
+box AP
+participant RMM
+participant BL31
+endbox
+box RSS
+participant DelegAttest
+participant InitAttest
+participant MeasuredBoot
+participant Crypto
+endbox
+
+== RMM Boot phase ==
+
+RMM -> BL31: get_realm_key(\n\t**hash_algo**, ...)
+BL31 -> DelegAttest: get_delegated_key
+DelegAttest -> MeasuredBoot: read_measurement
+Rnote over DelegAttest: Compute input\n\ for key derivation\n\ (hash of measurements)
+DelegAttest -> Crypto: derive_key
+Rnote over DelegAttest: Compute public key\n\ hash with **hash_algo**.
+Rnote over Crypto: Seed is provisioned\n\ in the factory.
+DelegAttest --> BL31: get_delegated_key
+BL31 --> RMM: get_realm_key
+Rnote over RMM: Only private key\n\ is returned. Public\n\ key and its hash\n\ must be computed.\n\
+Public key is included\n\ in the realm token.\n\ Its hash is the input\n\ for get_platform_token
+RMM -> BL31: get_platform_token(\n\t**pub_key_hash**, ...)
+BL31 -> DelegAttest: get_delegated_token
+Rnote over DelegAttest: Check **pub_key_hash**\n\ against derived key.
+DelegAttest -> InitAttest: get_initial_token
+Rnote over InitAttest: Create the token including\n\ the **pub_key_hash** as the\n\ challenge claim
+InitAttest -> MeasuredBoot: read_measurement
+InitAttest -> Crypto: sign_token
+InitAttest --> DelegAttest:  get_initial_token
+DelegAttest --> BL31: get_delegated_token
+BL31 --> RMM: get_platform_token
+Rnote over RMM: Platform token is\n\ cached. It is not\n\ changing within\n\ a power cycle.
+@enduml
diff --git a/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml b/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
new file mode 100644
index 0000000..1aeb1a9
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
@@ -0,0 +1,79 @@
+@startuml
+skinparam ParticipantPadding 10
+skinparam BoxPadding 10
+box RSS
+participant RSS_BL1_1
+participant RSS_BL1_2
+participant RSS_BL2
+participant RSS_S
+endbox
+box SCP
+participant SCP_BL1
+endbox
+box AP
+participant AP_BL1
+participant AP_BL2
+participant AP_BL31
+endbox
+
+== RSS Boot phase ==
+-> RSS_BL1_1: Reset
+Rnote over RSS_BL1_1: ROM code, XIP
+Rnote over RSS_BL1_2: OTP code, XIP
+Rnote over RSS_BL2, AP_BL31: Stored in flash, loaded and executed in RAM
+activate RSS_BL1_1 #Green
+RSS_BL1_1 -->> RSS_BL1_2: Validate, measure
+Rnote over RSS_BL1_1: BL1_2 measurement\n\ saved to a shared buffer
+RSS_BL1_1 -> RSS_BL1_2: Pass execution
+deactivate RSS_BL1_1
+activate RSS_BL1_2 #Green
+RSS_BL1_2 -->> RSS_BL2: Validate, measure, load
+Rnote over RSS_BL1_2: RSS_BL2 measurement\n\ saved to a shared buffer
+RSS_BL1_2 -> RSS_BL2: Pass execution
+deactivate RSS_BL1_2
+activate RSS_BL2 #Green
+RSS_BL2 -->> RSS_S: Validate, measure, load
+RSS_BL2 -->> SCP_BL1: Validate, measure, load
+Rnote over RSS_BL2: RSS_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer
+RSS_BL2 -> SCP_BL1: Release from reset
+activate SCP_BL1 #Green
+Rnote over RSS_BL2, SCP_BL1: MHU init between RSS and SCP
+Rnote over SCP_BL1: Configure memory
+Rnote over RSS_BL2: Waits for SCP
+SCP_BL1 --> RSS_BL2: Done
+RSS_BL2 -->> AP_BL1: Validate, measure, load
+Rnote over RSS_BL2: AP_BL1 measurement\n\ saved to a shared buffer
+RSS_BL2 -> AP_BL1: Release from reset
+activate AP_BL1 #Green
+RSS_BL2 -> RSS_S: Pass execution
+deactivate RSS_BL2
+activate RSS_S #Green
+Rnote over RSS_S: Measurements read from\n\ shared buffer and saved by\n\
+Measured Boot service to\n\ measurement slots.
+
+== RSS Runtime / AP Boot phase ==
+Rnote over RSS_S, AP_BL1: MHU init between RSS and AP
+Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG
+AP_BL1 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL1 -->> AP_BL2: Validate, measure,load
+AP_BL1 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL1 -> AP_BL2: Pass execution
+deactivate AP_BL1
+activate AP_BL2 #Green
+Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG
+AP_BL2 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL2 -->> AP_BL31: Validate, measure,load
+Rnote over AP_BL2: Measure and load:\n\ BL31
+AP_BL2 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+Rnote over AP_BL2: Measure and load:\n\ RMM
+AP_BL2 -> RSS_S: Extend measurement
+Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL2 -> AP_BL31: Pass execution
+deactivate AP_BL2
+activate AP_BL31 #Green
+== RSS / AP Runtime ==
+@enduml
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/resources/diagrams/rss_attestation_flow.svg b/docs/resources/diagrams/rss_attestation_flow.svg
new file mode 100644
index 0000000..3728c6f
--- /dev/null
+++ b/docs/resources/diagrams/rss_attestation_flow.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1087px" preserveAspectRatio="none" style="width:900px;height:1087px;background:#FFFFFF;" version="1.1" viewBox="0 0 900 1087" width="900px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="261.5" x="44" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="164.75" y="18.0669">AP</text><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="502" x="364" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="601" y="18.0669">RSS</text><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="82" x2="82" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="266.5" x2="266.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="426" x2="426" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="553.5" x2="553.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="705" x2="705" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="822" x2="822" y1="56.4297" y2="1046.875"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="45.1279">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="1065.8701">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="45.1279">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="1065.8701">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="45.1279">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="1065.8701">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="45.1279">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="1065.8701">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="45.1279">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="1065.8701">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="45.1279">Crypto</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="1065.8701">Crypto</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="893" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="144" x="374.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="125" x="380.5" y="92.4966">RMM Boot phase</text><polygon fill="#181818" points="255,141.8281,265,145.8281,255,149.8281,259,145.8281" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="145.8281" y2="145.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="89" y="125.6294">get_realm_key(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="121" y="140.7622">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="195" y="140.7622">, ...)</text><polygon fill="#181818" points="414,170.9609,424,174.9609,414,178.9609,418,174.9609" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="174.9609" y2="174.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="274" y="169.895">get_delegated_key</text><polygon fill="#181818" points="693,200.0938,703,204.0938,693,208.0938,697,204.0938" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="699" y1="204.0938" y2="204.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="433" y="199.0278">read_measurement</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="167" x="342" y="217.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="95" x="346" y="233.1606">Compute input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="110" x="346" y="248.2935">for key derivation</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="159" x="346" y="263.4263">(hash of measurements)</text><polygon fill="#181818" points="810.5,292.625,820.5,296.625,810.5,300.625,814.5,296.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="816.5" y1="296.625" y2="296.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="68" x="433" y="291.5591">derive_key</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="150" x="351" y="309.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="355" y="325.6919">Compute public key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="60" x="355" y="340.8247">hash with</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="419" y="340.8247">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="4" x="493" y="340.8247">.</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="132" x="756" y="357.8906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="124" x="760" y="373.9575">Seed is provisioned</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="760" y="389.0903">in the factory.</text><polygon fill="#181818" points="278,418.2891,268,422.2891,278,426.2891,274,422.2891" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="422.2891" y2="422.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="284" y="417.2231">get_delegated_key</text><polygon fill="#181818" points="93,447.4219,83,451.4219,93,455.4219,89,451.4219" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="451.4219" y2="451.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="94" x="99" y="446.356">get_realm_key</text><rect fill="#FEFFDD" height="129" style="stroke:#181818;stroke-width:0.5;" width="154" x="5" y="464.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="102" x="9" y="480.4888">Only private key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="9" y="495.6216">is returned. Public</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="9" y="510.7544">key and its hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="9" y="525.8872">must be computed.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="541.02">Public key is included</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="9" y="556.1528">in the realm token.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="9" y="571.2856">Its hash is the input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="146" x="9" y="586.4185">for get_platform_token</text><polygon fill="#181818" points="255,630.75,265,634.75,255,638.75,259,634.75" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="634.75" y2="634.75"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="130" x="89" y="614.5513">get_platform_token(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="121" y="629.6841">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="225" y="629.6841">, ...)</text><polygon fill="#181818" points="414,659.8828,424,663.8828,414,667.8828,418,663.8828" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="663.8828" y2="663.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="274" y="658.8169">get_delegated_token</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="155" x="348" y="676.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="39" x="352" y="692.9497">Check</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="395" y="692.9497">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="352" y="708.0825">against derived key.</text><polygon fill="#181818" points="542,737.2813,552,741.2813,542,745.2813,546,741.2813" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="548" y1="741.2813" y2="741.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="433" y="736.2153">get_initial_token</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="181" x="463" y="754.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="168" x="467" y="770.3481">Create the token including</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="21" x="467" y="785.481">the</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="492" y="785.481">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="40" x="600" y="785.481">as the</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="467" y="800.6138">challenge claim</text><polygon fill="#181818" points="693,829.8125,703,833.8125,693,837.8125,697,833.8125" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="699" y1="833.8125" y2="833.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="561" y="828.7466">read_measurement</text><polygon fill="#181818" points="810.5,858.9453,820.5,862.9453,810.5,866.9453,814.5,862.9453" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="816.5" y1="862.9453" y2="862.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="69" x="561" y="857.8794">sign_token</text><polygon fill="#181818" points="437,888.0781,427,892.0781,437,896.0781,433,892.0781" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="431" x2="553" y1="892.0781" y2="892.0781"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="443" y="887.0122">get_initial_token</text><polygon fill="#181818" points="278,917.2109,268,921.2109,278,925.2109,274,921.2109" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="921.2109" y2="921.2109"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="284" y="916.145">get_delegated_token</text><polygon fill="#181818" points="93,946.3438,83,950.3438,93,954.3438,89,950.3438" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="950.3438" y2="950.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="99" y="945.2778">get_platform_token</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="116" x="24" y="963.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="108" x="28" y="979.4106">Platform token is</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="28" y="994.5435">cached. It is not</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="98" x="28" y="1009.6763">changing within</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="90" x="28" y="1024.8091">a power cycle.</text><!--MD5=[84fabec568a656165bea957fac178b53]
+@startuml

+skinparam ParticipantPadding 10

+skinparam BoxPadding 10

+box AP

+participant RMM

+participant BL31

+endbox

+box RSS

+participant DelegAttest

+participant InitAttest

+participant MeasuredBoot

+participant Crypto

+endbox

+

+== RMM Boot phase ==

+

+RMM -> BL31: get_realm_key(\n\t**hash_algo**, ...)

+BL31 -> DelegAttest: get_delegated_key

+DelegAttest -> MeasuredBoot: read_measurement

+Rnote over DelegAttest: Compute input\n\ for key derivation\n\ (hash of measurements)

+DelegAttest -> Crypto: derive_key

+Rnote over DelegAttest: Compute public key\n\ hash with **hash_algo**.

+Rnote over Crypto: Seed is provisioned\n\ in the factory.

+DelegAttest - -> BL31: get_delegated_key

+BL31 - -> RMM: get_realm_key

+Rnote over RMM: Only private key\n\ is returned. Public\n\ key and its hash\n\ must be computed.\nPublic key is included\n\ in the realm token.\n\ Its hash is the input\n\ for get_platform_token

+RMM -> BL31: get_platform_token(\n\t**pub_key_hash**, ...)

+BL31 -> DelegAttest: get_delegated_token

+Rnote over DelegAttest: Check **pub_key_hash**\n\ against derived key.

+DelegAttest -> InitAttest: get_initial_token

+Rnote over InitAttest: Create the token including\n\ the **pub_key_hash** as the\n\ challenge claim

+InitAttest -> MeasuredBoot: read_measurement

+InitAttest -> Crypto: sign_token

+InitAttest - -> DelegAttest:  get_initial_token

+DelegAttest - -> BL31: get_delegated_token

+BL31 - -> RMM: get_platform_token

+Rnote over RMM: Platform token is\n\ cached. It is not\n\ changing within\n\ a power cycle.

+@enduml

+
+PlantUML version 1.2022.7(Mon Aug 22 19:01:30 CEST 2022)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: hu
+Country: HU
+--></g></svg>
\ No newline at end of file
diff --git a/docs/resources/diagrams/rss_measured_boot_flow.svg b/docs/resources/diagrams/rss_measured_boot_flow.svg
new file mode 100644
index 0000000..f5bf311
--- /dev/null
+++ b/docs/resources/diagrams/rss_measured_boot_flow.svg
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1826px" preserveAspectRatio="none" style="width:1254px;height:1826px;background:#FFFFFF;" version="1.1" viewBox="0 0 1254 1826" width="1254px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="610.5" x="27" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="318.25" y="18.0669">RSS</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="103" x="659.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="29" x="696.5" y="18.0669">SCP</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="451.5" x="784.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="1000.25" y="18.0669">AP</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="86" x2="86" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="232" x2="232" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="413" x2="413" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="594.5" x2="594.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="710.5" x2="710.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="830.5" x2="830.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1007.5" x2="1007.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1185" x2="1185" y1="56.4297" y2="1785.7969"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="45.1279">RSS_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="1804.792">RSS_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="45.1279">RSS_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="1804.792">RSS_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="45.1279">RSS_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="1804.792">RSS_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="45.1279">RSS_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="1804.792">RSS_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="45.1279">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="1804.792">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="45.1279">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="1804.792">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="45.1279">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="1804.792">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="45.1279">AP_BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="1804.792">AP_BL31</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="136" x="555.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="117" x="561.5" y="92.4966">RSS Boot phase</text><polygon fill="#181818" points="69.5,126.6953,79.5,130.6953,69.5,134.6953,73.5,130.6953" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="0" x2="75.5" y1="130.6953" y2="130.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="36" x="7" y="125.6294">Reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="99" x="37" y="143.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="91" x="41" y="159.7622">ROM code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="95" x="185" y="176.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="87" x="189" y="192.895">OTP code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="861" x="368" y="209.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="281" x="658" y="226.0278">Stored in flash, loaded and executed in RAM</text><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="255.2266"/><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="263.2266"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="91.5" x2="231.5" y1="259.2266" y2="259.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="117" x="98.5" y="254.1606">Validate, measure</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="5" y="272.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="288.2935">BL1_2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="9" y="303.4263">saved to a shared buffer</text><polygon fill="#181818" points="215.5,332.625,225.5,336.625,215.5,340.625,219.5,336.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="86.5" x2="221.5" y1="336.625" y2="336.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="93.5" y="331.5591">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="361.7578"/><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="369.7578"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="237.5" x2="412.5" y1="365.7578" y2="365.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="244.5" y="360.6919">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="150" y="378.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="154" y="394.8247">RSS_BL2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="154" y="409.9575">saved to a shared buffer</text><polygon fill="#181818" points="396.5,439.1563,406.5,443.1563,396.5,447.1563,400.5,443.1563" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="232.5" x2="402.5" y1="443.1563" y2="443.1563"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="239.5" y="438.0903">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="468.2891"/><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="476.2891"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="593.5" y1="472.2891" y2="472.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="467.2231">Validate, measure, load</text><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="497.4219"/><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="505.4219"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="710" y1="501.4219" y2="501.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="496.356">Validate, measure, load</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="148" x="339" y="514.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="131" x="343" y="530.4888">RSS_S and SCP_BL1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="140" x="343" y="545.6216">measurements saved</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="343" y="560.7544">to a shared buffer</text><polygon fill="#181818" points="694,589.9531,704,593.9531,694,597.9531,698,593.9531" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="700" y1="593.9531" y2="593.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="588.8872">Release from reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="387" x="368" y="606.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="200" x="461.75" y="623.02">MHU init between RSS and SCP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="127" x="647" y="640.0859"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="119" x="651" y="656.1528">Configure memory</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="93" x="367" y="673.2188"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="85" x="371" y="689.2856">Waits for SCP</text><polygon fill="#181818" points="429.5,718.4844,419.5,722.4844,429.5,726.4844,425.5,722.4844" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="423.5" x2="705" y1="722.4844" y2="722.4844"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="34" x="435.5" y="717.4185">Done</text><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="747.6172"/><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="755.6172"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="830" y1="751.6172" y2="751.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="746.5513">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="331" y="764.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="143" x="335" y="780.6841">AP_BL1 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="335" y="795.8169">saved to a shared buffer</text><polygon fill="#181818" points="814,825.0156,824,829.0156,814,833.0156,818,829.0156" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="820" y1="829.0156" y2="829.0156"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="823.9497">Release from reset</text><polygon fill="#181818" points="577.5,854.1484,587.5,858.1484,577.5,862.1484,581.5,858.1484" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="413.5" x2="583.5" y1="858.1484" y2="858.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="420.5" y="853.0825">Pass execution</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="182" x="503" y="871.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="887.2153">Measurements read from</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="174" x="507" y="902.3481">shared buffer and saved by</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="917.481">Measured Boot service to</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="129" x="507" y="932.6138">measurement slots.</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="965.2461" y2="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="968.2461" y2="968.2461"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="237" x="505" y="954.6797"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="218" x="511" y="970.7466">RSS Runtime / AP Boot phase</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="313" x="556" y="992.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="191" x="617" y="1008.8794">MHU init between RSS and AP</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="126" x="768" y="1025.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="772" y="1042.0122">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="74" x="772" y="1057.145">FW_CONFIG</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="97" x="772" y="1072.2778">TB_FW_CONFIG</text><polygon fill="#181818" points="610.5,1101.4766,600.5,1105.4766,610.5,1109.4766,606.5,1105.4766" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1105.4766" y2="1105.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1100.4106">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1118.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1134.5435">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1149.6763">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1178.875"/><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1186.875"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="836" x2="1007" y1="1182.875" y2="1182.875"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="843" y="1177.8091">Validate, measure,load</text><polygon fill="#181818" points="610.5,1208.0078,600.5,1212.0078,610.5,1216.0078,606.5,1212.0078" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1212.0078" y2="1212.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1206.9419">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1225.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1241.0747">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1256.2075">store measurement</text><polygon fill="#181818" points="991,1285.4063,1001,1289.4063,991,1293.4063,995,1289.4063" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="831" x2="997" y1="1289.4063" y2="1289.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="838" y="1284.3403">Pass execution</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1302.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1318.4731">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="77" x="949" y="1333.606">HW_CONFIG</text><polygon fill="#181818" points="610.5,1362.8047,600.5,1366.8047,610.5,1370.8047,606.5,1366.8047" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1366.8047" y2="1366.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1361.7388">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1379.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1395.8716">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1411.0044">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1440.2031"/><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1448.2031"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="1013" x2="1184" y1="1444.2031" y2="1444.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="1020" y="1439.1372">Validate, measure,load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1457.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1473.27">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="32" x="949" y="1488.4028">BL31</text><polygon fill="#181818" points="610.5,1517.6016,600.5,1521.6016,610.5,1525.6016,606.5,1521.6016" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1521.6016" y2="1521.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1516.5356">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1534.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1550.6685">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1565.8013">store measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1582.8672"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1598.9341">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="30" x="949" y="1614.0669">RMM</text><polygon fill="#181818" points="610.5,1643.2656,600.5,1647.2656,610.5,1651.2656,606.5,1647.2656" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1647.2656" y2="1647.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1642.1997">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1660.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1676.3325">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1691.4653">store measurement</text><polygon fill="#181818" points="1168,1720.6641,1178,1724.6641,1168,1728.6641,1172,1724.6641" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="1008" x2="1174" y1="1724.6641" y2="1724.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="1015" y="1719.5981">Pass execution</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1753.2305" y2="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1756.2305" y2="1756.2305"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="148" x="549.5" y="1742.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="129" x="555.5" y="1758.731">RSS / AP Runtime</text><!--MD5=[e3f0ee259d2a4aa9c2a97ff856de0312]
+@startuml

+skinparam ParticipantPadding 10

+skinparam BoxPadding 10

+box RSS

+participant RSS_BL1_1

+participant RSS_BL1_2

+participant RSS_BL2

+participant RSS_S

+endbox

+box SCP

+participant SCP_BL1

+endbox

+box AP

+participant AP_BL1

+participant AP_BL2

+participant AP_BL31

+endbox

+

+== RSS Boot phase ==

+-> RSS_BL1_1: Reset

+Rnote over RSS_BL1_1: ROM code, XIP

+Rnote over RSS_BL1_2: OTP code, XIP

+Rnote over RSS_BL2, AP_BL31: Stored in flash, loaded and executed in RAM

+activate RSS_BL1_1 #Green

+RSS_BL1_1 - ->> RSS_BL1_2: Validate, measure

+Rnote over RSS_BL1_1: BL1_2 measurement\n\ saved to a shared buffer

+RSS_BL1_1 -> RSS_BL1_2: Pass execution

+deactivate RSS_BL1_1

+activate RSS_BL1_2 #Green

+RSS_BL1_2 - ->> RSS_BL2: Validate, measure, load

+Rnote over RSS_BL1_2: RSS_BL2 measurement\n\ saved to a shared buffer

+RSS_BL1_2 -> RSS_BL2: Pass execution

+deactivate RSS_BL1_2

+activate RSS_BL2 #Green

+RSS_BL2 - ->> RSS_S: Validate, measure, load

+RSS_BL2 - ->> SCP_BL1: Validate, measure, load

+Rnote over RSS_BL2: RSS_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer

+RSS_BL2 -> SCP_BL1: Release from reset

+activate SCP_BL1 #Green

+Rnote over RSS_BL2, SCP_BL1: MHU init between RSS and SCP

+Rnote over SCP_BL1: Configure memory

+Rnote over RSS_BL2: Waits for SCP

+SCP_BL1 - -> RSS_BL2: Done

+RSS_BL2 - ->> AP_BL1: Validate, measure, load

+Rnote over RSS_BL2: AP_BL1 measurement\n\ saved to a shared buffer

+RSS_BL2 -> AP_BL1: Release from reset

+activate AP_BL1 #Green

+RSS_BL2 -> RSS_S: Pass execution

+deactivate RSS_BL2

+activate RSS_S #Green

+Rnote over RSS_S: Measurements read from\n\ shared buffer and saved by\nMeasured Boot service to\n\ measurement slots.

+

+== RSS Runtime / AP Boot phase ==

+Rnote over RSS_S, AP_BL1: MHU init between RSS and AP

+Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG

+AP_BL1 -> RSS_S: Extend measurement

+Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL1 - ->> AP_BL2: Validate, measure,load

+AP_BL1 -> RSS_S: Extend measurement

+Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL1 -> AP_BL2: Pass execution

+deactivate AP_BL1

+activate AP_BL2 #Green

+Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG

+AP_BL2 -> RSS_S: Extend measurement

+Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL2 - ->> AP_BL31: Validate, measure,load

+Rnote over AP_BL2: Measure and load:\n\ BL31

+AP_BL2 -> RSS_S: Extend measurement

+Rnote over RSS_S: Measured Boot:\n\ store measurement

+Rnote over AP_BL2: Measure and load:\n\ RMM

+AP_BL2 -> RSS_S: Extend measurement

+Rnote over RSS_S: Measured Boot:\n\ store measurement

+AP_BL2 -> AP_BL31: Pass execution

+deactivate AP_BL2

+activate AP_BL31 #Green

+== RSS / AP Runtime ==

+@enduml

+
+PlantUML version 1.2022.7(Mon Aug 22 19:01:30 CEST 2022)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: hu
+Country: HU
+--></g></svg>
\ No newline at end of file
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 99bbb3a..940cad5 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                 | | **Attacker wants to execute an arbitrary or       |
+|                        |   untrusted binary as the secure OS.**              |
+|                        |                                                     |
+|                        | | When the option OPTEE_ALLOW_SMC_LOAD is enabled,  |
+|                        |   this 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             | High (4)        | High (4)        | High (4)        |
++------------------------+-----------------+-----------------+-----------------+
+| Total Risk Rating      | Critical (20)   | Critical (20)   | Critical (20)   |
++------------------------+-----------------+-----------------+-----------------+
+| 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/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c
index f1250b0..79f9089 100644
--- a/drivers/allwinner/axp/common.c
+++ b/drivers/allwinner/axp/common.c
@@ -9,6 +9,7 @@
 #include <libfdt.h>
 
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/allwinner/axp.h>
 
 int axp_check_id(void)
@@ -97,19 +98,9 @@
 	return 0;
 }
 
-static bool is_node_disabled(const void *fdt, int node)
-{
-	const char *cell;
-	cell = fdt_getprop(fdt, node, "status", NULL);
-	if (cell == NULL) {
-		return false;
-	}
-	return strcmp(cell, "okay") != 0;
-}
-
 static bool should_enable_regulator(const void *fdt, int node)
 {
-	if (is_node_disabled(fdt, node)) {
+	if (!fdt_node_is_enabled(fdt, node)) {
 		return false;
 	}
 	if (fdt_getprop(fdt, node, "phandle", NULL) != NULL) {
diff --git a/drivers/auth/mbedtls/mbedtls_x509_parser.c b/drivers/auth/mbedtls/mbedtls_x509_parser.c
index bef2f3d..bbabd9b 100644
--- a/drivers/auth/mbedtls/mbedtls_x509_parser.c
+++ b/drivers/auth/mbedtls/mbedtls_x509_parser.c
@@ -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
  */
@@ -484,7 +484,7 @@
 		rc = get_ext(type_desc->cookie, param, param_len);
 		break;
 	case AUTH_PARAM_PUB_KEY:
-		if (type_desc->cookie != 0) {
+		if (type_desc->cookie != NULL) {
 			/* Get public key from extension */
 			rc = get_ext(type_desc->cookie, param, param_len);
 		} else {
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index e3fb749..93c38d8 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
 #include <drivers/console.h>
 
 console_t *console_list;
-uint8_t console_state = CONSOLE_FLAG_BOOT;
+static uint8_t console_state = CONSOLE_FLAG_BOOT;
 
 IMPORT_SYM(console_t *, __STACKS_START__, stacks_start)
 IMPORT_SYM(console_t *, __STACKS_END__, stacks_end)
diff --git a/drivers/io/io_block.c b/drivers/io/io_block.c
index 5d45c2f..b5e0e5f 100644
--- a/drivers/io/io_block.c
+++ b/drivers/io/io_block.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -271,7 +271,7 @@
 	block_size = cur->dev_spec->block_size;
 	assert((length <= cur->size) &&
 	       (length > 0U) &&
-	       (ops->read != 0));
+	       (ops->read != NULL));
 
 	/*
 	 * We don't know the number of bytes that we are going
@@ -383,8 +383,8 @@
 	block_size = cur->dev_spec->block_size;
 	assert((length <= cur->size) &&
 	       (length > 0U) &&
-	       (ops->read != 0) &&
-	       (ops->write != 0));
+	       (ops->read != NULL) &&
+	       (ops->write != NULL));
 
 	/*
 	 * We don't know the number of bytes that we are going
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 8e83464..2b727d4 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -69,8 +69,7 @@
 		int i;
 
 		for (i = 0; i < 4; i++) {
-			*r_data = cmd.resp_data[i];
-			r_data++;
+			r_data[i] = cmd.resp_data[i];
 		}
 	}
 
@@ -112,7 +111,7 @@
 	return MMC_GET_STATE(resp_data[0]);
 }
 
-static int mmc_send_part_switch_cmd(unsigned int part_config)
+static int mmc_send_part_switch_cmd(unsigned char part_config)
 {
 	int ret;
 	unsigned int part_time = 0;
@@ -760,9 +759,9 @@
 	return size;
 }
 
-static int mmc_part_switch(unsigned int part_type)
+static int mmc_part_switch(unsigned char part_type)
 {
-	uint8_t part_config = mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG];
+	unsigned char part_config = mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG];
 
 	part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
 	part_config |= part_type;
@@ -780,8 +779,7 @@
 	unsigned char current_boot_part = mmc_current_boot_part();
 	int ret;
 
-	if (current_boot_part != 1U &&
-	    current_boot_part != 2U) {
+	if ((current_boot_part != 1U) && (current_boot_part != 2U)) {
 		ERROR("Got unexpected value for active boot partition, %u\n", current_boot_part);
 		return -EIO;
 	}
diff --git a/drivers/partition/gpt.c b/drivers/partition/gpt.c
index 4fe8322..8b1046d 100644
--- a/drivers/partition/gpt.c
+++ b/drivers/partition/gpt.c
@@ -26,14 +26,16 @@
 
 	/* check whether the unicode string is valid */
 	for (i = 1; i < (EFI_NAMELEN << 1); i += 2) {
-		if (name[i] != '\0')
+		if (name[i] != '\0') {
 			return -EINVAL;
+		}
 	}
 	/* convert the unicode string to ascii string */
 	for (i = 0; i < (EFI_NAMELEN << 1); i += 2) {
 		str_out[i >> 1] = name[i];
-		if (name[i] == '\0')
+		if (name[i] == '\0') {
 			break;
+		}
 	}
 	return 0;
 }
diff --git a/fdts/tc.dts b/fdts/tc.dts
index 192f407..4f27589 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -456,13 +456,25 @@
 		clock-names = "mclk", "apb_pclk";
 	};
 
+	gpu_clk: gpu_clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000000>;
+	};
+
+	gpu_core_clk: gpu_core_clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000000>;
+	};
+
 	gpu: gpu@2d000000 {
 		compatible = "arm,mali-midgard";
 		reg = <0x0 0x2d000000 0x0 0x200000>;
 		interrupts = <0 66 4>, <0 67 4>, <0 65 4>;
 		interrupt-names = "JOB", "MMU", "GPU";
-		clocks = <&soc_refclk100mhz>;
-		clock-names = "clk_mali";
+		clocks = <&gpu_clk>, <&gpu_core_clk>;
+		clock-names = "clk_mali", "shadercores";
 		iommus = <&smmu_700 0x200>;
 		operating-points = <
 			/* KHz uV */
@@ -470,6 +482,18 @@
 		>;
 	};
 
+	power_model@simple {
+		/*
+		 * Numbers used are irrelevant to Titan,
+		 * it helps suppressing the kernel warnings.
+		 */
+		compatible = "arm,mali-simple-power-model";
+		static-coefficient = <2427750>;
+		dynamic-coefficient = <4687>;
+		ts = <20000 2000 (-20) 2>;
+		thermal-zone = "";
+	};
+
 	smmu_700: smmu_700@3f000000 {
 		#iommu-cells = <1>;
 		compatible = "arm,smmu-v3";
@@ -519,6 +543,15 @@
 		};
 	};
 
+	/*
+	 * L3 cache in the DSU is the Memory System Component (MSC)
+	 * The MPAM registers are accessed through utility bus in the DSU
+	 */
+	msc0 {
+		compatible = "arm,mpam-msc";
+		reg = <0x1 0x00010000 0x0 0x2000>;
+	};
+
 	ete0 {
 		compatible = "arm,embedded-trace-extension";
 		cpu = <&CPU0>;
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 9e13c3d..9e4a3b7 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -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.
  * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -1063,13 +1063,17 @@
 #define PMBLIMITR_EL1		S3_0_C9_C10_0
 
 /*******************************************************************************
- * Definitions for system register interface to MPAM
+ * Definitions for system register interface, shifts and masks for MPAM
  ******************************************************************************/
 #define MPAMIDR_EL1		S3_0_C10_C4_4
 #define MPAM2_EL2		S3_4_C10_C5_0
 #define MPAMHCR_EL2		S3_4_C10_C4_0
 #define MPAM3_EL3		S3_6_C10_C5_0
 
+#define MPAMIDR_EL1_HAS_HCR_SHIFT	ULL(0x11)
+#define MPAMIDR_EL1_VPMR_MAX_SHIFT	ULL(0x12)
+#define MPAMIDR_EL1_VPMR_MAX_WIDTH	ULL(0x3)
+#define MPAMIDR_EL1_VPMR_MAX_POSSIBLE	ULL(0x7)
 /*******************************************************************************
  * Definitions for system register interface to AMU for FEAT_AMUv1
  ******************************************************************************/
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index 2929fc2..b16510f 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -10,6 +10,7 @@
 #define FDT_WRAPPERS_H
 
 #include <libfdt_env.h>
+#include <libfdt.h>
 
 /* Number of cells, given total length in bytes. Each cell is 4 bytes long */
 #define NCELLS(len) ((len) / 4U)
@@ -53,6 +54,15 @@
 	return fdt32_to_cpu(dtb_header[1]);
 }
 
+static inline bool fdt_node_is_enabled(const void *fdt, int node)
+{
+	int len;
+	const void *prop = fdt_getprop(fdt, node, "status", &len);
+
+	/* A non-existing status property means the device is enabled. */
+	return (prop == NULL) || (len == 5 && strcmp(prop, "okay") == 0);
+}
+
 #define fdt_for_each_compatible_node(dtb, node, compatible_str)       \
 for (node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);   \
      node >= 0;                                                       \
diff --git a/include/drivers/console.h b/include/drivers/console.h
index 99bf960..f499571 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -48,6 +48,8 @@
 	/* Additional private driver data may follow here. */
 } console_t;
 
+extern console_t *console_list;
+
 /* offset macro assertions for console_t */
 #include <drivers/console_assertions.h>
 
diff --git a/include/drivers/partition/efi.h b/include/drivers/partition/efi.h
index e463f96..96c2857 100644
--- a/include/drivers/partition/efi.h
+++ b/include/drivers/partition/efi.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2021, Linaro Limited
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -25,13 +26,13 @@
 }
 
 #define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
-	{ (a) & 0xffffffff,		\
-	  (b) & 0xffff,			\
-	  (c) & 0xffff,			\
+	{ (a) & 0xffffffffU,		\
+	  (b) & 0xffffU,			\
+	  (c) & 0xffffU,			\
 	  { (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } }
 
 #define NULL_GUID \
-	EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, \
-		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
+	EFI_GUID(0x00000000U, 0x0000U, 0x0000U, 0x00U, 0x00U, \
+		 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U)
 
 #endif /* DRIVERS_PARTITION_EFI_H */
diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h
index 31da99e..fb325b6 100644
--- a/include/lib/cpus/aarch64/cortex_a78.h
+++ b/include/lib/cpus/aarch64/cortex_a78.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,6 +40,8 @@
 #define CORTEX_A78_ACTLR2_EL1_BIT_2			(ULL(1) << 2)
 #define CORTEX_A78_ACTLR2_EL1_BIT_40			(ULL(1) << 40)
 
+#define CORTEX_A78_ACTLR3_EL1				S3_0_C15_C1_2
+
 /*******************************************************************************
  * CPU Activity Monitor Unit register specific definitions.
  ******************************************************************************/
diff --git a/include/lib/cpus/aarch64/neoverse_v1.h b/include/lib/cpus/aarch64/neoverse_v1.h
index 9c7e967..4c10484 100644
--- a/include/lib/cpus/aarch64/neoverse_v1.h
+++ b/include/lib/cpus/aarch64/neoverse_v1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,4 +41,6 @@
 #define NEOVERSE_V1_ACTLR2_EL1_BIT_28				(ULL(1) << 28)
 #define NEOVERSE_V1_ACTLR2_EL1_BIT_40				(ULL(1) << 40)
 
+#define NEOVERSE_V1_ACTLR3_EL1					S3_0_C15_C1_2
+
 #endif /* NEOVERSE_V1_H */
diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h
index 43f298e..3554673 100644
--- a/include/lib/fconf/fconf_dyn_cfg_getter.h
+++ b/include/lib/fconf/fconf_dyn_cfg_getter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,12 +19,11 @@
 	uint32_t config_max_size;
 	unsigned int config_id;
 	/*
-	 * Load address in non-secure memory. Only needed by those
-	 * configuration files which require being loaded in secure
-	 * memory (at config_addr) as well as in non-secure memory
+	 * A platform uses this address to copy the configuration
+	 * to another location during the boot-flow.
 	 * - e.g. HW_CONFIG
 	 */
-	uintptr_t ns_config_addr;
+	uintptr_t secondary_config_addr;
 };
 
 unsigned int dyn_cfg_dtb_info_get_index(unsigned int config_id);
@@ -32,7 +31,7 @@
 int fconf_populate_dtb_registry(uintptr_t config);
 
 /* Set config information in global DTB array */
-void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+void set_config_info(uintptr_t config_addr, uintptr_t secondary_config_addr,
 		     uint32_t config_max_size,
 		     unsigned int config_id);
 
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/lib/psa/psa_manifest/sid.h b/include/lib/psa/psa_manifest/sid.h
index 0bdeed4..be78bae 100644
--- a/include/lib/psa/psa_manifest/sid.h
+++ b/include/lib/psa/psa_manifest/sid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -8,6 +8,9 @@
 #ifndef PSA_MANIFEST_SID_H
 #define PSA_MANIFEST_SID_H
 
+/******** RSS_SP_PLATFORM ********/
+#define RSS_PLATFORM_SERVICE_HANDLE			(0x40000105U)
+
 /******** PSA_SP_MEASURED_BOOT ********/
 #define RSS_MEASURED_BOOT_HANDLE			(0x40000110U)
 
diff --git a/include/lib/psa/rss_platform_api.h b/include/lib/psa/rss_platform_api.h
new file mode 100644
index 0000000..1dd7d05
--- /dev/null
+++ b/include/lib/psa/rss_platform_api.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef RSS_PLATFORM_API_H
+#define RSS_PLATFORM_API_H
+
+#include <stdint.h>
+
+#include "psa/error.h"
+
+#define RSS_PLATFORM_API_ID_NV_READ       (1010)
+#define RSS_PLATFORM_API_ID_NV_INCREMENT  (1011)
+
+/*
+ * Increments the given non-volatile (NV) counter by one
+ *
+ * counter_id	NV counter ID.
+ *
+ * PSA_SUCCESS if the value is read correctly. Otherwise,
+ *	it returns a PSA_ERROR.
+ */
+psa_status_t
+rss_platform_nv_counter_increment(uint32_t counter_id);
+
+/*
+ * Reads the given non-volatile (NV) counter
+ *
+ * counter_id	NV counter ID.
+ * size		Size of the buffer to store NV counter value
+ *			in bytes.
+ * val		Pointer to store the current NV counter value.
+ *
+ * PSA_SUCCESS if the value is read correctly. Otherwise,
+ *	it returns a PSA_ERROR.
+ */
+psa_status_t
+rss_platform_nv_counter_read(uint32_t counter_id,
+		uint32_t size, uint8_t *val);
+
+#endif /* RSS_PLATFORM_API_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/compiler-rt/builtins/arm/aeabi_memset.S b/lib/compiler-rt/builtins/arm/aeabi_memset.S
new file mode 100644
index 0000000..2aa8ec0
--- /dev/null
+++ b/lib/compiler-rt/builtins/arm/aeabi_memset.S
@@ -0,0 +1,49 @@
+//===-- aeabi_memset.S - EABI memset implementation -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+//  void __aeabi_memset(void *dest, size_t n, int c) { memset(dest, c, n); }
+//  void __aeabi_memclr(void *dest, size_t n) { __aeabi_memset(dest, n, 0); }
+
+        .syntax unified
+        .p2align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memset)
+        mov     r3, r1
+        mov     r1, r2
+        mov     r2, r3
+#ifdef USE_THUMB_1
+        push    {r7, lr}
+        bl      memset
+        pop     {r7, pc}
+#else
+        b       memset
+#endif
+END_COMPILERRT_FUNCTION(__aeabi_memset)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset4, __aeabi_memset)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset8, __aeabi_memset)
+
+        .p2align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_memclr)
+        mov     r2, r1
+        movs    r1, #0
+#ifdef USE_THUMB_1
+        push    {r7, lr}
+        bl      memset
+        pop     {r7, pc}
+#else
+        b       memset
+#endif
+END_COMPILERRT_FUNCTION(__aeabi_memclr)
+
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr)
+DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr)
+
+NO_EXEC_STACK_DIRECTIVE
+
diff --git a/lib/compiler-rt/compiler-rt.mk b/lib/compiler-rt/compiler-rt.mk
index 2338908..b41c4d0 100644
--- a/lib/compiler-rt/compiler-rt.mk
+++ b/lib/compiler-rt/compiler-rt.mk
@@ -35,6 +35,7 @@
 COMPILER_RT_SRCS	+=	lib/compiler-rt/builtins/arm/aeabi_ldivmod.S	\
 				lib/compiler-rt/builtins/arm/aeabi_uldivmod.S	\
 				lib/compiler-rt/builtins/arm/aeabi_memcpy.S	\
+				lib/compiler-rt/builtins/arm/aeabi_memset.S	\
 				lib/compiler-rt/builtins/ctzdi2.c		\
 				lib/compiler-rt/builtins/divdi3.c		\
 				lib/compiler-rt/builtins/divmoddi4.c		\
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index f7f8027..886e1f3 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -361,6 +361,45 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2666669
 
+/* ------------------------------------------------------
+ * Errata Workaround for Cortex-A510 Erratum 2684597.
+ * This erratum applies to revision r0p0, r0p1, r0p2,
+ * r0p3, r1p0, r1p1 and r1p2 of the Cortex-A510 cpu and
+ * is fixed in r1p3.
+ * Shall clobber: x0-x17
+ * ------------------------------------------------------
+ */
+	.globl	errata_cortex_a510_2684597_wa
+func errata_cortex_a510_2684597_wa
+	mov	x17, x30
+	/* Ensure this errata is only applied to Cortex-A510 cores */
+	jump_if_cpu_midr	CORTEX_A510_MIDR,	1f
+	b	2f
+
+1:
+	/* Check workaround compatibility. */
+	mov	x0, x18
+	bl	check_errata_2684597
+	cbz	x0, 2f
+
+	tsb	csync
+2:
+	ret	x17
+endfunc errata_cortex_a510_2684597_wa
+/* ------------------------------------------------------
+ * Errata Workaround for Cortex-A510 Erratum 2684597.
+ * This erratum applies to revision r0p0, r0p1, r0p2,
+ * r0p3, r1p0, r1p1 and r1p2 of the Cortex-A510 cpu and
+ * is fixed in r1p3.
+ * Shall clobber: x0-x17
+ * ------------------------------------------------------
+ */
+func check_errata_2684597
+	/* Applies to revision < r1p3 */
+	mov	x1, #0x12
+	b	cpu_rev_var_ls
+endfunc check_errata_2684597
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -401,6 +440,7 @@
 	report_errata ERRATA_A510_2347730, cortex_a510, 2347730
 	report_errata ERRATA_A510_2371937, cortex_a510, 2371937
 	report_errata ERRATA_A510_2666669, cortex_a510, 2666669
+	report_errata ERRATA_A510_2684597, cortex_a510, 2684597
 	report_errata ERRATA_DSU_2313941, cortex_a510, dsu_2313941
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 38f58bb..a3932e8 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -351,6 +351,35 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2772019
 
+/* ----------------------------------------------------
+ * Errata Workaround for Cortex A78 Errata 2779479.
+ * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
+ * It is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * ----------------------------------------------------
+ */
+func errata_a78_2779479_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2779479
+	cbz	x0, 1f
+
+	/* Apply the workaround */
+	mrs	x1, CORTEX_A78_ACTLR3_EL1
+	orr	x1, x1, #BIT(47)
+	msr	CORTEX_A78_ACTLR3_EL1, x1
+
+1:
+	ret	x17
+endfunc errata_a78_2779479_wa
+
+func check_errata_2779479
+	/* Applies to r0p0, r1p0, r1p1, r1p2 */
+	mov	x1, #CPU_REV(1, 2)
+	b	cpu_rev_var_ls
+endfunc check_errata_2779479
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -414,6 +443,11 @@
 	bl	errata_a78_2395406_wa
 #endif
 
+#if ERRATA_A78_2779479
+	mov	x0, x18
+	bl	errata_a78_2779479_wa
+#endif
+
 #if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
@@ -493,6 +527,7 @@
 	report_errata ERRATA_A78_2376745, cortex_a78, 2376745
 	report_errata ERRATA_A78_2395406, cortex_a78, 2395406
 	report_errata ERRATA_A78_2772019, cortex_a78, 2772019
+	report_errata ERRATA_A78_2779479, cortex_a78, 2779479
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a78, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 49cebfe..5cdce89 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -117,13 +117,13 @@
 	b	cpu_rev_var_range
 endfunc check_errata_2132064
 
-/* --------------------------------------------------------------------
+/* ----------------------------------------------------------
  * Errata Workaround for A78C Erratum 2242638.
  * This applies to revisions r0p1 and r0p2 of the Cortex A78C
  * processor and is still open.
  * x0: variant[4:7] and revision[0:3] of current cpu.
  * Shall clobber: x0-x17
- * --------------------------------------------------------------------
+ * ----------------------------------------------------------
  */
 func errata_a78c_2242638_wa
 	/* Compare x0 against revisions r0p1 - r0p2 */
@@ -152,6 +152,31 @@
 	b	cpu_rev_var_range
 endfunc check_errata_2242638
 
+/* ----------------------------------------------------------------
+ * Errata Workaround for A78C Erratum 2772121.
+ * This applies to revisions r0p0, r0p1 and r0p2 of the Cortex A78C
+ * processor and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ----------------------------------------------------------------
+ */
+func errata_a78c_2772121_wa
+	mov	x17, x30
+	bl	check_errata_2772121
+	cbz	x0, 1f
+
+	/* dsb before isb of power down sequence */
+	dsb	sy
+1:
+	ret	x17
+endfunc errata_a78c_2772121_wa
+
+func check_errata_2772121
+	/* Applies to all revisions <= r0p2 */
+	mov	x1, #0x02
+	b	cpu_rev_var_ls
+endfunc check_errata_2772121
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -215,6 +240,12 @@
 	mrs	x0, CORTEX_A78C_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 	msr	CORTEX_A78C_CPUPWRCTLR_EL1, x0
+#if ERRATA_A78C_2772121
+	mov	x15, x30
+	bl	cpu_get_rev_var
+	bl	errata_a78c_2772121_wa
+	mov	x30, x15
+#endif /* ERRATA_A78C_2772121 */
 	isb
 	ret
 endfunc cortex_a78c_core_pwr_dwn
@@ -237,6 +268,7 @@
 	report_errata ERRATA_A78C_2242638, cortex_a78c, 2242638
 	report_errata ERRATA_A78C_2376749, cortex_a78c, 2376749
 	report_errata ERRATA_A78C_2395411, cortex_a78c, 2395411
+	report_errata ERRATA_A78C_2772121, cortex_a78c, 2772121
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a78c, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index c3a70ca..f9a5789 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -486,6 +486,35 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_2743093
 
+	/* ----------------------------------------------------
+ 	 * Errata Workaround for Neoverse V1 Errata #2779461.
+	 * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
+	 * It is still open.
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x1, x17
+	 * ----------------------------------------------------
+	 */
+func errata_neoverse_v1_2779461_wa
+	/* Check revision. */
+	mov	x17, x30
+	bl	check_errata_2779461
+	cbz	x0, 1f
+
+	/* Apply the workaround */
+	mrs	x1, NEOVERSE_V1_ACTLR3_EL1
+	orr	x1, x1, #BIT(47)
+	msr	NEOVERSE_V1_ACTLR3_EL1, x1
+
+1:
+	ret	x17
+endfunc errata_neoverse_v1_2779461_wa
+
+func check_errata_2779461
+	/* Applies to r0p0, r1p0, r1p1, r1p2 */
+	mov	x1, #CPU_REV(1, 2)
+	b	cpu_rev_var_ls
+endfunc check_errata_2779461
+
 func check_errata_cve_2022_23960
 #if WORKAROUND_CVE_2022_23960
 	mov	x0, #ERRATA_APPLIES
@@ -544,6 +573,7 @@
 	report_errata ERRATA_V1_2294912, neoverse_v1, 2294912
 	report_errata ERRATA_V1_2372203, neoverse_v1, 2372203
 	report_errata ERRATA_V1_2743093, neoverse_v1, 2743093
+	report_errata ERRATA_V1_2779461, neoverse_v1, 2779461
 	report_errata WORKAROUND_CVE_2022_23960, neoverse_v1, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
@@ -622,6 +652,11 @@
 	bl	errata_neoverse_v1_2372203_wa
 #endif
 
+#if ERRATA_V1_2779461
+	mov	x0, x18
+	bl	errata_neoverse_v1_2779461_wa
+#endif
+
 #if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
 	/*
 	 * The Neoverse-V1 generic vectors are overridden to apply errata
diff --git a/lib/cpus/aarch64/runtime_errata.S b/lib/cpus/aarch64/runtime_errata.S
new file mode 100644
index 0000000..8d46691
--- /dev/null
+++ b/lib/cpus/aarch64/runtime_errata.S
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <cortex_a510.h>
+#include <cpu_macros.S>
+
+/*
+ * void apply_cpu_pwr_dwn_errata(void);
+ *
+ * This function applies various CPU errata during power down.
+ */
+	.globl apply_cpu_pwr_dwn_errata
+func apply_cpu_pwr_dwn_errata
+	mov	x19, x30
+	bl      cpu_get_rev_var
+	mov	x18, x0
+
+#if ERRATA_A510_2684597
+	bl errata_cortex_a510_2684597_wa
+#endif
+
+	ret	x19
+endfunc apply_cpu_pwr_dwn_errata
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index c9b4447..4582f28 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -362,6 +362,10 @@
 # open.
 ERRATA_A78_2772019	?=0
 
+# Flag to apply erratum 2779479 workaround during reset. This erratum applies
+# to revision r0p0, r1p0, r1p1 and r1p2 of the A78 cpu. It is still open.
+ERRATA_A78_2779479	?=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
@@ -394,6 +398,10 @@
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
 ERRATA_A78C_2395411 	?=0
 
+# Flag to apply erratum 2772121 workaround during powerdown. This erratum
+# applies to revisions r0p0, r0p1 and r0p2 of the A78C cpu. It is still open.
+ERRATA_A78C_2772121 	?=0
+
 # Flag to apply erratum 1821534 workaround during reset. This erratum applies
 # to revisions r0p0 - r1p0 of the X1 cpu and fixed in r1p1.
 ERRATA_X1_1821534	?=0
@@ -522,6 +530,11 @@
 # still open.
 ERRATA_V1_2743093	?=0
 
+# Flag to apply erratum 2779461 workaround during powerdown. This erratum
+# applies to revisions r0p0, r1p0, r1p1 and r1p2  of the Neoverse V1 cpu and is
+# still open.
+ERRATA_V1_2779461       ?=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
@@ -736,6 +749,11 @@
 # to revisions r0p0, r0p1, r0p2, r0p3, r1p0, and r1p1. It is fixed in r1p2.
 ERRATA_A510_2666669	?=0
 
+# Flag to apply erratum 2684597 workaround during powerdown. This erratum
+# applies to revision r0p0, r0p1, r0p2, r0p3, r1p0, r1p1 and r1p2 of the
+# Cortex-A510 cpu and is fixed in r1p3.
+ERRATA_A510_2684597	?=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
@@ -1030,6 +1048,10 @@
 $(eval $(call assert_boolean,ERRATA_A78_2772019))
 $(eval $(call add_define,ERRATA_A78_2772019))
 
+# Process ERRATA_A78_2779479 flag
+$(eval $(call assert_boolean,ERRATA_A78_2779479))
+$(eval $(call add_define,ERRATA_A78_2779479))
+
 # Process ERRATA_A78_AE_1941500 flag
 $(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
 $(eval $(call add_define,ERRATA_A78_AE_1941500))
@@ -1062,6 +1084,10 @@
 $(eval $(call assert_boolean,ERRATA_A78C_2395411))
 $(eval $(call add_define,ERRATA_A78C_2395411))
 
+# Process ERRATA_A78C_2772121 flag
+$(eval $(call assert_boolean,ERRATA_A78C_2772121))
+$(eval $(call add_define,ERRATA_A78C_2772121))
+
 # Process ERRATA_X1_1821534 flag
 $(eval $(call assert_boolean,ERRATA_X1_1821534))
 $(eval $(call add_define,ERRATA_X1_1821534))
@@ -1186,6 +1212,10 @@
 $(eval $(call assert_boolean,ERRATA_V1_2743093))
 $(eval $(call add_define,ERRATA_V1_2743093))
 
+# Process ERRATA_V1_2779461 flag
+$(eval $(call assert_boolean,ERRATA_V1_2779461))
+$(eval $(call add_define,ERRATA_V1_2779461))
+
 # Process ERRATA_A710_1987031 flag
 $(eval $(call assert_boolean,ERRATA_A710_1987031))
 $(eval $(call add_define,ERRATA_A710_1987031))
@@ -1390,6 +1420,10 @@
 $(eval $(call assert_boolean,ERRATA_A510_2666669))
 $(eval $(call add_define,ERRATA_A510_2666669))
 
+# Process ERRATA_A510_2684597 flag
+$(eval $(call assert_boolean,ERRATA_A510_2684597))
+$(eval $(call add_define,ERRATA_A510_2684597))
+
 #Process ERRATA_DSU_798953 flag
 $(eval $(call assert_boolean,ERRATA_DSU_798953))
 $(eval $(call add_define,ERRATA_DSU_798953))
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index b5d61ff..722b8ae 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -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
  */
@@ -257,52 +257,200 @@
 	mrs	x10, MPAM2_EL2
 	str	x10, [x0, #CTX_MPAM2_EL2]
 
+	mrs	x10, MPAMIDR_EL1
+
+	/*
+	 * The context registers that we intend to save would be part of the
+	 * PE's system register frame only if MPAMIDR_EL1.HAS_HCR == 1.
+	 */
+	tbz	w10, #MPAMIDR_EL1_HAS_HCR_SHIFT, 3f
+
+	/*
+	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 would be present in the
+	 * system register frame if MPAMIDR_EL1.HAS_HCR == 1. Proceed to save
+	 * the context of these registers.
+	 */
 	mrs	x11, MPAMHCR_EL2
 	mrs	x12, MPAMVPM0_EL2
 	stp	x11, x12, [x0, #CTX_MPAMHCR_EL2]
 
-	mrs	x13, MPAMVPM1_EL2
-	mrs	x14, MPAMVPM2_EL2
-	stp	x13, x14, [x0, #CTX_MPAMVPM1_EL2]
+	mrs	x13, MPAMVPMV_EL2
+	str	x13, [x0, #CTX_MPAMVPMV_EL2]
 
-	mrs	x15, MPAMVPM3_EL2
-	mrs	x16, MPAMVPM4_EL2
-	stp	x15, x16, [x0, #CTX_MPAMVPM3_EL2]
+	/*
+	 * MPAMIDR_EL1.VPMR_MAX has to be probed to obtain the maximum supported
+	 * VPMR value. Proceed to save the context of registers from
+	 * MPAMVPM1_EL2 to MPAMVPM<x>_EL2 where x is VPMR_MAX. From MPAM spec,
+	 * VPMR_MAX should not be zero if HAS_HCR == 1.
+	 */
+	ubfx	x10, x10, #MPAMIDR_EL1_VPMR_MAX_SHIFT, \
+		#MPAMIDR_EL1_VPMR_MAX_WIDTH
 
-	mrs	x9, MPAMVPM5_EL2
-	mrs	x10, MPAMVPM6_EL2
-	stp	x9, x10, [x0, #CTX_MPAMVPM5_EL2]
+	/*
+	 * Once VPMR_MAX has been identified, calculate the offset relative to
+	 * PC to jump to so that relevant context can be saved. The offset is
+	 * calculated as (VPMR_POSSIBLE_MAX - VPMR_MAX) * (instruction size for
+	 * saving one VPM register) + (absolute address of label "1").
+	 */
+	mov	w11, #MPAMIDR_EL1_VPMR_MAX_POSSIBLE
+	sub	w10, w11, w10
 
-	mrs	x11, MPAMVPM7_EL2
-	mrs	x12, MPAMVPMV_EL2
-	stp	x11, x12, [x0, #CTX_MPAMVPM7_EL2]
-	ret
+	/* Calculate the size of one block of MPAMVPM*_EL2 save */
+	adr	x11, 1f
+	adr	x12, 2f
+	sub	x12, x12, x11
+
+	madd	x10, x10, x12, x11
+	br	x10
+
+	/*
+	 * The branch above would land properly on one of the blocks following
+	 * label "1". Make sure that the order of save is retained.
+	 */
+1:
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x10, MPAMVPM7_EL2
+	str	x10, [x0, #CTX_MPAMVPM7_EL2]
+2:
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x11, MPAMVPM6_EL2
+	str	x11, [x0, #CTX_MPAMVPM6_EL2]
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x12, MPAMVPM5_EL2
+	str	x12, [x0, #CTX_MPAMVPM5_EL2]
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x13, MPAMVPM4_EL2
+	str	x13, [x0, #CTX_MPAMVPM4_EL2]
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x14, MPAMVPM3_EL2
+	str	x14, [x0, #CTX_MPAMVPM3_EL2]
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x15, MPAMVPM2_EL2
+	str	x15, [x0, #CTX_MPAMVPM2_EL2]
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	mrs	x16, MPAMVPM1_EL2
+	str	x16, [x0, #CTX_MPAMVPM1_EL2]
+
+3:	ret
 endfunc el2_sysregs_context_save_mpam
 
 func el2_sysregs_context_restore_mpam
 	ldr	x10, [x0, #CTX_MPAM2_EL2]
 	msr	MPAM2_EL2, x10
 
+	mrs	x10, MPAMIDR_EL1
+	/*
+	 * The context registers that we intend to restore would be part of the
+	 * PE's system register frame only if MPAMIDR_EL1.HAS_HCR == 1.
+	 */
+	tbz	w10, #MPAMIDR_EL1_HAS_HCR_SHIFT, 3f
+
+	/*
+	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 would be present in the
+	 * system register frame if MPAMIDR_EL1.HAS_HCR == 1. Proceed to restore
+	 * the context of these registers
+	 */
 	ldp	x11, x12, [x0, #CTX_MPAMHCR_EL2]
 	msr	MPAMHCR_EL2, x11
 	msr	MPAMVPM0_EL2, x12
 
-	ldp	x13, x14, [x0, #CTX_MPAMVPM1_EL2]
-	msr	MPAMVPM1_EL2, x13
-	msr	MPAMVPM2_EL2, x14
+	ldr	x13, [x0, #CTX_MPAMVPMV_EL2]
+	msr	MPAMVPMV_EL2, x13
 
-	ldp	x15, x16, [x0, #CTX_MPAMVPM3_EL2]
-	msr	MPAMVPM3_EL2, x15
-	msr	MPAMVPM4_EL2, x16
+	/*
+	 * MPAMIDR_EL1.VPMR_MAX has to be probed to obtain the maximum supported
+	 * VPMR value. Proceed to restore the context of registers from
+	 * MPAMVPM1_EL2 to MPAMVPM<x>_EL2 where x is VPMR_MAX. from MPAM spec,
+	 * VPMR_MAX should not be zero if HAS_HCR == 1.
+	 */
+	ubfx	x10, x10, #MPAMIDR_EL1_VPMR_MAX_SHIFT,	\
+		#MPAMIDR_EL1_VPMR_MAX_WIDTH
 
-	ldp	x9, x10, [x0, #CTX_MPAMVPM5_EL2]
-	msr	MPAMVPM5_EL2, x9
-	msr	MPAMVPM6_EL2, x10
+	/*
+	 * Once VPMR_MAX has been identified, calculate the offset relative to
+	 * PC to jump to so that relevant context can be restored. The offset is
+	 * calculated as (VPMR_POSSIBLE_MAX - VPMR_MAX) * (instruction size for
+	 * restoring one VPM register) + (absolute address of label "1").
+	 */
+	mov	w11, #MPAMIDR_EL1_VPMR_MAX_POSSIBLE
+	sub	w10, w11, w10
 
-	ldp	x11, x12, [x0, #CTX_MPAMVPM7_EL2]
-	msr	MPAMVPM7_EL2, x11
-	msr	MPAMVPMV_EL2, x12
-	ret
+	/* Calculate the size of one block of MPAMVPM*_EL2 restore */
+	adr	x11, 1f
+	adr	x12, 2f
+	sub	x12, x12, x11
+
+	madd	x10, x10, x12, x11
+	br	x10
+
+	/*
+	 * The branch above would land properly on one of the blocks following
+	 * label "1". Make sure that the order of restore is retained.
+	 */
+1:
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x10, [x0, #CTX_MPAMVPM7_EL2]
+	msr	MPAMVPM7_EL2, x10
+2:
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x11, [x0, #CTX_MPAMVPM6_EL2]
+	msr	MPAMVPM6_EL2, x11
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x12, [x0, #CTX_MPAMVPM5_EL2]
+	msr	MPAMVPM5_EL2, x12
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x13, [x0, #CTX_MPAMVPM4_EL2]
+	msr	MPAMVPM4_EL2, x13
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x14, [x0, #CTX_MPAMVPM3_EL2]
+	msr	MPAMVPM3_EL2, x14
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x15, [x0, #CTX_MPAMVPM2_EL2]
+	msr	MPAMVPM2_EL2, x15
+
+#if ENABLE_BTI
+	bti	j
+#endif
+	ldr	x16, [x0, #CTX_MPAMVPM1_EL2]
+	msr	MPAMVPM1_EL2, x16
+
+3:	ret
 endfunc el2_sysregs_context_restore_mpam
 #endif /* ENABLE_MPAM_FOR_LOWER_ELS */
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 3bcefdb..dab25d6 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.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.
  * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -169,7 +169,12 @@
 	state = get_el3state_ctx(ctx);
 	scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
 
-	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT | SCR_EnSCXT_BIT;
+	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT;
+
+#if ENABLE_FEAT_CSV2_2
+	/* Enable access to the SCXTNUM_ELx registers. */
+	scr_el3 |= SCR_EnSCXT_BIT;
+#endif
 
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 }
@@ -222,6 +227,11 @@
 	scr_el3 |= SCR_TERR_BIT;
 #endif
 
+#if ENABLE_FEAT_CSV2_2
+	/* Enable access to the SCXTNUM_ELx registers. */
+	scr_el3 |= SCR_EnSCXT_BIT;
+#endif
+
 #ifdef IMAGE_BL31
 	/*
 	 * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
index 351772e..13081b0 100644
--- a/lib/fconf/fconf_dyn_cfg_getter.c
+++ b/lib/fconf/fconf_dyn_cfg_getter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,7 +31,7 @@
  * This function is used to alloc memory for config information from
  * global pool and set the configuration information.
  */
-void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+void set_config_info(uintptr_t config_addr, uintptr_t secondary_config_addr,
 		     uint32_t config_max_size,
 		     unsigned int config_id)
 {
@@ -39,7 +39,7 @@
 
 	dtb_info = pool_alloc(&dtb_info_pool);
 	dtb_info->config_addr = config_addr;
-	dtb_info->ns_config_addr = ns_config_addr;
+	dtb_info->secondary_config_addr = secondary_config_addr;
 	dtb_info->config_max_size = config_max_size;
 	dtb_info->config_id = config_id;
 }
@@ -106,7 +106,7 @@
 	fdt_for_each_subnode(child, dtb, node) {
 		uint32_t config_max_size, config_id;
 		uintptr_t config_addr;
-		uintptr_t ns_config_addr = ~0UL;
+		uintptr_t secondary_config_addr = ~0UL;
 		uint64_t val64;
 
 		/* Read configuration dtb information */
@@ -134,14 +134,16 @@
 		VERBOSE("\tmax-size = 0x%x\n", config_max_size);
 		VERBOSE("\tconfig-id = %u\n", config_id);
 
-		rc = fdt_read_uint64(dtb, child, "ns-load-address", &val64);
+		rc = fdt_read_uint64(dtb, child, "secondary-load-address",
+				     &val64);
 		if (rc == 0) {
-			ns_config_addr = (uintptr_t)val64;
-			VERBOSE("\tns-load-address = %lx\n", ns_config_addr);
+			secondary_config_addr = (uintptr_t)val64;
+			VERBOSE("\tsecondary-load-address = %lx\n",
+				secondary_config_addr);
 		}
 
-		set_config_info(config_addr, ns_config_addr, config_max_size,
-				config_id);
+		set_config_info(config_addr, secondary_config_addr,
+				config_max_size, config_id);
 	}
 
 	if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
diff --git a/lib/libc/putchar.c b/lib/libc/putchar.c
index 3472b24..340bdd8 100644
--- a/lib/libc/putchar.c
+++ b/lib/libc/putchar.c
@@ -1,14 +1,13 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdio.h>
 
-int __putchar(int c)
+#pragma weak putchar
+int putchar(int c)
 {
 	return c;
 }
-
-int putchar(int c) __attribute__((weak,alias("__putchar")));
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/lib/psa/rss_platform.c b/lib/psa/rss_platform.c
new file mode 100644
index 0000000..359f894
--- /dev/null
+++ b/lib/psa/rss_platform.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+
+#include <psa/client.h>
+#include <psa_manifest/sid.h>
+#include <rss_platform_api.h>
+
+psa_status_t
+rss_platform_nv_counter_increment(uint32_t counter_id)
+{
+	struct psa_invec in_vec[1];
+
+	in_vec[0].base = &counter_id;
+	in_vec[0].len = sizeof(counter_id);
+
+	return psa_call(RSS_PLATFORM_SERVICE_HANDLE,
+			RSS_PLATFORM_API_ID_NV_INCREMENT,
+			in_vec, 1, NULL, 0);
+}
+
+psa_status_t
+rss_platform_nv_counter_read(uint32_t counter_id,
+		uint32_t size, uint8_t *val)
+{
+	struct psa_invec in_vec[1];
+	struct psa_outvec out_vec[1];
+
+	in_vec[0].base = &counter_id;
+	in_vec[0].len = sizeof(counter_id);
+
+	out_vec[0].base = val;
+	out_vec[0].len = size;
+
+	return psa_call(RSS_PLATFORM_SERVICE_HANDLE,
+			RSS_PLATFORM_API_ID_NV_READ,
+			in_vec, 1, out_vec, 1);
+}
diff --git a/lib/psci/aarch32/psci_helpers.S b/lib/psci/aarch32/psci_helpers.S
index 5cc192e..d28d469 100644
--- a/lib/psci/aarch32/psci_helpers.S
+++ b/lib/psci/aarch32/psci_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -143,6 +143,7 @@
  */
 func psci_power_down_wfi
 	dsb	sy		// ensure write buffer empty
+1:
 	wfi
-	no_ret	plat_panic_handler
+	b	1b
 endfunc psci_power_down_wfi
diff --git a/lib/psci/aarch64/psci_helpers.S b/lib/psci/aarch64/psci_helpers.S
index add968a..61f31e5 100644
--- a/lib/psci/aarch64/psci_helpers.S
+++ b/lib/psci/aarch64/psci_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -124,7 +124,11 @@
  * -----------------------------------------------------------------------
  */
 func psci_power_down_wfi
+#if ERRATA_A510_2684597
+	bl apply_cpu_pwr_dwn_errata
+#endif
 	dsb	sy		// ensure write buffer empty
+1:
 	wfi
-	no_ret	plat_panic_handler
+	b	1b
 endfunc psci_power_down_wfi
diff --git a/lib/psci/psci_lib.mk b/lib/psci/psci_lib.mk
index 1d4aac4..6864202 100644
--- a/lib/psci/psci_lib.mk
+++ b/lib/psci/psci_lib.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -21,7 +21,8 @@
 				lib/psci/${ARCH}/psci_helpers.S
 
 ifeq (${ARCH}, aarch64)
-PSCI_LIB_SOURCES	+=	lib/el3_runtime/aarch64/context.S
+PSCI_LIB_SOURCES	+=	lib/el3_runtime/aarch64/context.S	\
+				lib/cpus/aarch64/runtime_errata.S
 endif
 
 ifeq (${USE_COHERENT_MEM}, 1)
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 1901c17..6ca9ef6 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -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
  */
@@ -304,6 +304,9 @@
  */
 void prepare_cpu_pwr_dwn(unsigned int power_level);
 
+/* This function applies various CPU errata during power down. */
+void apply_cpu_pwr_dwn_errata(void);
+
 /* Private exported functions from psci_on.c */
 int psci_cpu_on_start(u_register_t target_cpu,
 		      const entry_point_info_t *ep);
diff --git a/lib/romlib/romlib.ld.S b/lib/romlib/romlib.ld.S
index 2aac4ad..d54a684 100644
--- a/lib/romlib/romlib.ld.S
+++ b/lib/romlib/romlib.ld.S
@@ -8,37 +8,42 @@
 #include <platform_def.h>
 
 MEMORY {
-	ROM (rx): ORIGIN = ROMLIB_RO_BASE, LENGTH = ROMLIB_RO_LIMIT - ROMLIB_RO_BASE
-	RAM (rwx): ORIGIN = ROMLIB_RW_BASE, LENGTH = ROMLIB_RW_END - ROMLIB_RW_BASE
+    ROM (rx): ORIGIN = ROMLIB_RO_BASE, LENGTH = ROMLIB_RO_LIMIT - ROMLIB_RO_BASE
+    RAM (rwx): ORIGIN = ROMLIB_RW_BASE, LENGTH = ROMLIB_RW_END - ROMLIB_RW_BASE
 }
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(jmptbl)
 
-SECTIONS
-{
-	. = ROMLIB_RO_BASE;
-	.text : {
-		*jmptbl.o(.text)
-		*(.text*)
-		*(.rodata*)
-	} >ROM
+SECTIONS {
+    . = ROMLIB_RO_BASE;
 
-	__DATA_ROM_START__ = LOADADDR(.data);
+    .text : {
+        *jmptbl.o(.text)
+        *(.text*)
+        *(.rodata*)
+    } >ROM
 
-	.data : {
-		__DATA_RAM_START__ = .;
-		*(.data*)
-		__DATA_RAM_END__ = .;
-	} >RAM AT>ROM
+    __DATA_ROM_START__ = LOADADDR(.data);
 
-	__DATA_SIZE__ = SIZEOF(.data);
+    .data : {
+        __DATA_RAM_START__ = .;
+
+        *(.data*)
+
+        __DATA_RAM_END__ = .;
+    } >RAM AT>ROM
+
+    __DATA_SIZE__ = SIZEOF(.data);
+
+    .bss : {
+        __BSS_START__ = .;
+
+        *(.bss*)
+
+        __BSS_END__ = .;
+     } >RAM
 
-	.bss : {
-		__BSS_START__ = .;
-		*(.bss*)
-		__BSS_END__ = .;
-	 } >RAM
-	__BSS_SIZE__ = SIZEOF(.bss);
+    __BSS_SIZE__ = SIZEOF(.bss);
 }
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 426e344..a6b1d52 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -13,6 +13,7 @@
 # Some utility macros for manipulating awkward (whitespace) characters.
 blank			:=
 space			:=${blank} ${blank}
+comma			:= ,
 
 # A user defined function to recursively search for a filename below a directory
 #    $1 is the directory root of the recursive search (blank for current directory).
@@ -97,12 +98,6 @@
 )
 endef
 
-# IMG_LINKERFILE defines the linker script corresponding to a BL stage
-#   $(1) = BL stage
-define IMG_LINKERFILE
-    ${BUILD_DIR}/$(1).ld
-endef
-
 # IMG_MAPFILE defines the output file describing the memory map corresponding
 # to a BL stage
 #   $(1) = BL stage
@@ -457,6 +452,15 @@
 	$$(Q)$$(AR) cr $$@ $$?
 endef
 
+# Generate the path to one or more preprocessed linker scripts given the paths
+# of their sources.
+#
+# Arguments:
+#   $(1) = path to one or more linker script sources
+define linker_script_path
+        $(patsubst %.S,$(BUILD_DIR)/%,$(1))
+endef
+
 # MAKE_BL macro defines the targets and options to build each BL image.
 # Arguments:
 #   $(1) = BL stage
@@ -468,17 +472,22 @@
         $(eval BL_SOURCES := $($(call uppercase,$(1))_SOURCES))
         $(eval SOURCES    := $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
-        $(eval LINKERFILE := $(call IMG_LINKERFILE,$(1)))
         $(eval MAPFILE    := $(call IMG_MAPFILE,$(1)))
         $(eval ELF        := $(call IMG_ELF,$(1)))
         $(eval DUMP       := $(call IMG_DUMP,$(1)))
         $(eval BIN        := $(call IMG_BIN,$(1)))
         $(eval ENC_BIN    := $(call IMG_ENC_BIN,$(1)))
-        $(eval BL_LINKERFILE := $($(call uppercase,$(1))_LINKERFILE))
         $(eval BL_LIBS    := $($(call uppercase,$(1))_LIBS))
+
+        $(eval DEFAULT_LINKER_SCRIPT_SOURCE := $($(call uppercase,$(1))_DEFAULT_LINKER_SCRIPT_SOURCE))
+        $(eval DEFAULT_LINKER_SCRIPT := $(call linker_script_path,$(DEFAULT_LINKER_SCRIPT_SOURCE)))
+
+        $(eval LINKER_SCRIPT_SOURCES := $($(call uppercase,$(1))_LINKER_SCRIPT_SOURCES))
+        $(eval LINKER_SCRIPTS := $(call linker_script_path,$(LINKER_SCRIPT_SOURCES)))
+
         # We use sort only to get a list of unique object directory names.
         # ordering is not relevant but sort removes duplicates.
-        $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS} ${LINKERFILE})))
+        $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS} ${DEFAULT_LINKER_SCRIPT} ${LINKER_SCRIPTS})))
         # The $(dir ) function leaves a trailing / on the directory names
         # Rip off the / to match directory names with make rule targets.
         $(eval OBJ_DIRS   := $(patsubst %/,%,$(TEMP_OBJ_DIRS)))
@@ -487,7 +496,8 @@
 
 $(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
 
-$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
+$(eval $(foreach objd,${OBJ_DIRS},
+        $(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
 
 .PHONY : ${1}_dirs
 
@@ -496,7 +506,11 @@
 ${1}_dirs: | ${OBJ_DIRS}
 
 $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
-$(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE),$(1)))
+
+# Generate targets to preprocess each required linker script
+$(eval $(foreach source,$(DEFAULT_LINKER_SCRIPT_SOURCE) $(LINKER_SCRIPT_SOURCES), \
+        $(call MAKE_LD,$(call linker_script_path,$(source)),$(source),$(1))))
+
 $(eval BL_LDFLAGS := $($(call uppercase,$(1))_LDFLAGS))
 
 ifeq ($(USE_ROMLIB),1)
@@ -507,7 +521,7 @@
 # object file path, and prebuilt object file path.
 $(eval OBJS += $(MODULE_OBJS))
 
-$(ELF): $(OBJS) $(LINKERFILE) | $(1)_dirs libraries $(BL_LIBS)
+$(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $(1)_dirs libraries $(BL_LIBS)
 	$$(ECHO) "  LD      $$@"
 ifdef MAKE_BUILD_STRINGS
 	$(call MAKE_BUILD_STRINGS, $(BUILD_DIR)/build_message.o)
@@ -526,11 +540,13 @@
 		$(BUILD_DIR)/build_message.o $(OBJS)
 else ifneq ($(findstring gcc,$(notdir $(LD))),)
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \
-		-Wl,-dT $(LINKERFILE) $(EXTRA_LINKERFILE) $(BUILD_DIR)/build_message.o \
+		$(addprefix -Wl$(comma)--script$(comma),$(LINKER_SCRIPTS)) -Wl,--script,$(DEFAULT_LINKER_SCRIPT) \
+		$(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 else
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
-		--script $(LINKERFILE) $(BUILD_DIR)/build_message.o \
+		$(addprefix -T ,$(LINKER_SCRIPTS)) --script $(DEFAULT_LINKER_SCRIPT) \
+		$(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 endif
 ifeq ($(DISABLE_BIN_GENERATION),1)
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index d298e6b..1257076 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -8,8 +8,10 @@
 #include <errno.h>
 
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/allwinner/axp.h>
 #include <drivers/allwinner/sunxi_rsb.h>
+#include <libfdt.h>
 #include <lib/mmio.h>
 
 #include <sunxi_cpucfg.h>
@@ -63,7 +65,12 @@
 
 int sunxi_pmic_setup(uint16_t socid, const void *fdt)
 {
-	int ret;
+	int node, ret;
+
+	node = fdt_node_offset_by_compatible(fdt, 0, "allwinner,sun8i-a23-rsb");
+	if ((node < 0) || !fdt_node_is_enabled(fdt, node)) {
+		return -ENODEV;
+	}
 
 	INFO("PMIC: Probing AXP805 on RSB\n");
 
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/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index 577ac74..4adf5d5 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,7 +22,7 @@
 			load-address = <0x0 0x07f00000>;
 			max-size = <0x00100000>;
 			id = <HW_CONFIG_ID>;
-			ns-load-address = <0x0 0x82000000>;
+			secondary-load-address = <0x0 0x82000000>;
 		};
 
 		/*
@@ -40,7 +40,11 @@
 /* If required, SPD should enable loading of trusted OS fw config */
 #if defined(SPD_tspd) || defined(SPD_spmd)
 		tos_fw-config {
+
 			load-address = <0x0 0x04001500>;
+#if ENABLE_RME
+			secondary-load-address = <0x0 0x7e00000>;
+#endif /* ENABLE_RME */
 			max-size = <0xB00>;
 			id = <TOS_FW_CONFIG_ID>;
 		};
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 74e5d72..4c71d81 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.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
  */
@@ -82,7 +82,7 @@
 	assert(param_node != NULL);
 
 	/* Copy HW config from Secure address to NS address */
-	memcpy((void *)hw_config_info->ns_config_addr,
+	memcpy((void *)hw_config_info->secondary_config_addr,
 	       (void *)hw_config_info->config_addr,
 	       (size_t)param_node->image_info.image_size);
 
@@ -91,14 +91,14 @@
 	 * a possibility to use HW-config without cache and MMU enabled
 	 * at BL33
 	 */
-	flush_dcache_range(hw_config_info->ns_config_addr,
+	flush_dcache_range(hw_config_info->secondary_config_addr,
 			   param_node->image_info.image_size);
 
 	param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
 	assert(param_node != NULL);
 
 	/* Update BL33's ep info with NS HW config address  */
-	param_node->ep_info.args.arg1 = hw_config_info->ns_config_addr;
+	param_node->ep_info.args.arg1 = hw_config_info->secondary_config_addr;
 #endif /* !BL2_AT_EL3 && !EL3_PAYLOAD_BASE */
 
 	return arm_bl_params;
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index dd90965..57865eb 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.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
  */
@@ -45,8 +45,8 @@
 	 */
 	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
 	assert(hw_config_info != NULL);
-	assert(hw_config_info->ns_config_addr != 0UL);
-	arg2 = hw_config_info->ns_config_addr;
+	assert(hw_config_info->secondary_config_addr != 0UL);
+	arg2 = hw_config_info->secondary_config_addr;
 #endif /* !RESET_TO_BL31 && !BL2_AT_EL3 */
 
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
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/board/morello/fdts/morello_fw_config.dts b/plat/arm/board/morello/fdts/morello_fw_config.dts
index c47bae5..a63d7eb 100644
--- a/plat/arm/board/morello/fdts/morello_fw_config.dts
+++ b/plat/arm/board/morello/fdts/morello_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,8 +19,14 @@
 
 		nt_fw-config {
 			load-address = <0x0 0xFEF00000>;
-			max-size = <0x0100000>;
+			max-size = <0xF8000>;
 			id = <NT_FW_CONFIG_ID>;
 		};
+
+		hw-config {
+			load-address = <0x0 0xFEFF8000>;
+			max-size = <0x8000>;
+			id = <HW_CONFIG_ID>;
+		};
 	};
 };
diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk
index 156b7ea..0f0cabb 100644
--- a/plat/arm/board/morello/platform.mk
+++ b/plat/arm/board/morello/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -59,11 +59,14 @@
 				${MORELLO_BASE}/fdts/morello_nt_fw_config.dts
 
 FW_CONFIG		:=	${BUILD_PLAT}/fdts/morello_fw_config.dtb
+HW_CONFIG		:=	${BUILD_PLAT}/fdts/morello-${TARGET_PLATFORM}.dtb
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/morello_tb_fw_config.dtb
 NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/morello_nt_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config,${HW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
diff --git a/plat/arm/board/tc/plat_def_fip_uuid.h b/plat/arm/board/tc/plat_def_fip_uuid.h
new file mode 100644
index 0000000..631f7c9
--- /dev/null
+++ b/plat/arm/board/tc/plat_def_fip_uuid.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PLAT_DEF_FIP_UUID__
+#define __PLAT_DEF_FIP_UUID__
+
+#include "uuid.h"
+
+#define UUID_RSS_FIRMWARE_BL1_2 \
+	{{0x0a, 0xa5, 0xb1, 0xbe}, {0xe7, 0x84}, {0x41, 0xc5}, 0x81, 0xb8, {0x4a, 0x41, 0xcb, 0x4a, 0xd2, 0xdf}}
+
+#define UUID_RSS_FIRMWARE_BL2 \
+	{{0xa3, 0xb3, 0xb3, 0x0d}, {0xeb, 0xc9}, {0x40, 0x48}, 0xb4, 0x80, {0x15, 0x53, 0x61, 0xc1, 0x70, 0x48}}
+
+#define UUID_RSS_FIRMWARE_SCP_BL1 \
+	{{0xbf, 0xd5, 0x09, 0x8d}, {0xa7, 0x07}, {0x4f, 0x15}, 0x89, 0x1c, {0x37, 0x22, 0x10, 0xcb, 0x51, 0xe2}}
+
+#define UUID_RSS_FIRMWARE_AP_BL1 \
+	{{0x12, 0x4c, 0x50, 0xe0}, {0xf2, 0xda}, {0x45, 0xe9}, 0x85, 0xc8, {0xda, 0xd9, 0x60, 0x9b, 0x7a, 0x11}}
+
+#define UUID_RSS_FIRMWARE_NS \
+	{{0x8d, 0x95, 0x9f, 0x72}, {0xb8, 0xb1}, {0x42, 0x11}, 0x9a, 0xe6, {0x4b, 0x80, 0x97, 0x47, 0x5a, 0xd9}}
+
+#define UUID_RSS_FIRMWARE_S \
+	{{0x22, 0xea, 0x33, 0x85}, {0xf8, 0x6e}, {0x47, 0x93}, 0x96, 0x8a, {0x2f, 0xe3, 0xdd, 0x50, 0x33, 0xcc}}
+
+#define UUID_RSS_SIC_TABLES_NS \
+	{{0xd9, 0x10, 0x00, 0x72}, {0x6a, 0x28}, {0x4b, 0xec}, 0xb0, 0xd6, {0x8c, 0xed, 0xc4, 0x15, 0x7c, 0xe0}}
+
+#define UUID_RSS_SIC_TABLES_S \
+	{{0xc7, 0x38, 0xd0, 0xde}, {0x8c, 0x26}, {0x48, 0x51}, 0x93, 0x36, {0xf3, 0xdb, 0xe2, 0x96, 0x65, 0x18}}
+
+#endif /* __PLAT_DEF_FIP_UUID__ */
diff --git a/plat/arm/board/tc/plat_def_uuid_config.c b/plat/arm/board/tc/plat_def_uuid_config.c
new file mode 100644
index 0000000..903310b
--- /dev/null
+++ b/plat/arm/board/tc/plat_def_uuid_config.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stddef.h>
+
+#include <firmware_image_package.h>
+
+#include "tbbr_config.h"
+
+toc_entry_t plat_def_toc_entries[] = {
+	{
+		.name = "RSS Firmware BL1_2 image",
+		.uuid = UUID_RSS_FIRMWARE_BL1_2,
+		.cmdline_name = "rss-bl1_2"
+	},
+	{
+		.name = "RSS Firmware BL2 image",
+		.uuid = UUID_RSS_FIRMWARE_BL2,
+		.cmdline_name = "rss-bl2"
+	},
+	{
+		.name = "RSS Firmware SCP BL1 image",
+		.uuid = UUID_RSS_FIRMWARE_SCP_BL1,
+		.cmdline_name = "rss-scp-bl1"
+	},
+	{
+		.name = "RSS Firmware AP BL1 image",
+		.uuid = UUID_RSS_FIRMWARE_AP_BL1,
+		.cmdline_name = "rss-ap-bl1"
+	},
+	{
+		.name = "RSS Firmware non-secure image",
+		.uuid = UUID_RSS_FIRMWARE_NS,
+		.cmdline_name = "rss-ns"
+	},
+	{
+		.name = "RSS Firmware secure image",
+		.uuid = UUID_RSS_FIRMWARE_S,
+		.cmdline_name = "rss-s"
+	},
+	{
+		.name = "RSS Firmware non-secure SIC tables",
+		.uuid = UUID_RSS_SIC_TABLES_NS,
+		.cmdline_name = "rss-sic-tables-ns"
+	},
+	{
+		.name = "RSS Firmware secure SIC tables",
+		.uuid = UUID_RSS_SIC_TABLES_S,
+		.cmdline_name = "rss-sic-tables-s"
+	},
+
+	{
+		.name = NULL,
+		.uuid = { {0} },
+		.cmdline_name = NULL,
+	}
+};
diff --git a/plat/arm/board/tc/plat_fiptool.mk b/plat/arm/board/tc/plat_fiptool.mk
new file mode 100644
index 0000000..0e13556
--- /dev/null
+++ b/plat/arm/board/tc/plat_fiptool.mk
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2021, NXP. All rights reserved.
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Name of the platform defined source file name,
+# which contains platform defined UUID entries populated
+# in the plat_def_toc_entries[].
+PLAT_DEF_UUID_CONFIG_FILE_NAME	:= plat_def_uuid_config
+
+PLAT_DEF_UUID_CONFIG_FILE_PATH := ../../plat/arm/board/tc
+
+PLAT_DEF_UUID := yes
+PLAT_DEF_UUID_OID_CONFIG_PATH := ../../plat/arm/board/tc
+
+
+INCLUDE_PATHS += -I${PLAT_DEF_UUID_OID_CONFIG_PATH} \
+		 -I./
+# Clean the stale object file.
+$(shell rm ${PLAT_DEF_UUID_CONFIG_FILE_PATH}/${PLAT_DEF_UUID_CONFIG_FILE_NAME}.o)
+
+ifeq (${PLAT_DEF_OID},yes)
+HOSTCCFLAGS += -DPLAT_DEF_OID
+endif
+
+ifeq (${PLAT_DEF_UUID},yes)
+HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
+PLAT_OBJECTS += ${PLAT_DEF_UUID_CONFIG_FILE_PATH}/${PLAT_DEF_UUID_CONFIG_FILE_NAME}.o
+endif
+
+OBJECTS += ${PLAT_OBJECTS}
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 74c0f17..2182477 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -53,6 +53,9 @@
 # enable trace filter control registers access to NS by default
 ENABLE_TRF_FOR_NS               := 1
 
+# Enable RSS-required FIP UUIDs
+$(shell cp plat/arm/board/tc/plat_fiptool.mk ${PLAT_DIR})
+
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
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/fconf/fconf_ethosn_getter.c b/plat/arm/common/fconf/fconf_ethosn_getter.c
index 0b48a98..251471e 100644
--- a/plat/arm/common/fconf/fconf_ethosn_getter.c
+++ b/plat/arm/common/fconf/fconf_ethosn_getter.c
@@ -20,21 +20,6 @@
 	uint32_t stream_id;
 };
 
-static bool fdt_node_is_enabled(const void *fdt, int node)
-{
-	int len;
-	const char *node_status;
-
-	node_status = fdt_getprop(fdt, node, "status", &len);
-	if (node_status == NULL ||
-	    (len == 5 && /* Includes null character */
-	     strncmp(node_status, "okay", 4U) == 0)) {
-		return true;
-	}
-
-	return false;
-}
-
 static bool fdt_node_has_reserved_memory(const void *fdt, int dev_node)
 {
 	return fdt_get_property(fdt, dev_node, "memory-region", NULL) != NULL;
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/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index b1fc13c..5f7d142 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.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
  */
@@ -150,7 +150,7 @@
 	rc = mmap_add_dynamic_region((unsigned long long)pm_base_align,
 				     pm_base_align,
 				     PAGE_SIZE,
-				     MT_RO_DATA);
+				     MT_RO_DATA | EL3_PAS);
 	if (rc != 0) {
 		ERROR("Error while mapping SPM Core manifest (%d).\n", rc);
 		return rc;
diff --git a/plat/imx/common/imx_uart_console.S b/plat/imx/common/imx_uart_console.S
index ceeb3a7..4d17288 100644
--- a/plat/imx/common/imx_uart_console.S
+++ b/plat/imx/common/imx_uart_console.S
@@ -12,6 +12,7 @@
 
 #define URXD  0x0  /* Receiver Register */
 #define UTXD  0x40 /* Transmitter Register */
+#define USR2  0x98 /* UART Status Register 2 */
 #define UTS   0xb4 /* UART Test Register (mx31) */
 #define  URXD_RX_DATA    (0xFF)
 
@@ -53,13 +54,13 @@
 1:
 	/* Check if the transmit FIFO is full */
 	ldr	w2, [x1, #UTS]
-	tbz	w2, #6, 1b
+	tbnz	w2, #4, 1b
 	mov	w2, #0xD
 	str	w2, [x1, #UTXD]
 2:
 	/* Check if the transmit FIFO is full */
 	ldr	w2, [x1, #UTS]
-	tbz	w2, #6, 2b
+	tbnz	w2, #4, 2b
 	str	w0, [x1, #UTXD]
 	ret
 putc_error:
@@ -84,5 +85,13 @@
 endfunc console_imx_uart_getc
 
 func console_imx_uart_flush
+	ldr	x0, [x0, #CONSOLE_T_BASE]
+	cbz	x0, flush_exit
+1:
+	/* Wait for the transmit complete bit */
+	ldr	w1, [x0, #USR2]
+	tbz	w1, #3, 1b
+
+flush_exit:
 	ret
 endfunc console_imx_uart_flush
diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk
index 160e98f..752ab41 100644
--- a/plat/marvell/armada/a8k/common/ble/ble.mk
+++ b/plat/marvell/armada/a8k/common/ble/ble.mk
@@ -21,7 +21,7 @@
 				-I$(CURDIR)/include/lib/libc			\
 				-I$(CURDIR)/include/lib/libc/aarch64
 
-BLE_LINKERFILE		:=	$(BLE_PATH)/ble.ld.S
+BLE_DEFAULT_LINKER_SCRIPT_SOURCE := $(BLE_PATH)/ble.ld.S
 
 BLE_OBJS := $(addprefix $(BUILD_PLAT)/ble/,$(call SOURCES_TO_OBJS,$(BLE_SOURCES)))
 $(BLE_OBJS): PLAT_INCLUDES += -I$(MV_DDR_PATH)
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
index fc3876e..83a4dd2 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -61,31 +61,6 @@
 $(eval $(call uppercase,$(2))_SOURCES += $(1))
 endef
 
-# MAKE_LINKERFILE change linker script source file name to
-# target linker script
-#   $(1) = linker script source file
-#   $(2) = BL stage
-define MAKE_LINKERFILE
-$(eval EXTRA_GENERATED_LINKER_SCRIPT += $(BUILD_PLAT)/$(2)/$(patsubst %.ld.S,%.ld,$(notdir $(1))))
-endef
-
-# MAKE_LINKERFILE_ITER call MAKE_LINKERFILE iteratively
-#   $(1) = linker script source file
-#   $(2) = BL stage
-define MAKE_LINKERFILE_ITER
-$(eval $(foreach link_src,$(1),$(call MAKE_LINKERFILE,$(link_src),$(2))))
-endef
-
-# MAKE_LD_ITER generate the linker scripts using the C preprocessor iteratively
-#   $(1) = output linker script
-#   $(2) = input template
-#   $(3) = BL stage (1, 2, 2u, 31, 32)
-define MAKE_LD_ITER
-$(eval index_list=$(shell seq $(words $(1))))
-$(eval $(foreach i, $(index_list), \
-$(call MAKE_LD,$(word $(i), $(1)), $(word $(i), $(2)),$(3))))
-endef
-
 # MAKE_MODULE reference MAKE_OBJS.
 # Create module folder under out/bl$(BL)/$(module)
 # Arguments:
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
index 22a546c..4fed41f 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
@@ -9,22 +9,7 @@
 
 # Make next section align to page size
 ifneq ($(MTK_EXTRA_LINKERFILE),)
-$(eval $(call MAKE_LINKERFILE_ITER,$(MTK_LINKERFILE_SOURCE),bl31))
-
-# EXTRA_GENERATED_LINKER_SCRIPT is a global variable of derived linker
-# script list(from MTK_LINKERFILE_SOURCE) after MAKE_LINKERFILE_ITER
-# function call
-EXTRA_LINKERFILE += ${EXTRA_GENERATED_LINKER_SCRIPT}
-
-# Expand derived linker script as build target
-$(eval $(call MAKE_LD_ITER, $(EXTRA_GENERATED_LINKER_SCRIPT),$(MTK_LINKERFILE_SOURCE),bl31))
-
-# mtk_align.ld MUST BE THE LAST LINKER SCRIPT!
-EXTRA_LINKERFILE += ${MTK_PLAT}/include/mtk_align.ld
-
-# bl31.ld should depend on EXTRA_LINKERFILE
-$(eval ${BUILD_PLAT}/bl31/bl31.ld: ${EXTRA_LINKERFILE})
-EXTRA_LINKERFILE := $(addprefix -T,$(EXTRA_LINKERFILE))
-else
-EXTRA_LINKERFILE :=
+        # mtk_align.ld MUST BE THE LAST LINKER SCRIPT!
+        BL31_LINKER_SCRIPT_SOURCES += $(MTK_LINKERFILE_SOURCE)
+        BL31_LINKER_SCRIPT_SOURCES += ${MTK_PLAT}/include/mtk_align.ld
 endif
diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h
index 1733930..ce356f6 100644
--- a/plat/xilinx/common/include/plat_startup.h
+++ b/plat/xilinx/common/include/plat_startup.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,4 +39,8 @@
 					entry_point_info_t *bl33,
 					uint64_t atf_handoff_addr);
 
+/* JEDEC Standard Manufacturer's Identification Code and Bank ID JEP106 */
+#define JEDEC_XILINX_MFID	U(0x49)
+#define JEDEC_XILINX_BKID	U(0)
+
 #endif /* PLAT_STARTUP_H */
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/versal_net/versal_net_gicv3.c b/plat/xilinx/versal_net/versal_net_gicv3.c
index b7ac6ab..1d45a58 100644
--- a/plat/xilinx/versal_net/versal_net_gicv3.c
+++ b/plat/xilinx/versal_net/versal_net_gicv3.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (C) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,14 +30,6 @@
 /* The GICv3 driver only needs to be initialized in EL3 */
 static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
 
-static const uintptr_t gicr_base_addrs[2] = {
-	PLAT_VERSAL_NET_GICR_BASE,	/* GICR Base address of the primary CPU */
-	0U				/* Zero Termination */
-};
-
-/* List of zero terminated GICR frame addresses which CPUs will probe */
-static const uintptr_t *gicr_frames;
-
 static const interrupt_prop_t versal_net_interrupt_props[] = {
 	PLAT_VERSAL_NET_G1S_IRQ_PROPS(INTR_GROUP1S),
 	PLAT_VERSAL_NET_G0_IRQ_PROPS(INTR_GROUP0)
@@ -72,7 +64,7 @@
 
 static const gicv3_driver_data_t versal_net_gic_data __unused = {
 	.gicd_base = PLAT_VERSAL_NET_GICD_BASE,
-	.gicr_base = 0U,
+	.gicr_base = PLAT_VERSAL_NET_GICR_BASE,
 	.interrupt_props = versal_net_interrupt_props,
 	.interrupt_props_num = ARRAY_SIZE(versal_net_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
@@ -90,12 +82,6 @@
 	 */
 #if IMAGE_BL31
 	gicv3_driver_init(&versal_net_gic_data);
-	gicr_frames = gicr_base_addrs;
-
-	if (gicv3_rdistif_probe(gicr_frames[0]) == -1) {
-		ERROR("No GICR base frame found for Primary CPU\n");
-		panic();
-	}
 #endif
 }
 
@@ -131,25 +117,6 @@
  *****************************************************************************/
 void plat_versal_net_gic_pcpu_init(void)
 {
-	int32_t result;
-	const uintptr_t *plat_gicr_frames = gicr_frames;
-
-	do {
-		result = gicv3_rdistif_probe(*plat_gicr_frames);
-
-		/* If the probe is successful, no need to proceed further */
-		if (result == 0) {
-			break;
-		}
-
-		plat_gicr_frames++;
-	} while (*plat_gicr_frames != 0U);
-
-	if (result == -1) {
-		ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
-		panic();
-	}
-
 	gicv3_rdistif_init(plat_my_core_pos());
 }
 
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 7bdd5bd..95a266e 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
  */
@@ -10,10 +11,13 @@
 #include <common/debug.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
+#include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables.h>
 #include <plat_ipi.h>
 #include <plat_private.h>
+#include <plat_startup.h>
 #include <plat/common/platform.h>
+#include <services/arm_arch_svc.h>
 
 #include "pm_api_sys.h"
 
@@ -303,13 +307,38 @@
 	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();
 }
 
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+	switch (fid) {
+	case SMCCC_ARCH_SOC_ID:
+		return SMC_ARCH_CALL_SUCCESS;
+	default:
+		return SMC_ARCH_CALL_NOT_SUPPORTED;
+	}
+
+	return SMC_ARCH_CALL_NOT_SUPPORTED;
+}
+
+int32_t plat_get_soc_version(void)
+{
+	uint32_t chip_id = zynqmp_get_silicon_ver();
+	uint32_t manfid = SOC_ID_SET_JEP_106(JEDEC_XILINX_BKID, JEDEC_XILINX_MFID);
+
+	return (int32_t)(manfid | (chip_id & 0xFFFF));
+}
+
+int32_t plat_get_soc_revision(void)
+{
+	return mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
+}
+
 static uint32_t zynqmp_get_ps_ver(void)
 {
 	uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 05adbd0..b751de8 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -5,6 +5,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 
 override ERRATA_A53_855873 := 1
+ERRATA_A53_1530924 := 1
 override PROGRAMMABLE_RESET_ADDRESS := 1
 PSCI_EXTENDED_STATE_ID := 1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
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..ff09e7e 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 */
 }
 
 /*******************************************************************************
@@ -151,20 +168,15 @@
  * used.  It also assumes that a valid non-secure context has been
  * initialised by PSCI so it does not need to save and restore any
  * non-secure state. This function performs a synchronous entry into
- * OPTEE. OPTEE passes control back to this routine through a SMC.
+ * OPTEE. OPTEE passes control back to this routine through a SMC. This returns
+ * a non-zero value on success and zero on failure.
  ******************************************************************************/
-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,6 +191,121 @@
 	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);
+
+	/*
+	 * We do not validate the passed in address because we are trusting the
+	 * non-secure world at this point still.
+	 */
+	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]);
+	if (opteed_init_with_entry_point(&optee_ep_info) == 0) {
+		rc = -EFAULT;
+	}
+
+	/* 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
@@ -207,6 +334,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 +374,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/linker.lds b/services/std_svc/rmmd/trp/linker.ld.S
similarity index 89%
rename from services/std_svc/rmmd/trp/linker.lds
rename to services/std_svc/rmmd/trp/linker.ld.S
index 2b7f383..9895cf9 100644
--- a/services/std_svc/rmmd/trp/linker.lds
+++ b/services/std_svc/rmmd/trp/linker.ld.S
@@ -1,6 +1,7 @@
 /*
- * (C) COPYRIGHT 2021 Arm Limited or its affiliates.
- * ALL RIGHTS RESERVED
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/bl_common.ld.h>
diff --git a/services/std_svc/rmmd/trp/trp.mk b/services/std_svc/rmmd/trp/trp.mk
index 44bbf22..e511bf5 100644
--- a/services/std_svc/rmmd/trp/trp.mk
+++ b/services/std_svc/rmmd/trp/trp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2022 Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2023 Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,7 @@
 				services/std_svc/rmmd/trp/trp_main.c  \
 				services/std_svc/rmmd/trp/trp_helpers.c
 
-RMM_LINKERFILE		:=	services/std_svc/rmmd/trp/linker.lds
+RMM_DEFAULT_LINKER_SCRIPT_SOURCE := services/std_svc/rmmd/trp/linker.ld.S
 
 # Include the platform-specific TRP Makefile
 # If no platform-specific TRP Makefile exists, it means TRP is not supported
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,
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index afd0f2e..dde1622 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,10 +16,14 @@
 #include <bl31/interrupt_mgmt.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <common/tbbr/tbbr_img_def.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/smccc.h>
 #include <lib/spinlock.h>
 #include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
@@ -245,6 +249,92 @@
 	SMC_RET0(&ctx->cpu_ctx);
 }
 
+#if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31
+static int spmd_dynamic_map_mem(uintptr_t base_addr, size_t size,
+				 unsigned int attr, uintptr_t *align_addr,
+				 size_t *align_size)
+{
+	uintptr_t base_addr_align;
+	size_t mapped_size_align;
+	int rc;
+
+	/* Page aligned address and size if necessary */
+	base_addr_align = page_align(base_addr, DOWN);
+	mapped_size_align = page_align(size, UP);
+
+	if ((base_addr != base_addr_align) &&
+	    (size == mapped_size_align)) {
+		mapped_size_align += PAGE_SIZE;
+	}
+
+	/*
+	 * Map dynamically given region with its aligned base address and
+	 * size
+	 */
+	rc = mmap_add_dynamic_region((unsigned long long)base_addr_align,
+				     base_addr_align,
+				     mapped_size_align,
+				     attr);
+	if (rc == 0) {
+		*align_addr = base_addr_align;
+		*align_size = mapped_size_align;
+	}
+
+	return rc;
+}
+
+static void spmd_do_sec_cpy(uintptr_t root_base_addr, uintptr_t sec_base_addr,
+			    size_t size)
+{
+	uintptr_t root_base_addr_align, sec_base_addr_align;
+	size_t root_mapped_size_align, sec_mapped_size_align;
+	int rc;
+
+	assert(root_base_addr != 0UL);
+	assert(sec_base_addr != 0UL);
+	assert(size != 0UL);
+
+	/* Map the memory with required attributes */
+	rc = spmd_dynamic_map_mem(root_base_addr, size, MT_RO_DATA | MT_ROOT,
+				  &root_base_addr_align,
+				  &root_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while mapping", "root region",
+		      root_base_addr, rc);
+		panic();
+	}
+
+	rc = spmd_dynamic_map_mem(sec_base_addr, size, MT_RW_DATA | MT_SECURE,
+				  &sec_base_addr_align, &sec_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while mapping",
+		      "secure region", sec_base_addr, rc);
+		panic();
+	}
+
+	/* Do copy operation */
+	(void)memcpy((void *)sec_base_addr, (void *)root_base_addr, size);
+
+	/* Unmap root memory region */
+	rc = mmap_remove_dynamic_region(root_base_addr_align,
+					root_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while unmapping",
+		      "root region", root_base_addr_align, rc);
+		panic();
+	}
+
+	/* Unmap secure memory region */
+	rc = mmap_remove_dynamic_region(sec_base_addr_align,
+					sec_mapped_size_align);
+	if (rc != 0) {
+		ERROR("%s %s %lu (%d)\n", "Error while unmapping",
+		      "secure region", sec_base_addr_align, rc);
+		panic();
+	}
+}
+#endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */
+
 /*******************************************************************************
  * Loads SPMC manifest and inits SPMC.
  ******************************************************************************/
@@ -254,6 +344,7 @@
 	unsigned int core_id;
 	uint32_t ep_attr, flags;
 	int rc;
+	const struct dyn_cfg_dtb_info_t *image_info __unused;
 
 	/* Load the SPM Core manifest */
 	rc = plat_spm_core_manifest_load(&spmc_attrs, pm_addr);
@@ -344,6 +435,26 @@
 					     DISABLE_ALL_EXCEPTIONS);
 	}
 
+#if ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31
+	image_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TOS_FW_CONFIG_ID);
+	assert(image_info != NULL);
+
+	if ((image_info->config_addr == 0UL) ||
+	    (image_info->secondary_config_addr == 0UL) ||
+	    (image_info->config_max_size == 0UL)) {
+		return -EINVAL;
+	}
+
+	/* Copy manifest from root->secure region */
+	spmd_do_sec_cpy(image_info->config_addr,
+			image_info->secondary_config_addr,
+			image_info->config_max_size);
+
+	/* Update ep info of BL32 */
+	assert(spmc_ep_info != NULL);
+	spmc_ep_info->args.arg0 = image_info->secondary_config_addr;
+#endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 && !RESET_TO_BL31 */
+
 	/* Set an initial SPMC context state for all cores. */
 	for (core_id = 0U; core_id < PLATFORM_CORE_COUNT; core_id++) {
 		spm_core_context[core_id].state = SPMC_STATE_OFF;
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 487777b..27ec979 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -212,7 +212,7 @@
 			*err_code = KEY_ERR_OPEN;
 		}
 	} else {
-		WARN("Key filename not specified\n");
+		VERBOSE("Key filename not specified\n");
 		*err_code = KEY_ERR_FILENAME;
 	}
 
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 5c240b5..fadf319 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -1,9 +1,12 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#ifndef _MSC_VER
+#include <sys/mount.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -298,6 +301,7 @@
 	fip_toc_header_t *toc_header;
 	fip_toc_entry_t *toc_entry;
 	int terminated = 0;
+	size_t st_size;
 
 	fp = fopen(filename, "rb");
 	if (fp == NULL)
@@ -306,13 +310,21 @@
 	if (fstat(fileno(fp), &st) == -1)
 		log_err("fstat %s", filename);
 
+	st_size = st.st_size;
+
-	buf = xmalloc(st.st_size, "failed to load file into memory");
-	if (fread(buf, 1, st.st_size, fp) != st.st_size)
+#ifdef BLKGETSIZE64
+	if ((st.st_mode & S_IFBLK) != 0)
+		if (ioctl(fileno(fp), BLKGETSIZE64, &st_size) == -1)
+			log_err("ioctl %s", filename);
+#endif
+
+	buf = xmalloc(st_size, "failed to load file into memory");
+	if (fread(buf, 1, st_size, fp) != st_size)
 		log_errx("Failed to read %s", filename);
-	bufend = buf + st.st_size;
+	bufend = buf + st_size;
 	fclose(fp);
 
-	if (st.st_size < sizeof(fip_toc_header_t))
+	if (st_size < sizeof(fip_toc_header_t))
 		log_errx("FIP %s is truncated", filename);
 
 	toc_header = (fip_toc_header_t *)buf;
@@ -347,9 +359,11 @@
 		    "failed to allocate image buffer, is FIP file corrupted?");
 		/* Overflow checks before memory copy. */
 		if (toc_entry->size > (uint64_t)-1 - toc_entry->offset_address)
-			log_errx("FIP %s is corrupted", filename);
-		if (toc_entry->size + toc_entry->offset_address > st.st_size)
-			log_errx("FIP %s is corrupted", filename);
+			log_errx("FIP %s is corrupted: entry size exceeds 64 bit address space",
+				filename);
+		if (toc_entry->size + toc_entry->offset_address > st_size)
+			log_errx("FIP %s is corrupted: entry size exceeds FIP file size",
+				filename);
 
 		memcpy(image->buffer, buf + toc_entry->offset_address,
 		    toc_entry->size);