From e1588a2741dfd0f37421e13ceb5e310e0b35d3bf Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 5 Jun 2018 03:30:37 -0700 Subject: [PATCH] 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 Signed-off-by: Haoran.Wang (cherry picked from commit 1ae9ecc73f5001b8bd743011c06a7d07861be64e) (cherry picked from commit 6fa4f4a42fd90631f8dc8303b17f600c085d8595) (cherry picked from commit d5046e6f021f3d55c58e8b46b13ac3e8e1761755) --- arch/arm/include/asm/system.h | 4 ++ arch/arm/mach-imx/Kconfig | 5 +++ arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/imx8/cpu.c | 4 ++ arch/arm/mach-imx/imx8m/soc.c | 8 ++++ arch/arm/mach-imx/mx6/soc.c | 14 +++++++ arch/arm/mach-imx/mx7/soc.c | 14 +++++++ arch/arm/mach-imx/trusty.S | 69 +++++++++++++++++++++++++++++++++++ common/board_r.c | 12 ++++++ common/spl/spl_fit.c | 24 ++++++++++++ common/spl/spl_mmc.c | 25 ++++++++++++- 11 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-imx/trusty.S diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 5fe83699f4..a7a3b1950a 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -491,7 +491,11 @@ enum dcache_option { 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 af6ef6eb81..33ee63ba92 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -178,3 +178,8 @@ config IMX_DCD_ADDR the ROM code to configure the device at early boot stage, is located. This information is shared with the user via mkimage -l just so the image can be signed. + +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 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index baa3eeda17..a7a28953ab 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -52,6 +52,7 @@ endif obj-$(CONFIG_SATA) += sata.o obj-$(CONFIG_IMX_HAB) += 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 mmdc_size.o diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 2a6e827fe5..bc4835360d 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -449,7 +449,11 @@ static u64 get_block_attrs(sc_faddr_t addr_start) addr_start <= ((sc_faddr_t)phys_sdram_1_start + phys_sdram_1_size)) || (addr_start >= phys_sdram_2_start && addr_start <= ((sc_faddr_t)phys_sdram_2_start + 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/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 4b6715c081..c821c988e9 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -137,7 +137,11 @@ static struct mm_region imx8m_mem_map[] = { .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 */ @@ -145,7 +149,11 @@ static struct mm_region imx8m_mem_map[] = { .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 }, { /* empty entrie to split table entry 5 if needed when TEEs are used */ diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c index c0b2ece31e..6679d5a63a 100644 --- a/arch/arm/mach-imx/mx6/soc.c +++ b/arch/arm/mach-imx/mx6/soc.c @@ -240,6 +240,20 @@ u32 __weak get_board_rev(void) } #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 3e00de6abd..378ee2b584 100644 --- a/arch/arm/mach-imx/mx7/soc.c +++ b/arch/arm/mach-imx/mx7/soc.c @@ -475,6 +475,20 @@ void reset_misc(void) #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 0000000000..2ca9b3c83a --- /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 +#include +#include +#include +_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 904cc999e2..02ece4b67e 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -603,6 +603,15 @@ static int initr_check_fastboot(void) } #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 @@ -829,6 +838,9 @@ static init_fnc_t init_sequence_r[] = { #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 75c8ff065b..acd8984b2e 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -213,6 +213,15 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size, 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 @@ -261,6 +270,21 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector, 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 add2785b4e..96e543c376 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -61,6 +61,11 @@ static __maybe_unused unsigned long spl_mmc_raw_uboot_offset(int part) return 0; } +#if defined(CONFIG_IMX_TRUSTY_OS) +/* 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) @@ -113,7 +118,23 @@ end: return -1; } - return 0; + /* 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) + if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) { +#if !defined(CONFIG_DUAL_BOOTLOADER) + ret = check_rpmb_blob(mmc); +#endif + } else { +#if !defined(CONFIG_AVB_ATX) + ret = check_rpmb_blob(mmc); +#endif + } +#endif + + return ret; } static int spl_mmc_get_device_index(u32 boot_device) @@ -180,7 +201,7 @@ static int mmc_load_image_raw_partition(struct spl_image_info *spl_image, err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info); if (err) continue; - if (info.sys_ind == + if (info.sys_ind == CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE) { partition = type_part; break; -- 2.17.1