Merge pull request #885 from antonio-nino-diaz-arm/an/console-flush

Implement console_flush()
diff --git a/Makefile b/Makefile
index 83650a8..9f9061c 100644
--- a/Makefile
+++ b/Makefile
@@ -246,6 +246,12 @@
         # over the sources.
 endif
 
+################################################################################
+# Include libraries' Makefile that are used in all BL
+################################################################################
+
+include lib/stack_protector/stack_protector.mk
+
 
 ################################################################################
 # Include the platform specific Makefile after the SPD Makefile (the platform
@@ -374,6 +380,55 @@
 FIPTOOLPATH		?=	tools/fiptool
 FIPTOOL			?=	${FIPTOOLPATH}/fiptool${BIN_EXT}
 
+################################################################################
+# Include BL specific makefiles
+################################################################################
+ifdef BL1_SOURCES
+NEED_BL1 := yes
+include bl1/bl1.mk
+endif
+
+ifdef BL2_SOURCES
+NEED_BL2 := yes
+include bl2/bl2.mk
+endif
+
+# For AArch32, BL31 is not applicable, and BL2U is not supported at present.
+ifneq (${ARCH},aarch32)
+ifdef BL2U_SOURCES
+NEED_BL2U := yes
+include bl2u/bl2u.mk
+endif
+
+ifdef BL31_SOURCES
+# When booting an EL3 payload, there is no need to compile the BL31 image nor
+# put it in the FIP.
+ifndef EL3_PAYLOAD_BASE
+NEED_BL31 := yes
+include bl31/bl31.mk
+endif
+endif
+endif
+
+ifeq (${ARCH},aarch32)
+NEED_BL32 := yes
+
+################################################################################
+# Build `AARCH32_SP` as BL32 image for AArch32
+################################################################################
+ifneq (${AARCH32_SP},none)
+# We expect to locate an sp.mk under the specified AARCH32_SP directory
+AARCH32_SP_MAKE	:=	$(wildcard bl32/${AARCH32_SP}/${AARCH32_SP}.mk)
+
+ifeq (${AARCH32_SP_MAKE},)
+  $(error Error: No bl32/${AARCH32_SP}/${AARCH32_SP}.mk located)
+endif
+
+$(info Including ${AARCH32_SP_MAKE})
+include ${AARCH32_SP_MAKE}
+endif
+
+endif
 
 ################################################################################
 # Build options checks
@@ -460,56 +515,6 @@
 endif
 
 ################################################################################
-# Include BL specific makefiles
-################################################################################
-ifdef BL1_SOURCES
-NEED_BL1 := yes
-include bl1/bl1.mk
-endif
-
-ifdef BL2_SOURCES
-NEED_BL2 := yes
-include bl2/bl2.mk
-endif
-
-# For AArch32, BL31 is not applicable, and BL2U is not supported at present.
-ifneq (${ARCH},aarch32)
-ifdef BL2U_SOURCES
-NEED_BL2U := yes
-include bl2u/bl2u.mk
-endif
-
-ifdef BL31_SOURCES
-# When booting an EL3 payload, there is no need to compile the BL31 image nor
-# put it in the FIP.
-ifndef EL3_PAYLOAD_BASE
-NEED_BL31 := yes
-include bl31/bl31.mk
-endif
-endif
-endif
-
-ifeq (${ARCH},aarch32)
-NEED_BL32 := yes
-
-################################################################################
-# Build `AARCH32_SP` as BL32 image for AArch32
-################################################################################
-ifneq (${AARCH32_SP},none)
-# We expect to locate an sp.mk under the specified AARCH32_SP directory
-AARCH32_SP_MAKE	:=	$(wildcard bl32/${AARCH32_SP}/${AARCH32_SP}.mk)
-
-ifeq (${AARCH32_SP_MAKE},)
-  $(error Error: No bl32/${AARCH32_SP}/${AARCH32_SP}.mk located)
-endif
-
-$(info Including ${AARCH32_SP_MAKE})
-include ${AARCH32_SP_MAKE}
-endif
-
-endif
-
-################################################################################
 # Build targets
 ################################################################################
 
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index b69065e..2cfb24c 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -111,14 +111,20 @@
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
            "cpu_ops not defined for this platform.")
 
+    . = BL1_RW_BASE;
+    ASSERT(BL1_RW_BASE == ALIGN(4096),
+           "BL1_RW_BASE address is not aligned on a page boundary.")
+
     /*
      * The .data section gets copied from ROM to RAM at runtime.
-     * Its LMA must be 16-byte aligned.
+     * 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.
+     *
+     * It must be placed at a lower address than the stacks if the stack
+     * protector is enabled. Alternatively, the .data.stack_protector_canary
+     * section can be placed independently of the main .data section.
      */
-    . = BL1_RW_BASE;
-    ASSERT(. == ALIGN(4096),
-           "BL1_RW_BASE address is not aligned on a page boundary.")
     .data . : ALIGN(16) {
         __DATA_RAM_START__ = .;
         *(.data*)
diff --git a/bl2/aarch32/bl2_entrypoint.S b/bl2/aarch32/bl2_entrypoint.S
index bb0b7f3..c82456f 100644
--- a/bl2/aarch32/bl2_entrypoint.S
+++ b/bl2/aarch32/bl2_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -122,6 +122,15 @@
 	bl	plat_set_my_stack
 
 	/* ---------------------------------------------
+	 * Initialize the stack protector canary before
+	 * any C code is called.
+	 * ---------------------------------------------
+	 */
+#if STACK_PROTECTOR_ENABLED
+	bl	update_stack_protector_canary
+#endif
+
+	/* ---------------------------------------------
 	 * Perform early platform setup & platform
 	 * specific early arch. setup e.g. mmu setup
 	 * ---------------------------------------------
diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S
index 31f7787..15a217d 100644
--- a/bl2/aarch64/bl2_entrypoint.S
+++ b/bl2/aarch64/bl2_entrypoint.S
@@ -113,6 +113,15 @@
 	bl	plat_set_my_stack
 
 	/* ---------------------------------------------
+	 * Initialize the stack protector canary before
+	 * any C code is called.
+	 * ---------------------------------------------
+	 */
+#if STACK_PROTECTOR_ENABLED
+	bl	update_stack_protector_canary
+#endif
+
+	/* ---------------------------------------------
 	 * Perform early platform setup & platform
 	 * specific early arch. setup e.g. mmu setup
 	 * ---------------------------------------------
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index b9275f3..07e0bcc 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -99,6 +99,11 @@
      */
     __RW_START__ = . ;
 
+    /*
+     * .data must be placed at a lower address than the stacks if the stack
+     * protector is enabled. Alternatively, the .data.stack_protector_canary
+     * section can be placed independently of the main .data section.
+     */
     .data . : {
         __DATA_START__ = .;
         *(.data*)
diff --git a/bl2u/aarch64/bl2u_entrypoint.S b/bl2u/aarch64/bl2u_entrypoint.S
index 9fa84bf..81aabc7 100644
--- a/bl2u/aarch64/bl2u_entrypoint.S
+++ b/bl2u/aarch64/bl2u_entrypoint.S
@@ -107,6 +107,15 @@
 	bl	plat_set_my_stack
 
 	/* ---------------------------------------------
+	 * Initialize the stack protector canary before
+	 * any C code is called.
+	 * ---------------------------------------------
+	 */
+#if STACK_PROTECTOR_ENABLED
+	bl	update_stack_protector_canary
+#endif
+
+	/* ---------------------------------------------
 	 * Perform early platform setup & platform
 	 * specific early arch. setup e.g. mmu setup
 	 * ---------------------------------------------
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index 91e8556..aebf84f 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -86,6 +86,11 @@
      */
     __RW_START__ = . ;
 
+    /*
+     * .data must be placed at a lower address than the stacks if the stack
+     * protector is enabled. Alternatively, the .data.stack_protector_canary
+     * section can be placed independently of the main .data section.
+     */
     .data . : {
         __DATA_START__ = .;
         *(.data*)
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index e5d6232..3a3fbd9 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -140,7 +140,12 @@
      */
     __RW_START__ = . ;
 
-    .data . : {
+    /*
+     * .data must be placed at a lower address than the stacks if the stack
+     * protector is enabled. Alternatively, the .data.stack_protector_canary
+     * section can be placed independently of the main .data section.
+     */
+   .data . : {
         __DATA_START__ = .;
         *(.data*)
         __DATA_END__ = .;
diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S
index 182f314..3f28139 100644
--- a/bl32/tsp/aarch64/tsp_entrypoint.S
+++ b/bl32/tsp/aarch64/tsp_entrypoint.S
@@ -139,6 +139,15 @@
 	bl	plat_set_my_stack
 
 	/* ---------------------------------------------
+	 * Initialize the stack protector canary before
+	 * any C code is called.
+	 * ---------------------------------------------
+	 */
+#if STACK_PROTECTOR_ENABLED
+	bl	update_stack_protector_canary
+#endif
+
+	/* ---------------------------------------------
 	 * Perform early platform setup & platform
 	 * specific early arch. setup e.g. mmu setup
 	 * ---------------------------------------------
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 034174c..0189ec4 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -920,6 +920,20 @@
 needs. This function is currently invoked in BL2 to pass this information to
 the next BL image, when LOAD_IMAGE_V2 is enabled.
 
+### Function : plat_get_stack_protector_canary()
+    Argument : void
+    Return   : u_register_t
+
+This function returns a random value that is used to initialize the canary used
+when the stack protector is enabled with ENABLE_STACK_PROTECTOR. A predictable
+value will weaken the protection as the attacker could easily write the right
+value as part of the attack most of the time. Therefore, it should return a
+true random number.
+
+Note: For the protection to be effective, the global data need to be placed at
+a lower address than the stack bases. Failure to do so would allow an attacker
+to overwrite the canary as part of the stack buffer overflow attack.
+
 ### Function : plat_flush_next_bl_params()
 
     Argument : void
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 2770b2c..a1df965 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -301,6 +301,14 @@
     Currently, only PSCI is instrumented. Enabling this option enables
     the `ENABLE_PMF` build option as well. Default is 0.
 
+*   `ENABLE_STACK_PROTECTOR`: String option to enable the stack protection
+    checks in GCC. Allowed values are "all", "strong" and "0" (default).
+    "strong" is the recommended stack protection level if this feature is
+    desired. 0 disables the stack protection. For all values other than 0, the
+    `plat_get_stack_protector_canary()` platform hook needs to be implemented.
+    The value is passed as the last component of the option
+    `-fstack-protector-$ENABLE_STACK_PROTECTOR`.
+
 *   `ERROR_DEPRECATED`: This option decides whether to treat the usage of
     deprecated platform APIs, helper functions or drivers within Trusted
     Firmware as error. It can take the value 1 (flag the use of deprecated
@@ -799,7 +807,7 @@
     modules by checking out a recent version of the [mbed TLS Repository]. It
     is important to use a version that is compatible with TF and fixes any
     known security vulnerabilities. See [mbed TLS Security Center] for more
-    information. This version of TF is tested with tag `mbedtls-2.2.1`.
+    information. The latest version of TF is tested with tag `mbedtls-2.4.2`.
 
     The `drivers/auth/mbedtls/mbedtls_*.mk` files contain the list of mbed TLS
     source files the modules depend upon.
diff --git a/drivers/auth/mbedtls/mbedtls_common.c b/drivers/auth/mbedtls/mbedtls_common.c
index 053bf1a..1d2df5a 100644
--- a/drivers/auth/mbedtls/mbedtls_common.c
+++ b/drivers/auth/mbedtls/mbedtls_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -36,9 +36,9 @@
 /*
  * mbed TLS heap
  */
-#if (MBEDTLS_KEY_ALG_ID == MBEDTLS_ECDSA)
+#if (TBBR_KEY_ALG_ID == TBBR_ECDSA)
 #define MBEDTLS_HEAP_SIZE		(14*1024)
-#elif (MBEDTLS_KEY_ALG_ID == MBEDTLS_RSA)
+#elif (TBBR_KEY_ALG_ID == TBBR_RSA)
 #define MBEDTLS_HEAP_SIZE		(8*1024)
 #endif
 static unsigned char heap[MBEDTLS_HEAP_SIZE];
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.mk b/drivers/auth/mbedtls/mbedtls_crypto.mk
index b788097..302a0a1 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.mk
+++ b/drivers/auth/mbedtls/mbedtls_crypto.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -55,18 +55,18 @@
     					ecp_curves.c				\
     					ecp.c					\
     					)
-    MBEDTLS_KEY_ALG_ID		:=	MBEDTLS_ECDSA
+    TBBR_KEY_ALG_ID		:=	TBBR_ECDSA
 else ifeq (${MBEDTLS_KEY_ALG},rsa)
     MBEDTLS_CRYPTO_SOURCES	+=	$(addprefix ${MBEDTLS_DIR}/library/,	\
     					rsa.c					\
     					)
-    MBEDTLS_KEY_ALG_ID		:=	MBEDTLS_RSA
+    TBBR_KEY_ALG_ID		:=	TBBR_RSA
 else
     $(error "MBEDTLS_KEY_ALG=${MBEDTLS_KEY_ALG} not supported on mbed TLS")
 endif
 
-# mbed TLS libraries rely on this define to build correctly
-$(eval $(call add_define,MBEDTLS_KEY_ALG_ID))
+# Needs to be set to drive mbed TLS configuration correctly
+$(eval $(call add_define,TBBR_KEY_ALG_ID))
 
 BL1_SOURCES			+=	${MBEDTLS_CRYPTO_SOURCES}
 BL2_SOURCES			+=	${MBEDTLS_CRYPTO_SOURCES}
diff --git a/include/common/aarch32/el3_common_macros.S b/include/common/aarch32/el3_common_macros.S
index f6b7527..d7e0b3f 100644
--- a/include/common/aarch32/el3_common_macros.S
+++ b/include/common/aarch32/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -278,6 +278,12 @@
 	 * ---------------------------------------------------------------------
 	 */
 	bl	plat_set_my_stack
+
+#if STACK_PROTECTOR_ENABLED
+	.if \_init_c_runtime
+	bl	update_stack_protector_canary
+	.endif /* _init_c_runtime */
+#endif
 	.endm
 
 #endif /* __EL3_COMMON_MACROS_S__ */
diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S
index e085f9f..5c6aa06 100644
--- a/include/common/aarch64/el3_common_macros.S
+++ b/include/common/aarch64/el3_common_macros.S
@@ -283,6 +283,12 @@
 	 * ---------------------------------------------------------------------
 	 */
 	bl	plat_set_my_stack
+
+#if STACK_PROTECTOR_ENABLED
+	.if \_init_c_runtime
+	bl	update_stack_protector_canary
+	.endif /* _init_c_runtime */
+#endif
 	.endm
 
 #endif /* __EL3_COMMON_MACROS_S__ */
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 66c20fc..38be628 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -31,9 +31,8 @@
 #ifndef __BL_COMMON_H__
 #define __BL_COMMON_H__
 
-#define SECURE		0x0
-#define NON_SECURE	0x1
-#define sec_state_is_valid(s) (((s) == SECURE) || ((s) == NON_SECURE))
+#include <ep_info.h>
+#include <param_header.h>
 
 #define UP	1
 #define DOWN	0
@@ -45,25 +44,6 @@
 #define TOP	0x1
 #define BOTTOM	!TOP
 
-/*******************************************************************************
- * Constants that allow assembler code to access members of and the
- * 'entry_point_info' structure at their correct offsets.
- ******************************************************************************/
-#define ENTRY_POINT_INFO_PC_OFFSET	0x08
-#ifdef AARCH32
-#define ENTRY_POINT_INFO_ARGS_OFFSET	0x10
-#else
-#define ENTRY_POINT_INFO_ARGS_OFFSET	0x18
-#endif
-
-/* The following are used to set/get image attributes. */
-#define PARAM_EP_SECURITY_MASK		(0x1)
-
-#define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK)
-#define SET_SECURITY_STATE(x, security) \
-			((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security))
-
-
 /*
  * The following are used for image state attributes.
  * Image can only be in one of the following state.
@@ -75,59 +55,11 @@
 #define IMAGE_STATE_EXECUTED			4
 #define IMAGE_STATE_INTERRUPTED			5
 
-#define EP_EE_MASK	0x2
-#define EP_EE_LITTLE	0x0
-#define EP_EE_BIG	0x2
-#define EP_GET_EE(x) (x & EP_EE_MASK)
-#define EP_SET_EE(x, ee) ((x) = ((x) & ~EP_EE_MASK) | (ee))
-
-#define EP_ST_MASK	0x4
-#define EP_ST_DISABLE	0x0
-#define EP_ST_ENABLE	0x4
-#define EP_GET_ST(x) (x & EP_ST_MASK)
-#define EP_SET_ST(x, ee) ((x) = ((x) & ~EP_ST_MASK) | (ee))
-
-#define EP_EXE_MASK	0x8
-#define NON_EXECUTABLE	0x0
-#define EXECUTABLE	0x8
-#define EP_GET_EXE(x) (x & EP_EXE_MASK)
-#define EP_SET_EXE(x, ee) ((x) = ((x) & ~EP_EXE_MASK) | (ee))
-
-#define EP_FIRST_EXE_MASK	0x10
-#define EP_FIRST_EXE		0x10
-#define EP_GET_FIRST_EXE(x) ((x) & EP_FIRST_EXE_MASK)
-#define EP_SET_FIRST_EXE(x, ee) ((x) = ((x) & ~EP_FIRST_EXE_MASK) | (ee))
-
-#define PARAM_EP		0x01
-#define PARAM_IMAGE_BINARY	0x02
-#define PARAM_BL31		0x03
-#define PARAM_BL_LOAD_INFO	0x04
-#define PARAM_BL_PARAMS		0x05
-#define PARAM_PSCI_LIB_ARGS	0x06
-
 #define IMAGE_ATTRIB_SKIP_LOADING	0x02
 #define IMAGE_ATTRIB_PLAT_SETUP		0x04
 
-#define VERSION_1	0x01
-#define VERSION_2	0x02
-
 #define INVALID_IMAGE_ID		(0xFFFFFFFF)
 
-#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \
-	(_p)->h.type = (uint8_t)(_type); \
-	(_p)->h.version = (uint8_t)(_ver); \
-	(_p)->h.size = (uint16_t)sizeof(*_p); \
-	(_p)->h.attr = (uint32_t)(_attr) ; \
-	} while (0)
-
-/* Following is used for populating structure members statically. */
-#define SET_STATIC_PARAM_HEAD(_p, _type, _ver, _p_type, _attr)	\
-	._p.h.type = (uint8_t)(_type), \
-	._p.h.version = (uint8_t)(_ver), \
-	._p.h.size = (uint16_t)sizeof(_p_type), \
-	._p.h.attr = (uint32_t)(_attr)
-
-
 /*******************************************************************************
  * Constants to indicate type of exception to the common exception handler.
  ******************************************************************************/
@@ -149,10 +81,9 @@
 #define SERROR_AARCH32			0xf
 
 #ifndef __ASSEMBLY__
-#include <cdefs.h> /* For __dead2 */
 #include <cassert.h>
-#include <stdint.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <types.h>
 #include <utils.h> /* To retain compatibility */
 
@@ -185,7 +116,6 @@
 extern uintptr_t __COHERENT_RAM_END__;
 #endif
 
-
 /*******************************************************************************
  * Structure used for telling the next BL how much of a particular type of
  * memory is available for its use and how much is already used.
@@ -199,55 +129,6 @@
 #endif
 } meminfo_t;
 
-typedef struct aapcs64_params {
-	u_register_t arg0;
-	u_register_t arg1;
-	u_register_t arg2;
-	u_register_t arg3;
-	u_register_t arg4;
-	u_register_t arg5;
-	u_register_t arg6;
-	u_register_t arg7;
-} aapcs64_params_t;
-
-typedef struct aapcs32_params {
-	u_register_t arg0;
-	u_register_t arg1;
-	u_register_t arg2;
-	u_register_t arg3;
-} aapcs32_params_t;
-
-/***************************************************************************
- * This structure provides version information and the size of the
- * structure, attributes for the structure it represents
- ***************************************************************************/
-typedef struct param_header {
-	uint8_t type;		/* type of the structure */
-	uint8_t version;    /* version of this structure */
-	uint16_t size;      /* size of this structure in bytes */
-	uint32_t attr;      /* attributes: unused bits SBZ */
-} param_header_t;
-
-/*****************************************************************************
- * This structure represents the superset of information needed while
- * switching exception levels. The only two mechanisms to do so are
- * ERET & SMC. Security state is indicated using bit zero of header
- * attribute
- * NOTE: BL1 expects entrypoint followed by spsr at an offset from the start
- * of this structure defined by the macro `ENTRY_POINT_INFO_PC_OFFSET` while
- * processing SMC to jump to BL31.
- *****************************************************************************/
-typedef struct entry_point_info {
-	param_header_t h;
-	uintptr_t pc;
-	uint32_t spsr;
-#ifdef AARCH32
-	aapcs32_params_t args;
-#else
-	aapcs64_params_t args;
-#endif
-} entry_point_info_t;
-
 /*****************************************************************************
  * Image info binary provides information from the image loader that
  * can be used by the firmware to manage available trusted RAM.
@@ -338,24 +219,6 @@
 
 #endif /* LOAD_IMAGE_V2 */
 
-/*
- * Compile time assertions related to the 'entry_point_info' structure to
- * ensure that the assembler and the compiler view of the offsets of
- * the structure members is the same.
- */
-CASSERT(ENTRY_POINT_INFO_PC_OFFSET ==
-		__builtin_offsetof(entry_point_info_t, pc), \
-		assert_BL31_pc_offset_mismatch);
-
-CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \
-		__builtin_offsetof(entry_point_info_t, args), \
-		assert_BL31_args_offset_mismatch);
-
-CASSERT(sizeof(uintptr_t) ==
-		__builtin_offsetof(entry_point_info_t, spsr) - \
-		__builtin_offsetof(entry_point_info_t, pc), \
-		assert_entrypoint_and_spsr_should_be_adjacent);
-
 /*******************************************************************************
  * Function & variable prototypes
  ******************************************************************************/
diff --git a/include/common/debug.h b/include/common/debug.h
index 41c8df0..c6f211f 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -84,6 +84,9 @@
 void __dead2 do_panic(void);
 #define panic()	do_panic()
 
+/* Function called when stack protection check code detects a corrupted stack */
+void __dead2 __stack_chk_fail(void);
+
 void tf_printf(const char *fmt, ...) __printflike(1, 2);
 
 #endif /* __ASSEMBLY__ */
diff --git a/include/common/ep_info.h b/include/common/ep_info.h
new file mode 100644
index 0000000..3613614
--- /dev/null
+++ b/include/common/ep_info.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __EP_INFO_H__
+#define __EP_INFO_H__
+
+#include <param_header.h>
+
+#define SECURE		0x0
+#define NON_SECURE	0x1
+#define sec_state_is_valid(s) (((s) == SECURE) || ((s) == NON_SECURE))
+
+/*******************************************************************************
+ * Constants that allow assembler code to access members of and the
+ * 'entry_point_info' structure at their correct offsets.
+ ******************************************************************************/
+#define ENTRY_POINT_INFO_PC_OFFSET	0x08
+#ifdef AARCH32
+#define ENTRY_POINT_INFO_ARGS_OFFSET	0x10
+#else
+#define ENTRY_POINT_INFO_ARGS_OFFSET	0x18
+#endif
+
+/* The following are used to set/get image attributes. */
+#define PARAM_EP_SECURITY_MASK		(0x1)
+
+#define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK)
+#define SET_SECURITY_STATE(x, security) \
+			((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security))
+
+#define EP_EE_MASK	0x2
+#define EP_EE_LITTLE	0x0
+#define EP_EE_BIG	0x2
+#define EP_GET_EE(x) (x & EP_EE_MASK)
+#define EP_SET_EE(x, ee) ((x) = ((x) & ~EP_EE_MASK) | (ee))
+
+#define EP_ST_MASK	0x4
+#define EP_ST_DISABLE	0x0
+#define EP_ST_ENABLE	0x4
+#define EP_GET_ST(x) (x & EP_ST_MASK)
+#define EP_SET_ST(x, ee) ((x) = ((x) & ~EP_ST_MASK) | (ee))
+
+#define EP_EXE_MASK	0x8
+#define NON_EXECUTABLE	0x0
+#define EXECUTABLE	0x8
+#define EP_GET_EXE(x) (x & EP_EXE_MASK)
+#define EP_SET_EXE(x, ee) ((x) = ((x) & ~EP_EXE_MASK) | (ee))
+
+#define EP_FIRST_EXE_MASK	0x10
+#define EP_FIRST_EXE		0x10
+#define EP_GET_FIRST_EXE(x) ((x) & EP_FIRST_EXE_MASK)
+#define EP_SET_FIRST_EXE(x, ee) ((x) = ((x) & ~EP_FIRST_EXE_MASK) | (ee))
+
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+#include <types.h>
+
+typedef struct aapcs64_params {
+	u_register_t arg0;
+	u_register_t arg1;
+	u_register_t arg2;
+	u_register_t arg3;
+	u_register_t arg4;
+	u_register_t arg5;
+	u_register_t arg6;
+	u_register_t arg7;
+} aapcs64_params_t;
+
+typedef struct aapcs32_params {
+	u_register_t arg0;
+	u_register_t arg1;
+	u_register_t arg2;
+	u_register_t arg3;
+} aapcs32_params_t;
+
+/*****************************************************************************
+ * This structure represents the superset of information needed while
+ * switching exception levels. The only two mechanisms to do so are
+ * ERET & SMC. Security state is indicated using bit zero of header
+ * attribute
+ * NOTE: BL1 expects entrypoint followed by spsr at an offset from the start
+ * of this structure defined by the macro `ENTRY_POINT_INFO_PC_OFFSET` while
+ * processing SMC to jump to BL31.
+ *****************************************************************************/
+typedef struct entry_point_info {
+	param_header_t h;
+	uintptr_t pc;
+	uint32_t spsr;
+#ifdef AARCH32
+	aapcs32_params_t args;
+#else
+	aapcs64_params_t args;
+#endif
+} entry_point_info_t;
+
+/*
+ * Compile time assertions related to the 'entry_point_info' structure to
+ * ensure that the assembler and the compiler view of the offsets of
+ * the structure members is the same.
+ */
+CASSERT(ENTRY_POINT_INFO_PC_OFFSET ==
+		__builtin_offsetof(entry_point_info_t, pc), \
+		assert_BL31_pc_offset_mismatch);
+
+CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \
+		__builtin_offsetof(entry_point_info_t, args), \
+		assert_BL31_args_offset_mismatch);
+
+CASSERT(sizeof(uintptr_t) ==
+		__builtin_offsetof(entry_point_info_t, spsr) - \
+		__builtin_offsetof(entry_point_info_t, pc), \
+		assert_entrypoint_and_spsr_should_be_adjacent);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __EP_INFO_H__ */
+
diff --git a/include/common/param_header.h b/include/common/param_header.h
new file mode 100644
index 0000000..176fc95
--- /dev/null
+++ b/include/common/param_header.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PARAM_HEADER_H__
+#define __PARAM_HEADER_H__
+
+/* Param header types */
+#define PARAM_EP		0x01
+#define PARAM_IMAGE_BINARY	0x02
+#define PARAM_BL31		0x03
+#define PARAM_BL_LOAD_INFO	0x04
+#define PARAM_BL_PARAMS		0x05
+#define PARAM_PSCI_LIB_ARGS	0x06
+
+/* Param header version */
+#define VERSION_1	0x01
+#define VERSION_2	0x02
+
+#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \
+	(_p)->h.type = (uint8_t)(_type); \
+	(_p)->h.version = (uint8_t)(_ver); \
+	(_p)->h.size = (uint16_t)sizeof(*_p); \
+	(_p)->h.attr = (uint32_t)(_attr) ; \
+	} while (0)
+
+/* Following is used for populating structure members statically. */
+#define SET_STATIC_PARAM_HEAD(_p, _type, _ver, _p_type, _attr)	\
+	._p.h.type = (uint8_t)(_type), \
+	._p.h.version = (uint8_t)(_ver), \
+	._p.h.size = (uint16_t)sizeof(_p_type), \
+	._p.h.attr = (uint32_t)(_attr)
+
+#ifndef __ASSEMBLY__
+
+#include <types.h>
+
+/***************************************************************************
+ * This structure provides version information and the size of the
+ * structure, attributes for the structure it represents
+ ***************************************************************************/
+typedef struct param_header {
+	uint8_t type;		/* type of the structure */
+	uint8_t version;    /* version of this structure */
+	uint16_t size;      /* size of this structure in bytes */
+	uint32_t attr;      /* attributes: unused bits SBZ */
+} param_header_t;
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __PARAM_HEADER_H__ */
+
diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h
index a8d7241..9fce424 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -33,8 +33,8 @@
 /*
  * Key algorithms currently supported on mbed TLS libraries
  */
-#define MBEDTLS_RSA			1
-#define MBEDTLS_ECDSA			2
+#define TBBR_RSA	1
+#define TBBR_ECDSA	2
 
 /*
  * Configuration file to build mbed TLS with the required features for
@@ -69,11 +69,11 @@
 
 #define MBEDTLS_PLATFORM_C
 
-#if (MBEDTLS_KEY_ALG_ID == MBEDTLS_ECDSA)
+#if (TBBR_KEY_ALG_ID == TBBR_ECDSA)
 #define MBEDTLS_ECDSA_C
 #define MBEDTLS_ECP_C
 #define MBEDTLS_ECP_DP_SECP256R1_ENABLED
-#elif (MBEDTLS_KEY_ALG_ID == MBEDTLS_RSA)
+#elif (TBBR_KEY_ALG_ID == TBBR_RSA)
 #define MBEDTLS_RSA_C
 #endif
 
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index 676973c..ca868dd 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -31,7 +31,9 @@
 #ifndef __CM_H__
 #define __CM_H__
 
+#ifndef AARCH32
 #include <arch.h>
+#endif
 
 /*******************************************************************************
  * Forward declarations
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index 34de4c2..fa85e0b 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -37,6 +37,7 @@
 #if ENABLE_PLAT_COMPAT
 #include <psci_compat.h>
 #endif
+#include <psci_lib.h>		/* To maintain compatibility for SPDs */
 
 /*******************************************************************************
  * Number of power domains whose state this PSCI implementation can track
@@ -311,24 +312,6 @@
 } plat_psci_ops_t;
 
 /*******************************************************************************
- * Optional structure populated by the Secure Payload Dispatcher to be given a
- * chance to perform any bookkeeping before PSCI executes a power management
- * operation. It also allows PSCI to determine certain properties of the SP e.g.
- * migrate capability etc.
- ******************************************************************************/
-typedef struct spd_pm_ops {
-	void (*svc_on)(u_register_t target_cpu);
-	int32_t (*svc_off)(u_register_t __unused);
-	void (*svc_suspend)(u_register_t max_off_pwrlvl);
-	void (*svc_on_finish)(u_register_t __unused);
-	void (*svc_suspend_finish)(u_register_t max_off_pwrlvl);
-	int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu);
-	int32_t (*svc_migrate_info)(u_register_t *resident_cpu);
-	void (*svc_system_off)(void);
-	void (*svc_system_reset)(void);
-} spd_pm_ops_t;
-
-/*******************************************************************************
  * Function & Data prototypes
  ******************************************************************************/
 unsigned int psci_version(void);
