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)
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"
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
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;
}
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;
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;
}
.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 */
.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 */
}
#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
#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;
--- /dev/null
+/*
+ * (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
}
#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
#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
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
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)) {
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)
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)