Merge pull request #1851 from antonio-nino-diaz-arm/an/pauth

Correctly check for support of Address Authentication
diff --git a/Makefile b/Makefile
index 7b0ef5b..6386bef 100644
--- a/Makefile
+++ b/Makefile
@@ -245,8 +245,13 @@
 
 GCC_V_OUTPUT		:=	$(shell $(CC) -v 2>&1)
 
+ifneq ($(findstring armlink,$(notdir $(LD))),)
+TF_LDFLAGS		+=	--diag_error=warning --lto_level=O1
+TF_LDFLAGS		+=	--remove --info=unused,unusedsymbols
+else
 TF_LDFLAGS		+=	--fatal-warnings -O1
 TF_LDFLAGS		+=	--gc-sections
+endif
 TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH))
 
 DTC_FLAGS		+=	-I dts -O dtb
@@ -714,6 +719,10 @@
 $(eval $(call add_define,DYN_DISABLE_AUTH))
 endif
 
+ifneq ($(findstring armlink,$(notdir $(LD))),)
+$(eval $(call add_define,USE_ARM_LINK))
+endif
+
 ################################################################################
 # Build targets
 ################################################################################
@@ -728,8 +737,12 @@
 
 # Check if deprecated declarations and cpp warnings should be treated as error or not.
 ifeq (${ERROR_DEPRECATED},0)
+ifneq ($(findstring clang,$(notdir $(CC))),)
+    CPPFLAGS		+= 	-Wno-error=deprecated-declarations
+else
     CPPFLAGS		+= 	-Wno-error=deprecated-declarations -Wno-error=cpp
 endif
+endif
 
 $(eval $(call MAKE_LIB_DIRS))
 $(eval $(call MAKE_LIB,c))
diff --git a/docs/cpu-specific-build-macros.rst b/docs/cpu-specific-build-macros.rst
index 81738d8..95538d0 100644
--- a/docs/cpu-specific-build-macros.rst
+++ b/docs/cpu-specific-build-macros.rst
@@ -166,6 +166,9 @@
 
 For Cortex-A73, the following errata build flags are defined :
 
+-  ``ERRATA_A73_852427``: This applies errata 852427 workaround to Cortex-A73
+   CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
 -  ``ERRATA_A73_855423``: This applies errata 855423 workaround to Cortex-A73
    CPU. This needs to be enabled only for revision <= r0p1 of the CPU.
 
diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst
index 7ed0f2c..6a03b12 100644
--- a/docs/plat/nvidia-tegra.rst
+++ b/docs/plat/nvidia-tegra.rst
@@ -82,6 +82,16 @@
 Tegra210: TLK and Trusty
 Tegra186: Trusty
 
+Scatter files
+=============
+
+Tegra platforms currently support scatter files and ld.S scripts. The scatter
+files help support ARMLINK linker to generate BL31 binaries. For now, there
+exists a common scatter file, plat/nvidia/tegra/scat/bl31.scat, for all Tegra
+SoCs. The `LINKER` build variable needs to point to the ARMLINK binary for
+the scatter file to be used. Tegra platforms have verified BL31 image generation
+with ARMCLANG (compilation) and ARMLINK (linking) for the Tegra186 platforms.
+
 Preparing the BL31 image to run on Tegra SoCs
 =============================================
 
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index b602956..d3c63c7 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -729,6 +729,12 @@
    Note: when ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT``
    must also be set to ``1``.
 
