]> git.sur5r.net Git - u-boot/commitdiff
Merge git://git.denx.de/u-boot-dm
authorTom Rini <trini@konsulko.com>
Fri, 15 Jul 2016 12:06:22 +0000 (08:06 -0400)
committerTom Rini <trini@konsulko.com>
Fri, 15 Jul 2016 12:06:22 +0000 (08:06 -0400)
85 files changed:
Kconfig
Makefile
arch/Kconfig
arch/arm/cpu/arm11/cpu.c
arch/arm/cpu/arm926ejs/cache.c
arch/arm/cpu/armv7/am33xx/config.mk
arch/arm/cpu/armv7/cache_v7.c
arch/arm/cpu/armv7/omap-common/Makefile
arch/arm/cpu/armv7/omap-common/config_secure.mk
arch/arm/cpu/armv7/omap-common/emif-common.c
arch/arm/cpu/armv7/omap-common/hwinit-common.c
arch/arm/cpu/armv7/omap-common/lowlevel_init.S
arch/arm/cpu/armv7/omap-common/sec-common.c [new file with mode: 0644]
arch/arm/cpu/armv7/omap5/config.mk
arch/arm/cpu/armv7m/config.mk
arch/arm/cpu/armv8/Kconfig
arch/arm/cpu/armv8/Makefile
arch/arm/cpu/armv8/spin_table.c [new file with mode: 0644]
arch/arm/cpu/armv8/spin_table_v8.S [new file with mode: 0644]
arch/arm/cpu/armv8/start.S
arch/arm/include/asm/arch-stm32f7/fmc.h [new file with mode: 0644]
arch/arm/include/asm/arch-stm32f7/stm32.h
arch/arm/include/asm/arch-stm32f7/stm32_periph.h
arch/arm/include/asm/armv7m.h
arch/arm/include/asm/cache.h
arch/arm/include/asm/io.h
arch/arm/include/asm/omap_common.h
arch/arm/include/asm/omap_sec_common.h [new file with mode: 0644]
arch/arm/include/asm/spin_table.h [new file with mode: 0644]
arch/arm/include/asm/types.h
arch/arm/lib/bootm-fdt.c
arch/arm/lib/cache.c
arch/arm/mach-stm32/stm32f7/Makefile
arch/arm/mach-stm32/stm32f7/clock.c
arch/arm/mach-stm32/stm32f7/soc.c [new file with mode: 0644]
arch/nds32/include/asm/io.h
arch/sandbox/lib/bootm.c
arch/sh/include/asm/io.h
board/st/stm32f746-disco/stm32f746-disco.c
board/ti/am43xx/board.c
board/ti/am57xx/board.c
board/ti/dra7xx/evm.c
common/board_f.c
common/bootm.c
common/bootm_os.c
common/image.c
common/spl/spl_fit.c
configs/am43xx_hs_evm_defconfig
configs/am57xx_hs_evm_defconfig
configs/da850evm_defconfig
configs/dra7xx_hs_evm_defconfig
doc/README.ti-secure
drivers/rtc/date.c
drivers/serial/serial_stm32x7.c
include/common.h
include/configs/dragonboard410c.h
include/configs/stm32f746-disco.h
include/image.h
include/linux/io.h
include/linux/types.h
test/README [new file with mode: 0644]
test/py/conftest.py
test/py/multiplexed_log.py
test/py/tests/test_vboot.py [new file with mode: 0644]
test/py/tests/vboot/sandbox-kernel.dts [new file with mode: 0644]
test/py/tests/vboot/sandbox-u-boot.dts [new file with mode: 0644]
test/py/tests/vboot/sign-configs-sha1.its [new file with mode: 0644]
test/py/tests/vboot/sign-configs-sha256.its [new file with mode: 0644]
test/py/tests/vboot/sign-images-sha1.its [new file with mode: 0644]
test/py/tests/vboot/sign-images-sha256.its [new file with mode: 0644]
test/py/u_boot_console_base.py
test/py/u_boot_console_sandbox.py
test/py/u_boot_utils.py
test/run [new file with mode: 0755]
test/vboot/.gitignore [deleted file]
test/vboot/sandbox-kernel.dts [deleted file]
test/vboot/sandbox-u-boot.dts [deleted file]
test/vboot/sign-configs-sha1.its [deleted file]
test/vboot/sign-configs-sha256.its [deleted file]
test/vboot/sign-images-sha1.its [deleted file]
test/vboot/sign-images-sha256.its [deleted file]
test/vboot/vboot_test.sh [deleted file]
tools/fit_image.c
tools/image-host.c
tools/mkimage.c

diff --git a/Kconfig b/Kconfig
index 3ceff250321e2d3c50575939f100317369247d49..ef12f9fbee403c2e9786764f64ff2070f6e336cb 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -114,6 +114,15 @@ if EXPERT
          Warning:
          When disabling this, please check if malloc calls, maybe
          should be replaced by calloc - if one expects zeroed memory.
+
+config TOOLS_DEBUG
+       bool "Enable debug information for tools"
+       help
+         Enable generation of debug information for tools such as mkimage.
+         This can be used for debugging purposes. With debug information
+         it is possible to set breakpoints on particular lines, single-step
+         debug through the source code, etc.
+
 endif
 endmenu                # General setup
 
@@ -313,6 +322,20 @@ config SPL_LOAD_FIT
          particular it can handle selecting from multiple device tree
          and passing the correct one to U-Boot.
 
+config SPL_FIT_IMAGE_POST_PROCESS
+       bool "Enable post-processing of FIT artifacts after loading by the SPL"
+       depends on SPL_LOAD_FIT && TI_SECURE_DEVICE
+       help
+         Allows doing any sort of manipulation to blobs after they got extracted
+         from the U-Boot FIT image like stripping off headers or modifying the
+         size of the blob, verification, authentication, decryption etc. in a
+         platform or board specific way. In order to use this feature a platform
+         or board-specific implementation of board_fit_image_post_process() must
+         be provided. Also, anything done during this post-processing step would
+         need to be comprehended in how the images were prepared before being
+         injected into the FIT creation (i.e. the blobs would have been pre-
+         processed before being added to the FIT image).
+
 config SYS_CLK_FREQ
        depends on ARC || ARCH_SUNXI
        int "CPU clock frequency"
index 84bb620a19f63631feb5a007f3fe963ca58d0012..7ce933c72a198fd05a7def6bd5d478b6c741d507 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -256,7 +256,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
 
 HOSTCC       = cc
 HOSTCXX      = c++
-HOSTCFLAGS   = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+HOSTCFLAGS   = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer \
+               $(if $(CONFIG_TOOLS_DEBUG),-g)
 HOSTCXXFLAGS = -O2
 
 ifeq ($(HOSTOS),cygwin)
index c43787c63962af2c9b2d9d8ab381de2a67a8e2cb..92d4b97701bf6b160e99f2214328fac1046c47e8 100644 (file)
@@ -1,6 +1,9 @@
 config CREATE_ARCH_SYMLINK
        bool
 
+config HAVE_ARCH_IOREMAP
+       bool
+
 choice
        prompt "Architecture select"
        default SANDBOX
@@ -33,6 +36,7 @@ config MICROBLAZE
 
 config MIPS
        bool "MIPS architecture"
+       select HAVE_ARCH_IOREMAP
        select HAVE_PRIVATE_LIBGCC
        select SUPPORT_OF_CONTROL
 
index 1e4c2142b1317cea432c950af40486b35876fe53..7244c2e7d79e6e6dd34b3009d10b4dc10db4b07b 100644 (file)
@@ -69,23 +69,6 @@ void flush_dcache_all(void)
        asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
 }
 
-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;
-}
-
 void invalidate_dcache_range(unsigned long start, unsigned long stop)
 {
        if (!check_cache_range(start, stop))
index 2839c863e82c790f2345332f8b7eb23033d96bab..2119382ab2451583a0399672e0bf914389d8743c 100644 (file)
@@ -29,23 +29,6 @@ void flush_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;
-}
-
 void invalidate_dcache_range(unsigned long start, unsigned long stop)
 {
        if (!check_cache_range(start, stop))
index 6d95d327b45b525b5bbc43bb8e232a9a2acf0be4..ab9470820d521ee854b28dc06fe30c59da1fb96e 100644 (file)
@@ -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
index dc309dac909a1aefeb8490da03db23cab0dff8d9..52f18565db2726844a075b82e15b60a8978c16f7 100644 (file)
 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)
 {
 }
index 87a7ac03f92021f50bd9252e6d087820c1cbc6b4..3172bae105bb120b79d33b900b3a9e09ea89e2b5 100644 (file)
@@ -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
index c7bb101be8e96fd966101cfa7bf3a03884ca74b8..1122439e38b34a4b3ec70293cf357907b9652cdd 100644 (file)
@@ -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
index 9a9c764b4d11319d1743256b1ac1eee3bee838b1..2b790105b0bb51036a6e38d849121342b0e65e63 100644 (file)
@@ -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)
index 2f9693f28e9ded3d6c26dfde701ea20f9f33512d..f3172939889296dec5c5ec797058505c60372ed1 100644 (file)
@@ -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();
index 528313584f3dd07e28dda860a2dc6d7404c7f074..66a3b3d26c950a48f29e19cab4681eff98f9e766 100644 (file)
 #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 (file)
index 0000000..246a239
--- /dev/null
@@ -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;
+}
index a7e55a5e2449e0c9d6e4cbb158cf0dc186c1a57b..d245572ef04344113bc9a910e3586828d235e167 100644 (file)
@@ -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
index 4a53006b6a77f711829b1c12bdcde5b02fee2ea3..db4660e15dae0b0dabc97bc5d0d17b69aec99f57 100644 (file)
@@ -5,4 +5,4 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-PLATFORM_CPPFLAGS += -march=armv7-m -mthumb
+PLATFORM_CPPFLAGS += -march=armv7-m -mthumb -mno-unaligned-access
index 3d19bbfbe24124df6f3a7680f9b0a5d5adc6050b..acf2460ede2509f17bbd246072a09e6e8826aa14 100644 (file)
@@ -3,4 +3,22 @@ if ARM64
 config ARMV8_MULTIENTRY
         boolean "Enable multiple CPUs to enter into U-Boot"
 
+config ARMV8_SPIN_TABLE
+       bool "Support spin-table enable method"
+       depends on ARMV8_MULTIENTRY && OF_LIBFDT
+       help
+         Say Y here to support "spin-table" enable method for booting Linux.
+
+         To use this feature, you must do:
+           - Specify enable-method = "spin-table" in each CPU node in the
+             Device Tree you are using to boot the kernel
+           - Let secondary CPUs in U-Boot (in a board specific manner)
+             before the master CPU jumps to the kernel
+
+         U-Boot automatically does:
+           - Set "cpu-release-addr" property of each CPU node
+             (overwrites it if already exists).
+           - Reserve the code for the spin-table and the release address
+             via a /memreserve/ region in the Device Tree.
+
 endif
index bf8644ccd2e70b6b066af38df530ed3342098c7d..f6eb9f4a7fb4be2cd51d4bf08b5f6c65adf78868 100644 (file)
@@ -15,6 +15,9 @@ obj-y += cache.o
 obj-y  += tlb.o
 obj-y  += transition.o
 obj-y  += fwcall.o
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o
+endif
 
 obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/
 obj-$(CONFIG_S32V234) += s32v234/
diff --git a/arch/arm/cpu/armv8/spin_table.c b/arch/arm/cpu/armv8/spin_table.c
new file mode 100644 (file)
index 0000000..ec1c9b8
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <asm/spin_table.h>
+
+int spin_table_update_dt(void *fdt)
+{
+       int cpus_offset, offset;
+       const char *prop;
+       int ret;
+       unsigned long rsv_addr = (unsigned long)&spin_table_reserve_begin;
+       unsigned long rsv_size = &spin_table_reserve_end -
+                                               &spin_table_reserve_begin;
+
+       cpus_offset = fdt_path_offset(fdt, "/cpus");
+       if (cpus_offset < 0)
+               return -ENODEV;
+
+       for (offset = fdt_first_subnode(fdt, cpus_offset);
+            offset >= 0;
+            offset = fdt_next_subnode(fdt, offset)) {
+               prop = fdt_getprop(fdt, offset, "device_type", NULL);
+               if (!prop || strcmp(prop, "cpu"))
+                       continue;
+
+               /*
+                * In the first loop, we check if every CPU node specifies
+                * spin-table.  Otherwise, just return successfully to not
+                * disturb other methods, like psci.
+                */
+               prop = fdt_getprop(fdt, offset, "enable-method", NULL);
+               if (!prop || strcmp(prop, "spin-table"))
+                       return 0;
+       }
+
+       for (offset = fdt_first_subnode(fdt, cpus_offset);
+            offset >= 0;
+            offset = fdt_next_subnode(fdt, offset)) {
+               prop = fdt_getprop(fdt, offset, "device_type", NULL);
+               if (!prop || strcmp(prop, "cpu"))
+                       continue;
+
+               ret = fdt_setprop_u64(fdt, offset, "cpu-release-addr",
+                               (unsigned long)&spin_table_cpu_release_addr);
+               if (ret)
+                       return -ENOSPC;
+       }
+
+       ret = fdt_add_mem_rsv(fdt, rsv_addr, rsv_size);
+       if (ret)
+               return -ENOSPC;
+
+       printf("   Reserved memory region for spin-table: addr=%lx size=%lx\n",
+              rsv_addr, rsv_size);
+
+       return 0;
+}
diff --git a/arch/arm/cpu/armv8/spin_table_v8.S b/arch/arm/cpu/armv8/spin_table_v8.S
new file mode 100644 (file)
index 0000000..d7f78a6
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(spin_table_secondary_jump)
+.globl spin_table_reserve_begin
+spin_table_reserve_begin:
+0:     wfe
+       ldr     x0, spin_table_cpu_release_addr
+       cbz     x0, 0b
+       br      x0
+.globl spin_table_cpu_release_addr
+       .align  3
+spin_table_cpu_release_addr:
+       .quad   0
+.globl spin_table_reserve_end
+spin_table_reserve_end:
+ENDPROC(spin_table_secondary_jump)
index 670e323b61b37bc56bce5972fb80f13541263f94..67edf94520c5fb2214eadaf036ae38fb1942cab8 100644 (file)
@@ -94,7 +94,11 @@ reset:
        /* Processor specific initialization */
        bl      lowlevel_init
 
-#ifdef CONFIG_ARMV8_MULTIENTRY
+#if CONFIG_IS_ENABLED(ARMV8_SPIN_TABLE)
+       branch_if_master x0, x1, master_cpu
+       b       spin_table_secondary_jump
+       /* never return */
+#elif defined(CONFIG_ARMV8_MULTIENTRY)
        branch_if_master x0, x1, master_cpu
 
        /*
@@ -106,10 +110,8 @@ slave_cpu:
        ldr     x0, [x1]
        cbz     x0, slave_cpu
        br      x0                      /* branch to the given address */
-master_cpu:
-       /* On the master CPU */
 #endif /* CONFIG_ARMV8_MULTIENTRY */
-
+master_cpu:
        bl      _main
 
 #ifdef CONFIG_SYS_RESET_SCTRL
diff --git a/arch/arm/include/asm/arch-stm32f7/fmc.h b/arch/arm/include/asm/arch-stm32f7/fmc.h
new file mode 100644 (file)
index 0000000..7dd5077
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * (C) Copyright 2013
+ * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com
+ *
+ * (C) Copyright 2015
+ * Kamil Lulko, <kamil.lulko@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _MACH_FMC_H_
+#define _MACH_FMC_H_
+
+struct stm32_fmc_regs {
+       u32 sdcr1;      /* Control register 1 */
+       u32 sdcr2;      /* Control register 2 */
+       u32 sdtr1;      /* Timing register 1 */
+       u32 sdtr2;      /* Timing register 2 */
+       u32 sdcmr;      /* Mode register */
+       u32 sdrtr;      /* Refresh timing register */
+       u32 sdsr;       /* Status register */
+};
+
+/*
+ * FMC registers base
+ */
+#define STM32_SDRAM_FMC_BASE   0xA0000140
+#define STM32_SDRAM_FMC                ((struct stm32_fmc_regs *)STM32_SDRAM_FMC_BASE)
+
+/* Control register SDCR */
+#define FMC_SDCR_RPIPE_SHIFT   13      /* RPIPE bit shift */
+#define FMC_SDCR_RBURST_SHIFT  12      /* RBURST bit shift */
+#define FMC_SDCR_SDCLK_SHIFT   10      /* SDRAM clock divisor shift */
+#define FMC_SDCR_WP_SHIFT      9       /* Write protection shift */
+#define FMC_SDCR_CAS_SHIFT     7       /* CAS latency shift */
+#define FMC_SDCR_NB_SHIFT      6       /* Number of banks shift */
+#define FMC_SDCR_MWID_SHIFT    4       /* Memory width shift */
+#define FMC_SDCR_NR_SHIFT      2       /* Number of row address bits shift */
+#define FMC_SDCR_NC_SHIFT      0       /* Number of col address bits shift */
+
+/* Timings register SDTR */
+#define FMC_SDTR_TMRD_SHIFT    0       /* Load mode register to active */
+#define FMC_SDTR_TXSR_SHIFT    4       /* Exit self-refresh time */
+#define FMC_SDTR_TRAS_SHIFT    8       /* Self-refresh time */
+#define FMC_SDTR_TRC_SHIFT     12      /* Row cycle delay */
+#define FMC_SDTR_TWR_SHIFT     16      /* Recovery delay */
+#define FMC_SDTR_TRP_SHIFT     20      /* Row precharge delay */
+#define FMC_SDTR_TRCD_SHIFT    24      /* Row-to-column delay */
+
+
+#define FMC_SDCMR_NRFS_SHIFT   5
+
+#define FMC_SDCMR_MODE_NORMAL          0
+#define FMC_SDCMR_MODE_START_CLOCK     1
+#define FMC_SDCMR_MODE_PRECHARGE       2
+#define FMC_SDCMR_MODE_AUTOREFRESH     3
+#define FMC_SDCMR_MODE_WRITE_MODE      4
+#define FMC_SDCMR_MODE_SELFREFRESH     5
+#define FMC_SDCMR_MODE_POWERDOWN       6
+
+#define FMC_SDCMR_BANK_1               (1 << 4)
+#define FMC_SDCMR_BANK_2               (1 << 3)
+
+#define FMC_SDCMR_MODE_REGISTER_SHIFT  9
+
+#define FMC_SDSR_BUSY                  (1 << 5)
+
+#define FMC_BUSY_WAIT()                do { \
+               __asm__ __volatile__ ("dsb" : : : "memory"); \
+               while (STM32_SDRAM_FMC->sdsr & FMC_SDSR_BUSY) \
+                       ; \
+       } while (0)
+
+
+#endif /* _MACH_FMC_H_ */
index 68bdab069d480752a7c99e6bbde255a0442dd319..de55ae5df1530c595c21e9c1f3be0ea7e198262e 100644 (file)
@@ -64,6 +64,52 @@ enum clock {
 };
 #define STM32_BUS_MASK          0xFFFF0000
 
