]> git.ipfire.org Git - people/ms/u-boot.git/commitdiff
Merge branch 'master' of http://git.denx.de/u-boot-sunxi
authorTom Rini <trini@konsulko.com>
Fri, 15 Jul 2016 14:44:01 +0000 (10:44 -0400)
committerTom Rini <trini@konsulko.com>
Fri, 15 Jul 2016 14:44:01 +0000 (10:44 -0400)
153 files changed:
Kconfig
Makefile
README
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/dts/exynos4210-origen.dts
arch/arm/dts/exynos4210-trats.dts
arch/arm/dts/exynos4210-universal_c210.dts
arch/arm/dts/exynos4412-odroid.dts
arch/arm/dts/exynos4412-trats2.dts
arch/arm/dts/rk3288-firefly.dts
arch/arm/include/asm/arch-rockchip/sdram.h
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-exynos/include/mach/dwmmc.h
arch/arm/mach-rockchip/rk3288-board-spl.c
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
arch/arm/mach-rockchip/rk3288/syscon_rk3288.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/Kconfig
arch/sandbox/config.mk
arch/sandbox/cpu/Makefile
arch/sandbox/cpu/cpu.c
arch/sandbox/cpu/os.c
arch/sandbox/cpu/spl.c [new file with mode: 0644]
arch/sandbox/cpu/start.c
arch/sandbox/cpu/u-boot-spl.lds [new file with mode: 0644]
arch/sandbox/dts/sandbox.dts
arch/sandbox/include/asm/spl.h [new file with mode: 0644]
arch/sandbox/lib/Makefile
arch/sandbox/lib/bootm.c
arch/sh/include/asm/io.h
board/sandbox/MAINTAINERS
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.c
common/spl/spl_fit.c
configs/am43xx_hs_evm_defconfig
configs/am57xx_hs_evm_defconfig
configs/da850evm_defconfig
configs/dra7xx_hs_evm_defconfig
configs/firefly-rk3288_defconfig
configs/sandbox_spl_defconfig [new file with mode: 0644]
doc/README.ti-secure
doc/driver-model/of-plat.txt [new file with mode: 0644]
drivers/clk/clk-uclass.c
drivers/clk/clk_fixed_rate.c
drivers/clk/clk_rk3288.c
drivers/core/device-remove.c
drivers/core/device.c
drivers/core/lists.c
drivers/core/regmap.c
drivers/core/root.c
drivers/core/syscon-uclass.c
drivers/misc/Makefile
drivers/misc/spltest_sandbox.c [new file with mode: 0644]
drivers/mmc/exynos_dw_mmc.c
drivers/mmc/rockchip_dw_mmc.c
drivers/pinctrl/rockchip/pinctrl_rk3288.c
drivers/rtc/date.c
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/ns16550.c
drivers/serial/sandbox.c
drivers/serial/serial-uclass.c
drivers/serial/serial_rockchip.c [new file with mode: 0644]
drivers/serial/serial_stm32x7.c
dts/Kconfig
include/clk.h
include/common.h
include/configs/dragonboard410c.h
include/configs/sandbox.h
include/configs/sandbox_spl.h [new file with mode: 0644]
include/configs/stm32f746-disco.h
include/dm/device.h
include/dm/platdata.h
include/dt-structs.h [new file with mode: 0644]
include/image.h
include/linux/io.h
include/linux/types.h
include/os.h
include/regmap.h
include/syscon.h
lib/Makefile
lib/libfdt/libfdt.swig [new file with mode: 0644]
lib/libfdt/setup.py [new file with mode: 0644]
lib/libfdt/test_libfdt.py [new file with mode: 0644]
lib/tiny-printf.c
scripts/Makefile.host
scripts/Makefile.spl
test/README [new file with mode: 0644]
test/py/conftest.py
test/py/multiplexed_log.py
test/py/tests/test_ofplatdata.py [new file with mode: 0644]
test/py/tests/test_vboot.py [new file with mode: 0644]
test/py/tests/vboot/sandbox-kernel.dts [moved from test/vboot/sandbox-kernel.dts with 100% similarity]
test/py/tests/vboot/sandbox-u-boot.dts [moved from test/vboot/sandbox-u-boot.dts with 100% similarity]
test/py/tests/vboot/sign-configs-sha1.its [moved from test/vboot/sign-configs-sha1.its with 100% similarity]
test/py/tests/vboot/sign-configs-sha256.its [moved from test/vboot/sign-configs-sha256.its with 100% similarity]
test/py/tests/vboot/sign-images-sha1.its [moved from test/vboot/sign-images-sha1.its with 100% similarity]
test/py/tests/vboot/sign-images-sha256.its [moved from test/vboot/sign-images-sha256.its with 100% similarity]
test/py/u_boot_console_base.py
test/py/u_boot_console_sandbox.py
test/py/u_boot_spawn.py
test/py/u_boot_utils.py
test/run [new file with mode: 0755]
test/vboot/.gitignore [deleted file]
test/vboot/vboot_test.sh [deleted file]
tools/Makefile
tools/dtoc/.gitignore [new file with mode: 0644]
tools/dtoc/dtoc [new symlink]
tools/dtoc/dtoc.py [new file with mode: 0755]
tools/dtoc/fdt.py [new file with mode: 0644]
tools/dtoc/fdt_fallback.py [new file with mode: 0644]
tools/dtoc/fdt_util.py [new file with mode: 0644]
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 88128ec72a26878740dc3ac0719252819654bea4..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)
@@ -801,7 +802,7 @@ quiet_cmd_pad_cat = CAT     $@
 cmd_pad_cat = $(cmd_objcopy) && $(append) || rm -f $@
 
 all:           $(ALL-y)
-ifeq ($(CONFIG_DM_I2C_COMPAT),y)
+ifeq ($(CONFIG_DM_I2C_COMPAT)$(CONFIG_SANDBOX),y)
        @echo "===================== WARNING ======================"
        @echo "This board uses CONFIG_DM_I2C_COMPAT. Please remove"
        @echo "(possibly in a subsequent patch in your series)"
@@ -1318,7 +1319,8 @@ u-boot.lds: $(LDSCRIPT) prepare FORCE
 
 spl/u-boot-spl.bin: spl/u-boot-spl
        @:
-spl/u-boot-spl: tools prepare $(if $(CONFIG_OF_SEPARATE),dts/dt.dtb)
+spl/u-boot-spl: tools prepare \
+               $(if $(CONFIG_OF_SEPARATE)$(CONFIG_SPL_OF_PLATDATA),dts/dt.dtb)
        $(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
 
 spl/sunxi-spl.bin: spl/u-boot-spl
diff --git a/README b/README
index 26d5ad273ef2d1524bad067b820611a0804df07f..e906253fa2b03dafa7dc20a3f41bec5854c9af0d 100644 (file)
--- a/README
+++ b/README
@@ -3835,9 +3835,6 @@ Configuration Settings:
                The memory will be freed (or in fact just forgotten) when
                U-Boot relocates itself.
 
-               Pre-relocation malloc() is only supported on ARM and sandbox
-               at present but is fairly easy to enable for other archs.
-
 - CONFIG_SYS_MALLOC_SIMPLE
                Provides a simple and small malloc() and calloc() for those
                boards which do not use the full malloc in SPL (which is
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
index 3f877615844e107262316dead327905335f862d0..26c4d7f4c646f7c65196640b72e5701ecbb64931 100644 (file)
@@ -22,7 +22,7 @@
        aliases {
                serial0 = "/serial@13800000";
                console = "/serial@13820000";
-               mmc2 = "sdhci@12530000";
+               mmc2 = "/sdhci@12530000";
        };
 
        sdhci@12510000 {
index f3fac801905696f9eba76814fb3a8e0c4833152b..2ed38f369e4ee8ec602c5e4e530a92356b0832e9 100644 (file)
@@ -29,8 +29,8 @@
                i2c7 = "/i2c@138d0000";
                serial0 = "/serial@13800000";
                console = "/serial@13820000";
-               mmc0 = "sdhci@12510000";
-               mmc2 = "sdhci@12530000";
+               mmc0 = "/sdhci@12510000";
+               mmc2 = "/sdhci@12530000";
        };
 
        fimd@11c00000 {
index ad3527ec6f118324e82e0168681c6d2e7774dec2..8cac7dd752e082589eb85e7c3c01868c39ad894b 100644 (file)
@@ -17,8 +17,8 @@
        aliases {
                serial0 = "/serial@13800000";
                console = "/serial@13820000";
-               mmc0 = "sdhci@12510000";
-               mmc2 = "sdhci@12530000";
+               mmc0 = "/sdhci@12510000";
+               mmc2 = "/sdhci@12530000";
        };
 
        sdhci@12510000 {
index a63e8abab4ae9cdcc708960930f551bde7bbcb8d..188cb939bb8a1795037c937b9b7101c0900a90ef 100644 (file)
@@ -25,8 +25,8 @@
                i2c7 = "/i2c@138d0000";
                serial0 = "/serial@13800000";
                console = "/serial@13810000";
-               mmc2 = "sdhci@12530000";
-               mmc4 = "dwmmc@12550000";
+               mmc2 = "/sdhci@12530000";
+               mmc4 = "/dwmmc@12550000";
        };
 
        i2c@13860000 {
index 2d4e522ea2770ef0e428eea352b4ffd4e43271d9..1fbcf8914fa50050fbdffbd64ed41b3262ad1fa7 100644 (file)
@@ -29,9 +29,9 @@
                i2c7 = "/i2c@138d0000";
                serial0 = "/serial@13800000";
                console = "/serial@13820000";
-               mmc0 = "sdhci@12510000";
-               mmc2 = "sdhci@12530000";
-               mmc4 = "dwmmc@12550000";
+               mmc0 = "/sdhci@12510000";
+               mmc2 = "/sdhci@12530000";
+               mshc0 = "/dwmmc@12550000";
        };
 
        i2c@138d0000 {
index aed8d3a712b037b363464759c9c17a6adc1d1e67..3176d5046b2a4a622bb700b2ab189575204ec2c0 100644 (file)
@@ -30,7 +30,8 @@
                0x5 0x0>;
        rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
                0xa60 0x40 0x10 0x0>;
-       rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf>;
+       /* Add a dummy value to cause of-platdata think this is bytes */
+       rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
        rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
index d3de42d297745152efa3076e0e3aa1427005c7f6..e08e28f4f0c5c9e9e81c3f77db85972162512e46 100644 (file)
@@ -24,6 +24,12 @@ struct rk3288_sdram_channel {
        u8 row_3_4;
        u8 cs0_row;
        u8 cs1_row;
+       /*
+        * For of-platdata, which would otherwise convert this into two
+        * byte-swapped integers. With a size of 9 bytes, this struct will
+        * appear in of-platdata as a byte array.
+        */
+       u8 dummy;
 };
 
 struct rk3288_sdram_pctl_timing {
@@ -81,12 +87,4 @@ struct rk3288_base_params {
        u32 odt;
 };
 
-struct rk3288_sdram_params {
-       struct rk3288_sdram_channel ch[2];
-       struct rk3288_sdram_pctl_timing pctl_timing;
-       struct rk3288_sdram_phy_timing phy_timing;
-       struct rk3288_base_params base;
-       int num_channels;
-};
-
 #endif
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 bd997ad47e31f82cf96df1d15dceb327bd8b2849..ab8361f4a8bf119b11273161d9c21cce2a95f943 100644 (file)
@@ -28,4 +28,3 @@
 #define DWMCI_DIVRATIO_MASK            0x7
 
 int exynos_dwmmc_init(const void *blob);
-int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel);
index 15f1266a7bf4380cdb195fa3810b0ded970c735e..123f58b27f2c3c459924e03f611e36b48ae50ad6 100644 (file)
@@ -29,6 +29,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 u32 spl_boot_device(void)
 {
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
        const void *blob = gd->fdt_blob;
        struct udevice *dev;
        const char *bootdev;
@@ -63,6 +64,7 @@ u32 spl_boot_device(void)
        }
 
 fallback:
+#endif
        return BOOT_DEVICE_MMC1;
 }
 
@@ -114,7 +116,6 @@ static void configure_l2ctlr(void)
 #ifdef CONFIG_SPL_MMC_SUPPORT
 static int configure_emmc(struct udevice *pinctrl)
 {
-#if !defined(CONFIG_TARGET_ROCK2) && !defined(CONFIG_TARGET_FIREFLY_RK3288)
        struct gpio_desc desc;
        int ret;
 
@@ -144,7 +145,6 @@ static int configure_emmc(struct udevice *pinctrl)
                debug("gpio value ret=%d\n", ret);
                return ret;
        }
-#endif
 
        return 0;
 }
@@ -247,15 +247,18 @@ void spl_board_init(void)
                goto err;
        }
 #ifdef CONFIG_SPL_MMC_SUPPORT
-       ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
-       if (ret) {
-               debug("%s: Failed to set up SD card\n", __func__);
-               goto err;
-       }
-       ret = configure_emmc(pinctrl);
-       if (ret) {
-               debug("%s: Failed to set up eMMC\n", __func__);
-               goto err;
+       if (!IS_ENABLED(CONFIG_TARGET_ROCK2) &&
+           !IS_ENABLED(CONFIG_TARGET_FIREFLY_RK3288)) {
+               ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
+               if (ret) {
+                       debug("%s: Failed to set up SD card\n", __func__);
+                       goto err;
+               }
+               ret = configure_emmc(pinctrl);
+               if (ret) {
+                       debug("%s: Failed to set up eMMC\n", __func__);
+                       goto err;
+               }
        }
 #endif
 
index 55ac73e9d25111eb96345e07d66cd7af9f80e9ed..b36b6afcd978232ceedebc1479aa811d6d206fce 100644 (file)
@@ -10,6 +10,7 @@
 #include <common.h>
 #include <clk.h>
 #include <dm.h>
+#include <dt-structs.h>
 #include <errno.h>
 #include <ram.h>
 #include <regmap.h>
@@ -41,6 +42,19 @@ struct dram_info {
        struct rk3288_grf *grf;
        struct rk3288_sgrf *sgrf;
        struct rk3288_pmu *pmu;
+       bool is_veyron;
+};
+
+struct rk3288_sdram_params {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       struct dtd_rockchip_rk3288_dmc of_plat;
+#endif
+       struct rk3288_sdram_channel ch[2];
+       struct rk3288_sdram_pctl_timing pctl_timing;
+       struct rk3288_sdram_phy_timing phy_timing;
+       struct rk3288_base_params base;
+       int num_channels;
+       struct regmap *map;
 };
 
 #ifdef CONFIG_SPL_BUILD
@@ -703,7 +717,7 @@ static int sdram_init(struct dram_info *dram,
 
        return 0;
 }
-#endif
+#endif /* CONFIG_SPL_BUILD */
 
 size_t sdram_size_mb(struct rk3288_pmu *pmu)
 {
@@ -779,18 +793,36 @@ static int veyron_init(struct dram_info *priv)
 static int setup_sdram(struct udevice *dev)
 {
        struct dram_info *priv = dev_get_priv(dev);
-       struct rk3288_sdram_params params;
+       struct rk3288_sdram_params *params = dev_get_platdata(dev);
+
+# ifdef CONFIG_ROCKCHIP_FAST_SPL
+       if (priv->is_veyron) {
+               int ret;
+
+               ret = veyron_init(priv);
+               if (ret)
+                       return ret;
+       }
+# endif
+
+       return sdram_init(priv, params);
+}
+
+static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+       struct rk3288_sdram_params *params = dev_get_platdata(dev);
        const void *blob = gd->fdt_blob;
        int node = dev->of_offset;
        int i, ret;
 
-       params.num_channels = fdtdec_get_int(blob, node,
-                                            "rockchip,num-channels", 1);
-       for (i = 0; i < params.num_channels; i++) {
+       params->num_channels = fdtdec_get_int(blob, node,
+                                             "rockchip,num-channels", 1);
+       for (i = 0; i < params->num_channels; i++) {
                ret = fdtdec_get_byte_array(blob, node,
                                            "rockchip,sdram-channel",
-                                           (u8 *)&params.ch[i],
-                                           sizeof(params.ch[i]));
+                                           (u8 *)&params->ch[i],
+                                           sizeof(params->ch[i]));
                if (ret) {
                        debug("%s: Cannot read rockchip,sdram-channel\n",
                              __func__);
@@ -798,46 +830,82 @@ static int setup_sdram(struct udevice *dev)
                }
        }
        ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
-                                  (u32 *)&params.pctl_timing,
-                                  sizeof(params.pctl_timing) / sizeof(u32));
+                                  (u32 *)&params->pctl_timing,
+                                  sizeof(params->pctl_timing) / sizeof(u32));
        if (ret) {
                debug("%s: Cannot read rockchip,pctl-timing\n", __func__);
                return -EINVAL;
        }
        ret = fdtdec_get_int_array(blob, node, "rockchip,phy-timing",
-                                  (u32 *)&params.phy_timing,
-                                  sizeof(params.phy_timing) / sizeof(u32));
+                                  (u32 *)&params->phy_timing,
+                                  sizeof(params->phy_timing) / sizeof(u32));
        if (ret) {
                debug("%s: Cannot read rockchip,phy-timing\n", __func__);
                return -EINVAL;
        }
        ret = fdtdec_get_int_array(blob, node, "rockchip,sdram-params",
-                                  (u32 *)&params.base,
-                                  sizeof(params.base) / sizeof(u32));
+                                  (u32 *)&params->base,
+                                  sizeof(params->base) / sizeof(u32));
        if (ret) {
                debug("%s: Cannot read rockchip,sdram-params\n", __func__);
                return -EINVAL;
        }