@@ -357,63 +340,6 @@
  */
 void psci_entrypoint(void) __deprecated;
 
-/*
- * Function prototype for the warmboot entrypoint function which will be
- * programmed in the mailbox by the platform.
- */
-typedef void (*mailbox_entrypoint_t)(void);
-
-/******************************************************************************
- * Structure to pass PSCI Library arguments.
- *****************************************************************************/
-typedef struct psci_lib_args {
-	/* The version information of PSCI Library Interface */
-	param_header_t		h;
-	/* The warm boot entrypoint function */
-	mailbox_entrypoint_t	mailbox_ep;
-} psci_lib_args_t;
-
-/* Helper macro to set the psci_lib_args_t structure at runtime */
-#define SET_PSCI_LIB_ARGS_V1(_p, _entry)	do {			\
-	SET_PARAM_HEAD(_p, PARAM_PSCI_LIB_ARGS, VERSION_1, 0);		\
-	(_p)->mailbox_ep = (_entry);					\
-	} while (0)
-
-/* Helper macro to define the psci_lib_args_t statically */
-#define DEFINE_STATIC_PSCI_LIB_ARGS_V1(_name, _entry)		\
-	static const psci_lib_args_t (_name) = {		\
-		.h.type = (uint8_t)PARAM_PSCI_LIB_ARGS,		\
-		.h.version = (uint8_t)VERSION_1,		\
-		.h.size = (uint16_t)sizeof(_name),		\
-		.h.attr = 0,					\
-		.mailbox_ep = (_entry)				\
-	}
-
-/* Helper macro to verify the pointer to psci_lib_args_t structure */
-#define VERIFY_PSCI_LIB_ARGS_V1(_p)	((_p)			\
-		&& ((_p)->h.type == PARAM_PSCI_LIB_ARGS)	\
-		&& ((_p)->h.version == VERSION_1)		\
-		&& ((_p)->h.size == sizeof(*(_p)))		\
-		&& ((_p)->h.attr == 0)				\
-		&& ((_p)->mailbox_ep))
-
-/******************************************************************************
- * PSCI Library Interfaces
- *****************************************************************************/
-u_register_t psci_smc_handler(uint32_t smc_fid,
-			  u_register_t x1,
-			  u_register_t x2,
-			  u_register_t x3,
-			  u_register_t x4,
-			  void *cookie,
-			  void *handle,
-			  u_register_t flags);
-int psci_setup(const psci_lib_args_t *lib_args);
-void psci_warmboot_entrypoint(void);
-void psci_register_spd_pm_hook(const spd_pm_ops_t *pm);
-void psci_prepare_next_non_secure_ctx(
-			  entry_point_info_t *next_image_info);
-
 #endif /*__ASSEMBLY__*/
 
 #endif /* __PSCI_H__ */
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
new file mode 100644
index 0000000..2169d6d
--- /dev/null
+++ b/include/lib/psci/psci_lib.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PSCI_LIB_H__
+#define __PSCI_LIB_H__
+
+#include <ep_info.h>
+
+#ifndef __ASSEMBLY__
+#include <types.h>
+
+/*******************************************************************************
+ * Optional structure populated by the Secure Payload Dispatcher to be given a
+ * chance to perform any bookkeeping before PSCI executes a power management
+ * operation. It also allows PSCI to determine certain properties of the SP e.g.
+ * migrate capability etc.
+ ******************************************************************************/
+typedef struct spd_pm_ops {
+	void (*svc_on)(u_register_t target_cpu);
+	int32_t (*svc_off)(u_register_t __unused);
+	void (*svc_suspend)(u_register_t max_off_pwrlvl);
+	void (*svc_on_finish)(u_register_t __unused);
+	void (*svc_suspend_finish)(u_register_t max_off_pwrlvl);
+	int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu);
+	int32_t (*svc_migrate_info)(u_register_t *resident_cpu);
+	void (*svc_system_off)(void);
+	void (*svc_system_reset)(void);
+} spd_pm_ops_t;
+
+/*
+ * Function prototype for the warmboot entrypoint function which will be
+ * programmed in the mailbox by the platform.
+ */
+typedef void (*mailbox_entrypoint_t)(void);
+
+/******************************************************************************
+ * Structure to pass PSCI Library arguments.
+ *****************************************************************************/
+typedef struct psci_lib_args {
+	/* The version information of PSCI Library Interface */
+	param_header_t		h;
+	/* The warm boot entrypoint function */
+	mailbox_entrypoint_t	mailbox_ep;
+} psci_lib_args_t;
+
+/* Helper macro to set the psci_lib_args_t structure at runtime */
+#define SET_PSCI_LIB_ARGS_V1(_p, _entry)	do {			\
+	SET_PARAM_HEAD(_p, PARAM_PSCI_LIB_ARGS, VERSION_1, 0);		\
+	(_p)->mailbox_ep = (_entry);					\
+	} while (0)
+
+/* Helper macro to define the psci_lib_args_t statically */
+#define DEFINE_STATIC_PSCI_LIB_ARGS_V1(_name, _entry)		\
+	static const psci_lib_args_t (_name) = {		\
+		.h.type = (uint8_t)PARAM_PSCI_LIB_ARGS,		\
+		.h.version = (uint8_t)VERSION_1,		\
+		.h.size = (uint16_t)sizeof(_name),		\
+		.h.attr = 0,					\
+		.mailbox_ep = (_entry)				\
+	}
+
+/* Helper macro to verify the pointer to psci_lib_args_t structure */
+#define VERIFY_PSCI_LIB_ARGS_V1(_p)	((_p)			\
+		&& ((_p)->h.type == PARAM_PSCI_LIB_ARGS)	\
+		&& ((_p)->h.version == VERSION_1)		\
+		&& ((_p)->h.size == sizeof(*(_p)))		\
+		&& ((_p)->h.attr == 0)				\
+		&& ((_p)->mailbox_ep))
+
+/******************************************************************************
+ * PSCI Library Interfaces
+ *****************************************************************************/
+u_register_t psci_smc_handler(uint32_t smc_fid,
+			  u_register_t x1,
+			  u_register_t x2,
+			  u_register_t x3,
+			  u_register_t x4,
+			  void *cookie,
+			  void *handle,
+			  u_register_t flags);
+int psci_setup(const psci_lib_args_t *lib_args);
+void psci_warmboot_entrypoint(void);
+void psci_register_spd_pm_hook(const spd_pm_ops_t *pm);
+void psci_prepare_next_non_secure_ctx(
+			  entry_point_info_t *next_image_info);
+#endif /* __ASSEMBLY__ */
+
+#endif /* __PSCI_LIB_H */
+
diff --git a/include/lib/utils.h b/include/lib/utils.h
index 69bbb43..279c913 100644
--- a/include/lib/utils.h
+++ b/include/lib/utils.h
@@ -42,6 +42,20 @@
 
 #define BIT(nr)				(1UL << (nr))
 
