MLK-18591-6 android: iot: Add boot Trusty OS codes for i.MX SoCs

Use trusty_os_init to load Trusty OS from CONFIG_TRUSTY_OS_ENTRY
before u-boot ready.

Add Trusty OS SOC level codes and u-boot/SPL common codes.

Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Haoran.Wang <elven.wang@nxp.com>
(cherry picked from commit 1ae9ecc73f5001b8bd743011c06a7d07861be64e)
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index aed2e3c..5c5a451 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -471,7 +471,11 @@
 	DCACHE_OFF = TTB_SECT_DOMAIN(0) | TTB_SECT_XN_MASK | TTB_SECT,
 	DCACHE_WRITETHROUGH = DCACHE_OFF | TTB_SECT_C_MASK,
 	DCACHE_WRITEBACK = DCACHE_WRITETHROUGH | TTB_SECT_B_MASK,
+#ifdef CONFIG_IMX_TRUSTY_OS
+	DCACHE_WRITEALLOC = DCACHE_WRITEBACK | TTB_SECT_TEX(1) | TTB_SECT_S_MASK,
+#else
 	DCACHE_WRITEALLOC = DCACHE_WRITEBACK | TTB_SECT_TEX(1),
+#endif
 };
 #else
 #define TTB_SECT_AP		(3 << 10)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index f5abb27..fbc95fb 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -156,3 +156,11 @@
 	  NXP does NOT recommend to perform this calibration at each boot. One
 	  shall perform it on a new PCB and then use those values to program
 	  the ddrmc_cr_setting on relevant board file.
+
+config IMX_TRUSTY_OS
+	bool "Support Trusty OS related feature"
+	depends on ARCH_MX6 || ARCH_MX7 || ARCH_IMX8 || ARCH_IMX8M
+	select SYS_ARM_CACHE_WRITEALLOC
+
+config SYS_ARM_CACHE_WRITEALLOC
+	bool "support cache write alloc"
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index bfd5e9a..6eb3e99 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -50,6 +50,7 @@
 obj-$(CONFIG_SATA) += sata.o
 obj-$(CONFIG_SECURE_BOOT)    += hab.o
 obj-$(CONFIG_SYSCOUNTER_TIMER) += syscounter.o
+obj-$(CONFIG_IMX_TRUSTY_OS) += trusty.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx7ulp))
 obj-y  += cache.o
diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c
index 9683751..e446800 100644
--- a/arch/arm/mach-imx/imx8/cpu.c
+++ b/arch/arm/mach-imx/imx8/cpu.c
@@ -1332,7 +1332,11 @@
 	     addr_start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) ||
 	    (addr_start >= PHYS_SDRAM_2 &&
 	     addr_start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)))
+#ifdef CONFIG_IMX_TRUSTY_OS
+		return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE);
+#else
 		return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE);
+#endif
 
 	return attr;
 }
diff --git a/arch/arm/mach-imx/imx8/parser.c b/arch/arm/mach-imx/imx8/parser.c
index 31129b4..1a8e3e1 100644
--- a/arch/arm/mach-imx/imx8/parser.c
+++ b/arch/arm/mach-imx/imx8/parser.c
@@ -28,6 +28,11 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if defined(CONFIG_IMX_TRUSTY_OS)
+/* Pre-declaration of check_rpmb_blob. */
+int check_rpmb_blob(struct mmc *mmc);
+#endif
+
 static int current_dev_type = MMC_DEV;
 static int start_offset;
 static void *device;
@@ -270,6 +275,16 @@
 
 	ret = read_auth_container(spl_image);
 
+	if (!ret)
+	{
+		/* Images loaded, now check the rpmb keyblob for Trusty OS.
+		 * Skip this step when the dual bootloader feature is enabled
+		 * since the blob should be checked earlier.
+		 */
+#if defined(CONFIG_IMX_TRUSTY_OS) && !defined(CONFIG_DUAL_BOOTLOADER)
+		ret = check_rpmb_blob(mmc);
+#endif
+	}
 	return ret;
 }
 
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index 3de22ff..dad6988 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -129,7 +129,11 @@
 		.phys = 0x40000000UL,
 		.size = PHYS_SDRAM_SIZE,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+#ifdef CONFIG_IMX_TRUSTY_OS
+			 PTE_BLOCK_INNER_SHARE
+#else
 			 PTE_BLOCK_OUTER_SHARE
+#endif
 #ifdef PHYS_SDRAM_2_SIZE
 	}, {
 		/* DRAM2 */
@@ -137,8 +141,12 @@
 		.phys = 0x100000000UL,
 		.size = PHYS_SDRAM_2_SIZE,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+#ifdef CONFIG_IMX_TRUSTY_OS
+			 PTE_BLOCK_INNER_SHARE
+#else
 			 PTE_BLOCK_OUTER_SHARE
 #endif
+#endif
 	}, {
 		/* List terminator */
 		0,
diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c
index ef25795..4538c61 100644
--- a/arch/arm/mach-imx/mx6/soc.c
+++ b/arch/arm/mach-imx/mx6/soc.c
@@ -233,6 +233,20 @@
 }
 #endif
 