+-  ``USE_ARM_LINK``: This flag determines whether to enable support for ARM
+   linker. When the ``LINKER`` build variable points to the armlink linker,
+   this flag is enabled automatically. To enable support for armlink, platforms
+   will have to provide a scatter file for the BL image. Currently, Tegra
+   platforms use the armlink support to compile BL3-1 images.
+
 -  ``USE_COHERENT_MEM``: This flag determines whether to include the coherent
    memory region in the BL memory map or not (see "Use of Coherent memory in
    TF-A" section in `Firmware Design`_). It can take the value 1
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 9817ec7..457dc2a 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -57,6 +57,48 @@
 #define FIQ_AARCH32			U(0xe)
 #define SERROR_AARCH32			U(0xf)
 
+/*
+ * Mapping to connect linker symbols from .ld.S with their counterparts
+ * from .scat for the BL31 image
+ */
+#if defined(USE_ARM_LINK)
+#define __BL31_END__			Load$$LR$$LR_END$$Base
+#define __BSS_START__			Load$$LR$$LR_BSS$$Base
+#define __BSS_END__			Load$$LR$$LR_BSS$$Limit
+#define __BSS_SIZE__			Load$$LR$$LR_BSS$$Length
+#define __COHERENT_RAM_START__		Load$$LR$$LR_COHERENT_RAM$$Base
+#define __COHERENT_RAM_END_UNALIGNED__	Load$$__COHERENT_RAM_EPILOGUE_UNALIGNED__$$Base
+#define __COHERENT_RAM_END__		Load$$LR$$LR_COHERENT_RAM$$Limit
+#define __COHERENT_RAM_UNALIGNED_SIZE__	Load$$__COHERENT_RAM__$$Length
+#define __CPU_OPS_START__		Load$$__CPU_OPS__$$Base
+#define __CPU_OPS_END__			Load$$__CPU_OPS__$$Limit
+#define __DATA_START__			Load$$__DATA__$$Base
+#define __DATA_END__			Load$$__DATA__$$Limit
+#define __GOT_START__			Load$$__GOT__$$Base
+#define __GOT_END__			Load$$__GOT__$$Limit
+#define __PERCPU_BAKERY_LOCK_START__	Load$$__BAKERY_LOCKS__$$Base
+#define __PERCPU_BAKERY_LOCK_END__	Load$$__BAKERY_LOCKS_EPILOGUE__$$Base
+#define __PMF_SVC_DESCS_START__		Load$$__PMF_SVC_DESCS__$$Base
+#define __PMF_SVC_DESCS_END__		Load$$__PMF_SVC_DESCS__$$Limit
+#define __PMF_TIMESTAMP_START__		Load$$__PMF_TIMESTAMP__$$Base
+#define __PMF_TIMESTAMP_END__		Load$$__PER_CPU_TIMESTAMPS__$$Limit
+#define __PMF_PERCPU_TIMESTAMP_END__	Load$$__PMF_TIMESTAMP_EPILOGUE__$$Base
+#define __RELA_END__			Load$$__RELA__$$Limit
+#define __RELA_START__			Load$$__RELA__$$Base
+#define __RODATA_START__		Load$$__RODATA__$$Base
+#define __RODATA_END__			Load$$__RODATA_EPILOGUE__$$Base
+#define __RT_SVC_DESCS_START__		Load$$__RT_SVC_DESCS__$$Base
+#define __RT_SVC_DESCS_END__		Load$$__RT_SVC_DESCS__$$Limit
+#define __RW_START__			Load$$LR$$LR_RW_DATA$$Base
+#define __RW_END__			Load$$LR$$LR_END$$Base
+#define __SPM_SHIM_EXCEPTIONS_START__	Load$$__SPM_SHIM_EXCEPTIONS__$$Base
+#define __SPM_SHIM_EXCEPTIONS_END__	Load$$__SPM_SHIM_EXCEPTIONS_EPILOGUE__$$Base
+#define __STACKS_START__		Load$$__STACKS__$$Base
+#define __STACKS_END__			Load$$__STACKS__$$Limit
+#define __TEXT_START__			Load$$__TEXT__$$Base
+#define __TEXT_END__			Load$$__TEXT_EPILOGUE__$$Base
+#endif /* USE_ARM_LINK */
+
 #ifndef __ASSEMBLY__
 
 #include <stddef.h>
diff --git a/include/lib/cpus/aarch64/cortex_a73.h b/include/lib/cpus/aarch64/cortex_a73.h
index 61b2b73..1238c0e 100644
--- a/include/lib/cpus/aarch64/cortex_a73.h
+++ b/include/lib/cpus/aarch64/cortex_a73.h
@@ -31,6 +31,8 @@
 
 #define CORTEX_A73_IMP_DEF_REG1_DISABLE_LOAD_PASS_STORE	(ULL(1) << 3)
 
+#define CORTEX_A73_DIAGNOSTIC_REGISTER	S3_0_C15_C0_1
+
 #define CORTEX_A73_IMP_DEF_REG2		S3_0_C15_C0_2
 
 #endif /* CORTEX_A73_H */
diff --git a/include/lib/el3_runtime/pubsub.h b/include/lib/el3_runtime/pubsub.h
index 9c303f5..64fe5cc 100644
--- a/include/lib/el3_runtime/pubsub.h
+++ b/include/lib/el3_runtime/pubsub.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,13 +7,11 @@
 #ifndef PUBSUB_H
 #define PUBSUB_H
 
-#define __pubsub_start_sym(event)	__pubsub_##event##_start
-#define __pubsub_end_sym(event)		__pubsub_##event##_end
-
 #ifdef __LINKER__
 
 /* For the linker ... */
-
+#define __pubsub_start_sym(event)	__pubsub_##event##_start
+#define __pubsub_end_sym(event)		__pubsub_##event##_end
 #define __pubsub_section(event)		__pubsub_##event
 
 /*
@@ -21,10 +19,22 @@
  * contexts. In linker context, this collects pubsub sections for each event,
  * placing guard symbols around each.
  */
+#if defined(USE_ARM_LINK)
+#define REGISTER_PUBSUB_EVENT(event) \
+	__pubsub_start_sym(event) +0 FIXED \
+	{ \
+		*(__pubsub_section(event)) \
+	} \
+	__pubsub_end_sym(event) +0 FIXED EMPTY 0 \
+	{ \
+		/* placeholder */ \
+	}
+#else
 #define REGISTER_PUBSUB_EVENT(event) \
 	__pubsub_start_sym(event) = .; \
 	KEEP(*(__pubsub_section(event))); \
 	__pubsub_end_sym(event) = .
+#endif
 
 #else /* __LINKER__ */
 
@@ -36,6 +46,14 @@
 
 #include <arch_helpers.h>
 
+#if defined(USE_ARM_LINK)
+#define __pubsub_start_sym(event)	Load$$__pubsub_##event##_start$$Base
+#define __pubsub_end_sym(event)		Load$$__pubsub_##event##_end$$Base
+#else
+#define __pubsub_start_sym(event)	__pubsub_##event##_start
+#define __pubsub_end_sym(event)		__pubsub_##event##_end
+#endif
+
 #define __pubsub_section(event)		__section("__pubsub_" #event)
 
 /*
diff --git a/lib/cpus/aarch32/cpu_helpers.S b/lib/cpus/aarch32/cpu_helpers.S
index f84cd0d..f37a33d 100644
--- a/lib/cpus/aarch32/cpu_helpers.S
+++ b/lib/cpus/aarch32/cpu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 #include <asm_macros.S>
 #include <assert_macros.S>
 #include <cpu_macros.S>
+#include <common/bl_common.h>
 #include <lib/el3_runtime/cpu_data.h>
 
 #if defined(IMAGE_BL1) || defined(IMAGE_BL32) || (defined(IMAGE_BL2) && BL2_AT_EL3)
diff --git a/lib/cpus/aarch64/cortex_a73.S b/lib/cpus/aarch64/cortex_a73.S
index 6cfa4b5..5c8a887 100644
--- a/lib/cpus/aarch64/cortex_a73.S
+++ b/lib/cpus/aarch64/cortex_a73.S
@@ -36,6 +36,34 @@
 endfunc cortex_a73_disable_smp
 
 	/* ---------------------------------------------------
+	 * Errata Workaround for Cortex A73 Errata #852427.
+	 * This applies only to revision r0p0 of Cortex A73.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * ---------------------------------------------------
+	 */
+func errata_a73_852427_wa
+	/*
+	 * Compare x0 against revision r0p0
+	 */
+	mov	x17, x30
+	bl	check_errata_852427
+	cbz	x0, 1f
+	mrs	x1, CORTEX_A73_DIAGNOSTIC_REGISTER
+	orr	x1, x1, #(1 << 12)
+	msr	CORTEX_A73_DIAGNOSTIC_REGISTER, x1
+	isb
+1:
+	ret	x17
+endfunc errata_a73_852427_wa
+
+func check_errata_852427
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_852427
+
+	/* ---------------------------------------------------
 	 * Errata Workaround for Cortex A73 Errata #855423.
 	 * This applies only to revision <= r0p1 of Cortex A73.
 	 * Inputs:
@@ -71,8 +99,15 @@
 func cortex_a73_reset_func
 	mov	x19, x30
 	bl	cpu_get_rev_var
+	mov	x18, x0
+
+#if ERRATA_A73_852427
+	mov	x0, x18
+	bl	errata_a73_852427_wa
+#endif
 
 #if ERRATA_A73_855423
+	mov	x0, x18
 	bl	errata_a73_855423_wa
 #endif
 
@@ -200,6 +235,7 @@
 	 * Report all errata. The revision-variant information is passed to
 	 * checking functions of each errata.
 	 */
+	report_errata ERRATA_A73_852427, cortex_a73, 852427
 	report_errata ERRATA_A73_855423, cortex_a73, 855423
 	report_errata WORKAROUND_CVE_2017_5715, cortex_a73, cve_2017_5715
 	report_errata WORKAROUND_CVE_2018_3639, cortex_a73, cve_2018_3639
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 74d7bb2..de1177c 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <assert_macros.S>
+#include <common/bl_common.h>
 #include <common/debug.h>
 #include <cpu_macros.S>
 #include <lib/cpus/errata_report.h>
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 2d3984e..4985dd0 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -159,6 +159,10 @@
 # only to revision <= r0p3 of the Cortex A72 cpu.
 ERRATA_A72_859971	?=0
 
+# Flag to apply erratum 852427 workaround during reset. This erratum applies
+# only to revision r0p0 of the Cortex A73 cpu.
+ERRATA_A73_852427	?=0
+
 # Flag to apply erratum 855423 workaround during reset. This erratum applies
 # only to revision <= r0p1 of the Cortex A73 cpu.
 ERRATA_A73_855423	?=0
@@ -292,6 +296,10 @@
 $(eval $(call assert_boolean,ERRATA_A72_859971))
 $(eval $(call add_define,ERRATA_A72_859971))
 
+# Process ERRATA_A73_852427 flag
+$(eval $(call assert_boolean,ERRATA_A73_852427))
+$(eval $(call add_define,ERRATA_A73_852427))
+
 # Process ERRATA_A73_855423 flag
 $(eval $(call assert_boolean,ERRATA_A73_855423))
 $(eval $(call add_define,ERRATA_A73_855423))
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index d7d8c22..0e6a6fa 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -231,9 +231,101 @@
 
 } action_t;
 