+struct stm32_rcc_regs {
+       u32 cr;         /* RCC clock control */
+       u32 pllcfgr;    /* RCC PLL configuration */
+       u32 cfgr;       /* RCC clock configuration */
+       u32 cir;        /* RCC clock interrupt */
+       u32 ahb1rstr;   /* RCC AHB1 peripheral reset */
+       u32 ahb2rstr;   /* RCC AHB2 peripheral reset */
+       u32 ahb3rstr;   /* RCC AHB3 peripheral reset */
+       u32 rsv0;
+       u32 apb1rstr;   /* RCC APB1 peripheral reset */
+       u32 apb2rstr;   /* RCC APB2 peripheral reset */
+       u32 rsv1[2];
+       u32 ahb1enr;    /* RCC AHB1 peripheral clock enable */
+       u32 ahb2enr;    /* RCC AHB2 peripheral clock enable */
+       u32 ahb3enr;    /* RCC AHB3 peripheral clock enable */
+       u32 rsv2;
+       u32 apb1enr;    /* RCC APB1 peripheral clock enable */
+       u32 apb2enr;    /* RCC APB2 peripheral clock enable */
+       u32 rsv3[2];
+       u32 ahb1lpenr;  /* RCC AHB1 periph clk enable in low pwr mode */
+       u32 ahb2lpenr;  /* RCC AHB2 periph clk enable in low pwr mode */
+       u32 ahb3lpenr;  /* RCC AHB3 periph clk enable in low pwr mode */
+       u32 rsv4;
+       u32 apb1lpenr;  /* RCC APB1 periph clk enable in low pwr mode */
+       u32 apb2lpenr;  /* RCC APB2 periph clk enable in low pwr mode */
+       u32 rsv5[2];
+       u32 bdcr;       /* RCC Backup domain control */
+       u32 csr;        /* RCC clock control & status */
+       u32 rsv6[2];
+       u32 sscgr;      /* RCC spread spectrum clock generation */
+       u32 plli2scfgr; /* RCC PLLI2S configuration */
+       u32 pllsaicfgr;
+       u32 dckcfgr;
+};
+#define STM32_RCC              ((struct stm32_rcc_regs *)RCC_BASE)
+
+struct stm32_pwr_regs {
+       u32 cr1;   /* power control register 1 */
+       u32 csr1;  /* power control/status register 2 */
+       u32 cr2;   /* power control register 2 */
+       u32 csr2;  /* power control/status register 2 */
+};
+#define STM32_PWR              ((struct stm32_pwr_regs *)PWR_BASE)
+
 int configure_clocks(void);
+unsigned long clock_get(enum clock clck);
+void stm32_flash_latency_cfg(int latency);
 
 #endif /* _ASM_ARCH_HARDWARE_H */
index 38adc4e0e2f31acb9785649b35d97a4c44e8ec40..0bd4695727451891fa167c90b911a45a64777d0d 100644 (file)
 enum periph_id {
        UART1_GPIOA_9_10 = 0,
        UART2_GPIOD_5_6,
+       UART6_GPIOC_6_7,
 };
 
 enum periph_clock {
        USART1_CLOCK_CFG = 0,
        USART2_CLOCK_CFG,
+       USART6_CLOCK_CFG,
        GPIO_A_CLOCK_CFG,
        GPIO_B_CLOCK_CFG,
        GPIO_C_CLOCK_CFG,
index 200444dda14d7a937dafef574894648a410eb31f..54d8a2bdff6852f44996f17905fedc2edcf7c21c 100644 (file)
@@ -51,10 +51,21 @@ struct v7m_mpu {
 #define V7M_MPU_CTRL_ENABLE            (1 << 0)
 #define V7M_MPU_CTRL_HFNMIENA          (1 << 1)
 
+#define V7M_MPU_CTRL_ENABLE            (1 << 0)
+#define V7M_MPU_CTRL_DISABLE           (0 << 0)
+#define V7M_MPU_CTRL_HFNMIENA          (1 << 1)
+
 #define V7M_MPU_RASR_EN                        (1 << 0)
 #define V7M_MPU_RASR_SIZE_BITS         1
 #define V7M_MPU_RASR_SIZE_4GB          (31 << V7M_MPU_RASR_SIZE_BITS)
+#define V7M_MPU_RASR_SIZE_8MB          (24 << V7M_MPU_RASR_SIZE_BITS)
+#define V7M_MPU_RASR_TEX_SHIFT 19
+#define V7M_MPU_RASR_S_SHIFT           18
+#define V7M_MPU_RASR_C_SHIFT           17
+#define V7M_MPU_RASR_B_SHIFT           16
 #define V7M_MPU_RASR_AP_RW_RW          (3 << 24)
+#define V7M_MPU_RASR_XN_ENABLE (0 << 28)
+#define V7M_MPU_RASR_XN_DISABLE (1 << 28)
 
 #endif /* !defined(__ASSEMBLY__) */
 #endif /* ARMV7M_H */
index 1f63127bdc8af38269e0ab2ab9487dc1292641b9..16e65c36a9a5dacefadd4281b30a8a4d4bc77c41 100644 (file)
@@ -29,6 +29,8 @@ static inline void invalidate_l2_cache(void)
 }
 #endif
 
+int check_cache_range(unsigned long start, unsigned long stop);
+
 void l2_cache_enable(void);
 void l2_cache_disable(void);
 void set_section_dcache(int section, enum dcache_option option);
index 9d185a61223afbdb392f39d536c380976f169a0e..6121f1ddcac49febcd6ccf2a8d834aec00c6a148 100644 (file)
@@ -291,40 +291,6 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen)
 #define writesb(a, d, s)       __raw_writesb((unsigned long)a, d, s)
 #define readsb(a, d, s)                __raw_readsb((unsigned long)a, d, s)
 
-/*
- * ioremap and friends.
- *
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt.  If you want a
- * physical address, use __ioremap instead.
- */
-extern void * __ioremap(unsigned long offset, size_t size, unsigned long flags);
-extern void __iounmap(void *addr);
-
-/*
- * Generic ioremap support.
- *
- * Define:
- *  iomem_valid_addr(off,size)
- *  iomem_to_phys(off)
- */
-#ifdef iomem_valid_addr
-#define __arch_ioremap(off,sz,nocache)                                 \
- ({                                                                    \
-       unsigned long _off = (off), _size = (sz);                       \
-       void *_ret = (void *)0;                                         \
-       if (iomem_valid_addr(_off, _size))                              \
-               _ret = __ioremap(iomem_to_phys(_off),_size,nocache);    \
-       _ret;                                                           \
- })
-
-#define __arch_iounmap __iounmap
-#endif
-
-#define ioremap(off,sz)                        __arch_ioremap((off),(sz),0)
-#define ioremap_nocache(off,sz)                __arch_ioremap((off),(sz),1)
-#define iounmap(_addr)                 __arch_iounmap(_addr)
-
 /*
  * DMA-consistent mapping functions.  These allocate/free a region of
  * uncached, unwrite-buffered mapped memory space for use with DMA
index 07f384867eb03d43e75eefe8b001a7202033ad1c..605c549f0a5a647b84874d7cd4ed108762c63cc5 100644 (file)
@@ -627,6 +627,12 @@ void recalibrate_iodelay(void);
 
 void omap_smc1(u32 service, u32 val);
 
+/*
+ * Low-level helper function used when performing secure ROM calls on high-
+ * security (HS) device variants by doing a specially-formed smc entry.
+ */
+u32 omap_smc_sec(u32 service, u32 proc_id, u32 flag, u32 *params);
+
 void enable_edma3_clocks(void);
 void disable_edma3_clocks(void);
 
diff --git a/arch/arm/include/asm/omap_sec_common.h b/arch/arm/include/asm/omap_sec_common.h
new file mode 100644 (file)
index 0000000..842f2af
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2016
+ * Texas Instruments, <www.ti.com>
+ *
+ * Andreas Dannenberg <dannenberg@ti.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#ifndef        _OMAP_SEC_COMMON_H_
+#define        _OMAP_SEC_COMMON_H_
+
+#include <common.h>
+
+/*
+ * Invoke secure ROM API on high-security (HS) device variants. It formats
+ * the variable argument list into the format expected by the ROM code before
+ * triggering the actual low-level smc entry.
+ */
+u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...);
+
+/*
+ * Invoke a secure ROM API on high-secure (HS) device variants that can be used
+ * to verify a secure blob by authenticating and optionally decrypting it. The
+ * exact operation performed depends on how the certificate that was embedded
+ * into the blob during the signing/encryption step when the secure blob was
+ * first created.
+ */
+int secure_boot_verify_image(void **p_image, size_t *p_size);
+
+#endif /* _OMAP_SEC_COMMON_H_ */
diff --git a/arch/arm/include/asm/spin_table.h b/arch/arm/include/asm/spin_table.h
new file mode 100644 (file)
index 0000000..8b57539
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __ASM_SPIN_TABLE_H__
+#define __ASM_SPIN_TABLE_H__
+
+extern u64 spin_table_cpu_release_addr;
+extern char spin_table_reserve_begin;
+extern char spin_table_reserve_end;
+
+int spin_table_update_dt(void *fdt);
+
+#endif /* __ASM_SPIN_TABLE_H__ */
index d108915ff5c1e1accc0f4d80be10921707dea667..9af7353f0866f05dbe298a603d52d90e9c8e6d28 100644 (file)
@@ -71,5 +71,4 @@ typedef u32 dma_addr_t;
 
 #endif /* __KERNEL__ */
 
-typedef unsigned long resource_size_t;
 #endif
index 76b75d8e4643ee9a018c216c15301de2ae15f3d4..2c0b56a8f36f480349c5cdaded168c217220c51a 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/armv7.h>
 #endif
 #include <asm/psci.h>
+#include <asm/spin_table.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -45,6 +46,12 @@ int arch_fixup_fdt(void *blob)
        if (ret)
                return ret;
 
+#ifdef CONFIG_ARMV8_SPIN_TABLE
+       ret = spin_table_update_dt(blob);
+       if (ret)
+               return ret;
+#endif
+
 #ifdef CONFIG_ARMV7_NONSEC
        ret = psci_update_dt(blob);
        if (ret)
index 3bd87105c58bb760048f127c5e292ae9fec0362e..d330b09434a46df1ab6505bf8b46c54e90ccfa21 100644 (file)
 #include <common.h>
 #include <malloc.h>
 
+#ifndef CONFIG_SYS_CACHELINE_SIZE
+#define CONFIG_SYS_CACHELINE_SIZE 32
+#endif
+
 /*
  * Flush range from all levels of d-cache/unified-cache.
  * Affects the range [start, start + size - 1].
@@ -46,6 +50,24 @@ __weak void flush_dcache_range(unsigned long start, unsigned long stop)
        /* An empty stub, real implementation should be in platform code */
 }
 