+#ifdef CONFIG_IMX_TRUSTY_OS
+#ifdef CONFIG_MX6UL
+void smp_set_core_boot_addr(unsigned long addr, int corenr)
+{
+           return;
+}
+
+void smp_waitloop(unsigned previous_address)
+{
+           return;
+}
+#endif
+#endif
+
 static void init_csu(void)
 {
 #ifdef CONFIG_ARMV7_NONSEC
diff --git a/arch/arm/mach-imx/mx7/soc.c b/arch/arm/mach-imx/mx7/soc.c
index 705ca65..a33fed6 100644
--- a/arch/arm/mach-imx/mx7/soc.c
+++ b/arch/arm/mach-imx/mx7/soc.c
@@ -414,6 +414,20 @@
 #endif
 }
 
+#ifdef CONFIG_IMX_TRUSTY_OS
+#ifdef CONFIG_MX7D
+void smp_set_core_boot_addr(unsigned long addr, int corenr)
+{
+            return;
+}
+
+void smp_waitloop(unsigned previous_address)
+{
+            return;
+}
+#endif
+#endif
+
 void reset_cpu(ulong addr)
 {
 	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
diff --git a/arch/arm/mach-imx/trusty.S b/arch/arm/mach-imx/trusty.S
new file mode 100644
index 0000000..2ca9b3c
--- /dev/null
+++ b/arch/arm/mach-imx/trusty.S
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2009-2016 Freescale Semiconductor, Inc.
+ *
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/gic.h>
+#include <asm/armv7.h>
+_regs_save:
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+	.word 0
+
+#ifdef CONFIG_IMX_TRUSTY_OS
+ENTRY(trusty_os_init)
+	isb
+
+	/* Save current registers */
+	mov     ip, r0
+	adr     r0, _regs_save
+	str     ip, [r0]
+	add     r0, r0, #4		@ Get _regs_save from instruction offset
+
+	str     sp, [r0]
+	add     r0, r0, #4
+
+	stmia   r0!, {r1-r12}		@ Save r1 - r12
+
+	str     lr, [r0]
+	adr     lr, end_init_tee	@ save return address to lr
+
+	dsb
+
+	ldr     r1, =TRUSTY_OS_ENTRY
+	ldr     r0, =TRUSTY_OS_RAM_SIZE
+	movs    pc, r1			@ Go to TEE codes
+end_init_tee:
+	/* Restore saved registers */
+	adr     lr, _regs_save
+	ldr     r0, [lr]
+	add     lr, lr, #4
+
+	ldr     sp, [lr]
+	add     lr, lr, #4
+
+	ldmfd   lr!, {r1-r12}
+	ldr     lr, [lr]
+
+	dsb
+
+	bx      lr
+ENDPROC(trusty_os_init)
+#endif
diff --git a/common/board_r.c b/common/board_r.c
index f2ef1d3..7b1eadf 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -646,6 +646,15 @@
 }
 #endif
 
+#ifdef CONFIG_IMX_TRUSTY_OS
+extern void tee_setup(void);
+static int initr_tee_setup(void)
+{
+	tee_setup();
+	return 0;
+}
+#endif
+
 static int run_main_loop(void)
 {
 #ifdef CONFIG_SANDBOX
@@ -855,6 +864,9 @@
 #if defined(AVB_RPMB) && !defined(CONFIG_SPL)
 	initr_avbkey,
 #endif
+#ifdef CONFIG_IMX_TRUSTY_OS
+	initr_tee_setup,
+#endif
 #ifdef CONFIG_FSL_FASTBOOT
 	initr_check_fastboot,
 #endif
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index c9bfe0c..6f53400 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -150,6 +150,15 @@
 	return (data_size + info->bl_len - 1) / info->bl_len;
 }
 
+#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_IMX_TRUSTY_OS)
+__weak int get_tee_load(ulong *load)
+{
+	/* default return ok */
+	return 0;
+}
+
+#endif
+
 /**
  * spl_load_fit_image(): load the image described in a certain FIT node
  * @info:	points to information about the device to load data from
@@ -202,6 +211,21 @@
 	if (fit_image_get_load(fit, node, &load_addr))
 		load_addr = image_info->load_addr;
 
+#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_IMX_TRUSTY_OS)
+	char *desc = NULL;
+
+	if (fit_get_desc(fit, node, &desc)) {
+		printf("can't found node description!\n");
+		return -ENOENT;
+	} else if (!strncmp(desc, "TEE firmware",
+				strlen("TEE firmware"))) {
+		if (get_tee_load(&load_addr)) {
+			printf("Failed to get TEE load address!\n");
+			return -ENOENT;
+		}
+	}
+#endif
+
 	if (!fit_image_get_data_position(fit, node, &offset)) {
 		external_data = true;
 	} else if (!fit_image_get_data_offset(fit, node, &offset)) {
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index a7eedff..3e3c43b 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -49,6 +49,11 @@
 	return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
 }
 
+#if defined(CONFIG_IMX_TRUSTY_OS) && !defined(CONFIG_AVB_ATX)
+/* Pre-declaration of check_rpmb_blob. */
+int check_rpmb_blob(struct mmc *mmc);
+#endif
+
 static __maybe_unused
 int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
 			      struct mmc *mmc, unsigned long sector)
@@ -91,7 +96,11 @@
 		return -1;
 	}
 
-	return 0;
+	/* Images loaded, now check the rpmb keyblob for Trusty OS. */
+#if defined(CONFIG_IMX_TRUSTY_OS) && !defined(CONFIG_AVB_ATX)
+	ret = check_rpmb_blob(mmc);
+#endif
+	return ret;
 }
 
 static int spl_mmc_get_device_index(u32 boot_device)