+#ifdef CONFIG_ROCKCHIP_FAST_SPL
+       struct dram_info *priv = dev_get_priv(dev);
 
-# ifdef CONFIG_ROCKCHIP_FAST_SPL
-       if (!fdt_node_check_compatible(blob, 0, "google,veyron")) {
-               ret = veyron_init(priv);
-               if (ret)
-                       return ret;
+       priv->is_veyron = !fdt_node_check_compatible(blob, 0, "google,veyron");
+#endif
+       ret = regmap_init_mem(dev, &params->map);
+       if (ret)
+               return ret;
+#endif
+
+       return 0;
+}
+#endif /* CONFIG_SPL_BUILD */
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int conv_of_platdata(struct udevice *dev)
+{
+       struct rk3288_sdram_params *plat = dev_get_platdata(dev);
+       struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat;
+       int i, ret;
+
+       for (i = 0; i < 2; i++) {
+               memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel,
+                      sizeof(plat->ch[i]));
        }
-# endif
+       memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
+              sizeof(plat->pctl_timing));
+       memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
+              sizeof(plat->phy_timing));
+       memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
+       plat->num_channels = of_plat->rockchip_num_channels;
+       ret = regmap_init_mem_platdata(dev, of_plat->reg,
+                                      ARRAY_SIZE(of_plat->reg) / 2,
+                                      &plat->map);
+       if (ret)
+               return ret;
 
-       return sdram_init(priv, &params);
+       return 0;
 }
 #endif
 
 static int rk3288_dmc_probe(struct udevice *dev)
 {
+#ifdef CONFIG_SPL_BUILD
+       struct rk3288_sdram_params *plat = dev_get_platdata(dev);
+#endif
        struct dram_info *priv = dev_get_priv(dev);
        struct regmap *map;
        int ret;
        struct udevice *dev_clk;
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       ret = conv_of_platdata(dev);
+       if (ret)
+               return ret;
+#endif
        map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
        if (IS_ERR(map))
                return PTR_ERR(map);
@@ -849,14 +917,12 @@ static int rk3288_dmc_probe(struct udevice *dev)
        priv->sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_SGRF);
        priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
 
-       ret = regmap_init_mem(dev, &map);
-       if (ret)
-               return ret;
-       priv->chan[0].pctl = regmap_get_range(map, 0);
-       priv->chan[0].publ = regmap_get_range(map, 1);
-       priv->chan[1].pctl = regmap_get_range(map, 2);
-       priv->chan[1].publ = regmap_get_range(map, 3);
-
+#ifdef CONFIG_SPL_BUILD
+       priv->chan[0].pctl = regmap_get_range(plat->map, 0);
+       priv->chan[0].publ = regmap_get_range(plat->map, 1);
+       priv->chan[1].pctl = regmap_get_range(plat->map, 2);
+       priv->chan[1].publ = regmap_get_range(plat->map, 3);
+#endif
        ret = uclass_get_device(UCLASS_CLK, 0, &dev_clk);
        if (ret)
                return ret;
@@ -898,10 +964,16 @@ static const struct udevice_id rk3288_dmc_ids[] = {
 };
 
 U_BOOT_DRIVER(dmc_rk3288) = {
-       .name = "rk3288_dmc",
+       .name = "rockchip_rk3288_dmc",
        .id = UCLASS_RAM,
        .of_match = rk3288_dmc_ids,
        .ops = &rk3288_dmc_ops,
+#ifdef CONFIG_SPL_BUILD
+       .ofdata_to_platdata = rk3288_dmc_ofdata_to_platdata,
+#endif
        .probe = rk3288_dmc_probe,
        .priv_auto_alloc_size = sizeof(struct dram_info),
+#ifdef CONFIG_SPL_BUILD
+       .platdata_auto_alloc_size = sizeof(struct rk3288_sdram_params),
+#endif
 };
index c9f7c4e32f44b883cb22052e23f48b0f858e107b..be4b2b00c30b78a98a5919e19280ccb93bb3127a 100644 (file)
@@ -23,3 +23,41 @@ U_BOOT_DRIVER(syscon_rk3288) = {
        .id = UCLASS_SYSCON,
        .of_match = rk3288_syscon_ids,
 };
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3288_syscon_bind_of_platdata(struct udevice *dev)
+{
+       dev->driver_data = dev->driver->of_match->data;
+       debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+       return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rk3288_noc) = {
+       .name = "rockchip_rk3288_noc",
+       .id = UCLASS_SYSCON,
+       .of_match = rk3288_syscon_ids,
+       .bind = rk3288_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_grf) = {
+       .name = "rockchip_rk3288_grf",
+       .id = UCLASS_SYSCON,
+       .of_match = rk3288_syscon_ids + 1,
+       .bind = rk3288_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_sgrf) = {
+       .name = "rockchip_rk3288_sgrf",
+       .id = UCLASS_SYSCON,
+       .of_match = rk3288_syscon_ids + 2,
+       .bind = rk3288_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_pmu) = {
+       .name = "rockchip_rk3288_pmu",
+       .id = UCLASS_SYSCON,
+       .of_match = rk3288_syscon_ids + 3,
+       .bind = rk3288_syscon_bind_of_platdata,
+};
+#endif
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 a8a90cb7a4dd9d14c35cc60b16e6eca4698eb6af..d4c1ee0662c57f74e3b7acb35418a2789d2b90ac 100644 (file)
@@ -10,8 +10,13 @@ config SYS_BOARD
 config SYS_CPU
        default "sandbox"
 
+config SANDBOX_SPL
+       bool "Enable SPL for sandbox"
+       select SUPPORT_SPL
+
 config SYS_CONFIG_NAME
-       default "sandbox"
+       default "sandbox_spl" if SANDBOX_SPL
+       default "sandbox" if !SANDBOX_SPL
 
 config PCI
        bool "PCI support"
index 16fd6d508a9322ed5bf68db1b5769cea3b4c9e35..6d62abb0352492b7b2f19fcab60a43d001ad5d62 100644 (file)
@@ -20,4 +20,9 @@ cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds \
        -Wl,--start-group $(u-boot-main) -Wl,--end-group \
        $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map
 
+cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \
+       -Wl,--start-group $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \
+       $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) -Wl,--end-group \
+       $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot-spl.map -Wl,--gc-sections)
+
 CONFIG_ARCH_DEVICE_TREE := sandbox
index 1b42fee141277b0ca917ae14c265f72d9c73d2b5..db4363358a85dee0949dd1a683873afd8470cd58 100644 (file)
@@ -8,6 +8,7 @@
 #
 
 obj-y  := cpu.o os.o start.o state.o
+obj-$(CONFIG_SPL_BUILD)        += spl.o
 obj-$(CONFIG_ETH_SANDBOX_RAW)  += eth-raw-os.o
 obj-$(CONFIG_SANDBOX_SDL)      += sdl.o
 
index 196f3e1191e166c821378bc05dcecfb20cb25953..2def72212d1feae279506403663cfd4b0fdb0f56 100644 (file)
@@ -4,10 +4,12 @@
  */
 #define DEBUG
 #include <common.h>
-#include <dm/root.h>
+#include <errno.h>
+#include <libfdt.h>
 #include <os.h>
 #include <asm/io.h>
 #include <asm/state.h>
+#include <dm/root.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -55,7 +57,7 @@ int cleanup_before_linux_select(int flags)
 
 void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
 {
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && !defined(CONFIG_SPL_BUILD)
        unsigned long plen = len;
        void *ptr;
 
index 8a4d719835ccb88c00b5aa6fd1e37cfdc049e8e8..2d63dd88f121e0cbcb4effa498c56530aa6223fb 100644 (file)
@@ -541,6 +541,57 @@ int os_jump_to_image(const void *dest, int size)
        return unlink(fname);
 }
 
+int os_find_u_boot(char *fname, int maxlen)
+{
+       struct sandbox_state *state = state_get_current();
+       const char *progname = state->argv[0];
+       int len = strlen(progname);
+       char *p;
+       int fd;
+
+       if (len >= maxlen || len < 4)
+               return -ENOSPC;
+
+       /* Look for 'u-boot' in the same directory as 'u-boot-spl' */
+       strcpy(fname, progname);
+       if (!strcmp(fname + len - 4, "-spl")) {
+               fname[len - 4] = '\0';
+               fd = os_open(fname, O_RDONLY);
+               if (fd >= 0) {
+                       close(fd);
+                       return 0;
+               }
+       }
+
+       /* Look for 'u-boot' in the parent directory of spl/ */
+       p = strstr(fname, "/spl/");
+       if (p) {
+               strcpy(p, p + 4);
+               fd = os_open(fname, O_RDONLY);
+               if (fd >= 0) {
+                       close(fd);
+                       return 0;
+               }
+       }
+
+       return -ENOENT;
+}
+
+int os_spl_to_uboot(const char *fname)
+{
+       struct sandbox_state *state = state_get_current();
+       char *argv[state->argc + 1];
+       int ret;
+
+       memcpy(argv, state->argv, sizeof(char *) * (state->argc + 1));
+       argv[0] = (char *)fname;
+       ret = execv(fname, argv);
+       if (ret)
+               return ret;
+
+       return unlink(fname);
+}
+
 void os_localtime(struct rtc_time *rt)
 {
        time_t t = time(NULL);
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
new file mode 100644 (file)
index 0000000..e8349c0
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <os.h>
+#include <spl.h>
+#include <asm/spl.h>
+#include <asm/state.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_init_f(ulong flag)
+{
+       struct sandbox_state *state = state_get_current();
+
+       gd->arch.ram_buf = state->ram_buf;
+       gd->ram_size = state->ram_size;
+}
+
+u32 spl_boot_device(void)
+{
+       return BOOT_DEVICE_BOARD;
+}
+
+void spl_board_announce_boot_device(void)
+{
+       char fname[256];
+       int ret;
+
+       ret = os_find_u_boot(fname, sizeof(fname));
+       if (ret) {
+               printf("(%s not found, error %d)\n", fname, ret);
+               return;
+       }
+       printf("%s\n", fname);
+}
+
+int spl_board_load_image(void)
+{
+       char fname[256];
+       int ret;
+
+       ret = os_find_u_boot(fname, sizeof(fname));
+       if (ret)
+               return ret;
+
+       /* Hopefully this will not return */
+       return os_spl_to_uboot(fname);
+}
+
+void spl_board_init(void)
+{
+       struct udevice *dev;
+
+       preloader_console_init();
+
+       /*
+       * Scan all the devices so that we can output their platform data. See
+       * sandbox_spl_probe().
+       */
+       for (uclass_first_device(UCLASS_MISC, &dev);
+       dev;
+       uclass_next_device(&dev))
+               ;
+}
index 969618ef87502dfb1f34c0f677c18e66c4f6072f..6e4ec017ccd98239faf8af7a9730c8bb3567cb4c 100644 (file)
@@ -73,6 +73,7 @@ static int sandbox_cmdline_cb_help(struct sandbox_state *state, const char *arg)
 }
 SANDBOX_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help");
 
+#ifndef CONFIG_SPL_BUILD
 int sandbox_main_loop_init(void)
 {
        struct sandbox_state *state = state_get_current();
@@ -97,6 +98,7 @@ int sandbox_main_loop_init(void)
 
        return 0;
 }
+#endif
 
 static int sandbox_cmdline_cb_boot(struct sandbox_state *state,
                                      const char *arg)
diff --git a/arch/sandbox/cpu/u-boot-spl.lds b/arch/sandbox/cpu/u-boot-spl.lds
new file mode 100644 (file)
index 0000000..7e92b4a
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011-2012 The Chromium OS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+SECTIONS
+{
+
+       . = ALIGN(4);
+       .u_boot_list : {
+               KEEP(*(SORT(.u_boot_list*)));
+       }
+
+       __u_boot_sandbox_option_start = .;
+       _u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) }
+       __u_boot_sandbox_option_end = .;
+
+       __bss_start = .;
+}
+
+INSERT BEFORE .data;
index 2ae40148b09a3976f488b39a0df503ace67ab21f..e6d336f16ab3357f25fdef2e7cf06b3245e353b5 100644 (file)
                };
        };
 
+       spl-test {
+               u-boot,dm-pre-reloc;
+               compatible = "sandbox,spl-test";
+               boolval;
+               intval = <1>;
+               intarray = <2 3 4>;
+               byteval = [05];
+               bytearray = [06];
+               longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
+               stringval = "message";
+               stringarray = "multi-word", "message";
+       };
+
+       spl-test2 {
+               u-boot,dm-pre-reloc;
+               compatible = "sandbox,spl-test";
+               intval = <3>;
+               intarray = <5>;
+               byteval = [08];
+               bytearray = [01 23 34];
+               longbytearray = [09 0a 0b 0c];
+               stringval = "message2";
+               stringarray = "another", "multi-word", "message";
+       };
+
+       spl-test3 {
+               u-boot,dm-pre-reloc;
+               compatible = "sandbox,spl-test";
+               stringarray = "one";
+       };
+
        square {
                compatible = "demo-shape";
                colour = "blue";
diff --git a/arch/sandbox/include/asm/spl.h b/arch/sandbox/include/asm/spl.h
new file mode 100644 (file)
index 0000000..59f2401
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __asm_spl_h
+#define __asm_spl_h
+
+#define CONFIG_SPL_BOARD_LOAD_IMAGE
+
+/**
+ * Board-specific load method for boards that have a special way of loading
+ * U-Boot, which does not fit with the existing SPL code.
+ *
+ * @return 0 on success, negative errno value on failure.
+ */
+int spl_board_load_image(void);
+
+enum {
+       BOOT_DEVICE_BOARD,
+};
+
+#endif
index 96761e27f7a38a80a20176d85ca3c2f2242cc65a..7820c55c8554fce2f94c6af214d8a2cb921cbf20 100644 (file)
@@ -8,5 +8,7 @@
 #
 
 obj-y  += interrupts.o
+ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_PCI)      += pci_io.o
+endif
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
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 f5db773a478ec827b525487207013fe1410c0da4..4dcbf4ba03c518ad36ec40dcb006e9b4094f2ec5 100644 (file)
@@ -11,3 +11,10 @@ S:   Maintained
 F:     board/sandbox/
 F:     include/configs/sandbox.h
 F:     configs/sandbox_noblk_defconfig
+
+SANDBOX SPL BOARD
+M:     Simon Glass <sjg@chromium.org>
+S:     Maintained
+F:     board/sandbox/
+F:     include/configs/sandbox_spl.h
+F:     configs/sandbox_spl_defconfig
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 0039716774c5581189af85548d2c278076d8bfee..14320fe75c10aa673122c1ef0a08664dd37a8784 100644 (file)
@@ -13,7 +13,6 @@
 #include <nand.h>
 #include <fat.h>
 #include <version.h>
-#include <i2c.h>
 #include <image.h>
 #include <malloc.h>
 #include <dm/root.h>
@@ -203,7 +202,7 @@ int spl_init(void)
        gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
        gd->malloc_ptr = 0;
 #endif