+/*
+ * Function that returns the first VA of the table affected by the specified
+ * mmap region.
+ */
+static uintptr_t xlat_tables_find_start_va(mmap_region_t *mm,
+				   const uintptr_t table_base_va,
+				   const unsigned int level)
+{
+	uintptr_t table_idx_va;
+
+	if (mm->base_va > table_base_va) {
+		/* Find the first index of the table affected by the region. */
+		table_idx_va = mm->base_va & ~XLAT_BLOCK_MASK(level);
+	} else {
+		/* Start from the beginning of the table. */
+		table_idx_va = table_base_va;
+	}
+
+	return table_idx_va;
+}
+
+/*
+ * Function that returns table index for the given VA and level arguments.
+ */
+static inline unsigned int  xlat_tables_va_to_index(const uintptr_t table_base_va,
+						const uintptr_t va,
+						const unsigned int level)
+{
+	return (unsigned int)((va - table_base_va) >> XLAT_ADDR_SHIFT(level));
+}
+
 #if PLAT_XLAT_TABLES_DYNAMIC
 
 /*
+ * From the given arguments, it decides which action to take when unmapping the
+ * specified region.
+ */
+static action_t xlat_tables_unmap_region_action(const mmap_region_t *mm,
+		const uintptr_t table_idx_va, const uintptr_t table_idx_end_va,
+		const unsigned int level, const uint64_t desc_type)
+{
+	action_t action;
+	uintptr_t region_end_va = mm->base_va + mm->size - 1U;
+
+	if ((mm->base_va <= table_idx_va) &&
+	    (region_end_va >= table_idx_end_va)) {
+		/* Region covers all block */
+
+		if (level == 3U) {
+			/*
+			 * Last level, only page descriptors allowed,
+			 * erase it.
+			 */
+			assert(desc_type == PAGE_DESC);
+
+			action = ACTION_WRITE_BLOCK_ENTRY;
+		} else {
+			/*
+			 * Other levels can have table descriptors. If
+			 * so, recurse into it and erase descriptors
+			 * inside it as needed. If there is a block
+			 * descriptor, just erase it. If an invalid
+			 * descriptor is found, this table isn't
+			 * actually mapped, which shouldn't happen.
+			 */
+			if (desc_type == TABLE_DESC) {
+				action = ACTION_RECURSE_INTO_TABLE;
+			} else {
+				assert(desc_type == BLOCK_DESC);
+				action = ACTION_WRITE_BLOCK_ENTRY;
+			}
+		}
+
+	} else if ((mm->base_va <= table_idx_end_va) ||
+		   (region_end_va >= table_idx_va)) {
+		/*
+		 * Region partially covers block.
+		 *
+		 * It can't happen in level 3.
+		 *
+		 * There must be a table descriptor here, if not there
+		 * was a problem when mapping the region.
+		 */
+		assert(level < 3U);
+		assert(desc_type == TABLE_DESC);
+
+		action = ACTION_RECURSE_INTO_TABLE;
+	} else {
+		/* The region doesn't cover the block at all */
+		action = ACTION_NONE;
+	}
+
+	return action;
+}
+/*
  * Recursive function that writes to the translation tables and unmaps the
  * specified region.
  */