+#define MIN(x, y) __extension__ ({	\
+	__typeof__(x) _x = (x);		\
+	__typeof__(y) _y = (y);		\
+	(void)(&_x == &_y);		\
+	_x < _y ? _x : _y;		\
+})
+
+#define MAX(x, y) __extension__ ({	\
+	__typeof__(x) _x = (x);		\
+	__typeof__(y) _y = (y);		\
+	(void)(&_x == &_y);		\
+	_x > _y ? _x : _y;		\
+})
+
 /*
  * The round_up() macro rounds up a value to the given boundary in a
  * type-agnostic yet type-safe manner. The boundary must be a power of two.
diff --git a/include/plat/arm/board/common/board_css_def.h b/include/plat/arm/board/common/board_css_def.h
index 65e3d32..4b5e84d 100644
--- a/include/plat/arm/board/common/board_css_def.h
+++ b/include/plat/arm/board/common/board_css_def.h
@@ -33,6 +33,7 @@
 
 #include <common_def.h>
 #include <soc_css_def.h>
+#include <utils.h>
 #include <v2m_def.h>
 
 /*
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 8ce718a..43e0eb8 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -34,6 +34,7 @@
 #include <common_def.h>
 #include <platform_def.h>
 #include <tbbr_img_def.h>
+#include <utils.h>
 #include <xlat_tables_defs.h>
 
 
diff --git a/include/plat/arm/soc/common/soc_css_def.h b/include/plat/arm/soc/common/soc_css_def.h
index e83144e..3b4cc79 100644
--- a/include/plat/arm/soc/common/soc_css_def.h
+++ b/include/plat/arm/soc/common/soc_css_def.h
@@ -32,6 +32,7 @@
 #define __SOC_CSS_DEF_H__
 
 #include <common_def.h>
+#include <utils.h>
 
 
 /*
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index e8dfb99..ddb1cab 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -72,6 +72,16 @@
 unsigned int plat_my_core_pos(void);
 int plat_core_pos_by_mpidr(u_register_t mpidr);
 
+#if STACK_PROTECTOR_ENABLED
+/*
+ * Return a new value to be used for the stack protection's canary.
+ *
+ * Ideally, this value is a random number that is impossible to predict by an
+ * attacker.
+ */
+u_register_t plat_get_stack_protector_canary(void);
+#endif /* STACK_PROTECTOR_ENABLED */
+
 /*******************************************************************************
  * Mandatory interrupt management functions
  ******************************************************************************/
@@ -327,7 +337,7 @@
 
 unsigned int plat_get_aff_count(unsigned int, unsigned long);
 unsigned int plat_get_aff_state(unsigned int, unsigned long);
-#else
+#else /* __ENABLE_PLAT_COMPAT__ */
 /*
  * The below function enable Trusted Firmware components like SPDs which
  * haven't migrated to the new platform API to compile on platforms which
@@ -336,4 +346,6 @@
 unsigned int platform_get_core_pos(unsigned long mpidr) __deprecated;
 
 #endif /* __ENABLE_PLAT_COMPAT__ */
+
 #endif /* __PLATFORM_H__ */
+
diff --git a/lib/stack_protector/aarch32/asm_stack_protector.S b/lib/stack_protector/aarch32/asm_stack_protector.S
new file mode 100644
index 0000000..9d2d77d
--- /dev/null
+++ b/lib/stack_protector/aarch32/asm_stack_protector.S
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+
+	.globl	update_stack_protector_canary
+
+/* -----------------------------------------------------------------------
+ * void update_stack_protector_canary(void)
+ *
+ * Change the value of the canary used for stack smashing attacks protection.
+ * Note: This must be called when it is safe to call C code, but this cannot be
+ * called by C code. Doing this will make the check fail when the calling
+ * function returns.
+ * -----------------------------------------------------------------------
+ */
+
+func update_stack_protector_canary
+	/* Use r4 as it is callee-saved */
+	mov	r4, lr
+	bl	plat_get_stack_protector_canary
+
+	/* Update the canary with the returned value */
+	ldr	r1,  =__stack_chk_guard
+	str	r0, [r1]
+	bx	r4
+endfunc update_stack_protector_canary
+
+
diff --git a/lib/stack_protector/aarch64/asm_stack_protector.S b/lib/stack_protector/aarch64/asm_stack_protector.S
new file mode 100644
index 0000000..36f8f06
--- /dev/null
+++ b/lib/stack_protector/aarch64/asm_stack_protector.S
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+
+	.globl	update_stack_protector_canary
+
+/* -----------------------------------------------------------------------
+ * void update_stack_protector_canary(void)
+ *
+ * Change the value of the canary used for stack smashing attacks protection.
+ * Note: This must be called when it is safe to call C code, but this cannot be
+ * called by C code. Doing this will make the check fail when the calling
+ * function returns.
+ * -----------------------------------------------------------------------
+ */
+
+func update_stack_protector_canary
+	/* Use x19 as it is callee-saved */
+	mov	x19, x30
+	bl	plat_get_stack_protector_canary
+
+	/* Update the canary with the returned value */
+	adrp	x1,  __stack_chk_guard
+	str	x0, [x1, #:lo12:__stack_chk_guard]
+	ret	x19
+endfunc update_stack_protector_canary
+
+
diff --git a/lib/stack_protector/stack_protector.c b/lib/stack_protector/stack_protector.c
new file mode 100644
index 0000000..ccf2af4
--- /dev/null
+++ b/lib/stack_protector/stack_protector.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <debug.h>
+#include <platform.h>
+#include <stdint.h>
+
+/*
+ * Canary value used by the compiler runtime checks to detect stack corruption.
+ *
+ * Force the canary to be in .data to allow predictable memory layout relatively
+ * to the stacks.
+ */
+u_register_t  __attribute__((section(".data.stack_protector_canary")))
+	__stack_chk_guard = (u_register_t) 3288484550995823360ULL;
+
+/*
+ * Function called when the stack's canary check fails, which means the stack
+ * was corrupted. It must not return.
+ */
+void __dead2 __stack_chk_fail(void)
+{
+#if DEBUG
+	ERROR("Stack corruption detected\n");
+#endif
+	panic();
+}
+
diff --git a/lib/stack_protector/stack_protector.mk b/lib/stack_protector/stack_protector.mk
new file mode 100644
index 0000000..03d47c4
--- /dev/null
+++ b/lib/stack_protector/stack_protector.mk
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# Boolean macro to be used in C code
+STACK_PROTECTOR_ENABLED := 0
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+STACK_PROTECTOR_ENABLED := 1
+BL_COMMON_SOURCES	+=	lib/stack_protector/stack_protector.c			\
+				lib/stack_protector/${ARCH}/asm_stack_protector.S
+
+TF_CFLAGS		+=	-fstack-protector-${ENABLE_STACK_PROTECTOR}
+endif
+
+$(eval $(call add_define,STACK_PROTECTOR_ENABLED))
+
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index de506be..e66f511 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -90,6 +90,9 @@
 # Flag to enable runtime instrumentation using PMF
 ENABLE_RUNTIME_INSTRUMENTATION	:= 0
 
+# Flag to enable stack corruption protection
+ENABLE_STACK_PROTECTOR		:= 0
+
 # Build flag to treat usage of deprecated platform and framework APIs as error.
 ERROR_DEPRECATED		:= 0
 
diff --git a/plat/arm/board/fvp/fvp_stack_protector.c b/plat/arm/board/fvp/fvp_stack_protector.c
new file mode 100644
index 0000000..0375c1e
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_stack_protector.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <platform.h>
+#include <stdint.h>
+
+#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL)
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+	/*
+	 * Ideally, a random number should be returned instead of the
+	 * combination of a timer's value and a compile-time constant. As the
+	 * FVP does not have any random number generator, this is better than
+	 * nothing but not necessarily really secure.
+	 */
+	return RANDOM_CANARY_VALUE ^ read_cntpct_el0();
+}
+
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index bf5e03b..4088e98 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -35,6 +35,7 @@
 #include <board_arm_def.h>
 #include <common_def.h>
 #include <tzc400.h>
+#include <utils.h>
 #include <v2m_def.h>
 #include "../fvp_def.h"
 
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 9b827a6..8bac0be 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -157,5 +157,9 @@
 # Disable the PSCI platform compatibility layer
 ENABLE_PLAT_COMPAT	:= 	0
 
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES	+=	plat/arm/board/fvp/fvp_stack_protector.c
+endif
+
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
diff --git a/plat/arm/board/juno/juno_decl.h b/plat/arm/board/juno/juno_decl.h
new file mode 100644
index 0000000..75ed5b0
--- /dev/null
+++ b/plat/arm/board/juno/juno_decl.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __JUNO_DECL_H__
+#define __JUNO_DECL_H__
+
+int juno_getentropy(void *buf, size_t len);
+
+#endif /* __JUNO_DECL_H__ */
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
index f27bbb2..a8e9872 100644
--- a/plat/arm/board/juno/juno_def.h
+++ b/plat/arm/board/juno/juno_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -75,6 +75,17 @@
 #define TZC400_NSAID_CORESIGHT		12
 
 /*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define TRNG_BASE	0x7FE60000ULL
+#define TRNG_NOUTPUTS	4
+#define TRNG_STATUS	0x10
+#define TRNG_INTMASK	0x14
+#define TRNG_CONFIG	0x18
+#define TRNG_CONTROL	0x1C
+#define TRNG_NBYTES	16	/* Number of bytes generated per round. */
+
+/*******************************************************************************
  * MMU-401 related constants
  ******************************************************************************/
 #define MMU401_SSD_OFFSET		0x4000
diff --git a/plat/arm/board/juno/juno_stack_protector.c b/plat/arm/board/juno/juno_stack_protector.c
new file mode 100644
index 0000000..720a522
--- /dev/null
+++ b/plat/arm/board/juno/juno_stack_protector.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <utils.h>
+#include "juno_decl.h"
+#include "juno_def.h"
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+	u_register_t c[TRNG_NBYTES / sizeof(u_register_t)];
+	u_register_t ret = 0;
+	size_t i;
+
+	if (juno_getentropy(c, sizeof(c)) != 0) {
+		ERROR("Not enough entropy to initialize canary value\n");
+		panic();
+	}
+
+	/*
+	 * On Juno we get 128-bits of entropy in one round.
+	 * Fuse the values together to form the canary.
+	 */
+	for (i = 0; i < ARRAY_SIZE(c); i++)
+		ret ^= c[i];
+	return ret;
+}
diff --git a/plat/arm/board/juno/juno_trng.c b/plat/arm/board/juno/juno_trng.c
new file mode 100644
index 0000000..2fcddcd
--- /dev/null
+++ b/plat/arm/board/juno/juno_trng.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <mmio.h>
+#include <string.h>
+#include <utils.h>
+#include "juno_def.h"
+
+#define NSAMPLE_CLOCKS	1 /* min 1 cycle, max 231 cycles */
+#define NRETRIES	5
+
+static inline int output_valid(void)
+{
+	int i;
+
+	for (i = 0; i < NRETRIES; i++) {
+		uint32_t val;
+
+		val = mmio_read_32(TRNG_BASE + TRNG_STATUS);
+		if (val & 1U)
+			break;
+	}
+	if (i >= NRETRIES)
+		return 0; /* No output data available. */
+	return 1;
+}
+
+/*
+ * This function fills `buf` with `len` bytes of entropy.
+ * It uses the Trusted Entropy Source peripheral on Juno.
+ * Returns 0 when the buffer has been filled with entropy
+ * successfully and -1 otherwise.
+ */
+int juno_getentropy(void *buf, size_t len)
+{
+	uint8_t *bp = buf;
+
+	assert(buf);
+	assert(len);
+	assert(!check_uptr_overflow((uintptr_t)bp, len));
+
+	/* Disable interrupt mode. */
+	mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0);
+	/* Program TRNG to sample for `NSAMPLE_CLOCKS`. */
+	mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS);
+
+	while (len > 0) {
+		int i;
+
+		/* Start TRNG. */
+		mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1);
+
+		/* Check if output is valid. */
+		if (!output_valid())
+			return -1;
+
+		/* Fill entropy buffer. */
+		for (i = 0; i < TRNG_NOUTPUTS; i++) {
+			size_t n;
+			uint32_t val;
+
+			val = mmio_read_32(TRNG_BASE + i * sizeof(uint32_t));
+			n = MIN(len, sizeof(uint32_t));
+			memcpy(bp, &val, n);
+			bp += n;
+			len -= n;
+			if (len == 0)
+				break;
+		}
+
+		/* Reset TRNG outputs. */
+		mmio_write_32(TRNG_BASE + TRNG_STATUS, 1);
+	}
+
+	return 0;
+}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 7571582..3997724 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -39,8 +39,12 @@
 
 JUNO_SECURITY_SOURCES	:=	drivers/arm/tzc/tzc400.c		\
 				plat/arm/board/juno/juno_security.c	\
+				plat/arm/board/juno/juno_trng.c		\
 				plat/arm/common/arm_tzc400.c
 
+ifneq (${ENABLE_STACK_PROTECTOR}, 0)
+JUNO_SECURITY_SOURCES	+=	plat/arm/board/juno/juno_stack_protector.c
+endif
 
 PLAT_INCLUDES		:=	-Iplat/arm/board/juno/include
 
@@ -51,7 +55,8 @@
 				lib/cpus/aarch64/cortex_a72.S		\
 				plat/arm/board/juno/juno_bl1_setup.c	\
 				plat/arm/board/juno/juno_err.c		\
-				${JUNO_INTERCONNECT_SOURCES}
+				${JUNO_INTERCONNECT_SOURCES}		\
+				${JUNO_SECURITY_SOURCES}
 
 BL2_SOURCES		+=	plat/arm/board/juno/juno_err.c		\
 				${JUNO_SECURITY_SOURCES}
@@ -67,11 +72,20 @@
 				${JUNO_INTERCONNECT_SOURCES}		\
 				${JUNO_SECURITY_SOURCES}
 
-# Enable workarounds for selected Cortex-A53 and A57 erratas.
+# Enable workarounds for selected Cortex-A53 and A57 errata.
 ERRATA_A53_855873		:=	1
 ERRATA_A57_806969		:=	0
 ERRATA_A57_813419		:=	1
 ERRATA_A57_813420		:=	1
+ERRATA_A57_826974		:=	1
+ERRATA_A57_826977		:=	1
+ERRATA_A57_828024		:=	1
+ERRATA_A57_829520		:=	1
+ERRATA_A57_833471		:=	1
+
+# Enable workarounds for selected Cortex-A53 errata.
+ERRATA_A53_826319		:=	1
+ERRATA_A53_836870		:=	1
 
 # Enable option to skip L1 data cache flush during the Cortex-A57 cluster
 # power down sequence
diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S
index 472cd2e..73d5fdf 100644
--- a/plat/mediatek/mt6795/bl31.ld.S
+++ b/plat/mediatek/mt6795/bl31.ld.S
@@ -95,6 +95,11 @@
      */
     __RW_START__ = . ;
 
+    /*
+     * .data must be placed at a lower address than the stacks if the stack
+     * protector is enabled. Alternatively, the .data.stack_protector_canary
+     * section can be placed independently of the main .data section.
+     */
     .data . : {
         __DATA_START__ = .;
         *(.data*)
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
index c417050..859ecd5 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
@@ -43,7 +43,7 @@
 #define  GPU_RESET_BIT			(1 << 24)
 
 /* Video Memory base and size (live values) */
-static uintptr_t video_mem_base;
+static uint64_t video_mem_base;
 static uint64_t video_mem_size;
 
 /*
@@ -85,7 +85,9 @@
 	(void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */
 
 	/* video memory carveout */
-	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE, video_mem_base);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
+			  (uint32_t)(video_mem_base >> 32));
+	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base);
 	tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size);
 }
 
@@ -208,7 +210,8 @@
 	enable_mmu_el3(0);
 
 done:
-	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE, phys_base);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32));
+	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base);
 	tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);
 
 	/* store new values */
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index f020204..fb57b2b 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -38,6 +38,7 @@
 #include <smmu.h>
 #include <string.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 #include <xlat_tables.h>
 
 #define TEGRA_GPU_RESET_REG_OFFSET	0x30
@@ -45,7 +46,7 @@
 
 /* Video Memory base and size (live values) */
 static uint64_t video_mem_base;