-       if (CONFIG_IS_ENABLED(OF_CONTROL)) {
+       if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
                ret = fdtdec_setup();
                if (ret) {
                        debug("fdtdec_setup() returned error %d\n", ret);
@@ -211,7 +210,8 @@ int spl_init(void)
                }
        }
        if (IS_ENABLED(CONFIG_SPL_DM)) {
-               ret = dm_init_and_scan(true);
+               /* With CONFIG_OF_PLATDATA, bring in all devices */
+               ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA));
                if (ret) {
                        debug("dm_init_and_scan() returned error %d\n", ret);
                        return ret;
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 4af91206dcf7f63982cd547d83e424d69b513b51..bdafc716aa8dd0bea963e8c674530eccab64db92 100644 (file)
@@ -69,3 +69,6 @@ CONFIG_USE_PRIVATE_LIBGCC=y
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_ERRNO_STR=y
+CONFIG_SPL_OF_PLATDATA=y
+# CONFIG_SPL_OF_LIBFDT is not set
+CONFIG_ROCKCHIP_SERIAL=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
new file mode 100644 (file)
index 0000000..0f6dda8
--- /dev/null
@@ -0,0 +1,183 @@
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_MMC=y
+CONFIG_SANDBOX_SPL=y
+CONFIG_PCI=y
+CONFIG_DEFAULT_DEVICE_TREE="sandbox"
+CONFIG_I8042_KEYB=y
+CONFIG_SPL=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_BOOTSTAGE_USER_COUNT=0x20
+CONFIG_BOOTSTAGE_FDT=y
+CONFIG_BOOTSTAGE_STASH=y
+CONFIG_BOOTSTAGE_STASH_ADDR=0x0
+CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
+CONFIG_CONSOLE_RECORD=y
+CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_GREPENV=y
+CONFIG_LOOPW=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MX_CYCLIC=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_DEMO=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_TFTPSRV=y
+CONFIG_CMD_RARP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CDP=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_SOUND=y
+CONFIG_CMD_QFW=y
+CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
+CONFIG_CMD_TPM_TEST=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_HOSTFILE=y
+CONFIG_SPL_OF_PLATDATA=y
+CONFIG_NETCONSOLE=y
+CONFIG_SPL_DM=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_DEVRES=y
+CONFIG_DEBUG_DEVRES=y
+# CONFIG_SPL_SIMPLE_BUS is not set
+CONFIG_ADC=y
+CONFIG_ADC_SANDBOX=y
+CONFIG_BLK=y
+CONFIG_CLK=y
+CONFIG_CPU=y
+CONFIG_DM_DEMO=y
+CONFIG_DM_DEMO_SIMPLE=y
+CONFIG_DM_DEMO_SHAPE=y
+CONFIG_PM8916_GPIO=y
+CONFIG_SANDBOX_GPIO=y
+CONFIG_DM_I2C_COMPAT=y
+CONFIG_I2C_CROS_EC_TUNNEL=y
+CONFIG_I2C_CROS_EC_LDO=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_SYS_I2C_SANDBOX=y
+CONFIG_I2C_MUX=y
+CONFIG_SPL_I2C_MUX=y
+CONFIG_I2C_ARB_GPIO_CHALLENGE=y
+CONFIG_CROS_EC_KEYB=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_DM_MAILBOX=y
+CONFIG_SANDBOX_MBOX=y
+CONFIG_MISC=y
+CONFIG_CMD_CROS_EC=y
+CONFIG_CROS_EC=y
+CONFIG_CROS_EC_I2C=y
+CONFIG_CROS_EC_LPC=y
+CONFIG_CROS_EC_SANDBOX=y
+CONFIG_CROS_EC_SPI=y
+CONFIG_PWRSEQ=y
+CONFIG_SPL_PWRSEQ=y
+CONFIG_SYSRESET=y
+CONFIG_DM_MMC_OPS=y
+CONFIG_SANDBOX_MMC=y
+CONFIG_SPI_FLASH_SANDBOX=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_ETH=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_SANDBOX=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_ROCKCHIP_PINCTRL=y
+CONFIG_ROCKCHIP_3036_PINCTRL=y
+CONFIG_PINCTRL_SANDBOX=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_ACT8846=y
+CONFIG_DM_PMIC_PFUZE100=y
+CONFIG_DM_PMIC_MAX77686=y
+CONFIG_PMIC_PM8916=y
+CONFIG_PMIC_RK808=y
+CONFIG_PMIC_S2MPS11=y
+CONFIG_DM_PMIC_SANDBOX=y
+CONFIG_PMIC_S5M8767=y
+CONFIG_PMIC_TPS65090=y
+CONFIG_DM_REGULATOR=y
+CONFIG_REGULATOR_ACT8846=y
+CONFIG_DM_REGULATOR_PFUZE100=y
+CONFIG_DM_REGULATOR_MAX77686=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK808=y
+CONFIG_REGULATOR_S5M8767=y
+CONFIG_DM_REGULATOR_SANDBOX=y
+CONFIG_REGULATOR_TPS65090=y
+CONFIG_RAM=y
+CONFIG_REMOTEPROC_SANDBOX=y
+CONFIG_DM_RESET=y
+CONFIG_SANDBOX_RESET=y
+CONFIG_DM_RTC=y
+CONFIG_SANDBOX_SERIAL=y
+CONFIG_SOUND=y
+CONFIG_SOUND_SANDBOX=y
+CONFIG_SANDBOX_SPI=y
+CONFIG_SPMI=y
+CONFIG_SPMI_SANDBOX=y
+CONFIG_TIMER=y
+CONFIG_TIMER_EARLY=y
+CONFIG_SANDBOX_TIMER=y
+CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EMUL=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_SYS_USB_EVENT_POLL=y
+CONFIG_DM_VIDEO=y
+CONFIG_CONSOLE_ROTATION=y
+CONFIG_CONSOLE_TRUETYPE=y
+CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
+CONFIG_VIDEO_SANDBOX_SDL=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_TPM=y
+CONFIG_LZ4=y
+CONFIG_ERRNO_STR=y
+CONFIG_UNIT_TEST=y
+CONFIG_UT_TIME=y
+CONFIG_UT_DM=y
+CONFIG_UT_ENV=y
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.
diff --git a/doc/driver-model/of-plat.txt b/doc/driver-model/of-plat.txt
new file mode 100644 (file)
index 0000000..86e5e25
--- /dev/null
@@ -0,0 +1,310 @@
+Driver Model Compiled-in Device Tree / Platform Data
+====================================================
+
+
+Introduction
+------------
+
+Device tree is the standard configuration method in U-Boot. It is used to
+define what devices are in the system and provide configuration information
+to these devices.
+
+The overhead of adding device tree access to U-Boot is fairly modest,
+approximately 3KB on Thumb 2 (plus the size of the DT itself). This means
+that in most cases it is best to use device tree for configuration.
+
+However there are some very constrained environments where U-Boot needs to
+work. These include SPL with severe memory limitations. For example, some
+SoCs require a 16KB SPL image which must include a full MMC stack. In this
+case the overhead of device tree access may be too great.
+
+It is possible to create platform data manually by defining C structures
+for it, and reference that data in a U_BOOT_DEVICE() declaration. This
+bypasses the use of device tree completely, effectively creating a parallel
+configuration mechanism. But it is an available option for SPL.
+
+As an alternative, a new 'of-platdata' feature is provided. This converts the
+device tree contents into C code which can be compiled into the SPL binary.
+This saves the 3KB of code overhead and perhaps a few hundred more bytes due
+to more efficient storage of the data.
+
+Note: Quite a bit of thought has gone into the design of this feature.
+However it still has many rough edges and comments and suggestions are
+strongly encouraged! Quite possibly there is a much better approach.
+
+
+Caveats
+-------
+
+There are many problems with this features. It should only be used when
+strictly necessary. Notable problems include:
+
+   - Device tree does not describe data types. But the C code must define a
+        type for each property. These are guessed using heuristics which
+        are wrong in several fairly common cases. For example an 8-byte value
+        is considered to be a 2-item integer array, and is byte-swapped. A
+        boolean value that is not present means 'false', but cannot be
+        included in the structures since there is generally no mention of it
+        in the device tree file.
+
+   - Naming of nodes and properties is automatic. This means that they follow
+        the naming in the device tree, which may result in C identifiers that
+        look a bit strange.
+
+   - It is not possible to find a value given a property name. Code must use
+        the associated C member variable directly in the code. This makes
+        the code less robust in the face of device-tree changes. It also
+        makes it very unlikely that your driver code will be useful for more
+        than one SoC. Even if the code is common, each SoC will end up with
+        a different C struct name, and a likely a different format for the
+        platform data.
+
+   - The platform data is provided to drivers as a C structure. The driver
+        must use the same structure to access the data. Since a driver
+        normally also supports device tree it must use #ifdef to separate
+        out this code, since the structures are only available in SPL.
+
+
+How it works
+------------
+
+The feature is enabled by CONFIG SPL_OF_PLATDATA. This is only available
+in SPL and should be tested with:
+
+        #if CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
+
+A new tool called 'dtoc' converts a device tree file either into a set of
+struct declarations, one for each compatible node, or a set of
+U_BOOT_DEVICE() declarations along with the actual platform data for each
+device. As an example, consider this MMC node:
+
+        sdmmc: dwmmc@ff0c0000 {
+                compatible = "rockchip,rk3288-dw-mshc";
+                clock-freq-min-max = <400000 150000000>;
+                clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+                         <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+                clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+                fifo-depth = <0x100>;
+                interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+                reg = <0xff0c0000 0x4000>;
+                bus-width = <4>;
+                cap-mmc-highspeed;
+                cap-sd-highspeed;
+                card-detect-delay = <200>;
+                disable-wp;
+                num-slots = <1>;
+                pinctrl-names = "default";
+                pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
+                vmmc-supply = <&vcc_sd>;
+                status = "okay";
+                u-boot,dm-pre-reloc;
+        };
+
+
+Some of these properties are dropped by U-Boot under control of the
+CONFIG_OF_SPL_REMOVE_PROPS option. The rest are processed. This will produce
+the following C struct declaration:
+
+struct dtd_rockchip_rk3288_dw_mshc {
+        fdt32_t         bus_width;
+        bool            cap_mmc_highspeed;
+        bool            cap_sd_highspeed;
+        fdt32_t         card_detect_delay;
+        fdt32_t         clock_freq_min_max[2];
+        struct phandle_2_cell clocks[4];
+        bool            disable_wp;
+        fdt32_t         fifo_depth;
+        fdt32_t         interrupts[3];
+        fdt32_t         num_slots;
+        fdt32_t         reg[2];
+        fdt32_t         vmmc_supply;
+};
+
+and the following device declaration:
+
+static struct dtd_rockchip_rk3288_dw_mshc dtv_dwmmc_at_ff0c0000 = {
+        .fifo_depth             = 0x100,
+        .cap_sd_highspeed       = true,
+        .interrupts             = {0x0, 0x20, 0x4},
+        .clock_freq_min_max     = {0x61a80, 0x8f0d180},
+        .vmmc_supply            = 0xb,
+        .num_slots              = 0x1,
+        .clocks                 = {{&dtv_clock_controller_at_ff760000, 456},
+                                   {&dtv_clock_controller_at_ff760000, 68},
+                                   {&dtv_clock_controller_at_ff760000, 114},
+                                   {&dtv_clock_controller_at_ff760000, 118}},
+        .cap_mmc_highspeed      = true,
+        .disable_wp             = true,
+        .bus_width              = 0x4,
+        .u_boot_dm_pre_reloc    = true,
+        .reg                    = {0xff0c0000, 0x4000},
+        .card_detect_delay      = 0xc8,
+};
+U_BOOT_DEVICE(dwmmc_at_ff0c0000) = {
+        .name           = "rockchip_rk3288_dw_mshc",
+        .platdata       = &dtv_dwmmc_at_ff0c0000,
+        .platdata_size  = sizeof(dtv_dwmmc_at_ff0c0000),
+};
+
+The device is then instantiated at run-time and the platform data can be
+accessed using:
+
+        struct udevice *dev;
+        struct dtd_rockchip_rk3288_dw_mshc *plat = dev_get_platdata(dev);
+
+This avoids the code overhead of converting the device tree data to
+platform data in the driver. The ofdata_to_platdata() method should
+therefore do nothing in such a driver.
+
+
+Converting of-platdata to a useful form
+---------------------------------------
+
+Of course it would be possible use the of-platdata directly in your driver
+whenever configuration information is required. However this meands that the
+driver will not be able to support device tree, since the of-platdata
+structure is not available when device tree is used. It would make no sense
+to use this structure if device tree were available, since the structure has
+all the limitations metioned in caveats above.
+
+Therefore it is recommended that the of-platdata structure should be used
+only in the probe() method of your driver. It cannot be used in the
+ofdata_to_platdata() method since this is not called when platform data is
+already present.
+
+
+How to structure your driver
+----------------------------
+
+Drivers should always support device tree as an option. The of-platdata
+feature is intended as a add-on to existing drivers.
+
+Your driver should convert the platdata struct in its probe() method. The
+existing device tree decoding logic should be kept in the
+ofdata_to_platdata() method and wrapped with #if.
+
+For example:
+
+    #include <dt-structs.h>
+
+    struct mmc_platdata {
+    #if CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
+            /* Put this first since driver model will copy the data here */
+            struct dtd_mmc dtplat;
+    #endif
+            /*
+             * Other fields can go here, to be filled in by decoding from
+             * the device tree (or the C structures when of-platdata is used).
+             */
+            int fifo_depth;
+    };
+
+    static int mmc_ofdata_to_platdata(struct udevice *dev)
+    {
+    #if !CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
+            /* Decode the device tree data */
+            struct mmc_platdata *plat = dev_get_platdata(dev);
+            const void *blob = gd->fdt_blob;
+            int node = dev->of_offset;
+
+            plat->fifo_depth = fdtdec_get_int(blob, node, "fifo-depth", 0);
+    #endif
+
+            return 0;
+    }
+
+    static int mmc_probe(struct udevice *dev)
+    {
+            struct mmc_platdata *plat = dev_get_platdata(dev);
+
+    #if CONFIG_IS_ENABLED(SPL_OF_PLATDATA)
+            /* Decode the of-platdata from the C structures */
+            struct dtd_mmc *dtplat = &plat->dtplat;
+
+            plat->fifo_depth = dtplat->fifo_depth;
+    #endif
+            /* Set up the device from the plat data */
+            writel(plat->fifo_depth, ...)
+    }
+
+    static const struct udevice_id mmc_ids[] = {
+            { .compatible = "vendor,mmc" },
+            { }
+    };
+
+    U_BOOT_DRIVER(mmc_drv) = {
+            .name           = "mmc",
+            .id             = UCLASS_MMC,
+            .of_match       = mmc_ids,
+            .ofdata_to_platdata = mmc_ofdata_to_platdata,
+            .probe          = mmc_probe,
+            .priv_auto_alloc_size = sizeof(struct mmc_priv),
+            .platdata_auto_alloc_size = sizeof(struct mmc_platdata),
+    };
+
+
+In the case where SPL_OF_PLATDATA is enabled, platdata_auto_alloc_size is
+still used to allocate space for the platform data. This is different from
+the normal behaviour and is triggered by the use of of-platdata (strictly
+speaking it is a non-zero platdata_size which triggers this).
+
+The of-platdata struct contents is copied from the C structure data to the
+start of the newly allocated area. In the case where device tree is used,
+the platform data is allocated, and starts zeroed. In this case the
+ofdata_to_platdata() method should still set up the platform data (and the
+of-platdata struct will not be present).
+
+SPL must use either of-platdata or device tree. Drivers cannot use both at
+the same time, but they must support device tree. Supporting of-platdata is
+optional.
+
+The device tree becomes in accessible when CONFIG_SPL_OF_PLATDATA is enabled,
+since the device-tree access code is not compiled in. A corollary is that
+a board can only move to using of-platdata if all the drivers it uses support
+it. There would be little point in having some drivers require the device
+tree data, since then libfdt would still be needed for those drivers and
+there would be no code-size benefit.
+
+Internals
+---------
+
+The dt-structs.h file includes the generated file
+(include/generated//dt-structs.h) if CONFIG_SPL_OF_PLATDATA is enabled.
+Otherwise (such as in U-Boot proper) these structs are not available. This
+prevents them being used inadvertently. All usage must be bracketed with
+#if CONFIG_IS_ENABLED(SPL_OF_PLATDATA).
+
+The dt-platdata.c file contains the device declarations and is is built in
+spl/dt-platdata.c.
+
+Some phandles (thsoe that are recognised as such) are converted into
+points to platform data. This pointer can potentially be used to access the
+referenced device (by searching for the pointer value). This feature is not
+yet implemented, however.
+
+The beginnings of a libfdt Python module are provided. So far this only
+implements a subset of the features.
+
+The 'swig' tool is needed to build the libfdt Python module. If this is not
+found then the Python model is not used and a fallback is used instead, which
+makes use of fdtget.
+
+
+Credits
+-------
+
+This is an implementation of an idea by Tom Rini <trini@konsulko.com>.
+
+
+Future work
+-----------
+- Consider programmatically reading binding files instead of device tree
+     contents
+- Complete the phandle feature
+- Move to using a full Python libfdt module
+
+--
+Simon Glass <sjg@chromium.org>
+Google, Inc
+6/6/16
+Updated Independence Day 2016
index 6e4d67220a1685ccf8ce3dca91cd83300783203c..e0f85677e3464e5de1ba81c6e942da3cd0129aaf 100644 (file)
@@ -10,6 +10,7 @@
 #include <clk.h>
 #include <clk-uclass.h>
 #include <dm.h>
+#include <dt-structs.h>
 #include <errno.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -21,6 +22,22 @@ static inline struct clk_ops *clk_dev_ops(struct udevice *dev)
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 #ifdef CONFIG_SPL_BUILD
+# if CONFIG_IS_ENABLED(OF_PLATDATA)
+int clk_get_by_index_platdata(struct udevice *dev, int index,
+                             struct phandle_2_cell *cells, struct clk *clk)
+{
+       int ret;
+
+       if (index != 0)
+               return -ENOSYS;
+       ret = uclass_get_device(UCLASS_CLK, 0, &clk->dev);
+       if (ret)
+               return ret;
+       clk->id = cells[0].id;
+
+       return 0;
+}
+# else
 int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
 {
        int ret;
@@ -39,6 +56,7 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
        clk->id = cell[1];
        return 0;
 }
+# endif /* OF_PLATDATA */
 
 int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
 {
@@ -117,8 +135,8 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
 
        return clk_get_by_index(dev, index, clk);
 }
-#endif
-#endif
+#endif /* CONFIG_SPL_BUILD */
+#endif /* OF_CONTROL */
 
 int clk_request(struct udevice *dev, struct clk *clk)
 {
index 797e5379075da87e5dac71ed7d61106c8dd9fbff..9c4d2b322f707e63cf43407792a740074f1b1939 100644 (file)
@@ -30,9 +30,11 @@ const struct clk_ops clk_fixed_rate_ops = {
 
 static int clk_fixed_rate_ofdata_to_platdata(struct udevice *dev)
 {
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
        to_clk_fixed_rate(dev)->fixed_rate =
                                fdtdec_get_int(gd->fdt_blob, dev->of_offset,
                                               "clock-frequency", 0);
+#endif
 
        return 0;
 }
index 2285453e8de284b93731370e73ee48490781b4f7..679f010bb7b1b1a47c77d9d7702f7cefbacf3f9d 100644 (file)
@@ -7,7 +7,9 @@
 #include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
+#include <dt-structs.h>
 #include <errno.h>
+#include <mapmem.h>
 #include <syscon.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+struct rk3288_clk_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       struct dtd_rockchip_rk3288_cru dtd;
+#endif
+};
+
 struct rk3288_clk_priv {
        struct rk3288_grf *grf;
        struct rk3288_cru *cru;
@@ -783,13 +791,30 @@ static struct clk_ops rk3288_clk_ops = {
        .set_rate       = rk3288_clk_set_rate,
 };
 
-static int rk3288_clk_probe(struct udevice *dev)
+static int rk3288_clk_ofdata_to_platdata(struct udevice *dev)
 {
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
        struct rk3288_clk_priv *priv = dev_get_priv(dev);
 
        priv->cru = (struct rk3288_cru *)dev_get_addr(dev);
+#endif
+
+       return 0;
+}
+
+static int rk3288_clk_probe(struct udevice *dev)
+{
+       struct rk3288_clk_priv *priv = dev_get_priv(dev);
+
        priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+       if (IS_ERR(priv->grf))
+               return PTR_ERR(priv->grf);
 #ifdef CONFIG_SPL_BUILD
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       struct rk3288_clk_plat *plat = dev_get_platdata(dev);
+
+       priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
+#endif
        rkclk_init(priv->cru, priv->grf);
 #endif
 
@@ -813,12 +838,14 @@ static const struct udevice_id rk3288_clk_ids[] = {
        { }
 };
 
-U_BOOT_DRIVER(clk_rk3288) = {
-       .name           = "clk_rk3288",
+U_BOOT_DRIVER(rockchip_rk3288_cru) = {
+       .name           = "rockchip_rk3288_cru",
        .id             = UCLASS_CLK,
        .of_match       = rk3288_clk_ids,
        .priv_auto_alloc_size = sizeof(struct rk3288_clk_priv),
+       .platdata_auto_alloc_size = sizeof(struct rk3288_clk_plat),
        .ops            = &rk3288_clk_ops,
        .bind           = rk3288_clk_bind,
+       .ofdata_to_platdata     = rk3288_clk_ofdata_to_platdata,
        .probe          = rk3288_clk_probe,
 };
index 0e56b23fbbf44b059b6e38afd1c8366ee245e764..a7f77b4a21dc33efbdc62b2983de5fb970cd8979 100644 (file)
@@ -112,7 +112,7 @@ int device_unbind(struct udevice *dev)
 
        devres_release_all(dev);
 
-       if (dev->flags & DM_NAME_ALLOCED)
+       if (dev->flags & DM_FLAG_NAME_ALLOCED)
                free((char *)dev->name);
        free(dev);
 
index f7fb0cc0fa7c60000153897316b1ef7ff5ae8e95..5bb1d7793dd687a9fed5475409b382e32effab92 100644 (file)
@@ -30,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR;
 static int device_bind_common(struct udevice *parent, const struct driver *drv,
                              const char *name, void *platdata,
                              ulong driver_data, int of_offset,
-                             struct udevice **devp)
+                             uint of_platdata_size, struct udevice **devp)
 {
        struct udevice *dev;
        struct uclass *uc;
@@ -84,12 +84,29 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
                }
        }
 
-       if (!dev->platdata && drv->platdata_auto_alloc_size) {
-               dev->flags |= DM_FLAG_ALLOC_PDATA;
-               dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
-               if (!dev->platdata) {
-                       ret = -ENOMEM;
-                       goto fail_alloc1;
+       if (drv->platdata_auto_alloc_size) {
+               bool alloc = !platdata;
+
+               if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+                       if (of_platdata_size) {
+                               dev->flags |= DM_FLAG_OF_PLATDATA;
+                               if (of_platdata_size <
+                                               drv->platdata_auto_alloc_size)
+                                       alloc = true;
+                       }
+               }
+               if (alloc) {
+                       dev->flags |= DM_FLAG_ALLOC_PDATA;
+                       dev->platdata = calloc(1,
+                                              drv->platdata_auto_alloc_size);
+                       if (!dev->platdata) {
+                               ret = -ENOMEM;
+                               goto fail_alloc1;
+                       }
+                       if (CONFIG_IS_ENABLED(OF_PLATDATA) && platdata) {
+                               memcpy(dev->platdata, platdata,
+                                      of_platdata_size);
+                       }
                }
        }
 
@@ -202,14 +219,14 @@ int device_bind_with_driver_data(struct udevice *parent,
                                 struct udevice **devp)
 {
        return device_bind_common(parent, drv, name, NULL, driver_data,
-                                 of_offset, devp);
+                                 of_offset, 0, devp);
 }
 
 int device_bind(struct udevice *parent, const struct driver *drv,
                const char *name, void *platdata, int of_offset,
                struct udevice **devp)
 {
-       return device_bind_common(parent, drv, name, platdata, 0, of_offset,
+       return device_bind_common(parent, drv, name, platdata, 0, of_offset, 0,
                                  devp);
 }
 
@@ -217,6 +234,7 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
                        const struct driver_info *info, struct udevice **devp)
 {
        struct driver *drv;
+       uint platdata_size = 0;
 
        drv = lists_driver_lookup_name(info->name);
        if (!drv)
@@ -224,8 +242,11 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
        if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC))
                return -EPERM;
 
-       return device_bind(parent, drv, info->name, (void *)info->platdata,
-                          -1, devp);
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       platdata_size = info->platdata_size;
+#endif
+       return device_bind_common(parent, drv, info->name,
+                       (void *)info->platdata, 0, -1, platdata_size, devp);
 }
 
 static void *alloc_priv(int size, uint flags)
@@ -608,7 +629,7 @@ const char *dev_get_uclass_name(struct udevice *dev)
 
 fdt_addr_t dev_get_addr_index(struct udevice *dev, int index)
 {
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
        fdt_addr_t addr;
 
        if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {
@@ -738,7 +759,7 @@ bool device_is_last_sibling(struct udevice *dev)
 
 void device_set_name_alloced(struct udevice *dev)
 {
-       dev->flags |= DM_NAME_ALLOCED;
+       dev->flags |= DM_FLAG_NAME_ALLOCED;
 }
 
 int device_set_name(struct udevice *dev, const char *name)
index 0c277177909666e1dedfd12efbd6ca3b531549f1..6a634e695180cd35b35619ee6bdb10dbfa31ec08 100644 (file)
@@ -99,7 +99,7 @@ int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
        return 0;
 }
 
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 /**
  * driver_check_compatible() - Check if a driver is compatible with this node
  *
index 519832f173307e95a9862e33679c9f0707218696..0299ff087937f406a939a15a585046b900584143 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static struct regmap *regmap_alloc_count(int count)
+{
+       struct regmap *map;
+
+       map = malloc(sizeof(struct regmap));
+       if (!map)
+               return NULL;
+       if (count <= 1) {
+               map->range = &map->base_range;
+       } else {
+               map->range = malloc(count * sizeof(struct regmap_range));
+               if (!map->range) {
+                       free(map);
+                       return NULL;
+               }
+       }
+       map->range_count = count;
+
+       return map;
+}
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+int regmap_init_mem_platdata(struct udevice *dev, u32 *reg, int count,
+                            struct regmap **mapp)
+{
+       struct regmap_range *range;
+       struct regmap *map;
+
+       map = regmap_alloc_count(count);
+       if (!map)
+               return -ENOMEM;
+
+       map->base = *reg;
+       for (range = map->range; count > 0; reg += 2, range++, count--) {
+               range->start = *reg;
+               range->size = reg[1];
+       }
+
+       *mapp = map;
+
+       return 0;
+}
+#else
 int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
 {
        const void *blob = gd->fdt_blob;
@@ -37,22 +80,11 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
        if (!cell || !count)
                return -EINVAL;
 
-       map = malloc(sizeof(struct regmap));
+       map = regmap_alloc_count(count);
        if (!map)
                return -ENOMEM;
 
-       if (count <= 1) {
-               map->range = &map->base_range;
-       } else {
-               map->range = malloc(count * sizeof(struct regmap_range));
-               if (!map->range) {
-                       free(map);
-                       return -ENOMEM;
-               }
-       }
-
        map->base = fdtdec_get_number(cell, addr_len);
-       map->range_count = count;
 
        for (range = map->range; count > 0;
             count--, cell += both_len, range++) {
@@ -64,6 +96,7 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
 
        return 0;
 }
+#endif
 
 void *regmap_get_range(struct regmap *map, unsigned int range_num)
 {
index 95886add2381fc864a75f976b3fe4e8f444b7bb6..158702406ed19e617307de370a9ba4d6ab6b1565 100644 (file)
@@ -188,7 +188,7 @@ int dm_scan_platdata(bool pre_reloc_only)
        return ret;
 }
 
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
                     bool pre_reloc_only)
 {
@@ -244,7 +244,7 @@ int dm_init_and_scan(bool pre_reloc_only)
                return ret;
        }
 
-       if (CONFIG_IS_ENABLED(OF_CONTROL)) {
+       if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
                ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
                if (ret) {
                        debug("dm_scan_fdt() failed: %d\n", ret);
index e03f46af5739d7156ad0270a438e4744496e535f..01bd9683a7a757ccf20a9a769c83ee1555350cd6 100644 (file)
@@ -29,7 +29,20 @@ static int syscon_pre_probe(struct udevice *dev)
 {
        struct syscon_uc_info *priv = dev_get_uclass_priv(dev);
 
+       /*
+        * With OF_PLATDATA we really have no way of knowing the format of
+        * the device-specific platform data. So we assume that it starts with
+        * a 'reg' member, and this holds a single address and size. Drivers
+        * using OF_PLATDATA will need to ensure that this is true.
+        */
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       struct syscon_base_platdata *plat = dev_get_platdata(dev);
+
+       return regmap_init_mem_platdata(dev, plat->reg, ARRAY_SIZE(plat->reg),
+                                       &priv->regmap);
+#else
        return regmap_init_mem(dev, &priv->regmap);
+#endif
 }
 
 int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp)
index 066639ba1f10018595baedf75006567b94c6ef98..fff6f0cdf95bc1bf5a821d002cd02658bfd3e68b 100644 (file)
@@ -29,12 +29,19 @@ obj-$(CONFIG_PDSP188x) += pdsp188x.o
 obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
 obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
 ifdef CONFIG_DM_I2C
+ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
 endif
+endif
 obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
 obj-$(CONFIG_SMSC_SIO1007) += smsc_sio1007.o
 obj-$(CONFIG_STATUS_LED) += status_led.o
 obj-$(CONFIG_SANDBOX) += swap_case.o
+ifdef CONFIG_SPL_OF_PLATDATA
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SANDBOX) += spltest_sandbox.o
+endif
+endif
 obj-$(CONFIG_SANDBOX) += syscon_sandbox.o
 obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
 obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
