diff options
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/config.mk | 1 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/cache_v7.c | 48 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/config_secure.mk | 75 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/emif-common.c | 3 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/hwinit-common.c | 3 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/lowlevel_init.S | 45 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/sec-common.c | 139 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap5/config.mk | 3 |
9 files changed, 255 insertions, 64 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/config.mk b/arch/arm/cpu/armv7/am33xx/config.mk index 6d95d327b4..ab9470820d 100644 --- a/arch/arm/cpu/armv7/am33xx/config.mk +++ b/arch/arm/cpu/armv7/am33xx/config.mk @@ -26,6 +26,7 @@ endif else ifeq ($(CONFIG_TI_SECURE_DEVICE),y) ALL-$(CONFIG_QSPI_BOOT) += u-boot_HS_XIP_X-LOADER +ALL-y += u-boot_HS.img endif ALL-y += u-boot.img endif diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index dc309dac90..52f18565db 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -19,23 +19,6 @@ void v7_flush_dcache_all(void); void v7_invalidate_dcache_all(void); -static int check_cache_range(unsigned long start, unsigned long stop) -{ - int ok = 1; - - if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) - ok = 0; - - if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) - ok = 0; - - if (!ok) - debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n", - start, stop); - - return ok; -} - static u32 get_ccsidr(void) { u32 ccsidr; @@ -61,27 +44,8 @@ static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len) { u32 mva; - /* - * If start address is not aligned to cache-line do not - * invalidate the first cache-line - */ - if (start & (line_len - 1)) { - printf("ERROR: %s - start address is not aligned - 0x%08x\n", - __func__, start); - /* move to next cache line */ - start = (start + line_len - 1) & ~(line_len - 1); - } - - /* - * If stop address is not aligned to cache-line do not - * invalidate the last cache-line - */ - if (stop & (line_len - 1)) { - printf("ERROR: %s - stop address is not aligned - 0x%08x\n", - __func__, stop); - /* align to the beginning of this cache line */ - stop &= ~(line_len - 1); - } + if (!check_cache_range(start, stop)) + return; for (mva = start; mva < stop; mva = mva + line_len) { /* DCIMVAC - Invalidate data cache by MVA to PoC */ @@ -195,6 +159,14 @@ void flush_dcache_all(void) { } +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +} + void arm_init_before_mmu(void) { } diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 87a7ac03f9..3172bae105 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -36,3 +36,5 @@ obj-y += boot-common.o obj-y += lowlevel_init.o obj-y += mem-common.o + +obj-$(CONFIG_TI_SECURE_DEVICE) += sec-common.o diff --git a/arch/arm/cpu/armv7/omap-common/config_secure.mk b/arch/arm/cpu/armv7/omap-common/config_secure.mk index c7bb101be8..1122439e38 100644 --- a/arch/arm/cpu/armv7/omap-common/config_secure.mk +++ b/arch/arm/cpu/armv7/omap-common/config_secure.mk @@ -12,8 +12,8 @@ cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \ $(if $(KBUILD_VERBOSE:1=), >/dev/null) else cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \ - $(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \ - $(if $(KBUILD_VERBOSE:1=), >/dev/null) + $(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \ + $(if $(KBUILD_VERBOSE:1=), >/dev/null) endif else cmd_mkomapsecimg = echo "WARNING:" \ @@ -25,14 +25,33 @@ cmd_mkomapsecimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \ "variable must be defined for TI secure devices. $@ was NOT created!" endif +ifdef CONFIG_SPL_LOAD_FIT +quiet_cmd_omapsecureimg = SECURE $@ +ifneq ($(TI_SECURE_DEV_PKG),) +ifneq ($(wildcard $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh),) +cmd_omapsecureimg = $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh \ + $< $@ \ + $(if $(KBUILD_VERBOSE:1=), >/dev/null) +else +cmd_omapsecureimg = echo "WARNING:" \ + "$(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh not found." \ + "$@ was NOT created!"; cp $< $@ +endif +else +cmd_omapsecureimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \ + "variable must be defined for TI secure devices." \ + "$@ was NOT created!"; cp $< $@ +endif +endif + + # Standard X-LOADER target (QPSI, NOR flash) u-boot-spl_HS_X-LOADER: $(obj)/u-boot-spl.bin $(call if_changed,mkomapsecimg) -# For MLO targets (SD card boot) the final file name -# that is copied to the SD card fAT partition must -# be MLO, so we make a copy of the output file to a -# new file with that name +# For MLO targets (SD card boot) the final file name that is copied to the SD +# card FAT partition must be MLO, so we make a copy of the output file to a new +# file with that name u-boot-spl_HS_MLO: $(obj)/u-boot-spl.bin $(call if_changed,mkomapsecimg) @if [ -f $@ ]; then \ @@ -51,16 +70,44 @@ u-boot-spl_HS_ULO: $(obj)/u-boot-spl.bin u-boot-spl_HS_ISSW: $(obj)/u-boot-spl.bin $(call if_changed,mkomapsecimg) -# For SPI flash on AM335x and AM43xx, these -# require special byte swap handling so we use -# the SPI_X-LOADER target instead of X-LOADER -# and let the create-boot-image.sh script handle -# that +# For SPI flash on AM335x and AM43xx, these require special byte swap handling +# so we use the SPI_X-LOADER target instead of X-LOADER and let the +# create-boot-image.sh script handle that u-boot-spl_HS_SPI_X-LOADER: $(obj)/u-boot-spl.bin $(call if_changed,mkomapsecimg) -# For supporting single stage XiP QSPI on AM43xx, the -# image is a full u-boot file, not an SPL. In this case -# the mkomapsecimg command looks for a u-boot-HS_* prefix +# For supporting single stage XiP QSPI on AM43xx, the image is a full u-boot +# file, not an SPL. In this case the mkomapsecimg command looks for a +# u-boot-HS_* prefix u-boot_HS_XIP_X-LOADER: $(obj)/u-boot.bin $(call if_changed,mkomapsecimg) + +# For supporting the SPL loading and interpreting of FIT images whose +# components are pre-processed before being integrated into the FIT image in +# order to secure them in some way +ifdef CONFIG_SPL_LOAD_FIT + +MKIMAGEFLAGS_u-boot_HS.img = -f auto -A $(ARCH) -T firmware -C none -O u-boot \ + -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \ + -n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" -E \ + $(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) + +OF_LIST_TARGETS = $(patsubst %,arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) +$(OF_LIST_TARGETS): dtbs + +%_HS.dtb: %.dtb + $(call if_changed,omapsecureimg) + $(Q)if [ -f $@ ]; then \ + cp -f $@ $<; \ + fi + +u-boot-nodtb_HS.bin: u-boot-nodtb.bin + $(call if_changed,omapsecureimg) + +u-boot_HS.img: u-boot-nodtb_HS.bin u-boot.img $(patsubst %.dtb,%_HS.dtb,$(OF_LIST_TARGETS)) + $(call if_changed,mkimage) + $(Q)if [ -f $@ ]; then \ + cp -f $@ u-boot.img; \ + fi + +endif diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 9a9c764b4d..2b790105b0 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -37,7 +37,8 @@ void set_lpmode_selfrefresh(u32 base) void force_emif_self_refresh() { set_lpmode_selfrefresh(EMIF1_BASE); - set_lpmode_selfrefresh(EMIF2_BASE); + if (!is_dra72x()) + set_lpmode_selfrefresh(EMIF2_BASE); } inline u32 emif_num(u32 base) diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 2f9693f28e..f317293988 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -147,8 +147,7 @@ void early_system_init(void) hw_data_init(); #ifdef CONFIG_SPL_BUILD - if (warm_reset() && - (is_omap44xx() || (omap_revision() == OMAP5430_ES1_0))) + if (warm_reset()) force_emif_self_refresh(); #endif watchdog_init(); diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S index 528313584f..66a3b3d26c 100644 --- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S @@ -16,9 +16,10 @@ #include <asm/arch/spl.h> #include <linux/linkage.h> +.arch_extension sec + #ifdef CONFIG_SPL ENTRY(save_boot_params) - ldr r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS str r0, [r1] b save_boot_params_ret @@ -26,14 +27,40 @@ ENDPROC(save_boot_params) #endif ENTRY(omap_smc1) - PUSH {r4-r12, lr} @ save registers - ROM code may pollute + push {r4-r12, lr} @ save registers - ROM code may pollute @ our registers - MOV r12, r0 @ Service - MOV r0, r1 @ Argument - DSB - DMB - .word 0xe1600070 @ SMC #0 - hand assembled for GCC versions - @ call ROM Code API for the service requested + mov r12, r0 @ Service + mov r0, r1 @ Argument - POP {r4-r12, pc} + dsb + dmb + smc 0 @ SMC #0 to enter monitor mode + @ call ROM Code API for the service requested + pop {r4-r12, pc} ENDPROC(omap_smc1) + +ENTRY(omap_smc_sec) + push {r4-r12, lr} @ save registers - ROM code may pollute + @ our registers + mov r6, #0xFF @ Indicate new Task call + mov r12, #0x00 @ Secure Service ID in R12 + + dsb + dmb + smc 0 @ SMC #0 to enter monitor mode + + b omap_smc_sec_end @ exit at end of the service execution + nop + + @ In case of IRQ happening in Secure, then ARM will branch here. + @ At that moment, IRQ will be pending and ARM will jump to Non Secure + @ IRQ handler + mov r12, #0xFE + + dsb + dmb + smc 0 @ SMC #0 to enter monitor mode + +omap_smc_sec_end: + pop {r4-r12, pc} +ENDPROC(omap_smc_sec) diff --git a/arch/arm/cpu/armv7/omap-common/sec-common.c b/arch/arm/cpu/armv7/omap-common/sec-common.c new file mode 100644 index 0000000000..246a2393da --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/sec-common.c @@ -0,0 +1,139 @@ +/* + * + * Common security related functions for OMAP devices + * + * (C) Copyright 2016 + * Texas Instruments, <www.ti.com> + * + * Daniel Allred <d-allred@ti.com> + * Andreas Dannenberg <dannenberg@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <stdarg.h> + +#include <asm/arch/sys_proto.h> +#include <asm/omap_common.h> +#include <asm/omap_sec_common.h> +#include <asm/spl.h> +#include <spl.h> + +/* Index for signature verify ROM API */ +#define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX (0x0000000E) + +static uint32_t secure_rom_call_args[5] __aligned(ARCH_DMA_MINALIGN); + +u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...) +{ + int i; + u32 num_args; + va_list ap; + + va_start(ap, flag); + + num_args = va_arg(ap, u32); + + if (num_args > 4) + return 1; + + /* Copy args to aligned args structure */ + for (i = 0; i < num_args; i++) + secure_rom_call_args[i + 1] = va_arg(ap, u32); + + secure_rom_call_args[0] = num_args; + + va_end(ap); + + /* if data cache is enabled, flush the aligned args structure */ + flush_dcache_range( + (unsigned int)&secure_rom_call_args[0], + (unsigned int)&secure_rom_call_args[0] + + roundup(sizeof(secure_rom_call_args), ARCH_DMA_MINALIGN)); + + return omap_smc_sec(service, proc_id, flag, secure_rom_call_args); +} + +static u32 find_sig_start(char *image, size_t size) +{ + char *image_end = image + size; + char *sig_start_magic = "CERT_"; + int magic_str_len = strlen(sig_start_magic); + char *ch; + + while (--image_end > image) { + if (*image_end == '_') { + ch = image_end - magic_str_len + 1; + if (!strncmp(ch, sig_start_magic, magic_str_len)) + return (u32)ch; + } + } + return 0; +} + +int secure_boot_verify_image(void **image, size_t *size) +{ + int result = 1; + u32 cert_addr, sig_addr; + size_t cert_size; + + /* Perform cache writeback on input buffer */ + flush_dcache_range( + (u32)*image, + (u32)*image + roundup(*size, ARCH_DMA_MINALIGN)); + + cert_addr = (uint32_t)*image; + sig_addr = find_sig_start((char *)*image, *size); + + if (sig_addr == 0) { + printf("No signature found in image!\n"); + result = 1; + goto auth_exit; + } + + *size = sig_addr - cert_addr; /* Subtract out the signature size */ + cert_size = *size; + + /* Check if image load address is 32-bit aligned */ + if (!IS_ALIGNED(cert_addr, 4)) { + printf("Image is not 4-byte aligned!\n"); + result = 1; + goto auth_exit; + } + + /* Image size also should be multiple of 4 */ + if (!IS_ALIGNED(cert_size, 4)) { + printf("Image size is not 4-byte aligned!\n"); + result = 1; + goto auth_exit; + } + + /* Call ROM HAL API to verify certificate signature */ + debug("%s: load_addr = %x, size = %x, sig_addr = %x\n", __func__, + cert_addr, cert_size, sig_addr); + + result = secure_rom_call( + API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX, 0, 0, + 4, cert_addr, cert_size, sig_addr, 0xFFFFFFFF); +auth_exit: + if (result != 0) { + printf("Authentication failed!\n"); + printf("Return Value = %08X\n", result); + hang(); + } + + /* + * Output notification of successful authentication as well the name of + * the signing certificate used to re-assure the user that the secure + * code is being processed as expected. However suppress any such log + * output in case of building for SPL and booting via YMODEM. This is + * done to avoid disturbing the YMODEM serial protocol transactions. + */ + if (!(IS_ENABLED(CONFIG_SPL_BUILD) && + IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) && + spl_boot_device() == BOOT_DEVICE_UART)) + printf("Authentication passed: %s\n", (char *)sig_addr); + + return result; +} diff --git a/arch/arm/cpu/armv7/omap5/config.mk b/arch/arm/cpu/armv7/omap5/config.mk index a7e55a5e24..d245572ef0 100644 --- a/arch/arm/cpu/armv7/omap5/config.mk +++ b/arch/arm/cpu/armv7/omap5/config.mk @@ -15,5 +15,8 @@ else ALL-y += MLO endif else +ifeq ($(CONFIG_TI_SECURE_DEVICE),y) +ALL-y += u-boot_HS.img +endif ALL-y += u-boot.img endif |