-static uint64_t video_mem_size;
+static uint64_t video_mem_size_mb;
 
 /* array to hold stream_id override config register offsets */
 const static uint32_t streamid_overrides[] = {
@@ -135,7 +136,7 @@
 	mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(AONDMAW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(GPUSWR2, SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE),
@@ -144,8 +145,7 @@
 	mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SESWR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, ENABLE),
@@ -159,9 +159,7 @@
 	mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(VIW, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
@@ -180,8 +178,8 @@
 	mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(AONDMAR, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(AONW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE),
@@ -190,14 +188,17 @@
 	mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(AONR, NON_SECURE, OVERRIDE, ENABLE),
-	mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
-	mc_make_sec_cfg(SESRD, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(GPUSWR, SECURE, NO_OVERRIDE, DISABLE),
 	mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
 	mc_make_sec_cfg(ISPWB, NON_SECURE, OVERRIDE, ENABLE),
 	mc_make_sec_cfg(GPUSRD2, SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
 };
 
 const static mc_txn_override_cfg_t mc_override_cfgs[] = {
@@ -234,6 +235,251 @@
 	mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR),
 };
 
+static void tegra_memctrl_reconfig_mss_clients(void)
+{
+#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
+	uint32_t val, wdata_0, wdata_1;
+
+	/*
+	 * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for
+	 * boot and strongly ordered MSS clients to flush existing memory
+	 * traffic and stall future requests.
+	 */
+	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
+	assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL);
+
+	wdata_0 = MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+	} while ((val & wdata_0) != wdata_0);
+
+	/* Wait one more time due to SW WAR for known legacy issue */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+	} while ((val & wdata_0) != wdata_0);
+
+	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
+	assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL);
+
+	wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+	} while ((val & wdata_1) != wdata_1);
+
+	/* Wait one more time due to SW WAR for known legacy issue */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+	} while ((val & wdata_1) != wdata_1);
+
+	/*
+	 * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
+	 * strongly ordered MSS clients. ROC needs to be single point
+	 * of control on overriding the memory type. So, remove TSA's
+	 * memtype override.
+	 */
+	mc_set_tsa_passthrough(AFIW);
+	mc_set_tsa_passthrough(HDAW);
+	mc_set_tsa_passthrough(SATAW);
+	mc_set_tsa_passthrough(XUSB_HOSTW);
+	mc_set_tsa_passthrough(XUSB_DEVW);
+	mc_set_tsa_passthrough(SDMMCWAB);
+	mc_set_tsa_passthrough(APEDMAW);
+	mc_set_tsa_passthrough(SESWR);
+	mc_set_tsa_passthrough(ETRW);
+	mc_set_tsa_passthrough(AXISW);
+	mc_set_tsa_passthrough(EQOSW);
+	mc_set_tsa_passthrough(UFSHCW);
+	mc_set_tsa_passthrough(BPMPDMAW);
+	mc_set_tsa_passthrough(AONDMAW);
+	mc_set_tsa_passthrough(SCEDMAW);
+
+	/*
+	 * Change COH_PATH_OVERRIDE_SO_DEV from NO_OVERRIDE -> FORCE_COHERENT
+	 * for boot and strongly ordered MSS clients. This steers all sodev
+	 * transactions to ROC.
+	 *
+	 * Change AXID_OVERRIDE/AXID_OVERRIDE_SO_DEV only for some clients
+	 * whose AXI IDs we know and trust.
+	 */
+
+	/* Match AFIW */
+	mc_set_forced_coherent_so_dev_cfg(AFIR);
+
+	/*
+	 * See bug 200131110 comment #35 - there are no normal requests
+	 * and AWID for SO/DEV requests is hardcoded in RTL for a
+	 * particular PCIE controller
+	 */
+	mc_set_forced_coherent_so_dev_cfg(AFIW);
+	mc_set_forced_coherent_cfg(HDAR);
+	mc_set_forced_coherent_cfg(HDAW);
+	mc_set_forced_coherent_cfg(SATAR);
+	mc_set_forced_coherent_cfg(SATAW);
+	mc_set_forced_coherent_cfg(XUSB_HOSTR);
+	mc_set_forced_coherent_cfg(XUSB_HOSTW);
+	mc_set_forced_coherent_cfg(XUSB_DEVR);
+	mc_set_forced_coherent_cfg(XUSB_DEVW);
+	mc_set_forced_coherent_cfg(SDMMCRAB);
+	mc_set_forced_coherent_cfg(SDMMCWAB);
+
+	/* Match APEDMAW */
+	mc_set_forced_coherent_axid_so_dev_cfg(APEDMAR);
+
+	/*
+	 * See bug 200131110 comment #35 - AWID for normal requests
+	 * is 0x80 and AWID for SO/DEV requests is 0x01
+	 */
+	mc_set_forced_coherent_axid_so_dev_cfg(APEDMAW);
+	mc_set_forced_coherent_cfg(SESRD);
+	mc_set_forced_coherent_cfg(SESWR);
+	mc_set_forced_coherent_cfg(ETRR);
+	mc_set_forced_coherent_cfg(ETRW);
+	mc_set_forced_coherent_cfg(AXISR);
+	mc_set_forced_coherent_cfg(AXISW);
+	mc_set_forced_coherent_cfg(EQOSR);
+	mc_set_forced_coherent_cfg(EQOSW);
+	mc_set_forced_coherent_cfg(UFSHCR);
+	mc_set_forced_coherent_cfg(UFSHCW);
+	mc_set_forced_coherent_cfg(BPMPDMAR);
+	mc_set_forced_coherent_cfg(BPMPDMAW);
+	mc_set_forced_coherent_cfg(AONDMAR);
+	mc_set_forced_coherent_cfg(AONDMAW);
+	mc_set_forced_coherent_cfg(SCEDMAR);
+	mc_set_forced_coherent_cfg(SCEDMAW);
+
+	/*
+	 * At this point, ordering can occur at ROC. So, remove PCFIFO's
+	 * control over ordering requests.
+	 *
+	 * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
+	 * boot and strongly ordered MSS clients
+	 */
+	val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) &
+		mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) &
+		mc_set_pcfifo_unordered_boot_so_mss(1, SATAW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val);
+
+	val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) &
+		mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_DEVW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val);
+
+	val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val);
+
+	val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, EQOSW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val);
+
+	val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val);
+
+	/*
+	 * At this point, ordering can occur at ROC. SMMU need not
+	 * reorder any requests.
+	 *
+	 * Change SMMU_*_ORDERED_CLIENT from ORDERED -> UNORDERED
+	 * for boot and strongly ordered MSS clients
+	 */
+	val = MC_SMMU_CLIENT_CONFIG1_RESET_VAL &
+		mc_set_smmu_unordered_boot_so_mss(1, AFIW) &
+		mc_set_smmu_unordered_boot_so_mss(1, HDAW) &
+		mc_set_smmu_unordered_boot_so_mss(1, SATAW);
+	tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG1, val);
+
+	val = MC_SMMU_CLIENT_CONFIG2_RESET_VAL &
+		mc_set_smmu_unordered_boot_so_mss(2, XUSB_HOSTW) &
+		mc_set_smmu_unordered_boot_so_mss(2, XUSB_DEVW);
+	tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG2, val);
+
+	val = MC_SMMU_CLIENT_CONFIG3_RESET_VAL &
+		mc_set_smmu_unordered_boot_so_mss(3, SDMMCWAB);
+	tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG3, val);
+
+	val = MC_SMMU_CLIENT_CONFIG4_RESET_VAL &
+		mc_set_smmu_unordered_boot_so_mss(4, SESWR) &
+		mc_set_smmu_unordered_boot_so_mss(4, ETRW) &
+		mc_set_smmu_unordered_boot_so_mss(4, AXISW) &
+		mc_set_smmu_unordered_boot_so_mss(4, EQOSW) &
+		mc_set_smmu_unordered_boot_so_mss(4, UFSHCW) &
+		mc_set_smmu_unordered_boot_so_mss(4, BPMPDMAW) &
+		mc_set_smmu_unordered_boot_so_mss(4, AONDMAW) &
+		mc_set_smmu_unordered_boot_so_mss(4, SCEDMAW);
+	tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG4, val);
+
+	val = MC_SMMU_CLIENT_CONFIG5_RESET_VAL &
+		mc_set_smmu_unordered_boot_so_mss(5, APEDMAW);
+	tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG5, val);
+
+	/*
+	 * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS
+	 * clients to allow memory traffic from all clients to start passing
+	 * through ROC
+	 */
+	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
+	assert(val == wdata_0);
+
+	wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+	} while ((val & wdata_0) != wdata_0);
+
+	/* Wait one more time due to SW WAR for known legacy issue */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+	} while ((val & wdata_0) != wdata_0);
+
+	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
+	assert(val == wdata_1);
+
+	wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+	} while ((val & wdata_1) != wdata_1);
+
+	/* Wait one more time due to SW WAR for known legacy issue */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+	} while ((val & wdata_1) != wdata_1);
+
+#endif
+}
+
 /*
  * Init Memory controller during boot.
  */
@@ -243,7 +489,6 @@
 	uint32_t num_overrides = sizeof(streamid_overrides) / sizeof(uint32_t);
 	uint32_t num_sec_cfgs = sizeof(sec_cfgs) / sizeof(mc_streamid_security_cfg_t);
 	uint32_t num_txn_overrides = sizeof(mc_override_cfgs) / sizeof(mc_txn_override_cfg_t);
-	uint32_t tegra_rev;
 	int i;
 
 	INFO("Tegra Memory Controller (v2)\n");
@@ -281,12 +526,18 @@
 		MC_SMMU_BYPASS_CONFIG_SETTINGS);
 
 	/*
+	 * Re-configure MSS to allow ROC to deal with ordering of the
+	 * Memory Controller traffic. This is needed as the Memory Controller
+	 * boots with MSS having all control, but ROC provides a performance
+	 * boost as compared to MSS.
+	 */
+	tegra_memctrl_reconfig_mss_clients();
+
+	/*
 	 * Set the MC_TXN_OVERRIDE registers for write clients.
 	 */
-	tegra_rev = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) &
-			HARDWARE_MINOR_REVISION_MASK) >> HARDWARE_MINOR_REVISION_SHIFT;
-
-	if (tegra_rev == HARDWARE_REVISION_A01) {
+	if (!tegra_platform_is_silicon() ||
+	    (tegra_platform_is_silicon() && tegra_get_chipid_minor() == 1)) {
 
 		/* GPU and NVENC settings for rev. A01 */
 		val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
@@ -322,13 +573,21 @@
  */
 void tegra_memctrl_restore_settings(void)
 {
+	/*
+	 * Re-configure MSS to allow ROC to deal with ordering of the
+	 * Memory Controller traffic. This is needed as the Memory Controller
+	 * resets during System Suspend with MSS having all control, but ROC
+	 * provides a performance boost as compared to MSS.
+	 */
+	tegra_memctrl_reconfig_mss_clients();
+
 	/* video memory carveout region */
 	if (video_mem_base) {
 		tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO,
 				  (uint32_t)video_mem_base);
 		tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
 				  (uint32_t)(video_mem_base >> 32));
-		tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size);
+		tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb);
 
 		/*
 		 * MCE propogates the VideoMem configuration values across the
@@ -357,6 +616,20 @@
 	tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
 
 	/*
+	 * When TZ encryption enabled,
+	 * We need setup TZDRAM before CPU to access TZ Carveout,
+	 * otherwise CPU will fetch non-decrypted data.
+	 * So save TZDRAM setting for retore by SC7 resume FW.
+	 */
+
+	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_LO,
+					tegra_mc_read_32(MC_SECURITY_CFG0_0));
+	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_HI,
+					tegra_mc_read_32(MC_SECURITY_CFG3_0));
+	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV54_HI,
+					tegra_mc_read_32(MC_SECURITY_CFG1_0));
+
+	/*
 	 * MCE propogates the security configuration values across the
 	 * CCPLEX.
 	 */
@@ -371,33 +644,55 @@
  */
 void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
 {
-	uint64_t tzram_end = phys_base + size_in_bytes - 1;
+	uint32_t index;
+	uint32_t total_128kb_blocks = size_in_bytes >> 17;
+	uint32_t residual_4kb_blocks = (size_in_bytes & 0x1FFFF) >> 12;
 	uint32_t val;
 
 	/*
-	 * Check if the TZRAM is locked already.
+	 * Reset the access configuration registers to restrict access
+	 * to the TZRAM aperture
 	 */
-	if (tegra_mc_read_32(MC_TZRAM_REG_CTRL) == DISABLE_TZRAM_ACCESS)
-		return;
+	for (index = MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0;
+	     index <= MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5;
+	     index += 4)
+		tegra_mc_write_32(index, 0);
 
 	/*
-	 * Setup the Memory controller to allow only secure accesses to
-	 * the TZRAM carveout
+	 * Allow CPU read/write access to the aperture
 	 */
-	INFO("Configuring TrustZone RAM (SysRAM) Memory Carveout\n");
+	tegra_mc_write_32(MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG1,
+		TZRAM_CARVEOUT_CPU_WRITE_ACCESS_BIT |
+		TZRAM_CARVEOUT_CPU_READ_ACCESS_BIT);
 
-	/* Program the base and end values */
-	tegra_mc_write_32(MC_TZRAM_BASE, (uint32_t)phys_base);
-	tegra_mc_write_32(MC_TZRAM_END, (uint32_t)tzram_end);
+	/*
+	 * Set the TZRAM base. TZRAM base must be 4k aligned, at least.
+	 */
+	assert(!(phys_base & 0xFFF));
+	tegra_mc_write_32(MC_TZRAM_BASE_LO, (uint32_t)phys_base);
+	tegra_mc_write_32(MC_TZRAM_BASE_HI,
+		(uint32_t)(phys_base >> 32) & TZRAM_BASE_HI_MASK);
 
-	/* Extract the high address bits from the base/end values */
-	val = (uint32_t)(phys_base >> 32) & TZRAM_ADDR_HI_BITS_MASK;
-	val |= (((uint32_t)(tzram_end >> 32) & TZRAM_ADDR_HI_BITS_MASK) <<
-		TZRAM_END_HI_BITS_SHIFT);
-	tegra_mc_write_32(MC_TZRAM_HI_ADDR_BITS, val);
+	/*
+	 * Set the TZRAM size
+	 *
+	 * total size = (number of 128KB blocks) + (number of remaining 4KB
+	 * blocks)
+	 *
+	 */
+	val = (residual_4kb_blocks << TZRAM_SIZE_RANGE_4KB_SHIFT) |
+	      total_128kb_blocks;
+	tegra_mc_write_32(MC_TZRAM_SIZE, val);
 
-	/* Disable further writes to the TZRAM setup registers */
-	tegra_mc_write_32(MC_TZRAM_REG_CTRL, DISABLE_TZRAM_ACCESS);
+	/*
+	 * Lock the configuration settings by disabling TZ-only lock
+	 * and locking the configuration against any future changes
+	 * at all.
+	 */
+	val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
+	val &= ~TZRAM_ENABLE_TZ_LOCK_BIT;
+	val |= TZRAM_LOCK_CFG_SETTINGS_BIT;
+	tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val);
 
 	/*
 	 * MCE propogates the security configuration values across the
@@ -436,11 +731,11 @@
 	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base);
 	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
 			  (uint32_t)(phys_base >> 32));
-	tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);
 
 	/* store new values */
 	video_mem_base = phys_base;
-	video_mem_size = size_in_bytes >> 20;
+	video_mem_size_mb = size_in_bytes >> 20;
 
 	/*
 	 * MCE propogates the VideoMem configuration values across the
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v1.h b/plat/nvidia/tegra/include/drivers/memctrl_v1.h
index e44a9ea..b504594 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v1.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v1.h
@@ -60,14 +60,6 @@
 #define MC_SMMU_TRANSLATION_ENABLE_4_0		0xb98
 #define  MC_SMMU_TRANSLATION_ENABLE		(~0)
 
-/* TZDRAM carveout configuration registers */
-#define MC_SECURITY_CFG0_0			0x70
-#define MC_SECURITY_CFG1_0			0x74
-
-/* Video Memory carveout configuration registers */
-#define MC_VIDEO_PROTECT_BASE			0x648
-#define MC_VIDEO_PROTECT_SIZE_MB		0x64c
-
 static inline uint32_t tegra_mc_read_32(uint32_t off)
 {
 	return mmio_read_32(TEGRA_MC_BASE + off);
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index 9623e25..559ea2c 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -31,7 +31,6 @@
 #ifndef __MEMCTRLV2_H__
 #define __MEMCTRLV2_H__
 
-#include <mmio.h>
 #include <tegra_def.h>
 
 /*******************************************************************************
@@ -283,6 +282,10 @@
 #define MC_TXN_OVERRIDE_CONFIG_AFIW		0x1188
 #define MC_TXN_OVERRIDE_CONFIG_SCEW		0x14e0
 
+#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID	(1 << 0)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV	(2 << 4)
+#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT	(1 << 12)
+
 /*******************************************************************************
  * Non-SO_DEV transactions override values for CGID_TAG bitfield for the
  * MC_TXN_OVERRIDE_CONFIG_{module} registers
@@ -293,6 +296,10 @@
 #define MC_TXN_OVERRIDE_CGID_TAG_ADR		3
 #define MC_TXN_OVERRIDE_CGID_TAG_MASK		3
 
+#ifndef __ASSEMBLY__
+
+#include <sys/types.h>
+
 /*******************************************************************************
  * Structure to hold the transaction override settings to use to override
  * client inputs
@@ -327,12 +334,12 @@
 	int override_client_ns_flag;
 } mc_streamid_security_cfg_t;
 
-#define OVERRIDE_DISABLE			1
-#define OVERRIDE_ENABLE				0
-#define CLIENT_FLAG_SECURE			0
-#define CLIENT_FLAG_NON_SECURE			1
-#define CLIENT_INPUTS_OVERRIDE			1
-#define CLIENT_INPUTS_NO_OVERRIDE		0
+#define OVERRIDE_DISABLE				1
+#define OVERRIDE_ENABLE					0
+#define CLIENT_FLAG_SECURE				0
+#define CLIENT_FLAG_NON_SECURE				1
+#define CLIENT_INPUTS_OVERRIDE				1
+#define CLIENT_INPUTS_NO_OVERRIDE			0
 
 #define mc_make_sec_cfg(off, ns, ovrrd, access) \
 		{ \
@@ -343,30 +350,147 @@
 			.override_enable = OVERRIDE_ ## access \
 		}
 
-/*******************************************************************************
- * TZDRAM carveout configuration registers
- ******************************************************************************/
-#define MC_SECURITY_CFG0_0			0x70
-#define MC_SECURITY_CFG1_0			0x74
-#define MC_SECURITY_CFG3_0			0x9BC
+#endif /* __ASSEMBLY__ */
 
 /*******************************************************************************
- * Video Memory carveout configuration registers
+ * Memory Controller Reset Control registers
  ******************************************************************************/
-#define MC_VIDEO_PROTECT_BASE_HI		0x978
-#define MC_VIDEO_PROTECT_BASE_LO		0x648
-#define MC_VIDEO_PROTECT_SIZE_MB		0x64c
+#define MC_CLIENT_HOTRESET_CTRL0			0x200
+#define  MC_CLIENT_HOTRESET_CTRL0_RESET_VAL		0
+#define  MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB		(1 << 0)
+#define  MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB		(1 << 6)
+#define  MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB		(1 << 7)
+#define  MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB	(1 << 8)
+#define  MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB	(1 << 9)
+#define  MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB	(1 << 11)
+#define  MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB	(1 << 15)
+#define  MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB		(1 << 17)
+#define  MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB		(1 << 18)
+#define  MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB	(1 << 19)
+#define  MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB	(1 << 20)
+#define  MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB	(1 << 22)
+#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB	(1 << 29)
+#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB	(1 << 30)
+#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB	(1 << 31)
+#define MC_CLIENT_HOTRESET_STATUS0			0x204
+#define MC_CLIENT_HOTRESET_CTRL1			0x970
+#define  MC_CLIENT_HOTRESET_CTRL1_RESET_VAL		0
+#define  MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB	(1 << 0)
+#define  MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB		(1 << 2)
+#define  MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB	(1 << 5)
+#define  MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB		(1 << 6)
+#define  MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB		(1 << 7)
+#define  MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB	(1 << 8)
+#define  MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB		(1 << 12)
+#define  MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB	(1 << 13)
+#define  MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB	(1 << 18)
+#define  MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB	(1 << 19)
+#define  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB	(1 << 20)
+#define  MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB	(1 << 21)
+#define  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB	(1 << 22)
+#define  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB		(1 << 23)
+#define  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB		(1 << 24)
+#define MC_CLIENT_HOTRESET_STATUS1			0x974
 
 /*******************************************************************************
- * TZRAM carveout configuration registers
+ * Memory Controller's PCFIFO client configuration registers
  ******************************************************************************/
-#define MC_TZRAM_BASE				0x1850
-#define MC_TZRAM_END				0x1854
-#define MC_TZRAM_HI_ADDR_BITS			0x1588
- #define TZRAM_ADDR_HI_BITS_MASK		0x3
- #define TZRAM_END_HI_BITS_SHIFT		8
-#define MC_TZRAM_REG_CTRL			0x185c
- #define DISABLE_TZRAM_ACCESS			1
+#define MC_PCFIFO_CLIENT_CONFIG1			0xdd4
+#define  MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL		0x20000
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED	(0 << 17)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK	(1 << 17)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED	(0 << 21)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK	(1 << 21)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0 << 29)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK	(1 << 29)
+
+#define MC_PCFIFO_CLIENT_CONFIG2			0xdd8
+#define  MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL		0x20000
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED	(0 << 11)
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK	(1 << 11)
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED	(0 << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK	(1 << 13)
+
+#define MC_PCFIFO_CLIENT_CONFIG3			0xddc
+#define  MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL		0
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED	(0 << 7)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK	(1 << 7)
+
+#define MC_PCFIFO_CLIENT_CONFIG4		0xde0
+#define  MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL	0
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0 << 1)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK	(1 << 1)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED	(0 << 5)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK	(1 << 5)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0 << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK	(1 << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0 << 15)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK	(1 << 15)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED	(0 << 17)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK	(1 << 17)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED	(0 << 22)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK	(1 << 22)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED	(0 << 26)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK	(1 << 26)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED	(0 << 30)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK	(1 << 30)
+
+#define MC_PCFIFO_CLIENT_CONFIG5		0xbf4
+#define  MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL	0
+#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED	(0 << 0)
+#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK	(1 << 0)
+
+/*******************************************************************************
+ * Memory Controller's SMMU client configuration registers
+ ******************************************************************************/
+#define MC_SMMU_CLIENT_CONFIG1				0x44
+#define  MC_SMMU_CLIENT_CONFIG1_RESET_VAL		0x20000
+#define  MC_SMMU_CLIENT_CONFIG1_AFIW_UNORDERED		(0 << 17)
+#define  MC_SMMU_CLIENT_CONFIG1_AFIW_MASK		(1 << 17)
+#define  MC_SMMU_CLIENT_CONFIG1_HDAW_UNORDERED		(0 << 21)
+#define  MC_SMMU_CLIENT_CONFIG1_HDAW_MASK		(1 << 21)
+#define  MC_SMMU_CLIENT_CONFIG1_SATAW_UNORDERED		(0 << 29)
+#define  MC_SMMU_CLIENT_CONFIG1_SATAW_MASK		(1 << 29)
+
+#define MC_SMMU_CLIENT_CONFIG2				0x48
+#define  MC_SMMU_CLIENT_CONFIG2_RESET_VAL		0x20000
+#define  MC_SMMU_CLIENT_CONFIG2_XUSB_HOSTW_UNORDERED	(0 << 11)
+#define  MC_SMMU_CLIENT_CONFIG2_XUSB_HOSTW_MASK		(1 << 11)
+#define  MC_SMMU_CLIENT_CONFIG2_XUSB_DEVW_UNORDERED	(0 << 13)
+#define  MC_SMMU_CLIENT_CONFIG2_XUSB_DEVW_MASK		(1 << 13)
+
+#define MC_SMMU_CLIENT_CONFIG3				0x4c
+#define  MC_SMMU_CLIENT_CONFIG3_RESET_VAL		0
+#define  MC_SMMU_CLIENT_CONFIG3_SDMMCWAB_UNORDERED	(0 << 7)
+#define  MC_SMMU_CLIENT_CONFIG3_SDMMCWAB_MASK		(1 << 7)
+
+#define MC_SMMU_CLIENT_CONFIG4				0xb9c
+#define  MC_SMMU_CLIENT_CONFIG4_RESET_VAL		0
+#define  MC_SMMU_CLIENT_CONFIG4_SESWR_UNORDERED		(0 << 1)
+#define  MC_SMMU_CLIENT_CONFIG4_SESWR_MASK		(1 << 1)
+#define  MC_SMMU_CLIENT_CONFIG4_ETRW_UNORDERED		(0 << 5)
+#define  MC_SMMU_CLIENT_CONFIG4_ETRW_MASK		(1 << 5)
+#define  MC_SMMU_CLIENT_CONFIG4_AXISW_UNORDERED		(0 << 13)
+#define  MC_SMMU_CLIENT_CONFIG4_AXISW_MASK		(1 << 13)
+#define  MC_SMMU_CLIENT_CONFIG4_EQOSW_UNORDERED		(0 << 15)
+#define  MC_SMMU_CLIENT_CONFIG4_EQOSW_MASK		(1 << 15)
+#define  MC_SMMU_CLIENT_CONFIG4_UFSHCW_UNORDERED	(0 << 17)
+#define  MC_SMMU_CLIENT_CONFIG4_UFSHCW_MASK		(1 << 17)
+#define  MC_SMMU_CLIENT_CONFIG4_BPMPDMAW_UNORDERED	(0 << 22)
+#define  MC_SMMU_CLIENT_CONFIG4_BPMPDMAW_MASK		(1 << 22)
+#define  MC_SMMU_CLIENT_CONFIG4_AONDMAW_UNORDERED	(0 << 26)
+#define  MC_SMMU_CLIENT_CONFIG4_AONDMAW_MASK		(1 << 26)
+#define  MC_SMMU_CLIENT_CONFIG4_SCEDMAW_UNORDERED	(0 << 30)
+#define  MC_SMMU_CLIENT_CONFIG4_SCEDMAW_MASK		(1 << 30)
+
+#define MC_SMMU_CLIENT_CONFIG5				0xbac
+#define  MC_SMMU_CLIENT_CONFIG5_RESET_VAL		0
+#define  MC_SMMU_CLIENT_CONFIG5_APEDMAW_UNORDERED	(0 << 0)
+#define  MC_SMMU_CLIENT_CONFIG5_APEDMAW_MASK	(1 << 0)
+
+#ifndef __ASSEMBLY__
+
+#include <mmio.h>
 
 static inline uint32_t tegra_mc_read_32(uint32_t off)
 {
@@ -388,4 +512,42 @@
 	mmio_write_32(TEGRA_MC_STREAMID_BASE + off, val);
 }
 