@@ -255,19 +347,8 @@
 
 	unsigned int table_idx;
 
-	if (mm->base_va > table_base_va) {
-		/* Find the first index of the table affected by the region. */
-		table_idx_va = mm->base_va & ~XLAT_BLOCK_MASK(level);
-
-		table_idx = (unsigned int)((table_idx_va - table_base_va) >>
-			    XLAT_ADDR_SHIFT(level));
-
-		assert(table_idx < table_entries);
-	} else {
-		/* Start from the beginning of the table. */
-		table_idx_va = table_base_va;
-		table_idx = 0;
-	}
+	table_idx_va = xlat_tables_find_start_va(mm, table_base_va, level);
+	table_idx = xlat_tables_va_to_index(table_base_va, table_idx_va, level);
 
 	while (table_idx < table_entries) {
 
@@ -276,55 +357,9 @@
 		desc = table_base[table_idx];
 		uint64_t desc_type = desc & DESC_MASK;
 
-		action_t action;
-
-		if ((mm->base_va <= table_idx_va) &&
-		    (region_end_va >= table_idx_end_va)) {
-			/* Region covers all block */
-
-			if (level == 3U) {
-				/*
-				 * Last level, only page descriptors allowed,
-				 * erase it.
-				 */
-				assert(desc_type == PAGE_DESC);
-
-				action = ACTION_WRITE_BLOCK_ENTRY;
-			} else {
-				/*
-				 * Other levels can have table descriptors. If
-				 * so, recurse into it and erase descriptors
-				 * inside it as needed. If there is a block
-				 * descriptor, just erase it. If an invalid
-				 * descriptor is found, this table isn't
-				 * actually mapped, which shouldn't happen.
-				 */
-				if (desc_type == TABLE_DESC) {
-					action = ACTION_RECURSE_INTO_TABLE;
-				} else {
-					assert(desc_type == BLOCK_DESC);
-					action = ACTION_WRITE_BLOCK_ENTRY;
-				}
-			}
-
-		} else if ((mm->base_va <= table_idx_end_va) ||
-			   (region_end_va >= table_idx_va)) {
-			/*
-			 * Region partially covers block.
-			 *
-			 * It can't happen in level 3.
-			 *
-			 * There must be a table descriptor here, if not there
-			 * was a problem when mapping the region.
-			 */
-			assert(level < 3U);
-			assert(desc_type == TABLE_DESC);
-
-			action = ACTION_RECURSE_INTO_TABLE;
-		} else {
-			/* The region doesn't cover the block at all */
-			action = ACTION_NONE;
-		}
+		action_t action = xlat_tables_unmap_region_action(mm,
+				table_idx_va, table_idx_end_va, level,
+				desc_type);
 
 		if (action == ACTION_WRITE_BLOCK_ENTRY) {
 
@@ -525,19 +560,8 @@
 
 	unsigned int table_idx;
 
-	if (mm->base_va > table_base_va) {
-		/* Find the first index of the table affected by the region. */
-		table_idx_va = mm->base_va & ~XLAT_BLOCK_MASK(level);
-
-		table_idx = (unsigned int)((table_idx_va - table_base_va) >>
-			    XLAT_ADDR_SHIFT(level));
-
-		assert(table_idx < table_entries);
-	} else {
-		/* Start from the beginning of the table. */
-		table_idx_va = table_base_va;
-		table_idx = 0U;
-	}
+	table_idx_va = xlat_tables_find_start_va(mm, table_base_va, level);
+	table_idx = xlat_tables_va_to_index(table_base_va, table_idx_va, level);
 
 #if PLAT_XLAT_TABLES_DYNAMIC
 	if (level > ctx->base_level)
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 4a264d7..5d33954 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -355,8 +355,13 @@
 .PHONY : lib${1}_dirs
 lib${1}_dirs: | ${BUILD_DIR} ${LIB_DIR}  ${ROMLIB_DIR} ${LIBWRAPPER_DIR}
 libraries: ${LIB_DIR}/lib$(1).a
+ifneq ($(findstring armlink,$(notdir $(LD))),)
+LDPATHS = --userlibpath=${LIB_DIR}
+LDLIBS += --library=$(1)
+else
 LDPATHS = -L${LIB_DIR}
 LDLIBS += -l$(1)
+endif
 
 ifeq ($(USE_ROMLIB),1)
 LIBWRAPPER = -lwrappers
@@ -421,9 +426,18 @@
 	       const char version_string[] = "${VERSION_STRING}";' | \
 		$$(CC) $$(TF_CFLAGS) $$(CFLAGS) -xc -c - -o $(BUILD_DIR)/build_message.o
 endif
+ifneq ($(findstring armlink,$(notdir $(LD))),)
+	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) --entry=bl${1}_entrypoint \
+		--predefine="-D__LINKER__=$(__LINKER__)" \
+		--predefine="-DTF_CFLAGS=$(TF_CFLAGS)" \
+		--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/bl${1}.scat \
+		$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \
+		$(BUILD_DIR)/build_message.o $(OBJS)
+else
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Map=$(MAPFILE) \
 		--script $(LINKERFILE) $(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
+endif
 
 $(DUMP): $(ELF)
 	$${ECHO} "  OD      $$@"
diff --git a/plat/imx/common/plat_imx8_gic.c b/plat/imx/common/plat_imx8_gic.c
index 27c525b..3a7dcfe 100644
--- a/plat/imx/common/plat_imx8_gic.c
+++ b/plat/imx/common/plat_imx8_gic.c
@@ -9,6 +9,8 @@
 #include <common/bl_common.h>
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
+#include <drivers/arm/arm_gicv3_common.h>
+#include <lib/mmio.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 
@@ -52,8 +54,27 @@
 #endif
 }
 
+static __inline void plat_gicr_exit_sleep(void)
+{
+	unsigned int val = mmio_read_32(PLAT_GICR_BASE + GICR_WAKER);
+
+	/*
+	 * ProcessorSleep bit can ONLY be set to zero when
+	 * Quiescent bit and Sleep bit are both zero, so
+	 * need to make sure Quiescent bit and Sleep bit
+	 * are zero before clearing ProcessorSleep bit.
+	 */
+	if (val & WAKER_QSC_BIT) {
+		mmio_write_32(PLAT_GICR_BASE + GICR_WAKER, val & ~WAKER_SL_BIT);
+		/* Wait till the WAKER_QSC_BIT changes to 0 */
+		while ((mmio_read_32(PLAT_GICR_BASE + GICR_WAKER) & WAKER_QSC_BIT) != 0U)
+			;
+	}
+}
+
 void plat_gic_init(void)
 {
+	plat_gicr_exit_sleep();
 	gicv3_distif_init();
 	gicv3_rdistif_init(plat_my_core_pos());
 	gicv3_cpuif_enable(plat_my_core_pos());
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index b18edd9..99fa980 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -84,6 +84,11 @@
 		mmio_write_32(IMX_CSU_BASE + i * 4, 0xffffffff);
 	}
 
+	/* config CAAM JRaMID set MID to Cortex A */
+	mmio_write_32(CAAM_JR0MID, CAAM_NS_MID);
+	mmio_write_32(CAAM_JR1MID, CAAM_NS_MID);
+	mmio_write_32(CAAM_JR2MID, CAAM_NS_MID);
+
 #if DEBUG_CONSOLE
 	static console_uart_t console;
 
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index 4957582..5c5b0a5 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -119,3 +119,8 @@
 #define DEBUG_CONSOLE			0
 #define IMX_WDOG_B_RESET
 #define PLAT_IMX8M			1
+
+#define CAAM_JR0MID			U(0x30900010)
+#define CAAM_JR1MID			U(0x30900018)
+#define CAAM_JR2MID			U(0x30900020)
+#define CAAM_NS_MID			U(0x1)
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index 6ef1900..b429eb7 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -59,3 +59,18 @@
 
 INCLUDES	+=	-Iinclude/lib/libc		\
 			-Iinclude/lib/libc/$(ARCH)	\
+
+ifneq ($(findstring armlink,$(notdir $(LD))),)
+# o suppress warnings for section mismatches, undefined symbols
+# o use only those libraries that are specified in the input file
+#   list to resolve references
+# o create a static callgraph of functions
+# o resolve undefined symbols to el3_panic
+# o include only required sections
+TF_LDFLAGS	+= --diag_suppress=L6314,L6332 --no_scanlib --callgraph
+TF_LDFLAGS	+= --unresolved=el3_panic
+TF_LDFLAGS	+= --keep="*(__pubsub*)" --keep="*(rt_svc_descs*)" --keep="*(*cpu_ops)"
+ifeq (${ENABLE_PMF},1)
+TF_LDFLAGS	+= --keep="*(*pmf_svc_descs*)"
+endif
+endif
diff --git a/plat/nvidia/tegra/scat/bl31.scat b/plat/nvidia/tegra/scat/bl31.scat
new file mode 100644
index 0000000..2f5fd9e
--- /dev/null
+++ b/plat/nvidia/tegra/scat/bl31.scat
@@ -0,0 +1,284 @@
+#! armclang -E -x c
+
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#define PAGE_SIZE	(1024 * 4)
+
+LR_START BL31_BASE
+{
+	__BL31_START__ +0 FIXED EMPTY 0
+	{
+		/* placeholder */
+	}
+
+	/* BL31_BASE address must be aligned on a page boundary. */
+	ScatterAssert((ImageBase(__BL31_START__) AND 0xFFF) == 0)
+}
+
+LR_TEXT BL31_BASE
+{
+	__TEXT__ +0 FIXED
+	{
+		*(:gdef:bl31_entrypoint, +FIRST)
+		*(.text*)
+		*(.vectors)
+		.ANY1(+RO-CODE)
+	}
+
+	__TEXT_EPILOGUE__ AlignExpr(+0, PAGE_SIZE) FIXED EMPTY 0
+	{
+		/* section delimiter */
+	}
+}
+
+LR_RO_DATA +0
+{
+	__RODATA__ AlignExpr(ImageLimit(LR_TEXT), 0) FIXED
+	{
+		*(.rodata*)
+		.ANY2(+RO-DATA)
+	}
+
+	/* Ensure 8-byte alignment for descriptors and ensure inclusion */
+	__RT_SVC_DESCS__ AlignExpr(ImageLimit(__RODATA__), 8) FIXED
+	{
+		*(rt_svc_descs)
+	}
+
+#if ENABLE_PMF
+	/* Ensure 8-byte alignment for descriptors and ensure inclusion */
+	__PMF_SVC_DESCS__ AlignExpr(ImageLimit(__RT_SVC_DESCS__), 8) FIXED
+	{
+		*(pmf_svc_descs)
+	}
+#endif /* ENABLE_PMF */
+
+	/*
+	 * Ensure 8-byte alignment for cpu_ops so that its fields are also
+	 * aligned.
+	 */
+	__CPU_OPS__ AlignExpr(+0, 8) FIXED
+	{
+		*(cpu_ops)
+	}
+
+	/*
+	 * Keep the .got section in the RO section as it is patched
+	 * prior to enabling the MMU and having the .got in RO is better for
+	 * security. GOT is a table of addresses so ensure 8-byte alignment.
+	 */
+	__GOT__ AlignExpr(ImageLimit(__CPU_OPS__), 8) FIXED
+	{
+		*(.got)
+	}
+
+	/* Place pubsub sections for events */
+	__PUBSUB_EVENTS__ AlignExpr(+0, 8) EMPTY 0
+	{
+		/* placeholder */
+	}
+
+#include <lib/el3_runtime/pubsub_events.h>
+
+	__RODATA_EPILOGUE__ AlignExpr(+0, PAGE_SIZE) FIXED EMPTY 0
+	{
+		/* section delimiter */
+	}
+}
+
+	/* cpu_ops must always be defined */
+	ScatterAssert(ImageLength(__CPU_OPS__) > 0)
+
+#if ENABLE_SPM
+LR_SPM +0
+{
+	/*
+	 * 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.
+	 *
+	 * 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__ AlignExpr(ImageLimit(LR_RO_DATA), PAGE_SIZE) FIXED
+	{
+		*(.spm_shim_exceptions)
+	}
+
+	__SPM_SHIM_EXCEPTIONS_EPILOGUE__ AlignExpr(ImageLimit(__SPM_SHIM_EXCEPTIONS__), PAGE_SIZE) FIXED
+	{
+		/* placeholder */
+	}
+}
+#endif
+
+LR_RW_DATA +0
+{
+	__DATA__ AlignExpr(+0, 16) FIXED
+	{
+		*(.data*)
+		*(.constdata)
+		*(locale$$data)
+	}
+}
+
+LR_RELA +0
+{
+	/*
+	 * .rela.dyn needs to come after .data for the read-elf utility to parse
+	 * this section correctly. Ensure 8-byte alignment so that the fields of
+	 * RELA data structure are aligned.
+	 */
+	__RELA__ AlignExpr(ImageLimit(LR_RW_DATA), 8) FIXED
+	{
+		*(.rela.dyn)
+	}
+}
+
+#ifdef BL31_PROGBITS_LIMIT
+	/* BL31 progbits has exceeded its limit. */
+	ScatterAssert(ImageLimit(LR_RELA) <= BL31_PROGBITS_LIMIT)
+#endif
+
+LR_STACKS +0
+{
+	__STACKS__ AlignExpr(+0, 64) FIXED
+	{
+		*(tzfw_normal_stacks)
+	}
+}
+
+#define __BAKERY_LOCK_SIZE__		(ImageLimit(__BAKERY_LOCKS_EPILOGUE__) - \
+					 ImageBase(__BAKERY_LOCKS__))
+#define BAKERY_LOCK_SIZE		(__BAKERY_LOCK_SIZE__ * (PLATFORM_CORE_COUNT - 1))
+#define __PMF_TIMESTAMP_SIZE__		(ImageLimit(__PMF_TIMESTAMP__) - \
+					 ImageBase(__PMF_TIMESTAMP__))
+#define PER_CPU_TIMESTAMP_SIZE		(__PMF_TIMESTAMP_SIZE__ * (PLATFORM_CORE_COUNT - 1))
+
+LR_BSS +0
+{
+	__BSS__ AlignExpr(ImageLimit(LR_STACKS), 256) FIXED
+	{
+		*(.bss*)
+		*(COMDAT)
+	}
+
+#if !USE_COHERENT_MEM
+	/*
+	 * Bakery locks are stored in normal .bss memory
+	 *
+	 * Each lock's data is spread across multiple cache lines, one per CPU,
+	 * but multiple locks can share the same cache line.
+	 * The compiler will allocate enough memory for one CPU's bakery locks,
+	 * the remaining cache lines are allocated by the linker script
+	 */
+	__BAKERY_LOCKS__ AlignExpr(ImageLimit(__BSS__), CACHE_WRITEBACK_GRANULE) FIXED
+	{
+		*(bakery_lock)
+	}
+
+	__BAKERY_LOCKS_EPILOGUE__ AlignExpr(ImageLimit(__BAKERY_LOCKS__), CACHE_WRITEBACK_GRANULE) FIXED EMPTY 0
+	{
+		/* section delimiter */
+	}
+
+	__PER_CPU_BAKERY_LOCKS__ ImageLimit(__BAKERY_LOCKS_EPILOGUE__) FIXED FILL 0 BAKERY_LOCK_SIZE
+	{
+		/* padded memory section to store per cpu bakery locks */
+	}
+
+#ifdef PLAT_PERCPU_BAKERY_LOCK_SIZE
+	/* PLAT_PERCPU_BAKERY_LOCK_SIZE does not match bakery lock requirements */
+	ScatterAssert(__PER_CPU_BAKERY_LOCK_SIZE__ == PLAT_PERCPU_BAKERY_LOCK_SIZE)
+#endif
+#endif
+
+#if ENABLE_PMF
+	/*
+	 * Time-stamps are stored in normal .bss memory
+	 *
+	 * The compiler will allocate enough memory for one CPU's time-stamps,
+	 * the remaining memory for other CPU's is allocated by the
+	 * linker script
+	 */
+	__PMF_TIMESTAMP__ AlignExpr(+0, CACHE_WRITEBACK_GRANULE) FIXED EMPTY CACHE_WRITEBACK_GRANULE
+	{
+		/* store timestamps in this carved out memory */
+	}
+
+	__PMF_TIMESTAMP_EPILOGUE__ AlignExpr(ImageLimit(__PMF_TIMESTAMP__), CACHE_WRITEBACK_GRANULE) FIXED EMPTY 0
+	{
+		/*
+		 * placeholder to make __PMF_TIMESTAMP_START__ end on a
+		 * CACHE_WRITEBACK_GRANULE boundary
+		 */
+	}
+
+	__PER_CPU_TIMESTAMPS__ +0 FIXED FILL 0 PER_CPU_TIMESTAMP_SIZE
+	{
+		/* padded memory section to store per cpu timestamps */
+	}
+#endif /* ENABLE_PMF */
+}
+
+LR_XLAT_TABLE +0
+{
+	xlat_table +0 FIXED
+	{
+		*(xlat_table)
+	}
+}
+
+#if USE_COHERENT_MEM
+LR_COHERENT_RAM +0
+{
+	/*
+	 * 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.
+	 */
+	__COHERENT_RAM__ AlignExpr(+0, PAGE_SIZE) FIXED
+	{
+		/*
+		 * 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_EPILOGUE_UNALIGNED__ +0 FIXED EMPTY 0
+	{
+		/* section delimiter */
+	}
+
+	/*
+	 * 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.
+	 */
+	__COHERENT_RAM_EPILOGUE__ AlignExpr(ImageLimit(__COHERENT_RAM_START__), PAGE_SIZE) FIXED EMPTY 0
+	{
+		/* section delimiter */
+	}
+}
+#endif
+
+LR_END +0
+{
+	__BL31_END__ +0 FIXED EMPTY 0
+	{
+		/* placeholder */
+	}
+
+	/* BL31 image has exceeded its limit. */
+	ScatterAssert(ImageLimit(__BL31_END__) <= BL31_LIMIT)
+}