diff --git a/drivers/misc/spltest_sandbox.c b/drivers/misc/spltest_sandbox.c
new file mode 100644 (file)
index 0000000..1fef825
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sandbox_spl_probe(struct udevice *dev)
+{
+       struct dtd_sandbox_spl_test *plat = dev_get_platdata(dev);
+       int i;
+
+       printf("of-platdata probe:\n");
+       printf("bool %d\n", plat->boolval);
+
+       printf("byte %02x\n", plat->byteval);
+       printf("bytearray");
+       for (i = 0; i < sizeof(plat->bytearray); i++)
+               printf(" %02x", plat->bytearray[i]);
+       printf("\n");
+
+       printf("int %d\n", plat->intval);
+       printf("intarray");
+       for (i = 0; i < ARRAY_SIZE(plat->intarray); i++)
+               printf(" %d", plat->intarray[i]);
+       printf("\n");
+
+       printf("longbytearray");
+       for (i = 0; i < sizeof(plat->longbytearray); i++)
+               printf(" %02x", plat->longbytearray[i]);
+       printf("\n");
+
+       printf("string %s\n", plat->stringval);
+       printf("stringarray");
+       for (i = 0; i < ARRAY_SIZE(plat->stringarray); i++)
+               printf(" \"%s\"", plat->stringarray[i]);
+       printf("\n");
+
+       return 0;
+}
+
+U_BOOT_DRIVER(sandbox_spl_test) = {
+       .name   = "sandbox_spl_test",
+       .id     = UCLASS_MISC,
+       .flags  = DM_FLAG_PRE_RELOC,
+       .probe  = sandbox_spl_probe,
+};
index 863bbb3f64b27ea6ef1e860a7a7bd743426567ba..283befccfbe6ceca869b4cc51c1df0628570aaa1 100644 (file)
 #define        DWMMC_MMC0_SDR_TIMING_VAL       0x03030001
 #define        DWMMC_MMC2_SDR_TIMING_VAL       0x03020001
 
+#ifdef CONFIG_DM_MMC
+#include <dm.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+struct exynos_mmc_plat {
+       struct mmc_config cfg;
+       struct mmc mmc;
+};
+#endif
+
 /* Exynos implmentation specific drver private data */
 struct dwmci_exynos_priv_data {
+#ifdef CONFIG_DM_MMC
+       struct dwmci_host host;
+#endif
        u32 sdr_timing;
 };
 
@@ -80,11 +93,10 @@ static void exynos_dwmci_board_init(struct dwmci_host *host)
                exynos_dwmci_clksel(host);
 }
 
-static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
+static int exynos_dwmci_core_init(struct dwmci_host *host)
 {
        unsigned int div;
        unsigned long freq, sclk;
-       struct dwmci_exynos_priv_data *priv = host->priv;
 
        if (host->bus_hz)
                freq = host->bus_hz;
@@ -92,10 +104,10 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
                freq = DWMMC_MAX_FREQ;
 
        /* request mmc clock vlaue of 52MHz.  */
-       sclk = get_mmc_clk(index);
+       sclk = get_mmc_clk(host->dev_index);
        div = DIV_ROUND_UP(sclk, freq);
        /* set the clock divisor for mmc */
-       set_mmc_clk(index, div);
+       set_mmc_clk(host->dev_index, div);
 
        host->name = "EXYNOS DWMMC";
 #ifdef CONFIG_EXYNOS5420
@@ -103,78 +115,35 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
 #endif
        host->board_init = exynos_dwmci_board_init;
 
-       if (!priv->sdr_timing) {
-               if (index == 0)
-                       priv->sdr_timing = DWMMC_MMC0_SDR_TIMING_VAL;
-               else if (index == 2)
-                       priv->sdr_timing = DWMMC_MMC2_SDR_TIMING_VAL;
-       }
-
        host->caps = MMC_MODE_DDR_52MHz;
        host->clksel = exynos_dwmci_clksel;
-       host->dev_index = index;
        host->get_mmc_clk = exynos_dwmci_get_clk;
+
+#ifndef CONFIG_DM_MMC
        /* Add the mmc channel to be registered with mmc core */
        if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) {
-               printf("DWMMC%d registration failed\n", index);
+               printf("DWMMC%d registration failed\n", host->dev_index);
                return -1;
        }