+#define mc_set_pcfifo_unordered_boot_so_mss(id, client) \
+	(~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
+	 MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
+
+#define mc_set_smmu_unordered_boot_so_mss(id, client) \
+	(~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
+	 MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
+
+#define mc_set_tsa_passthrough(client) \
+	{ \
+		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
+			(TSA_CONFIG_STATIC0_CSW_##client##_RESET & \
+			 ~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+			TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+	}
+
+#define mc_set_forced_coherent_cfg(client) \
+	{ \
+		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
+			MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV); \
+	}
+
+#define mc_set_forced_coherent_so_dev_cfg(client) \
+	{ \
+		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
+			MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV | \
+			MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT); \
+	}
+
+#define mc_set_forced_coherent_axid_so_dev_cfg(client) \
+	{ \
+		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
+			MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV | \
+			MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID | \
+			MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT); \
+	}
+#endif /* __ASSMEBLY__ */
+
 #endif /* __MEMCTRLV2_H__ */
diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h
index bb08a55..0640846 100644
--- a/plat/nvidia/tegra/include/drivers/smmu.h
+++ b/plat/nvidia/tegra/include/drivers/smmu.h
@@ -599,9 +599,16 @@
  * SMMU Global Secure Aux. Configuration Register
  ******************************************************************************/
 #define SMMU_GSR0_SECURE_ACR			0x10
+#define SMMU_GNSR_ACR				(SMMU_GSR0_SECURE_ACR + 0x400)
 #define SMMU_GSR0_PGSIZE_SHIFT			16
 #define SMMU_GSR0_PGSIZE_4K			(0 << SMMU_GSR0_PGSIZE_SHIFT)
 #define SMMU_GSR0_PGSIZE_64K			(1 << SMMU_GSR0_PGSIZE_SHIFT)
+#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT		(1 << 26)
+
+/*******************************************************************************
+ * SMMU Global Aux. Control Register
+ ******************************************************************************/
+#define SMMU_CBn_ACTLR_CPRE_BIT			(1 << 1)
 
 /*******************************************************************************
  * SMMU configuration constants
@@ -627,6 +634,6 @@
 }
 
 void tegra_smmu_init(void);
-void tegra_smmu_save_context(void);
+void tegra_smmu_save_context(uint64_t smmu_ctx_addr);
 
 #endif /*__SMMU_H */
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
index 314b700..4ba4f12 100644
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ b/plat/nvidia/tegra/include/t132/tegra_def.h
@@ -104,6 +104,16 @@
  ******************************************************************************/
 #define TEGRA_MC_BASE			0x70019000
 
+/* TZDRAM carveout configuration registers */
+#define MC_SECURITY_CFG0_0		0x70
+#define MC_SECURITY_CFG1_0		0x74
+#define MC_SECURITY_CFG3_0		0x9BC
+
+/* Video Memory carveout configuration registers */
+#define MC_VIDEO_PROTECT_BASE_HI	0x978
+#define MC_VIDEO_PROTECT_BASE_LO	0x648
+#define MC_VIDEO_PROTECT_SIZE_MB	0x64c
+
 /*******************************************************************************
  * Tegra TZRAM constants
  ******************************************************************************/
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index f3fbb89..6bac0d7 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -31,7 +31,35 @@
 #ifndef __TEGRA_DEF_H__
 #define __TEGRA_DEF_H__
 
-#include <platform_def.h>
+/*******************************************************************************
+ * MCE apertures used by the ARI interface
+ *
+ * Aperture 0 - Cpu0 (ARM Cortex A-57)
+ * Aperture 1 - Cpu1 (ARM Cortex A-57)
+ * Aperture 2 - Cpu2 (ARM Cortex A-57)
+ * Aperture 3 - Cpu3 (ARM Cortex A-57)
+ * Aperture 4 - Cpu4 (Denver15)
+ * Aperture 5 - Cpu5 (Denver15)
+ ******************************************************************************/
+#define MCE_ARI_APERTURE_0_OFFSET	0x0
+#define MCE_ARI_APERTURE_1_OFFSET	0x10000
+#define MCE_ARI_APERTURE_2_OFFSET	0x20000
+#define MCE_ARI_APERTURE_3_OFFSET	0x30000
+#define MCE_ARI_APERTURE_4_OFFSET	0x40000
+#define MCE_ARI_APERTURE_5_OFFSET	0x50000
+#define MCE_ARI_APERTURE_OFFSET_MAX	MCE_APERTURE_5_OFFSET
+
+/* number of apertures */
+#define MCE_ARI_APERTURES_MAX		6
+
+/* each ARI aperture is 64KB */
+#define MCE_ARI_APERTURE_SIZE		0x10000
+
+/*******************************************************************************
+ * CPU core id macros for the MCE_ONLINE_CORE ARI
+ ******************************************************************************/
+#define MCE_CORE_ID_MAX			8
+#define MCE_CORE_ID_MASK		0x7
 
 /*******************************************************************************
  * These values are used by the PSCI implementation during the `CPU_SUSPEND`
@@ -78,17 +106,96 @@
  ******************************************************************************/
 #define TEGRA_MISC_BASE			0x00100000
 #define  HARDWARE_REVISION_OFFSET	0x4
-#define  HARDWARE_MINOR_REVISION_MASK	0xf0000
-#define  HARDWARE_MINOR_REVISION_SHIFT	0x10
-#define  HARDWARE_REVISION_A01		1
+
 #define  MISCREG_PFCFG			0x200C
 
 /*******************************************************************************
+ * Tegra TSA Controller constants
+ ******************************************************************************/
+#define TEGRA_TSA_BASE			0x02400000
+
+/*******************************************************************************
+ * TSA configuration registers
+ ******************************************************************************/
+#define TSA_CONFIG_STATIC0_CSW_SESWR			0x4010
+#define  TSA_CONFIG_STATIC0_CSW_SESWR_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_ETRW			0x4038
+#define  TSA_CONFIG_STATIC0_CSW_ETRW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_SDMMCWAB			0x5010
+#define  TSA_CONFIG_STATIC0_CSW_SDMMCWAB_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_AXISW			0x7008
+#define  TSA_CONFIG_STATIC0_CSW_AXISW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_HDAW			0xA008
+#define  TSA_CONFIG_STATIC0_CSW_HDAW_RESET		0x100
+#define TSA_CONFIG_STATIC0_CSW_AONDMAW			0xB018
+#define  TSA_CONFIG_STATIC0_CSW_AONDMAW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_SCEDMAW			0xD018
+#define  TSA_CONFIG_STATIC0_CSW_SCEDMAW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_BPMPDMAW			0xD028
+#define  TSA_CONFIG_STATIC0_CSW_BPMPDMAW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_APEDMAW			0x12018
+#define  TSA_CONFIG_STATIC0_CSW_APEDMAW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_UFSHCW			0x13008
+#define  TSA_CONFIG_STATIC0_CSW_UFSHCW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_AFIW			0x13018
+#define  TSA_CONFIG_STATIC0_CSW_AFIW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_SATAW			0x13028
+#define  TSA_CONFIG_STATIC0_CSW_SATAW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_EQOSW			0x13038
+#define  TSA_CONFIG_STATIC0_CSW_EQOSW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_XUSB_DEVW		0x15008
+#define  TSA_CONFIG_STATIC0_CSW_XUSB_DEVW_RESET		0x1100
+#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW		0x15018
+#define  TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW_RESET	0x1100
+
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK		(0x3 << 11)
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU		(0 << 11)
+
+/*******************************************************************************
  * Tegra Memory Controller constants
  ******************************************************************************/
 #define TEGRA_MC_STREAMID_BASE		0x02C00000
 #define TEGRA_MC_BASE			0x02C10000
 
+/* TZDRAM carveout configuration registers */
+#define MC_SECURITY_CFG0_0		0x70
+#define MC_SECURITY_CFG1_0		0x74
+#define MC_SECURITY_CFG3_0		0x9BC
+
+/* Video Memory carveout configuration registers */
+#define MC_VIDEO_PROTECT_BASE_HI	0x978
+#define MC_VIDEO_PROTECT_BASE_LO	0x648
+#define MC_VIDEO_PROTECT_SIZE_MB	0x64c
+
+/* TZRAM carveout (MC_SECURITY_CARVEOUT11) configuration registers */
+#define MC_TZRAM_BASE_LO		0x2194
+#define  TZRAM_BASE_LO_SHIFT		12
+#define  TZRAM_BASE_LO_MASK		0xFFFFF
+#define MC_TZRAM_BASE_HI		0x2198
+#define  TZRAM_BASE_HI_SHIFT		0
+#define  TZRAM_BASE_HI_MASK		3
+#define MC_TZRAM_SIZE			0x219C
+#define  TZRAM_SIZE_RANGE_4KB_SHIFT	27
+
+#define MC_TZRAM_CARVEOUT_CFG			0x2190
+#define  TZRAM_LOCK_CFG_SETTINGS_BIT		(1 << 1)
+#define  TZRAM_ENABLE_TZ_LOCK_BIT		(1 << 0)
+#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0	0x21A0
+#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG1	0x21A4
+#define  TZRAM_CARVEOUT_CPU_WRITE_ACCESS_BIT	(1 << 25)
+#define  TZRAM_CARVEOUT_CPU_READ_ACCESS_BIT	(1 << 7)
+#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG2	0x21A8
+#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG3	0x21AC
+#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG4	0x21B0
+#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG5	0x21B4
+
+#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS0	0x21B8
+#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS1	0x21BC
+#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS2	0x21C0
+#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS3	0x21C4
+#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS4	0x21C8
+#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5	0x21CC
+
 /*******************************************************************************
  * Tegra UART Controller constants
  ******************************************************************************/
@@ -101,6 +208,13 @@
 #define TEGRA_UARTG_BASE		0x0C290000
 
 /*******************************************************************************
+ * Tegra Fuse Controller related constants
+ ******************************************************************************/
+#define TEGRA_FUSE_BASE			0x03820000
+#define  OPT_SUBREVISION		0x248
+#define  SUBREVISION_MASK		0xFF
+
+/*******************************************************************************
  * GICv2 & interrupt handling related constants
  ******************************************************************************/
 #define TEGRA_GICD_BASE			0x03881000
@@ -138,6 +252,11 @@
 #define  SECURE_SCRATCH_RSV6		0x680
 #define  SECURE_SCRATCH_RSV11_LO	0x6A8
 #define  SECURE_SCRATCH_RSV11_HI	0x6AC
+#define  SECURE_SCRATCH_RSV53_LO	0x7F8
+#define  SECURE_SCRATCH_RSV53_HI	0x7FC
+#define  SECURE_SCRATCH_RSV54_HI	0x804
+#define  SECURE_SCRATCH_RSV55_LO	0x808
+#define  SECURE_SCRATCH_RSV55_HI	0x80C
 
 /*******************************************************************************
  * Tegra Memory Mapped Control Register Access Bus constants
@@ -153,6 +272,6 @@
  * Tegra TZRAM constants
  ******************************************************************************/
 #define TEGRA_TZRAM_BASE		0x30000000
-#define TEGRA_TZRAM_SIZE		0x50000
+#define TEGRA_TZRAM_SIZE		0x40000
 
 #endif /* __TEGRA_DEF_H__ */
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index d24377d..0961355 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -129,6 +129,16 @@
  ******************************************************************************/
 #define TEGRA_MC_BASE			0x70019000
 
+/* TZDRAM carveout configuration registers */
+#define MC_SECURITY_CFG0_0		0x70
+#define MC_SECURITY_CFG1_0		0x74
+#define MC_SECURITY_CFG3_0		0x9BC
+
+/* Video Memory carveout configuration registers */
+#define MC_VIDEO_PROTECT_BASE_HI	0x978
+#define MC_VIDEO_PROTECT_BASE_LO	0x648
+#define MC_VIDEO_PROTECT_SIZE_MB	0x64c
+
 /*******************************************************************************
  * Tegra TZRAM constants
  ******************************************************************************/
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index 012bfd7..39006f6 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -119,4 +119,7 @@
 /* Declarations for tegra_delay_timer.c */
 void tegra_delay_timer_init(void);
 
+void tegra_secure_entrypoint(void);
+void tegra186_cpu_reset_handler(void);
+
 #endif /* __TEGRA_PRIVATE_H__ */
diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h
index 7078b8b..441a2c1 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h
+++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h
@@ -35,65 +35,28 @@
 #include <tegra_def.h>
 
 /*******************************************************************************
- * MCE apertures used by the ARI interface
- *
- * Aperture 0 - Cpu0 (ARM Cortex A-57)
- * Aperture 1 - Cpu1 (ARM Cortex A-57)
- * Aperture 2 - Cpu2 (ARM Cortex A-57)
- * Aperture 3 - Cpu3 (ARM Cortex A-57)
- * Aperture 4 - Cpu4 (Denver15)
- * Aperture 5 - Cpu5 (Denver15)
- ******************************************************************************/
-#define MCE_ARI_APERTURE_0_OFFSET	0x0
-#define MCE_ARI_APERTURE_1_OFFSET	0x10000
-#define MCE_ARI_APERTURE_2_OFFSET	0x20000
-#define MCE_ARI_APERTURE_3_OFFSET	0x30000
-#define MCE_ARI_APERTURE_4_OFFSET	0x40000
-#define MCE_ARI_APERTURE_5_OFFSET	0x50000
-#define MCE_ARI_APERTURE_OFFSET_MAX	MCE_APERTURE_5_OFFSET
-
-/* number of apertures */
-#define MCE_ARI_APERTURES_MAX		6
-
-/* each ARI aperture is 64KB */
-#define MCE_ARI_APERTURE_SIZE		0x10000
-
-/*******************************************************************************
- * CPU core ids - used by the MCE_ONLINE_CORE ARI
- ******************************************************************************/
-typedef enum mce_core_id {
-	MCE_CORE_ID_DENVER_15_0,
-	MCE_CORE_ID_DENVER_15_1,
-	/* 2 and 3 are reserved */
-	MCE_CORE_ID_A57_0 = 4,
-	MCE_CORE_ID_A57_1,
-	MCE_CORE_ID_A57_2,
-	MCE_CORE_ID_A57_3,
-	MCE_CORE_ID_MAX
-} mce_core_id_t;
-
-#define MCE_CORE_ID_MASK			0x7
-
-/*******************************************************************************
  * MCE commands
  ******************************************************************************/
 typedef enum mce_cmd {
 	MCE_CMD_ENTER_CSTATE = 0,
-	MCE_CMD_UPDATE_CSTATE_INFO,
-	MCE_CMD_UPDATE_CROSSOVER_TIME,
-	MCE_CMD_READ_CSTATE_STATS,
-	MCE_CMD_WRITE_CSTATE_STATS,
-	MCE_CMD_IS_SC7_ALLOWED,
-	MCE_CMD_ONLINE_CORE,
-	MCE_CMD_CC3_CTRL,
-	MCE_CMD_ECHO_DATA,
-	MCE_CMD_READ_VERSIONS,
-	MCE_CMD_ENUM_FEATURES,
-	MCE_CMD_ROC_FLUSH_CACHE_TRBITS,
-	MCE_CMD_ENUM_READ_MCA,
-	MCE_CMD_ENUM_WRITE_MCA,
-	MCE_CMD_ROC_FLUSH_CACHE,
-	MCE_CMD_ROC_CLEAN_CACHE,
+	MCE_CMD_UPDATE_CSTATE_INFO = 1,
+	MCE_CMD_UPDATE_CROSSOVER_TIME = 2,
+	MCE_CMD_READ_CSTATE_STATS = 3,
+	MCE_CMD_WRITE_CSTATE_STATS = 4,
+	MCE_CMD_IS_SC7_ALLOWED = 5,
+	MCE_CMD_ONLINE_CORE = 6,
+	MCE_CMD_CC3_CTRL = 7,
+	MCE_CMD_ECHO_DATA = 8,
+	MCE_CMD_READ_VERSIONS = 9,
+	MCE_CMD_ENUM_FEATURES = 10,
+	MCE_CMD_ROC_FLUSH_CACHE_TRBITS = 11,
+	MCE_CMD_ENUM_READ_MCA = 12,
+	MCE_CMD_ENUM_WRITE_MCA = 13,
+	MCE_CMD_ROC_FLUSH_CACHE = 14,
+	MCE_CMD_ROC_CLEAN_CACHE = 15,
+	MCE_CMD_ENABLE_LATIC = 16,
+	MCE_CMD_UNCORE_PERFMON_REQ = 17,
+	MCE_CMD_MISC_CCPLEX = 18,
 	MCE_CMD_IS_CCX_ALLOWED = 0xFE,
 	MCE_CMD_MAX = 0xFF,
 } mce_cmd_t;