+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) {
+               warn_non_spl("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
+                            start, stop);
+       }
+
+       return ok;
+}
+
 #ifdef CONFIG_SYS_NONCACHED_MEMORY
 /*
  * Reserve one MMU section worth of address space below the malloc() area that
index 40f1ad35b7eb1fe4d3b4991ed4cc05d8387f6162..643d4d919c2cdf5c0f156f362a09540de2202cc3 100644 (file)
@@ -5,4 +5,4 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-y += timer.o clock.o
+obj-y += timer.o clock.o soc.o
index 17a715bac92e9fb840b08b2ae40f28dd81a0711d..ac478505516c339a0e9a43a92623a11854c80ca3 100644 (file)
 #include <asm/arch/stm32.h>
 #include <asm/arch/stm32_periph.h>
 
+#define RCC_CR_HSION           (1 << 0)
+#define RCC_CR_HSEON           (1 << 16)
+#define RCC_CR_HSERDY          (1 << 17)
+#define RCC_CR_HSEBYP          (1 << 18)
+#define RCC_CR_CSSON           (1 << 19)
+#define RCC_CR_PLLON           (1 << 24)
+#define RCC_CR_PLLRDY          (1 << 25)
+
+#define RCC_PLLCFGR_PLLM_MASK  0x3F
+#define RCC_PLLCFGR_PLLN_MASK  0x7FC0
+#define RCC_PLLCFGR_PLLP_MASK  0x30000
+#define RCC_PLLCFGR_PLLQ_MASK  0xF000000
+#define RCC_PLLCFGR_PLLSRC     (1 << 22)
+#define RCC_PLLCFGR_PLLM_SHIFT 0
+#define RCC_PLLCFGR_PLLN_SHIFT 6
+#define RCC_PLLCFGR_PLLP_SHIFT 16
+#define RCC_PLLCFGR_PLLQ_SHIFT 24
+
+#define RCC_CFGR_AHB_PSC_MASK  0xF0
+#define RCC_CFGR_APB1_PSC_MASK 0x1C00
+#define RCC_CFGR_APB2_PSC_MASK 0xE000
+#define RCC_CFGR_SW0           (1 << 0)
+#define RCC_CFGR_SW1           (1 << 1)
+#define RCC_CFGR_SW_MASK       0x3
+#define RCC_CFGR_SW_HSI                0
+#define RCC_CFGR_SW_HSE                RCC_CFGR_SW0
+#define RCC_CFGR_SW_PLL                RCC_CFGR_SW1
+#define RCC_CFGR_SWS0          (1 << 2)
+#define RCC_CFGR_SWS1          (1 << 3)
+#define RCC_CFGR_SWS_MASK      0xC
+#define RCC_CFGR_SWS_HSI       0
+#define RCC_CFGR_SWS_HSE       RCC_CFGR_SWS0
+#define RCC_CFGR_SWS_PLL       RCC_CFGR_SWS1
+#define RCC_CFGR_HPRE_SHIFT    4
+#define RCC_CFGR_PPRE1_SHIFT   10
+#define RCC_CFGR_PPRE2_SHIFT   13
+
+#define RCC_APB1ENR_PWREN      (1 << 28)
+
+/*
+ * RCC USART specific definitions
+ */
+#define RCC_ENR_USART1EN               (1 << 4)
+#define RCC_ENR_USART2EN               (1 << 17)
+#define RCC_ENR_USART3EN               (1 << 18)
+#define RCC_ENR_USART6EN               (1 <<  5)
+
+/*
+ * Offsets of some PWR registers
+ */
+#define PWR_CR1_ODEN           (1 << 16)
+#define PWR_CR1_ODSWEN         (1 << 17)
+#define PWR_CSR1_ODRDY         (1 << 16)
+#define PWR_CSR1_ODSWRDY       (1 << 17)
+
+
+/*
+ * RCC GPIO specific definitions
+ */
+#define RCC_ENR_GPIO_A_EN      (1 << 0)
+#define RCC_ENR_GPIO_B_EN      (1 << 1)
+#define RCC_ENR_GPIO_C_EN      (1 << 2)
+#define RCC_ENR_GPIO_D_EN      (1 << 3)
+#define RCC_ENR_GPIO_E_EN      (1 << 4)
+#define RCC_ENR_GPIO_F_EN      (1 << 5)
+#define RCC_ENR_GPIO_G_EN      (1 << 6)
+#define RCC_ENR_GPIO_H_EN      (1 << 7)
+#define RCC_ENR_GPIO_I_EN      (1 << 8)
+#define RCC_ENR_GPIO_J_EN      (1 << 9)
+#define RCC_ENR_GPIO_K_EN      (1 << 10)
+
+struct pll_psc {
+       u8      pll_m;
+       u16     pll_n;
+       u8      pll_p;
+       u8      pll_q;
+       u8      ahb_psc;
+       u8      apb1_psc;
+       u8      apb2_psc;
+};
+
+#define AHB_PSC_1              0
+#define AHB_PSC_2              0x8
+#define AHB_PSC_4              0x9
+#define AHB_PSC_8              0xA
+#define AHB_PSC_16             0xB
+#define AHB_PSC_64             0xC
+#define AHB_PSC_128            0xD
+#define AHB_PSC_256            0xE
+#define AHB_PSC_512            0xF
+
+#define APB_PSC_1              0
+#define APB_PSC_2              0x4
+#define APB_PSC_4              0x5
+#define APB_PSC_8              0x6
+#define APB_PSC_16             0x7
+
+#if !defined(CONFIG_STM32_HSE_HZ)
+#error "CONFIG_STM32_HSE_HZ not defined!"
+#else
+#if (CONFIG_STM32_HSE_HZ == 25000000)
+#if (CONFIG_SYS_CLK_FREQ == 200000000)
+/* 200 MHz */
+struct pll_psc sys_pll_psc = {
+       .pll_m = 25,
+       .pll_n = 400,
+       .pll_p = 2,
+       .pll_q = 8,
+       .ahb_psc = AHB_PSC_1,
+       .apb1_psc = APB_PSC_4,
+       .apb2_psc = APB_PSC_2
+};
+#endif
+#else
+#error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists"
+#endif
+#endif
+
+int configure_clocks(void)
+{
+       /* Reset RCC configuration */
+       setbits_le32(&STM32_RCC->cr, RCC_CR_HSION);
+       writel(0, &STM32_RCC->cfgr); /* Reset CFGR */
+       clrbits_le32(&STM32_RCC->cr, (RCC_CR_HSEON | RCC_CR_CSSON
+               | RCC_CR_PLLON));
+       writel(0x24003010, &STM32_RCC->pllcfgr); /* Reset value from RM */
+       clrbits_le32(&STM32_RCC->cr, RCC_CR_HSEBYP);
+       writel(0, &STM32_RCC->cir); /* Disable all interrupts */
+
+       /* Configure for HSE+PLL operation */
+       setbits_le32(&STM32_RCC->cr, RCC_CR_HSEON);
+       while (!(readl(&STM32_RCC->cr) & RCC_CR_HSERDY))
+               ;
+
+       setbits_le32(&STM32_RCC->cfgr, ((
+               sys_pll_psc.ahb_psc << RCC_CFGR_HPRE_SHIFT)
+               | (sys_pll_psc.apb1_psc << RCC_CFGR_PPRE1_SHIFT)
+               | (sys_pll_psc.apb2_psc << RCC_CFGR_PPRE2_SHIFT)));
+
+       /* Configure the main PLL */
+       uint32_t pllcfgr = 0;
+       pllcfgr = RCC_PLLCFGR_PLLSRC; /* pll source HSE */
+       pllcfgr |= sys_pll_psc.pll_m << RCC_PLLCFGR_PLLM_SHIFT;
+       pllcfgr |= sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT;
+       pllcfgr |= ((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT;
+       pllcfgr |= sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT;
+       writel(pllcfgr, &STM32_RCC->pllcfgr);
+
+       /* Enable the main PLL */
+       setbits_le32(&STM32_RCC->cr, RCC_CR_PLLON);
+       while (!(readl(&STM32_RCC->cr) & RCC_CR_PLLRDY))
+               ;
+
+       /* Enable high performance mode, System frequency up to 200 MHz */
+       setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_PWREN);
+       setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODEN);
+       /* Infinite wait! */
+       while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODRDY))
+               ;
+       /* Enable the Over-drive switch */
+       setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODSWEN);
+       /* Infinite wait! */
+       while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODSWRDY))
+               ;
+
+       stm32_flash_latency_cfg(5);
+       clrbits_le32(&STM32_RCC->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
+       setbits_le32(&STM32_RCC->cfgr, RCC_CFGR_SW_PLL);
+
+       while ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) !=
+                       RCC_CFGR_SWS_PLL)
+               ;
+
+       return 0;
+}
+
+unsigned long clock_get(enum clock clck)
+{
+       u32 sysclk = 0;
+       u32 shift = 0;
+       /* Prescaler table lookups for clock computation */
+       u8 ahb_psc_table[16] = {
+               0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
+       };
+       u8 apb_psc_table[8] = {
+               0, 0, 0, 0, 1, 2, 3, 4
+       };
+
+       if ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) ==
+                       RCC_CFGR_SWS_PLL) {
+               u16 pllm, plln, pllp;
+               pllm = (readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
+               plln = ((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
+                       >> RCC_PLLCFGR_PLLN_SHIFT);
+               pllp = ((((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLP_MASK)
+                       >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1);
+               sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp;
+       }
+
+       switch (clck) {
+       case CLOCK_CORE:
+               return sysclk;
+               break;
+       case CLOCK_AHB:
+               shift = ahb_psc_table[(
+                       (readl(&STM32_RCC->cfgr) & RCC_CFGR_AHB_PSC_MASK)
+                       >> RCC_CFGR_HPRE_SHIFT)];
+               return sysclk >>= shift;
+               break;
+       case CLOCK_APB1:
+               shift = apb_psc_table[(
+                       (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB1_PSC_MASK)
+                       >> RCC_CFGR_PPRE1_SHIFT)];
+               return sysclk >>= shift;
+               break;
+       case CLOCK_APB2:
+               shift = apb_psc_table[(
+                       (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB2_PSC_MASK)
+                       >> RCC_CFGR_PPRE2_SHIFT)];
+               return sysclk >>= shift;
+               break;
+       default:
+               return 0;
+               break;
+       }
+}
+
+
 void clock_setup(int peripheral)
 {
        switch (peripheral) {
        case USART1_CLOCK_CFG:
                setbits_le32(RCC_BASE + RCC_APB2ENR, RCC_ENR_USART1EN);
                break;
+       case USART6_CLOCK_CFG:
+               setbits_le32(RCC_BASE + RCC_APB2ENR, RCC_ENR_USART6EN);
+               break;
        case GPIO_A_CLOCK_CFG:
                setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_A_EN);
                break;
diff --git a/arch/arm/mach-stm32/stm32f7/soc.c b/arch/arm/mach-stm32/stm32f7/soc.c
new file mode 100644 (file)
index 0000000..8baee99
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * (C) Copyright 2015
+ * Kamil Lulko, <kamil.lulko@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/armv7m.h>
+#include <asm/arch/stm32.h>
+
+u32 get_cpu_rev(void)
+{
+       return 0;
+}
+
+int arch_cpu_init(void)
+{
+       configure_clocks();
+
+       /*
+               * Configure the memory protection unit (MPU)
+               * 0x00000000 - 0xffffffff: Strong-order, Shareable
+               * 0xC0000000 - 0xC0800000: Normal, Outer and inner Non-cacheable
+        */
+
+        /* Disable MPU */
+        writel(0, &V7M_MPU->ctrl);
+
+        writel(
+                0x00000000 /* address */
+                | 1 << 4       /* VALID */
+                | 0 << 0       /* REGION */
+                , &V7M_MPU->rbar
+        );
+
+        /* Strong-order, Shareable */
+        /* TEX=000, S=1, C=0, B=0*/
+        writel(
+                (V7M_MPU_RASR_XN_ENABLE
+                        | V7M_MPU_RASR_AP_RW_RW
+                        | 0x01 << V7M_MPU_RASR_S_SHIFT
+                        | 0x00 << V7M_MPU_RASR_TEX_SHIFT
+                        | V7M_MPU_RASR_SIZE_4GB
+                        | V7M_MPU_RASR_EN)
+                , &V7M_MPU->rasr
+        );
+
+        writel(
+                0xC0000000 /* address */
+                | 1 << 4       /* VALID */
+                | 1 << 0       /* REGION */
+                , &V7M_MPU->rbar
+        );
+
+        /* Normal, Outer and inner Non-cacheable */
+        /* TEX=001, S=0, C=0, B=0*/
+        writel(
+                (V7M_MPU_RASR_XN_ENABLE
+                        | V7M_MPU_RASR_AP_RW_RW
+                        | 0x01 << V7M_MPU_RASR_TEX_SHIFT
+                        | V7M_MPU_RASR_SIZE_8MB
+                        | V7M_MPU_RASR_EN)
+                        , &V7M_MPU->rasr
+        );
+
+        /* Enable MPU */
+        writel(V7M_MPU_CTRL_ENABLE | V7M_MPU_CTRL_HFNMIENA, &V7M_MPU->ctrl);
+
+       return 0;
+}
+
+void s_init(void)
+{
+}
index 04708e9359461b641d01e9c8b1fd2d4920b91ef3..b2c4d0ef8cf342e18f523920987e5f11917fb08e 100644 (file)
@@ -343,40 +343,6 @@ static inline void writesl(unsigned int *addr, const void * data, int longlen)
 #define insw_p(port, to, len)          insw(port, to, len)
 #define insl_p(port, to, len)          insl(port, to, len)
 
-/*
- * ioremap and friends.
- *
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt.  If you want a
- * physical address, use __ioremap instead.
- */
-extern void *__ioremap(unsigned long offset, size_t size, unsigned long flags);
-extern void __iounmap(void *addr);
-
-/*
- * Generic ioremap support.
- *
- * Define:
- *  iomem_valid_addr(off,size)
- *  iomem_to_phys(off)
- */
-#ifdef iomem_valid_addr
-#define __arch_ioremap(off, sz, nocache)                               \
-({                                                                     \
-       unsigned long _off = (off), _size = (sz);                       \
-       void *_ret = (void *)0;                                         \
-       if (iomem_valid_addr(_off, _size))                              \
-               _ret = __ioremap(iomem_to_phys(_off), _size, 0);        \
-       _ret;                                                           \
-})
-
-#define __arch_iounmap __iounmap
-#endif
-
-#define ioremap(off, sz)               __arch_ioremap((off), (sz), 0)
-#define ioremap_nocache(off, sz)       __arch_ioremap((off), (sz), 1)
-#define iounmap(_addr)                 __arch_iounmap(_addr)
-
 /*
  * DMA-consistent mapping functions.  These allocate/free a region of
  * uncached, unwrite-buffered mapped memory space for use with DMA
index d49c927b3465b5c73956f6d312b7a8226ac2c558..0c9a7979d23142fbc3d96d1722c7d8cd4d6b3c09 100644 (file)
@@ -56,7 +56,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
                bootstage_mark(BOOTSTAGE_ID_RUN_OS);
                printf("## Transferring control to Linux (at address %08lx)...\n",
                       images->ep);
-               reset_cpu(0);
+               printf("sandbox: continuing, as we cannot run Linux\n");
        }
 
        return 0;
index 0a00db361798d17dfdf666b73b9834a1afbeda60..5dc27bebd5033b28213043ea2d0755697a34021d 100644 (file)
@@ -128,39 +128,6 @@ extern void __raw_readsl(unsigned int addr, void *data, int longlen);
 #define in_8(port)                     inb(port)
 #define in_le16(port)          inw(port)
 #define in_le32(port)          inl(port)
-/*
- * ioremap and friends.
- *
- * ioremap takes a PCI memory address, as specified in
- * linux/Documentation/IO-mapping.txt.  If you want a
- * physical address, use __ioremap instead.
- */
-extern void *__ioremap(unsigned long offset, size_t size, unsigned long flags);
-extern void __iounmap(void *addr);
-
-/*
- * Generic ioremap support.
- *
- * Define:
- *  iomem_valid_addr(off,size)
- *  iomem_to_phys(off)
- */
-#ifdef iomem_valid_addr
-#define __arch_ioremap(off, sz, nocache)                               \
-({                                                             \
-       unsigned long _off = (off), _size = (sz);               \
-       void *_ret = (void *)0;                                 \
-       if (iomem_valid_addr(_off, _size))                      \
-               _ret = __ioremap(iomem_to_phys(_off), _size, 0);        \
-       _ret;                                                   \
-})
-
-#define __arch_iounmap __iounmap
-#endif
-
-#define ioremap(off, sz)                       __arch_ioremap((off), (sz), 0)
-#define ioremap_nocache(off, sz)               __arch_ioremap((off), (sz), 1)
-#define iounmap(_addr)                 __arch_iounmap(_addr)
 
 /*
  * DMA-consistent mapping functions.  These allocate/free a region of
index 0e04d141480f8ade641957e6a6e1bf0b72af5f01..47aa05897eb1adf59d184037dd39c0014c4cc8f9 100644 (file)
@@ -10,6 +10,8 @@
 #include <asm/armv7m.h>
 #include <asm/arch/stm32.h>
 #include <asm/arch/gpio.h>
+#include <asm/arch/rcc.h>
+#include <asm/arch/fmc.h>
 #include <dm/platdata.h>
 #include <dm/platform_data/serial_stm32x7.h>
 #include <asm/arch/stm32_periph.h>
@@ -30,12 +32,227 @@ const struct stm32_gpio_ctl gpio_ctl_usart = {
        .otype = STM32_GPIO_OTYPE_PP,
        .speed = STM32_GPIO_SPEED_50M,
        .pupd = STM32_GPIO_PUPD_UP,
-       .af = STM32_GPIO_AF7
+       .af = STM32_GPIO_AF8
 };
 
+const struct stm32_gpio_ctl gpio_ctl_fmc = {
+       .mode = STM32_GPIO_MODE_AF,
+       .otype = STM32_GPIO_OTYPE_PP,
+       .speed = STM32_GPIO_SPEED_100M,
+       .pupd = STM32_GPIO_PUPD_NO,
+       .af = STM32_GPIO_AF12
+};
+
+static const struct stm32_gpio_dsc ext_ram_fmc_gpio[] = {
+       /* Chip is LQFP144, see DM00077036.pdf for details */
+       {STM32_GPIO_PORT_D, STM32_GPIO_PIN_10}, /* 79, FMC_D15 */
+       {STM32_GPIO_PORT_D, STM32_GPIO_PIN_9},  /* 78, FMC_D14 */
+       {STM32_GPIO_PORT_D, STM32_GPIO_PIN_8},  /* 77, FMC_D13 */
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_15}, /* 68, FMC_D12 */
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_14}, /* 67, FMC_D11 */
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_13}, /* 66, FMC_D10 */
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_12}, /* 65, FMC_D9 */
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_11}, /* 64, FMC_D8 */
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_10}, /* 63, FMC_D7 */
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_9},  /* 60, FMC_D6 */
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_8},  /* 59, FMC_D5 */
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_7},  /* 58, FMC_D4 */
+       {STM32_GPIO_PORT_D, STM32_GPIO_PIN_1},  /* 115, FMC_D3 */
+       {STM32_GPIO_PORT_D, STM32_GPIO_PIN_0},  /* 114, FMC_D2 */
+       {STM32_GPIO_PORT_D, STM32_GPIO_PIN_15}, /* 86, FMC_D1 */
+       {STM32_GPIO_PORT_D, STM32_GPIO_PIN_14}, /* 85, FMC_D0 */
+
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_1},  /* 142, FMC_NBL1 */
+       {STM32_GPIO_PORT_E, STM32_GPIO_PIN_0},  /* 141, FMC_NBL0 */
+
+       {STM32_GPIO_PORT_G, STM32_GPIO_PIN_5},  /* 90, FMC_A15, BA1 */
+       {STM32_GPIO_PORT_G, STM32_GPIO_PIN_4},  /* 89, FMC_A14, BA0 */
+
+       {STM32_GPIO_PORT_G, STM32_GPIO_PIN_1},  /* 57, FMC_A11 */
+       {STM32_GPIO_PORT_G, STM32_GPIO_PIN_0},  /* 56, FMC_A10 */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_15}, /* 55, FMC_A9 */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_14}, /* 54, FMC_A8 */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_13}, /* 53, FMC_A7 */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_12}, /* 50, FMC_A6 */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_5},  /* 15, FMC_A5 */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_4},  /* 14, FMC_A4 */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_3},  /* 13, FMC_A3 */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_2},  /* 12, FMC_A2 */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_1},  /* 11, FMC_A1 */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_0},  /* 10, FMC_A0 */
+
+       {STM32_GPIO_PORT_H, STM32_GPIO_PIN_3},  /* 136, SDRAM_NE */
+       {STM32_GPIO_PORT_F, STM32_GPIO_PIN_11}, /* 49, SDRAM_NRAS */
+       {STM32_GPIO_PORT_G, STM32_GPIO_PIN_15}, /* 132, SDRAM_NCAS */
+       {STM32_GPIO_PORT_H, STM32_GPIO_PIN_5},  /* 26, SDRAM_NWE */
+       {STM32_GPIO_PORT_C, STM32_GPIO_PIN_3},  /* 135, SDRAM_CKE */
+
+       {STM32_GPIO_PORT_G, STM32_GPIO_PIN_8},  /* 93, SDRAM_CLK */
+};
+
+static int fmc_setup_gpio(void)
+{
+       int rv = 0;
+       int i;
+
+       clock_setup(GPIO_B_CLOCK_CFG);
+       clock_setup(GPIO_C_CLOCK_CFG);
+       clock_setup(GPIO_D_CLOCK_CFG);
+       clock_setup(GPIO_E_CLOCK_CFG);
+       clock_setup(GPIO_F_CLOCK_CFG);
+       clock_setup(GPIO_G_CLOCK_CFG);
+       clock_setup(GPIO_H_CLOCK_CFG);
+
+       for (i = 0; i < ARRAY_SIZE(ext_ram_fmc_gpio); i++) {
+               rv = stm32_gpio_config(&ext_ram_fmc_gpio[i],
+                               &gpio_ctl_fmc);
+               if (rv)
+                       goto out;
+       }
+
+out:
+       return rv;
+}
+
+/*
+ * STM32 RCC FMC specific definitions
+ */
+#define RCC_ENR_FMC    (1 << 0)        /* FMC module clock  */
+
+static inline u32 _ns2clk(u32 ns, u32 freq)
+{
+       u32 tmp = freq/1000000;
+       return (tmp * ns) / 1000;
+}
+
+#define NS2CLK(ns) (_ns2clk(ns, freq))
+
+/*
+ * Following are timings for IS42S16400J, from corresponding datasheet
+ */
+#define SDRAM_CAS      3       /* 3 cycles */
+#define SDRAM_NB       1       /* Number of banks */
+#define SDRAM_MWID     1       /* 16 bit memory */
+
+#define SDRAM_NR       0x1     /* 12-bit row */
+#define SDRAM_NC       0x0     /* 8-bit col */
+#define SDRAM_RBURST   0x1     /* Single read requests always as bursts */
+#define SDRAM_RPIPE    0x0     /* No HCLK clock cycle delay */
+
+#define SDRAM_TRRD     NS2CLK(12)
+#define SDRAM_TRCD     NS2CLK(18)
+#define SDRAM_TRP      NS2CLK(18)
+#define SDRAM_TRAS     NS2CLK(42)
+#define SDRAM_TRC      NS2CLK(60)
+#define SDRAM_TRFC     NS2CLK(60)
+#define SDRAM_TCDL     (1 - 1)
+#define SDRAM_TRDL     NS2CLK(12)
+#define SDRAM_TBDL     (1 - 1)
+#define SDRAM_TREF     (NS2CLK(64000000 / 8192) - 20)
+#define SDRAM_TCCD     (1 - 1)
+
+#define SDRAM_TXSR     SDRAM_TRFC      /* Row cycle time after precharge */
+#define SDRAM_TMRD     1               /* Page 10, Mode Register Set */
+
+
+/* Last data in to row precharge, need also comply ineq on page 1648 */
+#define SDRAM_TWR      max(\
+       (int)max((int)SDRAM_TRDL, (int)(SDRAM_TRAS - SDRAM_TRCD)), \
+       (int)(SDRAM_TRC - SDRAM_TRCD - SDRAM_TRP)\
+)
+
+
+#define SDRAM_MODE_BL_SHIFT    0
+#define SDRAM_MODE_CAS_SHIFT   4
+#define SDRAM_MODE_BL          0
+#define SDRAM_MODE_CAS         SDRAM_CAS
+
+int dram_init(void)
+{
+       u32 freq;
+       int rv;
+
+       rv = fmc_setup_gpio();
+       if (rv)
+               return rv;
+
+       setbits_le32(RCC_BASE + RCC_AHB3ENR, RCC_ENR_FMC);
+
+       /*
+        * Get frequency for NS2CLK calculation.
+        */
+       freq = clock_get(CLOCK_AHB) / CONFIG_SYS_RAM_FREQ_DIV;
+
+       writel(
+               CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT
+               | SDRAM_CAS << FMC_SDCR_CAS_SHIFT
+               | SDRAM_NB << FMC_SDCR_NB_SHIFT
+               | SDRAM_MWID << FMC_SDCR_MWID_SHIFT
+               | SDRAM_NR << FMC_SDCR_NR_SHIFT
+               | SDRAM_NC << FMC_SDCR_NC_SHIFT
+               | SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT
+               | SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT,
+               &STM32_SDRAM_FMC->sdcr1);
+
+       writel(
+               SDRAM_TRCD << FMC_SDTR_TRCD_SHIFT
+               | SDRAM_TRP << FMC_SDTR_TRP_SHIFT
+               | SDRAM_TWR << FMC_SDTR_TWR_SHIFT
+               | SDRAM_TRC << FMC_SDTR_TRC_SHIFT
+               | SDRAM_TRAS << FMC_SDTR_TRAS_SHIFT
+               | SDRAM_TXSR << FMC_SDTR_TXSR_SHIFT
+               | SDRAM_TMRD << FMC_SDTR_TMRD_SHIFT,
+               &STM32_SDRAM_FMC->sdtr1);
+
+       writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK,
+              &STM32_SDRAM_FMC->sdcmr);
+
+       udelay(200);    /* 200 us delay, page 10, "Power-Up" */
+       FMC_BUSY_WAIT();
+
+       writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_PRECHARGE,
+              &STM32_SDRAM_FMC->sdcmr);
+
+       udelay(100);
+       FMC_BUSY_WAIT();
+
+       writel((FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_AUTOREFRESH
+               | 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr);
+
+       udelay(100);
+       FMC_BUSY_WAIT();
+
+       writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT
+               | SDRAM_MODE_CAS << SDRAM_MODE_CAS_SHIFT)
+               << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE,
+               &STM32_SDRAM_FMC->sdcmr);
+
+       udelay(100);
+
+       FMC_BUSY_WAIT();
+
+       writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_NORMAL,
+              &STM32_SDRAM_FMC->sdcmr);
+
+       FMC_BUSY_WAIT();
+
+       /* Refresh timer */
+       writel(SDRAM_TREF, &STM32_SDRAM_FMC->sdrtr);
+
+       /*
+        * Fill in global info with description of SRAM configuration
+        */
+       gd->bd->bi_dram[0].start = CONFIG_SYS_RAM_BASE;
+       gd->bd->bi_dram[0].size  = CONFIG_SYS_RAM_SIZE;
+
+       gd->ram_size = CONFIG_SYS_RAM_SIZE;
+
+       return rv;
+}
+
 static const struct stm32_gpio_dsc usart_gpio[] = {
-       {STM32_GPIO_PORT_A, STM32_GPIO_PIN_9},  /* TX */
-       {STM32_GPIO_PORT_B, STM32_GPIO_PIN_7},  /* RX */
+       {STM32_GPIO_PORT_C, STM32_GPIO_PIN_6},  /* TX */
+       {STM32_GPIO_PORT_C, STM32_GPIO_PIN_7},  /* RX */
 };
 
 int uart_setup_gpio(void)
