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)