@@ -101,6 +64,24 @@
 #define MCE_CMD_MASK				0xFF
 
 /*******************************************************************************
+ * Struct to prepare UPDATE_CSTATE_INFO request
+ ******************************************************************************/
+typedef struct mce_cstate_info {
+	/* cluster cstate value */
+	uint32_t cluster;
+	/* ccplex cstate value */
+	uint32_t ccplex;
+	/* system cstate value */
+	uint32_t system;
+	/* force system state? */
+	uint8_t system_state_force;
+	/* wake mask value */
+	uint32_t wake_mask;
+	/* update the wake mask? */
+	uint8_t update_wake_mask;
+} mce_cstate_info_t;
+
+/*******************************************************************************
  * Macros to prepare CSTATE info request
  ******************************************************************************/
 /* Description of the parameters for UPDATE_CSTATE_INFO request */
@@ -183,6 +164,54 @@
 } mca_arg_t;
 
 /*******************************************************************************
+ * Uncore PERFMON ARI struct
+ ******************************************************************************/
+typedef union uncore_perfmon_req {
+	struct perfmon_command {
+		/*
+		 * Commands: 0 = READ, 1 = WRITE
+		 */
+		uint64_t cmd:8;
+		/*
+		 * The unit group: L2=0, L3=1, ROC=2, MC=3, IOB=4
+		 */
+		uint64_t grp:4;
+		/*
+		 * Unit selector: Selects the unit instance, with 0 = Unit
+		 * = (number of units in group) - 1.
+		 */
+		uint64_t unit:4;
+		/*
+		 * Selects the uncore perfmon register to access
+		 */
+		uint64_t reg:8;
+		/*
+		 * Counter number. Selects which counter to use for
+		 * registers NV_PMEVCNTR and NV_PMEVTYPER.
+		 */
+		uint64_t counter:8;
+	} perfmon_command;
+	struct perfmon_status {
+		/*
+		 * Resulting command status
+		 */
+		uint64_t val:8;
+		uint64_t unused:24;
+	} perfmon_status;
+	uint64_t data;
+} uncore_perfmon_req_t;
+
+#define UNCORE_PERFMON_CMD_READ			0
+#define UNCORE_PERFMON_CMD_WRITE		1
+
+#define UNCORE_PERFMON_CMD_MASK			0xFF
+#define UNCORE_PERFMON_UNIT_GRP_MASK		0xF
+#define UNCORE_PERFMON_SELECTOR_MASK		0xF
+#define UNCORE_PERFMON_REG_MASK			0xFF
+#define UNCORE_PERFMON_CTR_MASK			0xFF
+#define UNCORE_PERFMON_RESP_STATUS_MASK		0xFF
+
+/*******************************************************************************
  * Structure populated by arch specific code to export routines which perform
  * common low level MCE functions
  ******************************************************************************/
@@ -269,9 +298,7 @@
 	 * This ARI request allows updating the reset vector register for
 	 * D15 and A57 CPUs.
 	 */
-	int (*update_reset_vector)(uint32_t ari_base,
-				   uint32_t addr_low,
-				   uint32_t addr_high);
+	int (*update_reset_vector)(uint32_t ari_base);
 	/*
 	 * This ARI request instructs the ROC to flush A57 data caches in
 	 * order to maintain coherency with the Denver cluster.
@@ -312,15 +339,29 @@
 	 * reset the entire system
 	 */
 	void (*enter_ccplex_state)(uint32_t ari_base, uint32_t state_idx);
+	/*
+	 * This ARI request reads/writes data from/to Uncore PERFMON
+	 * registers
+	 */
+	int (*read_write_uncore_perfmon)(uint32_t ari_base,
+			uncore_perfmon_req_t req, uint64_t *data);
+	/*
+	 * This ARI implements ARI_MISC_CCPLEX commands. This can be
+	 * used to enable/disable coresight clock gating.
+	 */
+	void (*misc_ccplex)(uint32_t ari_base, uint32_t index,
+			uint32_t value);
 } arch_mce_ops_t;
 
 int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
 		uint64_t arg2);
-int mce_update_reset_vector(uint32_t addr_lo, uint32_t addr_hi);
+int mce_update_reset_vector(void);
 int mce_update_gsc_videomem(void);
 int mce_update_gsc_tzdram(void);
 int mce_update_gsc_tzram(void);
 __dead2 void mce_enter_ccplex_state(uint32_t state_idx);
+void mce_update_cstate_info(mce_cstate_info_t *cstate);
+void mce_verify_firmware_version(void);
 
 /* declarations for ARI/NVG handler functions */
 int ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time);
@@ -335,13 +376,16 @@
 int ari_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time);
 int ari_online_core(uint32_t ari_base, uint32_t core);
 int ari_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable);
-int ari_reset_vector_update(uint32_t ari_base, uint32_t lo, uint32_t hi);
+int ari_reset_vector_update(uint32_t ari_base);
 int ari_roc_flush_cache_trbits(uint32_t ari_base);
 int ari_roc_flush_cache(uint32_t ari_base);
 int ari_roc_clean_cache(uint32_t ari_base);
 uint64_t ari_read_write_mca(uint32_t ari_base, mca_cmd_t cmd, uint64_t *data);
 int ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx);
 void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx);
+int ari_read_write_uncore_perfmon(uint32_t ari_base,
+		uncore_perfmon_req_t req, uint64_t *data);
+void ari_misc_ccplex(uint32_t ari_base, uint32_t index, uint32_t value);
 
 int nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time);
 int nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex,
diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h b/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h
index 3e6054b..cb48de6 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h
+++ b/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h
@@ -40,8 +40,8 @@
  */
 
 enum {
-	TEGRA_ARI_VERSION_MAJOR = 2,
-	TEGRA_ARI_VERSION_MINOR = 19,
+	TEGRA_ARI_VERSION_MAJOR = 3,
+	TEGRA_ARI_VERSION_MINOR = 0,
 };
 
 typedef enum {
@@ -107,15 +107,15 @@
 typedef enum {
 	TEGRA_ARI_CCPLEX_CCP0 = 0,
 	TEGRA_ARI_CCPLEX_CCP1 = 1,
-	TEGRA_ARI_CCPLEX_CCP3 = 3,
+	TEGRA_ARI_CCPLEX_CCP3 = 3,  /* obsoleted */
 } tegra_ari_ccplex_sleep_state_t;
 
 typedef enum {
 	TEGRA_ARI_SYSTEM_SC0 = 0,
-	TEGRA_ARI_SYSTEM_SC1 = 1,
-	TEGRA_ARI_SYSTEM_SC2 = 2,
-	TEGRA_ARI_SYSTEM_SC3 = 3,
-	TEGRA_ARI_SYSTEM_SC4 = 4,
+	TEGRA_ARI_SYSTEM_SC1 = 1,  /* obsoleted */
+	TEGRA_ARI_SYSTEM_SC2 = 2,  /* obsoleted */
+	TEGRA_ARI_SYSTEM_SC3 = 3,  /* obsoleted */
+	TEGRA_ARI_SYSTEM_SC4 = 4,  /* obsoleted */
 	TEGRA_ARI_SYSTEM_SC7 = 7,
 	TEGRA_ARI_SYSTEM_SC8 = 8,
 } tegra_ari_system_sleep_state_t;
@@ -124,21 +124,22 @@
 	TEGRA_ARI_CROSSOVER_C1_C6 = 0,
 	TEGRA_ARI_CROSSOVER_CC1_CC6 = 1,
 	TEGRA_ARI_CROSSOVER_CC1_CC7 = 2,
-	TEGRA_ARI_CROSSOVER_CCP1_CCP3 = 3,
-	TEGRA_ARI_CROSSOVER_CCP3_SC2 = 4,
-	TEGRA_ARI_CROSSOVER_CCP3_SC3 = 5,
-	TEGRA_ARI_CROSSOVER_CCP3_SC4 = 6,
-	TEGRA_ARI_CROSSOVER_CCP3_SC7 = 7,
-	TEGRA_ARI_CROSSOVER_CCP3_SC1 = 8,
+	TEGRA_ARI_CROSSOVER_CCP1_CCP3 = 3,  /* obsoleted */
+	TEGRA_ARI_CROSSOVER_CCP3_SC2 = 4,  /* obsoleted */
+	TEGRA_ARI_CROSSOVER_CCP3_SC3 = 5,  /* obsoleted */
+	TEGRA_ARI_CROSSOVER_CCP3_SC4 = 6,  /* obsoleted */
+	TEGRA_ARI_CROSSOVER_CCP3_SC7 = 7,  /* obsoleted */
+	TEGRA_ARI_CROSSOVER_SC0_SC7 = 7,
+	TEGRA_ARI_CROSSOVER_CCP3_SC1 = 8,  /* obsoleted */
 } tegra_ari_crossover_index_t;
 
 typedef enum {
 	TEGRA_ARI_CSTATE_STATS_CLEAR = 0,
-	TEGRA_ARI_CSTATE_STATS_SC7_ENTRIES = 1,
-	TEGRA_ARI_CSTATE_STATS_SC4_ENTRIES,
-	TEGRA_ARI_CSTATE_STATS_SC3_ENTRIES,
-	TEGRA_ARI_CSTATE_STATS_SC2_ENTRIES,
-	TEGRA_ARI_CSTATE_STATS_CCP3_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_SC7_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_SC4_ENTRIES,  /* obsoleted */
+	TEGRA_ARI_CSTATE_STATS_SC3_ENTRIES,  /* obsoleted */
+	TEGRA_ARI_CSTATE_STATS_SC2_ENTRIES,  /* obsoleted */
+	TEGRA_ARI_CSTATE_STATS_CCP3_ENTRIES,  /* obsoleted */
 	TEGRA_ARI_CSTATE_STATS_A57_CC6_ENTRIES,
 	TEGRA_ARI_CSTATE_STATS_A57_CC7_ENTRIES,
 	TEGRA_ARI_CSTATE_STATS_D15_CC6_ENTRIES,
@@ -403,17 +404,18 @@
 	TEGRA_NVG_CHANNEL_CROSSOVER_C1_C6 = 5,
 	TEGRA_NVG_CHANNEL_CROSSOVER_CC1_CC6 = 6,
 	TEGRA_NVG_CHANNEL_CROSSOVER_CC1_CC7 = 7,
-	TEGRA_NVG_CHANNEL_CROSSOVER_CCP1_CCP3 = 8,
-	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC2 = 9,
-	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC3 = 10,
-	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC4 = 11,
-	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC7 = 12,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP1_CCP3 = 8,  /* obsoleted */
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC2 = 9,  /* obsoleted */
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC3 = 10,  /* obsoleted */
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC4 = 11,  /* obsoleted */
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC7 = 12,  /* obsoleted */
+	TEGRA_NVG_CHANNEL_CROSSOVER_SC0_SC7 = 12,
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR = 13,
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC7_ENTRIES = 14,
-	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC4_ENTRIES = 15,
-	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC3_ENTRIES = 16,
-	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC2_ENTRIES = 17,
-	TEGRA_NVG_CHANNEL_CSTATE_STATS_CCP3_ENTRIES = 18,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC4_ENTRIES = 15,  /* obsoleted */
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC3_ENTRIES = 16,  /* obsoleted */
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC2_ENTRIES = 17,  /* obsoleted */
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_CCP3_ENTRIES = 18,  /* obsoleted */
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_CC6_ENTRIES = 19,
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_CC7_ENTRIES = 20,
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_CC6_ENTRIES = 21,
@@ -432,7 +434,7 @@
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_3_C7_ENTRIES = 34,
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_0 = 35,
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_1 = 36,
-	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_2 = 37, /*  Reserved (for Denver15 core 2) */
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_2 = 37, /* Reserved (for Denver15 core 2) */
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_3 = 38, /* Reserved (for Denver15 core 3) */
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_0 = 39,
 	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_1 = 40,
@@ -441,10 +443,8 @@
 	TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = 43,
 	TEGRA_NVG_CHANNEL_ONLINE_CORE = 44,
 	TEGRA_NVG_CHANNEL_CC3_CTRL = 45,
-	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC1 = 46,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC1 = 46,  /* obsoleted */
 	TEGRA_NVG_CHANNEL_LAST_INDEX,
 } tegra_nvg_channel_id_t;
 
 #endif /* T18X_TEGRA_ARI_H */
-
-
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
index 147a358..7597c12 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -129,6 +129,9 @@
 		return EINVAL;
 	}
 
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	/* Enter the cstate, to be woken up after wake_time (TSC ticks) */
 	return ari_request_wait(ari_base, ARI_EVT_MASK_STANDBYWFI_BIT,
 		TEGRA_ARI_ENTER_CSTATE, state, wake_time);
@@ -140,6 +143,9 @@
 {
 	uint32_t val = 0;
 
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	/* update CLUSTER_CSTATE? */
 	if (cluster)
 		val |= (cluster & CLUSTER_CSTATE_MASK) |
@@ -172,6 +178,9 @@
 	    (type > TEGRA_ARI_CROSSOVER_CCP3_SC1))
 		return EINVAL;
 
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	/* update crossover threshold time */
 	return ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CROSSOVER,
 			type, time);
@@ -185,6 +194,9 @@
 	if (state == 0)
 		return EINVAL;
 
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_CSTATE_STATS, state, 0);
 	if (ret != 0)
 		return EINVAL;
@@ -194,6 +206,9 @@
 
 int ari_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats)
 {
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	/* write the cstate stats */
 	return ari_request_wait(ari_base, 0, TEGRA_ARI_WRITE_CSTATE_STATS, state,
 			stats);
@@ -226,6 +241,9 @@
 {
 	int ret;
 
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_IS_CCX_ALLOWED, state & 0x7,
 			wake_time);
 	if (ret) {
@@ -248,6 +266,9 @@
 		return EINVAL;
 	}
 
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_IS_SC7_ALLOWED, state,
 			wake_time);
 	if (ret) {
@@ -283,6 +304,9 @@
 		return EINVAL;
 	}
 
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	return ari_request_wait(ari_base, 0, TEGRA_ARI_ONLINE_CORE, core, 0);
 }
 
@@ -290,6 +314,9 @@
 {
 	int val;
 
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	/*
 	 * If the enable bit is cleared, Auto-CC3 will be disabled by setting
 	 * the SW visible voltage/frequency request registers for all non
@@ -307,31 +334,43 @@
 	return ari_request_wait(ari_base, 0, TEGRA_ARI_CC3_CTRL, val, 0);
 }
 
-int ari_reset_vector_update(uint32_t ari_base, uint32_t lo, uint32_t hi)
+int ari_reset_vector_update(uint32_t ari_base)
 {
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	/*
 	 * Need to program the CPU reset vector one time during cold boot
 	 * and SC7 exit
 	 */
-	ari_request_wait(ari_base, 0, TEGRA_ARI_COPY_MISCREG_AA64_RST, lo, hi);
+	ari_request_wait(ari_base, 0, TEGRA_ARI_COPY_MISCREG_AA64_RST, 0, 0);
 
 	return 0;
 }
 
 int ari_roc_flush_cache_trbits(uint32_t ari_base)
 {
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS,
 			0, 0);
 }
 
 int ari_roc_flush_cache(uint32_t ari_base)
 {
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_FLUSH_CACHE_ONLY,
 			0, 0);
 }
 
 int ari_roc_clean_cache(uint32_t ari_base)
 {
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_CLEAN_CACHE_ONLY,
 			0, 0);
 }
@@ -372,6 +411,9 @@
 	if (gsc_idx > TEGRA_ARI_GSC_VPR_IDX)
 		return EINVAL;
 
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	/*
 	 * The MCE code will read the GSC carveout value, corrseponding to
 	 * the ID, from the MC registers and update the internal GSC registers
@@ -384,8 +426,71 @@
 
 void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx)
 {
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
 	/*
 	 * The MCE will shutdown or restart the entire system
 	 */
 	(void)ari_request_wait(ari_base, 0, TEGRA_ARI_MISC_CCPLEX, state_idx, 0);
 }
+
+int ari_read_write_uncore_perfmon(uint32_t ari_base,
+		uncore_perfmon_req_t req, uint64_t *data)
+{
+	int ret;
+	uint32_t val;
+
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
+	/* sanity check input parameters */
+	if (req.perfmon_command.cmd == UNCORE_PERFMON_CMD_READ && !data) {
+		ERROR("invalid parameters\n");
+		return EINVAL;
+	}
+
+	/*
+	 * For "write" commands get the value that has to be written
+	 * to the uncore perfmon registers
+	 */
+	val = (req.perfmon_command.cmd == UNCORE_PERFMON_CMD_WRITE) ?
+		*data : 0;
+
+	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_PERFMON, val, req.data);
+	if (ret)
+		return ret;
+
+	/* read the command status value */
+	req.perfmon_status.val = ari_get_response_high(ari_base) &
+				 UNCORE_PERFMON_RESP_STATUS_MASK;
+
+	/*
+	 * For "read" commands get the data from the uncore
+	 * perfmon registers
+	 */
+	if ((req.perfmon_status.val == 0) && (req.perfmon_command.cmd ==
+	     UNCORE_PERFMON_CMD_READ))
+		*data = ari_get_response_low(ari_base);
+
+	return (int)req.perfmon_status.val;
+}
+
+void ari_misc_ccplex(uint32_t ari_base, uint32_t index, uint32_t value)
+{
+	/*
+	 * This invokes the ARI_MISC_CCPLEX commands. This can be
+	 * used to enable/disable coresight clock gating.
+	 */
+
+	if ((index > TEGRA_ARI_MISC_CCPLEX_CORESIGHT_CG_CTRL) ||
+		((index == TEGRA_ARI_MISC_CCPLEX_CORESIGHT_CG_CTRL) &&
+		(value > 1))) {
+		ERROR("%s: invalid parameters \n", __func__);
+		return;
+	}
+
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+	(void)ari_request_wait(ari_base, 0, TEGRA_ARI_MISC_CCPLEX, index, value);
+}
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
index 745b6f4..3a0edfb 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
@@ -42,6 +42,7 @@
 #include <sys/errno.h>
 #include <t18x_ari.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 
 /* NVG functions handlers */
 static arch_mce_ops_t nvg_mce_ops = {
@@ -61,7 +62,9 @@
 	.roc_clean_cache = ari_roc_clean_cache,
 	.read_write_mca = ari_read_write_mca,
 	.update_ccplex_gsc = ari_update_ccplex_gsc,
-	.enter_ccplex_state = ari_enter_ccplex_state
+	.enter_ccplex_state = ari_enter_ccplex_state,
+	.read_write_uncore_perfmon = ari_read_write_uncore_perfmon,
+	.misc_ccplex = ari_misc_ccplex
 };
 
 /* ARI functions handlers */