-       return 0;
-}
-
-/*
- * This function adds the mmc channel to be registered with mmc core.
- * index -     mmc channel number.
- * regbase -   register base address of mmc channel specified in 'index'.
- * bus_width - operating bus width of mmc channel specified in 'index'.
- * clksel -    value to be written into CLKSEL register in case of FDT.
- *             NULL in case od non-FDT.
- */
-int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
-{
-       struct dwmci_host *host = NULL;
-       struct dwmci_exynos_priv_data *priv;
-
-       host = malloc(sizeof(struct dwmci_host));
-       if (!host) {
-               error("dwmci_host malloc fail!\n");
-               return -ENOMEM;
-       }
-
-       priv = malloc(sizeof(struct dwmci_exynos_priv_data));
-       if (!priv) {
-               error("dwmci_exynos_priv_data malloc fail!\n");
-               return -ENOMEM;
-       }
-
-       host->ioaddr = (void *)regbase;
-       host->buswidth = bus_width;
-
-       if (clksel)
-               priv->sdr_timing = clksel;
-
-       host->priv = priv;
+#endif
 
-       return exynos_dwmci_core_init(host, index);
+       return 0;
 }
 
-#if CONFIG_IS_ENABLED(OF_CONTROL)
 static struct dwmci_host dwmci_host[DWMMC_MAX_CH_NUM];
 
 static int do_dwmci_init(struct dwmci_host *host)
 {
-       int index, flag, err;
-
-       index = host->dev_index;
+       int flag, err;
 
        flag = host->buswidth == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE;
        err = exynos_pinmux_config(host->dev_id, flag);
        if (err) {
-               printf("DWMMC%d not configure\n", index);
+               printf("DWMMC%d not configure\n", host->dev_index);
                return err;
        }
 
-       return exynos_dwmci_core_init(host, index);
+       return exynos_dwmci_core_init(host);
 }
 
 static int exynos_dwmci_get_config(const void *blob, int node,
@@ -197,13 +166,14 @@ static int exynos_dwmci_get_config(const void *blob, int node,
        if (host->dev_index == host->dev_id)
                host->dev_index = host->dev_id - PERIPH_ID_SDMMC0;
 
-       /* Get the bus width from the device node */
-       host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
-       if (host->buswidth <= 0) {
-               printf("DWMMC%d: Can't get bus-width\n", host->dev_index);
+       if (host->dev_index > 4) {
+               printf("DWMMC%d: Can't get the dev index\n", host->dev_index);
                return -EINVAL;
        }
 
+       /* Get the bus width from the device node (Default is 4bit buswidth) */
+       host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 4);
+
        /* Set the base address from the device node */
        base = fdtdec_get_addr(blob, node, "reg");
        if (!base) {
@@ -265,15 +235,13 @@ static int exynos_dwmci_process_node(const void *blob,
 
 int exynos_dwmmc_init(const void *blob)
 {
-       int compat_id;
        int node_list[DWMMC_MAX_CH_NUM];
        int boot_dev_node;
        int err = 0, count;
 
-       compat_id = COMPAT_SAMSUNG_EXYNOS_DWMMC;
-
        count = fdtdec_find_aliases_for_id(blob, "mmc",
-                               compat_id, node_list, DWMMC_MAX_CH_NUM);
+                       COMPAT_SAMSUNG_EXYNOS_DWMMC, node_list,
+                       DWMMC_MAX_CH_NUM);
 
        /* For DWMMC always set boot device as mmc 0 */
        if (count >= 3 && get_boot_mode() == BOOT_MODE_SD) {
@@ -286,4 +254,58 @@ int exynos_dwmmc_init(const void *blob)
 
        return err;
 }
+
+#ifdef CONFIG_DM_MMC
+static int exynos_dwmmc_probe(struct udevice *dev)
+{
+       struct exynos_mmc_plat *plat = dev_get_platdata(dev);
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+       struct dwmci_exynos_priv_data *priv = dev_get_priv(dev);
+       struct dwmci_host *host = &priv->host;
+       int err;
+
+       err = exynos_dwmci_get_config(gd->fdt_blob, dev->of_offset, host);
+       if (err)
+               return err;
+       err = do_dwmci_init(host);
+       if (err)
+               return err;
+
+       dwmci_setup_cfg(&plat->cfg, host->name, host->buswidth, host->caps,
+                       DWMMC_MAX_FREQ, DWMMC_MIN_FREQ);
+       host->mmc = &plat->mmc;
+       host->mmc->priv = &priv->host;
+       host->priv = dev;
+       upriv->mmc = host->mmc;
+
+       return dwmci_probe(dev);
+}
+
+static int exynos_dwmmc_bind(struct udevice *dev)
+{
+       struct exynos_mmc_plat *plat = dev_get_platdata(dev);
+       int ret;
+
+       ret = dwmci_bind(dev, &plat->mmc, &plat->cfg);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static const struct udevice_id exynos_dwmmc_ids[] = {
+       { .compatible = "samsung,exynos4412-dw-mshc" },
+       { }
+};
+
+U_BOOT_DRIVER(exynos_dwmmc_drv) = {
+       .name           = "exynos_dwmmc",
+       .id             = UCLASS_MMC,
+       .of_match       = exynos_dwmmc_ids,
+       .bind           = exynos_dwmmc_bind,
+       .ops            = &dm_dwmci_ops,
+       .probe          = exynos_dwmmc_probe,
+       .priv_auto_alloc_size   = sizeof(struct dwmci_exynos_priv_data),
+       .platdata_auto_alloc_size = sizeof(struct exynos_mmc_plat),
+};
 #endif
index 691a51557de4e89b41f3b975618fe6ba28a7c111..020a59b92187a96ca9426d59e9ea578bd83f3a43 100644 (file)
@@ -7,8 +7,10 @@
 #include <common.h>
 #include <clk.h>
 #include <dm.h>
+#include <dt-structs.h>
 #include <dwmmc.h>
 #include <errno.h>
+#include <mapmem.h>
 #include <pwrseq.h>
 #include <syscon.h>
 #include <asm/gpio.h>
@@ -19,6 +21,9 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 struct rockchip_mmc_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       struct dtd_rockchip_rk3288_dw_mshc dtplat;
+#endif
        struct mmc_config cfg;
        struct mmc mmc;
 };
@@ -26,6 +31,9 @@ struct rockchip_mmc_plat {
 struct rockchip_dwmmc_priv {
        struct clk clk;
        struct dwmci_host host;
+       int fifo_depth;
+       bool fifo_mode;
+       u32 minmax[2];
 };
 
 static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq)
@@ -45,6 +53,7 @@ static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq)
 
 static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
 {
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
        struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
        struct dwmci_host *host = &priv->host;
 
@@ -61,6 +70,16 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
        else
                host->dev_index = 1;
 
+       priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+                                   "fifo-depth", 0);
+       if (priv->fifo_depth < 0)
+               return -EINVAL;
+       priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+                                         "fifo-mode");
+       if (fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
+                                "clock-freq-min-max", priv->minmax, 2))
+               return -EINVAL;
+#endif
        return 0;
 }
 
@@ -71,28 +90,34 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
        struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
        struct dwmci_host *host = &priv->host;
        struct udevice *pwr_dev __maybe_unused;
-       u32 minmax[2];
        int ret;
-       int fifo_depth;
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       struct dtd_rockchip_rk3288_dw_mshc *dtplat = &plat->dtplat;
+
+       host->name = dev->name;
+       host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
+       host->buswidth = dtplat->bus_width;
+       host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk;
+       host->priv = dev;
+       host->dev_index = 0;
+       priv->fifo_depth = dtplat->fifo_depth;
+       priv->fifo_mode = 0;
+       memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
+
+       ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+       if (ret < 0)
+               return ret;
+#else
        ret = clk_get_by_index(dev, 0, &priv->clk);
        if (ret < 0)
                return ret;
-
-       if (fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
-                                "clock-freq-min-max", minmax, 2))
-               return -EINVAL;
-
-       fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
-                                   "fifo-depth", 0);
-       if (fifo_depth < 0)
-               return -EINVAL;
-
+#endif
        host->fifoth_val = MSIZE(0x2) |
-               RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2);
+               RX_WMARK(priv->fifo_depth / 2 - 1) |
+               TX_WMARK(priv->fifo_depth / 2);
 
-       if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "fifo-mode"))
-               host->fifo_mode = true;
+       host->fifo_mode = priv->fifo_mode;
 
 #ifdef CONFIG_PWRSEQ
        /* Enable power if needed */
@@ -105,7 +130,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
        }
 #endif
        dwmci_setup_cfg(&plat->cfg, dev->name, host->buswidth, host->caps,
-                       minmax[1], minmax[0]);
+                       priv->minmax[1], priv->minmax[0]);
        host->mmc = &plat->mmc;
        host->mmc->priv = &priv->host;
        host->mmc->dev = dev;
@@ -132,7 +157,7 @@ static const struct udevice_id rockchip_dwmmc_ids[] = {
 };
 
 U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
-       .name           = "rockchip_dwmmc",
+       .name           = "rockchip_rk3288_dw_mshc",
        .id             = UCLASS_MMC,
        .of_match       = rockchip_dwmmc_ids,
        .ofdata_to_platdata = rockchip_dwmmc_ofdata_to_platdata,
index 1fa1daa939c75c296d62bbf240bd667eb691e1fc..8cb3b8228ed3aa4f61e68d8684e045448505a2d3 100644 (file)
@@ -476,6 +476,7 @@ static int rk3288_pinctrl_request(struct udevice *dev, int func, int flags)
 static int rk3288_pinctrl_get_periph_id(struct udevice *dev,
                                        struct udevice *periph)
 {
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
        u32 cell[3];
        int ret;
 
@@ -506,6 +507,7 @@ static int rk3288_pinctrl_get_periph_id(struct udevice *dev,
        case 103:
                return PERIPH_ID_HDMI;
        }
+#endif
 
        return -ENOENT;
 }