@@ -43,8 +260,7 @@ int uart_setup_gpio(void)
        int i;
        int rv = 0;
 
-       clock_setup(GPIO_A_CLOCK_CFG);
-       clock_setup(GPIO_B_CLOCK_CFG);
+       clock_setup(GPIO_C_CLOCK_CFG);
        for (i = 0; i < ARRAY_SIZE(usart_gpio); i++) {
                rv = stm32_gpio_config(&usart_gpio[i], &gpio_ctl_usart);
                if (rv)
@@ -56,7 +272,7 @@ out:
 }
 
 static const struct stm32x7_serial_platdata serial_platdata = {
-       .base = (struct stm32_usart *)USART1_BASE,
+       .base = (struct stm32_usart *)USART6_BASE,
        .clock = CONFIG_SYS_CLK_FREQ,
 };
 
@@ -75,7 +291,7 @@ int board_early_init_f(void)
        int res;
 
        res = uart_setup_gpio();
-       clock_setup(USART1_CLOCK_CFG);
+       clock_setup(USART6_CLOCK_CFG);
        if (res)
                return res;
 
@@ -88,12 +304,3 @@ int board_init(void)
 
        return 0;
 }
-
-int dram_init(void)
-{
-       gd->bd->bi_dram[0].start = CONFIG_SYS_RAM_BASE;
-       gd->bd->bi_dram[0].size  = CONFIG_SYS_RAM_SIZE;
-
-       gd->ram_size = CONFIG_SYS_RAM_SIZE;
-       return 0;
-}
index f005762edadea944ce1840bc7430086912131c76..27c311ee9d2d930482c5f423a56b8c7df3eaabcb 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/errno.h>
 #include <spl.h>
 #include <usb.h>
+#include <asm/omap_sec_common.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/mux.h>
@@ -862,3 +863,10 @@ int board_fit_config_name_match(const char *name)
                return -1;
 }
 #endif
+
+#ifdef CONFIG_TI_SECURE_DEVICE
+void board_fit_image_post_process(void **p_image, size_t *p_size)
+{
+       secure_boot_verify_image(p_image, p_size);
+}
+#endif
index 08cf14d5e73f629bf4a47d880aca7888d432d928..927d1364fe46736d0e52ab37d29e988d6125cbe0 100644 (file)
@@ -13,6 +13,7 @@
 #include <sata.h>
 #include <usb.h>
 #include <asm/omap_common.h>
+#include <asm/omap_sec_common.h>
 #include <asm/emif.h>
 #include <asm/gpio.h>
 #include <asm/arch/gpio.h>
@@ -750,3 +751,10 @@ int board_fit_config_name_match(const char *name)
                return -1;
 }
 #endif
+
+#ifdef CONFIG_TI_SECURE_DEVICE
+void board_fit_image_post_process(void **p_image, size_t *p_size)
+{
+       secure_boot_verify_image(p_image, p_size);
+}
+#endif
index 6a4d02769e584eed96fef0675e3bef5816d738db..99e82542f72a375d5f26cdf0b387ea4aba313432 100644 (file)
@@ -17,6 +17,8 @@
 #include <asm/gpio.h>
 #include <usb.h>
 #include <linux/usb/gadget.h>
+#include <asm/omap_common.h>
+#include <asm/omap_sec_common.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/dra7xx_iodelay.h>
 #include <asm/emif.h>
@@ -834,3 +836,10 @@ int board_fit_config_name_match(const char *name)
                return -1;
 }
 #endif
+
+#ifdef CONFIG_TI_SECURE_DEVICE
+void board_fit_image_post_process(void **p_image, size_t *p_size)
+{
+       secure_boot_verify_image(p_image, p_size);
+}
+#endif
index d405b5b407e817677afcea7f626c44c2c9c16d23..8d936cc0b7bae9af144afe7e75d3b68f042708ea 100644 (file)
@@ -117,10 +117,11 @@ static int init_func_watchdog_init(void)
 # if defined(CONFIG_HW_WATCHDOG) && (defined(CONFIG_BLACKFIN) || \
        defined(CONFIG_M68K) || defined(CONFIG_MICROBLAZE) || \
        defined(CONFIG_SH) || defined(CONFIG_AT91SAM9_WATCHDOG) || \
+       defined(CONFIG_DESIGNWARE_WATCHDOG) || \
        defined(CONFIG_IMX_WATCHDOG))
        hw_watchdog_init();
-# endif
        puts("       Watchdog enabled\n");
+# endif
        WATCHDOG_RESET();
 
        return 0;
index 2431019b3f407d8eff683fa1cd8c5ce46a468cc4..9ed6428281b35c4c9e60d107e5188db1d982d706 100644 (file)
@@ -635,10 +635,6 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                        goto err;
                else if (ret == BOOTM_ERR_OVERLAP)
                        ret = 0;
-#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
-               if (images->os.os == IH_OS_LINUX)
-                       fixup_silent_linux();
-#endif
        }
 
        /* Relocate the ramdisk */
@@ -678,13 +674,19 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                return 1;
        }
 
+
        /* Call various other states that are not generally used */
        if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
                ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
        if (!ret && (states & BOOTM_STATE_OS_BD_T))
                ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
-       if (!ret && (states & BOOTM_STATE_OS_PREP))
+       if (!ret && (states & BOOTM_STATE_OS_PREP)) {
+#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
+               if (images->os.os == IH_OS_LINUX)
+                       fixup_silent_linux();
+#endif
                ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
+       }
 
 #ifdef CONFIG_TRACE
        /* Pretend to run the OS, then run a user command */