@@ -82,7 +85,9 @@
 	.roc_clean_cache = ari_roc_clean_cache,
 	.read_write_mca = ari_read_write_mca,
 	.update_ccplex_gsc = ari_update_ccplex_gsc,
-	.enter_ccplex_state = ari_enter_ccplex_state
+	.enter_ccplex_state = ari_enter_ccplex_state,
+	.read_write_uncore_perfmon = ari_read_write_uncore_perfmon,
+	.misc_ccplex = ari_misc_ccplex
 };
 
 typedef struct mce_config {
@@ -173,6 +178,7 @@
 	uint64_t ret64 = 0, arg3, arg4, arg5;
 	int ret = 0;
 	mca_cmd_t mca_cmd;
+	uncore_perfmon_req_t req;
 	cpu_context_t *ctx = cm_get_context(NON_SECURE);
 	gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
 
@@ -303,14 +309,12 @@
 		break;
 
 	case MCE_CMD_ENUM_FEATURES:
-		ret = ops->call_enum_misc(cpu_ari_base,
+		ret64 = ops->call_enum_misc(cpu_ari_base,
 				TEGRA_ARI_MISC_FEATURE_LEAF_0, arg0);
 
 		/* update context to return features value */
 		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64);
 
-		ret = 0;
-
 		break;
 
 	case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
@@ -356,6 +360,38 @@
 
 		break;
 
+#if ENABLE_CHIP_VERIFICATION_HARNESS
+	case MCE_CMD_ENABLE_LATIC:
+		/*
+		 * This call is not for production use. The constant value,
+		 * 0xFFFF0000, is specific to allowing for enabling LATIC on
+		 * pre-production parts for the chip verification harness.
+		 *
+		 * Enabling LATIC allows S/W to read the MINI ISPs in the
+		 * CCPLEX. The ISMs are used for various measurements relevant
+		 * to particular locations in the Silicon. They are small
+		 * counters which can be polled to determine how fast a
+		 * particular location in the Silicon is.
+		 */
+		ops->enter_ccplex_state(mce_get_curr_cpu_ari_base(),
+			0xFFFF0000);
+
+		break;
+#endif
+
+	case MCE_CMD_UNCORE_PERFMON_REQ:
+		memcpy(&req, &arg0, sizeof(arg0));
+		ret = ops->read_write_uncore_perfmon(cpu_ari_base, req, &arg1);
+
+		/* update context to return data */
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, arg1);
+		break;
+
+	case MCE_CMD_MISC_CCPLEX:
+		ops->misc_ccplex(cpu_ari_base, arg0, arg1);
+
+		break;
+
 	default:
 		ERROR("unknown MCE command (%d)\n", cmd);
 		return EINVAL;
@@ -367,11 +403,11 @@
 /*******************************************************************************
  * Handler to update the reset vector for CPUs
  ******************************************************************************/
-int mce_update_reset_vector(uint32_t addr_lo, uint32_t addr_hi)
+int mce_update_reset_vector(void)
 {
 	arch_mce_ops_t *ops = mce_get_curr_cpu_ops();
 
-	ops->update_reset_vector(mce_get_curr_cpu_ari_base(), addr_lo, addr_hi);
+	ops->update_reset_vector(mce_get_curr_cpu_ari_base());
 
 	return 0;
 }
@@ -429,3 +465,65 @@
 
 	panic();
 }
+
+/*******************************************************************************
+ * Handler to issue the UPDATE_CSTATE_INFO request
+ ******************************************************************************/
+void mce_update_cstate_info(mce_cstate_info_t *cstate)
+{
+	arch_mce_ops_t *ops = mce_get_curr_cpu_ops();
+
+	/* issue the UPDATE_CSTATE_INFO request */
+	ops->update_cstate_info(mce_get_curr_cpu_ari_base(), cstate->cluster,
+		cstate->ccplex, cstate->system, cstate->system_state_force,
+		cstate->wake_mask, cstate->update_wake_mask);
+}
+
+/*******************************************************************************
+ * Handler to read the MCE firmware version and check if it is compatible
+ * with interface header the BL3-1 was compiled against
+ ******************************************************************************/
+void mce_verify_firmware_version(void)
+{
+	arch_mce_ops_t *ops;
+	uint32_t cpu_ari_base;
+	uint64_t version;
+	uint32_t major, minor;
+
+	/*
+	 * MCE firmware is not running on simulation platforms.
+	 */
+	if (tegra_platform_is_emulation())
+		return;
+
+	/* get a pointer to the CPU's arch_mce_ops_t struct */
+	ops = mce_get_curr_cpu_ops();
+
+	/* get the CPU's ARI base address */
+	cpu_ari_base = mce_get_curr_cpu_ari_base();
+
+	/*
+	 * Read the MCE firmware version and extract the major and minor
+	 * version fields
+	 */
+	version = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION, 0);
+	major = (uint32_t)version;
+	minor = (uint32_t)(version >> 32);
+
+	INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor,
+		TEGRA_ARI_VERSION_MAJOR, TEGRA_ARI_VERSION_MINOR);
+
+	/*
+	 * Verify that the MCE firmware version and the interface header
+	 * match
+	 */
+	if (major != TEGRA_ARI_VERSION_MAJOR) {
+		ERROR("ARI major version mismatch\n");
+		panic();
+	}
+
+	if (minor < TEGRA_ARI_VERSION_MINOR) {
+		ERROR("ARI minor version mismatch\n");
+		panic();
+	}
+}
diff --git a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c
index 2940f58..bca6f2e 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c
@@ -29,9 +29,13 @@
  */
 
 #include <assert.h>
+#include <bl_common.h>
 #include <debug.h>
 #include <memctrl_v2.h>
+#include <platform_def.h>
 #include <smmu.h>
+#include <string.h>
+#include <tegra_private.h>
 
 typedef struct smmu_regs {
 	uint32_t reg;
@@ -133,7 +137,7 @@
 		.val = 0xFFFFFFFF, \
 	}
 
-static smmu_regs_t smmu_ctx_regs[] = {
+static __attribute__((aligned(16))) smmu_regs_t smmu_ctx_regs[] = {
 	_START_OF_TABLE_,
 	mc_make_sid_security_cfg(SCEW),
 	mc_make_sid_security_cfg(AFIR),
@@ -421,12 +425,15 @@
 };
 
 /*
- * Save SMMU settings before "System Suspend"
+ * Save SMMU settings before "System Suspend" to TZDRAM
  */
-void tegra_smmu_save_context(void)
+void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
 {
 	uint32_t i;
 #if DEBUG
+	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	uint64_t tzdram_base = params_from_bl2->tzdram_base;
+	uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size;
 	uint32_t reg_id1, pgshift, cb_size;
 
 	/* sanity check SMMU settings c*/
@@ -438,6 +445,8 @@
 	assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE)));
 #endif
 
+	assert((smmu_ctx_addr >= tzdram_base) && (smmu_ctx_addr <= tzdram_end));
+
 	/* index of _END_OF_TABLE_ */
 	smmu_ctx_regs[0].val = ARRAY_SIZE(smmu_ctx_regs) - 1;
 
@@ -445,22 +454,53 @@
 	for (i = 1; i < ARRAY_SIZE(smmu_ctx_regs) - 1; i++)
 		smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg);
 
+	/* Save SMMU config settings */
+	memcpy16((void *)(uintptr_t)smmu_ctx_addr, (void *)smmu_ctx_regs,
+		 sizeof(smmu_ctx_regs));
+
 	/* save the SMMU table address */
 	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_LO,
-		(uint32_t)(unsigned long)smmu_ctx_regs);
+		(uint32_t)smmu_ctx_addr);
 	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_HI,
-		(uint32_t)(((unsigned long)smmu_ctx_regs) >> 32));
+		(uint32_t)(smmu_ctx_addr >> 32));
 }
 
+#define SMMU_NUM_CONTEXTS		64
+#define SMMU_CONTEXT_BANK_MAX_IDX	64
+
 /*
  * Init SMMU during boot or "System Suspend" exit
  */
 void tegra_smmu_init(void)
 {
-	uint32_t val;
+	uint32_t val, i, ctx_base;
 
-	/* Program the SMMU pagesize */
+	/* Program the SMMU pagesize and reset CACHE_LOCK bit */
 	val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR);
 	val |= SMMU_GSR0_PGSIZE_64K;
+	val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+	tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val);
+
+	/* reset CACHE LOCK bit for NS Aux. Config. Register */
+	val = tegra_smmu_read_32(SMMU_GNSR_ACR);
+	val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+	tegra_smmu_write_32(SMMU_GNSR_ACR, val);
+
+	/* disable TCU prefetch for all contexts */
+	ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) + SMMU_CBn_ACTLR;
+	for (i = 0; i < SMMU_CONTEXT_BANK_MAX_IDX; i++) {
+		val = tegra_smmu_read_32(ctx_base + (SMMU_GSR0_PGSIZE_64K * i));
+		val &= ~SMMU_CBn_ACTLR_CPRE_BIT;
+		tegra_smmu_write_32(ctx_base + (SMMU_GSR0_PGSIZE_64K * i), val);
+	}
+
+	/* set CACHE LOCK bit for NS Aux. Config. Register */
+	val = tegra_smmu_read_32(SMMU_GNSR_ACR);
+	val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+	tegra_smmu_write_32(SMMU_GNSR_ACR, val);
+
+	/* set CACHE LOCK bit for S Aux. Config. Register */
+	val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR);
+	val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
 	tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val);
 }
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index 7e35cc6..a170b99 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -37,23 +37,35 @@
 #include <debug.h>
 #include <denver.h>
 #include <mce.h>
+#include <platform.h>
 #include <psci.h>
 #include <smmu.h>
+#include <string.h>
 #include <t18x_ari.h>
 #include <tegra_private.h>
 
 extern void prepare_cpu_pwr_dwn(void);
+extern void tegra186_cpu_reset_handler(void);
+extern uint32_t __tegra186_cpu_reset_handler_data,
+		__tegra186_cpu_reset_handler_end;
+
+/* TZDRAM offset for saving SMMU context */
+#define TEGRA186_SMMU_CTX_OFFSET	16
 
 /* state id mask */
 #define TEGRA186_STATE_ID_MASK		0xF
 /* constants to get power state's wake time */
-#define TEGRA186_WAKE_TIME_MASK		0xFFFFFF
+#define TEGRA186_WAKE_TIME_MASK		0x0FFFFFF0
 #define TEGRA186_WAKE_TIME_SHIFT	4
+/* default core wake mask for CPU_SUSPEND */
+#define TEGRA186_CORE_WAKE_MASK		0x180c
 /* context size to save during system suspend */
-#define TEGRA186_SE_CONTEXT_SIZE		3
+#define TEGRA186_SE_CONTEXT_SIZE	3
 
 static uint32_t se_regs[TEGRA186_SE_CONTEXT_SIZE];
-static unsigned int wake_time[PLATFORM_CORE_COUNT];
+static struct t18x_psci_percpu_data {
+	unsigned int wake_time;
+} __aligned(CACHE_WRITEBACK_GRANULE) percpu_data[PLATFORM_CORE_COUNT];
 
 /* System power down state */
 uint32_t tegra186_system_powerdn_state = TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF;
@@ -62,23 +74,30 @@
 					psci_power_state_t *req_state)
 {
 	int state_id = psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK;
-	int cpu = read_mpidr() & MPIDR_CPU_MASK;
-	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+	int cpu = plat_my_core_pos();
 
-	if (impl == DENVER_IMPL)
-		cpu |= 0x4;
+	/* save the core wake time (in TSC ticks)*/
+	percpu_data[cpu].wake_time = (power_state & TEGRA186_WAKE_TIME_MASK)
+			<< TEGRA186_WAKE_TIME_SHIFT;
 
-	wake_time[cpu] = (power_state  >> TEGRA186_WAKE_TIME_SHIFT) &
-			 TEGRA186_WAKE_TIME_MASK;
+	/*
+	 * Clean percpu_data[cpu] to DRAM. This needs to be done to ensure that
+	 * the correct value is read in tegra_soc_pwr_domain_suspend(), which
+	 * is called with caches disabled. It is possible to read a stale value
+	 * from DRAM in that function, because the L2 cache is not flushed
+	 * unless the cluster is entering CC6/CC7.
+	 */
+	clean_dcache_range((uint64_t)&percpu_data[cpu],
+			sizeof(percpu_data[cpu]));
 
 	/* Sanity check the requested state id */
 	switch (state_id) {
 	case PSTATE_ID_CORE_IDLE:
 	case PSTATE_ID_CORE_POWERDN:
-		/*
-		 * Core powerdown request only for afflvl 0
-		 */
+
+		/* Core powerdown request */
 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
+		req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
 
 		break;
 
@@ -94,18 +113,12 @@
 {
 	const plat_local_state_t *pwr_domain_state;
 	unsigned int stateid_afflvl0, stateid_afflvl2;
-	int cpu = read_mpidr() & MPIDR_CPU_MASK;
-	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
-	cpu_context_t *ctx = cm_get_context(NON_SECURE);
-	gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
+	int cpu = plat_my_core_pos();
+	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	mce_cstate_info_t cstate_info = { 0 };
+	uint64_t smmu_ctx_base;
 	uint32_t val;
 
-	assert(ctx);
-	assert(gp_regs);
-
-	if (impl == DENVER_IMPL)
-		cpu |= 0x4;
-
 	/* get the state ID */
 	pwr_domain_state = target_state->pwr_domain_state;
 	stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] &
@@ -113,28 +126,17 @@
 	stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
 		TEGRA186_STATE_ID_MASK;
 
-	if (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) {
+	if ((stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ||
+	    (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) {
 
-		/* Prepare for cpu idle */
-		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
-			TEGRA_ARI_CORE_C6, wake_time[cpu], 0);
-
-	} else if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) {
-
-		/* Prepare for cpu powerdn */
-		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
-			TEGRA_ARI_CORE_C7, wake_time[cpu], 0);
+		/* Enter CPU idle/powerdown */
+		val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ?
+			TEGRA_ARI_CORE_C6 : TEGRA_ARI_CORE_C7;
+		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE, val,
+				percpu_data[cpu].wake_time, 0);
 
 	} else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
 
-		/* loop until SC7 is allowed */
-		do {
-			val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
-					TEGRA_ARI_CORE_C7,
-					MCE_CORE_SLEEP_TIME_INFINITE,
-					0);
-		} while (val == 0);
-
 		/* save SE registers */
 		se_regs[0] = mmio_read_32(TEGRA_SE0_BASE +
 				SE_MUTEX_WATCHDOG_NS_LIMIT);
@@ -147,23 +149,130 @@
 		val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
 		mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV6, val);
 
-		/* save SMMU context */
-		tegra_smmu_save_context();
+		/* save SMMU context to TZDRAM */
+		smmu_ctx_base = params_from_bl2->tzdram_base +
+			((uintptr_t)&__tegra186_cpu_reset_handler_data -
+			 (uintptr_t)tegra186_cpu_reset_handler) +
+			TEGRA186_SMMU_CTX_OFFSET;
+		tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
 
 		/* Prepare for system suspend */
-		write_ctx_reg(gp_regs, CTX_GPREG_X4, 1);
-		write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
-		write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
-		(void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO,
-			TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC7);
+		cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
+		cstate_info.system = TEGRA_ARI_SYSTEM_SC7;
+		cstate_info.system_state_force = 1;
+		cstate_info.update_wake_mask = 1;
+		mce_update_cstate_info(&cstate_info);
 
-		/* Enter system suspend state */
+		/* Loop until system suspend is allowed */
+		do {
+			val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
+					TEGRA_ARI_CORE_C7,
+					MCE_CORE_SLEEP_TIME_INFINITE,
+					0);
+		} while (val == 0);
+
+		/* Instruct the MCE to enter system suspend state */
 		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
 			TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
+	}
 
-	} else {
-		ERROR("%s: Unknown state id\n", __func__);
-		return PSCI_E_NOT_SUPPORTED;
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Platform handler to calculate the proper target power level at the
+ * specified affinity level
+ ******************************************************************************/
+plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
+					     const plat_local_state_t *states,
+					     unsigned int ncpu)
+{
+	plat_local_state_t target = *states;
+	int cpu = plat_my_core_pos(), ret, cluster_powerdn = 1;
+	int core_pos = read_mpidr() & MPIDR_CPU_MASK;
+	mce_cstate_info_t cstate_info = { 0 };
+
+	/* get the current core's power state */
+	target = *(states + core_pos);
+
+	/* CPU suspend */
+	if (lvl == MPIDR_AFFLVL1 && target == PSTATE_ID_CORE_POWERDN) {
+
+		/* Program default wake mask */
+		cstate_info.wake_mask = TEGRA186_CORE_WAKE_MASK;
+		cstate_info.update_wake_mask = 1;
+		mce_update_cstate_info(&cstate_info);
+
+		/* Check if CCx state is allowed. */
+		ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED,
+				TEGRA_ARI_CORE_C7, percpu_data[cpu].wake_time,
+				0);
+		if (ret)
+			return PSTATE_ID_CORE_POWERDN;
+	}
+
+	/* CPU off */
+	if (lvl == MPIDR_AFFLVL1 && target == PLAT_MAX_OFF_STATE) {
+
+		/* find out the number of ON cpus in the cluster */
+		do {
+			target = *states++;
+			if (target != PLAT_MAX_OFF_STATE)
+				cluster_powerdn = 0;
+		} while (--ncpu);
+
+		/* Enable cluster powerdn from last CPU in the cluster */
+		if (cluster_powerdn) {
+
+			/* Enable CC7 state and turn off wake mask */
+			cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
+			cstate_info.update_wake_mask = 1;
+			mce_update_cstate_info(&cstate_info);
+
+			/* Check if CCx state is allowed. */
+			ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED,
+						  TEGRA_ARI_CORE_C7,
+						  MCE_CORE_SLEEP_TIME_INFINITE,
+						  0);
+			if (ret)
+				return PSTATE_ID_CORE_POWERDN;
+
+		} else {
+
+			/* Turn off wake_mask */
+			cstate_info.update_wake_mask = 1;
+			mce_update_cstate_info(&cstate_info);
+		}
+	}
+
+	/* System Suspend */
+	if ((lvl == MPIDR_AFFLVL2) || (target == PSTATE_ID_SOC_POWERDN))
+		return PSTATE_ID_SOC_POWERDN;
+
+	/* default state */
+	return PSCI_LOCAL_STATE_RUN;
+}
+
+int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
+	const plat_local_state_t *pwr_domain_state =
+		target_state->pwr_domain_state;
+	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
+		TEGRA186_STATE_ID_MASK;
+	uint32_t val;
+
+	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+		/*
+		 * The TZRAM loses power when we enter system suspend. To
+		 * allow graceful exit from system suspend, we need to copy
+		 * BL3-1 over to TZDRAM.
+		 */
+		val = params_from_bl2->tzdram_base +
+			((uintptr_t)&__tegra186_cpu_reset_handler_end -
+			 (uintptr_t)tegra186_cpu_reset_handler);
+		memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
+			 (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
 	}
 
 	return PSCI_E_SUCCESS;