@@ -664,8 +666,12 @@ static struct pinctrl_ops rk3288_pinctrl_ops = {
 
 static int rk3288_pinctrl_bind(struct udevice *dev)
 {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       return 0;
+#else
        /* scan child GPIO banks */
        return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+#endif
 }
 
 #ifndef CONFIG_SPL_BUILD
@@ -719,7 +725,7 @@ static const struct udevice_id rk3288_pinctrl_ids[] = {
 };
 
 U_BOOT_DRIVER(pinctrl_rk3288) = {
-       .name           = "pinctrl_rk3288",
+       .name           = "rockchip_rk3288_pinctrl",
        .id             = UCLASS_PINCTRL,
        .of_match       = rk3288_pinctrl_ids,
        .priv_auto_alloc_size = sizeof(struct rk3288_pinctrl_priv),
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 0e3890391b24342429b8ea2ad1b89273424bd6bb..9ff7234d61e787ce4f2a201f0a1569ed220ea06c 100644 (file)
@@ -312,6 +312,15 @@ config SYS_NS16550
          be used. It can be a constant or a function to get clock, eg,
          get_serial_clock().
 
+config ROCKCHIP_SERIAL
+       bool "Rockchip on-chip UART support"
+       depends on DM_SERIAL && SPL_OF_PLATDATA
+       help
+         Select this to enable a debug UART for Rockchip devices when using
+         CONFIG_OF_PLATDATA (i.e. a compiled-in device tree replacemenmt).
+         This uses the ns16550 driver, converting the platdata from of-platdata
+         to the ns16550 format.
+
 config SANDBOX_SERIAL
        bool "Sandbox UART support"
        depends on SANDBOX
index 92cbea59135abeabee0e7133f1bba417a9aae8cc..6986d659ab05e0f7fa29c1bd29733205cfad4354 100644 (file)
@@ -28,6 +28,9 @@ obj-$(CONFIG_S5P) += serial_s5p.o
 obj-$(CONFIG_MXC_UART) += serial_mxc.o
 obj-$(CONFIG_PXA_SERIAL) += serial_pxa.o
 obj-$(CONFIG_MESON_SERIAL) += serial_meson.o
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_ROCKCHIP_SERIAL) += serial_rockchip.o
+endif
 obj-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o
 obj-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
 obj-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
index c6cb3eb500cae251509f3979a688469dedd4d3c4..88fca15357e6414915427d79d561669d67a156d9 100644 (file)
@@ -347,7 +347,7 @@ int ns16550_serial_probe(struct udevice *dev)
        return 0;
 }
 
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
 {
        struct ns16550_platdata *plat = dev->platdata;
@@ -416,6 +416,7 @@ const struct dm_serial_ops ns16550_serial_ops = {
        .setbrg = ns16550_serial_setbrg,
 };
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 /*
  * Please consider existing compatible strings before adding a new
@@ -452,4 +453,5 @@ U_BOOT_DRIVER(ns16550_serial) = {
        .flags  = DM_FLAG_PRE_RELOC,
 };
 #endif
+#endif /* !OF_PLATDATA */
 #endif /* CONFIG_DM_SERIAL */
index 58f882b22a607b4b698e8c0d5e89642e56b208f5..bcc3465312e8819c71ff3667b3847b09e6de84bd 100644 (file)
@@ -115,7 +115,9 @@ static int sandbox_serial_pending(struct udevice *dev, bool input)
                return 0;
 
        os_usleep(100);
+#ifndef CONFIG_SPL_BUILD
        video_sync_all();
+#endif
        if (next_index == serial_buf_read)
                return 1;       /* buffer full */
 
index 0ce5c44f3315ca5244a8d097ba093bc2654350d4..19f38e162e0fcebb1e8488a2c7bde041108039c0 100644 (file)
@@ -33,7 +33,13 @@ static void serial_find_console_or_panic(void)
        struct udevice *dev;
        int node;
 
-       if (CONFIG_IS_ENABLED(OF_CONTROL) && blob) {
+       if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+               uclass_first_device(UCLASS_SERIAL, &dev);
+               if (dev) {
+                       gd->cur_serial_dev = dev;
+                       return;
+               }
+       } else if (CONFIG_IS_ENABLED(OF_CONTROL) && blob) {
                /* Check for a chosen console */
                node = fdtdec_get_chosen_node(blob, "stdout-path");
                if (node < 0) {
diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c
new file mode 100644 (file)
index 0000000..6bac95a
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <ns16550.h>
+#include <serial.h>
+#include <asm/arch/clock.h>
+
+struct rockchip_uart_platdata {
+       struct dtd_rockchip_rk3288_uart dtplat;
+       struct ns16550_platdata plat;
+};
+
+struct dtd_rockchip_rk3288_uart *dtplat, s_dtplat;
+
+static int rockchip_serial_probe(struct udevice *dev)
+{
+       struct rockchip_uart_platdata *plat = dev_get_platdata(dev);
+
+       /* Create some new platform data for the standard driver */
+       plat->plat.base = plat->dtplat.reg[0];
+       plat->plat.reg_shift = plat->dtplat.reg_shift;
+       plat->plat.clock = plat->dtplat.clock_frequency;
+       dev->platdata = &plat->plat;
+
+       return ns16550_serial_probe(dev);
+}
+
+U_BOOT_DRIVER(rockchip_rk3288_uart) = {
+       .name   = "rockchip_rk3288_uart",
+       .id     = UCLASS_SERIAL,
+       .priv_auto_alloc_size = sizeof(struct NS16550),
+       .platdata_auto_alloc_size = sizeof(struct rockchip_uart_platdata),
+       .probe  = rockchip_serial_probe,
+       .ops    = &ns16550_serial_ops,
+       .flags  = DM_FLAG_PRE_RELOC,
+};
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 c56c1299c09f65e445e80fe1da6e12516b74834c..4b7d8b15cc04d7f3a81ab7edf50268901ee4cf8c 100644 (file)
@@ -85,4 +85,25 @@ config OF_SPL_REMOVE_PROPS
          can be discarded. This option defines the list of properties to
          discard.
 
+config SPL_OF_PLATDATA
+       bool "Generate platform data for use in SPL"
+       depends on SPL_OF_CONTROL
+       help
+         For very constrained SPL environments the overhead of decoding
+         device tree nodes and converting their contents into platform data
+         is too large. This overhead includes libfdt code as well as the
+         device tree contents itself. The latter is fairly compact, but the
+         former can add 3KB or more to a Thumb 2 Image.
+
+         This option enables generation of platform data from the device
+         tree as C code. This code creates devices using U_BOOT_DEVICE()
+         declarations. The benefit is that it allows driver code to access
+         the platform data directly in C structures, avoidin the libfdt
+         overhead.
+
+         This option works by generating C structure declarations for each
+         compatible string, then adding platform data and U_BOOT_DEVICE
+         declarations for each node. See README.platdata for more
+         information.
+
 endmenu
index 2f31cf70e3de8dbf1cf3a5ee471911dede1b2ea1..161bc2825fc0f77f3281035271cb736651bf4990 100644 (file)
@@ -60,6 +60,10 @@ struct clk {
 };
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
+struct phandle_2_cell;
+int clk_get_by_index_platdata(struct udevice *dev, int index,
+                             struct phandle_2_cell *cells, struct clk *clk);
+
 /**
  * clock_get_by_index - Get/request a clock by integer index.
  *
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 23a0c40ca528a8377416d4036f6d46ffdeff29e2..4de89f8879d07105e3d5240fc8f62edad4b1a8be 100644 (file)
 
 #endif
 
+#ifndef CONFIG_SPL_BUILD
 #define CONFIG_IO_TRACE
 #define CONFIG_CMD_IOTRACE
+#endif
 
 #ifndef CONFIG_TIMER
 #define CONFIG_SYS_TIMER_RATE          1000000
 #define CONFIG_CMD_LZMADEC
 #define CONFIG_CMD_DATE
 
+#ifndef CONFIG_SPL_BUILD
 #define CONFIG_CMD_IDE
 #define CONFIG_SYS_IDE_MAXBUS          1
 #define CONFIG_SYS_ATA_IDE0_OFFSET     0
 #define CONFIG_SYS_ATA_REG_OFFSET      1
 #define CONFIG_SYS_ATA_ALT_OFFSET      2
 #define CONFIG_SYS_ATA_STRIDE          4
+#endif
 
 #define CONFIG_SCSI
 #define CONFIG_SCSI_AHCI_PLAT
diff --git a/include/configs/sandbox_spl.h b/include/configs/sandbox_spl.h
new file mode 100644 (file)
index 0000000..ffc3098
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __SANDBOX_SPL_CONFIG_H
+#define __SANDBOX_SPL_CONFIG_H
+
+#include <configs/sandbox.h>
+
+#define CONFIG_SPL_BOARD_INIT
+
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+#define CONFIG_SPL_ENV_SUPPORT
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+
+#endif
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 1bfcf3bcbc012ae0994625b78ce166a5070ca897..c825d472366a33d810b8adda8e9d7b88701839a4 100644 (file)
@@ -42,7 +42,9 @@ struct driver_info;
 #define DM_FLAG_BOUND                  (1 << 6)
 
 /* Device name is allocated and should be freed on unbind() */
-#define DM_NAME_ALLOCED                        (1 << 7)
+#define DM_FLAG_NAME_ALLOCED           (1 << 7)
+
+#define DM_FLAG_OF_PLATDATA            (1 << 8)
 
 /**
  * struct udevice - An instance of a driver
@@ -553,7 +555,7 @@ int device_set_name(struct udevice *dev, const char *name);
 /**
  * device_set_name_alloced() - note that a device name is allocated
  *
- * This sets the DM_NAME_ALLOCED flag for the device, so that when it is
+ * This sets the DM_FLAG_NAME_ALLOCED flag for the device, so that when it is
  * unbound the name will be freed. This avoids memory leaks.
  *
  * @dev:       Device to update
index 6f4f00140e5690f404b3169e2dce4e2c0133e735..488b2ab0aea446f524b7edede8cc7ee583b920b5 100644 (file)
  *
  * @name:      Driver name
  * @platdata:  Driver-specific platform data
+ * @platdata_size: Size of platform data structure
+ * @flags:     Platform data flags (DM_FLAG_...)
  */
 struct driver_info {
        const char *name;
        const void *platdata;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       uint platdata_size;
+#endif
 };
 
 /**
diff --git a/include/dt-structs.h b/include/dt-structs.h
new file mode 100644 (file)
index 0000000..e13afa6
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __DT_STTUCTS
+#define __DT_STTUCTS
+
+/* These structures may only be used in SPL */
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+struct phandle_2_cell {
+       const void *node;
+       int id;
+};
+#include <generated/dt-structs.h>
+#endif
+
+#endif
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.
index 954a48c9919e78a9259b615d6be12aa01c1ef4b3..1782e50e77511769b19b7a83679d5521107e5f8e 100644 (file)
@@ -286,6 +286,31 @@ int os_read_ram_buf(const char *fname);
  */
 int os_jump_to_image(const void *dest, int size);
 
+/**
+ * os_find_u_boot() - Determine the path to U-Boot proper
+ *
+ * This function is intended to be called from within sandbox SPL. It uses
+ * a few heuristics to find U-Boot proper. Normally it is either in the same
+ * directory, or the directory above (since u-boot-spl is normally in an
+ * spl/ subdirectory when built).
+ *
+ * @fname:     Place to put full path to U-Boot
+ * @maxlen:    Maximum size of @fname
+ * @return 0 if OK, -NOSPC if the filename is too large, -ENOENT if not found
+ */
+int os_find_u_boot(char *fname, int maxlen);
+
+/**
+ * os_spl_to_uboot() - Run U-Boot proper
+ *
+ * When called from SPL, this runs U-Boot proper. The filename is obtained by
+ * calling os_find_u_boot().
+ *
+ * @fname:     Full pathname to U-Boot executable
+ * @return 0 if OK, -ve on error
+ */
+int os_spl_to_uboot(const char *fname);
+
 /**
  * Read the current system time
  *
index eccf7707f456568de6cd371d6d971e71bd403ee6..1eed94e47a32d4eaa67e01a6ba22d05f5951ffe7 100644 (file)
@@ -56,6 +56,22 @@ int regmap_read(struct regmap *map, uint offset, uint *valp);
  */
 int regmap_init_mem(struct udevice *dev, struct regmap **mapp);
 
+/**
+ * regmap_init_mem_platdata() - Set up a new memory register map for of-platdata
+ *
+ * This creates a new regmap with a list of regions passed in, rather than
+ * using the device tree. It only supports 32-bit machines.
+ *
+ * Use regmap_uninit() to free it.
+ *
+ * @dev:       Device that uses this map
+ * @reg:       List of address, size pairs
+ * @count:     Number of pairs (e.g. 1 if the regmap has a single entry)
+ * @mapp:      Returns allocated map
+ */
+int regmap_init_mem_platdata(struct udevice *dev, u32 *reg, int count,
+                            struct regmap **mapp);
+
 /**
  * regmap_get_range() - Obtain the base memory address of a regmap range
  *
index 4593b6e3ebfdb96e7869cc9cc88045eaa42cb35d..34842aa4705891928df2f1346f22803f80116caa 100644 (file)
@@ -23,6 +23,17 @@ struct syscon_ops {
 
 #define syscon_get_ops(dev)        ((struct syscon_ops *)(dev)->driver->ops)
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+/*
+ * We don't support 64-bit machines. If they are so resource-contrained that
+ * they need to use OF_PLATDATA, something is horribly wrong with the
+ * education of our hardware engineers.
+ */
+struct syscon_base_platdata {
+       u32 reg[2];
+};
+#endif
+
 /**
  * syscon_get_regmap() - Get access to a register map
  *
index f48d90103d2134f841912ff9c82450d6b8707087..f6a8ba1227f00f45d0a8b5cbf4412ea14b665f27 100644 (file)
@@ -48,11 +48,10 @@ obj-$(CONFIG_$(SPL_)SHA1) += sha1.o
 obj-$(CONFIG_$(SPL_)SHA256) += sha256.o
 
 obj-$(CONFIG_$(SPL_)OF_LIBFDT) += libfdt/
-ifdef CONFIG_SPL_OF_CONTROL
-obj-$(CONFIG_OF_LIBFDT) += libfdt/
-endif
+ifneq ($(CONFIG_SPL_BUILD)$(CONFIG_SPL_OF_PLATDATA),yy)
 obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec_common.o
 obj-$(CONFIG_$(SPL_)OF_CONTROL) += fdtdec.o
+endif
 
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
diff --git a/lib/libfdt/libfdt.swig b/lib/libfdt/libfdt.swig
new file mode 100644 (file)
index 0000000..14f583d
--- /dev/null
@@ -0,0 +1,89 @@
+/* File: libfdt.i */
+%module libfdt
+
+%{
+#define SWIG_FILE_WITH_INIT
+#include "libfdt.h"
+%}
+
+%pythoncode %{
+def Raise(errnum):
+    raise ValueError('Error %s' % fdt_strerror(errnum))
+
+def Name(fdt, offset):
+    name, len = fdt_get_name(fdt, offset)
+    return name
+
+def String(fdt, offset):
+    offset = fdt32_to_cpu(offset)
+    name = fdt_string(fdt, offset)
+    return name
+
+def swap32(x):
+    return (((x << 24) & 0xFF000000) |
+            ((x <<  8) & 0x00FF0000) |
+            ((x >>  8) & 0x0000FF00) |
+            ((x >> 24) & 0x000000FF))
+
+def fdt32_to_cpu(x):
+    return swap32(x)
+
+def Data(prop):
+    set_prop(prop)
+    return get_prop_data()
+%}
+
+%include "typemaps.i"
+%include "cstring.i"
+
+%typemap(in) void* = char*;
+
+typedef int fdt32_t;
+
+struct fdt_property {
+        fdt32_t tag;
+        fdt32_t len;
+        fdt32_t nameoff;
+        char data[0];
+};
+
+/*
+ * This is a work-around since I'm not sure of a better way to copy out the
+ * contents of a string. This is used in dtoc/GetProps(). The intent is to
+ * pass in a pointer to a property and access the data field at the end of
+ * it. Ideally the Data() function above would be able to do this directly,
+ * but I'm not sure how to do that.
+ */
+#pragma SWIG nowarn=454
+%inline %{
+    static struct fdt_property *cur_prop;
+
+    void set_prop(struct fdt_property *prop) {
+        cur_prop = prop;
+    }
+%}
+
+%cstring_output_allocate_size(char **s, int *sz, free(*$1));
+%inline %{
+    void get_prop_data(char **s, int *sz) {
+        *sz = fdt32_to_cpu(cur_prop->len);
+        *s = (char *)malloc(*sz);
+        if (!*s)
+            *sz = 0;
+        else
+            memcpy(*s, cur_prop + 1, *sz);
+    }
+%}
+
+const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
+int fdt_path_offset(const void *fdt, const char *path);
+int fdt_first_property_offset(const void *fdt, int nodeoffset);
+int fdt_next_property_offset(const void *fdt, int offset);
+const char *fdt_strerror(int errval);
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+                                                      int offset,
+                                                      int *OUTPUT);
+const char *fdt_get_name(const void *fdt, int nodeoffset, int *OUTPUT);
+const char *fdt_string(const void *fdt, int stroffset);
+int fdt_first_subnode(const void *fdt, int offset);
+int fdt_next_subnode(const void *fdt, int offset);
diff --git a/lib/libfdt/setup.py b/lib/libfdt/setup.py
new file mode 100644 (file)
index 0000000..62e7bcc
--- /dev/null
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+"""
+setup.py file for SWIG libfdt
+"""
+
+from distutils.core import setup, Extension
+import os
+import sys
+
+# Don't cross-compile - always use the host compiler.
+del os.environ['CROSS_COMPILE']
+del os.environ['CC']
+
+progname = sys.argv[0]
+cflags = sys.argv[1]
+files = sys.argv[2:]
+
+if cflags:
+    cflags = [flag for flag in cflags.split(' ') if flag]
+else:
+    cflags = None
+
+libfdt_module = Extension(
+    '_libfdt',
+    sources = files,
+    extra_compile_args =  cflags
+)
+
+sys.argv = [progname, '--quiet', 'build_ext', '--inplace']
+
+setup (name = 'libfdt',
+       version = '0.1',
+       author      = "SWIG Docs",
+       description = """Simple swig libfdt from docs""",
+       ext_modules = [libfdt_module],
+       py_modules = ["libfdt"],
+       )
diff --git a/lib/libfdt/test_libfdt.py b/lib/libfdt/test_libfdt.py
new file mode 100644 (file)
index 0000000..14d0da4
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+import os
+import sys
+
+our_path = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(our_path, '../../b/sandbox_spl/tools'))
+
+import libfdt
+
+with open('b/sandbox_spl/u-boot.dtb') as fd:
+    fdt = fd.read()
+
+print libfdt.fdt_path_offset(fdt, "/aliases")
index b334f053cc0ee2645aa3669701f0ec22419bb572..1aa43aba44b5b2428033638574f49e76058f80bc 100644 (file)
@@ -185,3 +185,12 @@ int snprintf(char *buf, size_t size, const char *fmt, ...)
 
        return ret;
 }
+
+void __assert_fail(const char *assertion, const char *file, unsigned line,
+                  const char *function)
+{
+       /* This will not return */
+       printf("%s:%u: %s: Assertion `%s' failed.", file, line, function,
+              assertion);
+       hang();
+}
index bff8b5bc614c25ee89e3e74e73b6b542a46567e4..763a699c4ce7b37ea018006880fc5b059534d846 100644 (file)
@@ -28,12 +28,16 @@ __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))
 # C code
 # Executables compiled from a single .c file
 host-csingle   := $(foreach m,$(__hostprogs), \
-                       $(if $($(m)-objs)$($(m)-cxxobjs),,$(m)))
+                       $(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-sharedobjs),,$(m)))
 
 # C executables linked based on several .o files
 host-cmulti    := $(foreach m,$(__hostprogs),\
                   $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
 
+# Shared object libraries
+host-shared    := $(foreach m,$(__hostprogs),\
+                  $(if $($(m)-sharedobjs),$(m))))
+
 # Object (.o) files compiled from .c files
 host-cobjs     := $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
 
@@ -59,6 +63,7 @@ host-cmulti   := $(addprefix $(obj)/,$(host-cmulti))
 host-cobjs     := $(addprefix $(obj)/,$(host-cobjs))
 host-cxxmulti  := $(addprefix $(obj)/,$(host-cxxmulti))
 host-cxxobjs   := $(addprefix $(obj)/,$(host-cxxobjs))
+host-shared    := $(addprefix $(obj)/,$(host-shared))
 host-objdirs    := $(addprefix $(obj)/,$(host-objdirs))
 
 obj-dirs += $(host-objdirs)
@@ -128,4 +133,4 @@ $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
        $(call if_changed_dep,host-cxxobjs)
 
 targets += $(host-csingle)  $(host-cmulti) $(host-cobjs)\
-          $(host-cxxmulti) $(host-cxxobjs)
+          $(host-cxxmulti) $(host-cxxobjs) $(host-shared)
index 0997fd9fddfc862dec9164bc7ccc82cf96986b9c..3ba974226b8bc0fbdf4b68747367504a971c94f3 100644 (file)
@@ -45,6 +45,7 @@ LDFLAGS_FINAL += --gc-sections
 # FIX ME
 cpp_flags := $(KBUILD_CPPFLAGS) $(PLATFORM_CPPFLAGS) $(UBOOTINCLUDE) \
                                                        $(NOSTDINC_FLAGS)
+c_flags := $(KBUILD_CFLAGS) $(cpp_flags)
 
 HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makefile),y,n)
 
@@ -76,6 +77,9 @@ endif
 
 u-boot-spl-init := $(head-y)
 u-boot-spl-main := $(libs-y)
+ifdef CONFIG_SPL_OF_PLATDATA
+u-boot-spl-platdata := $(obj)/dts/dt-platdata.o
+endif
 
 # Linker Script
 ifdef CONFIG_SPL_LDSCRIPT
@@ -169,7 +173,7 @@ cmd_cat = cat $(filter-out $(PHONY), $^) > $@
 quiet_cmd_copy = COPY    $@
       cmd_copy = cp $< $@
 