index 9ec84bd0dbe0349741b09b44010f3e4f75709be8..e3f5a4641207e41a387cbf941fb1d23afde0fdc0 100644 (file)
@@ -481,6 +481,7 @@ int boot_selected_os(int argc, char * const argv[], int state,
 
        /* Stand-alone may return when 'autostart' is 'no' */
        if (images->os.type == IH_TYPE_STANDALONE ||
+           IS_ENABLED(CONFIG_SANDBOX) ||
            state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */
                return 0;
        bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
index 0be09e5c6306df7973b3a45e00c6c891cef7ee26..af155b229b9dc2b5c5268732060860055d033a84 100644 (file)
@@ -69,7 +69,7 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,
 #endif
 
 static const table_entry_t uimage_arch[] = {
-       {       IH_ARCH_INVALID,        NULL,           "Invalid ARCH", },
+       {       IH_ARCH_INVALID,        "invalid",      "Invalid ARCH", },
        {       IH_ARCH_ALPHA,          "alpha",        "Alpha",        },
        {       IH_ARCH_ARM,            "arm",          "ARM",          },
        {       IH_ARCH_I386,           "x86",          "Intel x86",    },
@@ -97,7 +97,7 @@ static const table_entry_t uimage_arch[] = {
 };
 
 static const table_entry_t uimage_os[] = {
-       {       IH_OS_INVALID,  NULL,           "Invalid OS",           },
+       {       IH_OS_INVALID,  "invalid",      "Invalid OS",           },
        {       IH_OS_LINUX,    "linux",        "Linux",                },
 #if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
        {       IH_OS_LYNXOS,   "lynxos",       "LynxOS",               },
@@ -144,7 +144,7 @@ static const table_entry_t uimage_type[] = {
        {       IH_TYPE_KERNEL_NOLOAD, "kernel_noload",  "Kernel Image (no loading done)", },
        {       IH_TYPE_KWBIMAGE,   "kwbimage",   "Kirkwood Boot Image",},
        {       IH_TYPE_IMXIMAGE,   "imximage",   "Freescale i.MX Boot Image",},
-       {       IH_TYPE_INVALID,    NULL,         "Invalid Image",      },
+       {       IH_TYPE_INVALID,    "invalid",    "Invalid Image",      },
        {       IH_TYPE_MULTI,      "multi",      "Multi-File Image",   },
        {       IH_TYPE_OMAPIMAGE,  "omapimage",  "TI OMAP SPL With GP CH",},
        {       IH_TYPE_PBLIMAGE,   "pblimage",   "Freescale PBL Boot Image",},
@@ -176,6 +176,19 @@ static const table_entry_t uimage_comp[] = {
        {       -1,             "",             "",                     },
 };
 
+struct table_info {
+       const char *desc;
+       int count;
+       const table_entry_t *table;
+};
+
+static const struct table_info table_info[IH_COUNT] = {
+       { "architecture", IH_ARCH_COUNT, uimage_arch },
+       { "compression", IH_COMP_COUNT, uimage_comp },
+       { "operating system", IH_OS_COUNT, uimage_os },
+       { "image type", IH_TYPE_COUNT, uimage_type },
+};
+
 /*****************************************************************************/
 /* Legacy format routines */
 /*****************************************************************************/
@@ -570,6 +583,74 @@ const table_entry_t *get_table_entry(const table_entry_t *table, int id)
        return NULL;
 }
 
+static const char *unknown_msg(enum ih_category category)
+{
+       static char msg[30];
+
+       strcpy(msg, "Unknown ");
+       strcat(msg, table_info[category].desc);
+
+       return msg;
+}
+
+/**
+ * get_cat_table_entry_name - translate entry id to long name
+ * @category: category to look up (enum ih_category)
+ * @id: entry id to be translated
+ *
+ * This will scan the translation table trying to find the entry that matches
+ * the given id.
+ *
+ * @retur long entry name if translation succeeds; error string on failure
+ */
+const char *genimg_get_cat_name(enum ih_category category, uint id)
+{
+       const table_entry_t *entry;
+
+       entry = get_table_entry(table_info[category].table, id);
+       if (!entry)
+               return unknown_msg(category);
+#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
+       return entry->lname;
+#else
+       return entry->lname + gd->reloc_off;
+#endif
+}
+
+/**
+ * get_cat_table_entry_short_name - translate entry id to short name
+ * @category: category to look up (enum ih_category)
+ * @id: entry id to be translated
+ *
+ * This will scan the translation table trying to find the entry that matches
+ * the given id.
+ *
+ * @retur short entry name if translation succeeds; error string on failure
+ */
+const char *genimg_get_cat_short_name(enum ih_category category, uint id)
+{
+       const table_entry_t *entry;
+
+       entry = get_table_entry(table_info[category].table, id);
+       if (!entry)
+               return unknown_msg(category);
+#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
+       return entry->sname;
+#else
+       return entry->sname + gd->reloc_off;
+#endif
+}
+
+int genimg_get_cat_count(enum ih_category category)
+{
+       return table_info[category].count;
+}
+
+const char *genimg_get_cat_desc(enum ih_category category)
+{
+       return table_info[category].desc;
+}
+
 /**
  * get_table_entry_name - translate entry id to long name
  * @table: pointer to a translation table for entries of a specific type
index 987470896c46d28c00561f5ce8f0b002862e353b..069e94d529b380e19abb3f452ab26dd39cdb2354 100644 (file)
@@ -132,7 +132,7 @@ int spl_load_simple_fit(struct spl_load_info *info, ulong sector, void *fit)
        int data_offset, data_size;
        int base_offset, align_len = ARCH_DMA_MINALIGN - 1;
        int src_sector;
-       void *dst;
+       void *dst, *src;
 
        /*
         * Figure out where the external images start. This is the base for the
@@ -206,8 +206,13 @@ int spl_load_simple_fit(struct spl_load_info *info, ulong sector, void *fit)
                return -EIO;
        debug("image: dst=%p, data_offset=%x, size=%x\n", dst, data_offset,
              data_size);
-       memcpy(dst, dst + get_aligned_image_overhead(info, data_offset),
-              data_size);
+       src = dst + get_aligned_image_overhead(info, data_offset);
+
+#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
+       board_fit_image_post_process((void **)&src, (size_t *)&data_size);
+#endif
+
+       memcpy(dst, src, data_size);
 
        /* Figure out which device tree the board wants to use */
        fdt_len = spl_fit_select_fdt(fit, images, &fdt_offset);
@@ -236,8 +241,14 @@ int spl_load_simple_fit(struct spl_load_info *info, ulong sector, void *fit)
         */
        debug("fdt: dst=%p, data_offset=%x, size=%x\n", dst, fdt_offset,
              fdt_len);
-       memcpy(load_ptr + data_size,
-              dst + get_aligned_image_overhead(info, fdt_offset), fdt_len);
+       src = dst + get_aligned_image_overhead(info, fdt_offset);
+       dst = load_ptr + data_size;
+
+#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
+       board_fit_image_post_process((void **)&src, (size_t *)&fdt_len);
+#endif
+
+       memcpy(dst, src, fdt_len);
 
        return 0;
 }
index 4856a19f0b0bb284cda090e210348ade41618f33..68dfb6c575a6b67502d9cf21657fee82de143c4b 100644 (file)
@@ -13,6 +13,7 @@ CONFIG_SPL_STACK_R=y
 CONFIG_FIT=y
 CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=1, NAND"
 CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
index e01e50482a6142b3989c94cc14b4d10d46b15fe3..01a4701dab3de9d464286bd5039730cb8c3b22a8 100644 (file)
@@ -40,4 +40,5 @@ CONFIG_USB_XHCI_DWC3=y
 CONFIG_FIT=y
 CONFIG_SPL_OF_LIBFDT=y
 CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
 CONFIG_OF_LIST="am57xx-beagle-x15"
index 0e281a5e672c4ad10beeb005e8685c52da57158d..40ab975f02b9064ec8bd8de54230ad49c080e13f 100644 (file)
@@ -5,6 +5,7 @@ CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="MAC_ADDR_IN_SPIFLASH"
 CONFIG_BOOTDELAY=3
 CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTZ=y
 CONFIG_SYS_PROMPT="U-Boot > "
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_ASKENV=y
index 6933ab5cc6f2c8838b0d208fb989497b4fd762c2..eb01f41d02e60eb01b5c7a0124e82999f1c2598b 100644 (file)
@@ -58,4 +58,5 @@ CONFIG_G_DNL_PRODUCT_NUM=0xd022
 CONFIG_FIT=y
 CONFIG_SPL_OF_LIBFDT=y
 CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
 CONFIG_OF_LIST="dra7-evm dra72-evm"
index 7fc9b9bc30fa34ca5c3781eb8b0f7b26ef1f90f8..54c996d8f6ad0969e275248083a7d189f558d4db 100644 (file)
@@ -19,69 +19,80 @@ control restrictions. Access must be requested and granted by TI before the
 package is viewable and downloadable. Contact TI, either online or by way
 of a local TI representative, to request access.
 
-When CONFIG_TI_SECURE_DEVICE is set, the U-Boot SPL build process requires
-the presence and use of these tools in order to create a viable boot image.
-The build process will look for the environment variable TI_SECURE_DEV_PKG,
-which should be the path of the installed SECDEV package. If the
-TI_SECURE_DEV_PKG variable is not defined or if it is defined but doesn't
-point to a valid SECDEV package, a warning is issued during the build to
-indicate that a final secure bootable image was not created.
-
-Within the SECDEV package exists an image creation script:
-
-${TI_SECURE_DEV_PKG}/scripts/create-boot-image.sh
-
-This is called as part of the SPL/u-boot build process. As the secure boot
-image formats and requirements differ between secure SOC from TI, the
-purpose of this script is to abstract these details as much as possible.
-
-The script is basically the only required interface to the TI SECDEV package
-for secure TI devices.
-
-Invoking the script for AM43xx Secure Devices
-=============================================
-
-create-boot-image.sh <IMAGE_FLAG> <INPUT_FILE> <OUTPUT_FILE> <SPL_LOAD_ADDR>
-
-<IMAGE_FLAG> is a value that specifies the type of the image to generate OR
-the action the image generation tool will take. Valid values are:
-       SPI_X-LOADER - Generates an image for SPI flash (byte swapped)
-       XIP_X-LOADER - Generates a single stage u-boot for NOR/QSPI XiP
-       ISSW - Generates an image for all other boot modes
-
-<INPUT_FILE> is the full path and filename of the public world boot loader
-binary file (depending on the boot media, this is usually either
-u-boot-spl.bin or u-boot.bin).
-
-<OUTPUT_FILE> is the full path and filename of the final secure image. The
-output binary images should be used in place of the standard non-secure
-binary images (see the platform-specific user's guides and releases notes
-for how the non-secure images are typically used)
+Booting of U-Boot SPL
+=====================
+
+       When CONFIG_TI_SECURE_DEVICE is set, the U-Boot SPL build process
+       requires the presence and use of these tools in order to create a
+       viable boot image. The build process will look for the environment
+       variable TI_SECURE_DEV_PKG, which should be the path of the installed
+       SECDEV package. If the TI_SECURE_DEV_PKG variable is not defined or
+       if it is defined but doesn't point to a valid SECDEV package, a
+       warning is issued during the build to indicate that a final secure
+       bootable image was not created.
+
+       Within the SECDEV package exists an image creation script:
+
+       ${TI_SECURE_DEV_PKG}/scripts/create-boot-image.sh
+
+       This is called as part of the SPL/u-boot build process. As the secure
+       boot image formats and requirements differ between secure SOC from TI,
+       the purpose of this script is to abstract these details as much as
+       possible.
+
+       The script is basically the only required interface to the TI SECDEV
+       package for creating a bootable SPL image for secure TI devices.
+
+       Invoking the script for AM43xx Secure Devices
+       =============================================
+
+       create-boot-image.sh \
+               <IMAGE_FLAG> <INPUT_FILE> <OUTPUT_FILE> <SPL_LOAD_ADDR>
+
+       <IMAGE_FLAG> is a value that specifies the type of the image to
+       generate OR the action the image generation tool will take. Valid
+       values are:
+               SPI_X-LOADER - Generates an image for SPI flash (byte
+                       swapped)
+               XIP_X-LOADER - Generates a single stage u-boot for
+                       NOR/QSPI XiP
+               ISSW - Generates an image for all other boot modes
+
+       <INPUT_FILE> is the full path and filename of the public world boot
+       loaderbinary file (depending on the boot media, this is usually
+       either u-boot-spl.bin or u-boot.bin).
+
+       <OUTPUT_FILE> is the full path and filename of the final secure
+       image. The output binary images should be used in place of the standard
+       non-secure binary images (see the platform-specific user's guides and
+       releases notes for how the non-secure images are typically used)
        u-boot-spl_HS_SPI_X-LOADER - byte swapped boot image for SPI flash
        u-boot_HS_XIP_X-LOADER - boot image for NOR or QSPI flash
        u-boot-spl_HS_ISSW - boot image for all other boot media
 
-<SPL_LOAD_ADDR> is the address at which SOC ROM should load the <INPUT_FILE>
+       <SPL_LOAD_ADDR> is the address at which SOC ROM should load the
+       <INPUT_FILE>
 
-Invoking the script for DRA7xx/AM57xx Secure Devices
-====================================================
+       Invoking the script for DRA7xx/AM57xx Secure Devices
+       ====================================================
 
-create-boot-image.sh <IMAGE_TYPE> <INPUT_FILE> <OUTPUT_FILE>
+       create-boot-image.sh <IMAGE_TYPE> <INPUT_FILE> <OUTPUT_FILE>
 
-<IMAGE_TYPE> is a value that specifies the type of the image to generate OR
-the action the image generation tool will take. Valid values are:
-       X-LOADER - Generates an image for NOR or QSPI boot modes
-       MLO - Generates an image for SD/MMC/eMMC boot modes
-       ULO - Generates an image for USB/UART peripheral boot modes
-       Note: ULO is not yet used by the u-boot build process
+       <IMAGE_TYPE> is a value that specifies the type of the image to
+       generate OR the action the image generation tool will take. Valid
+       values are:
+               X-LOADER - Generates an image for NOR or QSPI boot modes
+               MLO - Generates an image for SD/MMC/eMMC boot modes
+               ULO - Generates an image for USB/UART peripheral boot modes
+               Note: ULO is not yet used by the u-boot build process
 
-<INPUT_FILE> is the full path and filename of the public world boot loader
-binary file (for this platform, this is always u-boot-spl.bin).
+       <INPUT_FILE> is the full path and filename of the public world boot
+       loader binary file (for this platform, this is always u-boot-spl.bin).
 
-<OUTPUT_FILE> is the full path and filename of the final secure image. The
-output binary images should be used in place of the standard non-secure
-binary images (see the platform-specific user's guides and releases notes
-for how the non-secure images are typically used)
+       <OUTPUT_FILE> is the full path and filename of the final secure image.
+       The output binary images should be used in place of the standard
+       non-secure binary images (see the platform-specific user's guides
+       and releases notes for how the non-secure images are typically used)
        u-boot-spl_HS_MLO - boot image for SD/MMC/eMMC. This image is
                copied to a file named MLO, which is the name that
                the device ROM bootloader requires for loading from
@@ -89,3 +100,61 @@ for how the non-secure images are typically used)
                non-secure devices)
        u-boot-spl_HS_X-LOADER - boot image for all other flash memories
                including QSPI and NOR flash
+
+Booting of Primary U-Boot (u-boot.img)
+======================================
+
+       The SPL image is responsible for loading the next stage boot loader,
+       which is the main u-boot image. For secure TI devices, the SPL will
+       be authenticated, as described above, as part of the particular
+       device's ROM boot process. In order to continue the secure boot
+       process, the authenticated SPL must authenticate the main u-boot
+       image that it loads.
+
+       The configurations for secure TI platforms are written to make the boot
+       process use the FIT image format for the u-boot.img (CONFIG_SPL_FRAMEWORK
+       and CONFIG_SPL_LOAD_FIT). With these configurations the binary
+       components that the SPL loads include a specific DTB image and u-boot
+       image. These DTB image may be one of many available to the boot
+       process. In order to secure these components so that they can be
+       authenticated by the SPL as they are loaded from the FIT image, the
+       build procedure for secure TI devices will secure these images before
+       they are integrated into the FIT image. When those images are extracted
+       from the FIT image at boot time, they are post-processed to verify that
+       they are still secure. The outlined security-related SPL post-processing
+       is enabled through the CONFIG_SPL_FIT_IMAGE_POST_PROCESS option which
+       must be enabled for the secure boot scheme to work. In order to allow
+       verifying proper operation of the secure boot chain in case of successful
+       authentication messages like "Authentication passed: CERT_U-BOOT-NOD" are
+       output by the SPL to the console for each blob that got extracted from the
+       FIT image. Note that the last part of this log message is the (truncated)
+       name of the signing certificate embedded into the blob that got processed.
+
+       The exact details of the how the images are secured is handled by the
+       SECDEV package. Within the SECDEV package exists a script to process
+       an input binary image:
+
+       ${TI_SECURE_DEV_PKG}/scripts/secure-binary-image.sh
+
+       This is called as part of the u-boot build process. As the secure
+       image formats and requirements can differ between the various secure
+       SOCs from TI, this script in the SECDEV package abstracts these
+       details. This script is essentially the only required interface to the
+       TI SECDEV package for creating a u-boot.img image for secure TI
+       devices.
+
+       The SPL/u-boot code contains calls to dedicated secure ROM functions
+       to perform the validation on the secured images. The details of the
+       interface to those functions is shown in the code. The summary
+       is that they are accessed by invoking an ARM secure monitor call to
+       the device's secure ROM (fixed read-only-memory that is secure and
+       only accessible when the ARM core is operating in the secure mode).
+
+       Invoking the secure-binary-image script for Secure Devices
+       ==========================================================
+
+       secure-binary-image.sh <INPUT_FILE> <OUTPUT_FILE>
+
+       <INPUT_FILE> is the full path and filename of the input binary image
+
+       <OUTPUT_FILE> is the full path and filename of the output secure image.
index 8c643a0b460c81afe4aeb9113bb020d16033aa68..bfa2e1378e22467cbe9c9049a868f7567ef46eee 100644 (file)
@@ -5,10 +5,6 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-/*
- * Date & Time support for Philips PCF8563 RTC
- */
-
 #include <common.h>
 #include <command.h>
 #include <errno.h>
@@ -28,53 +24,52 @@ static int month_days[12] = {
        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
 };
 