@@ -190,13 +299,30 @@
 
 int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
-	int state_id = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
+	int stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
+	int stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0];
+	mce_cstate_info_t cstate_info = { 0 };
+
+	/*
+	 * Reset power state info for CPUs when onlining, we set
+	 * deepest power when offlining a core but that may not be
+	 * requested by non-secure sw which controls idle states. It
+	 * will re-init this info from non-secure software when the
+	 * core come online.
+	 */
+	if (stateid_afflvl0 == PLAT_MAX_OFF_STATE) {
+
+		cstate_info.cluster = TEGRA_ARI_CLUSTER_CC1;
+		cstate_info.update_wake_mask = 1;
+		mce_update_cstate_info(&cstate_info);
+	}
 
 	/*
 	 * Check if we are exiting from deep sleep and restore SE
 	 * context if we are.
 	 */
-	if (state_id == PSTATE_ID_SOC_POWERDN) {
+	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+
 		mmio_write_32(TEGRA_SE0_BASE + SE_MUTEX_WATCHDOG_NS_LIMIT,
 			se_regs[0]);
 		mmio_write_32(TEGRA_RNG1_BASE + RNG_MUTEX_WATCHDOG_NS_LIMIT,
@@ -206,6 +332,17 @@
 
 		/* Init SMMU */
 		tegra_smmu_init();
+
+		/*
+		 * Reset power state info for the last core doing SC7
+		 * entry and exit, we set deepest power state as CC7
+		 * and SC7 for SC7 entry which may not be requested by
+		 * non-secure SW which controls idle states.
+		 */
+		cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
+		cstate_info.system = TEGRA_ARI_SYSTEM_SC1;
+		cstate_info.update_wake_mask = 1;
+		mce_update_cstate_info(&cstate_info);
 	}
 
 	return PSCI_E_SUCCESS;
@@ -213,33 +350,22 @@
 
 int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
-	cpu_context_t *ctx = cm_get_context(NON_SECURE);
-	gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
 	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
 
-	assert(ctx);
-	assert(gp_regs);
-
-	/* Turn off wake_mask */
-	write_ctx_reg(gp_regs, CTX_GPREG_X4, 0);
-	write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
-	write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
-	mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, TEGRA_ARI_CLUSTER_CC7,
-		0, TEGRA_ARI_SYSTEM_SC7);
-
 	/* Disable Denver's DCO operations */
 	if (impl == DENVER_IMPL)
 		denver_disable_dco();
 
 	/* Turn off CPU */
-	return mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
+	(void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
 			MCE_CORE_SLEEP_TIME_INFINITE, 0);
+
+	return PSCI_E_SUCCESS;
 }
 
 __dead2 void tegra_soc_prepare_system_off(void)
 {
-	cpu_context_t *ctx = cm_get_context(NON_SECURE);
-	gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
+	mce_cstate_info_t cstate_info = { 0 };
 	uint32_t val;
 
 	if (tegra186_system_powerdn_state == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) {
@@ -249,6 +375,13 @@
 
 	} else if (tegra186_system_powerdn_state == TEGRA_ARI_SYSTEM_SC8) {
 
+		/* Prepare for quasi power down */
+		cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
+		cstate_info.system = TEGRA_ARI_SYSTEM_SC8;
+		cstate_info.system_state_force = 1;
+		cstate_info.update_wake_mask = 1;
+		mce_update_cstate_info(&cstate_info);
+
 		/* loop until other CPUs power down */
 		do {
 			val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
@@ -257,13 +390,6 @@
 					0);
 		} while (val == 0);
 
-		/* Prepare for quasi power down */
-		write_ctx_reg(gp_regs, CTX_GPREG_X4, 1);
-		write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
-		write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
-		(void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO,
-			TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC8);
-
 		/* Enter quasi power down state */
 		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
 			TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
@@ -274,6 +400,9 @@
 		/* power down core */
 		prepare_cpu_pwr_dwn();
 
+		/* flush L1/L2 data caches */
+		dcsw_op_all(DCCISW);
+
 	} else {
 		ERROR("%s: unsupported power down state (%d)\n", __func__,
 			tegra186_system_powerdn_state);
diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c
index df80289..6576db1 100644
--- a/plat/nvidia/tegra/soc/t186/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c
@@ -28,10 +28,13 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <arch_helpers.h>
 #include <debug.h>
 #include <mce.h>
 #include <mmio.h>
+#include <string.h>
 #include <tegra_def.h>
+#include <tegra_private.h>
 
 #define MISCREG_CPU_RESET_VECTOR	0x2000
 #define MISCREG_AA64_RST_LOW		0x2004
@@ -42,7 +45,8 @@
 
 #define CPU_RESET_MODE_AA64		1
 
-extern void tegra_secure_entrypoint(void);
+extern uint64_t tegra_bl31_phys_base;
+extern uint64_t __tegra186_cpu_reset_handler_end;
 
 /*******************************************************************************
  * Setup secondary CPU vectors
@@ -50,12 +54,31 @@
 void plat_secondary_setup(void)
 {
 	uint32_t addr_low, addr_high;
-	uint64_t reset_addr = (uint64_t)tegra_secure_entrypoint;
+	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	uint64_t cpu_reset_handler_base;
 
 	INFO("Setting up secondary CPU boot\n");
 
-	addr_low = (uint32_t)reset_addr | CPU_RESET_MODE_AA64;
-	addr_high = (uint32_t)((reset_addr >> 32) & 0x7ff);
+	if ((tegra_bl31_phys_base >= TEGRA_TZRAM_BASE) &&
+	    (tegra_bl31_phys_base <= (TEGRA_TZRAM_BASE + TEGRA_TZRAM_SIZE))) {
+
+		/*
+		 * The BL31 code resides in the TZSRAM which loses state
+		 * when we enter System Suspend. Copy the wakeup trampoline
+		 * code to TZDRAM to help us exit from System Suspend.
+		 */
+		cpu_reset_handler_base = params_from_bl2->tzdram_base;
+		memcpy16((void *)((uintptr_t)cpu_reset_handler_base),
+			 (void *)(uintptr_t)tegra186_cpu_reset_handler,
+			 (uintptr_t)&__tegra186_cpu_reset_handler_end -
+			 (uintptr_t)tegra186_cpu_reset_handler);
+
+	} else {
+		cpu_reset_handler_base = (uintptr_t)tegra_secure_entrypoint;
+	}
+
+	addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64;
+	addr_high = (uint32_t)((cpu_reset_handler_base >> 32) & 0x7ff);
 
 	/* write lower 32 bits first, then the upper 11 bits */
 	mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
@@ -68,5 +91,5 @@
 			addr_high);
 
 	/* update reset vector address to the CCPLEX */
-	mce_update_reset_vector(addr_low, addr_high);
+	mce_update_reset_vector();
 }
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index d6b8bc3..e848eab 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -30,18 +30,25 @@
 
 #include <arch_helpers.h>
 #include <assert.h>
+#include <bl31.h>
 #include <bl_common.h>
 #include <console.h>
 #include <context.h>
 #include <context_mgmt.h>
+#include <cortex_a57.h>
 #include <debug.h>
 #include <denver.h>
 #include <interrupt_mgmt.h>
+#include <mce.h>
 #include <platform.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 #include <tegra_private.h>
 #include <xlat_tables.h>
 
+DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, L2CTLR_EL1)
+extern uint64_t tegra_enable_l2_ecc_parity_prot;
+
 /*******************************************************************************
  * The Tegra power domain tree has a single system level power domain i.e. a
  * single root node. The first entry in the power domain descriptor specifies
@@ -65,11 +72,19 @@
 static const mmap_region_t tegra_mmap[] = {
 	MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000, /* 128KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB */
+	MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB - UART A, B*/
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000, /* 128KB - UART C, G */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000, /* 192KB - UART D, E, F */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
@@ -139,6 +154,51 @@
 	return tegra186_uart_addresses[id];
 }
 
+/* represent chip-version as concatenation of major (15:12), minor (11:8) and subrev (7:0) */
+#define TEGRA186_VER_A02P	0x1201
+
+/*******************************************************************************
+ * Handler for early platform setup
+ ******************************************************************************/
+void plat_early_platform_setup(void)
+{
+	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+	uint32_t chip_subrev, val;
+
+	/* sanity check MCE firmware compatibility */
+	mce_verify_firmware_version();
+
+	/*
+	 * Enable ECC and Parity Protection for Cortex-A57 CPUs
+	 * for Tegra A02p SKUs
+	 */
+	if (impl != DENVER_IMPL) {
+
+		/* get the major, minor and sub-version values */
+		chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) &
+			      SUBREVISION_MASK;
+
+		/* prepare chip version number */
+		val = (tegra_get_chipid_major() << 12) |
+		      (tegra_get_chipid_minor() << 8) |
+		       chip_subrev;
+
+		/* enable L2 ECC for Tegra186 A02P and beyond */
+		if (val >= TEGRA186_VER_A02P) {
+
+			val = read_l2ctlr_el1();
+			val |= L2_ECC_PARITY_PROTECTION_BIT;
+			write_l2ctlr_el1(val);
+
+			/*
+			 * Set the flag to enable ECC/Parity Protection
+			 * when we exit System Suspend or Cluster Powerdn
+			 */
+			tegra_enable_l2_ecc_parity_prot = 1;
+		}
+	}
+}
+
 /* Secure IRQs for Tegra186 */
 static const irq_sec_cfg_t tegra186_sec_irqs[] = {
 	{
@@ -168,3 +228,27 @@
 	if (sizeof(tegra186_sec_irqs) > 0)
 		tegra_fiq_handler_setup();
 }
+
+/*******************************************************************************
+ * Return pointer to the BL31 params from previous bootloader
+ ******************************************************************************/
+bl31_params_t *plat_get_bl31_params(void)
+{
+	uint32_t val;
+
+	val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO);
+
+	return (bl31_params_t *)(uintptr_t)val;
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 platform params from previous bootloader
+ ******************************************************************************/
+plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
+{
+	uint32_t val;
+
+	val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI);
+
+	return (plat_params_from_bl2_t *)(uintptr_t)val;
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
index fabab01..31e903e 100644
--- a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
@@ -64,6 +64,9 @@
 #define TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA		0x82FFFF0D
 #define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE		0x82FFFF0E
 #define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE		0x82FFFF0F
+#define TEGRA_SIP_MCE_CMD_ENABLE_LATIC			0x82FFFF10
+#define TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ		0x82FFFF11
+#define TEGRA_SIP_MCE_CMD_MISC_CCPLEX			0x82FFFF12
 
 /*******************************************************************************
  * This function is responsible for handling all T186 SiP calls
@@ -100,6 +103,9 @@
 	case TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA:
 	case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE:
 	case TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE:
+	case TEGRA_SIP_MCE_CMD_ENABLE_LATIC:
+	case TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ:
+	case TEGRA_SIP_MCE_CMD_MISC_CCPLEX:
 
 		/* clean up the high bits */
 		smc_fid &= MCE_CMD_MASK;
@@ -110,32 +116,6 @@
 
 		return 0;
 
-	case TEGRA_SIP_NEW_VIDEOMEM_REGION:
-		/* clean up the high bits */
-		x1 = (uint32_t)x1;
-		x2 = (uint32_t)x2;
-
-		/*
-		 * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
-		 * or falls outside of the valid DRAM range
-		 */
-		mce_ret = bl31_check_ns_address(x1, x2);
-		if (mce_ret)
-			return -ENOTSUP;
-
-		/*
-		 * Check if Video Memory is aligned to 1MB.
-		 */
-		if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) {
-			ERROR("Unaligned Video Memory base address!\n");
-			return -ENOTSUP;
-		}
-
-		/* new video memory carveout settings */
-		tegra_memctrl_videomem_setup(x1, x2);
-
-		return 0;
-
 	case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE:
 
 		/* clean up the high bits */
diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
new file mode 100644
index 0000000..21393d9
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common_def.h>
+#include <memctrl_v2.h>
+#include <tegra_def.h>
+
+#define TEGRA186_SMMU_CTX_SIZE		0x420
+
+	.align 4
+	.globl	tegra186_cpu_reset_handler
+
+/* CPU reset handler routine */
+func tegra186_cpu_reset_handler
+	/*
+	 * The TZRAM loses state during System Suspend. We use this
+	 * information to decide if the reset handler is running after a
+	 * System Suspend. Resume from system suspend requires restoring
+	 * the entire state from TZDRAM to TZRAM.
+	 */
+	mov	x0, #BL31_BASE
+	ldr	x0, [x0]
+	cbnz	x0, boot_cpu
+
+	/* resume from system suspend */
+	mov	x0, #BL31_BASE
+	adr	x1, __tegra186_cpu_reset_handler_end
+	adr	x2, __tegra186_cpu_reset_handler_data
+	ldr	x2, [x2, #8]
+
+	/* memcpy16 */
+m_loop16:
+	cmp	x2, #16
+	b.lt	m_loop1
+	ldp	x3, x4, [x1], #16
+	stp	x3, x4, [x0], #16
+	sub	x2, x2, #16
+	b	m_loop16
+	/* copy byte per byte */
+m_loop1:
+	cbz	x2, boot_cpu
+	ldrb	w3, [x1], #1
+	strb	w3, [x0], #1
+	subs	x2, x2, #1
+	b.ne	m_loop1
+
+boot_cpu:
+	adr	x0, __tegra186_cpu_reset_handler_data
+	ldr	x0, [x0]
+	br	x0
+endfunc tegra186_cpu_reset_handler
+
+	/*
+	 * Tegra186 reset data (offset 0x0 - 0x430)
+	 *
+	 * 0x000: secure world's entrypoint
+	 * 0x008: BL31 size (RO + RW)
+	 * 0x00C: SMMU context start
+	 * 0x42C: SMMU context end
+	 */
+
+	.align 4
+	.type	__tegra186_cpu_reset_handler_data, %object
+	.globl	__tegra186_cpu_reset_handler_data
+__tegra186_cpu_reset_handler_data:
+	.quad	tegra_secure_entrypoint
+	.quad	__BL31_END__ - BL31_BASE
+	.rept	TEGRA186_SMMU_CTX_SIZE
+	.quad	0
+	.endr
+	.size	__tegra186_cpu_reset_handler_data, \
+		. - __tegra186_cpu_reset_handler_data
+
+	.align 4
+	.globl	__tegra186_cpu_reset_handler_end
+__tegra186_cpu_reset_handler_end:
diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk
index adc4a9e..b62d47d 100644
--- a/plat/nvidia/tegra/soc/t186/platform_t186.mk
+++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk
@@ -29,8 +29,20 @@
 #
 
 # platform configs
-ENABLE_NS_L2_CPUECTRL_RW_ACCESS		:= 1
-$(eval $(call add_define,ENABLE_NS_L2_CPUECTRL_RW_ACCESS))
+ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS	:= 1
+$(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS))
+
+RELOCATE_TO_BL31_BASE			:= 1
+$(eval $(call add_define,RELOCATE_TO_BL31_BASE))
+
+ENABLE_CHIP_VERIFICATION_HARNESS	:= 0
+$(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
+
+RESET_TO_BL31				:= 1
+
+PROGRAMMABLE_RESET_ADDRESS		:= 1
+
+COLD_BOOT_SINGLE_CPU			:= 1
 
 # platform settings
 TZDRAM_BASE				:= 0x30000000
@@ -42,10 +54,10 @@
 PLATFORM_MAX_CPUS_PER_CLUSTER		:= 4
 $(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
 
-MAX_XLAT_TABLES				:= 15
+MAX_XLAT_TABLES				:= 20
 $(eval $(call add_define,MAX_XLAT_TABLES))
 
-MAX_MMAP_REGIONS			:= 15
+MAX_MMAP_REGIONS			:= 20
 $(eval $(call add_define,MAX_MMAP_REGIONS))
 
 # platform files
@@ -62,4 +74,5 @@
 				${SOC_DIR}/plat_psci_handlers.c		\
 				${SOC_DIR}/plat_setup.c			\
 				${SOC_DIR}/plat_secondary.c		\
-				${SOC_DIR}/plat_sip_calls.c
+				${SOC_DIR}/plat_sip_calls.c		\
+				${SOC_DIR}/plat_trampoline.S
diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c
index 09c5397..2d4dc99 100644
--- a/plat/rockchip/common/plat_pm.c
+++ b/plat/rockchip/common/plat_pm.c
@@ -391,15 +391,6 @@
 	rockchip_soc_system_off();
 }
 
-static void __dead2 rockchip_pd_pwr_down_wfi(
-		const psci_power_state_t *target_state)
-{
-	if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
-		rockchip_soc_sys_pd_pwr_dn_wfi();
-	else
-		rockchip_soc_cores_pd_pwr_dn_wfi(target_state);
-}
-
 /*******************************************************************************
  * Export the platform handlers via plat_rockchip_psci_pm_ops. The rockchip
  * standard
diff --git a/plat/rockchip/rk3399/drivers/dram/dfs.c b/plat/rockchip/rk3399/drivers/dram/dfs.c
index f589a8a..267398f 100644
--- a/plat/rockchip/rk3399/drivers/dram/dfs.c
+++ b/plat/rockchip/rk3399/drivers/dram/dfs.c
@@ -445,7 +445,7 @@
 	} else if (timing_config->dram_type == LPDDR3) {
 		mem_delay_ps = 5500;
 	} else {
-		printf("get_pi_tdfi_phy_rdlat:dramtype unsupport\n");
+		NOTICE("get_pi_tdfi_phy_rdlat:dramtype unsupport\n");
 		return 0;
 	}
 	round_trip_ps = 1100 + 500 + mem_delay_ps + 500 + 600;
@@ -2009,21 +2009,6 @@
 	return index;
 }
 
-void print_dram_status_info(void)
-{
-	uint32_t *p;
-	uint32_t i;
-
-	p = (uint32_t *) &rk3399_dram_status.timing_config;
-	INFO("rk3399_dram_status.timing_config:\n");
-	for (i = 0; i < sizeof(struct timing_related_config) / 4; i++)
-		tf_printf("%u\n", p[i]);
-	p = (uint32_t *) &rk3399_dram_status.drv_odt_lp_cfg;
-	INFO("rk3399_dram_status.drv_odt_lp_cfg:\n");
-	for (i = 0; i < sizeof(struct drv_odt_lp_config) / 4; i++)
-		tf_printf("%u\n", p[i]);
-}
-
 uint32_t ddr_set_rate(uint32_t hz)
 {
 	uint32_t low_power, index, ddr_index;