-ifeq ($(CONFIG_SPL_OF_CONTROL)$(CONFIG_OF_SEPARATE),yy)
+ifeq ($(CONFIG_SPL_OF_CONTROL)$(CONFIG_OF_SEPARATE)$(CONFIG_SPL_OF_PLATDATA),yy)
 $(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb.bin $(obj)/$(SPL_BIN)-pad.bin \
                $(obj)/$(SPL_BIN).dtb FORCE
        $(call if_changed,cat)
@@ -207,6 +211,32 @@ cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
 $(obj)/$(SPL_BIN).cfg: include/config.h FORCE
        $(call if_changed,cpp_cfg)
 
+pythonpath = PYTHONPATH=tools
+
+quiet_cmd_dtocc = DTOC C  $@
+cmd_dtocc = $(pythonpath) $(srctree)/tools/dtoc/dtoc -d $(obj)/$(SPL_BIN).dtb -o $@ platdata
+
+quiet_cmd_dtoch = DTOC H  $@
+cmd_dtoch = $(pythonpath) $(srctree)/tools/dtoc/dtoc -d $(obj)/$(SPL_BIN).dtb -o $@ struct
+
+quiet_cmd_plat = PLAT    $@
+cmd_plat = $(CC) $(c_flags) -c $< -o $@
+
+$(obj)/dts/dt-platdata.o: $(obj)/dts/dt-platdata.c include/generated/dt-structs.h
+       $(call if_changed,plat)
+
+PHONY += dts_dir
+dts_dir:
+       $(shell [ -d $(obj)/dts ] || mkdir -p $(obj)/dts)
+
+include/generated/dt-structs.h: $(obj)/$(SPL_BIN).dtb dts_dir dtoc
+       $(call if_changed,dtoch)
+
+$(obj)/dts/dt-platdata.c: $(obj)/$(SPL_BIN).dtb dts_dir dtoc
+       $(call if_changed,dtocc)
+
+dtoc: #$(objtree)/tools/_libfdt.so
+
 ifdef CONFIG_SAMSUNG
 ifdef CONFIG_VAR_SIZE_SPL
 VAR_SIZE_PARAM = --vs
@@ -241,19 +271,24 @@ cmd_mksunxiboot = $(objtree)/tools/mksunxiboot $< $@
 $(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin FORCE
        $(call if_changed,mksunxiboot)
 
-quiet_cmd_u-boot-spl = LD      $@
-      cmd_u-boot-spl = (cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
+# Rule to link u-boot-spl
+# May be overridden by arch/$(ARCH)/config.mk
+quiet_cmd_u-boot-spl ?= LD      $@
+      cmd_u-boot-spl ?= (cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
                       $(patsubst $(obj)/%,%,$(u-boot-spl-init)) --start-group \
-                      $(patsubst $(obj)/%,%,$(u-boot-spl-main)) --end-group \
+                      $(patsubst $(obj)/%,%,$(u-boot-spl-main))  \
+                      $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \
+                      --end-group \
                       $(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN))
 
-$(obj)/$(SPL_BIN): $(u-boot-spl-init) $(u-boot-spl-main) $(obj)/u-boot-spl.lds FORCE
+$(obj)/$(SPL_BIN): $(u-boot-spl-platdata) $(u-boot-spl-init) \
+               $(u-boot-spl-main) $(obj)/u-boot-spl.lds FORCE
        $(call if_changed,u-boot-spl)
 
 $(sort $(u-boot-spl-init) $(u-boot-spl-main)): $(u-boot-spl-dirs) ;
 
 PHONY += $(u-boot-spl-dirs)
-$(u-boot-spl-dirs):
+$(u-boot-spl-dirs): $(u-boot-spl-platdata)
        $(Q)$(MAKE) $(build)=$@
 
 quiet_cmd_cpp_lds = LDS     $@
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 449f98bee39cb1ecc2d7758af18e72e98d7283a0..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',
@@ -192,7 +193,7 @@ def pytest_configure(config):
     for v in env_vars:
         os.environ['U_BOOT_' + v.upper()] = getattr(ubconfig, v)
 
-    if board_type == 'sandbox':
+    if board_type.startswith('sandbox'):
         import u_boot_console_sandbox
         console = u_boot_console_sandbox.ConsoleSandbox(log, ubconfig)
     else:
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_ofplatdata.py b/test/py/tests/test_ofplatdata.py
new file mode 100644 (file)
index 0000000..c8b309e
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+
+import pytest
+
+OF_PLATDATA_OUTPUT = '''
+of-platdata probe:
+bool 1
+byte 05
+bytearray 06 00 00
+int 1
+intarray 2 3 4 0
+longbytearray 09 0a 0b 0c 0d 0e 0f 10 11
+string message
+stringarray "multi-word" "message" ""
+of-platdata probe:
+bool 0
+byte 08
+bytearray 01 23 34
+int 3
+intarray 5 0 0 0
+longbytearray 09 00 00 00 00 00 00 00 00
+string message2
+stringarray "another" "multi-word" "message"
+of-platdata probe:
+bool 0
+byte 00
+bytearray 00 00 00
+int 0
+intarray 0 0 0 0
+longbytearray 00 00 00 00 00 00 00 00 00
+string <NULL>
+stringarray "one" "" ""
+'''
+
+@pytest.mark.buildconfigspec('spl')
+def test_ofplatdata(u_boot_console):
+    """Test that of-platdata can be generated and used in sandbox"""
+    cons = u_boot_console
+    output = cons.get_spawn_output().replace('\r', '')
+    assert OF_PLATDATA_OUTPUT in output
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
index 815fa64d5ff344ba7dc6470e714862d6f59c568c..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.
 
@@ -329,7 +345,7 @@ class ConsoleBase(object):
                 m = self.p.expect([pattern_u_boot_spl_signon] +
                                   self.bad_patterns)
                 if m != 0:
-                    raise Exception('Bad pattern found on console: ' +
+                    raise Exception('Bad pattern found on SPL console: ' +
                                     self.bad_pattern_ids[m - 1])
             m = self.p.expect([pattern_u_boot_main_signon] + self.bad_patterns)
             if m != 0:
@@ -377,6 +393,16 @@ class ConsoleBase(object):
             pass
         self.p = None
 
+    def get_spawn_output(self):
+        """Return the start-up output from U-Boot
+
+        Returns:
+            The output produced by ensure_spawed(), as a string.
+        """
+        if self.p:
+            return self.p.get_expect_output()
+        return None
+
     def validate_version_string_in_text(self, text):
         """Assert that a command's output includes the U-Boot signon message.
 
index 04654ae8c9fee10a84944cbddcd632ce40114d72..647e1f879fcadcbaf1487e6ad728597959e6f577 100644 (file)
@@ -39,14 +39,18 @@ class ConsoleSandbox(ConsoleBase):
             A u_boot_spawn.Spawn object that is attached to U-Boot.
         """
 
+        bcfg = self.config.buildconfig
+        config_spl = bcfg.get('config_spl', 'n') == 'y'
+        fname = '/spl/u-boot-spl' if config_spl else '/u-boot'
+        print fname
         cmd = []
         if self.config.gdbserver:
             cmd += ['gdbserver', self.config.gdbserver]
         cmd += [
-            self.config.build_dir + '/u-boot',
+            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 d15517389e510fa8ddd7d96cfa5dd4b73f86e285..3a0fbfad90f25b39aad147d046ee4d2a2c0d085b 100644 (file)
@@ -18,6 +18,9 @@ class Timeout(Exception):
 class Spawn(object):
     """Represents the stdio of a freshly created sub-process. Commands may be
     sent to the process, and responses waited for.
+
+    Members:
+        output: accumulated output from expect()
     """
 
     def __init__(self, args, cwd=None):
@@ -34,6 +37,7 @@ class Spawn(object):
 
         self.waited = False
         self.buf = ''
+        self.output = ''
         self.logfile_read = None
         self.before = ''
         self.after = ''
@@ -154,6 +158,7 @@ class Spawn(object):
                     posafter = earliest_m.end()
                     self.before = self.buf[:pos]
                     self.after = self.buf[pos:posafter]
+                    self.output += self.buf[:posafter]
                     self.buf = self.buf[posafter:]
                     return earliest_pi
                 tnow_s = time.time()
@@ -198,3 +203,11 @@ class Spawn(object):
             if not self.isalive():
                 break
             time.sleep(0.1)
+
+    def get_expect_output(self):
+        """Return the output read by expect()
+
+        Returns:
+            The output processed by expect(), as a string.
+        """
+        return self.output
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/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 f72294a98a583fee5cfb43ec15cc61615b7e8e88..421414bc154b0a596cb5833148f2c19c614d5fa9 100644 (file)
@@ -107,6 +107,20 @@ mkimage-objs   := $(dumpimage-mkimage-objs) mkimage.o
 fit_info-objs   := $(dumpimage-mkimage-objs) fit_info.o
 fit_check_sign-objs   := $(dumpimage-mkimage-objs) fit_check_sign.o
 
+# Build a libfdt Python module if swig is available
+# Use 'sudo apt-get install swig libpython-dev' to enable this
+hostprogs-$(CONFIG_SPL_OF_PLATDATA) += \
+       $(if $(shell which swig),_libfdt.so)
+_libfdt.so-sharedobjs += $(LIBFDT_OBJS)
+libfdt:
+
+tools/_libfdt.so: $(patsubst %.o,%.c,$(LIBFDT_OBJS)) tools/libfdt_wrap.c
+       python $(srctree)/lib/libfdt/setup.py "$(_hostc_flags)" $^
+       mv _libfdt.so $@
+
+tools/libfdt_wrap.c: $(srctree)/lib/libfdt/libfdt.swig
+       swig -python -o $@ $<
+
 # TODO(sjg@chromium.org): Is this correct on Mac OS?
 
 ifneq ($(CONFIG_MX23)$(CONFIG_MX28),)
diff --git a/tools/dtoc/.gitignore b/tools/dtoc/.gitignore
new file mode 100644 (file)
index 0000000..0d20b64
--- /dev/null
@@ -0,0 +1 @@
+*.pyc
diff --git a/tools/dtoc/dtoc b/tools/dtoc/dtoc
new file mode 120000 (symlink)
index 0000000..896ca44
--- /dev/null
@@ -0,0 +1 @@
+dtoc.py
\ No newline at end of file
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
new file mode 100755 (executable)
index 0000000..ec80abe
--- /dev/null
@@ -0,0 +1,394 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+import copy
+from optparse import OptionError, OptionParser
+import os
+import sys
+
+import fdt_util
+
+# Bring in the patman libraries
+our_path = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(our_path, '../patman'))
+
+# Bring in either the normal fdt library (which relies on libfdt) or the
+# fallback one (which uses fdtget and is slower). Both provide the same
+# interfface for this file to use.
+try:
+    from fdt import Fdt
+    import fdt
+    have_libfdt = True
+except ImportError:
+    have_libfdt = False
+    from fdt_fallback import Fdt
+    import fdt_fallback as fdt
+
+import struct
+
+# When we see these properties we ignore them - i.e. do not create a structure member
+PROP_IGNORE_LIST = [
+    '#address-cells',
+    '#gpio-cells',
+    '#size-cells',
+    'compatible',
+    'linux,phandle',
+    "status",
+    'phandle',
+    'u-boot,dm-pre-reloc',
+]
+
+# C type declarations for the tyues we support
+TYPE_NAMES = {
+    fdt_util.TYPE_INT: 'fdt32_t',
+    fdt_util.TYPE_BYTE: 'unsigned char',
+    fdt_util.TYPE_STRING: 'const char *',
+    fdt_util.TYPE_BOOL: 'bool',
+};
+
+STRUCT_PREFIX = 'dtd_'
+VAL_PREFIX = 'dtv_'
+
+def Conv_name_to_c(name):
+    """Convert a device-tree name to a C identifier
+
+    Args:
+        name:   Name to convert
+    Return:
+        String containing the C version of this name
+    """
+    str = name.replace('@', '_at_')
+    str = str.replace('-', '_')
+    str = str.replace(',', '_')
+    str = str.replace('/', '__')
+    return str
+
+def TabTo(num_tabs, str):
+    if len(str) >= num_tabs * 8:
+        return str + ' '
+    return str + '\t' * (num_tabs - len(str) / 8)
+
+class DtbPlatdata:
+    """Provide a means to convert device tree binary data to platform data
+
+    The output of this process is C structures which can be used in space-
+    constrained encvironments where the ~3KB code overhead of device tree
+    code is not affordable.
+
+    Properties:
+        fdt: Fdt object, referencing the device tree
+        _dtb_fname: Filename of the input device tree binary file
+        _valid_nodes: A list of Node object with compatible strings
+        _options: Command-line options
+        _phandle_node: A dict of nodes indexed by phandle number (1, 2...)
+        _outfile: The current output file (sys.stdout or a real file)
+        _lines: Stashed list of output lines for outputting in the future
+        _phandle_node: A dict of Nodes indexed by phandle (an integer)
+    """
+    def __init__(self, dtb_fname, options):
+        self._dtb_fname = dtb_fname
+        self._valid_nodes = None
+        self._options = options
+        self._phandle_node = {}
+        self._outfile = None
+        self._lines = []
+
+    def SetupOutput(self, fname):
+        """Set up the output destination
+
+        Once this is done, future calls to self.Out() will output to this
+        file.
+
+        Args:
+            fname: Filename to send output to, or '-' for stdout
+        """
+        if fname == '-':
+            self._outfile = sys.stdout
+        else:
+            self._outfile = open(fname, 'w')
+
+    def Out(self, str):
+        """Output a string to the output file
+
+        Args:
+            str: String to output
+        """
+        self._outfile.write(str)
+
+    def Buf(self, str):
+        """Buffer up a string to send later
+
+        Args:
+            str: String to add to our 'buffer' list
+        """
+        self._lines.append(str)
+
+    def GetBuf(self):
+        """Get the contents of the output buffer, and clear it
+
+        Returns:
+            The output buffer, which is then cleared for future use
+        """
+        lines = self._lines
+        self._lines = []
+        return lines
+
+    def GetValue(self, type, value):
+        """Get a value as a C expression
+
+        For integers this returns a byte-swapped (little-endian) hex string
+        For bytes this returns a hex string, e.g. 0x12
+        For strings this returns a literal string enclosed in quotes
+        For booleans this return 'true'
+
+        Args:
+            type: Data type (fdt_util)
+            value: Data value, as a string of bytes
+        """
+        if type == fdt_util.TYPE_INT:
+            return '%#x' % fdt_util.fdt32_to_cpu(value)
+        elif type == fdt_util.TYPE_BYTE:
+            return '%#x' % ord(value[0])
+        elif type == fdt_util.TYPE_STRING:
+            return '"%s"' % value
+        elif type == fdt_util.TYPE_BOOL:
+            return 'true'
+
+    def GetCompatName(self, node):
+        """Get a node's first compatible string as a C identifier
+
+        Args:
+            node: Node object to check
+        Return:
+            C identifier for the first compatible string
+        """
+        compat = node.props['compatible'].value
+        if type(compat) == list:
+            compat = compat[0]
+        return Conv_name_to_c(compat)
+
+    def ScanDtb(self):
+        """Scan the device tree to obtain a tree of notes and properties
+
+        Once this is done, self.fdt.GetRoot() can be called to obtain the
+        device tree root node, and progress from there.
+        """
+        self.fdt = Fdt(self._dtb_fname)
+        self.fdt.Scan()
+
+    def ScanTree(self):
+        """Scan the device tree for useful information
+
+        This fills in the following properties:
+            _phandle_node: A dict of Nodes indexed by phandle (an integer)
+            _valid_nodes: A list of nodes we wish to consider include in the
+                platform data
+        """
+        node_list = []
+        self._phandle_node = {}
+        for node in self.fdt.GetRoot().subnodes:
+            if 'compatible' in node.props:
+                status = node.props.get('status')
+                if (not options.include_disabled and not status or
+                    status.value != 'disabled'):
+                    node_list.append(node)
+                    phandle_prop = node.props.get('phandle')
+                    if phandle_prop:
+                        phandle = phandle_prop.GetPhandle()
+                        self._phandle_node[phandle] = node
+
+        self._valid_nodes = node_list
+
+    def IsPhandle(self, prop):
+        """Check if a node contains phandles
+
+        We have no reliable way of detecting whether a node uses a phandle
+        or not. As an interim measure, use a list of known property names.
+
+        Args:
+            prop: Prop object to check
+        Return:
+            True if the object value contains phandles, else False
+        """
+        if prop.name in ['clocks']:
+            return True
+        return False
+
+    def ScanStructs(self):
+        """Scan the device tree building up the C structures we will use.
+
+        Build a dict keyed by C struct name containing a dict of Prop
+        object for each struct field (keyed by property name). Where the
+        same struct appears multiple times, try to use the 'widest'
+        property, i.e. the one with a type which can express all others.
+
+        Once the widest property is determined, all other properties are
+        updated to match that width.
+        """
+        structs = {}
+        for node in self._valid_nodes:
+            node_name = self.GetCompatName(node)
+            fields = {}
+
+            # Get a list of all the valid properties in this node.
+            for name, prop in node.props.iteritems():
+                if name not in PROP_IGNORE_LIST and name[0] != '#':
+                    fields[name] = copy.deepcopy(prop)
+
+            # If we've seen this node_name before, update the existing struct.
+            if node_name in structs:
+                struct = structs[node_name]
+                for name, prop in fields.iteritems():
+                    oldprop = struct.get(name)
+                    if oldprop:
+                        oldprop.Widen(prop)
+                    else:
+                        struct[name] = prop
+
+            # Otherwise store this as a new struct.
+            else:
+                structs[node_name] = fields
+
+        upto = 0
+        for node in self._valid_nodes:
+            node_name = self.GetCompatName(node)
+            struct = structs[node_name]
+            for name, prop in node.props.iteritems():
+                if name not in PROP_IGNORE_LIST and name[0] != '#':
+                    prop.Widen(struct[name])
+            upto += 1
+        return structs
+
+    def GenerateStructs(self, structs):
+        """Generate struct defintions for the platform data
+
+        This writes out the body of a header file consisting of structure
+        definitions for node in self._valid_nodes. See the documentation in
+        README.of-plat for more information.
+        """
+        self.Out('#include <stdbool.h>\n')
+        self.Out('#include <libfdt.h>\n')
+
+        # Output the struct definition
+        for name in sorted(structs):
+            self.Out('struct %s%s {\n' % (STRUCT_PREFIX, name));
+            for pname in sorted(structs[name]):
+                prop = structs[name][pname]
+                if self.IsPhandle(prop):
+                    # For phandles, include a reference to the target
+                    self.Out('\t%s%s[%d]' % (TabTo(2, 'struct phandle_2_cell'),
+                                             Conv_name_to_c(prop.name),
+                                             len(prop.value) / 2))
+                else:
+                    ptype = TYPE_NAMES[prop.type]
+                    self.Out('\t%s%s' % (TabTo(2, ptype),
+                                         Conv_name_to_c(prop.name)))
+                    if type(prop.value) == list:
+                        self.Out('[%d]' % len(prop.value))
+                self.Out(';\n')
+            self.Out('};\n')
+
+    def GenerateTables(self):
+        """Generate device defintions for the platform data
+
+        This writes out C platform data initialisation data and
+        U_BOOT_DEVICE() declarations for each valid node. See the
+        documentation in README.of-plat for more information.
+        """
+        self.Out('#include <common.h>\n')
+        self.Out('#include <dm.h>\n')
+        self.Out('#include <dt-structs.h>\n')
+        self.Out('\n')
+        node_txt_list = []
+        for node in self._valid_nodes:
+            struct_name = self.GetCompatName(node)
+            var_name = Conv_name_to_c(node.name)
+            self.Buf('static struct %s%s %s%s = {\n' %
+                (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
+            for pname, prop in node.props.iteritems():
+                if pname in PROP_IGNORE_LIST or pname[0] == '#':
+                    continue
+                ptype = TYPE_NAMES[prop.type]
+                member_name = Conv_name_to_c(prop.name)
+                self.Buf('\t%s= ' % TabTo(3, '.' + member_name))
+
+                # Special handling for lists
+                if type(prop.value) == list:
+                    self.Buf('{')
+                    vals = []
+                    # For phandles, output a reference to the platform data
+                    # of the target node.
+                    if self.IsPhandle(prop):
+                        # Process the list as pairs of (phandle, id)
+                        it = iter(prop.value)
+                        for phandle_cell, id_cell in zip(it, it):
+                            phandle = fdt_util.fdt32_to_cpu(phandle_cell)
+                            id = fdt_util.fdt32_to_cpu(id_cell)
+                            target_node = self._phandle_node[phandle]
+                            name = Conv_name_to_c(target_node.name)
+                            vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id))
+                    else:
+                        for val in prop.value:
+                            vals.append(self.GetValue(prop.type, val))
+                    self.Buf(', '.join(vals))
+                    self.Buf('}')
+                else:
+                    self.Buf(self.GetValue(prop.type, prop.value))
+                self.Buf(',\n')
+            self.Buf('};\n')
+
+            # Add a device declaration
+            self.Buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
+            self.Buf('\t.name\t\t= "%s",\n' % struct_name)
+            self.Buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
+            self.Buf('\t.platdata_size\t= sizeof(%s%s),\n' %
+                     (VAL_PREFIX, var_name))
+            self.Buf('};\n')
+            self.Buf('\n')
+
+            # Output phandle target nodes first, since they may be referenced
+            # by others
+            if 'phandle' in node.props:
+                self.Out(''.join(self.GetBuf()))
+            else:
+                node_txt_list.append(self.GetBuf())
+
+        # Output all the nodes which are not phandle targets themselves, but
+        # may reference them. This avoids the need for forward declarations.
+        for node_txt in node_txt_list:
+            self.Out(''.join(node_txt))
+
+
+if __name__ != "__main__":
+    pass
+
+parser = OptionParser()
+parser.add_option('-d', '--dtb-file', action='store',
+                  help='Specify the .dtb input file')
+parser.add_option('--include-disabled', action='store_true',
+                  help='Include disabled nodes')
+parser.add_option('-o', '--output', action='store', default='-',
+                  help='Select output filename')
+(options, args) = parser.parse_args()
+
+if not args:
+    raise ValueError('Please specify a command: struct, platdata')
+
+plat = DtbPlatdata(options.dtb_file, options)
+plat.ScanDtb()
+plat.ScanTree()
+plat.SetupOutput(options.output)
+structs = plat.ScanStructs()
+
+for cmd in args[0].split(','):
+    if cmd == 'struct':
+        plat.GenerateStructs(structs)
+    elif cmd == 'platdata':
+        plat.GenerateTables()
+    else:
+        raise ValueError("Unknown command '%s': (use: struct, platdata)" % cmd)
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
new file mode 100644 (file)
index 0000000..1d913a9
--- /dev/null
@@ -0,0 +1,180 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+import fdt_util
+import libfdt
+import sys
+
+# This deals with a device tree, presenting it as a list of Node and Prop
+# objects, representing nodes and properties, respectively.
+#
+# This implementation uses a libfdt Python library to access the device tree,
+# so it is fairly efficient.
+
+class Prop:
+    """A device tree property
+
+    Properties:
+        name: Property name (as per the device tree)
+        value: Property value as a string of bytes, or a list of strings of
+            bytes
+        type: Value type
+    """
+    def __init__(self, name, bytes):
+        self.name = name
+        self.value = None
+        if not bytes:
+            self.type = fdt_util.TYPE_BOOL
+            self.value = True
+            return
+        self.type, self.value = fdt_util.BytesToValue(bytes)
+
+    def GetPhandle(self):
+        """Get a (single) phandle value from a property
+
+        Gets the phandle valuie from a property and returns it as an integer
+        """
+        return fdt_util.fdt32_to_cpu(self.value[:4])
+
+    def Widen(self, newprop):
+        """Figure out which property type is more general
+
+        Given a current property and a new property, this function returns the
+        one that is less specific as to type. The less specific property will
+        be ble to represent the data in the more specific property. This is
+        used for things like:
+
+            node1 {
+                compatible = "fred";
+                value = <1>;
+            };
+            node1 {
+                compatible = "fred";
+                value = <1 2>;
+            };
+
+        He we want to use an int array for 'value'. The first property
+        suggests that a single int is enough, but the second one shows that
+        it is not. Calling this function with these two propertes would
+        update the current property to be like the second, since it is less
+        specific.
+        """
+        if newprop.type < self.type:
+            self.type = newprop.type
+
+        if type(newprop.value) == list and type(self.value) != list:
+            self.value = [self.value]
+
+        if type(self.value) == list and len(newprop.value) > len(self.value):
+            val = fdt_util.GetEmpty(self.type)
+            while len(self.value) < len(newprop.value):
+                self.value.append(val)
+
+
+class Node:
+    """A device tree node
+
+    Properties:
+        offset: Integer offset in the device tree
+        name: Device tree node tname
+        path: Full path to node, along with the node name itself
+        _fdt: Device tree object
+        subnodes: A list of subnodes for this node, each a Node object
+        props: A dict of properties for this node, each a Prop object.
+            Keyed by property name
+    """
+    def __init__(self, fdt, offset, name, path):
+        self.offset = offset
+        self.name = name
+        self.path = path
+        self._fdt = fdt
+        self.subnodes = []
+        self.props = {}
+
+    def Scan(self):
+        """Scan a node's properties and subnodes
+
+        This fills in the props and subnodes properties, recursively
+        searching into subnodes so that the entire tree is built.
+        """
+        self.props = self._fdt.GetProps(self.path)
+
+        offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self.offset)
+        while offset >= 0:
+            sep = '' if self.path[-1] == '/' else '/'
+            name = libfdt.Name(self._fdt.GetFdt(), offset)
+            path = self.path + sep + name
+            node = Node(self._fdt, offset, name, path)
+            self.subnodes.append(node)
+
+            node.Scan()
+            offset = libfdt.fdt_next_subnode(self._fdt.GetFdt(), offset)
+
+
+class Fdt:
+    """Provides simple access to a flat device tree blob.
+
+    Properties:
+      fname: Filename of fdt
+      _root: Root of device tree (a Node object)
+    """
+
+    def __init__(self, fname):
+        self.fname = fname
+        with open(fname) as fd:
+            self._fdt = fd.read()
+
+    def GetFdt(self):
+        """Get the contents of the FDT
+
+        Returns:
+            The FDT contents as a string of bytes
+        """
+        return self._fdt
+
+    def Scan(self):
+        """Scan a device tree, building up a tree of Node objects
+
+        This fills in the self._root property
+        """
+        self._root = Node(self, 0, '/', '/')
+        self._root.Scan()
+
+    def GetRoot(self):
+        """Get the root Node of the device tree
+
+        Returns:
+            The root Node object
+        """
+        return self._root
+
+    def GetProps(self, node):
+        """Get all properties from a node.
+
+        Args:
+            node: Full path to node name to look in.
+
+        Returns:
+            A dictionary containing all the properties, indexed by node name.
+            The entries are Prop objects.
+
+        Raises:
+            ValueError: if the node does not exist.
+        """
+        offset = libfdt.fdt_path_offset(self._fdt, node)
+        if offset < 0:
+            libfdt.Raise(offset)
+        props_dict = {}
+        poffset = libfdt.fdt_first_property_offset(self._fdt, offset)
+        while poffset >= 0:
+            dprop, plen = libfdt.fdt_get_property_by_offset(self._fdt, poffset)
+            prop = Prop(libfdt.String(self._fdt, dprop.nameoff), libfdt.Data(dprop))
+            props_dict[prop.name] = prop
+
+            poffset = libfdt.fdt_next_property_offset(self._fdt, poffset)
+        return props_dict
diff --git a/tools/dtoc/fdt_fallback.py b/tools/dtoc/fdt_fallback.py
new file mode 100644 (file)
index 0000000..14decf3
--- /dev/null
@@ -0,0 +1,207 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+import command
+import fdt_util
+import sys
+
+# This deals with a device tree, presenting it as a list of Node and Prop
+# objects, representing nodes and properties, respectively.
+#
+# This implementation uses the fdtget tool to access the device tree, so it
+# is not very efficient for larger trees. The tool is called once for each
+# node and property in the tree.
+
+class Prop:
+    """A device tree property
+
+    Properties:
+        name: Property name (as per the device tree)
+        value: Property value as a string of bytes, or a list of strings of
+            bytes
+        type: Value type
+    """
+    def __init__(self, name, byte_list_str):
+        self.name = name
+        self.value = None
+        if not byte_list_str.strip():
+            self.type = fdt_util.TYPE_BOOL
+            return
+        bytes = [chr(int(byte, 16)) for byte in byte_list_str.strip().split(' ')]
+        self.type, self.value = fdt_util.BytesToValue(''.join(bytes))
+
+    def GetPhandle(self):
+        """Get a (single) phandle value from a property
+
+        Gets the phandle valuie from a property and returns it as an integer
+        """
+        return fdt_util.fdt32_to_cpu(self.value[:4])
+
+    def Widen(self, newprop):
+        """Figure out which property type is more general
+
+        Given a current property and a new property, this function returns the
+        one that is less specific as to type. The less specific property will
+        be ble to represent the data in the more specific property. This is
+        used for things like:
+
+            node1 {
+                compatible = "fred";
+                value = <1>;
+            };
+            node1 {
+                compatible = "fred";
+                value = <1 2>;
+            };
+
+        He we want to use an int array for 'value'. The first property
+        suggests that a single int is enough, but the second one shows that
+        it is not. Calling this function with these two propertes would
+        update the current property to be like the second, since it is less
+        specific.
+        """
+        if newprop.type < self.type:
+            self.type = newprop.type
+
+        if type(newprop.value) == list and type(self.value) != list:
+            self.value = newprop.value
+
+class Node:
+    """A device tree node
+
+    Properties:
+        name: Device tree node tname
+        path: Full path to node, along with the node name itself
+        _fdt: Device tree object
+        subnodes: A list of subnodes for this node, each a Node object
+        props: A dict of properties for this node, each a Prop object.
+            Keyed by property name
+    """
+    def __init__(self, fdt, name, path):
+        self.name = name
+        self.path = path
+        self._fdt = fdt
+        self.subnodes = []
+        self.props = {}
+
+    def Scan(self):
+        """Scan a node's properties and subnodes
+
+        This fills in the props and subnodes properties, recursively
+        searching into subnodes so that the entire tree is built.
+        """
+        for name, byte_list_str in self._fdt.GetProps(self.path).iteritems():
+            prop = Prop(name, byte_list_str)
+            self.props[name] = prop
+
+        for name in self._fdt.GetSubNodes(self.path):
+            sep = '' if self.path[-1] == '/' else '/'
+            path = self.path + sep + name
+            node = Node(self._fdt, name, path)
+            self.subnodes.append(node)
+
+            node.Scan()
+
+
+class Fdt:
+    """Provides simple access to a flat device tree blob.
+
+    Properties:
+      fname: Filename of fdt
+      _root: Root of device tree (a Node object)
+    """
+
+    def __init__(self, fname):
+        self.fname = fname
+
+    def Scan(self):
+        """Scan a device tree, building up a tree of Node objects
+
+        This fills in the self._root property
+        """
+        self._root = Node(self, '/', '/')
+        self._root.Scan()
+
+    def GetRoot(self):
+        """Get the root Node of the device tree
+
+        Returns:
+            The root Node object
+        """
+        return self._root
+
+    def GetSubNodes(self, node):
+        """Returns a list of sub-nodes of a given node
+
+        Args:
+            node: Node name to return children from
+
+        Returns:
+            List of children in the node (each a string node name)
+
+        Raises:
+            CmdError: if the node does not exist.
+        """
+        out = command.Output('fdtget', self.fname, '-l', node)
+        return out.strip().splitlines()
+
+    def GetProps(self, node, convert_dashes=False):
+        """Get all properties from a node
+
+        Args:
+            node: full path to node name to look in
+            convert_dashes: True to convert - to _ in node names
+
+        Returns:
+            A dictionary containing all the properties, indexed by node name.
+            The entries are simply strings - no decoding of lists or numbers
+            is done.
+
+        Raises:
+            CmdError: if the node does not exist.
+        """
+        out = command.Output('fdtget', self.fname, node, '-p')
+        props = out.strip().splitlines()
+        props_dict = {}
+        for prop in props:
+            name = prop
+            if convert_dashes:
+                prop = re.sub('-', '_', prop)
+            props_dict[prop] = self.GetProp(node, name)
+        return props_dict
+
+    def GetProp(self, node, prop, default=None, typespec=None):
+        """Get a property from a device tree.
+
+        This looks up the given node and property, and returns the value as a
+        string,
+
+        If the node or property does not exist, this will return the default
+        value.
+
+        Args:
+            node: Full path to node to look up.
+            prop: Property name to look up.
+            default: Default value to return if nothing is present in the fdt,
+                or None to raise in this case. This will be converted to a
+                string.
+            typespec: Type character to use (None for default, 's' for string)
+
+        Returns:
+            string containing the property value.
+
+        Raises:
+            CmdError: if the property does not exist and no default is provided.
+        """
+        args = [self.fname, node, prop, '-t', 'bx']
+        if default is not None:
+          args += ['-d', str(default)]
+        if typespec is not None:
+          args += ['-t%s' % typespec]
+        out = command.Output('fdtget', *args)
+        return out.strip()
diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py
new file mode 100644 (file)
index 0000000..929b524
--- /dev/null
@@ -0,0 +1,86 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+import struct
+
+# A list of types we support
+(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL) = range(4)
+
+def BytesToValue(bytes):
+    """Converts a string of bytes into a type and value
+
+    Args:
+        A string containing bytes
+
+    Return:
+        A tuple:
+            Type of data
+            Data, either a single element or a list of elements. Each element
+            is one of:
+                TYPE_STRING: string value from the property
+                TYPE_INT: a byte-swapped integer stored as a 4-byte string
+                TYPE_BYTE: a byte stored as a single-byte string
+    """
+    size = len(bytes)
+    strings = bytes.split('\0')
+    is_string = True
+    count = len(strings) - 1
+    if count > 0 and not strings[-1]:
+        for string in strings[:-1]:
+            if not string:
+                is_string = False
+                break
+            for ch in string:
+                if ch < ' ' or ch > '~':
+                    is_string = False
+                    break
+    else:
+        is_string = False
+    if is_string:
+        if count == 1:
+            return TYPE_STRING, strings[0]
+        else:
+            return TYPE_STRING, strings[:-1]
+    if size % 4:
+        if size == 1:
+            return TYPE_BYTE, bytes[0]
+        else:
+            return TYPE_BYTE, list(bytes)
+    val = []
+    for i in range(0, size, 4):
+        val.append(bytes[i:i + 4])
+    if size == 4:
+        return TYPE_INT, val[0]
+    else:
+        return TYPE_INT, val
+
+def GetEmpty(type):
+    """Get an empty / zero value of the given type
+
+    Returns:
+        A single value of the given type
+    """
+    if type == TYPE_BYTE:
+        return chr(0)
+    elif type == TYPE_INT:
+        return struct.pack('<I', 0);
+    elif type == TYPE_STRING:
+        return ''
+    else:
+        return True
+
+def fdt32_to_cpu(val):
+    """Convert a device tree cell to an integer
+
+    Args:
+        Value to convert (4-character string representing the cell value)
+
+    Return:
+        A native-endian integer value
+    """
+    return struct.unpack(">I", val)[0]
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;