+static int month_offset[] = {
+       0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+};
+
 /*
  * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
  */
 int rtc_calc_weekday(struct rtc_time *tm)
 {
-       int leapsToDate;
-       int lastYear;
+       int leaps_to_date;
+       int last_year;
        int day;
-       int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
 
        if (tm->tm_year < 1753)
-               return -EINVAL;
-       lastYear=tm->tm_year-1;
+               return -1;
+       last_year = tm->tm_year - 1;
 
-       /*
-        * Number of leap corrections to apply up to end of last year
-        */
-       leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+       /* Number of leap corrections to apply up to end of last year */
+       leaps_to_date = last_year / 4 - last_year / 100 + last_year / 400;
 
        /*
         * This year is a leap year if it is divisible by 4 except when it is
         * divisible by 100 unless it is divisible by 400
         *
-        * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+        * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 is.
         */
-       if((tm->tm_year%4==0) &&
-          ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
-          (tm->tm_mon>2)) {
-               /*
-                * We are past Feb. 29 in a leap year
-                */
-               day=1;
+       if (tm->tm_year % 4 == 0 &&
+           ((tm->tm_year % 100 != 0) || (tm->tm_year % 400 == 0)) &&
+           tm->tm_mon > 2) {
+               /* We are past Feb. 29 in a leap year */
+               day = 1;
        } else {
-               day=0;
+               day = 0;
        }
 
-       day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday;
-
-       tm->tm_wday=day%7;
+       day += last_year * 365 + leaps_to_date + month_offset[tm->tm_mon - 1] +
+                       tm->tm_mday;
+       tm->tm_wday = day % 7;
 
        return 0;
 }
 
 int rtc_to_tm(int tim, struct rtc_time *tm)
 {
-       register int    i;
-       register long   hms, day;
+       register int i;
+       register long hms, day;
 
        day = tim / SECDAY;
        hms = tim % SECDAY;
@@ -85,22 +80,19 @@ int rtc_to_tm(int tim, struct rtc_time *tm)
        tm->tm_sec = (hms % 3600) % 60;
 
        /* Number of years in days */
-       for (i = STARTOFTIME; day >= days_in_year(i); i++) {
+       for (i = STARTOFTIME; day >= days_in_year(i); i++)
                day -= days_in_year(i);
-       }
        tm->tm_year = i;
 
        /* Number of months in days left */
-       if (leapyear(tm->tm_year)) {
+       if (leapyear(tm->tm_year))
                days_in_month(FEBRUARY) = 29;
-       }
-       for (i = 1; day >= days_in_month(i); i++) {
+       for (i = 1; day >= days_in_month(i); i++)
                day -= days_in_month(i);
-       }
        days_in_month(FEBRUARY) = 28;
        tm->tm_mon = i;
 
-       /* Days are what is left over (+1) from all that. */
+       /* Days are what is left over (+1) from all that */
        tm->tm_mday = day + 1;
 
        /* Zero unused fields */
@@ -113,19 +105,20 @@ int rtc_to_tm(int tim, struct rtc_time *tm)
        return rtc_calc_weekday(tm);
 }
 
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+/*
+ * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
  * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
  *
  * [For the Julian calendar (which was used in Russia before 1917,
  * Britain & colonies before 1752, anywhere else before 1582,
  * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
+ * -year / 100 + year / 400 terms, and add 10.]
  *
  * This algorithm was first published by Gauss (I think).
  *
  * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
+ * machines where long is 32-bit! (However, as time_t is signed, we
  * will already get problems at other places on 2038-01-19 03:14:08)
  */
 unsigned long rtc_mktime(const struct rtc_time *tm)
@@ -135,8 +128,8 @@ unsigned long rtc_mktime(const struct rtc_time *tm)
        int days, hours;
 
        mon -= 2;
-       if (0 >= (int)mon) {    /* 1..12 -> 11,12,1..10 */
-               mon += 12;              /* Puts Feb last since it has leap day */
+       if (0 >= (int)mon) {    /* 1..12 -> 11, 12, 1..10 */
+               mon += 12;      /* Puts Feb last since it has leap day */
                year -= 1;
        }
 
index cfbfab7e414ffc6106bed56febe44b226cff30d1..592c0bde3680006786bafde2f8df8f4faf22298c 100644 (file)
@@ -9,6 +9,7 @@
 #include <dm.h>
 #include <asm/io.h>
 #include <serial.h>
+#include <asm/arch/stm32.h>
 #include <dm/platform_data/serial_stm32x7.h>
 #include "serial_stm32x7.h"
 
@@ -18,7 +19,20 @@ static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
 {
        struct stm32x7_serial_platdata *plat = dev->platdata;
        struct stm32_usart *const usart = plat->base;
-       writel(plat->clock/baudrate, &usart->brr);
+       u32  clock, int_div, frac_div, tmp;
+
+       if (((u32)usart & STM32_BUS_MASK) == APB1_PERIPH_BASE)
+               clock = clock_get(CLOCK_APB1);
+       else if (((u32)usart & STM32_BUS_MASK) == APB2_PERIPH_BASE)
+               clock = clock_get(CLOCK_APB2);
+       else
+               return -EINVAL;
+
+       int_div = (25 * clock) / (4 * baudrate);
+       tmp = ((int_div / 100) << USART_BRR_M_SHIFT) & USART_BRR_M_MASK;
+       frac_div = int_div - (100 * (tmp >> USART_BRR_M_SHIFT));
+       tmp |= (((frac_div * 16) + 50) / 100) & USART_BRR_F_MASK;
+       writel(tmp, &usart->brr);
 
        return 0;
 }
index 3feaae641c797d5802319969fa309298e4ff2b90..e9f0dea3084212eaa836306e97496565d1b617ef 100644 (file)
@@ -101,6 +101,13 @@ typedef volatile unsigned char     vu_char;
 #define _DEBUG 0
 #endif
 
+#ifdef CONFIG_SPL_BUILD
+#define _SPL_BUILD     1
+#else
+#define _SPL_BUILD     0
+#endif
+
+/* Define this at the top of a file to add a prefix to debug messages */
 #ifndef pr_fmt
 #define pr_fmt(fmt) fmt
 #endif
@@ -116,9 +123,14 @@ typedef volatile unsigned char     vu_char;
                        printf(pr_fmt(fmt), ##args);    \
        } while (0)
 
+/* Show a message if DEBUG is defined in a file */
 #define debug(fmt, args...)                    \
        debug_cond(_DEBUG, fmt, ##args)
 
+/* Show a message if not in SPL */
+#define warn_non_spl(fmt, args...)                     \
+       debug_cond(!_SPL_BUILD, fmt, ##args)
+
 /*
  * An assertion is run-time check done in debug mode only. If DEBUG is not
  * defined then it is skipped. If DEBUG is defined and the assertion fails,
index 4b009223b2f5567c065ac7fdc761d520045fdf7f..1dbe2194f86c55ef52ae9f5f8a754a712fda7c08 100644 (file)
@@ -84,8 +84,8 @@
 
 #define BOOT_TARGET_DEVICES(func) \
        func(USB, usb, 0) \
-       func(MMC, mmc, 0) \
        func(MMC, mmc, 1) \
+       func(MMC, mmc, 0) \
        func(DHCP, dhcp, na)
 
 #include <config_distro_bootcmd.h>
@@ -126,6 +126,8 @@ REFLASH(dragonboard/u-boot.img, 8)\
        "fdtfile=apq8016-sbc.dtb\0" \
        "fdt_addr_r=0x83000000\0"\
        "ramdisk_addr_r=0x84000000\0"\
+       "scriptaddr=0x90000000\0"\
+       "pxefile_addr_r=0x90100000\0"\
        BOOTENV
 
 #define CONFIG_ENV_IS_NOWHERE
index e544a218dd75b23e551bcddfaebbf2317fdc36d6..4391bff1cc8725cece7b76196a2487cb2949a4a0 100644 (file)
  * Configuration of the external SDRAM memory
  */
 #define CONFIG_NR_DRAM_BANKS           1
-#define CONFIG_SYS_RAM_SIZE            ((64 + 192) << 10)
+#define CONFIG_SYS_RAM_SIZE            (8 * 1024 * 1024)
 #define CONFIG_SYS_RAM_CS              1
 #define CONFIG_SYS_RAM_FREQ_DIV                2
-#define CONFIG_SYS_RAM_BASE            0x20000000
+#define CONFIG_SYS_RAM_BASE            0xC0000000
 #define CONFIG_SYS_SDRAM_BASE          CONFIG_SYS_RAM_BASE
-#define CONFIG_SYS_LOAD_ADDR           0x20000000
-#define CONFIG_LOADADDR                        0x20000000
+#define CONFIG_SYS_LOAD_ADDR           0xC0400000
+#define CONFIG_LOADADDR                        0xC0400000
 
 #define CONFIG_SYS_MAX_FLASH_SECT      8
 #define CONFIG_SYS_MAX_FLASH_BANKS     1
@@ -42,7 +42,8 @@
 #define CONFIG_STM32_FLASH
 #define CONFIG_STM32X7_SERIAL
 
-#define CONFIG_SYS_CLK_FREQ            16*1000*1000 /* 180 MHz */
+#define CONFIG_STM32_HSE_HZ            25000000
+#define CONFIG_SYS_CLK_FREQ            200000000 /* 200 MHz */
 #define CONFIG_SYS_HZ_CLOCK            1000000 /* Timer is clocked at 1MHz */
 
 #define CONFIG_CMDLINE_TAG
index d788c260e30aeebd345bd65fb7144d1cf5c8cdb8..2a5b5605756e7bfb556cd7d9862936b6ea33d02d 100644 (file)
@@ -123,62 +123,79 @@ struct lmb;
 # define IMAGE_OF_SYSTEM_SETUP 0
 #endif
 
+enum ih_category {
+       IH_ARCH,
+       IH_COMP,
+       IH_OS,
+       IH_TYPE,
+
+       IH_COUNT,
+};
+
 /*
  * Operating System Codes
  */
-#define IH_OS_INVALID          0       /* Invalid OS   */
-#define IH_OS_OPENBSD          1       /* OpenBSD      */
-#define IH_OS_NETBSD           2       /* NetBSD       */
-#define IH_OS_FREEBSD          3       /* FreeBSD      */
-#define IH_OS_4_4BSD           4       /* 4.4BSD       */
-#define IH_OS_LINUX            5       /* Linux        */
-#define IH_OS_SVR4             6       /* SVR4         */
-#define IH_OS_ESIX             7       /* Esix         */
-#define IH_OS_SOLARIS          8       /* Solaris      */
-#define IH_OS_IRIX             9       /* Irix         */
-#define IH_OS_SCO              10      /* SCO          */
-#define IH_OS_DELL             11      /* Dell         */
-#define IH_OS_NCR              12      /* NCR          */
-#define IH_OS_LYNXOS           13      /* LynxOS       */
-#define IH_OS_VXWORKS          14      /* VxWorks      */
-#define IH_OS_PSOS             15      /* pSOS         */
-#define IH_OS_QNX              16      /* QNX          */
-#define IH_OS_U_BOOT           17      /* Firmware     */
-#define IH_OS_RTEMS            18      /* RTEMS        */
-#define IH_OS_ARTOS            19      /* ARTOS        */
-#define IH_OS_UNITY            20      /* Unity OS     */
-#define IH_OS_INTEGRITY                21      /* INTEGRITY    */
-#define IH_OS_OSE              22      /* OSE          */
-#define IH_OS_PLAN9            23      /* Plan 9       */
-#define IH_OS_OPENRTOS         24      /* OpenRTOS     */
+enum {
+       IH_OS_INVALID           = 0,    /* Invalid OS   */
+       IH_OS_OPENBSD,                  /* OpenBSD      */
+       IH_OS_NETBSD,                   /* NetBSD       */
+       IH_OS_FREEBSD,                  /* FreeBSD      */
+       IH_OS_4_4BSD,                   /* 4.4BSD       */
+       IH_OS_LINUX,                    /* Linux        */
+       IH_OS_SVR4,                     /* SVR4         */
+       IH_OS_ESIX,                     /* Esix         */
+       IH_OS_SOLARIS,                  /* Solaris      */
+       IH_OS_IRIX,                     /* Irix         */
+       IH_OS_SCO,                      /* SCO          */
+       IH_OS_DELL,                     /* Dell         */
+       IH_OS_NCR,                      /* NCR          */
+       IH_OS_LYNXOS,                   /* LynxOS       */
+       IH_OS_VXWORKS,                  /* VxWorks      */
+       IH_OS_PSOS,                     /* pSOS         */
+       IH_OS_QNX,                      /* QNX          */
+       IH_OS_U_BOOT,                   /* Firmware     */
+       IH_OS_RTEMS,                    /* RTEMS        */
+       IH_OS_ARTOS,                    /* ARTOS        */
+       IH_OS_UNITY,                    /* Unity OS     */
+       IH_OS_INTEGRITY,                /* INTEGRITY    */
+       IH_OS_OSE,                      /* OSE          */
+       IH_OS_PLAN9,                    /* Plan 9       */
+       IH_OS_OPENRTOS,         /* OpenRTOS     */
+
+       IH_OS_COUNT,
+};
 
 /*
  * CPU Architecture Codes (supported by Linux)
  */
-#define IH_ARCH_INVALID                0       /* Invalid CPU  */
-#define IH_ARCH_ALPHA          1       /* Alpha        */
-#define IH_ARCH_ARM            2       /* ARM          */
-#define IH_ARCH_I386           3       /* Intel x86    */
-#define IH_ARCH_IA64           4       /* IA64         */
-#define IH_ARCH_MIPS           5       /* MIPS         */
-#define IH_ARCH_MIPS64         6       /* MIPS  64 Bit */
-#define IH_ARCH_PPC            7       /* PowerPC      */
-#define IH_ARCH_S390           8       /* IBM S390     */
-#define IH_ARCH_SH             9       /* SuperH       */
-#define IH_ARCH_SPARC          10      /* Sparc        */
-#define IH_ARCH_SPARC64                11      /* Sparc 64 Bit */
-#define IH_ARCH_M68K           12      /* M68K         */
-#define IH_ARCH_MICROBLAZE     14      /* MicroBlaze   */
-#define IH_ARCH_NIOS2          15      /* Nios-II      */
-#define IH_ARCH_BLACKFIN       16      /* Blackfin     */
-#define IH_ARCH_AVR32          17      /* AVR32        */
-#define IH_ARCH_ST200          18      /* STMicroelectronics ST200  */
-#define IH_ARCH_SANDBOX                19      /* Sandbox architecture (test only) */
-#define IH_ARCH_NDS32          20      /* ANDES Technology - NDS32  */
-#define IH_ARCH_OPENRISC        21     /* OpenRISC 1000  */
-#define IH_ARCH_ARM64          22      /* ARM64        */
-#define IH_ARCH_ARC            23      /* Synopsys DesignWare ARC */
-#define IH_ARCH_X86_64         24      /* AMD x86_64, Intel and Via */
+enum {
+       IH_ARCH_INVALID         = 0,    /* Invalid CPU  */
+       IH_ARCH_ALPHA,                  /* Alpha        */
+       IH_ARCH_ARM,                    /* ARM          */
+       IH_ARCH_I386,                   /* Intel x86    */
+       IH_ARCH_IA64,                   /* IA64         */
+       IH_ARCH_MIPS,                   /* MIPS         */
+       IH_ARCH_MIPS64,                 /* MIPS  64 Bit */
+       IH_ARCH_PPC,                    /* PowerPC      */
+       IH_ARCH_S390,                   /* IBM S390     */
+       IH_ARCH_SH,                     /* SuperH       */
+       IH_ARCH_SPARC,                  /* Sparc        */
+       IH_ARCH_SPARC64,                /* Sparc 64 Bit */
+       IH_ARCH_M68K,                   /* M68K         */
+       IH_ARCH_MICROBLAZE,             /* MicroBlaze   */
+       IH_ARCH_NIOS2,                  /* Nios-II      */
+       IH_ARCH_BLACKFIN,               /* Blackfin     */
+       IH_ARCH_AVR32,                  /* AVR32        */
+       IH_ARCH_ST200,                  /* STMicroelectronics ST200  */
+       IH_ARCH_SANDBOX,                /* Sandbox architecture (test only) */
+       IH_ARCH_NDS32,                  /* ANDES Technology - NDS32  */
+       IH_ARCH_OPENRISC,               /* OpenRISC 1000  */
+       IH_ARCH_ARM64,                  /* ARM64        */
+       IH_ARCH_ARC,                    /* Synopsys DesignWare ARC */
+       IH_ARCH_X86_64,                 /* AMD x86_64, Intel and Via */
+
+       IH_ARCH_COUNT,
+};
 
 /*
  * Image Types
@@ -219,47 +236,54 @@ struct lmb;
  *     as command interpreter (=> Shell Scripts).
  */
 
-#define IH_TYPE_INVALID                0       /* Invalid Image                */
-#define IH_TYPE_STANDALONE     1       /* Standalone Program           */
-#define IH_TYPE_KERNEL         2       /* OS Kernel Image              */
-#define IH_TYPE_RAMDISK                3       /* RAMDisk Image                */
-#define IH_TYPE_MULTI          4       /* Multi-File Image             */
-#define IH_TYPE_FIRMWARE       5       /* Firmware Image               */
-#define IH_TYPE_SCRIPT         6       /* Script file                  */
-#define IH_TYPE_FILESYSTEM     7       /* Filesystem Image (any type)  */
-#define IH_TYPE_FLATDT         8       /* Binary Flat Device Tree Blob */
-#define IH_TYPE_KWBIMAGE       9       /* Kirkwood Boot Image          */
-#define IH_TYPE_IMXIMAGE       10      /* Freescale IMXBoot Image      */
-#define IH_TYPE_UBLIMAGE       11      /* Davinci UBL Image            */
-#define IH_TYPE_OMAPIMAGE      12      /* TI OMAP Config Header Image  */
-#define IH_TYPE_AISIMAGE       13      /* TI Davinci AIS Image         */
-#define IH_TYPE_KERNEL_NOLOAD  14      /* OS Kernel Image, can run from any load address */
-#define IH_TYPE_PBLIMAGE       15      /* Freescale PBL Boot Image     */
-#define IH_TYPE_MXSIMAGE       16      /* Freescale MXSBoot Image      */
-#define IH_TYPE_GPIMAGE                17      /* TI Keystone GPHeader Image   */
-#define IH_TYPE_ATMELIMAGE     18      /* ATMEL ROM bootable Image     */
-#define IH_TYPE_SOCFPGAIMAGE   19      /* Altera SOCFPGA Preloader     */
-#define IH_TYPE_X86_SETUP      20      /* x86 setup.bin Image          */
-#define IH_TYPE_LPC32XXIMAGE   21      /* x86 setup.bin Image          */
-#define IH_TYPE_LOADABLE       22      /* A list of typeless images    */
-#define IH_TYPE_RKIMAGE                23      /* Rockchip Boot Image          */
-#define IH_TYPE_RKSD           24      /* Rockchip SD card             */
-#define IH_TYPE_RKSPI          25      /* Rockchip SPI image           */
-#define IH_TYPE_ZYNQIMAGE      26      /* Xilinx Zynq Boot Image */
-#define IH_TYPE_ZYNQMPIMAGE    27      /* Xilinx ZynqMP Boot Image */
-#define IH_TYPE_FPGA           28      /* FPGA Image */
-
-#define IH_TYPE_COUNT          29      /* Number of image types */
+enum {
+       IH_TYPE_INVALID         = 0,    /* Invalid Image                */
+       IH_TYPE_STANDALONE,             /* Standalone Program           */
+       IH_TYPE_KERNEL,                 /* OS Kernel Image              */
+       IH_TYPE_RAMDISK,                /* RAMDisk Image                */
+       IH_TYPE_MULTI,                  /* Multi-File Image             */
+       IH_TYPE_FIRMWARE,               /* Firmware Image               */
+       IH_TYPE_SCRIPT,                 /* Script file                  */
+       IH_TYPE_FILESYSTEM,             /* Filesystem Image (any type)  */
+       IH_TYPE_FLATDT,                 /* Binary Flat Device Tree Blob */
+       IH_TYPE_KWBIMAGE,               /* Kirkwood Boot Image          */
+       IH_TYPE_IMXIMAGE,               /* Freescale IMXBoot Image      */
+       IH_TYPE_UBLIMAGE,               /* Davinci UBL Image            */
+       IH_TYPE_OMAPIMAGE,              /* TI OMAP Config Header Image  */
+       IH_TYPE_AISIMAGE,               /* TI Davinci AIS Image         */
+       /* OS Kernel Image, can run from any load address */
+       IH_TYPE_KERNEL_NOLOAD,
+       IH_TYPE_PBLIMAGE,               /* Freescale PBL Boot Image     */
+       IH_TYPE_MXSIMAGE,               /* Freescale MXSBoot Image      */
+       IH_TYPE_GPIMAGE,                /* TI Keystone GPHeader Image   */
+       IH_TYPE_ATMELIMAGE,             /* ATMEL ROM bootable Image     */
+       IH_TYPE_SOCFPGAIMAGE,           /* Altera SOCFPGA Preloader     */
+       IH_TYPE_X86_SETUP,              /* x86 setup.bin Image          */
+       IH_TYPE_LPC32XXIMAGE,           /* x86 setup.bin Image          */
+       IH_TYPE_LOADABLE,               /* A list of typeless images    */
+       IH_TYPE_RKIMAGE,                /* Rockchip Boot Image          */
+       IH_TYPE_RKSD,                   /* Rockchip SD card             */
+       IH_TYPE_RKSPI,                  /* Rockchip SPI image           */
+       IH_TYPE_ZYNQIMAGE,              /* Xilinx Zynq Boot Image */
+       IH_TYPE_ZYNQMPIMAGE,            /* Xilinx ZynqMP Boot Image */
+       IH_TYPE_FPGA,                   /* FPGA Image */
+
+       IH_TYPE_COUNT,                  /* Number of image types */
+};
 
 /*
  * Compression Types
  */
-#define IH_COMP_NONE           0       /*  No   Compression Used       */
-#define IH_COMP_GZIP           1       /* gzip  Compression Used       */
-#define IH_COMP_BZIP2          2       /* bzip2 Compression Used       */
-#define IH_COMP_LZMA           3       /* lzma  Compression Used       */
-#define IH_COMP_LZO            4       /* lzo   Compression Used       */
-#define IH_COMP_LZ4            5       /* lz4   Compression Used       */
+enum {
+       IH_COMP_NONE            = 0,    /*  No   Compression Used       */
+       IH_COMP_GZIP,                   /* gzip  Compression Used       */
+       IH_COMP_BZIP2,                  /* bzip2 Compression Used       */
+       IH_COMP_LZMA,                   /* lzma  Compression Used       */
+       IH_COMP_LZO,                    /* lzo   Compression Used       */
+       IH_COMP_LZ4,                    /* lz4   Compression Used       */
+
+       IH_COMP_COUNT,
+};
 
 #define IH_MAGIC       0x27051956      /* Image Magic Number           */
 #define IH_NMLEN               32      /* Image Name Length            */
@@ -454,6 +478,40 @@ const char *genimg_get_comp_name(uint8_t comp);
  */
 const char *genimg_get_comp_short_name(uint8_t comp);
 
+/**
+ * genimg_get_cat_name() - Get the name of an item in a category
+ *
+ * @category:  Category of item
+ * @id:                Item ID
+ * @return name of item, or "Unknown ..." if unknown
+ */
+const char *genimg_get_cat_name(enum ih_category category, uint id);
+
+/**
+ * genimg_get_cat_short_name() - Get the short name of an item in a category
+ *
+ * @category:  Category of item
+ * @id:                Item ID
+ * @return short name of item, or "Unknown ..." if unknown
+ */
+const char *genimg_get_cat_short_name(enum ih_category category, uint id);
+
+/**
+ * genimg_get_cat_count() - Get the number of items in a category
+ *
+ * @category:  Category to check
+ * @return the number of items in the category (IH_xxx_COUNT)
+ */
+int genimg_get_cat_count(enum ih_category category);
+
+/**
+ * genimg_get_cat_desc() - Get the description of a category
+ *
+ * @return the description of a category, e.g. "architecture". This
+ * effectively converts the enum to a string.
+ */
+const char *genimg_get_cat_desc(enum ih_category category);
+
 int genimg_get_os_id(const char *name);
 int genimg_get_arch_id(const char *name);
 int genimg_get_type_id(const char *name);
@@ -1173,4 +1231,21 @@ void android_print_contents(const struct andr_img_hdr *hdr);
  */
 int board_fit_config_name_match(const char *name);
 
+#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
+/**
+ * board_fit_image_post_process() - Do any post-process on FIT binary data
+ *
+ * This is used to do any sort of image manipulation, verification, decryption
+ * etc. in a platform or board specific way. Obviously, anything done here would
+ * need to be comprehended in how the images were prepared before being injected
+ * into the FIT creation (i.e. the binary blobs would have been pre-processed
+ * before being added to the FIT image).
+ *
+ * @image: pointer to the image start pointer
+ * @size: pointer to the image size
+ * @return no return value (failure should be handled internally)
+ */
+void board_fit_image_post_process(void **p_image, size_t *p_size);
+#endif /* CONFIG_SPL_FIT_IMAGE_POST_PROCESS */
+
 #endif /* __IMAGE_H__ */
index 1b36a2299e1b095f298e550242207f5141852fde..a104b7e69f7c871d267f7a541683b831aed3a071 100644 (file)
@@ -5,6 +5,22 @@
 #ifndef _LINUX_IO_H
 #define _LINUX_IO_H
 
+#include <linux/compiler.h>
+#include <linux/types.h>
 #include <asm/io.h>
 
+#ifndef CONFIG_HAVE_ARCH_IOREMAP
+static inline void __iomem *ioremap(resource_size_t offset,
+                                   resource_size_t size)
+{
+       return (void __iomem *)(unsigned long)offset;
+}
+
+static inline void iounmap(void __iomem *addr)
+{
+}
+
+#define devm_ioremap(dev, offset, size)                ioremap(offset, size)
+#endif
+
 #endif /* _LINUX_IO_H */
index 6f75be4253786888b7717febfadc74a22afb29d3..416fa6628482d8cb5afa356df2f3e34f2411fa8d 100644 (file)
@@ -124,6 +124,10 @@ typedef            __UINT64_TYPE__ u_int64_t;
 typedef                __INT64_TYPE__          int64_t;
 #endif
 
+#ifdef __KERNEL__
+typedef phys_addr_t resource_size_t;
+#endif
+
 /*
  * Below are truly Linux-specific types that should never collide with
  * any application/library that wants linux/types.h.
diff --git a/test/README b/test/README
new file mode 100644 (file)
index 0000000..ee55972
--- /dev/null
@@ -0,0 +1,92 @@
+Testing in U-Boot
+=================
+
+U-Boot has a large amount of code. This file describes how this code is
+tested and what tests you should write when adding a new feature.
+
+
+Running tests
+-------------
+
+To run most tests on sandbox, type this:
+
+    test/run
+
+in the U-Boot directory. Note that only the pytest suite is run using this
+comment.
+
+
+Sandbox
+-------
+U-Boot can be built as a user-space application (e.g. for Linux). This
+allows test to be executed without needing target hardware. The 'sandbox'
+target provides this feature and it is widely used in tests.
+
+
+Pytest Suite
+------------
+
+Many tests are available using the pytest suite, in test/py. This can run
+either on sandbox or on real hardware. It relies on the U-Boot console to
+inject test commands and check the result. It is slower to run than C code,
+but provides the ability to unify lots of test and summarise their results.
+
+You can run the tests on sandbox with:
+
+       ./test/py/test.py --bd sandbox --build
+
+This will produce HTML output in build-sandbox/test-log.html
+
+See test/py/README.md for more information about the pytest suite.
+
+
+tbot
+----
+
+Tbot provides a way to execute tests on target hardware. It is intended for
+trying out both U-Boot and Linux (and potentially other software) on a
+number of boards automatically. It can be used to create a continuous test
+environment. See tools/tbot/README for more information.
+
+
+Ad-hoc tests
+------------
+
+There are several ad-hoc tests which run outside the pytest environment:
+
+   test/fs     - File system test (shell script)
+   test/image  - FIT and lagacy image tests (shell script and Python)
+   test/stdint - A test that stdint.h can be used in U-Boot (shell script)
+   trace       - Test for the tracing feature (shell script)
+
+The above should be converted to run as part of the pytest suite.
+
+
+When to write tests
+-------------------
+
+If you add code to U-Boot without a test you are taking a risk. Even if you
+perform thorough manual testing at the time of submission, it may break when
+future changes are made to U-Boot. It may even break when applied to mainline,
+if other changes interact with it. A good mindset is that untested code
+probably doesn't work and should be deleted.
+
+You can assume that the Pytest suite will be run before patches are accepted
+to mainline, so this provides protection against future breakage.
+
+On the other hand there is quite a bit of code that is not covered with tests,
+or is covered sparingly. So here are some suggestions:
+
+- If you are adding a new uclass, add a sandbox driver and a test that uses it
+- If you are modifying code covered by an existing test, add a new test case
+  to cover your changes
+- If the code you are modifying has not tests, consider writing one. Even a
+  very basic test is useful, and may be picked up and enhanced by others. It
+  is much easier to add onto a test - writing a new large test can seem
+  daunting to most contributors.
+
+
+Future work
+-----------
+
+Converting existing shell scripts into pytest tests.
index 050f6e409db99b247e1682a0d7a11214ef720578..5b3a92316bbfae2969f76fc11a61e713b649f30b 100644 (file)
@@ -179,6 +179,7 @@ def pytest_configure(config):
     ubconfig.board_type = board_type
     ubconfig.board_identity = board_identity
     ubconfig.gdbserver = gdbserver
+    ubconfig.dtb = build_dir + '/arch/sandbox/dts/test.dtb'
 
     env_vars = (
         'board_type',
index 68917eb0ea9644d4e922ebcba2a07065a6e8e7bf..35a32fb5c0514fdbd8e697680bac8e338b74edb9 100644 (file)
@@ -101,6 +101,7 @@ class RunAndLog(object):
         self.logfile = logfile
         self.name = name
         self.chained_file = chained_file
+        self.output = None
 
     def close(self):
         """Clean up any resources managed by this object."""
@@ -109,6 +110,9 @@ class RunAndLog(object):
     def run(self, cmd, cwd=None, ignore_errors=False):
         """Run a command as a sub-process, and log the results.
 
+        The output is available at self.output which can be useful if there is
+        an exception.
+
         Args:
             cmd: The command to execute.
             cwd: The directory to run the command in. Can be None to use the
@@ -119,7 +123,7 @@ class RunAndLog(object):
                 raised if such problems occur.
 
         Returns:
-            Nothing.
+            The output as a string.
         """
 
         msg = '+' + ' '.join(cmd) + '\n'
@@ -159,8 +163,12 @@ class RunAndLog(object):
         self.logfile.write(self, output)
         if self.chained_file:
             self.chained_file.write(output)
+
+        # Store the output so it can be accessed if we raise an exception.
+        self.output = output
         if exception:
             raise exception
+        return output
 
 class SectionCtxMgr(object):
     """A context manager for Python's "with" statement, which allows a certain
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
new file mode 100644 (file)
index 0000000..c779895
--- /dev/null
@@ -0,0 +1,185 @@
+# Copyright (c) 2013, Google Inc.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+# U-Boot Verified Boot Test
+
+"""
+This tests verified boot in the following ways:
+
+For image verification:
+- Create FIT (unsigned) with mkimage
+- Check that verification shows that no keys are verified
+- Sign image
+- Check that verification shows that a key is now verified
+
+For configuration verification:
+- Corrupt signature and check for failure
+- Create FIT (with unsigned configuration) with mkimage
+- Check that image veriication works
+- Sign the FIT and mark the key as 'required' for verification
+- Check that image verification works
+- Corrupt the signature
+- Check that image verification no-longer works
+
+Tests run with both SHA1 and SHA256 hashing.
+"""
+
+import pytest
+import sys
+import u_boot_utils as util
+
+@pytest.mark.buildconfigspec('fit_signature')
+def test_vboot(u_boot_console):
+    """Test verified boot signing with mkimage and verification with 'bootm'.
+
+    This works using sandbox only as it needs to update the device tree used
+    by U-Boot to hold public keys from the signing process.
+
+    The SHA1 and SHA256 tests are combined into a single test since the
+    key-generation process is quite slow and we want to avoid doing it twice.
+    """
+    def dtc(dts):
+        """Run the device-tree compiler to compile a .dts file
+
+        The output file will be the same as the input file but with a .dtb
+        extension.
+
+        Args:
+            dts: Device tree file to compile.
+        """
+        dtb = dts.replace('.dts', '.dtb')
+        util.cmd(cons, 'dtc %s %s%s -O dtb '
+                       '-o %s%s' % (dtc_args, datadir, dts, tmpdir, dtb))
+
+    def run_bootm(test_type, expect_string):
+        """Run a 'bootm' command U-Boot.
+
+        This always starts a fresh U-Boot instance since the device tree may
+        contain a new public key.
+
+        Args:
+            test_type: A string identifying the test type
+            expect_string: A string which is expected in the output
+        """
+        cons.cleanup_spawn()
+        cons.ensure_spawned()
+        cons.log.action('%s: Test Verified Boot Run: %s' % (algo, test_type))
+        output = cons.run_command_list(
+            ['sb load hostfs - 100 %stest.fit' % tmpdir,
+             'fdt addr 100',
+             'bootm 100'])
+        assert(expect_string in output)
+
+    def make_fit(its):
+        """Make a new FIT from the .its source file
+
+        This runs 'mkimage -f' to create a new FIT.
+
+        Args:
+            its: Filename containing .its source
+        """
+        util.run_and_log(cons, [mkimage, '-D', dtc_args, '-f',
+                                '%s%s' % (datadir, its), fit])
+
+    def sign_fit():
+        """Sign the FIT
+
+        Signs the FIT and writes the signature into it. It also writes the
+        public key into the dtb.
+        """
+        cons.log.action('%s: Sign images' % algo)
+        util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb,
+                                '-r', fit])
+
+    def test_with_algo(sha):
+        """Test verified boot with the given hash algorithm
+
+        This is the main part of the test code. The same procedure is followed
+        for both hashing algorithms.
+
+        Args:
+            sha: Either 'sha1' or 'sha256', to select the algorithm to use
+        """
+        global algo
+
+        algo = sha
+
+        # Compile our device tree files for kernel and U-Boot
+        dtc('sandbox-kernel.dts')
+        dtc('sandbox-u-boot.dts')
+
+        # Build the FIT, but don't sign anything yet
+        cons.log.action('%s: Test FIT with signed images' % algo)
+        make_fit('sign-images-%s.its' % algo)
+        run_bootm('unsigned images', 'dev-')
+
+        # Sign images with our dev keys
+        sign_fit()
+        run_bootm('signed images', 'dev+')
+
+        # Create a fresh .dtb without the public keys
+        dtc('sandbox-u-boot.dts')
+
+        cons.log.action('%s: Test FIT with signed configuration' % algo)
+        make_fit('sign-configs-%s.its' % algo)
+        run_bootm('unsigned config', '%s+ OK' % algo)
+
+        # Sign images with our dev keys
+        sign_fit()
+        run_bootm('signed config', 'dev+')
+
+        cons.log.action('%s: Check signed config on the host' % algo)
+
+        util.run_and_log(cons, [fit_check_sign, '-f', fit, '-k', tmpdir,
+                                '-k', dtb])
+
+        # Increment the first byte of the signature, which should cause failure
+        sig = util.cmd(cons, 'fdtget -t bx %s %s value' % (fit, sig_node))
+        byte_list = sig.split()
+        byte = int(byte_list[0], 16)
+        byte_list = ['%x' % (byte + 1)] + byte_list[1:]
+        sig = ' '.join(byte_list)
+        util.cmd(cons, 'fdtput -t bx %s %s value %s' % (fit, sig_node, sig))
+
+        run_bootm('Signed config with bad hash', 'Bad Data Hash')
+
+        cons.log.action('%s: Check bad config on the host' % algo)
+        util.run_and_log_expect_exception(cons, [fit_check_sign, '-f', fit,
+                '-k', dtb], 1, 'Failed to verify required signature')
+
+    cons = u_boot_console
+    tmpdir = cons.config.result_dir + '/'
+    tmp = tmpdir + 'vboot.tmp'
+    datadir = 'test/py/tests/vboot/'
+    fit = '%stest.fit' % tmpdir
+    mkimage = cons.config.build_dir + '/tools/mkimage'
+    fit_check_sign = cons.config.build_dir + '/tools/fit_check_sign'
+    dtc_args = '-I dts -O dtb -i %s' % tmpdir
+    dtb = '%ssandbox-u-boot.dtb' % tmpdir
+    sig_node = '/configurations/conf@1/signature@1'
+
+    # Create an RSA key pair
+    public_exponent = 65537
+    util.cmd(cons, 'openssl genpkey -algorithm RSA -out %sdev.key '
+                   '-pkeyopt rsa_keygen_bits:2048 '
+                   '-pkeyopt rsa_keygen_pubexp:%d '
+                   '2>/dev/null'  % (tmpdir, public_exponent))
+
+    # Create a certificate containing the public key
+    util.cmd(cons, 'openssl req -batch -new -x509 -key %sdev.key -out '
+                   '%sdev.crt' % (tmpdir, tmpdir))
+
+    # Create a number kernel image with zeroes
+    with open('%stest-kernel.bin' % tmpdir, 'w') as fd:
+        fd.write(5000 * chr(0))
+
+    try:
+        # We need to use our own device tree file. Remember to restore it
+        # afterwards.
+        old_dtb = cons.config.dtb
+        cons.config.dtb = dtb
+        test_with_algo('sha1')
+        test_with_algo('sha256')
+    finally:
+        cons.config.dtb = old_dtb
diff --git a/test/py/tests/vboot/sandbox-kernel.dts b/test/py/tests/vboot/sandbox-kernel.dts
new file mode 100644 (file)
index 0000000..a1e853c
--- /dev/null
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+       model = "Sandbox Verified Boot Test";
+       compatible = "sandbox";
+
+};
diff --git a/test/py/tests/vboot/sandbox-u-boot.dts b/test/py/tests/vboot/sandbox-u-boot.dts
new file mode 100644 (file)
index 0000000..63f8f40
--- /dev/null
@@ -0,0 +1,10 @@
+/dts-v1/;
+
+/ {
+       model = "Sandbox Verified Boot Test";
+       compatible = "sandbox";
+
+       reset@0 {
+               compatible = "sandbox,reset";
+       };
+};
diff --git a/test/py/tests/vboot/sign-configs-sha1.its b/test/py/tests/vboot/sign-configs-sha1.its
new file mode 100644 (file)
index 0000000..db2ed79
--- /dev/null
@@ -0,0 +1,45 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       hash@1 {
+                               algo = "sha1";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       hash@1 {
+                               algo = "sha1";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+                       signature@1 {
+                               algo = "sha1,rsa2048";
+                               key-name-hint = "dev";
+                               sign-images = "fdt", "kernel";
+                       };
+               };
+       };
+};
diff --git a/test/py/tests/vboot/sign-configs-sha256.its b/test/py/tests/vboot/sign-configs-sha256.its
new file mode 100644 (file)
index 0000000..1b3432e
--- /dev/null
@@ -0,0 +1,45 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       hash@1 {
+                               algo = "sha256";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       hash@1 {
+                               algo = "sha256";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                               sign-images = "fdt", "kernel";
+                       };
+               };
+       };
+};
diff --git a/test/py/tests/vboot/sign-images-sha1.its b/test/py/tests/vboot/sign-images-sha1.its
new file mode 100644 (file)
index 0000000..f69326a
--- /dev/null
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       signature@1 {
+                               algo = "sha1,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       signature@1 {
+                               algo = "sha1,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+               };
+       };
+};
diff --git a/test/py/tests/vboot/sign-images-sha256.its b/test/py/tests/vboot/sign-images-sha256.its
new file mode 100644 (file)
index 0000000..e6aa9fc
--- /dev/null
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+               };
+       };
+};
index 3d2ac448757d59906135ab7e644eacd7f8801be4..4606ad48bf5d49d7c90c2ade5418347f08b577bf 100644 (file)
@@ -216,6 +216,22 @@ class ConsoleBase(object):
             self.cleanup_spawn()
             raise
 
+    def run_command_list(self, cmds):
+        """Run a list of commands.
+
+        This is a helper function to call run_command() with default arguments
+        for each command in a list.
+
+        Args:
+            cmd: List of commands (each a string)
+        Returns:
+            Combined output of all commands, as a string
+        """
+        output = ''
+        for cmd in cmds:
+            output += self.run_command(cmd)
+        return output
+
     def ctrlc(self):
         """Send a CTRL-C character to U-Boot.
 
index 6bf46530833b4f8cbaff6deb549903749f0121fa..647e1f879fcadcbaf1487e6ad728597959e6f577 100644 (file)
@@ -50,7 +50,7 @@ class ConsoleSandbox(ConsoleBase):
             self.config.build_dir + fname,
             '-v',
             '-d',
-            self.config.build_dir + '/arch/sandbox/dts/test.dtb'
+            self.config.dtb
         ]
         return Spawn(cmd, cwd=self.config.source_dir)
 
index e4765e38c1474bf5122423683d92f2cbfeb5b738..e358c585bf888f71ee55d326df9126f1111d1a46 100644 (file)
@@ -165,12 +165,47 @@ def run_and_log(u_boot_console, cmd, ignore_errors=False):
             problems occur.
 
     Returns:
-        Nothing.
+        The output as a string.
     """
 
     runner = u_boot_console.log.get_runner(cmd[0], sys.stdout)
-    runner.run(cmd, ignore_errors=ignore_errors)
+    output = runner.run(cmd, ignore_errors=ignore_errors)
     runner.close()
+    return output
+
+def cmd(u_boot_console, cmd_str):
+    """Run a single command string and log its output.
+
+    Args:
+        u_boot_console: A console connection to U-Boot.
+        cmd: The command to run, as a string.
+
+    Returns:
+        The output as a string.
+    """
+    return run_and_log(u_boot_console, cmd_str.split())
+
+def run_and_log_expect_exception(u_boot_console, cmd, retcode, msg):
+    """Run a command which is expected to fail.
+
+    This runs a command and checks that it fails with the expected return code
+    and exception method. If not, an exception is raised.
+
+    Args:
+        u_boot_console: A console connection to U-Boot.
+        cmd: The command to run, as an array of argv[].
+        retcode: Expected non-zero return code from the command.
+        msg: String which should be contained within the command's output.
+    """
+    try:
+        runner = u_boot_console.log.get_runner(cmd[0], sys.stdout)
+        runner.run(cmd)
+    except Exception as e:
+        assert(msg in runner.output)
+    else:
+        raise Exception('Expected exception, but not raised')
+    finally:
+        runner.close()
 
 ram_base = None
 def find_ram_base(u_boot_console):
diff --git a/test/run b/test/run
new file mode 100755 (executable)
index 0000000..a6dcf8f
--- /dev/null
+++ b/test/run
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Run all tests
+./test/py/test.py --bd sandbox --build
diff --git a/test/vboot/.gitignore b/test/vboot/.gitignore
deleted file mode 100644 (file)
index 4631242..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/*.dtb
-/test.fit
-/dev-keys
diff --git a/test/vboot/sandbox-kernel.dts b/test/vboot/sandbox-kernel.dts
deleted file mode 100644 (file)
index a1e853c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/dts-v1/;
-
-/ {
-       model = "Sandbox Verified Boot Test";
-       compatible = "sandbox";
-
-};
diff --git a/test/vboot/sandbox-u-boot.dts b/test/vboot/sandbox-u-boot.dts
deleted file mode 100644 (file)
index 63f8f40..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/dts-v1/;
-
-/ {
-       model = "Sandbox Verified Boot Test";
-       compatible = "sandbox";
-
-       reset@0 {
-               compatible = "sandbox,reset";
-       };
-};
diff --git a/test/vboot/sign-configs-sha1.its b/test/vboot/sign-configs-sha1.its
deleted file mode 100644 (file)
index db2ed79..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/dts-v1/;
-
-/ {
-       description = "Chrome OS kernel image with one or more FDT blobs";
-       #address-cells = <1>;
-
-       images {
-               kernel@1 {
-                       data = /incbin/("test-kernel.bin");
-                       type = "kernel_noload";
-                       arch = "sandbox";
-                       os = "linux";
-                       compression = "none";
-                       load = <0x4>;
-                       entry = <0x8>;
-                       kernel-version = <1>;
-                       hash@1 {
-                               algo = "sha1";
-                       };
-               };
-               fdt@1 {
-                       description = "snow";
-                       data = /incbin/("sandbox-kernel.dtb");
-                       type = "flat_dt";
-                       arch = "sandbox";
-                       compression = "none";
-                       fdt-version = <1>;
-                       hash@1 {
-                               algo = "sha1";
-                       };
-               };
-       };
-       configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
-                       signature@1 {
-                               algo = "sha1,rsa2048";
-                               key-name-hint = "dev";
-                               sign-images = "fdt", "kernel";
-                       };
-               };
-       };
-};
diff --git a/test/vboot/sign-configs-sha256.its b/test/vboot/sign-configs-sha256.its
deleted file mode 100644 (file)
index 1b3432e..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/dts-v1/;
-
-/ {
-       description = "Chrome OS kernel image with one or more FDT blobs";
-       #address-cells = <1>;
-
-       images {
-               kernel@1 {
-                       data = /incbin/("test-kernel.bin");
-                       type = "kernel_noload";
-                       arch = "sandbox";
-                       os = "linux";
-                       compression = "none";
-                       load = <0x4>;
-                       entry = <0x8>;
-                       kernel-version = <1>;
-                       hash@1 {
-                               algo = "sha256";
-                       };
-               };
-               fdt@1 {
-                       description = "snow";
-                       data = /incbin/("sandbox-kernel.dtb");
-                       type = "flat_dt";
-                       arch = "sandbox";
-                       compression = "none";
-                       fdt-version = <1>;
-                       hash@1 {
-                               algo = "sha256";
-                       };
-               };
-       };
-       configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
-                       signature@1 {
-                               algo = "sha256,rsa2048";
-                               key-name-hint = "dev";
-                               sign-images = "fdt", "kernel";
-                       };
-               };
-       };
-};
diff --git a/test/vboot/sign-images-sha1.its b/test/vboot/sign-images-sha1.its
deleted file mode 100644 (file)
index f69326a..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/dts-v1/;
-
-/ {
-       description = "Chrome OS kernel image with one or more FDT blobs";
-       #address-cells = <1>;
-
-       images {
-               kernel@1 {
-                       data = /incbin/("test-kernel.bin");
-                       type = "kernel_noload";
-                       arch = "sandbox";
-                       os = "linux";
-                       compression = "none";
-                       load = <0x4>;
-                       entry = <0x8>;
-                       kernel-version = <1>;
-                       signature@1 {
-                               algo = "sha1,rsa2048";
-                               key-name-hint = "dev";
-                       };
-               };
-               fdt@1 {
-                       description = "snow";
-                       data = /incbin/("sandbox-kernel.dtb");
-                       type = "flat_dt";
-                       arch = "sandbox";
-                       compression = "none";
-                       fdt-version = <1>;
-                       signature@1 {
-                               algo = "sha1,rsa2048";
-                               key-name-hint = "dev";
-                       };
-               };
-       };
-       configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
-               };
-       };
-};
diff --git a/test/vboot/sign-images-sha256.its b/test/vboot/sign-images-sha256.its
deleted file mode 100644 (file)
index e6aa9fc..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/dts-v1/;
-
-/ {
-       description = "Chrome OS kernel image with one or more FDT blobs";
-       #address-cells = <1>;
-
-       images {
-               kernel@1 {
-                       data = /incbin/("test-kernel.bin");
-                       type = "kernel_noload";
-                       arch = "sandbox";
-                       os = "linux";
-                       compression = "none";
-                       load = <0x4>;
-                       entry = <0x8>;
-                       kernel-version = <1>;
-                       signature@1 {
-                               algo = "sha256,rsa2048";
-                               key-name-hint = "dev";
-                       };
-               };
-               fdt@1 {
-                       description = "snow";
-                       data = /incbin/("sandbox-kernel.dtb");
-                       type = "flat_dt";
-                       arch = "sandbox";
-                       compression = "none";
-                       fdt-version = <1>;
-                       signature@1 {
-                               algo = "sha256,rsa2048";
-                               key-name-hint = "dev";
-                       };
-               };
-       };
-       configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
-               };
-       };
-};
diff --git a/test/vboot/vboot_test.sh b/test/vboot/vboot_test.sh
deleted file mode 100755 (executable)
index 6d7abb8..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2013, Google Inc.
-#
-# Simple Verified Boot Test Script
-#
-# SPDX-License-Identifier:     GPL-2.0+
-
-set -e
-
-# Run U-Boot and report the result
-# Args:
-#      $1:     Test message
-run_uboot() {
-       echo -n "Test Verified Boot Run: $1: "
-       ${uboot} -d sandbox-u-boot.dtb >${tmp} -c '
-sb load hostfs - 100 test.fit;
-fdt addr 100;
-bootm 100;
-reset'
-       if ! grep -q "$2" ${tmp}; then
-               echo
-               echo "Verified boot key check failed, output follows:"
-               cat ${tmp}
-               false
-       else
-               echo "OK"
-       fi
-}
-
-echo "Simple Verified Boot Test"
-echo "========================="
-echo
-echo "Please see doc/uImage.FIT/verified-boot.txt for more information"
-echo
-
-err=0
-tmp=/tmp/vboot_test.$$
-
-dir=$(dirname $0)
-
-if [ -z ${O} ]; then
-       O=.
-fi
-O=$(readlink -f ${O})
-
-dtc="-I dts -O dtb -p 2000"
-uboot="${O}/u-boot"
-mkimage="${O}/tools/mkimage"
-fit_check_sign="${O}/tools/fit_check_sign"
-keys="${dir}/dev-keys"
-echo ${mkimage} -D "${dtc}"
-
-echo "Build keys"
-mkdir -p ${keys}
-
-PUBLIC_EXPONENT=${1}
-
-if [ -z "${PUBLIC_EXPONENT}" ]; then
-       PUBLIC_EXPONENT=65537
-fi
-
-# Create an RSA key pair
-openssl genpkey -algorithm RSA -out ${keys}/dev.key \
-    -pkeyopt rsa_keygen_bits:2048 \
-    -pkeyopt rsa_keygen_pubexp:${PUBLIC_EXPONENT} 2>/dev/null
-
-# Create a certificate containing the public key
-openssl req -batch -new -x509 -key ${keys}/dev.key -out ${keys}/dev.crt
-
-pushd ${dir} >/dev/null
-
-function do_test {
-       echo do $sha test
-       # Compile our device tree files for kernel and U-Boot
-       dtc -p 0x1000 sandbox-kernel.dts -O dtb -o sandbox-kernel.dtb
-       dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
-
-       # Create a number kernel image with zeroes
-       head -c 5000 /dev/zero >test-kernel.bin
-
-       # Build the FIT, but don't sign anything yet
-       echo Build FIT with signed images
-       ${mkimage} -D "${dtc}" -f sign-images-$sha.its test.fit >${tmp}
-
-       run_uboot "unsigned signatures:" "dev-"
-
-       # Sign images with our dev keys
-       echo Sign images
-       ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb \
-               -r test.fit >${tmp}
-
-       run_uboot "signed images" "dev+"
-
-
-       # Create a fresh .dtb without the public keys
-       dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
-
-       echo Build FIT with signed configuration
-       ${mkimage} -D "${dtc}" -f sign-configs-$sha.its test.fit >${tmp}
-
-       run_uboot "unsigned config" $sha"+ OK"
-
-       # Sign images with our dev keys
-       echo Sign images
-       ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb \
-               -r test.fit >${tmp}
-
-       run_uboot "signed config" "dev+"
-
-       echo check signed config on the host
-       if ! ${fit_check_sign} -f test.fit -k sandbox-u-boot.dtb >${tmp}; then
-               echo
-               echo "Verified boot key check on host failed, output follows:"
-               cat ${tmp}
-               false
-       else
-               if ! grep -q "dev+" ${tmp}; then
-                       echo
-                       echo "Verified boot key check failed, output follows:"
-                       cat ${tmp}
-                       false
-               else
-                       echo "OK"
-               fi
-       fi
-
-       run_uboot "signed config" "dev+"
-
-       # Increment the first byte of the signature, which should cause failure
-       sig=$(fdtget -t bx test.fit /configurations/conf@1/signature@1 value)
-       newbyte=$(printf %x $((0x${sig:0:2} + 1)))
-       sig="${newbyte} ${sig:2}"
-       fdtput -t bx test.fit /configurations/conf@1/signature@1 value ${sig}
-
-       run_uboot "signed config with bad hash" "Bad Data Hash"
-}
-
-sha=sha1
-do_test
-sha=sha256
-do_test
-
-popd >/dev/null
-
-echo
-if ${ok}; then
-       echo "Test passed"
-else
-       echo "Test failed"
-fi
index 58aa8e27db3ee19db661bde16ef4675c6ee775ba..10fd6d4929374728732efd63e327cab36275766e 100644 (file)
@@ -195,7 +195,8 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
        fdt_begin_node(fdt, str);
        fdt_property_string(fdt, "description", params->imagename);
        fdt_property_string(fdt, "type", typename);
-       fdt_property_string(fdt, "arch", genimg_get_arch_name(params->arch));
+       fdt_property_string(fdt, "arch",
+                           genimg_get_arch_short_name(params->arch));
        fdt_property_string(fdt, "os", genimg_get_os_short_name(params->os));
        fdt_property_string(fdt, "compression",
                            genimg_get_comp_short_name(params->comp));
@@ -650,8 +651,8 @@ static int fit_handle_file(struct image_tool_params *params)
        }
 
        if (ret) {
-               fprintf(stderr, "%s Can't add hashes to FIT blob\n",
-                       params->cmdname);
+               fprintf(stderr, "%s Can't add hashes to FIT blob: %d\n",
+                       params->cmdname, ret);
                goto err_system;
        }
 
index 7effb6cea59e2a084e253e26661949f058c8b534..3e14fdc1eb3c95d1b1372692a8a8da3a2945e025 100644 (file)
@@ -38,7 +38,7 @@ static int fit_set_hash_value(void *fit, int noffset, uint8_t *value,
                printf("Can't set hash '%s' property for '%s' node(%s)\n",
                       FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL),
                       fdt_strerror(ret));
-               return -1;
+               return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
        }
 
        return 0;
@@ -64,25 +64,27 @@ static int fit_image_process_hash(void *fit, const char *image_name,
        const char *node_name;
        int value_len;
        char *algo;
+       int ret;
 
        node_name = fit_get_name(fit, noffset, NULL);
 
        if (fit_image_hash_get_algo(fit, noffset, &algo)) {
                printf("Can't get hash algo property for '%s' hash node in '%s' image node\n",
                       node_name, image_name);
-               return -1;
+               return -ENOENT;
        }
 
        if (calculate_hash(data, size, algo, value, &value_len)) {
                printf("Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n",
                       algo, node_name, image_name);
-               return -1;
+               return -EPROTONOSUPPORT;
        }
 
-       if (fit_set_hash_value(fit, noffset, value, value_len)) {
+       ret = fit_set_hash_value(fit, noffset, value, value_len);
+       if (ret) {
                printf("Can't set hash value for '%s' hash node in '%s' image node\n",
                       node_name, image_name);
-               return -1;
+               return ret;
        }
 
        return 0;
@@ -322,7 +324,7 @@ int fit_image_add_verification_data(const char *keydir, void *keydest,
                                comment, require_keys);
                }
                if (ret)
-                       return -1;
+                       return ret;
        }
 
        return 0;
index ff3024a8f172c8557bfaa02612d995bdcdd04f2d..d9939583f5533cd044b32e98b66aa34468dd9157 100644 (file)
@@ -25,45 +25,47 @@ static struct image_tool_params params = {
        .imagename2 = "",
 };
 
-static int h_compare_image_name(const void *vtype1, const void *vtype2)
+static enum ih_category cur_category;
+
+static int h_compare_category_name(const void *vtype1, const void *vtype2)
 {
        const int *type1 = vtype1;
        const int *type2 = vtype2;
-       const char *name1 = genimg_get_type_short_name(*type1);
-       const char *name2 = genimg_get_type_short_name(*type2);
+       const char *name1 = genimg_get_cat_short_name(cur_category, *type1);
+       const char *name2 = genimg_get_cat_short_name(cur_category, *type2);
 
        return strcmp(name1, name2);
 }
 
-/* Show all image types supported by mkimage */
-static void show_image_types(void)
+static int show_valid_options(enum ih_category category)
 {
-       struct image_type_params *tparams;
-       int order[IH_TYPE_COUNT];
+       int *order;
        int count;
-       int type;
+       int item;
        int i;
 
+       count = genimg_get_cat_count(category);
+       order = calloc(count, sizeof(*order));
+       if (!order)
+               return -ENOMEM;
+
        /* Sort the names in order of short name for easier reading */
-       memset(order, '\0', sizeof(order));
-       for (count = 0, type = 0; type < IH_TYPE_COUNT; type++) {
-               tparams = imagetool_get_type(type);
-               if (tparams)
-                       order[count++] = type;
-       }
-       qsort(order, count, sizeof(int), h_compare_image_name);
+       for (item = 0; item < count; item++)
+               order[item] = item;
+       cur_category = category;
+       qsort(order, count, sizeof(int), h_compare_category_name);
 
-       fprintf(stderr, "\nInvalid image type. Supported image types:\n");
+       fprintf(stderr, "\nInvalid %s, supported are:\n",
+               genimg_get_cat_desc(category));
        for (i = 0; i < count; i++) {
-               type = order[i];
-               tparams = imagetool_get_type(type);
-               if (tparams) {
-                       fprintf(stderr, "\t%-15s  %s\n",
-                               genimg_get_type_short_name(type),
-                               genimg_get_type_name(type));
-               }
+               item = order[i];
+               fprintf(stderr, "\t%-15s  %s\n",
+                       genimg_get_cat_short_name(category, item),
+                       genimg_get_cat_name(category, item));
        }
        fprintf(stderr, "\n");
+
+       return 0;
 }
 
 static void usage(const char *msg)
@@ -150,8 +152,10 @@ static void process_args(int argc, char **argv)
                        break;
                case 'A':
                        params.arch = genimg_get_arch_id(optarg);
-                       if (params.arch < 0)
+                       if (params.arch < 0) {
+                               show_valid_options(IH_ARCH);
                                usage("Invalid architecture");
+                       }
                        break;
                case 'b':
                        if (add_content(IH_TYPE_FLATDT, optarg)) {
@@ -166,8 +170,10 @@ static void process_args(int argc, char **argv)
                        break;
                case 'C':
                        params.comp = genimg_get_comp_id(optarg);
-                       if (params.comp < 0)
+                       if (params.comp < 0) {
+                               show_valid_options(IH_COMP);
                                usage("Invalid compression type");
+                       }
                        break;
                case 'd':
                        params.datafile = optarg;
@@ -197,7 +203,6 @@ static void process_args(int argc, char **argv)
                         * The flattened image tree (FIT) format
                         * requires a flattened device tree image type
                         */
-                       params.fit_image_type = params.type;
                        params.type = IH_TYPE_FLATDT;
                        params.fflag = 1;
                        break;
@@ -215,8 +220,10 @@ static void process_args(int argc, char **argv)
                        break;
                case 'O':
                        params.os = genimg_get_os_id(optarg);
-                       if (params.os < 0)
+                       if (params.os < 0) {
+                               show_valid_options(IH_OS);
                                usage("Invalid operating system");
+                       }
                        break;
                case 'p':
                        params.external_offset = strtoull(optarg, &ptr, 16);
@@ -225,6 +232,7 @@ static void process_args(int argc, char **argv)
                                        params.cmdname, optarg);
                                exit(EXIT_FAILURE);
                        }
+                       break;
                case 'q':
                        params.quiet = 1;
                        break;
@@ -244,7 +252,7 @@ static void process_args(int argc, char **argv)
                case 'T':
                        type = genimg_get_type_id(optarg);
                        if (type < 0) {
-                               show_image_types();
+                               show_valid_options(IH_TYPE);
                                usage("Invalid image type");
                        }
                        break;
@@ -272,9 +280,12 @@ static void process_args(int argc, char **argv)
         * will always be IH_TYPE_FLATDT in this case).
         */
        if (params.type == IH_TYPE_FLATDT) {
-               params.fit_image_type = type;
+               params.fit_image_type = type ? type : IH_TYPE_KERNEL;
+               /* For auto_its, datafile is always 'auto' */
                if (!params.auto_its)
                        params.datafile = datafile;
+               else if (!params.datafile)
+                       usage("Missing data file for auto-FIT (use -d)");
        } else if (type != IH_TYPE_INVALID) {
                params.type = type;
        }
@@ -283,7 +294,6 @@ static void process_args(int argc, char **argv)
                usage("Missing output filename");
 }
 
-
 int main(int argc, char **argv)
 {
        int ifd = -1;