aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/common/spl
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/common/spl')
-rw-r--r--roms/u-boot/common/spl/Kconfig1639
-rw-r--r--roms/u-boot/common/spl/Makefile35
-rw-r--r--roms/u-boot/common/spl/spl.c895
-rw-r--r--roms/u-boot/common/spl/spl_atf.c297
-rw-r--r--roms/u-boot/common/spl/spl_bootrom.c27
-rw-r--r--roms/u-boot/common/spl/spl_dfu.c56
-rw-r--r--roms/u-boot/common/spl/spl_ext.c146
-rw-r--r--roms/u-boot/common/spl/spl_fat.c172
-rw-r--r--roms/u-boot/common/spl/spl_fit.c810
-rw-r--r--roms/u-boot/common/spl/spl_legacy.c133
-rw-r--r--roms/u-boot/common/spl/spl_mmc.c448
-rw-r--r--roms/u-boot/common/spl/spl_nand.c189
-rw-r--r--roms/u-boot/common/spl/spl_net.c97
-rw-r--r--roms/u-boot/common/spl/spl_nor.c122
-rw-r--r--roms/u-boot/common/spl/spl_onenand.c40
-rw-r--r--roms/u-boot/common/spl/spl_opensbi.c99
-rw-r--r--roms/u-boot/common/spl/spl_optee.S12
-rw-r--r--roms/u-boot/common/spl/spl_ram.c85
-rw-r--r--roms/u-boot/common/spl/spl_sata.c105
-rw-r--r--roms/u-boot/common/spl/spl_sdp.c48
-rw-r--r--roms/u-boot/common/spl/spl_spi.c171
-rw-r--r--roms/u-boot/common/spl/spl_ubi.c88
-rw-r--r--roms/u-boot/common/spl/spl_usb.c73
-rw-r--r--roms/u-boot/common/spl/spl_xip.c30
-rw-r--r--roms/u-boot/common/spl/spl_ymodem.c181
25 files changed, 5998 insertions, 0 deletions
diff --git a/roms/u-boot/common/spl/Kconfig b/roms/u-boot/common/spl/Kconfig
new file mode 100644
index 000000000..fa80524cf
--- /dev/null
+++ b/roms/u-boot/common/spl/Kconfig
@@ -0,0 +1,1639 @@
+menu "SPL / TPL"
+
+config SUPPORT_SPL
+ bool
+
+config SUPPORT_TPL
+ bool
+
+config SPL_DFU_NO_RESET
+ bool
+
+config SPL
+ bool
+ depends on SUPPORT_SPL
+ prompt "Enable SPL"
+ help
+ If you want to build SPL as well as the normal image, say Y.
+
+config SPL_FRAMEWORK
+ bool "Support SPL based upon the common SPL framework"
+ depends on SPL
+ default y
+ help
+ Enable the SPL framework under common/spl/. This framework
+ supports MMC, NAND and YMODEM and other methods loading of U-Boot
+ and the Linux Kernel. If unsure, say Y.
+
+config SPL_FRAMEWORK_BOARD_INIT_F
+ bool "Define a generic function board_init_f"
+ depends on SPL_FRAMEWORK
+ help
+ Define a generic function board_init_f that:
+ - initialize the spl (spl_early_init)
+ - initialize the serial (preloader_console_init)
+ Unless you want to provide your own board_init_f, you should say Y.
+
+config SPL_SIZE_LIMIT
+ hex "Maximum size of SPL image"
+ depends on SPL
+ default 0x11000 if ARCH_MX6 && !MX6_OCRAM_256KB
+ default 0x31000 if ARCH_MX6 && MX6_OCRAM_256KB
+ default 0x0
+ help
+ Specifies the maximum length of the U-Boot SPL image.
+ If this value is zero, it is ignored.
+
+config SPL_SIZE_LIMIT_SUBTRACT_GD
+ bool "SPL image size check: provide space for global data"
+ depends on SPL_SIZE_LIMIT > 0
+ help
+ If enabled, aligned size of global data is reserved in
+ SPL_SIZE_LIMIT check to ensure such an image does not overflow SRAM
+ if SPL_SIZE_LIMIT describes the size of SRAM available for SPL when
+ pre-reloc global data is put into this SRAM, too.
+
+config SPL_SIZE_LIMIT_SUBTRACT_MALLOC
+ bool "SPL image size check: provide space for malloc() pool before relocation"
+ depends on SPL_SIZE_LIMIT > 0
+ help
+ If enabled, SPL_SYS_MALLOC_F_LEN is reserved in SPL_SIZE_LIMIT check
+ to ensure such an image does not overflow SRAM if SPL_SIZE_LIMIT
+ describes the size of SRAM available for SPL when pre-reloc malloc
+ pool is put into this SRAM, too.
+
+config SPL_SIZE_LIMIT_PROVIDE_STACK
+ hex "SPL image size check: provide stack space before relocation"
+ depends on SPL_SIZE_LIMIT > 0
+ default 0
+ help
+ If set, this size is reserved in SPL_SIZE_LIMIT check to ensure such
+ an image does not overflow SRAM if SPL_SIZE_LIMIT describes the size
+ of SRAM available for SPL when the stack required before reolcation
+ uses this SRAM, too.
+
+config SPL_SYS_STACK_F_CHECK_BYTE
+ hex
+ default 0xaa
+ help
+ Constant used to check the stack
+
+config SPL_SYS_REPORT_STACK_F_USAGE
+ depends on SPL_SIZE_LIMIT_PROVIDE_STACK != 0
+ bool "Check and report stack usage in SPL before relocation"
+ help
+ If this option is enabled, the initial SPL stack is filled with 0xaa
+ very early, up to the size configured with
+ SPL_SIZE_LIMIT_PROVIDE_STACK.
+ Later when SPL is done using this initial stack and switches to a
+ stack in DRAM, the actually used size of this initial stack is
+ reported by examining the memory and searching for the lowest
+ occurrence of non 0xaa bytes.
+ This default implementation works for stacks growing down only.
+
+menu "PowerPC and LayerScape SPL Boot options"
+
+config SPL_NAND_BOOT
+ bool "Load SPL from NAND flash"
+ depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK)
+
+config SPL_MMC_BOOT
+ bool "Load SPL from SD Card / eMMC"
+ depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK)
+
+config SPL_SPI_BOOT
+ bool "Load SPL from SPI flash"
+ depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK)
+
+config SPL_FSL_PBL
+ bool "Create SPL in Freescale PBI format"
+ depends on (PPC || ARCH_LS1021A || ARCH_LS1043A || ARCH_LS1046A) && \
+ SUPPORT_SPL
+ help
+ Create boot binary having SPL binary in PBI format concatenated with
+ u-boot binary.
+
+endmenu
+
+config HANDOFF
+ bool "Pass hand-off information from SPL to U-Boot proper"
+ depends on SPL && BLOBLIST
+ help
+ It is useful to be able to pass information from SPL to U-Boot
+ proper to preserve state that is known in SPL and is needed in U-Boot.
+ Enable this to locate the handoff information in U-Boot proper, early
+ in boot. It is available in gd->handoff. The state state is set up
+ in SPL (or TPL if that is being used).
+
+if SPL
+
+config SPL_HANDOFF
+ bool "Pass hand-off information from SPL to U-Boot proper"
+ depends on HANDOFF && SPL_BLOBLIST
+ default y
+ help
+ This option enables SPL to write handoff information. This can be
+ used to pass information like the size of SDRAM from SPL to U-Boot
+ proper. Also SPL can receive information from TPL in the same place
+ if that is enabled.
+
+config SPL_LDSCRIPT
+ string "Linker script for the SPL stage"
+ default "arch/\$(ARCH)/cpu/u-boot-spl.lds"
+ help
+ The SPL stage will usually require a different linker-script
+ (as it runs from a different memory region) than the regular
+ U-Boot stage. Set this to the path of the linker-script to
+ be used for SPL.
+
+config SPL_TEXT_BASE
+ hex "SPL Text Base"
+ default ISW_ENTRY_ADDR if AM43XX || AM33XX || OMAP54XX || ARCH_KEYSTONE
+ default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN9I
+ default 0x20060 if SUN50I_GEN_H6
+ default 0x00060 if ARCH_SUNXI
+ default 0xfffc0000 if ARCH_ZYNQMP
+ default 0x0
+ help
+ The address in memory that SPL will be running from.
+
+config SPL_BOARD_INIT
+ bool "Call board-specific initialization in SPL"
+ help
+ If this option is enabled, U-Boot will call the function
+ spl_board_init() from board_init_r(). This function should be
+ provided by the board.
+
+config SPL_BOOTROM_SUPPORT
+ bool "Support returning to the BOOTROM"
+ help
+ Some platforms (e.g. the Rockchip RK3368) provide support in their
+ ROM for loading the next boot-stage after performing basic setup
+ from the SPL stage.
+
+ Enable this option, to return to the BOOTROM through the
+ BOOT_DEVICE_BOOTROM (or fall-through to the next boot device in the
+ boot device list, if not implemented for a given board)
+
+config SPL_BOOTCOUNT_LIMIT
+ bool "Support bootcount in SPL"
+ depends on SPL_ENV_SUPPORT && !TPL_BOOTCOUNT_LIMIT
+ help
+ On some boards, which use 'falcon' mode, it is necessary to check
+ and increment the number of boot attempts. Such boards do not
+ use proper U-Boot for normal boot flow and hence needs those
+ adjustments to be done in the SPL.
+
+config SPL_RAW_IMAGE_SUPPORT
+ bool "Support SPL loading and booting of RAW images"
+ default n if (ARCH_MX6 && (SPL_MMC_SUPPORT || SPL_SATA_SUPPORT))
+ default y if !TI_SECURE_DEVICE
+ help
+ SPL will support loading and booting a RAW image when this option
+ is y. If this is not set, SPL will move on to other available
+ boot media to find a suitable image.
+
+config SPL_LEGACY_IMAGE_SUPPORT
+ bool "Support SPL loading and booting of Legacy images"
+ default y if !TI_SECURE_DEVICE && !SPL_LOAD_FIT
+ help
+ SPL will support loading and booting Legacy images when this option
+ is y. If this is not set, SPL will move on to other available
+ boot media to find a suitable image.
+
+config SPL_LEGACY_IMAGE_CRC_CHECK
+ bool "Check CRC of Legacy images"
+ depends on SPL_LEGACY_IMAGE_SUPPORT
+ select SPL_CRC32_SUPPORT
+ help
+ Enable this to check the CRC of Legacy images. While this increases
+ reliability, it affects both code size and boot duration.
+ If disabled, Legacy images are booted if the image magic and size
+ are correct, without further integrity checks.
+
+config SPL_SYS_MALLOC_SIMPLE
+ bool
+ prompt "Only use malloc_simple functions in the SPL"
+ help
+ Say Y here to only use the *_simple malloc functions from
+ malloc_simple.c, rather then using the versions from dlmalloc.c;
+ this will make the SPL binary smaller at the cost of more heap
+ usage as the *_simple malloc functions do not re-use free-ed mem.
+
+config TPL_SYS_MALLOC_SIMPLE
+ bool
+ prompt "Only use malloc_simple functions in the TPL"
+ depends on TPL
+ help
+ Say Y here to only use the *_simple malloc functions from
+ malloc_simple.c, rather then using the versions from dlmalloc.c;
+ this will make the TPL binary smaller at the cost of more heap
+ usage as the *_simple malloc functions do not re-use free-ed mem.
+
+config SPL_STACK_R
+ bool "Enable SDRAM location for SPL stack"
+ help
+ SPL starts off execution in SRAM and thus typically has only a small
+ stack available. Since SPL sets up DRAM while in its board_init_f()
+ function, it is possible for the stack to move there before
+ board_init_r() is reached. This option enables a special SDRAM
+ location for the SPL stack. U-Boot SPL switches to this after
+ board_init_f() completes, and before board_init_r() starts.
+
+config SPL_STACK_R_ADDR
+ depends on SPL_STACK_R
+ hex "SDRAM location for SPL stack"
+ default 0x82000000 if ARCH_OMAP2PLUS
+ help
+ Specify the address in SDRAM for the SPL stack. This will be set up
+ before board_init_r() is called.
+
+config SPL_STACK_R_MALLOC_SIMPLE_LEN
+ depends on SPL_STACK_R && SPL_SYS_MALLOC_SIMPLE
+ hex "Size of malloc_simple heap after switching to DRAM SPL stack"
+ default 0x100000
+ help
+ Specify the amount of the stack to use as memory pool for
+ malloc_simple after switching the stack to DRAM. This may be set
+ to give board_init_r() a larger heap then the initial heap in
+ SRAM which is limited to SYS_MALLOC_F_LEN bytes.
+
+config SPL_SEPARATE_BSS
+ bool "BSS section is in a different memory region from text"
+ help
+ Some platforms need a large BSS region in SPL and can provide this
+ because RAM is already set up. In this case BSS can be moved to RAM.
+ This option should then be enabled so that the correct device tree
+ location is used. Normally we put the device tree at the end of BSS
+ but with this option enabled, it goes at _image_binary_end.
+
+config SPL_READ_ONLY
+ bool
+ depends on SPL_OF_PLATDATA
+ # Bind cannot be supported because the udevice structs are in read-only
+ # memory so we cannot update the linked lists.
+ select SPL_OF_PLATDATA_NO_BIND
+ select SPL_OF_PLATDATA_RT
+ help
+ Some platforms (e.g. x86 Apollo Lake) load SPL into a read-only
+ section of memory. This means that of-platdata must make a copy (in
+ writeable memory) of anything it wants to modify, such as
+ device-private data.
+
+config SPL_BANNER_PRINT
+ bool "Enable output of the SPL banner 'U-Boot SPL ...'"
+ default y
+ help
+ If this option is enabled, SPL will print the banner with version
+ info. Disabling this option could be useful to reduce SPL boot time
+ (e.g. approx. 6 ms faster, when output on i.MX6 with 115200 baud).
+
+config TPL_BANNER_PRINT
+ bool "Enable output of the TPL banner 'U-Boot TPL ...'"
+ depends on TPL
+ default y
+ help
+ If this option is enabled, TPL will print the banner with version
+ info. Disabling this option could be useful to reduce TPL boot time
+ (e.g. approx. 6 ms faster, when output on i.MX6 with 115200 baud).
+
+config SPL_EARLY_BSS
+ depends on ARM && !ARM64
+ bool "Allows initializing BSS early before entering board_init_f"
+ help
+ On some platform we have sufficient memory available early on to
+ allow setting up and using a basic BSS prior to entering
+ board_init_f. Activating this option will also de-activate the
+ clearing of BSS during the SPL relocation process, thus allowing
+ to carry state from board_init_f to board_init_r by way of BSS.
+
+config SPL_DISPLAY_PRINT
+ bool "Display a board-specific message in SPL"
+ help
+ If this option is enabled, U-Boot will call the function
+ spl_display_print() immediately after displaying the SPL console
+ banner ("U-Boot SPL ..."). This function should be provided by
+ the board.
+
+config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
+ bool "MMC raw mode: by sector"
+ default y if ARCH_SUNXI || ARCH_DAVINCI || ARCH_UNIPHIER || \
+ ARCH_MX6 || ARCH_MX7 || \
+ ARCH_ROCKCHIP || ARCH_MVEBU || ARCH_SOCFPGA || \
+ ARCH_AT91 || ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \
+ OMAP44XX || OMAP54XX || AM33XX || AM43XX || \
+ TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED
+ help
+ Use sector number for specifying U-Boot location on MMC/SD in
+ raw mode.
+
+config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
+ hex "Address on the MMC to load U-Boot from"
+ depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
+ default 0x40 if ARCH_SUNXI
+ default 0x75 if ARCH_DAVINCI
+ default 0x8a if ARCH_MX6 || ARCH_MX7
+ default 0x100 if ARCH_UNIPHIER
+ default 0x140 if ARCH_MVEBU
+ default 0x200 if ARCH_SOCFPGA || ARCH_AT91
+ default 0x300 if ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || OMAP44XX || \
+ OMAP54XX || AM33XX || AM43XX || ARCH_K3
+ default 0x4000 if ARCH_ROCKCHIP
+ default 0x822 if TARGET_SIFIVE_UNLEASHED || TARGET_SIFIVE_UNMATCHED
+ help
+ Address on the MMC to load U-Boot from, when the MMC is being used
+ in raw mode. Units: MMC sectors (1 sector = 512 bytes).
+
+config SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET
+ hex "U-Boot main hardware partition image offset"
+ depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
+ default 0x10 if ARCH_SUNXI
+ default 0x0
+ help
+ On some platforms SPL location depends on hardware partition. The ROM
+ code skips the MBR sector when loading SPL from main hardware data
+ partition. This adds offset to the main U-Boot image. Set this symbol
+ to the number of skipped sectors.
+
+ If unsure, leave the default.
+
+config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
+ bool "MMC Raw mode: by partition"
+ help
+ Use a partition for loading U-Boot when using MMC/SD in raw mode.
+
+config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
+ hex "Partition to use to load U-Boot from"
+ depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
+ default 1
+ help
+ Partition on the MMC to load U-Boot from when the MMC is being
+ used in raw mode
+
+config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
+ bool "MMC raw mode: by partition type"
+ depends on DOS_PARTITION && SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
+ help
+ Use partition type for specifying U-Boot partition on MMC/SD in
+ raw mode. U-Boot will be loaded from the first partition of this
+ type to be found.
+
+config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE
+ hex "Partition Type on the MMC to load U-Boot from"
+ depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
+ help
+ Partition Type on the MMC to load U-Boot from, when the MMC is being
+ used in raw mode.
+
+config SUPPORT_EMMC_BOOT_OVERRIDE_PART_CONFIG
+ bool "Override eMMC EXT_CSC_PART_CONFIG by user defined partition"
+ depends on SUPPORT_EMMC_BOOT
+ help
+ eMMC boot partition is normally configured by the bits of the EXT_CSD
+ register (EXT_CSC_PART_CONFIG), BOOT_PARTITION_ENABLE field. In some
+ cases it might be required in SPL to load the image from different
+ partition than the partition selected by EXT_CSC_PART_CONFIG register.
+ Enable this option if you intend to use an eMMC boot partition other
+ then selected via EXT_CSC_PART_CONFIG register and specify the custom
+ partition number by the CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION
+ option.
+
+config SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION
+ int "Number of the eMMC boot partition to use"
+ depends on SUPPORT_EMMC_BOOT_OVERRIDE_PART_CONFIG
+ default 1
+ help
+ eMMC boot partition number to use when the eMMC in raw mode and
+ the eMMC EXT_CSC_PART_CONFIG selection should be overridden in SPL
+ by user defined partition number.
+
+config SPL_CRC32_SUPPORT
+ bool "Support CRC32"
+ default y if SPL_LEGACY_IMAGE_SUPPORT
+ help
+ Enable this to support CRC32 in uImages or FIT images within SPL.
+ This is a 32-bit checksum value that can be used to verify images.
+ For FIT images, this is the least secure type of checksum, suitable
+ for detected accidental image corruption. For secure applications you
+ should consider SHA1 or SHA256.
+
+config SPL_MD5_SUPPORT
+ bool "Support MD5"
+ depends on SPL_FIT
+ help
+ Enable this to support MD5 in FIT images within SPL. An MD5
+ checksum is a 128-bit hash value used to check that the image
+ contents have not been corrupted. Note that MD5 is not considered
+ secure as it is possible (with a brute-force attack) to adjust the
+ image while still retaining the same MD5 hash value. For secure
+ applications where images may be changed maliciously, you should
+ consider SHA256 or SHA384.
+
+config SPL_SHA1_SUPPORT
+ bool "Support SHA1"
+ depends on SPL_FIT
+ select SHA1
+ help
+ Enable this to support SHA1 in FIT images within SPL. A SHA1
+ checksum is a 160-bit (20-byte) hash value used to check that the
+ image contents have not been corrupted or maliciously altered.
+ While SHA1 is fairly secure it is coming to the end of its life
+ due to the expanding computing power available to brute-force
+ attacks. For more security, consider SHA256 or SHA384.
+
+config SPL_SHA256_SUPPORT
+ bool "Support SHA256"
+ depends on SPL_FIT
+ select SHA256
+ help
+ Enable this to support SHA256 in FIT images within SPL. A SHA256
+ checksum is a 256-bit (32-byte) hash value used to check that the
+ image contents have not been corrupted.
+
+config SPL_SHA384_SUPPORT
+ bool "Support SHA384"
+ depends on SPL_FIT
+ select SHA384
+ select SHA512_ALGO
+ help
+ Enable this to support SHA384 in FIT images within SPL. A SHA384
+ checksum is a 384-bit (48-byte) hash value used to check that the
+ image contents have not been corrupted. Use this for the highest
+ security.
+
+config SPL_SHA512_SUPPORT
+ bool "Support SHA512"
+ depends on SPL_FIT
+ select SHA512
+ select SHA512_ALGO
+ help
+ Enable this to support SHA512 in FIT images within SPL. A SHA512
+ checksum is a 512-bit (64-byte) hash value used to check that the
+ image contents have not been corrupted.
+
+config SPL_FIT_IMAGE_TINY
+ bool "Remove functionality from SPL FIT loading to reduce size"
+ depends on SPL_FIT
+ default y if MACH_SUN50I || MACH_SUN50I_H5 || SUN50I_GEN_H6
+ default y if ARCH_IMX8M
+ help
+ Enable this to reduce the size of the FIT image loading code
+ in SPL, if space for the SPL binary is very tight.
+
+ This skips the recording of each loaded payload
+ (i.e. loadable) into the FDT (modifying the loaded FDT to
+ ensure this information is available to the next image
+ invoked).
+
+config SPL_CACHE_SUPPORT
+ bool "Support CACHE drivers"
+ help
+ Enable CACHE drivers in SPL. These drivers can keep data so that
+ future requests for that data can be served faster. Enable this option
+ to build the drivers in drivers/cache as part of an SPL build.
+
+config SPL_CPU
+ bool "Support CPU drivers"
+ help
+ Enable this to support CPU drivers in SPL. These drivers can set
+ up CPUs and provide information about them such as the model and
+ name. This can be useful in SPL since setting up the CPUs earlier
+ may improve boot performance. Enable this option to build the
+ drivers in drivers/cpu as part of an SPL build.
+
+config SPL_CRYPTO_SUPPORT
+ bool "Support crypto drivers"
+ help
+ Enable crypto drivers in SPL. These drivers can be used to
+ accelerate secure boot processing in secure applications. Enable
+ this option to build the drivers in drivers/crypto as part of an
+ SPL build.
+
+config SPL_HASH_SUPPORT
+ bool "Support hashing drivers"
+ select SHA1
+ select SHA256
+ help
+ Enable hashing drivers in SPL. These drivers can be used to
+ accelerate secure boot processing in secure applications. Enable
+ this option to build system-specific drivers for hash acceleration
+ as part of an SPL build.
+
+config TPL_HASH_SUPPORT
+ bool "Support hashing drivers in TPL"
+ depends on TPL
+ select SHA1
+ select SHA256
+ help
+ Enable hashing drivers in SPL. These drivers can be used to
+ accelerate secure boot processing in secure applications. Enable
+ this option to build system-specific drivers for hash acceleration
+ as part of an SPL build.
+
+config SPL_DMA
+ bool "Support DMA drivers"
+ help
+ Enable DMA (direct-memory-access) drivers in SPL. These drivers
+ can be used to handle memory-to-peripheral data transfer without
+ the CPU moving the data. Enable this option to build the drivers
+ in drivers/dma as part of an SPL build.
+
+config SPL_DRIVERS_MISC_SUPPORT
+ bool "Support misc drivers"
+ help
+ Enable miscellaneous drivers in SPL. These drivers perform various
+ tasks that don't fall nicely into other categories, Enable this
+ option to build the drivers in drivers/misc as part of an SPL
+ build, for those that support building in SPL (not all drivers do).
+
+config SPL_ENV_SUPPORT
+ bool "Support an environment"
+ help
+ Enable environment support in SPL. The U-Boot environment provides
+ a number of settings (essentially name/value pairs) which can
+ control many aspects of U-Boot's operation. Normally this is not
+ needed in SPL as it has a much simpler task with less
+ configuration. But some boards use this to support 'Falcon' boot
+ on EXT2 and FAT, where SPL boots directly into Linux without
+ starting U-Boot first. Enabling this option will make env_get()
+ and env_set() available in SPL.
+
+config SPL_SAVEENV
+ bool "Support save environment"
+ depends on SPL_ENV_SUPPORT
+ select SPL_MMC_WRITE if ENV_IS_IN_MMC
+ help
+ Enable save environment support in SPL after setenv. By default
+ the saveenv option is not provided in SPL, but some boards need
+ this support in 'Falcon' boot, where SPL need to boot from
+ different images based on environment variable set by OS. For
+ example OS may set "reboot_image" environment variable to
+ "recovery" inorder to boot recovery image by SPL. The SPL read
+ "reboot_image" and act accordingly and change the reboot_image
+ to default mode using setenv and save the environment.
+
+config SPL_ETH_SUPPORT
+ bool "Support Ethernet"
+ depends on SPL_ENV_SUPPORT
+ help
+ Enable access to the network subsystem and associated Ethernet
+ drivers in SPL. This permits SPL to load U-Boot over an Ethernet
+ link rather than from an on-board peripheral. Environment support
+ is required since the network stack uses a number of environment
+ variables. See also SPL_NET_SUPPORT.
+
+config SPL_FS_EXT4
+ bool "Support EXT filesystems"
+ help
+ Enable support for EXT2/3/4 filesystems with SPL. This permits
+ U-Boot (or Linux in Falcon mode) to be loaded from an EXT
+ filesystem from within SPL. Support for the underlying block
+ device (e.g. MMC or USB) must be enabled separately.
+
+config SPL_FS_SQUASHFS
+ bool "Support SquashFS filesystems"
+ select FS_SQUASHFS
+ help
+ Enable support for SquashFS filesystems with SPL. This permits
+ U-Boot (or Linux in Falcon mode) to be loaded from a SquashFS
+ filesystem from within SPL. Support for the underlying block
+ device (e.g. MMC or USB) must be enabled separately.
+
+config SPL_FS_FAT
+ bool "Support FAT filesystems"
+ select FS_FAT
+ help
+ Enable support for FAT and VFAT filesystems with SPL. This
+ permits U-Boot (or Linux in Falcon mode) to be loaded from a FAT
+ filesystem from within SPL. Support for the underlying block
+ device (e.g. MMC or USB) must be enabled separately.
+
+config SPL_FAT_WRITE
+ bool "Support write for FAT filesystems"
+ help
+ Enable write support for FAT and VFAT filesystems with SPL.
+ Support for the underlying block device (e.g. MMC or USB) must be
+ enabled separately.
+
+config SPL_FPGA
+ bool "Support FPGAs"
+ help
+ Enable support for FPGAs in SPL. Field-programmable Gate Arrays
+ provide software-configurable hardware which is typically used to
+ implement peripherals (such as UARTs, LCD displays, MMC) or
+ accelerate custom processing functions, such as image processing
+ or machine learning. Sometimes it is useful to program the FPGA
+ as early as possible during boot, and this option can enable that
+ within SPL.
+
+config SPL_GPIO_SUPPORT
+ bool "Support GPIO in SPL"
+ help
+ Enable support for GPIOs (General-purpose Input/Output) in SPL.
+ GPIOs allow U-Boot to read the state of an input line (high or
+ low) and set the state of an output line. This can be used to
+ drive LEDs, control power to various system parts and read user
+ input. GPIOs can be useful in SPL to enable a 'sign-of-life' LED,
+ for example. Enable this option to build the drivers in
+ drivers/gpio as part of an SPL build.
+
+config SPL_I2C_SUPPORT
+ bool "Support I2C"
+ help
+ Enable support for the I2C (Inter-Integrated Circuit) bus in SPL.
+ I2C works with a clock and data line which can be driven by a
+ one or more masters or slaves. It is a fairly complex bus but is
+ widely used as it only needs two lines for communication. Speeds of
+ 400kbps are typical but up to 3.4Mbps is supported by some
+ hardware. I2C can be useful in SPL to configure power management
+ ICs (PMICs) before raising the CPU clock speed, for example.
+ Enable this option to build the drivers in drivers/i2c as part of
+ an SPL build.
+
+config SPL_LIBCOMMON_SUPPORT
+ bool "Support common libraries"
+ help
+ Enable support for common U-Boot libraries within SPL. These
+ libraries include common code to deal with U-Boot images,
+ environment and USB, for example. This option is enabled on many
+ boards. Enable this option to build the code in common/ as part of
+ an SPL build.
+
+config SPL_LIBDISK_SUPPORT
+ bool "Support disk partitions"
+ select PARTITIONS
+ help
+ Enable support for disk partitions within SPL. 'Disk' is something
+ of a misnomer as it includes non-spinning media such as flash (as
+ used in MMC and USB sticks). Partitions provide a way for a disk
+ to be split up into separate regions, with a partition table placed
+ at the start or end which describes the location and size of each
+ 'partition'. These partitions are typically uses as individual block
+ devices, typically with an EXT2 or FAT filesystem in each. This
+ option enables whatever partition support has been enabled in
+ U-Boot to also be used in SPL. It brings in the code in disk/.
+
+config SPL_LIBGENERIC_SUPPORT
+ bool "Support generic libraries"
+ help
+ Enable support for generic U-Boot libraries within SPL. These
+ libraries include generic code to deal with device tree, hashing,
+ printf(), compression and the like. This option is enabled on many
+ boards. Enable this option to build the code in lib/ as part of an
+ SPL build.
+
+config SPL_DM_MAILBOX
+ bool "Support Mailbox"
+ help
+ Enable support for Mailbox within SPL. This enable the inter
+ processor communication protocols tobe used within SPL. Enable
+ this option to build the drivers in drivers/mailbox as part of
+ SPL build.
+
+config SPL_MMC_SUPPORT
+ bool "Support MMC"
+ depends on MMC
+ select HAVE_BLOCK_DEVICE
+ help
+ Enable support for MMC (Multimedia Card) within SPL. This enables
+ the MMC protocol implementation and allows any enabled drivers to
+ be used within SPL. MMC can be used with or without disk partition
+ support depending on the application (SPL_LIBDISK_SUPPORT). Enable
+ this option to build the drivers in drivers/mmc as part of an SPL
+ build.
+
+config SYS_MMCSD_FS_BOOT_PARTITION
+ int "MMC Boot Partition"
+ default 1
+ help
+ Partition on the MMC to load U-Boot from when the MMC is being
+ used in fs mode
+
+config SPL_MMC_TINY
+ bool "Tiny MMC framework in SPL"
+ depends on SPL_MMC_SUPPORT
+ default n
+ help
+ Enable MMC framework tinification support. This option is useful if
+ if your SPL is extremely size constrained. Heed the warning, enable
+ this option if and only if you know exactly what you are doing, if
+ you are reading this help text, you most likely have no idea :-)
+
+ The MMC framework is reduced to bare minimum to be useful. No malloc
+ support is needed for the MMC framework operation with this option
+ enabled. The framework supports exactly one MMC device and exactly
+ one MMC driver. The MMC driver can be adjusted to avoid any malloc
+ operations too, which can remove the need for malloc support in SPL
+ and thus further reduce footprint.
+
+config SPL_MMC_WRITE
+ bool "MMC/SD/SDIO card support for write operations in SPL"
+ depends on SPL_MMC_SUPPORT
+ default n
+ help
+ Enable write access to MMC and SD Cards in SPL
+
+
+config SPL_MPC8XXX_INIT_DDR_SUPPORT
+ bool "Support MPC8XXX DDR init"
+ help
+ Enable support for DDR-SDRAM (double-data-rate synchronous dynamic
+ random-access memory) on the MPC8XXX family within SPL. This
+ allows DRAM to be set up before loading U-Boot into that DRAM,
+ where it can run.
+
+config SPL_MTD_SUPPORT
+ bool "Support MTD drivers"
+ help
+ Enable support for MTD (Memory Technology Device) within SPL. MTD
+ provides a block interface over raw NAND and can also be used with
+ SPI flash. This allows SPL to load U-Boot from supported MTD
+ devices. See SPL_NAND_SUPPORT and SPL_ONENAND_SUPPORT for how
+ to enable specific MTD drivers.
+
+config SPL_MUSB_NEW_SUPPORT
+ bool "Support new Mentor Graphics USB"
+ help
+ Enable support for Mentor Graphics USB in SPL. This is a new
+ driver used by some boards. Enable this option to build
+ the drivers in drivers/usb/musb-new as part of an SPL build. The
+ old drivers are in drivers/usb/musb.
+
+config SPL_NAND_SUPPORT
+ bool "Support NAND flash"
+ help
+ Enable support for NAND (Negative AND) flash in SPL. NAND flash
+ can be used to allow SPL to load U-Boot from supported devices.
+ This enables the drivers in drivers/mtd/nand/raw as part of an SPL
+ build.
+
+config SPL_NAND_DRIVERS
+ bool "Use standard NAND driver"
+ help
+ SPL uses normal NAND drivers, not minimal drivers.
+
+config SPL_NAND_ECC
+ bool "Include standard software ECC in the SPL"
+
+config SPL_NAND_SIMPLE
+ bool "Support simple NAND drivers in SPL"
+ help
+ Support for NAND boot using simple NAND drivers that
+ expose the cmd_ctrl() interface.
+
+config SPL_NAND_BASE
+ depends on SPL_NAND_DRIVERS
+ bool "Use Base NAND Driver"
+ help
+ Include nand_base.c in the SPL.
+
+config SPL_NAND_IDENT
+ depends on SPL_NAND_BASE
+ bool "Use chip ID to identify NAND flash"
+ help
+ SPL uses the chip ID list to identify the NAND flash.
+
+config SPL_UBI
+ bool "Support UBI"
+ help
+ Enable support for loading payloads from UBI. See
+ README.ubispl for more info.
+
+if SPL_DM
+config SPL_CACHE
+ depends on CACHE
+ bool "Support cache drivers in SPL"
+ help
+ Enable support for cache drivers in SPL.
+
+config SPL_DM_SPI
+ bool "Support SPI DM drivers in SPL"
+ help
+ Enable support for SPI DM drivers in SPL.
+
+config SPL_DM_SPI_FLASH
+ bool "Support SPI DM FLASH drivers in SPL"
+ help
+ Enable support for SPI DM flash drivers in SPL.
+
+endif
+if SPL_UBI
+config SPL_UBI_LOAD_BY_VOLNAME
+ bool "Support loading volumes by name"
+ help
+ This enables support for loading UBI volumes by name. When this
+ is set, CONFIG_SPL_UBI_LOAD_MONITOR_VOLNAME can be used to
+ configure the volume name from which to load U-Boot.
+
+config SPL_UBI_MAX_VOL_LEBS
+ int "Maximum number of LEBs per volume"
+ depends on SPL_UBI
+ help
+ The maximum number of logical eraseblocks which a static volume
+ to load can contain. Used for sizing the scan data structure.
+
+config SPL_UBI_MAX_PEB_SIZE
+ int "Maximum PEB size"
+ depends on SPL_UBI
+ help
+ The maximum physical erase block size.
+
+config SPL_UBI_MAX_PEBS
+ int "Maximum number of PEBs"
+ depends on SPL_UBI
+ help
+ The maximum physical erase block size. If not overridden by
+ board code, this value will be used as the actual number of PEBs.
+
+config SPL_UBI_PEB_OFFSET
+ int "Offset to first UBI PEB"
+ depends on SPL_UBI
+ help
+ The offset in number of PEBs from the start of flash to the first
+ PEB part of the UBI image.
+
+config SPL_UBI_VID_OFFSET
+ int "Offset to VID header"
+ depends on SPL_UBI
+
+config SPL_UBI_LEB_START
+ int "Offset to LEB in PEB"
+ depends on SPL_UBI
+ help
+ The offset in bytes to the LEB within a PEB.
+
+config SPL_UBI_INFO_ADDR
+ hex "Address to place UBI scan info"
+ depends on SPL_UBI
+ help
+ Address for ubispl to place the scan info. Read README.ubispl to
+ determine the required size
+
+config SPL_UBI_VOL_IDS
+ int "Maximum volume id"
+ depends on SPL_UBI
+ help
+ The maximum volume id which can be loaded. Used for sizing the
+ scan data structure.
+
+config SPL_UBI_LOAD_MONITOR_ID
+ int "id of U-Boot volume"
+ depends on SPL_UBI
+ help
+ The UBI volume id from which to load U-Boot
+
+config SPL_UBI_LOAD_MONITOR_VOLNAME
+ string "volume name of U-Boot volume"
+ depends on SPL_UBI_LOAD_BY_VOLNAME
+ help
+ The UBI volume name from which to load U-Boot
+
+config SPL_UBI_LOAD_KERNEL_ID
+ int "id of kernel volume"
+ depends on SPL_OS_BOOT && SPL_UBI
+ help
+ The UBI volume id from which to load the kernel
+
+config SPL_UBI_LOAD_ARGS_ID
+ int "id of kernel args volume"
+ depends on SPL_OS_BOOT && SPL_UBI
+ help
+ The UBI volume id from which to load the device tree
+
+config UBI_SPL_SILENCE_MSG
+ bool "silence UBI SPL messages"
+ default n
+ help
+ Disable messages from UBI SPL. This leaves warnings
+ and errors enabled.
+
+endif # if SPL_UBI
+
+config SPL_NET_SUPPORT
+ bool "Support networking"
+ help
+ Enable support for network devices (such as Ethernet) in SPL.
+ This permits SPL to load U-Boot over a network link rather than
+ from an on-board peripheral. Environment support is required since
+ the network stack uses a number of environment variables. See also
+ SPL_ETH_SUPPORT.
+
+if SPL_NET_SUPPORT
+config SPL_NET_VCI_STRING
+ string "BOOTP Vendor Class Identifier string sent by SPL"
+ help
+ As defined by RFC 2132 the vendor class identifier field can be
+ sent by the client to identify the vendor type and configuration
+ of a client. This is often used in practice to allow for the DHCP
+ server to specify different files to load depending on if the ROM,
+ SPL or U-Boot itself makes the request
+endif # if SPL_NET_SUPPORT
+
+config SPL_NO_CPU_SUPPORT
+ bool "Drop CPU code in SPL"
+ help
+ This is specific to the ARM926EJ-S CPU. It disables the standard
+ start.S start-up code, presumably so that a replacement can be
+ used on that CPU. You should not enable it unless you know what
+ you are doing.
+
+config SPL_NOR_SUPPORT
+ bool "Support NOR flash"
+ help
+ Enable support for loading U-Boot from memory-mapped NOR (Negative
+ OR) flash in SPL. NOR flash is slow to write but fast to read, and
+ a memory-mapped device makes it very easy to access. Loading from
+ NOR is typically achieved with just a memcpy().
+
+config SPL_XIP_SUPPORT
+ bool "Support XIP"
+ depends on SPL
+ help
+ Enable support for execute in place of U-Boot or kernel image. There
+ is no need to copy image from flash to ram if flash supports execute
+ in place. Its very useful in systems having enough flash but not
+ enough ram to load the image.
+
+config SPL_ONENAND_SUPPORT
+ bool "Support OneNAND flash"
+ help
+ Enable support for OneNAND (Negative AND) flash in SPL. OneNAND is
+ a type of NAND flash and therefore can be used to allow SPL to
+ load U-Boot from supported devices. This enables the drivers in
+ drivers/mtd/onenand as part of an SPL build.
+
+config SPL_OS_BOOT
+ bool "Activate Falcon Mode"
+ depends on !TI_SECURE_DEVICE
+ default n
+ help
+ Enable booting directly to an OS from SPL.
+ for more info read doc/README.falcon
+
+if SPL_OS_BOOT
+config SYS_OS_BASE
+ hex "addr, where OS is found"
+ depends on SPL_NOR_SUPPORT
+ help
+ Specify the address, where the OS image is found, which
+ gets booted.
+
+endif # SPL_OS_BOOT
+
+config SPL_PAYLOAD
+ string "SPL payload"
+ default "tpl/u-boot-with-tpl.bin" if TPL
+ default "u-boot.bin"
+ help
+ Payload for SPL boot. For backward compatibility, default to
+ u-boot.bin, i.e. RAW image without any header. In case of
+ TPL, tpl/u-boot-with-tpl.bin. For new boards, suggest to
+ use u-boot.img.
+
+config SPL_PCI
+ bool "Support PCI drivers"
+ help
+ Enable support for PCI in SPL. For platforms that need PCI to boot,
+ or must perform some init using PCI in SPL, this provides the
+ necessary driver support. This enables the drivers in drivers/pci
+ as part of an SPL build.
+
+config SPL_PCH_SUPPORT
+ bool "Support PCH drivers"
+ help
+ Enable support for PCH (Platform Controller Hub) devices in SPL.
+ These are used to set up GPIOs and the SPI peripheral early in
+ boot. This enables the drivers in drivers/pch as part of an SPL
+ build.
+
+config SPL_POST_MEM_SUPPORT
+ bool "Support POST drivers"
+ help
+ Enable support for POST (Power-on Self Test) in SPL. POST is a
+ procedure that checks that the hardware (CPU or board) appears to
+ be functionally correctly. It is a sanity check that can be
+ performed before booting. This enables the drivers in post/drivers
+ as part of an SPL build.
+
+config SPL_DM_RESET
+ bool "Support reset drivers"
+ depends on SPL
+ help
+ Enable support for reset control in SPL.
+ That can be useful in SPL to handle IP reset in driver, as in U-Boot,
+ by using the generic reset API provided by driver model.
+ This enables the drivers in drivers/reset as part of an SPL build.
+
+config SPL_POWER_SUPPORT
+ bool "Support power drivers"
+ help
+ Enable support for power control in SPL. This includes support
+ for PMICs (Power-management Integrated Circuits) and some of the
+ features provided by PMICs. In particular, voltage regulators can
+ be used to enable/disable power and vary its voltage. That can be
+ useful in SPL to turn on boot peripherals and adjust CPU voltage
+ so that the clock speed can be increased. This enables the drivers
+ in drivers/power, drivers/power/pmic and drivers/power/regulator
+ as part of an SPL build.
+
+config SPL_POWER_DOMAIN
+ bool "Support power domain drivers"
+ help
+ Enable support for power domain control in SPL. Many SoCs allow
+ power to be applied to or removed from portions of the SoC (power
+ domains). This may be used to save power. This API provides the
+ means to control such power management hardware. This enables
+ the drivers in drivers/power/domain as part of a SPL build.
+
+config SPL_RAM_SUPPORT
+ bool "Support booting from RAM"
+ default y if MICROBLAZE || ARCH_SOCFPGA || ARCH_TEGRA || ARCH_ZYNQ
+ help
+ Enable booting of an image in RAM. The image can be preloaded or
+ it can be loaded by SPL directly into RAM (e.g. using USB).
+
+config SPL_RAM_DEVICE
+ bool "Support booting from preloaded image in RAM"
+ depends on SPL_RAM_SUPPORT
+ default y if MICROBLAZE || ARCH_SOCFPGA || ARCH_TEGRA || ARCH_ZYNQ
+ help
+ Enable booting of an image already loaded in RAM. The image has to
+ be already in memory when SPL takes over, e.g. loaded by the boot
+ ROM.
+
+config SPL_REMOTEPROC
+ bool "Support REMOTEPROCS"
+ help
+ Enable support for REMOTEPROCs in SPL. This permits to load
+ a remote processor firmware in SPL.
+
+config SPL_RTC_SUPPORT
+ bool "Support RTC drivers"
+ help
+ Enable RTC (Real-time Clock) support in SPL. This includes support
+ for reading and setting the time. Some RTC devices also have some
+ non-volatile (battery-backed) memory which is accessible if
+ needed. This enables the drivers in drivers/rtc as part of an SPL
+ build.
+
+config SPL_SATA_SUPPORT
+ bool "Support loading from SATA"
+ help
+ Enable support for SATA (Serial AT attachment) in SPL. This allows
+ use of SATA devices such as hard drives and flash drivers for
+ loading U-Boot. SATA is used in higher-end embedded systems and
+ can provide higher performance than MMC , at somewhat higher
+ expense and power consumption. This enables loading from SATA
+ using a configured device.
+
+config SPL_SATA_RAW_U_BOOT_USE_SECTOR
+ bool "SATA raw mode: by sector"
+ depends on SPL_SATA_SUPPORT
+ help
+ Use sector number for specifying U-Boot location on SATA disk in
+ raw mode.
+
+config SPL_SATA_RAW_U_BOOT_SECTOR
+ hex "Sector on the SATA disk to load U-Boot from"
+ depends on SPL_SATA_RAW_U_BOOT_USE_SECTOR
+ help
+ Sector on the SATA disk to load U-Boot from, when the SATA disk is being
+ used in raw mode. Units: SATA disk sectors (1 sector = 512 bytes).
+
+config SPL_SERIAL_SUPPORT
+ bool "Support serial"
+ select SPL_PRINTF
+ select SPL_STRTO
+ help
+ Enable support for serial in SPL. This allows use of a serial UART
+ for displaying messages while SPL is running. It also brings in
+ printf() and panic() functions. This should normally be enabled
+ unless there are space reasons not to. Even then, consider
+ enabling SPL_USE_TINY_PRINTF which is a small printf() version.
+
+config SPL_SPI_SUPPORT
+ bool "Support SPI drivers"
+ help
+ Enable support for using SPI in SPL. This is used for connecting
+ to SPI flash for loading U-Boot. See SPL_SPI_FLASH_SUPPORT for
+ more details on that. The SPI driver provides the transport for
+ data between the SPI flash and the CPU. This option can be used to
+ enable SPI drivers that are needed for other purposes also, such
+ as a SPI PMIC.
+
+config SPL_SPI_FLASH_SUPPORT
+ bool "Support SPI flash drivers"
+ depends on SPL_SPI_SUPPORT
+ help
+ Enable support for using SPI flash in SPL, and loading U-Boot from
+ SPI flash. SPI flash (Serial Peripheral Bus flash) is named after
+ the SPI bus that is used to connect it to a system. It is a simple
+ but fast bidirectional 4-wire bus (clock, chip select and two data
+ lines). This enables the drivers in drivers/mtd/spi as part of an
+ SPL build. This normally requires SPL_SPI_SUPPORT.
+
+if SPL_SPI_FLASH_SUPPORT
+
+config SPL_SPI_FLASH_TINY
+ bool "Enable low footprint SPL SPI Flash support"
+ depends on !SPI_FLASH_BAR
+ default y if SPI_FLASH
+ help
+ Enable lightweight SPL SPI Flash support that supports just reading
+ data/images from flash. No support to write/erase flash. Enable
+ this if you have SPL size limitations and don't need full
+ fledged SPI flash support.
+
+config SPL_SPI_FLASH_SFDP_SUPPORT
+ bool "SFDP table parsing support for SPI NOR flashes"
+ depends on !SPI_FLASH_BAR && !SPL_SPI_FLASH_TINY
+ help
+ Enable support for parsing and auto discovery of parameters for
+ SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP)
+ tables as per JESD216 standard in SPL.
+
+config SPL_SPI_FLASH_MTD
+ bool "Support for SPI flash MTD drivers in SPL"
+ help
+ Enable support for SPI flash MTD drivers in SPL.
+
+config SPL_SPI_LOAD
+ bool "Support loading from SPI flash"
+ help
+ Enable support for loading next stage, U-Boot or otherwise, from
+ SPI NOR in U-Boot SPL.
+
+endif # SPL_SPI_FLASH_SUPPORT
+
+config SYS_SPI_U_BOOT_OFFS
+ hex "address of u-boot payload in SPI flash"
+ default 0x8000 if ARCH_SUNXI
+ default 0x0
+ depends on SPL_SPI_LOAD || SPL_SPI_SUNXI
+ help
+ Address within SPI-Flash from where the u-boot payload is fetched
+ from.
+
+config SPL_THERMAL
+ bool "Driver support for thermal devices"
+ help
+ Enable support for temperature-sensing devices. Some SoCs have on-chip
+ temperature sensors to permit warnings, speed throttling or even
+ automatic power-off when the temperature gets too high or low. Other
+ devices may be discrete but connected on a suitable bus.
+
+config SPL_USB_HOST_SUPPORT
+ bool "Support USB host drivers"
+ select HAVE_BLOCK_DEVICE
+ help
+ Enable access to USB (Universal Serial Bus) host devices so that
+ SPL can load U-Boot from a connected USB peripheral, such as a USB
+ flash stick. While USB takes a little longer to start up than most
+ buses, it is very flexible since many different types of storage
+ device can be attached. This option enables the drivers in
+ drivers/usb/host as part of an SPL build.
+
+config SPL_USB_STORAGE
+ bool "Support loading from USB"
+ depends on SPL_USB_HOST_SUPPORT && !(BLK && !DM_USB)
+ help
+ Enable support for USB devices in SPL. This allows use of USB
+ devices such as hard drives and flash drivers for loading U-Boot.
+ The actual drivers are enabled separately using the normal U-Boot
+ config options. This enables loading from USB using a configured
+ device.
+
+config SPL_USB_GADGET
+ bool "Suppport USB Gadget drivers"
+ help
+ Enable USB Gadget API which allows to enable USB device functions
+ in SPL.
+
+if SPL_USB_GADGET
+
+config SPL_USB_ETHER
+ bool "Support USB Ethernet drivers"
+ help
+ Enable access to the USB network subsystem and associated
+ drivers in SPL. This permits SPL to load U-Boot over a
+ USB-connected Ethernet link (such as a USB Ethernet dongle) rather
+ than from an onboard peripheral. Environment support is required
+ since the network stack uses a number of environment variables.
+ See also SPL_NET_SUPPORT and SPL_ETH_SUPPORT.
+
+config SPL_DFU
+ bool "Support DFU (Device Firmware Upgrade)"
+ select SPL_HASH_SUPPORT
+ select SPL_DFU_NO_RESET
+ depends on SPL_RAM_SUPPORT
+ help
+ This feature enables the DFU (Device Firmware Upgrade) in SPL with
+ RAM memory device support. The ROM code will load and execute
+ the SPL built with dfu. The user can load binaries (u-boot/kernel) to
+ selected device partition from host-pc using dfu-utils.
+ This feature is useful to flash the binaries to factory or bare-metal
+ boards using USB interface.
+
+choice
+ bool "DFU device selection"
+ depends on SPL_DFU
+
+config SPL_DFU_RAM
+ bool "RAM device"
+ depends on SPL_DFU && SPL_RAM_SUPPORT
+ help
+ select RAM/DDR memory device for loading binary images
+ (u-boot/kernel) to the selected device partition using
+ DFU and execute the u-boot/kernel from RAM.
+
+endchoice
+
+config SPL_USB_SDP_SUPPORT
+ bool "Support SDP (Serial Download Protocol)"
+ depends on SPL_SERIAL_SUPPORT
+ help
+ Enable Serial Download Protocol (SDP) device support in SPL. This
+ allows to download images into memory and execute (jump to) them
+ using the same protocol as implemented by the i.MX family's boot ROM.
+
+config SPL_SDP_USB_DEV
+ int "SDP USB controller index"
+ default 0
+ depends on SPL_USB_SDP_SUPPORT
+ help
+ Some boards have USB controller other than 0. Define this option
+ so it can be used in compiled environment.
+endif
+
+config SPL_WATCHDOG_SUPPORT
+ bool "Support watchdog drivers"
+ imply SPL_WDT if !HW_WATCHDOG
+ help
+ Enable support for watchdog drivers in SPL. A watchdog is
+ typically a hardware peripheral which can reset the system when it
+ detects no activity for a while (such as a software crash). This
+ enables the drivers in drivers/watchdog as part of an SPL build.
+
+config SPL_YMODEM_SUPPORT
+ bool "Support loading using Ymodem"
+ depends on SPL_SERIAL_SUPPORT
+ help
+ While loading from serial is slow it can be a useful backup when
+ there is no other option. The Ymodem protocol provides a reliable
+ means of transmitting U-Boot over a serial line for using in SPL,
+ with a checksum to ensure correctness.
+
+config SPL_ATF
+ bool "Support ARM Trusted Firmware"
+ depends on ARM64 && SPL_FIT
+ help
+ ATF(ARM Trusted Firmware) is a component for ARM AArch64 which
+ is loaded by SPL (which is considered as BL2 in ATF terminology).
+ More detail at: https://github.com/ARM-software/arm-trusted-firmware
+
+config SPL_ATF_LOAD_IMAGE_V2
+ bool "Use the new LOAD_IMAGE_V2 parameter passing"
+ depends on SPL_ATF
+ help
+ Some platforms use the newer LOAD_IMAGE_V2 parameter passing.
+
+ If you want to load a bl31 image from the SPL and need the new
+ method, say Y.
+
+config SPL_ATF_NO_PLATFORM_PARAM
+ bool "Pass no platform parameter"
+ depends on SPL_ATF
+ help
+ While we expect to call a pointer to a valid FDT (or NULL)
+ as the platform parameter to an ATF, some ATF versions are
+ not U-Boot aware and have an insufficiently robust parameter
+ validation to gracefully reject a FDT being passed.
+
+ If this option is enabled, the spl_atf os-type handler will
+ always pass NULL for the platform parameter.
+
+ If your ATF is affected, say Y.
+
+config SPL_AM33XX_ENABLE_RTC32K_OSC
+ bool "Enable the RTC32K OSC on AM33xx based platforms"
+ default y if AM33XX
+ help
+ Enable access to the AM33xx RTC and select the external 32kHz clock
+ source.
+
+config SPL_OPTEE
+ bool "Support OP-TEE Trusted OS"
+ depends on ARM
+ help
+ OP-TEE is an open source Trusted OS which is loaded by SPL.
+ More detail at: https://github.com/OP-TEE/optee_os
+
+config SPL_OPENSBI
+ bool "Support RISC-V OpenSBI"
+ depends on RISCV && SPL_RISCV_MMODE && RISCV_SMODE
+ help
+ OpenSBI is an open-source implementation of the RISC-V Supervisor Binary
+ Interface (SBI) specification. U-Boot supports the OpenSBI FW_DYNAMIC
+ firmware. It is loaded and started by U-Boot SPL.
+
+ More details are available at https://github.com/riscv/opensbi and
+ https://github.com/riscv/riscv-sbi-doc
+
+config SPL_OPENSBI_LOAD_ADDR
+ hex "OpenSBI load address"
+ depends on SPL_OPENSBI
+ help
+ Load address of the OpenSBI binary.
+
+config TPL
+ bool
+ depends on SUPPORT_TPL
+ prompt "Enable TPL"
+ help
+ If you want to build TPL as well as the normal image and SPL, say Y.
+
+if TPL
+
+config TPL_SIZE_LIMIT
+ hex "Maximum size of TPL image"
+ depends on TPL
+ default 0x0
+ help
+ Specifies the maximum length of the U-Boot TPL image.
+ If this value is zero, it is ignored.
+
+config TPL_FRAMEWORK
+ bool "Support TPL based upon the common SPL framework"
+ default y if SPL_FRAMEWORK
+ help
+ Enable the SPL framework under common/spl/ for TPL builds.
+ This framework supports MMC, NAND and YMODEM and other methods
+ loading of U-Boot's SPL stage. If unsure, say Y.
+
+config TPL_HANDOFF
+ bool "Pass hand-off information from TPL to SPL and U-Boot proper"
+ depends on HANDOFF && TPL_BLOBLIST
+ default y
+ help
+ This option enables TPL to write handoff information. This can be
+ used to pass information like the size of SDRAM from TPL to U-Boot
+ proper. The information is also available to SPL if it is useful
+ there.
+
+config TPL_BOARD_INIT
+ bool "Call board-specific initialization in TPL"
+ help
+ If this option is enabled, U-Boot will call the function
+ spl_board_init() from board_init_r(). This function should be
+ provided by the board.
+
+config TPL_BOOTCOUNT_LIMIT
+ bool "Support bootcount in TPL"
+ depends on TPL_ENV_SUPPORT
+ help
+ If this option is enabled, the TPL will support bootcount.
+ For example, it may be useful to choose the device to boot.
+
+config TPL_LDSCRIPT
+ string "Linker script for the TPL stage"
+ depends on TPL
+ default "arch/arm/cpu/armv8/u-boot-spl.lds" if ARM64
+ default "arch/\$(ARCH)/cpu/u-boot-spl.lds"
+ help
+ The TPL stage will usually require a different linker-script
+ (as it runs from a different memory region) than the regular
+ U-Boot stage. Set this to the path of the linker-script to
+ be used for TPL.
+
+ May be left empty to trigger the Makefile infrastructure to
+ fall back to the linker-script used for the SPL stage.
+
+config TPL_NEEDS_SEPARATE_TEXT_BASE
+ bool "TPL needs a separate text-base"
+ default n
+ depends on TPL
+ help
+ Enable, if the TPL stage should not inherit its text-base
+ from the SPL stage. When enabled, a base address for the
+ .text sections of the TPL stage has to be set below.
+
+config TPL_NEEDS_SEPARATE_STACK
+ bool "TPL needs a separate initial stack-pointer"
+ default n
+ depends on TPL
+ help
+ Enable, if the TPL stage should not inherit its initial
+ stack-pointer from the settings for the SPL stage.
+
+config TPL_TEXT_BASE
+ hex "Base address for the .text section of the TPL stage"
+ depends on TPL_NEEDS_SEPARATE_TEXT_BASE
+ help
+ The base address for the .text section of the TPL stage.
+
+config TPL_MAX_SIZE
+ int "Maximum size (in bytes) for the TPL stage"
+ default 0
+ depends on TPL
+ help
+ The maximum size (in bytes) of the TPL stage.
+
+config TPL_STACK
+ hex "Address of the initial stack-pointer for the TPL stage"
+ depends on TPL_NEEDS_SEPARATE_STACK
+ help
+ The address of the initial stack-pointer for the TPL stage.
+ Usually this will be the (aligned) top-of-stack.
+
+config TPL_READ_ONLY
+ bool
+ depends on TPL_OF_PLATDATA
+ select TPL_OF_PLATDATA_NO_BIND
+ select TPL_OF_PLATDATA_RT
+ help
+ Some platforms (e.g. x86 Apollo Lake) load SPL into a read-only
+ section of memory. This means that of-platdata must make a copy (in
+ writeable memory) of anything it wants to modify, such as
+ device-private data.
+
+config TPL_BOOTROM_SUPPORT
+ bool "Support returning to the BOOTROM (from TPL)"
+ help
+ Some platforms (e.g. the Rockchip RK3368) provide support in their
+ ROM for loading the next boot-stage after performing basic setup
+ from the TPL stage.
+
+ Enable this option, to return to the BOOTROM through the
+ BOOT_DEVICE_BOOTROM (or fall-through to the next boot device in the
+ boot device list, if not implemented for a given board)
+
+config TPL_DRIVERS_MISC_SUPPORT
+ bool "Support misc drivers in TPL"
+ help
+ Enable miscellaneous drivers in TPL. These drivers perform various
+ tasks that don't fall nicely into other categories, Enable this
+ option to build the drivers in drivers/misc as part of an TPL
+ build, for those that support building in TPL (not all drivers do).
+
+config TPL_ENV_SUPPORT
+ bool "Support an environment"
+ help
+ Enable environment support in TPL. See SPL_ENV_SUPPORT for details.
+
+config TPL_GPIO_SUPPORT
+ bool "Support GPIO in TPL"
+ help
+ Enable support for GPIOs (General-purpose Input/Output) in TPL.
+ GPIOs allow U-Boot to read the state of an input line (high or
+ low) and set the state of an output line. This can be used to
+ drive LEDs, control power to various system parts and read user
+ input. GPIOs can be useful in TPL to enable a 'sign-of-life' LED,
+ for example. Enable this option to build the drivers in
+ drivers/gpio as part of an TPL build.
+
+config TPL_I2C_SUPPORT
+ bool "Support I2C"
+ help
+ Enable support for the I2C bus in TPL. See SPL_I2C_SUPPORT for
+ details.
+
+config TPL_LIBCOMMON_SUPPORT
+ bool "Support common libraries"
+ help
+ Enable support for common U-Boot libraries within TPL. See
+ SPL_LIBCOMMON_SUPPORT for details.
+
+config TPL_LIBGENERIC_SUPPORT
+ bool "Support generic libraries"
+ help
+ Enable support for generic U-Boot libraries within TPL. See
+ SPL_LIBGENERIC_SUPPORT for details.
+
+config TPL_MPC8XXX_INIT_DDR_SUPPORT
+ bool "Support MPC8XXX DDR init"
+ help
+ Enable support for DDR-SDRAM on the MPC8XXX family within TPL. See
+ SPL_MPC8XXX_INIT_DDR_SUPPORT for details.
+
+config TPL_MMC_SUPPORT
+ bool "Support MMC"
+ depends on MMC
+ help
+ Enable support for MMC within TPL. See SPL_MMC_SUPPORT for details.
+
+config TPL_NAND_SUPPORT
+ bool "Support NAND flash"
+ help
+ Enable support for NAND in TPL. See SPL_NAND_SUPPORT for details.
+
+config TPL_PCI
+ bool "Support PCI drivers"
+ help
+ Enable support for PCI in TPL. For platforms that need PCI to boot,
+ or must perform some init using PCI in SPL, this provides the
+ necessary driver support. This enables the drivers in drivers/pci
+ as part of a TPL build.
+
+config TPL_PCH_SUPPORT
+ bool "Support PCH drivers"
+ help
+ Enable support for PCH (Platform Controller Hub) devices in TPL.
+ These are used to set up GPIOs and the SPI peripheral early in
+ boot. This enables the drivers in drivers/pch as part of a TPL
+ build.
+
+config TPL_RAM_SUPPORT
+ bool "Support booting from RAM"
+ help
+ Enable booting of an image in RAM. The image can be preloaded or
+ it can be loaded by TPL directly into RAM (e.g. using USB).
+
+config TPL_RAM_DEVICE
+ bool "Support booting from preloaded image in RAM"
+ depends on TPL_RAM_SUPPORT
+ help
+ Enable booting of an image already loaded in RAM. The image has to
+ be already in memory when TPL takes over, e.g. loaded by the boot
+ ROM.
+
+config TPL_RTC_SUPPORT
+ bool "Support RTC drivers"
+ help
+ Enable RTC (Real-time Clock) support in TPL. This includes support
+ for reading and setting the time. Some RTC devices also have some
+ non-volatile (battery-backed) memory which is accessible if
+ needed. This enables the drivers in drivers/rtc as part of an TPL
+ build.
+
+config TPL_SERIAL_SUPPORT
+ bool "Support serial"
+ select TPL_PRINTF
+ select TPL_STRTO
+ help
+ Enable support for serial in TPL. See SPL_SERIAL_SUPPORT for
+ details.
+
+config TPL_SPI_FLASH_SUPPORT
+ bool "Support SPI flash drivers"
+ help
+ Enable support for using SPI flash in TPL. See SPL_SPI_FLASH_SUPPORT
+ for details.
+
+config TPL_SPI_FLASH_TINY
+ bool "Enable low footprint TPL SPI Flash support"
+ depends on TPL_SPI_FLASH_SUPPORT && !SPI_FLASH_BAR
+ default y if SPI_FLASH
+ help
+ Enable lightweight TPL SPI Flash support that supports just reading
+ data/images from flash. No support to write/erase flash. Enable
+ this if you have TPL size limitations and don't need full-fledged
+ SPI flash support.
+
+config TPL_SPI_LOAD
+ bool "Support loading from SPI flash"
+ depends on TPL_SPI_FLASH_SUPPORT
+ help
+ Enable support for loading next stage, U-Boot or otherwise, from
+ SPI NOR in U-Boot TPL.
+
+config TPL_SPI_SUPPORT
+ bool "Support SPI drivers"
+ help
+ Enable support for using SPI in TPL. See SPL_SPI_SUPPORT for
+ details.
+
+config TPL_DM_SPI
+ bool "Support SPI DM drivers in TPL"
+ help
+ Enable support for SPI DM drivers in TPL.
+
+config TPL_DM_SPI_FLASH
+ bool "Support SPI DM FLASH drivers in TPL"
+ help
+ Enable support for SPI DM flash drivers in TPL.
+
+config TPL_YMODEM_SUPPORT
+ bool "Support loading using Ymodem"
+ depends on TPL_SERIAL_SUPPORT
+ help
+ While loading from serial is slow it can be a useful backup when
+ there is no other option. The Ymodem protocol provides a reliable
+ means of transmitting U-Boot over a serial line for using in TPL,
+ with a checksum to ensure correctness.
+
+endif # TPL
+
+config SPL_AT91_MCK_BYPASS
+ bool "Use external clock signal as a source of main clock for AT91 platforms"
+ depends on ARCH_AT91
+ default n
+ help
+ Use external 8 to 24 Mhz clock signal as source of main clock instead
+ of an external crystal oscillator.
+ This option disables the internal driving on the XOUT pin.
+ The external source has to provide a stable clock on the XIN pin.
+ If this option is disabled, the SoC expects a crystal oscillator
+ that needs driving on both XIN and XOUT lines.
+
+endif # SPL
+endmenu
diff --git a/roms/u-boot/common/spl/Makefile b/roms/u-boot/common/spl/Makefile
new file mode 100644
index 000000000..c576a7812
--- /dev/null
+++ b/roms/u-boot/common/spl/Makefile
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2012
+# Texas Instruments Incorporated - http://www.ti.com/
+# Aneesh V <aneesh@ti.com>
+# Based on common/Makefile.
+#
+
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
+obj-$(CONFIG_$(SPL_TPL_)BOOTROM_SUPPORT) += spl_bootrom.o
+obj-$(CONFIG_$(SPL_TPL_)LOAD_FIT) += spl_fit.o
+obj-$(CONFIG_$(SPL_TPL_)LEGACY_IMAGE_SUPPORT) += spl_legacy.o
+obj-$(CONFIG_$(SPL_TPL_)NOR_SUPPORT) += spl_nor.o
+obj-$(CONFIG_$(SPL_TPL_)XIP_SUPPORT) += spl_xip.o
+obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += spl_ymodem.o
+ifndef CONFIG_SPL_UBI
+obj-$(CONFIG_$(SPL_TPL_)NAND_SUPPORT) += spl_nand.o
+obj-$(CONFIG_$(SPL_TPL_)ONENAND_SUPPORT) += spl_onenand.o
+endif
+obj-$(CONFIG_$(SPL_TPL_)UBI) += spl_ubi.o
+obj-$(CONFIG_$(SPL_TPL_)NET_SUPPORT) += spl_net.o
+obj-$(CONFIG_$(SPL_TPL_)MMC_SUPPORT) += spl_mmc.o
+obj-$(CONFIG_$(SPL_TPL_)ATF) += spl_atf.o
+obj-$(CONFIG_$(SPL_TPL_)OPTEE) += spl_optee.o
+obj-$(CONFIG_$(SPL_TPL_)OPENSBI) += spl_opensbi.o
+obj-$(CONFIG_$(SPL_TPL_)USB_STORAGE) += spl_usb.o
+obj-$(CONFIG_$(SPL_TPL_)FS_FAT) += spl_fat.o
+obj-$(CONFIG_$(SPL_TPL_)FS_EXT4) += spl_ext.o
+obj-$(CONFIG_$(SPL_TPL_)SATA_SUPPORT) += spl_sata.o
+obj-$(CONFIG_$(SPL_TPL_)DFU) += spl_dfu.o
+obj-$(CONFIG_$(SPL_TPL_)SPI_LOAD) += spl_spi.o
+obj-$(CONFIG_$(SPL_TPL_)RAM_SUPPORT) += spl_ram.o
+obj-$(CONFIG_$(SPL_TPL_)USB_SDP_SUPPORT) += spl_sdp.o
+endif
diff --git a/roms/u-boot/common/spl/spl.c b/roms/u-boot/common/spl/spl.c
new file mode 100644
index 000000000..a0a608fd7
--- /dev/null
+++ b/roms/u-boot/common/spl/spl.c
@@ -0,0 +1,895 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.com>
+ */
+
+#include <common.h>
+#include <bloblist.h>
+#include <binman_sym.h>
+#include <bootstage.h>
+#include <dm.h>
+#include <handoff.h>
+#include <hang.h>
+#include <init.h>
+#include <irq_func.h>
+#include <log.h>
+#include <mapmem.h>
+#include <serial.h>
+#include <spl.h>
+#include <asm/global_data.h>
+#include <asm/u-boot.h>
+#include <nand.h>
+#include <fat.h>
+#include <u-boot/crc.h>
+#include <version.h>
+#include <image.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <dm/root.h>
+#include <linux/compiler.h>
+#include <fdt_support.h>
+#include <bootcount.h>
+#include <wdt.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_SYS_UBOOT_START
+#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
+#endif
+#ifndef CONFIG_SYS_MONITOR_LEN
+/* Unknown U-Boot size, let's assume it will not be more than 200 KB */
+#define CONFIG_SYS_MONITOR_LEN (200 * 1024)
+#endif
+
+u32 *boot_params_ptr = NULL;
+
+/* See spl.h for information about this */
+binman_sym_declare(ulong, u_boot_any, image_pos);
+binman_sym_declare(ulong, u_boot_any, size);
+
+#ifdef CONFIG_TPL
+binman_sym_declare(ulong, spl, image_pos);
+binman_sym_declare(ulong, spl, size);
+#endif
+
+/* Define board data structure */
+static struct bd_info bdata __attribute__ ((section(".data")));
+
+/*
+ * Board-specific Platform code can reimplement show_boot_progress () if needed
+ */
+__weak void show_boot_progress(int val) {}
+
+#if defined(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) || \
+ defined(CONFIG_SPL_ATF)
+/* weak, default platform-specific function to initialize dram banks */
+__weak int dram_init_banksize(void)
+{
+ return 0;
+}
+#endif
+
+/*
+ * Default function to determine if u-boot or the OS should
+ * be started. This implementation always returns 1.
+ *
+ * Please implement your own board specific funcion to do this.
+ *
+ * RETURN
+ * 0 to not start u-boot
+ * positive if u-boot should start
+ */
+#ifdef CONFIG_SPL_OS_BOOT
+__weak int spl_start_uboot(void)
+{
+ puts(SPL_TPL_PROMPT
+ "Please implement spl_start_uboot() for your board\n");
+ puts(SPL_TPL_PROMPT "Direct Linux boot not active!\n");
+ return 1;
+}
+
+/*
+ * Weak default function for arch specific zImage check. Return zero
+ * and fill start and end address if image is recognized.
+ */
+int __weak bootz_setup(ulong image, ulong *start, ulong *end)
+{
+ return 1;
+}
+#endif
+
+/* Weak default function for arch/board-specific fixups to the spl_image_info */
+void __weak spl_perform_fixups(struct spl_image_info *spl_image)
+{
+}
+
+void spl_fixup_fdt(void *fdt_blob)
+{
+#if defined(CONFIG_SPL_OF_LIBFDT)
+ int err;
+
+ if (!fdt_blob)
+ return;
+
+ err = fdt_check_header(fdt_blob);
+ if (err < 0) {
+ printf("fdt_root: %s\n", fdt_strerror(err));
+ return;
+ }
+
+ /* fixup the memory dt node */
+ err = fdt_shrink_to_minimum(fdt_blob, 0);
+ if (err == 0) {
+ printf(SPL_TPL_PROMPT "fdt_shrink_to_minimum err - %d\n", err);
+ return;
+ }
+
+ err = arch_fixup_fdt(fdt_blob);
+ if (err) {
+ printf(SPL_TPL_PROMPT "arch_fixup_fdt err - %d\n", err);
+ return;
+ }
+#endif
+}
+
+ulong spl_get_image_pos(void)
+{
+ return spl_phase() == PHASE_TPL ?
+ binman_sym(ulong, spl, image_pos) :
+ binman_sym(ulong, u_boot_any, image_pos);
+}
+
+ulong spl_get_image_size(void)
+{
+ return spl_phase() == PHASE_TPL ?
+ binman_sym(ulong, spl, size) :
+ binman_sym(ulong, u_boot_any, size);
+}
+
+ulong spl_get_image_text_base(void)
+{
+ return spl_phase() == PHASE_TPL ? CONFIG_SPL_TEXT_BASE :
+ CONFIG_SYS_TEXT_BASE;
+}
+
+/*
+ * Weak default function for board specific cleanup/preparation before
+ * Linux boot. Some boards/platforms might not need it, so just provide
+ * an empty stub here.
+ */
+__weak void spl_board_prepare_for_linux(void)
+{
+ /* Nothing to do! */
+}
+
+__weak void spl_board_prepare_for_boot(void)
+{
+ /* Nothing to do! */
+}
+
+__weak struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
+{
+ return map_sysmem(CONFIG_SYS_TEXT_BASE + offset, 0);
+}
+
+void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
+{
+ ulong u_boot_pos = binman_sym(ulong, u_boot_any, image_pos);
+
+ spl_image->size = CONFIG_SYS_MONITOR_LEN;
+
+ /*
+ * Binman error cases: address of the end of the previous region or the
+ * start of the image's entry area (usually 0) if there is no previous
+ * region.
+ */
+ if (u_boot_pos && u_boot_pos != BINMAN_SYM_MISSING) {
+ /* Binman does not support separated entry addresses */
+ spl_image->entry_point = u_boot_pos;
+ spl_image->load_addr = u_boot_pos;
+ } else {
+ spl_image->entry_point = CONFIG_SYS_UBOOT_START;
+ spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
+ }
+ spl_image->os = IH_OS_U_BOOT;
+ spl_image->name = "U-Boot";
+}
+
+#ifdef CONFIG_SPL_LOAD_FIT_FULL
+/* Parse and load full fitImage in SPL */
+static int spl_load_fit_image(struct spl_image_info *spl_image,
+ const struct image_header *header)
+{
+ bootm_headers_t images;
+ const char *fit_uname_config = NULL;
+ uintptr_t fdt_hack;
+ const char *uname;
+ ulong fw_data = 0, dt_data = 0, img_data = 0;
+ ulong fw_len = 0, dt_len = 0, img_len = 0;
+ int idx, conf_noffset;
+ int ret;
+
+#ifdef CONFIG_SPL_FIT_SIGNATURE
+ images.verify = 1;
+#endif
+ ret = fit_image_load(&images, (ulong)header,
+ NULL, &fit_uname_config,
+ IH_ARCH_DEFAULT, IH_TYPE_STANDALONE, -1,
+ FIT_LOAD_OPTIONAL, &fw_data, &fw_len);
+ if (ret >= 0) {
+ printf("DEPRECATED: 'standalone = ' property.");
+ printf("Please use either 'firmware =' or 'kernel ='\n");
+ } else {
+ ret = fit_image_load(&images, (ulong)header, NULL,
+ &fit_uname_config, IH_ARCH_DEFAULT,
+ IH_TYPE_FIRMWARE, -1, FIT_LOAD_OPTIONAL,
+ &fw_data, &fw_len);
+ }
+
+ if (ret < 0) {
+ ret = fit_image_load(&images, (ulong)header, NULL,
+ &fit_uname_config, IH_ARCH_DEFAULT,
+ IH_TYPE_KERNEL, -1, FIT_LOAD_OPTIONAL,
+ &fw_data, &fw_len);
+ }
+
+ if (ret < 0)
+ return ret;
+
+ spl_image->size = fw_len;
+ spl_image->entry_point = fw_data;
+ spl_image->load_addr = fw_data;
+ if (fit_image_get_os(header, ret, &spl_image->os))
+ spl_image->os = IH_OS_INVALID;
+ spl_image->name = genimg_get_os_name(spl_image->os);
+
+ debug(SPL_TPL_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n",
+ spl_image->name, spl_image->load_addr, spl_image->size);
+
+#ifdef CONFIG_SPL_FIT_SIGNATURE
+ images.verify = 1;
+#endif
+ ret = fit_image_load(&images, (ulong)header, NULL, &fit_uname_config,
+ IH_ARCH_DEFAULT, IH_TYPE_FLATDT, -1,
+ FIT_LOAD_OPTIONAL, &dt_data, &dt_len);
+ if (ret >= 0) {
+ spl_image->fdt_addr = (void *)dt_data;
+
+ if (spl_image->os == IH_OS_U_BOOT) {
+ /* HACK: U-boot expects FDT at a specific address */
+ fdt_hack = spl_image->load_addr + spl_image->size;
+ fdt_hack = (fdt_hack + 3) & ~3;
+ debug("Relocating FDT to %p\n", spl_image->fdt_addr);
+ memcpy((void *)fdt_hack, spl_image->fdt_addr, dt_len);
+ }
+ }
+
+ conf_noffset = fit_conf_get_node((const void *)header,
+ fit_uname_config);
+ if (conf_noffset <= 0)
+ return 0;
+
+ for (idx = 0;
+ uname = fdt_stringlist_get((const void *)header, conf_noffset,
+ FIT_LOADABLE_PROP, idx,
+ NULL), uname;
+ idx++)
+ {
+#ifdef CONFIG_SPL_FIT_SIGNATURE
+ images.verify = 1;
+#endif
+ ret = fit_image_load(&images, (ulong)header,
+ &uname, &fit_uname_config,
+ IH_ARCH_DEFAULT, IH_TYPE_LOADABLE, -1,
+ FIT_LOAD_OPTIONAL_NON_ZERO,
+ &img_data, &img_len);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
+__weak int spl_parse_legacy_header(struct spl_image_info *spl_image,
+ const struct image_header *header)
+{
+ /* LEGACY image not supported */
+ debug("Legacy boot image support not enabled, proceeding to other boot methods\n");
+ return -EINVAL;
+}
+
+int spl_parse_image_header(struct spl_image_info *spl_image,
+ const struct image_header *header)
+{
+#ifdef CONFIG_SPL_LOAD_FIT_FULL
+ int ret = spl_load_fit_image(spl_image, header);
+
+ if (!ret)
+ return ret;
+#endif
+ if (image_get_magic(header) == IH_MAGIC) {
+ int ret;
+
+ ret = spl_parse_legacy_header(spl_image, header);
+ if (ret)
+ return ret;
+ } else {
+#ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE
+ /*
+ * CONFIG_SPL_PANIC_ON_RAW_IMAGE is defined when the
+ * code which loads images in SPL cannot guarantee that
+ * absolutely all read errors will be reported.
+ * An example is the LPC32XX MLC NAND driver, which
+ * will consider that a completely unreadable NAND block
+ * is bad, and thus should be skipped silently.
+ */
+ panic("** no mkimage signature but raw image not supported");
+#endif
+
+#ifdef CONFIG_SPL_OS_BOOT
+ ulong start, end;
+
+ if (!bootz_setup((ulong)header, &start, &end)) {
+ spl_image->name = "Linux";
+ spl_image->os = IH_OS_LINUX;
+ spl_image->load_addr = CONFIG_SYS_LOAD_ADDR;
+ spl_image->entry_point = CONFIG_SYS_LOAD_ADDR;
+ spl_image->size = end - start;
+ debug(SPL_TPL_PROMPT
+ "payload zImage, load addr: 0x%lx size: %d\n",
+ spl_image->load_addr, spl_image->size);
+ return 0;
+ }
+#endif
+
+#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT
+ /* Signature not found - assume u-boot.bin */
+ debug("mkimage signature not found - ih_magic = %x\n",
+ header->ih_magic);
+ spl_set_header_raw_uboot(spl_image);
+#else
+ /* RAW image not supported, proceed to other boot methods. */
+ debug("Raw boot image support not enabled, proceeding to other boot methods\n");
+ return -EINVAL;
+#endif
+ }
+
+ return 0;
+}
+
+__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+{
+ typedef void __noreturn (*image_entry_noargs_t)(void);
+
+ image_entry_noargs_t image_entry =
+ (image_entry_noargs_t)spl_image->entry_point;
+
+ debug("image entry point: 0x%lx\n", spl_image->entry_point);
+ image_entry();
+}
+
+#if CONFIG_IS_ENABLED(HANDOFF)
+/**
+ * Set up the SPL hand-off information
+ *
+ * This is initially empty (zero) but can be written by
+ */
+static int setup_spl_handoff(void)
+{
+ struct spl_handoff *ho;
+
+ ho = bloblist_ensure(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
+ if (!ho)
+ return -ENOENT;
+
+ return 0;
+}
+
+__weak int handoff_arch_save(struct spl_handoff *ho)
+{
+ return 0;
+}
+
+static int write_spl_handoff(void)
+{
+ struct spl_handoff *ho;
+ int ret;
+
+ ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
+ if (!ho)
+ return -ENOENT;
+ handoff_save_dram(ho);
+ ret = handoff_arch_save(ho);
+ if (ret)
+ return ret;
+ debug(SPL_TPL_PROMPT "Wrote SPL handoff\n");
+
+ return 0;
+}
+#else
+static inline int setup_spl_handoff(void) { return 0; }
+static inline int write_spl_handoff(void) { return 0; }
+
+#endif /* HANDOFF */
+
+/**
+ * get_bootstage_id() - Get the bootstage ID to emit
+ *
+ * @start: true if this is for starting SPL, false for ending it
+ * @return bootstage ID to use
+ */
+static enum bootstage_id get_bootstage_id(bool start)
+{
+ enum u_boot_phase phase = spl_phase();
+
+ if (IS_ENABLED(CONFIG_TPL_BUILD) && phase == PHASE_TPL)
+ return start ? BOOTSTAGE_ID_START_TPL : BOOTSTAGE_ID_END_TPL;
+ else
+ return start ? BOOTSTAGE_ID_START_SPL : BOOTSTAGE_ID_END_SPL;
+}
+
+static int spl_common_init(bool setup_malloc)
+{
+ int ret;
+
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+ if (setup_malloc) {
+#ifdef CONFIG_MALLOC_F_ADDR
+ gd->malloc_base = CONFIG_MALLOC_F_ADDR;
+#endif
+ gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
+ gd->malloc_ptr = 0;
+ }
+#endif
+ ret = bootstage_init(u_boot_first_phase());
+ if (ret) {
+ debug("%s: Failed to set up bootstage: ret=%d\n", __func__,
+ ret);
+ return ret;
+ }
+#ifdef CONFIG_BOOTSTAGE_STASH
+ if (!u_boot_first_phase()) {
+ const void *stash = map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR,
+ CONFIG_BOOTSTAGE_STASH_SIZE);
+
+ ret = bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE);
+ if (ret)
+ debug("%s: Failed to unstash bootstage: ret=%d\n",
+ __func__, ret);
+ }
+#endif /* CONFIG_BOOTSTAGE_STASH */
+ bootstage_mark_name(get_bootstage_id(true),
+ spl_phase_name(spl_phase()));
+#if CONFIG_IS_ENABLED(LOG)
+ ret = log_init();
+ if (ret) {
+ debug("%s: Failed to set up logging\n", __func__);
+ return ret;
+ }
+#endif
+ if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
+ ret = fdtdec_setup();
+ if (ret) {
+ debug("fdtdec_setup() returned error %d\n", ret);
+ return ret;
+ }
+ }
+ if (CONFIG_IS_ENABLED(DM)) {
+ bootstage_start(BOOTSTAGE_ID_ACCUM_DM_SPL,
+ spl_phase() == PHASE_TPL ? "dm tpl" : "dm_spl");
+ /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */
+ ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA));
+ bootstage_accum(BOOTSTAGE_ID_ACCUM_DM_SPL);
+ if (ret) {
+ debug("dm_init_and_scan() returned error %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+void spl_set_bd(void)
+{
+ /*
+ * NOTE: On some platforms (e.g. x86) bdata may be in flash and not
+ * writeable.
+ */
+ if (!gd->bd)
+ gd->bd = &bdata;
+}
+
+int spl_early_init(void)
+{
+ int ret;
+
+ debug("%s\n", __func__);
+
+ ret = spl_common_init(true);
+ if (ret)
+ return ret;
+ gd->flags |= GD_FLG_SPL_EARLY_INIT;
+
+ return 0;
+}
+
+int spl_init(void)
+{
+ int ret;
+ bool setup_malloc = !(IS_ENABLED(CONFIG_SPL_STACK_R) &&
+ IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIMPLE));
+
+ debug("%s\n", __func__);
+
+ if (!(gd->flags & GD_FLG_SPL_EARLY_INIT)) {
+ ret = spl_common_init(setup_malloc);
+ if (ret)
+ return ret;
+ }
+ gd->flags |= GD_FLG_SPL_INIT;
+
+ return 0;
+}
+
+#ifndef BOOT_DEVICE_NONE
+#define BOOT_DEVICE_NONE 0xdeadbeef
+#endif
+
+__weak void board_boot_order(u32 *spl_boot_list)
+{
+ spl_boot_list[0] = spl_boot_device();
+}
+
+static struct spl_image_loader *spl_ll_find_loader(uint boot_device)
+{
+ struct spl_image_loader *drv =
+ ll_entry_start(struct spl_image_loader, spl_image_loader);
+ const int n_ents =
+ ll_entry_count(struct spl_image_loader, spl_image_loader);
+ struct spl_image_loader *entry;
+
+ for (entry = drv; entry != drv + n_ents; entry++) {
+ if (boot_device == entry->boot_device)
+ return entry;
+ }
+
+ /* Not found */
+ return NULL;
+}
+
+static int spl_load_image(struct spl_image_info *spl_image,
+ struct spl_image_loader *loader)
+{
+ int ret;
+ struct spl_boot_device bootdev;
+
+ bootdev.boot_device = loader->boot_device;
+ bootdev.boot_device_name = NULL;
+
+ ret = loader->load_image(spl_image, &bootdev);
+#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
+ if (!ret && spl_image->dcrc_length) {
+ /* check data crc */
+ ulong dcrc = crc32_wd(0, (unsigned char *)spl_image->dcrc_data,
+ spl_image->dcrc_length, CHUNKSZ_CRC32);
+ if (dcrc != spl_image->dcrc) {
+ puts("SPL: Image data CRC check failed!\n");
+ ret = -EINVAL;
+ }
+ }
+#endif
+ return ret;
+}
+
+/**
+ * boot_from_devices() - Try loading a booting U-Boot from a list of devices
+ *
+ * @spl_image: Place to put the image details if successful
+ * @spl_boot_list: List of boot devices to try
+ * @count: Number of elements in spl_boot_list
+ * @return 0 if OK, -ve on error
+ */
+static int boot_from_devices(struct spl_image_info *spl_image,
+ u32 spl_boot_list[], int count)
+{
+ int i;
+
+ for (i = 0; i < count && spl_boot_list[i] != BOOT_DEVICE_NONE; i++) {
+ struct spl_image_loader *loader;
+
+ loader = spl_ll_find_loader(spl_boot_list[i]);
+#if defined(CONFIG_SPL_SERIAL_SUPPORT) \
+ && defined(CONFIG_SPL_LIBCOMMON_SUPPORT) \
+ && !defined(CONFIG_SILENT_CONSOLE)
+ if (loader)
+ printf("Trying to boot from %s\n", loader->name);
+ else
+ puts(SPL_TPL_PROMPT "Unsupported Boot Device!\n");
+#endif
+ if (loader && !spl_load_image(spl_image, loader)) {
+ spl_image->boot_device = spl_boot_list[i];
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+#if defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F)
+void board_init_f(ulong dummy)
+{
+ if (CONFIG_IS_ENABLED(OF_CONTROL)) {
+ int ret;
+
+ ret = spl_early_init();
+ if (ret) {
+ debug("spl_early_init() failed: %d\n", ret);
+ hang();
+ }
+ }
+
+ preloader_console_init();
+}
+#endif
+
+void board_init_r(gd_t *dummy1, ulong dummy2)
+{
+ u32 spl_boot_list[] = {
+ BOOT_DEVICE_NONE,
+ BOOT_DEVICE_NONE,
+ BOOT_DEVICE_NONE,
+ BOOT_DEVICE_NONE,
+ BOOT_DEVICE_NONE,
+ };
+ struct spl_image_info spl_image;
+ int ret;
+
+ debug(">>" SPL_TPL_PROMPT "board_init_r()\n");
+
+ spl_set_bd();
+
+#if defined(CONFIG_SYS_SPL_MALLOC_START)
+ mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
+ CONFIG_SYS_SPL_MALLOC_SIZE);
+ gd->flags |= GD_FLG_FULL_MALLOC_INIT;
+#endif
+ if (!(gd->flags & GD_FLG_SPL_INIT)) {
+ if (spl_init())
+ hang();
+ }
+#if !defined(CONFIG_PPC) && !defined(CONFIG_ARCH_MX6)
+ /*
+ * timer_init() does not exist on PPC systems. The timer is initialized
+ * and enabled (decrementer) in interrupt_init() here.
+ */
+ timer_init();
+#endif
+ if (CONFIG_IS_ENABLED(BLOBLIST)) {
+ ret = bloblist_init();
+ if (ret) {
+ debug("%s: Failed to set up bloblist: ret=%d\n",
+ __func__, ret);
+ puts(SPL_TPL_PROMPT "Cannot set up bloblist\n");
+ hang();
+ }
+ }
+ if (CONFIG_IS_ENABLED(HANDOFF)) {
+ int ret;
+
+ ret = setup_spl_handoff();
+ if (ret) {
+ puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n");
+ hang();
+ }
+ }
+
+#if CONFIG_IS_ENABLED(BOARD_INIT)
+ spl_board_init();
+#endif
+
+#if defined(CONFIG_SPL_WATCHDOG_SUPPORT) && CONFIG_IS_ENABLED(WDT)
+ initr_watchdog();
+#endif
+
+ if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) ||
+ IS_ENABLED(CONFIG_SPL_ATF))
+ dram_init_banksize();
+
+ bootcount_inc();
+
+ memset(&spl_image, '\0', sizeof(spl_image));
+#ifdef CONFIG_SYS_SPL_ARGS_ADDR
+ spl_image.arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR;
+#endif
+ spl_image.boot_device = BOOT_DEVICE_NONE;
+ board_boot_order(spl_boot_list);
+
+ if (boot_from_devices(&spl_image, spl_boot_list,
+ ARRAY_SIZE(spl_boot_list))) {
+ puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n");
+ hang();
+ }
+
+ spl_perform_fixups(&spl_image);
+ if (CONFIG_IS_ENABLED(HANDOFF)) {
+ ret = write_spl_handoff();
+ if (ret)
+ printf(SPL_TPL_PROMPT
+ "SPL hand-off write failed (err=%d)\n", ret);
+ }
+ if (CONFIG_IS_ENABLED(BLOBLIST)) {
+ ret = bloblist_finish();
+ if (ret)
+ printf("Warning: Failed to finish bloblist (ret=%d)\n",
+ ret);
+ }
+
+#ifdef CONFIG_CPU_V7M
+ spl_image.entry_point |= 0x1;
+#endif
+ switch (spl_image.os) {
+ case IH_OS_U_BOOT:
+ debug("Jumping to %s...\n", spl_phase_name(spl_next_phase()));
+ break;
+#if CONFIG_IS_ENABLED(ATF)
+ case IH_OS_ARM_TRUSTED_FIRMWARE:
+ debug("Jumping to U-Boot via ARM Trusted Firmware\n");
+ spl_fixup_fdt(spl_image.fdt_addr);
+ spl_invoke_atf(&spl_image);
+ break;
+#endif
+#if CONFIG_IS_ENABLED(OPTEE)
+ case IH_OS_TEE:
+ debug("Jumping to U-Boot via OP-TEE\n");
+ spl_optee_entry(NULL, NULL, spl_image.fdt_addr,
+ (void *)spl_image.entry_point);
+ break;
+#endif
+#if CONFIG_IS_ENABLED(OPENSBI)
+ case IH_OS_OPENSBI:
+ debug("Jumping to U-Boot via RISC-V OpenSBI\n");
+ spl_invoke_opensbi(&spl_image);
+ break;
+#endif
+#ifdef CONFIG_SPL_OS_BOOT
+ case IH_OS_LINUX:
+ debug("Jumping to Linux\n");
+#if defined(CONFIG_SYS_SPL_ARGS_ADDR)
+ spl_fixup_fdt((void *)CONFIG_SYS_SPL_ARGS_ADDR);
+#endif
+ spl_board_prepare_for_linux();
+ jump_to_image_linux(&spl_image);
+#endif
+ default:
+ debug("Unsupported OS image.. Jumping nevertheless..\n");
+ }
+#if CONFIG_VAL(SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE)
+ debug("SPL malloc() used 0x%lx bytes (%ld KB)\n", gd->malloc_ptr,
+ gd->malloc_ptr / 1024);
+#endif
+ bootstage_mark_name(get_bootstage_id(false), "end phase");
+#ifdef CONFIG_BOOTSTAGE_STASH
+ ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
+ CONFIG_BOOTSTAGE_STASH_SIZE);
+ if (ret)
+ debug("Failed to stash bootstage: err=%d\n", ret);
+#endif
+
+ spl_board_prepare_for_boot();
+ jump_to_image_no_args(&spl_image);
+}
+
+/*
+ * This requires UART clocks to be enabled. In order for this to work the
+ * caller must ensure that the gd pointer is valid.
+ */
+void preloader_console_init(void)
+{
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+ gd->baudrate = CONFIG_BAUDRATE;
+
+ serial_init(); /* serial communications setup */
+
+ gd->have_console = 1;
+
+#if CONFIG_IS_ENABLED(BANNER_PRINT)
+ puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - "
+ U_BOOT_TIME " " U_BOOT_TZ ")\n");
+#endif
+#ifdef CONFIG_SPL_DISPLAY_PRINT
+ spl_display_print();
+#endif
+#endif
+}
+
+/**
+ * This function is called before the stack is changed from initial stack to
+ * relocated stack. It tries to dump the stack size used
+ */
+__weak void spl_relocate_stack_check(void)
+{
+#if CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)
+ ulong init_sp = gd->start_addr_sp;
+ ulong stack_bottom = init_sp - CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK);
+ u8 *ptr = (u8 *)stack_bottom;
+ ulong i;
+
+ for (i = 0; i < CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK); i++) {
+ if (*ptr != CONFIG_VAL(SYS_STACK_F_CHECK_BYTE))
+ break;
+ ptr++;
+ }
+ printf("SPL initial stack usage: %lu bytes\n",
+ CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK) - i);
+#endif
+}
+
+/**
+ * spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution
+ *
+ * Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM
+ * for the main board_init_r() execution. This is typically because we need
+ * more stack space for things like the MMC sub-system.
+ *
+ * This function calculates the stack position, copies the global_data into
+ * place, sets the new gd (except for ARM, for which setting GD within a C
+ * function may not always work) and returns the new stack position. The
+ * caller is responsible for setting up the sp register and, in the case
+ * of ARM, setting up gd.
+ *
+ * All of this is done using the same layout and alignments as done in
+ * board_init_f_init_reserve() / board_init_f_alloc_reserve().
+ *
+ * @return new stack location, or 0 to use the same stack
+ */
+ulong spl_relocate_stack_gd(void)
+{
+#ifdef CONFIG_SPL_STACK_R
+ gd_t *new_gd;
+ ulong ptr = CONFIG_SPL_STACK_R_ADDR;
+
+ if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE))
+ spl_relocate_stack_check();
+
+#if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_VAL(SYS_MALLOC_F_LEN)
+ if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) {
+ debug("SPL malloc() before relocation used 0x%lx bytes (%ld KB)\n",
+ gd->malloc_ptr, gd->malloc_ptr / 1024);
+ ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
+ gd->malloc_base = ptr;
+ gd->malloc_limit = CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
+ gd->malloc_ptr = 0;
+ }
+#endif
+ /* Get stack position: use 8-byte alignment for ABI compliance */
+ ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16);
+ new_gd = (gd_t *)ptr;
+ memcpy(new_gd, (void *)gd, sizeof(gd_t));
+#if CONFIG_IS_ENABLED(DM)
+ dm_fixup_for_gd_move(new_gd);
+#endif
+#if !defined(CONFIG_ARM) && !defined(CONFIG_RISCV)
+ gd = new_gd;
+#endif
+ return ptr;
+#else
+ return 0;
+#endif
+}
+
+#if defined(CONFIG_BOOTCOUNT_LIMIT) && \
+ ((!defined(CONFIG_TPL_BUILD) && !defined(CONFIG_SPL_BOOTCOUNT_LIMIT)) || \
+ (defined(CONFIG_TPL_BUILD) && !defined(CONFIG_TPL_BOOTCOUNT_LIMIT)))
+void bootcount_store(ulong a)
+{
+}
+
+ulong bootcount_load(void)
+{
+ return 0;
+}
+#endif
diff --git a/roms/u-boot/common/spl/spl_atf.c b/roms/u-boot/common/spl/spl_atf.c
new file mode 100644
index 000000000..e1b68dd56
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_atf.c
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Reference to the ARM TF Project,
+ * plat/arm/common/arm_bl2_setup.c
+ * Portions copyright (c) 2013-2016, ARM Limited and Contributors. All rights
+ * reserved.
+ * Copyright (C) 2016 Rockchip Electronic Co.,Ltd
+ * Written by Kever Yang <kever.yang@rock-chips.com>
+ * Copyright (C) 2017 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <common.h>
+#include <atf_common.h>
+#include <cpu_func.h>
+#include <errno.h>
+#include <image.h>
+#include <log.h>
+#include <spl.h>
+#include <asm/cache.h>
+
+/* Holds all the structures we need for bl31 parameter passing */
+struct bl2_to_bl31_params_mem {
+ struct bl31_params bl31_params;
+ struct atf_image_info bl31_image_info;
+ struct atf_image_info bl32_image_info;
+ struct atf_image_info bl33_image_info;
+ struct entry_point_info bl33_ep_info;
+ struct entry_point_info bl32_ep_info;
+ struct entry_point_info bl31_ep_info;
+};
+
+struct bl2_to_bl31_params_mem_v2 {
+ struct bl_params bl_params;
+ struct bl_params_node bl31_params_node;
+ struct bl_params_node bl32_params_node;
+ struct bl_params_node bl33_params_node;
+ struct atf_image_info bl31_image_info;
+ struct atf_image_info bl32_image_info;
+ struct atf_image_info bl33_image_info;
+ struct entry_point_info bl33_ep_info;
+ struct entry_point_info bl32_ep_info;
+ struct entry_point_info bl31_ep_info;
+};
+
+struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry,
+ uintptr_t bl33_entry,
+ uintptr_t fdt_addr)
+{
+ static struct bl2_to_bl31_params_mem bl31_params_mem;
+ struct bl31_params *bl2_to_bl31_params;
+ struct entry_point_info *bl32_ep_info;
+ struct entry_point_info *bl33_ep_info;
+
+ /*
+ * Initialise the memory for all the arguments that needs to
+ * be passed to BL31
+ */
+ memset(&bl31_params_mem, 0, sizeof(struct bl2_to_bl31_params_mem));
+
+ /* Assign memory for TF related information */
+ bl2_to_bl31_params = &bl31_params_mem.bl31_params;
+ SET_PARAM_HEAD(bl2_to_bl31_params, ATF_PARAM_BL31, ATF_VERSION_1, 0);
+
+ /* Fill BL31 related information */
+ bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
+ ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
+
+ /* Fill BL32 related information */
+ bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
+ bl32_ep_info = &bl31_params_mem.bl32_ep_info;
+ SET_PARAM_HEAD(bl32_ep_info, ATF_PARAM_EP, ATF_VERSION_1,
+ ATF_EP_SECURE);
+
+ /* secure payload is optional, so set pc to 0 if absent */
+ bl32_ep_info->args.arg3 = fdt_addr;
+ bl32_ep_info->pc = bl32_entry ? bl32_entry : 0;
+ bl32_ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+ DISABLE_ALL_EXECPTIONS);
+
+ bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info,
+ ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
+
+ /* Fill BL33 related information */
+ bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
+ bl33_ep_info = &bl31_params_mem.bl33_ep_info;
+ SET_PARAM_HEAD(bl33_ep_info, ATF_PARAM_EP, ATF_VERSION_1,
+ ATF_EP_NON_SECURE);
+
+ /* BL33 expects to receive the primary CPU MPID (through x0) */
+ bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
+ bl33_ep_info->pc = bl33_entry;
+ bl33_ep_info->spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+ DISABLE_ALL_EXECPTIONS);
+
+ bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
+ ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
+
+ return bl2_to_bl31_params;
+}
+
+__weak struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry,
+ uintptr_t bl33_entry,
+ uintptr_t fdt_addr)
+{
+ return bl2_plat_get_bl31_params_default(bl32_entry, bl33_entry,
+ fdt_addr);
+}
+
+struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry,
+ uintptr_t bl33_entry,
+ uintptr_t fdt_addr)
+{
+ static struct bl2_to_bl31_params_mem_v2 bl31_params_mem;
+ struct bl_params *bl_params;
+ struct bl_params_node *bl_params_node;
+
+ /*
+ * Initialise the memory for all the arguments that needs to
+ * be passed to BL31
+ */
+ memset(&bl31_params_mem, 0, sizeof(bl31_params_mem));
+
+ /* Assign memory for TF related information */
+ bl_params = &bl31_params_mem.bl_params;
+ SET_PARAM_HEAD(bl_params, ATF_PARAM_BL_PARAMS, ATF_VERSION_2, 0);
+ bl_params->head = &bl31_params_mem.bl31_params_node;
+
+ /* Fill BL31 related information */
+ bl_params_node = &bl31_params_mem.bl31_params_node;
+ bl_params_node->image_id = ATF_BL31_IMAGE_ID;
+ bl_params_node->image_info = &bl31_params_mem.bl31_image_info;
+ bl_params_node->ep_info = &bl31_params_mem.bl31_ep_info;
+ bl_params_node->next_params_info = &bl31_params_mem.bl32_params_node;
+ SET_PARAM_HEAD(bl_params_node->image_info, ATF_PARAM_IMAGE_BINARY,
+ ATF_VERSION_2, 0);
+
+ /* Fill BL32 related information */
+ bl_params_node = &bl31_params_mem.bl32_params_node;
+ bl_params_node->image_id = ATF_BL32_IMAGE_ID;
+ bl_params_node->image_info = &bl31_params_mem.bl32_image_info;
+ bl_params_node->ep_info = &bl31_params_mem.bl32_ep_info;
+ bl_params_node->next_params_info = &bl31_params_mem.bl33_params_node;
+ SET_PARAM_HEAD(bl_params_node->ep_info, ATF_PARAM_EP,
+ ATF_VERSION_2, ATF_EP_SECURE);
+
+ /* secure payload is optional, so set pc to 0 if absent */
+ bl_params_node->ep_info->args.arg3 = fdt_addr;
+ bl_params_node->ep_info->pc = bl32_entry ? bl32_entry : 0;
+ bl_params_node->ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+ DISABLE_ALL_EXECPTIONS);
+ SET_PARAM_HEAD(bl_params_node->image_info, ATF_PARAM_IMAGE_BINARY,
+ ATF_VERSION_2, 0);
+
+ /* Fill BL33 related information */
+ bl_params_node = &bl31_params_mem.bl33_params_node;
+ bl_params_node->image_id = ATF_BL33_IMAGE_ID;
+ bl_params_node->image_info = &bl31_params_mem.bl33_image_info;
+ bl_params_node->ep_info = &bl31_params_mem.bl33_ep_info;
+ bl_params_node->next_params_info = NULL;
+ SET_PARAM_HEAD(bl_params_node->ep_info, ATF_PARAM_EP,
+ ATF_VERSION_2, ATF_EP_NON_SECURE);
+
+ /* BL33 expects to receive the primary CPU MPID (through x0) */
+ bl_params_node->ep_info->args.arg0 = 0xffff & read_mpidr();
+ bl_params_node->ep_info->pc = bl33_entry;
+ bl_params_node->ep_info->spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+ DISABLE_ALL_EXECPTIONS);
+ SET_PARAM_HEAD(bl_params_node->image_info, ATF_PARAM_IMAGE_BINARY,
+ ATF_VERSION_2, 0);
+
+ return bl_params;
+}
+
+__weak struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry,
+ uintptr_t bl33_entry,
+ uintptr_t fdt_addr)
+{
+ return bl2_plat_get_bl31_params_v2_default(bl32_entry, bl33_entry,
+ fdt_addr);
+}
+
+static inline void raw_write_daif(unsigned int daif)
+{
+ __asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory");
+}
+
+typedef void (*atf_entry_t)(struct bl31_params *params, void *plat_params);
+
+static void bl31_entry(uintptr_t bl31_entry, uintptr_t bl32_entry,
+ uintptr_t bl33_entry, uintptr_t fdt_addr)
+{
+ atf_entry_t atf_entry = (atf_entry_t)bl31_entry;
+ void *bl31_params;
+
+ if (CONFIG_IS_ENABLED(ATF_LOAD_IMAGE_V2))
+ bl31_params = bl2_plat_get_bl31_params_v2(bl32_entry,
+ bl33_entry,
+ fdt_addr);
+ else
+ bl31_params = bl2_plat_get_bl31_params(bl32_entry, bl33_entry,
+ fdt_addr);
+
+ raw_write_daif(SPSR_EXCEPTION_MASK);
+ dcache_disable();
+
+ atf_entry(bl31_params, (void *)fdt_addr);
+}
+
+static int spl_fit_images_find(void *blob, int os)
+{
+ int parent, node, ndepth = 0;
+ const void *data;
+
+ if (!blob)
+ return -FDT_ERR_BADMAGIC;
+
+ parent = fdt_path_offset(blob, "/fit-images");
+ if (parent < 0)
+ return -FDT_ERR_NOTFOUND;
+
+ for (node = fdt_next_node(blob, parent, &ndepth);
+ (node >= 0) && (ndepth > 0);
+ node = fdt_next_node(blob, node, &ndepth)) {
+ if (ndepth != 1)
+ continue;
+
+ data = fdt_getprop(blob, node, FIT_OS_PROP, NULL);
+ if (!data)
+ continue;
+
+ if (genimg_get_os_id(data) == os)
+ return node;
+ };
+
+ return -FDT_ERR_NOTFOUND;
+}
+
+uintptr_t spl_fit_images_get_entry(void *blob, int node)
+{
+ ulong val;
+ int ret;
+
+ ret = fit_image_get_entry(blob, node, &val);
+ if (ret)
+ ret = fit_image_get_load(blob, node, &val);
+
+ debug("%s: entry point 0x%lx\n", __func__, val);
+ return val;
+}
+
+void spl_invoke_atf(struct spl_image_info *spl_image)
+{
+ uintptr_t bl32_entry = 0;
+ uintptr_t bl33_entry = CONFIG_SYS_TEXT_BASE;
+ void *blob = spl_image->fdt_addr;
+ uintptr_t platform_param = (uintptr_t)blob;
+ int node;
+
+ /*
+ * Find the OP-TEE binary (in /fit-images) load address or
+ * entry point (if different) and pass it as the BL3-2 entry
+ * point, this is optional.
+ */
+ node = spl_fit_images_find(blob, IH_OS_TEE);
+ if (node >= 0)
+ bl32_entry = spl_fit_images_get_entry(blob, node);
+
+ /*
+ * Find the U-Boot binary (in /fit-images) load addreess or
+ * entry point (if different) and pass it as the BL3-3 entry
+ * point.
+ * This will need to be extended to support Falcon mode.
+ */
+
+ node = spl_fit_images_find(blob, IH_OS_U_BOOT);
+ if (node >= 0)
+ bl33_entry = spl_fit_images_get_entry(blob, node);
+
+ /*
+ * If ATF_NO_PLATFORM_PARAM is set, we override the platform
+ * parameter and always pass 0. This is a workaround for
+ * older ATF versions that have insufficiently robust (or
+ * overzealous) argument validation.
+ */
+ if (CONFIG_IS_ENABLED(ATF_NO_PLATFORM_PARAM))
+ platform_param = 0;
+
+ /*
+ * We don't provide a BL3-2 entry yet, but this will be possible
+ * using similar logic.
+ */
+ bl31_entry(spl_image->entry_point, bl32_entry,
+ bl33_entry, platform_param);
+}
diff --git a/roms/u-boot/common/spl/spl_bootrom.c b/roms/u-boot/common/spl/spl_bootrom.c
new file mode 100644
index 000000000..0eefd39a5
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_bootrom.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Theobroma Systems Design und Consulting GmH
+ */
+
+#include <common.h>
+#include <spl.h>
+
+__weak int board_return_to_bootrom(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ return 0;
+}
+
+static int spl_return_to_bootrom(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ /*
+ * If the board implements a way to return to its ROM (with
+ * the expectation that the next stage of will be booted by
+ * the ROM), it will implement board_return_to_bootrom() and
+ * should not return from it.
+ */
+ return board_return_to_bootrom(spl_image, bootdev);
+}
+
+SPL_LOAD_IMAGE_METHOD("BOOTROM", 0, BOOT_DEVICE_BOOTROM, spl_return_to_bootrom);
diff --git a/roms/u-boot/common/spl/spl_dfu.c b/roms/u-boot/common/spl/spl_dfu.c
new file mode 100644
index 000000000..5728d43ad
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_dfu.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016
+ * Texas Instruments, <www.ti.com>
+ *
+ * Ravi B <ravibabu@ti.com>
+ */
+#include <common.h>
+#include <env.h>
+#include <spl.h>
+#include <linux/compiler.h>
+#include <errno.h>
+#include <watchdog.h>
+#include <console.h>
+#include <g_dnl.h>
+#include <usb.h>
+#include <dfu.h>
+
+static int run_dfu(int usb_index, char *interface, char *devstring)
+{
+ int ret;
+
+ ret = dfu_init_env_entities(interface, devstring);
+ if (ret) {
+ dfu_free_entities();
+ goto exit;
+ }
+
+ run_usb_dnl_gadget(usb_index, "usb_dnl_dfu");
+exit:
+ dfu_free_entities();
+ return ret;
+}
+
+int spl_dfu_cmd(int usbctrl, char *dfu_alt_info, char *interface, char *devstr)
+{
+ char *str_env;
+ int ret;
+
+ /* set default environment */
+ env_set_default(NULL, 0);
+ str_env = env_get(dfu_alt_info);
+ if (!str_env) {
+ pr_err("\"%s\" env variable not defined!\n", dfu_alt_info);
+ return -EINVAL;
+ }
+
+ ret = env_set("dfu_alt_info", str_env);
+ if (ret) {
+ pr_err("unable to set env variable \"dfu_alt_info\"!\n");
+ return -EINVAL;
+ }
+
+ /* invoke dfu command */
+ return run_dfu(usbctrl, interface, devstr);
+}
diff --git a/roms/u-boot/common/spl/spl_ext.c b/roms/u-boot/common/spl/spl_ext.c
new file mode 100644
index 000000000..d73f06276
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_ext.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <common.h>
+#include <env.h>
+#include <part.h>
+#include <spl.h>
+#include <asm/u-boot.h>
+#include <ext4fs.h>
+#include <errno.h>
+#include <image.h>
+
+int spl_load_image_ext(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition,
+ const char *filename)
+{
+ s32 err;
+ struct image_header *header;
+ loff_t filelen, actlen;
+ struct disk_partition part_info = {};
+
+ header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
+
+ if (part_get_info(block_dev, partition, &part_info)) {
+ printf("spl: no partition table found\n");
+ return -1;
+ }
+
+ ext4fs_set_blk_dev(block_dev, &part_info);
+
+ err = ext4fs_mount(0);
+ if (!err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("%s: ext4fs mount err - %d\n", __func__, err);
+#endif
+ return -1;
+ }
+
+ err = ext4fs_open(filename, &filelen);
+ if (err < 0) {
+ puts("spl: ext4fs_open failed\n");
+ goto end;
+ }
+ err = ext4fs_read((char *)header, 0, sizeof(struct image_header), &actlen);
+ if (err < 0) {
+ puts("spl: ext4fs_read failed\n");
+ goto end;
+ }
+
+ err = spl_parse_image_header(spl_image, header);
+ if (err < 0) {
+ puts("spl: ext: failed to parse image header\n");
+ goto end;
+ }
+
+ err = ext4fs_read((char *)spl_image->load_addr, 0, filelen, &actlen);
+
+end:
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ if (err < 0)
+ printf("%s: error reading image %s, err - %d\n",
+ __func__, filename, err);
+#endif
+
+ return err < 0;
+}
+
+#ifdef CONFIG_SPL_OS_BOOT
+int spl_load_image_ext_os(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition)
+{
+ int err;
+ __maybe_unused loff_t filelen, actlen;
+ struct disk_partition part_info = {};
+ __maybe_unused char *file;
+
+ if (part_get_info(block_dev, partition, &part_info)) {
+ printf("spl: no partition table found\n");
+ return -1;
+ }
+
+ ext4fs_set_blk_dev(block_dev, &part_info);
+
+ err = ext4fs_mount(0);
+ if (!err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("%s: ext4fs mount err - %d\n", __func__, err);
+#endif
+ return -1;
+ }
+#if defined(CONFIG_SPL_ENV_SUPPORT)
+ file = env_get("falcon_args_file");
+ if (file) {
+ err = ext4fs_open(file, &filelen);
+ if (err < 0) {
+ puts("spl: ext4fs_open failed\n");
+ goto defaults;
+ }
+ err = ext4fs_read((void *)CONFIG_SYS_SPL_ARGS_ADDR, 0, filelen, &actlen);
+ if (err < 0) {
+ printf("spl: error reading image %s, err - %d, falling back to default\n",
+ file, err);
+ goto defaults;
+ }
+ file = env_get("falcon_image_file");
+ if (file) {
+ err = spl_load_image_ext(spl_image, block_dev,
+ partition, file);
+ if (err != 0) {
+ puts("spl: falling back to default\n");
+ goto defaults;
+ }
+
+ return 0;
+ } else {
+ puts("spl: falcon_image_file not set in environment, falling back to default\n");
+ }
+ } else {
+ puts("spl: falcon_args_file not set in environment, falling back to default\n");
+ }
+
+defaults:
+#endif
+
+ err = ext4fs_open(CONFIG_SPL_FS_LOAD_ARGS_NAME, &filelen);
+ if (err < 0)
+ puts("spl: ext4fs_open failed\n");
+
+ err = ext4fs_read((void *)CONFIG_SYS_SPL_ARGS_ADDR, 0, filelen, &actlen);
+ if (err < 0) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("%s: error reading image %s, err - %d\n",
+ __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err);
+#endif
+ return -1;
+ }
+
+ return spl_load_image_ext(spl_image, block_dev, partition,
+ CONFIG_SPL_FS_LOAD_KERNEL_NAME);
+}
+#else
+int spl_load_image_ext_os(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition)
+{
+ return -ENOSYS;
+}
+#endif
diff --git a/roms/u-boot/common/spl/spl_fat.c b/roms/u-boot/common/spl/spl_fat.c
new file mode 100644
index 000000000..c2eb09736
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_fat.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2014
+ * Texas Instruments, <www.ti.com>
+ *
+ * Dan Murphy <dmurphy@ti.com>
+ *
+ * FAT Image Functions copied from spl_mmc.c
+ */
+
+#include <common.h>
+#include <env.h>
+#include <log.h>
+#include <spl.h>
+#include <asm/u-boot.h>
+#include <fat.h>
+#include <errno.h>
+#include <image.h>
+#include <linux/libfdt.h>
+
+static int fat_registered;
+
+static int spl_register_fat_device(struct blk_desc *block_dev, int partition)
+{
+ int err = 0;
+
+ if (fat_registered)
+ return err;
+
+ err = fat_register_device(block_dev, partition);
+ if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("%s: fat register err - %d\n", __func__, err);
+#endif
+ return err;
+ }
+
+ fat_registered = 1;
+
+ return err;
+}
+
+static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset,
+ ulong size, void *buf)
+{
+ loff_t actread;
+ int ret;
+ char *filename = (char *)load->filename;
+
+ ret = fat_read_file(filename, buf, file_offset, size, &actread);
+ if (ret)
+ return ret;
+
+ return actread;
+}
+
+int spl_load_image_fat(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition,
+ const char *filename)
+{
+ int err;
+ struct image_header *header;
+
+ err = spl_register_fat_device(block_dev, partition);
+ if (err)
+ goto end;
+
+ header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
+
+ err = file_fat_read(filename, header, sizeof(struct image_header));
+ if (err <= 0)
+ goto end;
+
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) &&
+ image_get_magic(header) == FDT_MAGIC) {
+ err = file_fat_read(filename, (void *)CONFIG_SYS_LOAD_ADDR, 0);
+ if (err <= 0)
+ goto end;
+ err = spl_parse_image_header(spl_image,
+ (struct image_header *)CONFIG_SYS_LOAD_ADDR);
+ if (err == -EAGAIN)
+ return err;
+ if (err == 0)
+ err = 1;
+ } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+ image_get_magic(header) == FDT_MAGIC) {
+ struct spl_load_info load;
+
+ debug("Found FIT\n");
+ load.read = spl_fit_read;
+ load.bl_len = 1;
+ load.filename = (void *)filename;
+ load.priv = NULL;
+
+ return spl_load_simple_fit(spl_image, &load, 0, header);
+ } else {
+ err = spl_parse_image_header(spl_image, header);
+ if (err)
+ goto end;
+
+ err = file_fat_read(filename,
+ (u8 *)(uintptr_t)spl_image->load_addr, 0);
+ }
+
+end:
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ if (err <= 0)
+ printf("%s: error reading image %s, err - %d\n",
+ __func__, filename, err);
+#endif
+
+ return (err <= 0);
+}
+
+#ifdef CONFIG_SPL_OS_BOOT
+int spl_load_image_fat_os(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition)
+{
+ int err;
+ __maybe_unused char *file;
+
+ err = spl_register_fat_device(block_dev, partition);
+ if (err)
+ return err;
+
+#if defined(CONFIG_SPL_ENV_SUPPORT) && defined(CONFIG_SPL_OS_BOOT)
+ file = env_get("falcon_args_file");
+ if (file) {
+ err = file_fat_read(file, (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);
+ if (err <= 0) {
+ printf("spl: error reading image %s, err - %d, falling back to default\n",
+ file, err);
+ goto defaults;
+ }
+ file = env_get("falcon_image_file");
+ if (file) {
+ err = spl_load_image_fat(spl_image, block_dev,
+ partition, file);
+ if (err != 0) {
+ puts("spl: falling back to default\n");
+ goto defaults;
+ }
+
+ return 0;
+ } else
+ puts("spl: falcon_image_file not set in environment, falling back to default\n");
+ } else
+ puts("spl: falcon_args_file not set in environment, falling back to default\n");
+
+defaults:
+#endif
+
+ err = file_fat_read(CONFIG_SPL_FS_LOAD_ARGS_NAME,
+ (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);
+ if (err <= 0) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("%s: error reading image %s, err - %d\n",
+ __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err);
+#endif
+ return -1;
+ }
+
+ return spl_load_image_fat(spl_image, block_dev, partition,
+ CONFIG_SPL_FS_LOAD_KERNEL_NAME);
+}
+#else
+int spl_load_image_fat_os(struct spl_image_info *spl_image,
+ struct blk_desc *block_dev, int partition)
+{
+ return -ENOSYS;
+}
+#endif
diff --git a/roms/u-boot/common/spl/spl_fit.c b/roms/u-boot/common/spl/spl_fit.c
new file mode 100644
index 000000000..caddf5119
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_fit.c
@@ -0,0 +1,810 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <fpga.h>
+#include <gzip.h>
+#include <image.h>
+#include <log.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <spl.h>
+#include <sysinfo.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <linux/libfdt.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ
+#define CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ (64 * 1024)
+#endif
+
+#ifndef CONFIG_SYS_BOOTM_LEN
+#define CONFIG_SYS_BOOTM_LEN (64 << 20)
+#endif
+
+struct spl_fit_info {
+ const void *fit; /* Pointer to a valid FIT blob */
+ size_t ext_data_offset; /* Offset to FIT external data (end of FIT) */
+ int images_node; /* FDT offset to "/images" node */
+ int conf_node; /* FDT offset to selected configuration node */
+};
+
+__weak void board_spl_fit_post_load(const void *fit)
+{
+}
+
+__weak ulong board_spl_fit_size_align(ulong size)
+{
+ return size;
+}
+
+static int find_node_from_desc(const void *fit, int node, const char *str)
+{
+ int child;
+
+ if (node < 0)
+ return -EINVAL;
+
+ /* iterate the FIT nodes and find a matching description */
+ for (child = fdt_first_subnode(fit, node); child >= 0;
+ child = fdt_next_subnode(fit, child)) {
+ int len;
+ const char *desc = fdt_getprop(fit, child, "description", &len);
+
+ if (!desc)
+ continue;
+
+ if (!strcmp(desc, str))
+ return child;
+ }
+
+ return -ENOENT;
+}
+
+/**
+ * spl_fit_get_image_name(): By using the matching configuration subnode,
+ * retrieve the name of an image, specified by a property name and an index
+ * into that.
+ * @fit: Pointer to the FDT blob.
+ * @images: Offset of the /images subnode.
+ * @type: Name of the property within the configuration subnode.
+ * @index: Index into the list of strings in this property.
+ * @outname: Name of the image
+ *
+ * Return: 0 on success, or a negative error number
+ */
+static int spl_fit_get_image_name(const struct spl_fit_info *ctx,
+ const char *type, int index,
+ const char **outname)
+{
+ struct udevice *sysinfo;
+ const char *name, *str;
+ __maybe_unused int node;
+ int len, i;
+ bool found = true;
+
+ name = fdt_getprop(ctx->fit, ctx->conf_node, type, &len);
+ if (!name) {
+ debug("cannot find property '%s': %d\n", type, len);
+ return -EINVAL;
+ }
+
+ str = name;
+ for (i = 0; i < index; i++) {
+ str = strchr(str, '\0') + 1;
+ if (!str || (str - name >= len)) {
+ found = false;
+ break;
+ }
+ }
+
+ if (!found && CONFIG_IS_ENABLED(SYSINFO) && !sysinfo_get(&sysinfo)) {
+ int rc;
+ /*
+ * no string in the property for this index. Check if the
+ * sysinfo-level code can supply one.
+ */
+ rc = sysinfo_detect(sysinfo);
+ if (rc)
+ return rc;
+
+ rc = sysinfo_get_fit_loadable(sysinfo, index - i - 1, type,
+ &str);
+ if (rc && rc != -ENOENT)
+ return rc;
+
+ if (!rc) {
+ /*
+ * The sysinfo provided a name for a loadable.
+ * Try to match it against the description properties
+ * first. If no matching node is found, use it as a
+ * node name.
+ */
+ int node;
+ int images = fdt_path_offset(ctx->fit, FIT_IMAGES_PATH);
+
+ node = find_node_from_desc(ctx->fit, images, str);
+ if (node > 0)
+ str = fdt_get_name(ctx->fit, node, NULL);
+
+ found = true;
+ }
+ }
+
+ if (!found) {
+ debug("no string for index %d\n", index);
+ return -E2BIG;
+ }
+
+ *outname = str;
+ return 0;
+}
+
+/**
+ * spl_fit_get_image_node(): By using the matching configuration subnode,
+ * retrieve the name of an image, specified by a property name and an index
+ * into that.
+ * @fit: Pointer to the FDT blob.
+ * @images: Offset of the /images subnode.
+ * @type: Name of the property within the configuration subnode.
+ * @index: Index into the list of strings in this property.
+ *
+ * Return: the node offset of the respective image node or a negative
+ * error number.
+ */
+static int spl_fit_get_image_node(const struct spl_fit_info *ctx,
+ const char *type, int index)
+{
+ const char *str;
+ int err;
+ int node;
+
+ err = spl_fit_get_image_name(ctx, type, index, &str);
+ if (err)
+ return err;
+
+ debug("%s: '%s'\n", type, str);
+
+ node = fdt_subnode_offset(ctx->fit, ctx->images_node, str);
+ if (node < 0) {
+ pr_err("cannot find image node '%s': %d\n", str, node);
+ return -EINVAL;
+ }
+
+ return node;
+}
+
+static int get_aligned_image_offset(struct spl_load_info *info, int offset)
+{
+ /*
+ * If it is a FS read, get the first address before offset which is
+ * aligned to ARCH_DMA_MINALIGN. If it is raw read return the
+ * block number to which offset belongs.
+ */
+ if (info->filename)
+ return offset & ~(ARCH_DMA_MINALIGN - 1);
+
+ return offset / info->bl_len;
+}
+
+static int get_aligned_image_overhead(struct spl_load_info *info, int offset)
+{
+ /*
+ * If it is a FS read, get the difference between the offset and
+ * the first address before offset which is aligned to
+ * ARCH_DMA_MINALIGN. If it is raw read return the offset within the
+ * block.
+ */
+ if (info->filename)
+ return offset & (ARCH_DMA_MINALIGN - 1);
+
+ return offset % info->bl_len;
+}
+
+static int get_aligned_image_size(struct spl_load_info *info, int data_size,
+ int offset)
+{
+ data_size = data_size + get_aligned_image_overhead(info, offset);
+
+ if (info->filename)
+ return data_size;
+
+ return (data_size + info->bl_len - 1) / info->bl_len;
+}
+
+/**
+ * spl_load_fit_image(): load the image described in a certain FIT node
+ * @info: points to information about the device to load data from
+ * @sector: the start sector of the FIT image on the device
+ * @ctx: points to the FIT context structure
+ * @node: offset of the DT node describing the image to load (relative
+ * to @fit)
+ * @image_info: will be filled with information about the loaded image
+ * If the FIT node does not contain a "load" (address) property,
+ * the image gets loaded to the address pointed to by the
+ * load_addr member in this struct, if load_addr is not 0
+ *
+ * Return: 0 on success or a negative error number.
+ */
+static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
+ const struct spl_fit_info *ctx, int node,
+ struct spl_image_info *image_info)
+{
+ int offset;
+ size_t length;
+ int len;
+ ulong size;
+ ulong load_addr;
+ void *load_ptr;
+ void *src;
+ ulong overhead;
+ int nr_sectors;
+ uint8_t image_comp = -1, type = -1;
+ const void *data;
+ const void *fit = ctx->fit;
+ bool external_data = false;
+
+ if (IS_ENABLED(CONFIG_SPL_FPGA) ||
+ (IS_ENABLED(CONFIG_SPL_OS_BOOT) && IS_ENABLED(CONFIG_SPL_GZIP))) {
+ if (fit_image_get_type(fit, node, &type))
+ puts("Cannot get image type.\n");
+ else
+ debug("%s ", genimg_get_type_name(type));
+ }
+
+ if (IS_ENABLED(CONFIG_SPL_GZIP)) {
+ fit_image_get_comp(fit, node, &image_comp);
+ debug("%s ", genimg_get_comp_name(image_comp));
+ }
+
+ if (fit_image_get_load(fit, node, &load_addr)) {
+ if (!image_info->load_addr) {
+ printf("Can't load %s: No load address and no buffer\n",
+ fit_get_name(fit, node, NULL));
+ return -ENOBUFS;
+ }
+ load_addr = image_info->load_addr;
+ }
+
+ if (!fit_image_get_data_position(fit, node, &offset)) {
+ external_data = true;
+ } else if (!fit_image_get_data_offset(fit, node, &offset)) {
+ offset += ctx->ext_data_offset;
+ external_data = true;
+ }
+
+ if (external_data) {
+ void *src_ptr;
+
+ /* External data */
+ if (fit_image_get_data_size(fit, node, &len))
+ return -ENOENT;
+
+ src_ptr = map_sysmem(ALIGN(load_addr, ARCH_DMA_MINALIGN), len);
+ length = len;
+
+ overhead = get_aligned_image_overhead(info, offset);
+ nr_sectors = get_aligned_image_size(info, length, offset);
+
+ if (info->read(info,
+ sector + get_aligned_image_offset(info, offset),
+ nr_sectors, src_ptr) != nr_sectors)
+ return -EIO;
+
+ debug("External data: dst=%p, offset=%x, size=%lx\n",
+ src_ptr, offset, (unsigned long)length);
+ src = src_ptr + overhead;
+ } else {
+ /* Embedded data */
+ if (fit_image_get_data(fit, node, &data, &length)) {
+ puts("Cannot get image data/size\n");
+ return -ENOENT;
+ }
+ debug("Embedded data: dst=%lx, size=%lx\n", load_addr,
+ (unsigned long)length);
+ src = (void *)data; /* cast away const */
+ }
+
+ if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
+ printf("## Checking hash(es) for Image %s ... ",
+ fit_get_name(fit, node, NULL));
+ if (!fit_image_verify_with_data(fit, node, src, length))
+ return -EPERM;
+ puts("OK\n");
+ }
+
+ if (CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS))
+ board_fit_image_post_process(&src, &length);
+
+ load_ptr = map_sysmem(load_addr, length);
+ if (IS_ENABLED(CONFIG_SPL_GZIP) && image_comp == IH_COMP_GZIP) {
+ size = length;
+ if (gunzip(load_ptr, CONFIG_SYS_BOOTM_LEN, src, &size)) {
+ puts("Uncompressing error\n");
+ return -EIO;
+ }
+ length = size;
+ } else {
+ memcpy(load_ptr, src, length);
+ }
+
+ if (image_info) {
+ ulong entry_point;
+
+ image_info->load_addr = load_addr;
+ image_info->size = length;
+
+ if (!fit_image_get_entry(fit, node, &entry_point))
+ image_info->entry_point = entry_point;
+ else
+ image_info->entry_point = FDT_ERROR;
+ }
+
+ return 0;
+}
+
+static bool os_takes_devicetree(uint8_t os)
+{
+ switch (os) {
+ case IH_OS_U_BOOT:
+ return true;
+ case IH_OS_LINUX:
+ return IS_ENABLED(CONFIG_SPL_OS_BOOT);
+ default:
+ return false;
+ }
+}
+
+static int spl_fit_append_fdt(struct spl_image_info *spl_image,
+ struct spl_load_info *info, ulong sector,
+ const struct spl_fit_info *ctx)
+{
+ struct spl_image_info image_info;
+ int node, ret = 0, index = 0;
+
+ /*
+ * Use the address following the image as target address for the
+ * device tree.
+ */
+ image_info.load_addr = spl_image->load_addr + spl_image->size;
+
+ /* Figure out which device tree the board wants to use */
+ node = spl_fit_get_image_node(ctx, FIT_FDT_PROP, index++);
+ if (node < 0) {
+ debug("%s: cannot find FDT node\n", __func__);
+
+ /*
+ * U-Boot did not find a device tree inside the FIT image. Use
+ * the U-Boot device tree instead.
+ */
+ if (gd->fdt_blob)
+ memcpy((void *)image_info.load_addr, gd->fdt_blob,
+ fdt_totalsize(gd->fdt_blob));
+ else
+ return node;
+ } else {
+ ret = spl_load_fit_image(info, sector, ctx, node,
+ &image_info);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* Make the load-address of the FDT available for the SPL framework */
+ spl_image->fdt_addr = map_sysmem(image_info.load_addr, 0);
+ if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY))
+ return 0;
+
+ if (CONFIG_IS_ENABLED(LOAD_FIT_APPLY_OVERLAY)) {
+ void *tmpbuffer = NULL;
+
+ for (; ; index++) {
+ node = spl_fit_get_image_node(ctx, FIT_FDT_PROP, index);
+ if (node == -E2BIG) {
+ debug("%s: No additional FDT node\n", __func__);
+ break;
+ } else if (node < 0) {
+ debug("%s: unable to find FDT node %d\n",
+ __func__, index);
+ continue;
+ }
+
+ if (!tmpbuffer) {
+ /*
+ * allocate memory to store the DT overlay
+ * before it is applied. It may not be used
+ * depending on how the overlay is stored, so
+ * don't fail yet if the allocation failed.
+ */
+ tmpbuffer = malloc(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ);
+ if (!tmpbuffer)
+ debug("%s: unable to allocate space for overlays\n",
+ __func__);
+ }
+ image_info.load_addr = (ulong)tmpbuffer;
+ ret = spl_load_fit_image(info, sector, ctx,
+ node, &image_info);
+ if (ret < 0)
+ break;
+
+ /* Make room in FDT for changes from the overlay */
+ ret = fdt_increase_size(spl_image->fdt_addr,
+ image_info.size);
+ if (ret < 0)
+ break;
+
+ ret = fdt_overlay_apply_verbose(spl_image->fdt_addr,
+ (void *)image_info.load_addr);
+ if (ret) {
+ pr_err("failed to apply DT overlay %s\n",
+ fit_get_name(ctx->fit, node, NULL));
+ break;
+ }
+
+ debug("%s: DT overlay %s applied\n", __func__,
+ fit_get_name(ctx->fit, node, NULL));
+ }
+ free(tmpbuffer);
+ if (ret)
+ return ret;
+ }
+ /* Try to make space, so we can inject details on the loadables */
+ ret = fdt_shrink_to_minimum(spl_image->fdt_addr, 8192);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
+static int spl_fit_record_loadable(const struct spl_fit_info *ctx, int index,
+ void *blob, struct spl_image_info *image)
+{
+ int ret = 0;
+ const char *name;
+ int node;
+
+ if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY))
+ return 0;
+
+ ret = spl_fit_get_image_name(ctx, "loadables", index, &name);
+ if (ret < 0)
+ return ret;
+
+ node = spl_fit_get_image_node(ctx, "loadables", index);
+
+ ret = fdt_record_loadable(blob, index, name, image->load_addr,
+ image->size, image->entry_point,
+ fdt_getprop(ctx->fit, node, "type", NULL),
+ fdt_getprop(ctx->fit, node, "os", NULL));
+ return ret;
+}
+
+static int spl_fit_image_is_fpga(const void *fit, int node)
+{
+ const char *type;
+
+ if (!IS_ENABLED(CONFIG_SPL_FPGA))
+ return 0;
+
+ type = fdt_getprop(fit, node, FIT_TYPE_PROP, NULL);
+ if (!type)
+ return 0;
+
+ return !strcmp(type, "fpga");
+}
+
+static int spl_fit_image_get_os(const void *fit, int noffset, uint8_t *os)
+{
+ if (!CONFIG_IS_ENABLED(FIT_IMAGE_TINY) || CONFIG_IS_ENABLED(OS_BOOT))
+ return fit_image_get_os(fit, noffset, os);
+
+ const char *name = fdt_getprop(fit, noffset, FIT_OS_PROP, NULL);
+ if (!name)
+ return -ENOENT;
+
+ /*
+ * We don't care what the type of the image actually is,
+ * only whether or not it is U-Boot. This saves some
+ * space by omitting the large table of OS types.
+ */
+ if (!strcmp(name, "u-boot"))
+ *os = IH_OS_U_BOOT;
+ else
+ *os = IH_OS_INVALID;
+
+ return 0;
+}
+
+/*
+ * The purpose of the FIT load buffer is to provide a memory location that is
+ * independent of the load address of any FIT component.
+ */
+static void *spl_get_fit_load_buffer(size_t size)
+{
+ void *buf;
+
+ buf = malloc(size);
+ if (!buf) {
+ pr_err("Could not get FIT buffer of %lu bytes\n", (ulong)size);
+ pr_err("\tcheck CONFIG_SYS_SPL_MALLOC_SIZE\n");
+ buf = spl_get_load_buffer(0, size);
+ }
+ return buf;
+}
+
+/*
+ * Weak default function to allow customizing SPL fit loading for load-only
+ * use cases by allowing to skip the parsing/processing of the FIT contents
+ * (so that this can be done separately in a more customized fashion)
+ */
+__weak bool spl_load_simple_fit_skip_processing(void)
+{
+ return false;
+}
+
+static void warn_deprecated(const char *msg)
+{
+ printf("DEPRECATED: %s\n", msg);
+ printf("\tSee doc/uImage.FIT/source_file_format.txt\n");
+}
+
+static int spl_fit_upload_fpga(struct spl_fit_info *ctx, int node,
+ struct spl_image_info *fpga_image)
+{
+ const char *compatible;
+ int ret;
+
+ debug("FPGA bitstream at: %x, size: %x\n",
+ (u32)fpga_image->load_addr, fpga_image->size);
+
+ compatible = fdt_getprop(ctx->fit, node, "compatible", NULL);
+ if (!compatible)
+ warn_deprecated("'fpga' image without 'compatible' property");
+ else if (strcmp(compatible, "u-boot,fpga-legacy"))
+ printf("Ignoring compatible = %s property\n", compatible);
+
+ ret = fpga_load(0, (void *)fpga_image->load_addr, fpga_image->size,
+ BIT_FULL);
+ if (ret) {
+ printf("%s: Cannot load the image to the FPGA\n", __func__);
+ return ret;
+ }
+
+ puts("FPGA image loaded from FIT\n");
+
+ return 0;
+}
+
+static int spl_fit_load_fpga(struct spl_fit_info *ctx,
+ struct spl_load_info *info, ulong sector)
+{
+ int node, ret;
+
+ struct spl_image_info fpga_image = {
+ .load_addr = 0,
+ };
+
+ node = spl_fit_get_image_node(ctx, "fpga", 0);
+ if (node < 0)
+ return node;
+
+ warn_deprecated("'fpga' property in config node. Use 'loadables'");
+
+ /* Load the image and set up the fpga_image structure */
+ ret = spl_load_fit_image(info, sector, ctx, node, &fpga_image);
+ if (ret) {
+ printf("%s: Cannot load the FPGA: %i\n", __func__, ret);
+ return ret;
+ }
+
+ return spl_fit_upload_fpga(ctx, node, &fpga_image);
+}
+
+static int spl_simple_fit_read(struct spl_fit_info *ctx,
+ struct spl_load_info *info, ulong sector,
+ const void *fit_header)
+{
+ unsigned long count, size;
+ int sectors;
+ void *buf;
+
+ /*
+ * For FIT with external data, figure out where the external images
+ * start. This is the base for the data-offset properties in each
+ * image.
+ */
+ size = ALIGN(fdt_totalsize(fit_header), 4);
+ size = board_spl_fit_size_align(size);
+ ctx->ext_data_offset = ALIGN(size, 4);
+
+ /*
+ * So far we only have one block of data from the FIT. Read the entire
+ * thing, including that first block.
+ *
+ * For FIT with data embedded, data is loaded as part of FIT image.
+ * For FIT with external data, data is not loaded in this step.
+ */
+ sectors = get_aligned_image_size(info, size, 0);
+ buf = spl_get_fit_load_buffer(sectors * info->bl_len);
+
+ count = info->read(info, sector, sectors, buf);
+ ctx->fit = buf;
+ debug("fit read sector %lx, sectors=%d, dst=%p, count=%lu, size=0x%lx\n",
+ sector, sectors, buf, count, size);
+
+ return (count == 0) ? -EIO : 0;
+}
+
+static int spl_simple_fit_parse(struct spl_fit_info *ctx)
+{
+ /* Find the correct subnode under "/configurations" */
+ ctx->conf_node = fit_find_config_node(ctx->fit);
+ if (ctx->conf_node < 0)
+ return -EINVAL;
+
+ if (IS_ENABLED(CONFIG_SPL_FIT_SIGNATURE)) {
+ printf("## Checking hash(es) for config %s ... ",
+ fit_get_name(ctx->fit, ctx->conf_node, NULL));
+ if (fit_config_verify(ctx->fit, ctx->conf_node))
+ return -EPERM;
+ puts("OK\n");
+ }
+
+ /* find the node holding the images information */
+ ctx->images_node = fdt_path_offset(ctx->fit, FIT_IMAGES_PATH);
+ if (ctx->images_node < 0) {
+ debug("%s: Cannot find /images node: %d\n", __func__,
+ ctx->images_node);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int spl_load_simple_fit(struct spl_image_info *spl_image,
+ struct spl_load_info *info, ulong sector, void *fit)
+{
+ struct spl_image_info image_info;
+ struct spl_fit_info ctx;
+ int node = -1;
+ int ret;
+ int index = 0;
+ int firmware_node;
+
+ ret = spl_simple_fit_read(&ctx, info, sector, fit);
+ if (ret < 0)
+ return ret;
+
+ /* skip further processing if requested to enable load-only use cases */
+ if (spl_load_simple_fit_skip_processing())
+ return 0;
+
+ ret = spl_simple_fit_parse(&ctx);
+ if (ret < 0)
+ return ret;
+
+ if (IS_ENABLED(CONFIG_SPL_FPGA))
+ spl_fit_load_fpga(&ctx, info, sector);
+
+ /*
+ * Find the U-Boot image using the following search order:
+ * - start at 'firmware' (e.g. an ARM Trusted Firmware)
+ * - fall back 'kernel' (e.g. a Falcon-mode OS boot
+ * - fall back to using the first 'loadables' entry
+ */
+ if (node < 0)
+ node = spl_fit_get_image_node(&ctx, FIT_FIRMWARE_PROP, 0);
+
+ if (node < 0 && IS_ENABLED(CONFIG_SPL_OS_BOOT))
+ node = spl_fit_get_image_node(&ctx, FIT_KERNEL_PROP, 0);
+
+ if (node < 0) {
+ debug("could not find firmware image, trying loadables...\n");
+ node = spl_fit_get_image_node(&ctx, "loadables", 0);
+ /*
+ * If we pick the U-Boot image from "loadables", start at
+ * the second image when later loading additional images.
+ */
+ index = 1;
+ }
+ if (node < 0) {
+ debug("%s: Cannot find u-boot image node: %d\n",
+ __func__, node);
+ return -1;
+ }
+
+ /* Load the image and set up the spl_image structure */
+ ret = spl_load_fit_image(info, sector, &ctx, node, spl_image);
+ if (ret)
+ return ret;
+
+ /*
+ * For backward compatibility, we treat the first node that is
+ * as a U-Boot image, if no OS-type has been declared.
+ */
+ if (!spl_fit_image_get_os(ctx.fit, node, &spl_image->os))
+ debug("Image OS is %s\n", genimg_get_os_name(spl_image->os));
+ else if (!IS_ENABLED(CONFIG_SPL_OS_BOOT))
+ spl_image->os = IH_OS_U_BOOT;
+
+ /*
+ * Booting a next-stage U-Boot may require us to append the FDT.
+ * We allow this to fail, as the U-Boot image might embed its FDT.
+ */
+ if (os_takes_devicetree(spl_image->os)) {
+ ret = spl_fit_append_fdt(spl_image, info, sector, &ctx);
+ if (ret < 0 && spl_image->os != IH_OS_U_BOOT)
+ return ret;
+ }
+
+ firmware_node = node;
+ /* Now check if there are more images for us to load */
+ for (; ; index++) {
+ uint8_t os_type = IH_OS_INVALID;
+
+ node = spl_fit_get_image_node(&ctx, "loadables", index);
+ if (node < 0)
+ break;
+
+ /*
+ * if the firmware is also a loadable, skip it because
+ * it already has been loaded. This is typically the case with
+ * u-boot.img generated by mkimage.
+ */
+ if (firmware_node == node)
+ continue;
+
+ image_info.load_addr = 0;
+ ret = spl_load_fit_image(info, sector, &ctx, node, &image_info);
+ if (ret < 0) {
+ printf("%s: can't load image loadables index %d (ret = %d)\n",
+ __func__, index, ret);
+ return ret;
+ }
+
+ if (spl_fit_image_is_fpga(ctx.fit, node))
+ spl_fit_upload_fpga(&ctx, node, &image_info);
+
+ if (!spl_fit_image_get_os(ctx.fit, node, &os_type))
+ debug("Loadable is %s\n", genimg_get_os_name(os_type));
+
+ if (os_takes_devicetree(os_type)) {
+ spl_fit_append_fdt(&image_info, info, sector, &ctx);
+ spl_image->fdt_addr = image_info.fdt_addr;
+ }
+
+ /*
+ * If the "firmware" image did not provide an entry point,
+ * use the first valid entry point from the loadables.
+ */
+ if (spl_image->entry_point == FDT_ERROR &&
+ image_info.entry_point != FDT_ERROR)
+ spl_image->entry_point = image_info.entry_point;
+
+ /* Record our loadables into the FDT */
+ if (spl_image->fdt_addr)
+ spl_fit_record_loadable(&ctx, index,
+ spl_image->fdt_addr,
+ &image_info);
+ }
+
+ /*
+ * If a platform does not provide CONFIG_SYS_UBOOT_START, U-Boot's
+ * Makefile will set it to 0 and it will end up as the entry point
+ * here. What it actually means is: use the load address.
+ */
+ if (spl_image->entry_point == FDT_ERROR || spl_image->entry_point == 0)
+ spl_image->entry_point = spl_image->load_addr;
+
+ spl_image->flags |= SPL_FIT_FOUND;
+
+ if (IS_ENABLED(CONFIG_IMX_HAB))
+ board_spl_fit_post_load(ctx.fit);
+
+ return 0;
+}
diff --git a/roms/u-boot/common/spl/spl_legacy.c b/roms/u-boot/common/spl/spl_legacy.c
new file mode 100644
index 000000000..82d032680
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_legacy.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <image.h>
+#include <log.h>
+#include <malloc.h>
+#include <spl.h>
+
+#include <lzma/LzmaTypes.h>
+#include <lzma/LzmaDec.h>
+#include <lzma/LzmaTools.h>
+
+#define LZMA_LEN (1 << 20)
+
+int spl_parse_legacy_header(struct spl_image_info *spl_image,
+ const struct image_header *header)
+{
+ u32 header_size = sizeof(struct image_header);
+
+ /* check uImage header CRC */
+ if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK) &&
+ !image_check_hcrc(header)) {
+ puts("SPL: Image header CRC check failed!\n");
+ return -EINVAL;
+ }
+
+ if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) {
+ /*
+ * On some system (e.g. powerpc), the load-address and
+ * entry-point is located at address 0. We can't load
+ * to 0-0x40. So skip header in this case.
+ */
+ spl_image->load_addr = image_get_load(header);
+ spl_image->entry_point = image_get_ep(header);
+ spl_image->size = image_get_data_size(header);
+ } else {
+ spl_image->entry_point = image_get_ep(header);
+ /* Load including the header */
+ spl_image->load_addr = image_get_load(header) -
+ header_size;
+ spl_image->size = image_get_data_size(header) +
+ header_size;
+ }
+
+#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
+ /* store uImage data length and CRC to check later */
+ spl_image->dcrc_data = image_get_load(header);
+ spl_image->dcrc_length = image_get_data_size(header);
+ spl_image->dcrc = image_get_dcrc(header);
+#endif
+
+ spl_image->os = image_get_os(header);
+ spl_image->name = image_get_name(header);
+ debug(SPL_TPL_PROMPT
+ "payload image: %32s load addr: 0x%lx size: %d\n",
+ spl_image->name, spl_image->load_addr, spl_image->size);
+
+ return 0;
+}
+
+/*
+ * This function is added explicitly to avoid code size increase, when
+ * no compression method is enabled. The compiler will optimize the
+ * following switch/case statement in spl_load_legacy_img() away due to
+ * Dead Code Elimination.
+ */
+static inline int spl_image_get_comp(const struct image_header *hdr)
+{
+ if (IS_ENABLED(CONFIG_SPL_LZMA))
+ return image_get_comp(hdr);
+
+ return IH_COMP_NONE;
+}
+
+int spl_load_legacy_img(struct spl_image_info *spl_image,
+ struct spl_load_info *load, ulong header)
+{
+ __maybe_unused SizeT lzma_len;
+ __maybe_unused void *src;
+ struct image_header hdr;
+ ulong dataptr;
+ int ret;
+
+ /* Read header into local struct */
+ load->read(load, header, sizeof(hdr), &hdr);
+
+ ret = spl_parse_image_header(spl_image, &hdr);
+ if (ret)
+ return ret;
+
+ dataptr = header + sizeof(hdr);
+
+ /* Read image */
+ switch (spl_image_get_comp(&hdr)) {
+ case IH_COMP_NONE:
+ load->read(load, dataptr, spl_image->size,
+ (void *)(unsigned long)spl_image->load_addr);
+ break;
+
+ case IH_COMP_LZMA:
+ lzma_len = LZMA_LEN;
+
+ debug("LZMA: Decompressing %08lx to %08lx\n",
+ dataptr, spl_image->load_addr);
+ src = malloc(spl_image->size);
+ if (!src) {
+ printf("Unable to allocate %d bytes for LZMA\n",
+ spl_image->size);
+ return -ENOMEM;
+ }
+
+ load->read(load, dataptr, spl_image->size, src);
+ ret = lzmaBuffToBuffDecompress((void *)spl_image->load_addr,
+ &lzma_len, src, spl_image->size);
+ if (ret) {
+ printf("LZMA decompression error: %d\n", ret);
+ return ret;
+ }
+
+ spl_image->size = lzma_len;
+ break;
+
+ default:
+ debug("Compression method %s is not supported\n",
+ genimg_get_comp_short_name(image_get_comp(&hdr)));
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/roms/u-boot/common/spl/spl_mmc.c b/roms/u-boot/common/spl/spl_mmc.c
new file mode 100644
index 000000000..add2785b4
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_mmc.c
@@ -0,0 +1,448 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.com>
+ */
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <part.h>
+#include <spl.h>
+#include <linux/compiler.h>
+#include <errno.h>
+#include <asm/u-boot.h>
+#include <errno.h>
+#include <mmc.h>
+#include <image.h>
+
+static int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
+ ulong sector, struct image_header *header)
+{
+ u32 image_size_sectors;
+ unsigned long count;
+ int ret;
+
+ ret = spl_parse_image_header(spl_image, header);
+ if (ret)
+ return ret;
+
+ /* convert size to sectors - round up */
+ image_size_sectors = (spl_image->size + mmc->read_bl_len - 1) /
+ mmc->read_bl_len;
+
+ /* Read the header too to avoid extra memcpy */
+ count = blk_dread(mmc_get_blk_desc(mmc), sector, image_size_sectors,
+ (void *)(ulong)spl_image->load_addr);
+ debug("read %x sectors to %lx\n", image_size_sectors,
+ spl_image->load_addr);
+ if (count != image_size_sectors)
+ return -EIO;
+
+ return 0;
+}
+
+static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ struct mmc *mmc = load->dev;
+
+ return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
+}
+
+static __maybe_unused unsigned long spl_mmc_raw_uboot_offset(int part)
+{
+#if IS_ENABLED(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR)
+ if (part == 0)
+ return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET;
+#endif
+
+ return 0;
+}
+
+static __maybe_unused
+int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
+ struct mmc *mmc, unsigned long sector)
+{
+ unsigned long count;
+ struct image_header *header;
+ struct blk_desc *bd = mmc_get_blk_desc(mmc);
+ int ret = 0;
+
+ header = spl_get_load_buffer(-sizeof(*header), bd->blksz);
+
+ /* read image header to find the image size & load address */
+ count = blk_dread(bd, sector, 1, header);
+ debug("hdr read sector %lx, count=%lu\n", sector, count);
+ if (count == 0) {
+ ret = -EIO;
+ goto end;
+ }
+
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+ image_get_magic(header) == FDT_MAGIC) {
+ struct spl_load_info load;
+
+ debug("Found FIT\n");
+ load.dev = mmc;
+ load.priv = NULL;
+ load.filename = NULL;
+ load.bl_len = mmc->read_bl_len;
+ load.read = h_spl_load_read;
+ ret = spl_load_simple_fit(spl_image, &load, sector, header);
+ } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
+ struct spl_load_info load;
+
+ load.dev = mmc;
+ load.priv = NULL;
+ load.filename = NULL;
+ load.bl_len = mmc->read_bl_len;
+ load.read = h_spl_load_read;
+
+ ret = spl_load_imx_container(spl_image, &load, sector);
+ } else {
+ ret = mmc_load_legacy(spl_image, mmc, sector, header);
+ }
+
+end:
+ if (ret) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ puts("mmc_load_image_raw_sector: mmc block read error\n");
+#endif
+ return -1;
+ }
+
+ return 0;
+}
+
+static int spl_mmc_get_device_index(u32 boot_device)
+{
+ switch (boot_device) {
+ case BOOT_DEVICE_MMC1:
+ return 0;
+ case BOOT_DEVICE_MMC2:
+ case BOOT_DEVICE_MMC2_2:
+ return 1;
+ }
+
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("spl: unsupported mmc boot device.\n");
+#endif
+
+ return -ENODEV;
+}
+
+static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
+{
+ int err, mmc_dev;
+
+ mmc_dev = spl_mmc_get_device_index(boot_device);
+ if (mmc_dev < 0)
+ return mmc_dev;
+
+#if CONFIG_IS_ENABLED(DM_MMC)
+ err = mmc_init_device(mmc_dev);
+#else
+ err = mmc_initialize(NULL);
+#endif /* DM_MMC */
+ if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("spl: could not initialize mmc. error: %d\n", err);
+#endif
+ return err;
+ }
+ *mmcp = find_mmc_device(mmc_dev);
+ err = *mmcp ? 0 : -ENODEV;
+ if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("spl: could not find mmc device %d. error: %d\n",
+ mmc_dev, err);
+#endif
+ return err;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
+static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
+ struct mmc *mmc, int partition,
+ unsigned long sector)
+{
+ struct disk_partition info;
+ int err;
+
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
+ int type_part;
+ /* Only support MBR so DOS_ENTRY_NUMBERS */
+ for (type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
+ err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
+ if (err)
+ continue;
+ if (info.sys_ind ==
+ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE) {
+ partition = type_part;
+ break;
+ }
+ }
+#endif
+
+ err = part_get_info(mmc_get_blk_desc(mmc), partition, &info);
+ if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ puts("spl: partition error\n");
+#endif
+ return -1;
+ }
+
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
+ return mmc_load_image_raw_sector(spl_image, mmc, info.start + sector);
+#else
+ return mmc_load_image_raw_sector(spl_image, mmc, info.start);
+#endif
+}
+#endif
+
+#ifdef CONFIG_SPL_OS_BOOT
+static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
+ struct mmc *mmc)
+{
+ int ret;
+
+#if defined(CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR)
+ unsigned long count;
+
+ count = blk_dread(mmc_get_blk_desc(mmc),
+ CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
+ CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
+ (void *) CONFIG_SYS_SPL_ARGS_ADDR);
+ if (count != CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ puts("mmc_load_image_raw_os: mmc block read error\n");
+#endif
+ return -1;
+ }
+#endif /* CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR */
+
+ ret = mmc_load_image_raw_sector(spl_image, mmc,
+ CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
+ if (ret)
+ return ret;
+
+ if (spl_image->os != IH_OS_LINUX) {
+ puts("Expected Linux image is not found. Trying to start U-boot\n");
+ return -ENOENT;
+ }
+
+ return 0;
+}
+#else
+int spl_start_uboot(void)
+{
+ return 1;
+}
+static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
+ struct mmc *mmc)
+{
+ return -ENOSYS;
+}
+#endif
+
+#ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
+static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
+ const char *filename)
+{
+ int err = -ENOSYS;
+
+#ifdef CONFIG_SPL_FS_FAT
+ if (!spl_start_uboot()) {
+ err = spl_load_image_fat_os(spl_image, mmc_get_blk_desc(mmc),
+ CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
+ if (!err)
+ return err;
+ }
+#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
+ err = spl_load_image_fat(spl_image, mmc_get_blk_desc(mmc),
+ CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
+ filename);
+ if (!err)
+ return err;
+#endif
+#endif
+#ifdef CONFIG_SPL_FS_EXT4
+ if (!spl_start_uboot()) {
+ err = spl_load_image_ext_os(spl_image, mmc_get_blk_desc(mmc),
+ CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
+ if (!err)
+ return err;
+ }
+#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
+ err = spl_load_image_ext(spl_image, mmc_get_blk_desc(mmc),
+ CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
+ filename);
+ if (!err)
+ return err;
+#endif
+#endif
+
+#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
+ err = -ENOENT;
+#endif
+
+ return err;
+}
+#else
+static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
+ const char *filename)
+{
+ return -ENOSYS;
+}
+#endif
+
+u32 __weak spl_mmc_boot_mode(const u32 boot_device)
+{
+#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
+ return MMCSD_MODE_FS;
+#elif defined(CONFIG_SUPPORT_EMMC_BOOT)
+ return MMCSD_MODE_EMMCBOOT;
+#else
+ return MMCSD_MODE_RAW;
+#endif
+}
+
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
+int __weak spl_mmc_boot_partition(const u32 boot_device)
+{
+ return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION;
+}
+#endif
+
+unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
+ unsigned long raw_sect)
+{
+ return raw_sect;
+}
+
+int spl_mmc_load(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev,
+ const char *filename,
+ int raw_part,
+ unsigned long raw_sect)
+{
+ static struct mmc *mmc;
+ u32 boot_mode;
+ int err = 0;
+ __maybe_unused int part = 0;
+
+ /* Perform peripheral init only once */
+ if (!mmc) {
+ err = spl_mmc_find_device(&mmc, bootdev->boot_device);
+ if (err)
+ return err;
+
+ err = mmc_init(mmc);
+ if (err) {
+ mmc = NULL;
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("spl: mmc init failed with error: %d\n", err);
+#endif
+ return err;
+ }
+ }
+
+ boot_mode = spl_mmc_boot_mode(bootdev->boot_device);
+ err = -EINVAL;
+ switch (boot_mode) {
+ case MMCSD_MODE_EMMCBOOT:
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION
+ part = CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION;
+#else
+ /*
+ * We need to check what the partition is configured to.
+ * 1 and 2 match up to boot0 / boot1 and 7 is user data
+ * which is the first physical partition (0).
+ */
+ part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
+
+ if (part == 7)
+ part = 0;
+#endif
+
+ if (CONFIG_IS_ENABLED(MMC_TINY))
+ err = mmc_switch_part(mmc, part);
+ else
+ err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+
+ if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ puts("spl: mmc partition switch failed\n");
+#endif
+ return err;
+ }
+ /* Fall through */
+ case MMCSD_MODE_RAW:
+ debug("spl: mmc boot mode: raw\n");
+
+ if (!spl_start_uboot()) {
+ err = mmc_load_image_raw_os(spl_image, mmc);
+ if (!err)
+ return err;
+ }
+
+ raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
+
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
+ err = mmc_load_image_raw_partition(spl_image, mmc, raw_part,
+ raw_sect);
+ if (!err)
+ return err;
+#endif
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
+ err = mmc_load_image_raw_sector(spl_image, mmc,
+ raw_sect + spl_mmc_raw_uboot_offset(part));
+ if (!err)
+ return err;
+#endif
+ /* If RAW mode fails, try FS mode. */
+ case MMCSD_MODE_FS:
+ debug("spl: mmc boot mode: fs\n");
+
+ err = spl_mmc_do_fs_boot(spl_image, mmc, filename);
+ if (!err)
+ return err;
+
+ break;
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ default:
+ puts("spl: mmc: wrong boot mode\n");
+#endif
+ }
+
+ return err;
+}
+
+int spl_mmc_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ return spl_mmc_load(spl_image, bootdev,
+#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
+ CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
+#else
+ NULL,
+#endif
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
+ spl_mmc_boot_partition(bootdev->boot_device),
+#else
+ 0,
+#endif
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
+ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
+#else
+ 0);
+#endif
+}
+
+SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
+SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image);
+SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image);
diff --git a/roms/u-boot/common/spl/spl_nand.c b/roms/u-boot/common/spl/spl_nand.c
new file mode 100644
index 000000000..59f4a84a3
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_nand.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
+ */
+#include <common.h>
+#include <config.h>
+#include <fdt_support.h>
+#include <image.h>
+#include <log.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <nand.h>
+#include <linux/libfdt_env.h>
+#include <fdt.h>
+
+uint32_t __weak spl_nand_get_uboot_raw_page(void)
+{
+ return CONFIG_SYS_NAND_U_BOOT_OFFS;
+}
+
+#if defined(CONFIG_SPL_NAND_RAW_ONLY)
+static int spl_nand_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ nand_init();
+
+ printf("Loading U-Boot from 0x%08x (size 0x%08x) to 0x%08x\n",
+ CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE,
+ CONFIG_SYS_NAND_U_BOOT_DST);
+
+ nand_spl_load_image(spl_nand_get_uboot_raw_page(),
+ CONFIG_SYS_NAND_U_BOOT_SIZE,
+ (void *)CONFIG_SYS_NAND_U_BOOT_DST);
+ spl_set_header_raw_uboot(spl_image);
+ nand_deselect();
+
+ return 0;
+}
+#else
+
+static ulong spl_nand_fit_read(struct spl_load_info *load, ulong offs,
+ ulong size, void *dst)
+{
+ int err;
+#ifdef CONFIG_SYS_NAND_BLOCK_SIZE
+ ulong sector;
+
+ sector = *(int *)load->priv;
+ offs = sector + nand_spl_adjust_offset(sector, offs - sector);
+#else
+ offs *= load->bl_len;
+ size *= load->bl_len;
+#endif
+ err = nand_spl_load_image(offs, size, dst);
+ if (err)
+ return 0;
+
+ return size / load->bl_len;
+}
+
+struct mtd_info * __weak nand_get_mtd(void)
+{
+ return NULL;
+}
+
+static int spl_nand_load_element(struct spl_image_info *spl_image,
+ int offset, struct image_header *header)
+{
+ struct mtd_info *mtd = nand_get_mtd();
+ int bl_len = mtd ? mtd->writesize : 1;
+ int err;
+
+ err = nand_spl_load_image(offset, sizeof(*header), (void *)header);
+ if (err)
+ return err;
+
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+ image_get_magic(header) == FDT_MAGIC) {
+ struct spl_load_info load;
+
+ debug("Found FIT\n");
+ load.dev = NULL;
+ load.priv = &offset;
+ load.filename = NULL;
+ load.bl_len = bl_len;
+ load.read = spl_nand_fit_read;
+ return spl_load_simple_fit(spl_image, &load, offset / bl_len, header);
+ } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
+ struct spl_load_info load;
+
+ load.dev = NULL;
+ load.priv = NULL;
+ load.filename = NULL;
+ load.bl_len = bl_len;
+ load.read = spl_nand_fit_read;
+ return spl_load_imx_container(spl_image, &load, offset / bl_len);
+ } else {
+ err = spl_parse_image_header(spl_image, header);
+ if (err)
+ return err;
+ return nand_spl_load_image(offset, spl_image->size,
+ (void *)(ulong)spl_image->load_addr);
+ }
+}
+
+static int spl_nand_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ int err;
+ struct image_header *header;
+ int *src __attribute__((unused));
+ int *dst __attribute__((unused));
+
+#ifdef CONFIG_SPL_NAND_SOFTECC
+ debug("spl: nand - using sw ecc\n");
+#else
+ debug("spl: nand - using hw ecc\n");
+#endif
+ nand_init();
+
+ header = spl_get_load_buffer(0, sizeof(*header));
+
+#ifdef CONFIG_SPL_OS_BOOT
+ if (!spl_start_uboot()) {
+ /*
+ * load parameter image
+ * load to temp position since nand_spl_load_image reads
+ * a whole block which is typically larger than
+ * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite
+ * following sections like BSS
+ */
+ nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS,
+ CONFIG_CMD_SPL_WRITE_SIZE,
+ (void *)CONFIG_SYS_TEXT_BASE);
+ /* copy to destintion */
+ for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR,
+ src = (int *)CONFIG_SYS_TEXT_BASE;
+ src < (int *)(CONFIG_SYS_TEXT_BASE +
+ CONFIG_CMD_SPL_WRITE_SIZE);
+ src++, dst++) {
+ writel(readl(src), dst);
+ }
+
+ /* load linux */
+ nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
+ sizeof(*header), (void *)header);
+ err = spl_parse_image_header(spl_image, header);
+ if (err)
+ return err;
+ if (header->ih_os == IH_OS_LINUX) {
+ /* happy - was a linux */
+ err = nand_spl_load_image(
+ CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
+ spl_image->size,
+ (void *)spl_image->load_addr);
+ nand_deselect();
+ return err;
+ } else {
+ puts("The Expected Linux image was not "
+ "found. Please check your NAND "
+ "configuration.\n");
+ puts("Trying to start u-boot now...\n");
+ }
+ }
+#endif
+#ifdef CONFIG_NAND_ENV_DST
+ spl_nand_load_element(spl_image, CONFIG_ENV_OFFSET, header);
+#ifdef CONFIG_ENV_OFFSET_REDUND
+ spl_nand_load_element(spl_image, CONFIG_ENV_OFFSET_REDUND, header);
+#endif
+#endif
+ /* Load u-boot */
+ err = spl_nand_load_element(spl_image, spl_nand_get_uboot_raw_page(),
+ header);
+#ifdef CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND
+#if CONFIG_SYS_NAND_U_BOOT_OFFS != CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND
+ if (err)
+ err = spl_nand_load_element(spl_image,
+ CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND,
+ header);
+#endif
+#endif
+ nand_deselect();
+ return err;
+}
+#endif
+/* Use priorty 1 so that Ubi can override this */
+SPL_LOAD_IMAGE_METHOD("NAND", 1, BOOT_DEVICE_NAND, spl_nand_load_image);
diff --git a/roms/u-boot/common/spl/spl_net.c b/roms/u-boot/common/spl/spl_net.c
new file mode 100644
index 000000000..e140a6306
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_net.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2012
+ * Ilya Yanok <ilya.yanok@gmail.com>
+ */
+#include <common.h>
+#include <env.h>
+#include <errno.h>
+#include <image.h>
+#include <log.h>
+#include <spl.h>
+#include <net.h>
+#include <linux/libfdt.h>
+
+#if defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USB_ETHER)
+static ulong spl_net_load_read(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ debug("%s: sector %lx, count %lx, buf %lx\n",
+ __func__, sector, count, (ulong)buf);
+ memcpy(buf, (void *)(image_load_addr + sector), count);
+ return count;
+}
+
+static int spl_net_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ struct image_header *header = (struct image_header *)image_load_addr;
+ int rv;
+
+ env_init();
+ env_relocate();
+ env_set("autoload", "yes");
+ rv = eth_initialize();
+ if (rv == 0) {
+ printf("No Ethernet devices found\n");
+ return -ENODEV;
+ }
+ if (bootdev->boot_device_name)
+ env_set("ethact", bootdev->boot_device_name);
+ rv = net_loop(BOOTP);
+ if (rv < 0) {
+ printf("Problem booting with BOOTP\n");
+ return rv;
+ }
+
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+ image_get_magic(header) == FDT_MAGIC) {
+ struct spl_load_info load;
+
+ debug("Found FIT\n");
+ load.bl_len = 1;
+ load.read = spl_net_load_read;
+ rv = spl_load_simple_fit(spl_image, &load, 0, header);
+ } else {
+ debug("Legacy image\n");
+
+ rv = spl_parse_image_header(spl_image, header);
+ if (rv)
+ return rv;
+
+ memcpy((void *)spl_image->load_addr, header, spl_image->size);
+ }
+
+ return rv;
+}
+#endif
+
+#ifdef CONFIG_SPL_ETH_SUPPORT
+int spl_net_load_image_cpgmac(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+#ifdef CONFIG_SPL_ETH_DEVICE
+ bootdev->boot_device_name = CONFIG_SPL_ETH_DEVICE;
+#endif
+
+ return spl_net_load_image(spl_image, bootdev);
+}
+SPL_LOAD_IMAGE_METHOD("eth device", 0, BOOT_DEVICE_CPGMAC,
+ spl_net_load_image_cpgmac);
+#endif
+
+#ifdef CONFIG_SPL_USB_ETHER
+int spl_net_load_image_usb(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ bootdev->boot_device_name = "usb_ether";
+#if CONFIG_IS_ENABLED(DM_USB_GADGET)
+ usb_ether_init();
+#endif
+ return spl_net_load_image(spl_image, bootdev);
+}
+SPL_LOAD_IMAGE_METHOD("USB eth", 0, BOOT_DEVICE_USBETH, spl_net_load_image_usb);
+#endif
diff --git a/roms/u-boot/common/spl/spl_nor.c b/roms/u-boot/common/spl/spl_nor.c
new file mode 100644
index 000000000..5270401db
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_nor.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2012 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <image.h>
+#include <log.h>
+#include <spl.h>
+
+static ulong spl_nor_load_read(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ debug("%s: sector %lx, count %lx, buf %p\n",
+ __func__, sector, count, buf);
+ memcpy(buf, (void *)sector, count);
+
+ return count;
+}
+
+unsigned long __weak spl_nor_get_uboot_base(void)
+{
+ return CONFIG_SYS_UBOOT_BASE;
+}
+
+static int spl_nor_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ __maybe_unused const struct image_header *header;
+ __maybe_unused struct spl_load_info load;
+
+ /*
+ * Loading of the payload to SDRAM is done with skipping of
+ * the mkimage header in this SPL NOR driver
+ */
+ spl_image->flags |= SPL_COPY_PAYLOAD_ONLY;
+
+#ifdef CONFIG_SPL_OS_BOOT
+ if (!spl_start_uboot()) {
+ /*
+ * Load Linux from its location in NOR flash to its defined
+ * location in SDRAM
+ */
+ header = (const struct image_header *)CONFIG_SYS_OS_BASE;
+#ifdef CONFIG_SPL_LOAD_FIT
+ if (image_get_magic(header) == FDT_MAGIC) {
+ int ret;
+
+ debug("Found FIT\n");
+ load.bl_len = 1;
+ load.read = spl_nor_load_read;
+
+ ret = spl_load_simple_fit(spl_image, &load,
+ CONFIG_SYS_OS_BASE,
+ (void *)header);
+
+#if defined CONFIG_SYS_SPL_ARGS_ADDR && defined CONFIG_CMD_SPL_NOR_OFS
+ memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR,
+ (void *)CONFIG_CMD_SPL_NOR_OFS,
+ CONFIG_CMD_SPL_WRITE_SIZE);
+#endif
+ return ret;
+ }
+#endif
+ if (image_get_os(header) == IH_OS_LINUX) {
+ /* happy - was a Linux */
+ int ret;
+
+ ret = spl_parse_image_header(spl_image, header);
+ if (ret)
+ return ret;
+
+ memcpy((void *)spl_image->load_addr,
+ (void *)(CONFIG_SYS_OS_BASE +
+ sizeof(struct image_header)),
+ spl_image->size);
+#ifdef CONFIG_SYS_FDT_BASE
+ spl_image->arg = (void *)CONFIG_SYS_FDT_BASE;
+#endif
+
+ return 0;
+ } else {
+ puts("The Expected Linux image was not found.\n"
+ "Please check your NOR configuration.\n"
+ "Trying to start u-boot now...\n");
+ }
+ }
+#endif
+
+ /*
+ * Load real U-Boot from its location in NOR flash to its
+ * defined location in SDRAM
+ */
+#ifdef CONFIG_SPL_LOAD_FIT
+ header = (const struct image_header *)spl_nor_get_uboot_base();
+ if (image_get_magic(header) == FDT_MAGIC) {
+ debug("Found FIT format U-Boot\n");
+ load.bl_len = 1;
+ load.read = spl_nor_load_read;
+ return spl_load_simple_fit(spl_image, &load,
+ spl_nor_get_uboot_base(),
+ (void *)header);
+ }
+#endif
+ if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
+ load.bl_len = 1;
+ load.read = spl_nor_load_read;
+ return spl_load_imx_container(spl_image, &load,
+ spl_nor_get_uboot_base());
+ }
+
+ /* Legacy image handling */
+ if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_SUPPORT)) {
+ load.bl_len = 1;
+ load.read = spl_nor_load_read;
+ return spl_load_legacy_img(spl_image, &load,
+ spl_nor_get_uboot_base());
+ }
+
+ return 0;
+}
+SPL_LOAD_IMAGE_METHOD("NOR", 0, BOOT_DEVICE_NOR, spl_nor_load_image);
diff --git a/roms/u-boot/common/spl/spl_onenand.c b/roms/u-boot/common/spl/spl_onenand.c
new file mode 100644
index 000000000..93cbf47e8
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_onenand.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2013
+ * ISEE 2007 SL - Enric Balletbo i Serra <eballetbo@iseebcn.com>
+ *
+ * Based on common/spl/spl_nand.c
+ * Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
+ */
+#include <common.h>
+#include <config.h>
+#include <image.h>
+#include <log.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <onenand_uboot.h>
+
+static int spl_onenand_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ struct image_header *header;
+ int ret;
+
+ debug("spl: onenand\n");
+
+ header = spl_get_load_buffer(0, CONFIG_SYS_ONENAND_PAGE_SIZE);
+ /* Load u-boot */
+ onenand_spl_load_image(CONFIG_SYS_ONENAND_U_BOOT_OFFS,
+ CONFIG_SYS_ONENAND_PAGE_SIZE, (void *)header);
+ ret = spl_parse_image_header(spl_image, header);
+ if (ret)
+ return ret;
+ onenand_spl_load_image(CONFIG_SYS_ONENAND_U_BOOT_OFFS,
+ spl_image->size, (void *)spl_image->load_addr);
+
+ return 0;
+}
+/* Use priorty 1 so that Ubi can override this */
+SPL_LOAD_IMAGE_METHOD("OneNAND", 1, BOOT_DEVICE_ONENAND,
+ spl_onenand_load_image);
diff --git a/roms/u-boot/common/spl/spl_opensbi.c b/roms/u-boot/common/spl/spl_opensbi.c
new file mode 100644
index 000000000..1c0abf855
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_opensbi.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Fraunhofer AISEC,
+ * Lukas Auer <lukas.auer@aisec.fraunhofer.de>
+ *
+ * Based on common/spl/spl_atf.c
+ */
+#include <common.h>
+#include <cpu_func.h>
+#include <errno.h>
+#include <hang.h>
+#include <image.h>
+#include <spl.h>
+#include <asm/global_data.h>
+#include <asm/smp.h>
+#include <opensbi.h>
+#include <linux/libfdt.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct fw_dynamic_info opensbi_info;
+
+static int spl_opensbi_find_uboot_node(void *blob, int *uboot_node)
+{
+ int fit_images_node, node;
+ const char *fit_os;
+
+ fit_images_node = fdt_path_offset(blob, "/fit-images");
+ if (fit_images_node < 0)
+ return -ENODEV;
+
+ fdt_for_each_subnode(node, blob, fit_images_node) {
+ fit_os = fdt_getprop(blob, node, FIT_OS_PROP, NULL);
+ if (!fit_os)
+ continue;
+
+ if (genimg_get_os_id(fit_os) == IH_OS_U_BOOT) {
+ *uboot_node = node;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+void spl_invoke_opensbi(struct spl_image_info *spl_image)
+{
+ int ret, uboot_node;
+ ulong uboot_entry;
+ void (*opensbi_entry)(ulong hartid, ulong dtb, ulong info);
+
+ if (!spl_image->fdt_addr) {
+ pr_err("No device tree specified in SPL image\n");
+ hang();
+ }
+
+ /* Find U-Boot image in /fit-images */
+ ret = spl_opensbi_find_uboot_node(spl_image->fdt_addr, &uboot_node);
+ if (ret) {
+ pr_err("Can't find U-Boot node, %d\n", ret);
+ hang();
+ }
+
+ /* Get U-Boot entry point */
+ ret = fit_image_get_entry(spl_image->fdt_addr, uboot_node, &uboot_entry);
+ if (ret)
+ ret = fit_image_get_load(spl_image->fdt_addr, uboot_node, &uboot_entry);
+
+ /* Prepare obensbi_info object */
+ opensbi_info.magic = FW_DYNAMIC_INFO_MAGIC_VALUE;
+ opensbi_info.version = FW_DYNAMIC_INFO_VERSION;
+ opensbi_info.next_addr = uboot_entry;
+ opensbi_info.next_mode = FW_DYNAMIC_INFO_NEXT_MODE_S;
+ opensbi_info.options = SBI_SCRATCH_NO_BOOT_PRINTS;
+ opensbi_info.boot_hart = gd->arch.boot_hart;
+
+ opensbi_entry = (void (*)(ulong, ulong, ulong))spl_image->entry_point;
+ invalidate_icache_all();
+
+#ifdef CONFIG_SPL_SMP
+ /*
+ * Start OpenSBI on all secondary harts and wait for acknowledgment.
+ *
+ * OpenSBI first relocates itself to its link address. This is done by
+ * the main hart. To make sure no hart is still running U-Boot SPL
+ * during relocation, we wait for all secondary harts to acknowledge
+ * the call-function request before entering OpenSBI on the main hart.
+ * Otherwise, code corruption can occur if the link address ranges of
+ * U-Boot SPL and OpenSBI overlap.
+ */
+ ret = smp_call_function((ulong)spl_image->entry_point,
+ (ulong)spl_image->fdt_addr,
+ (ulong)&opensbi_info, 1);
+ if (ret)
+ hang();
+#endif
+ opensbi_entry(gd->arch.boot_hart, (ulong)spl_image->fdt_addr,
+ (ulong)&opensbi_info);
+}
diff --git a/roms/u-boot/common/spl/spl_optee.S b/roms/u-boot/common/spl/spl_optee.S
new file mode 100644
index 000000000..8bd1949dd
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_optee.S
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2017 Rockchip Electronic Co.,Ltd
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ENTRY(spl_optee_entry)
+ ldr lr, =CONFIG_SYS_TEXT_BASE
+ mov pc, r3
+ENDPROC(spl_optee_entry)
diff --git a/roms/u-boot/common/spl/spl_ram.c b/roms/u-boot/common/spl/spl_ram.c
new file mode 100644
index 000000000..df1d5b43d
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_ram.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016
+ * Xilinx, Inc.
+ *
+ * (C) Copyright 2016
+ * Toradex AG
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ * Stefan Agner <stefan.agner@toradex.com>
+ */
+#include <common.h>
+#include <binman_sym.h>
+#include <image.h>
+#include <log.h>
+#include <mapmem.h>
+#include <spl.h>
+#include <linux/libfdt.h>
+
+#ifndef CONFIG_SPL_LOAD_FIT_ADDRESS
+# define CONFIG_SPL_LOAD_FIT_ADDRESS 0
+#endif
+
+static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ debug("%s: sector %lx, count %lx, buf %lx\n",
+ __func__, sector, count, (ulong)buf);
+ memcpy(buf, (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS + sector), count);
+ return count;
+}
+
+static int spl_ram_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ struct image_header *header;
+
+ header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS;
+
+#if CONFIG_IS_ENABLED(DFU)
+ if (bootdev->boot_device == BOOT_DEVICE_DFU)
+ spl_dfu_cmd(0, "dfu_alt_info_ram", "ram", "0");
+#endif
+
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+ image_get_magic(header) == FDT_MAGIC) {
+ struct spl_load_info load;
+
+ debug("Found FIT\n");
+ load.bl_len = 1;
+ load.read = spl_ram_load_read;
+ spl_load_simple_fit(spl_image, &load, 0, header);
+ } else {
+ ulong u_boot_pos = binman_sym(ulong, u_boot_any, image_pos);
+
+ debug("Legacy image\n");
+ /*
+ * Get the header. It will point to an address defined by
+ * handoff which will tell where the image located inside
+ * the flash.
+ */
+ debug("u_boot_pos = %lx\n", u_boot_pos);
+ if (u_boot_pos == BINMAN_SYM_MISSING) {
+ /*
+ * No binman support or no information. For now, fix it
+ * to the address pointed to by U-Boot.
+ */
+ u_boot_pos = (ulong)spl_get_load_buffer(-sizeof(*header),
+ sizeof(*header));
+ }
+ header = (struct image_header *)map_sysmem(u_boot_pos, 0);
+
+ spl_parse_image_header(spl_image, header);
+ }
+
+ return 0;
+}
+#if CONFIG_IS_ENABLED(RAM_DEVICE)
+SPL_LOAD_IMAGE_METHOD("RAM", 0, BOOT_DEVICE_RAM, spl_ram_load_image);
+#endif
+#if CONFIG_IS_ENABLED(DFU)
+SPL_LOAD_IMAGE_METHOD("DFU", 0, BOOT_DEVICE_DFU, spl_ram_load_image);
+#endif
+
+
diff --git a/roms/u-boot/common/spl/spl_sata.c b/roms/u-boot/common/spl/spl_sata.c
new file mode 100644
index 000000000..e108af057
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_sata.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * Dan Murphy <dmurphy@ti.com>
+ *
+ * Derived work from spl_usb.c
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/u-boot.h>
+#include <sata.h>
+#include <scsi.h>
+#include <errno.h>
+#include <fat.h>
+#include <image.h>
+
+#ifndef CONFIG_SYS_SATA_FAT_BOOT_PARTITION
+#define CONFIG_SYS_SATA_FAT_BOOT_PARTITION 1
+#endif
+
+#ifndef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
+#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
+#endif
+
+#ifndef CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR
+/* Dummy value to make the compiler happy */
+#define CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR 0x100
+#endif
+
+static int spl_sata_load_image_raw(struct spl_image_info *spl_image,
+ struct blk_desc *stor_dev, unsigned long sector)
+{
+ struct image_header *header;
+ unsigned long count;
+ u32 image_size_sectors;
+ int ret;
+
+ header = spl_get_load_buffer(-sizeof(*header), stor_dev->blksz);
+ count = blk_dread(stor_dev, sector, 1, header);
+ if (count == 0)
+ return -EIO;
+
+ ret = spl_parse_image_header(spl_image, header);
+ if (ret)
+ return ret;
+
+ image_size_sectors = DIV_ROUND_UP(spl_image->size, stor_dev->blksz);
+ count = blk_dread(stor_dev, sector, image_size_sectors,
+ (void *)spl_image->load_addr);
+ if (count != image_size_sectors)
+ return -EIO;
+
+ return 0;
+}
+
+static int spl_sata_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ int err = 0;
+ struct blk_desc *stor_dev;
+
+#if !defined(CONFIG_DM_SCSI) && !defined(CONFIG_AHCI)
+ err = init_sata(CONFIG_SPL_SATA_BOOT_DEVICE);
+#endif
+ if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("spl: sata init failed: err - %d\n", err);
+#endif
+ return err;
+ } else {
+ /* try to recognize storage devices immediately */
+ scsi_scan(false);
+ stor_dev = blk_get_devnum_by_type(IF_TYPE_SCSI, 0);
+ if (!stor_dev)
+ return -ENODEV;
+ }
+
+#ifdef CONFIG_SPL_OS_BOOT
+ if (spl_start_uboot() ||
+ spl_load_image_fat_os(spl_image, stor_dev,
+ CONFIG_SYS_SATA_FAT_BOOT_PARTITION))
+#endif
+ {
+ err = -ENOSYS;
+
+ if (IS_ENABLED(CONFIG_SPL_FS_FAT)) {
+ err = spl_load_image_fat(spl_image, stor_dev,
+ CONFIG_SYS_SATA_FAT_BOOT_PARTITION,
+ CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
+ } else if (IS_ENABLED(CONFIG_SPL_SATA_RAW_U_BOOT_USE_SECTOR)) {
+ err = spl_sata_load_image_raw(spl_image, stor_dev,
+ CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR);
+ }
+ }
+ if (err) {
+ puts("Error loading sata device\n");
+ return err;
+ }
+
+ return 0;
+}
+SPL_LOAD_IMAGE_METHOD("SATA", 0, BOOT_DEVICE_SATA, spl_sata_load_image);
diff --git a/roms/u-boot/common/spl/spl_sdp.c b/roms/u-boot/common/spl/spl_sdp.c
new file mode 100644
index 000000000..ae9c09883
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_sdp.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Toradex
+ * Author: Stefan Agner <stefan.agner@toradex.com>
+ */
+
+#include <common.h>
+#include <log.h>
+#include <spl.h>
+#include <usb.h>
+#include <g_dnl.h>
+#include <sdp.h>
+
+static int spl_sdp_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ int ret;
+ const int controller_index = CONFIG_SPL_SDP_USB_DEV;
+
+ usb_gadget_initialize(controller_index);
+
+ board_usb_init(0, USB_INIT_DEVICE);
+
+ g_dnl_clear_detach();
+ ret = g_dnl_register("usb_dnl_sdp");
+ if (ret) {
+ pr_err("SDP dnl register failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = sdp_init(controller_index);
+ if (ret) {
+ pr_err("SDP init failed: %d\n", ret);
+ return -ENODEV;
+ }
+
+ /*
+ * This command either loads a legacy image, jumps and never returns,
+ * or it loads a FIT image and returns it to be handled by the SPL
+ * code.
+ */
+ ret = spl_sdp_handle(controller_index, spl_image);
+ debug("SDP ended\n");
+
+ usb_gadget_release(controller_index);
+ return ret;
+}
+SPL_LOAD_IMAGE_METHOD("USB SDP", 0, BOOT_DEVICE_BOARD, spl_sdp_load_image);
diff --git a/roms/u-boot/common/spl/spl_spi.c b/roms/u-boot/common/spl/spl_spi.c
new file mode 100644
index 000000000..6a4e03328
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_spi.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2011 OMICRON electronics GmbH
+ *
+ * based on drivers/mtd/nand/raw/nand_spl_load.c
+ *
+ * Copyright (C) 2011
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ */
+
+#include <common.h>
+#include <image.h>
+#include <log.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <errno.h>
+#include <spl.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * Load the kernel, check for a valid header we can parse, and if found load
+ * the kernel and then device tree.
+ */
+static int spi_load_image_os(struct spl_image_info *spl_image,
+ struct spi_flash *flash,
+ struct image_header *header)
+{
+ int err;
+
+ /* Read for a header, parse or error out. */
+ spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, sizeof(*header),
+ (void *)header);
+
+ if (image_get_magic(header) != IH_MAGIC)
+ return -1;
+
+ err = spl_parse_image_header(spl_image, header);
+ if (err)
+ return err;
+
+ spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS,
+ spl_image->size, (void *)spl_image->load_addr);
+
+ /* Read device tree. */
+ spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS,
+ CONFIG_SYS_SPI_ARGS_SIZE,
+ (void *)CONFIG_SYS_SPL_ARGS_ADDR);
+
+ return 0;
+}
+#endif
+
+static ulong spl_spi_fit_read(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ struct spi_flash *flash = load->dev;
+ ulong ret;
+
+ ret = spi_flash_read(flash, sector, count, buf);
+ if (!ret)
+ return count;
+ else
+ return 0;
+}
+
+unsigned int __weak spl_spi_get_uboot_offs(struct spi_flash *flash)
+{
+ return CONFIG_SYS_SPI_U_BOOT_OFFS;
+}
+
+/*
+ * The main entry for SPI booting. It's necessary that SDRAM is already
+ * configured and available since this code loads the main U-Boot image
+ * from SPI into SDRAM and starts it from there.
+ */
+static int spl_spi_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ int err = 0;
+ unsigned int payload_offs;
+ struct spi_flash *flash;
+ struct image_header *header;
+
+ /*
+ * Load U-Boot image from SPI flash into RAM
+ * In DM mode: defaults speed and mode will be
+ * taken from DT when available
+ */
+
+ flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+ CONFIG_SF_DEFAULT_CS,
+ CONFIG_SF_DEFAULT_SPEED,
+ CONFIG_SF_DEFAULT_MODE);
+ if (!flash) {
+ puts("SPI probe failed.\n");
+ return -ENODEV;
+ }
+
+ payload_offs = spl_spi_get_uboot_offs(flash);
+
+ header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
+
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+ payload_offs = fdtdec_get_config_int(gd->fdt_blob,
+ "u-boot,spl-payload-offset",
+ payload_offs);
+#endif
+
+#ifdef CONFIG_SPL_OS_BOOT
+ if (spl_start_uboot() || spi_load_image_os(spl_image, flash, header))
+#endif
+ {
+ /* Load u-boot, mkimage header is 64 bytes. */
+ err = spi_flash_read(flash, payload_offs, sizeof(*header),
+ (void *)header);
+ if (err) {
+ debug("%s: Failed to read from SPI flash (err=%d)\n",
+ __func__, err);
+ return err;
+ }
+
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) &&
+ image_get_magic(header) == FDT_MAGIC) {
+ err = spi_flash_read(flash, payload_offs,
+ roundup(fdt_totalsize(header), 4),
+ (void *)CONFIG_SYS_LOAD_ADDR);
+ if (err)
+ return err;
+ err = spl_parse_image_header(spl_image,
+ (struct image_header *)CONFIG_SYS_LOAD_ADDR);
+ } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+ image_get_magic(header) == FDT_MAGIC) {
+ struct spl_load_info load;
+
+ debug("Found FIT\n");
+ load.dev = flash;
+ load.priv = NULL;
+ load.filename = NULL;
+ load.bl_len = 1;
+ load.read = spl_spi_fit_read;
+ err = spl_load_simple_fit(spl_image, &load,
+ payload_offs,
+ header);
+ } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
+ struct spl_load_info load;
+
+ load.dev = flash;
+ load.priv = NULL;
+ load.filename = NULL;
+ load.bl_len = 1;
+ load.read = spl_spi_fit_read;
+
+ err = spl_load_imx_container(spl_image, &load,
+ payload_offs);
+ } else {
+ err = spl_parse_image_header(spl_image, header);
+ if (err)
+ return err;
+ err = spi_flash_read(flash, payload_offs,
+ spl_image->size,
+ (void *)spl_image->load_addr);
+ }
+ }
+
+ return err;
+}
+/* Use priorty 1 so that boards can override this */
+SPL_LOAD_IMAGE_METHOD("SPI", 1, BOOT_DEVICE_SPI, spl_spi_load_image);
diff --git a/roms/u-boot/common/spl/spl_ubi.c b/roms/u-boot/common/spl/spl_ubi.c
new file mode 100644
index 000000000..de6a63bd2
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_ubi.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2016
+ * Ladislav Michl <ladis@linux-mips.org>
+ */
+
+#include <common.h>
+#include <config.h>
+#include <image.h>
+#include <nand.h>
+#include <onenand_uboot.h>
+#include <ubispl.h>
+#include <spl.h>
+
+int spl_ubi_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ struct image_header *header;
+ struct ubispl_info info;
+ struct ubispl_load volumes[2];
+ int ret = 1;
+
+ switch (bootdev->boot_device) {
+#ifdef CONFIG_SPL_NAND_SUPPORT
+ case BOOT_DEVICE_NAND:
+ nand_init();
+ info.read = nand_spl_read_block;
+ info.peb_size = CONFIG_SYS_NAND_BLOCK_SIZE;
+ break;
+#endif
+#ifdef CONFIG_SPL_ONENAND_SUPPORT
+ case BOOT_DEVICE_ONENAND:
+ info.read = onenand_spl_read_block;
+ info.peb_size = CONFIG_SYS_ONENAND_BLOCK_SIZE;
+ break;
+#endif
+ default:
+ goto out;
+ }
+ info.ubi = (struct ubi_scan_info *)CONFIG_SPL_UBI_INFO_ADDR;
+ info.fastmap = IS_ENABLED(CONFIG_MTD_UBI_FASTMAP);
+
+ info.peb_offset = CONFIG_SPL_UBI_PEB_OFFSET;
+ info.vid_offset = CONFIG_SPL_UBI_VID_OFFSET;
+ info.leb_start = CONFIG_SPL_UBI_LEB_START;
+ info.peb_count = CONFIG_SPL_UBI_MAX_PEBS - info.peb_offset;
+
+#ifdef CONFIG_SPL_OS_BOOT
+ if (!spl_start_uboot()) {
+ volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_KERNEL_ID;
+ volumes[0].load_addr = (void *)CONFIG_SYS_LOAD_ADDR;
+ volumes[1].vol_id = CONFIG_SPL_UBI_LOAD_ARGS_ID;
+ volumes[1].load_addr = (void *)CONFIG_SYS_SPL_ARGS_ADDR;
+
+ ret = ubispl_load_volumes(&info, volumes, 2);
+ if (!ret) {
+ header = (struct image_header *)volumes[0].load_addr;
+ spl_parse_image_header(spl_image, header);
+ puts("Linux loaded.\n");
+ goto out;
+ }
+ puts("Loading Linux failed, falling back to U-Boot.\n");
+ }
+#endif
+ header = spl_get_load_buffer(-sizeof(*header), sizeof(header));
+#ifdef CONFIG_SPL_UBI_LOAD_BY_VOLNAME
+ volumes[0].vol_id = -1;
+ strncpy(volumes[0].name,
+ CONFIG_SPL_UBI_LOAD_MONITOR_VOLNAME,
+ UBI_VOL_NAME_MAX + 1);
+#else
+ volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_MONITOR_ID;
+#endif
+ volumes[0].load_addr = (void *)header;
+
+ ret = ubispl_load_volumes(&info, volumes, 1);
+ if (!ret)
+ spl_parse_image_header(spl_image, header);
+out:
+#ifdef CONFIG_SPL_NAND_SUPPORT
+ if (bootdev->boot_device == BOOT_DEVICE_NAND)
+ nand_deselect();
+#endif
+ return ret;
+}
+/* Use priorty 0 so that Ubi will override NAND and ONENAND methods */
+SPL_LOAD_IMAGE_METHOD("NAND", 0, BOOT_DEVICE_NAND, spl_ubi_load_image);
+SPL_LOAD_IMAGE_METHOD("OneNAND", 0, BOOT_DEVICE_ONENAND, spl_ubi_load_image);
diff --git a/roms/u-boot/common/spl/spl_usb.c b/roms/u-boot/common/spl/spl_usb.c
new file mode 100644
index 000000000..3648de349
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_usb.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2014
+ * Texas Instruments, <www.ti.com>
+ *
+ * Dan Murphy <dmurphy@ti.com>
+ *
+ * Derived work from spl_mmc.c
+ */
+
+#include <common.h>
+#include <log.h>
+#include <spl.h>
+#include <asm/u-boot.h>
+#include <errno.h>
+#include <usb.h>
+#include <fat.h>
+
+static int usb_stor_curr_dev = -1; /* current device */
+
+int spl_usb_load(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev, int partition,
+ const char *filename)
+{
+ int err = 0;
+ struct blk_desc *stor_dev;
+ static bool usb_init_pending = true;
+
+ if (usb_init_pending) {
+ usb_stop();
+ err = usb_init();
+ usb_init_pending = false;
+ }
+
+ if (err) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+ printf("%s: usb init failed: err - %d\n", __func__, err);
+#endif
+ return err;
+ }
+
+ /* try to recognize storage devices immediately */
+ usb_stor_curr_dev = usb_stor_scan(1);
+ stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, usb_stor_curr_dev);
+ if (!stor_dev)
+ return -ENODEV;
+
+ debug("boot mode - FAT\n");
+
+#ifdef CONFIG_SPL_OS_BOOT
+ if (spl_start_uboot() ||
+ spl_load_image_fat_os(spl_image, stor_dev, partition))
+#endif
+ {
+ err = spl_load_image_fat(spl_image, stor_dev, partition, filename);
+ }
+
+ if (err) {
+ puts("Error loading from USB device\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int spl_usb_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ return spl_usb_load(spl_image, bootdev,
+ CONFIG_SYS_USB_FAT_BOOT_PARTITION,
+ CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
+}
+SPL_LOAD_IMAGE_METHOD("USB", 0, BOOT_DEVICE_USB, spl_usb_load_image);
diff --git a/roms/u-boot/common/spl/spl_xip.c b/roms/u-boot/common/spl/spl_xip.c
new file mode 100644
index 000000000..8ce0a09ef
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_xip.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
+ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
+ */
+
+#include <common.h>
+#include <image.h>
+#include <log.h>
+#include <spl.h>
+
+static int spl_xip(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+#ifdef CONFIG_SPL_OS_BOOT
+ if (!spl_start_uboot()) {
+ spl_image->arg = (void *)CONFIG_SYS_FDT_BASE;
+ spl_image->name = "Linux";
+ spl_image->os = IH_OS_LINUX;
+ spl_image->load_addr = CONFIG_SYS_LOAD_ADDR;
+ spl_image->entry_point = CONFIG_SYS_LOAD_ADDR;
+ debug("spl: payload xipImage, load addr: 0x%lx\n",
+ spl_image->load_addr);
+ return 0;
+ }
+#endif
+ return(spl_parse_image_header(spl_image, (const struct image_header *)
+ CONFIG_SYS_UBOOT_BASE));
+}
+SPL_LOAD_IMAGE_METHOD("XIP", 0, BOOT_DEVICE_XIP, spl_xip);
diff --git a/roms/u-boot/common/spl/spl_ymodem.c b/roms/u-boot/common/spl/spl_ymodem.c
new file mode 100644
index 000000000..e979f780a
--- /dev/null
+++ b/roms/u-boot/common/spl/spl_ymodem.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2011
+ * Texas Instruments, <www.ti.com>
+ *
+ * Matt Porter <mporter@ti.com>
+ */
+#include <common.h>
+#include <gzip.h>
+#include <image.h>
+#include <log.h>
+#include <spl.h>
+#include <xyzModem.h>
+#include <asm/u-boot.h>
+#include <linux/libfdt.h>
+
+#define BUF_SIZE 1024
+
+/*
+ * Information required to load image using ymodem.
+ *
+ * @image_read: Now of bytes read from the image.
+ * @buf: pointer to the previous read block.
+ */
+struct ymodem_fit_info {
+ int image_read;
+ char *buf;
+};
+
+static int getcymodem(void) {
+ if (tstc())
+ return (getchar());
+ return -1;
+}
+
+static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset,
+ ulong size, void *addr)
+{
+ int res, err, buf_offset;
+ struct ymodem_fit_info *info = load->priv;
+ char *buf = info->buf;
+
+ while (info->image_read < offset) {
+ res = xyzModem_stream_read(buf, BUF_SIZE, &err);
+ if (res <= 0)
+ break;
+
+ info->image_read += res;
+ }
+
+ if (info->image_read > offset) {
+ res = info->image_read - offset;
+ if (info->image_read % BUF_SIZE)
+ buf_offset = (info->image_read % BUF_SIZE);
+ else
+ buf_offset = BUF_SIZE;
+ memcpy(addr, &buf[buf_offset - res], res);
+ addr = addr + res;
+ }
+
+ while (info->image_read < offset + size) {
+ res = xyzModem_stream_read(buf, BUF_SIZE, &err);
+ if (res <= 0)
+ break;
+
+ memcpy(addr, buf, res);
+ info->image_read += res;
+ addr += res;
+ }
+
+ return size;
+}
+
+int spl_ymodem_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ ulong size = 0;
+ int err;
+ int res;
+ int ret;
+ connection_info_t info;
+ char buf[BUF_SIZE];
+ struct image_header *ih = NULL;
+ ulong addr = 0;
+
+ info.mode = xyzModem_ymodem;
+ ret = xyzModem_stream_open(&info, &err);
+ if (ret) {
+ printf("spl: ymodem err - %s\n", xyzModem_error(err));
+ return ret;
+ }
+
+ res = xyzModem_stream_read(buf, BUF_SIZE, &err);
+ if (res <= 0)
+ goto end_stream;
+
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) &&
+ image_get_magic((struct image_header *)buf) == FDT_MAGIC) {
+ addr = CONFIG_SYS_LOAD_ADDR;
+ ih = (struct image_header *)addr;
+
+ memcpy((void *)addr, buf, res);
+ size += res;
+ addr += res;
+
+ while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) {
+ memcpy((void *)addr, buf, res);
+ size += res;
+ addr += res;
+ }
+
+ ret = spl_parse_image_header(spl_image, ih);
+ if (ret)
+ return ret;
+ } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+ image_get_magic((struct image_header *)buf) == FDT_MAGIC) {
+ struct spl_load_info load;
+ struct ymodem_fit_info info;
+
+ debug("Found FIT\n");
+ load.dev = NULL;
+ load.priv = (void *)&info;
+ load.filename = NULL;
+ load.bl_len = 1;
+ info.buf = buf;
+ info.image_read = BUF_SIZE;
+ load.read = ymodem_read_fit;
+ ret = spl_load_simple_fit(spl_image, &load, 0, (void *)buf);
+ size = info.image_read;
+
+ while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0)
+ size += res;
+ } else {
+ ih = (struct image_header *)buf;
+ ret = spl_parse_image_header(spl_image, ih);
+ if (ret)
+ goto end_stream;
+#ifdef CONFIG_SPL_GZIP
+ if (ih->ih_comp == IH_COMP_GZIP)
+ addr = CONFIG_SYS_LOAD_ADDR;
+ else
+#endif
+ addr = spl_image->load_addr;
+ memcpy((void *)addr, buf, res);
+ ih = (struct image_header *)addr;
+ size += res;
+ addr += res;
+
+ while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) {
+ memcpy((void *)addr, buf, res);
+ size += res;
+ addr += res;
+ }
+ }
+
+end_stream:
+ xyzModem_stream_close(&err);
+ xyzModem_stream_terminate(false, &getcymodem);
+
+ printf("Loaded %lu bytes\n", size);
+
+#ifdef CONFIG_SPL_GZIP
+ if (!(IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+ image_get_magic((struct image_header *)buf) == FDT_MAGIC) &&
+ (ih->ih_comp == IH_COMP_GZIP)) {
+ if (gunzip((void *)(spl_image->load_addr + sizeof(*ih)),
+ CONFIG_SYS_BOOTM_LEN,
+ (void *)(CONFIG_SYS_LOAD_ADDR + sizeof(*ih)),
+ &size)) {
+ puts("Uncompressing error\n");
+ return -EIO;
+ }
+ }
+#endif
+
+ return ret;
+}
+SPL_LOAD_IMAGE_METHOD("UART", 0, BOOT_DEVICE_UART, spl_ymodem_load_image);